2021-12-08 01:16:28 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
|
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
|
|
#ifndef mozilla_dom_ScrollTimeline_h
|
|
|
|
#define mozilla_dom_ScrollTimeline_h
|
|
|
|
|
|
|
|
#include "mozilla/dom/AnimationTimeline.h"
|
Bug 1676791 - Part 9: Define Scroller to handle the source of ScrollTimeline. r=emilio
Per spec, "auto" represents the scrolling element of the document.
However, the scrolling element might be changed, based on the layout, in
quirks mode. Besides, the content of the root scroll frame is the root
element, instead of the scrolling element (e.g. body element) in both
standard and quirks modes. So now we define a special type, Scroller, to
represent the source of scroll-timeline, and use its |mType| to decide
which scroll frame we would like to use. In addition, hope this change let
us easier to implement nearest scroller.
Note: for auto scroller, we register this ScrollTimeline to the root
element, in both modes. Once we expose ScrollTimeline interface to the
script, we can rely on the |mType| of Scroller to return the correct
source element, whether it is scrolling element or not.
Differential Revision: https://phabricator.services.mozilla.com/D131578
2021-12-08 01:16:31 +00:00
|
|
|
#include "mozilla/dom/Document.h"
|
2021-12-08 01:16:28 +00:00
|
|
|
#include "mozilla/HashTable.h"
|
2022-06-13 20:26:46 +00:00
|
|
|
#include "mozilla/PairHash.h"
|
2021-12-08 01:16:28 +00:00
|
|
|
#include "mozilla/ServoStyleConsts.h"
|
2021-12-08 01:16:29 +00:00
|
|
|
#include "mozilla/WritingModes.h"
|
|
|
|
|
2022-07-07 18:33:42 +00:00
|
|
|
#define PROGRESS_TIMELINE_DURATION_MILLISEC 100000
|
|
|
|
|
2021-12-08 01:16:28 +00:00
|
|
|
namespace mozilla {
|
2024-05-30 06:32:20 +00:00
|
|
|
class ScrollContainerFrame;
|
2023-03-16 20:00:00 +00:00
|
|
|
class ElementAnimationData;
|
2021-12-08 01:16:31 +00:00
|
|
|
struct NonOwningAnimationTarget;
|
2021-12-08 01:16:28 +00:00
|
|
|
namespace dom {
|
2021-12-08 01:16:28 +00:00
|
|
|
class Element;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Implementation notes
|
|
|
|
* --------------------
|
|
|
|
*
|
|
|
|
* ScrollTimelines do not observe refreshes the way DocumentTimelines do.
|
|
|
|
* This is because the refresh driver keeps ticking while it has registered
|
|
|
|
* refresh observers. For a DocumentTimeline, it's appropriate to keep the
|
|
|
|
* refresh driver ticking as long as there are active animations, since the
|
|
|
|
* animations need to be sampled on every frame. Scroll-linked animations,
|
|
|
|
* however, only need to be sampled when scrolling has occurred, so keeping
|
|
|
|
* the refresh driver ticking is wasteful.
|
|
|
|
*
|
|
|
|
* As a result, we schedule an animation restyle when
|
|
|
|
* 1) there are any scroll offsets updated (from APZ or script), via
|
2024-05-30 06:32:20 +00:00
|
|
|
* ScrollContainerFrame, or
|
2021-12-08 01:16:28 +00:00
|
|
|
* 2) there are any possible scroll range updated during the frame reflow.
|
|
|
|
*
|
|
|
|
* -------------
|
|
|
|
* | Animation |
|
|
|
|
* -------------
|
|
|
|
* ^
|
|
|
|
* | Call Animation::Tick() if there are any scroll updates.
|
|
|
|
* |
|
|
|
|
* ------------------
|
|
|
|
* | ScrollTimeline |
|
|
|
|
* ------------------
|
|
|
|
* ^
|
2023-01-04 00:50:45 +00:00
|
|
|
* | Try schedule the scroll-driven animations, if there are any scroll
|
2021-12-08 01:16:28 +00:00
|
|
|
* | offsets changed or the scroll range changed [1].
|
|
|
|
* |
|
2024-05-30 06:32:20 +00:00
|
|
|
* ------------------------
|
|
|
|
* | ScrollContainerFrame |
|
|
|
|
* ------------------------
|
2021-12-08 01:16:28 +00:00
|
|
|
*
|
2024-05-30 06:32:20 +00:00
|
|
|
* [1] ScrollContainerFrame uses its associated dom::Element to lookup the
|
2021-12-08 01:16:28 +00:00
|
|
|
* ScrollTimelineSet, and iterates the set to schedule the animations
|
|
|
|
* linked to the ScrollTimelines.
|
|
|
|
*/
|
2023-04-12 20:52:02 +00:00
|
|
|
class ScrollTimeline : public AnimationTimeline {
|
2023-03-07 23:57:53 +00:00
|
|
|
template <typename T, typename... Args>
|
|
|
|
friend already_AddRefed<T> mozilla::MakeAndAddRef(Args&&... aArgs);
|
|
|
|
|
2021-12-08 01:16:28 +00:00
|
|
|
public:
|
Bug 1676791 - Part 9: Define Scroller to handle the source of ScrollTimeline. r=emilio
Per spec, "auto" represents the scrolling element of the document.
However, the scrolling element might be changed, based on the layout, in
quirks mode. Besides, the content of the root scroll frame is the root
element, instead of the scrolling element (e.g. body element) in both
standard and quirks modes. So now we define a special type, Scroller, to
represent the source of scroll-timeline, and use its |mType| to decide
which scroll frame we would like to use. In addition, hope this change let
us easier to implement nearest scroller.
Note: for auto scroller, we register this ScrollTimeline to the root
element, in both modes. Once we expose ScrollTimeline interface to the
script, we can rely on the |mType| of Scroller to return the correct
source element, whether it is scrolling element or not.
Differential Revision: https://phabricator.services.mozilla.com/D131578
2021-12-08 01:16:31 +00:00
|
|
|
struct Scroller {
|
2023-03-16 20:00:00 +00:00
|
|
|
// FIXME: Bug 1765211. Perhaps we only need root and a specific element.
|
|
|
|
// This depends on how we fix this bug.
|
2022-06-13 20:26:46 +00:00
|
|
|
enum class Type : uint8_t {
|
2022-06-13 20:26:45 +00:00
|
|
|
Root,
|
|
|
|
Nearest,
|
|
|
|
Name,
|
2023-05-04 21:35:14 +00:00
|
|
|
Self,
|
2022-06-13 20:26:45 +00:00
|
|
|
};
|
|
|
|
Type mType = Type::Root;
|
Bug 1676791 - Part 9: Define Scroller to handle the source of ScrollTimeline. r=emilio
Per spec, "auto" represents the scrolling element of the document.
However, the scrolling element might be changed, based on the layout, in
quirks mode. Besides, the content of the root scroll frame is the root
element, instead of the scrolling element (e.g. body element) in both
standard and quirks modes. So now we define a special type, Scroller, to
represent the source of scroll-timeline, and use its |mType| to decide
which scroll frame we would like to use. In addition, hope this change let
us easier to implement nearest scroller.
Note: for auto scroller, we register this ScrollTimeline to the root
element, in both modes. Once we expose ScrollTimeline interface to the
script, we can rely on the |mType| of Scroller to return the correct
source element, whether it is scrolling element or not.
Differential Revision: https://phabricator.services.mozilla.com/D131578
2021-12-08 01:16:31 +00:00
|
|
|
RefPtr<Element> mElement;
|
2023-03-16 20:00:00 +00:00
|
|
|
PseudoStyleType mPseudoType;
|
Bug 1676791 - Part 9: Define Scroller to handle the source of ScrollTimeline. r=emilio
Per spec, "auto" represents the scrolling element of the document.
However, the scrolling element might be changed, based on the layout, in
quirks mode. Besides, the content of the root scroll frame is the root
element, instead of the scrolling element (e.g. body element) in both
standard and quirks modes. So now we define a special type, Scroller, to
represent the source of scroll-timeline, and use its |mType| to decide
which scroll frame we would like to use. In addition, hope this change let
us easier to implement nearest scroller.
Note: for auto scroller, we register this ScrollTimeline to the root
element, in both modes. Once we expose ScrollTimeline interface to the
script, we can rely on the |mType| of Scroller to return the correct
source element, whether it is scrolling element or not.
Differential Revision: https://phabricator.services.mozilla.com/D131578
2021-12-08 01:16:31 +00:00
|
|
|
|
|
|
|
// We use the owner doc of the animation target. This may be different from
|
|
|
|
// |mDocument| after we implement ScrollTimeline interface for script.
|
2022-04-21 17:05:18 +00:00
|
|
|
static Scroller Root(const Document* aOwnerDoc) {
|
Bug 1676791 - Part 9: Define Scroller to handle the source of ScrollTimeline. r=emilio
Per spec, "auto" represents the scrolling element of the document.
However, the scrolling element might be changed, based on the layout, in
quirks mode. Besides, the content of the root scroll frame is the root
element, instead of the scrolling element (e.g. body element) in both
standard and quirks modes. So now we define a special type, Scroller, to
represent the source of scroll-timeline, and use its |mType| to decide
which scroll frame we would like to use. In addition, hope this change let
us easier to implement nearest scroller.
Note: for auto scroller, we register this ScrollTimeline to the root
element, in both modes. Once we expose ScrollTimeline interface to the
script, we can rely on the |mType| of Scroller to return the correct
source element, whether it is scrolling element or not.
Differential Revision: https://phabricator.services.mozilla.com/D131578
2021-12-08 01:16:31 +00:00
|
|
|
// For auto, we use scrolling element as the default scroller.
|
|
|
|
// However, it's mutable, and we would like to keep things simple, so
|
|
|
|
// we always register the ScrollTimeline to the document element (i.e.
|
|
|
|
// root element) because the content of the root scroll frame is the root
|
|
|
|
// element.
|
2023-03-16 20:00:00 +00:00
|
|
|
return {Type::Root, aOwnerDoc->GetDocumentElement(),
|
|
|
|
PseudoStyleType::NotPseudo};
|
2022-04-20 20:28:53 +00:00
|
|
|
}
|
|
|
|
|
2023-03-16 20:00:00 +00:00
|
|
|
static Scroller Nearest(Element* aElement, PseudoStyleType aPseudoType) {
|
|
|
|
return {Type::Nearest, aElement, aPseudoType};
|
2022-04-21 17:05:19 +00:00
|
|
|
}
|
|
|
|
|
2023-03-16 20:00:00 +00:00
|
|
|
static Scroller Named(Element* aElement, PseudoStyleType aPseudoType) {
|
|
|
|
return {Type::Name, aElement, aPseudoType};
|
|
|
|
}
|
2022-06-13 20:26:45 +00:00
|
|
|
|
2023-05-04 21:35:14 +00:00
|
|
|
static Scroller Self(Element* aElement, PseudoStyleType aPseudoType) {
|
|
|
|
return {Type::Self, aElement, aPseudoType};
|
|
|
|
}
|
|
|
|
|
Bug 1676791 - Part 9: Define Scroller to handle the source of ScrollTimeline. r=emilio
Per spec, "auto" represents the scrolling element of the document.
However, the scrolling element might be changed, based on the layout, in
quirks mode. Besides, the content of the root scroll frame is the root
element, instead of the scrolling element (e.g. body element) in both
standard and quirks modes. So now we define a special type, Scroller, to
represent the source of scroll-timeline, and use its |mType| to decide
which scroll frame we would like to use. In addition, hope this change let
us easier to implement nearest scroller.
Note: for auto scroller, we register this ScrollTimeline to the root
element, in both modes. Once we expose ScrollTimeline interface to the
script, we can rely on the |mType| of Scroller to return the correct
source element, whether it is scrolling element or not.
Differential Revision: https://phabricator.services.mozilla.com/D131578
2021-12-08 01:16:31 +00:00
|
|
|
explicit operator bool() const { return mElement; }
|
|
|
|
bool operator==(const Scroller& aOther) const {
|
2023-03-16 20:00:00 +00:00
|
|
|
return mType == aOther.mType && mElement == aOther.mElement &&
|
|
|
|
mPseudoType == aOther.mPseudoType;
|
Bug 1676791 - Part 9: Define Scroller to handle the source of ScrollTimeline. r=emilio
Per spec, "auto" represents the scrolling element of the document.
However, the scrolling element might be changed, based on the layout, in
quirks mode. Besides, the content of the root scroll frame is the root
element, instead of the scrolling element (e.g. body element) in both
standard and quirks modes. So now we define a special type, Scroller, to
represent the source of scroll-timeline, and use its |mType| to decide
which scroll frame we would like to use. In addition, hope this change let
us easier to implement nearest scroller.
Note: for auto scroller, we register this ScrollTimeline to the root
element, in both modes. Once we expose ScrollTimeline interface to the
script, we can rely on the |mType| of Scroller to return the correct
source element, whether it is scrolling element or not.
Differential Revision: https://phabricator.services.mozilla.com/D131578
2021-12-08 01:16:31 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2023-03-07 23:57:53 +00:00
|
|
|
static already_AddRefed<ScrollTimeline> MakeAnonymous(
|
2022-04-21 17:05:19 +00:00
|
|
|
Document* aDocument, const NonOwningAnimationTarget& aTarget,
|
|
|
|
StyleScrollAxis aAxis, StyleScroller aScroller);
|
|
|
|
|
2023-04-12 20:52:02 +00:00
|
|
|
// Note: |aReferfenceElement| is used as the scroller which specifies
|
|
|
|
// scroll-timeline-name property.
|
2023-03-07 23:57:53 +00:00
|
|
|
static already_AddRefed<ScrollTimeline> MakeNamed(
|
|
|
|
Document* aDocument, Element* aReferenceElement,
|
2023-03-16 20:00:00 +00:00
|
|
|
PseudoStyleType aPseudoType, const StyleScrollTimeline& aStyleTimeline);
|
2022-06-13 20:26:45 +00:00
|
|
|
|
2021-12-08 01:16:31 +00:00
|
|
|
bool operator==(const ScrollTimeline& aOther) const {
|
|
|
|
return mDocument == aOther.mDocument && mSource == aOther.mSource &&
|
2022-04-21 17:05:18 +00:00
|
|
|
mAxis == aOther.mAxis;
|
2021-12-08 01:16:31 +00:00
|
|
|
}
|
|
|
|
|
2021-12-08 01:16:28 +00:00
|
|
|
NS_DECL_ISUPPORTS_INHERITED
|
2023-04-12 20:52:02 +00:00
|
|
|
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ScrollTimeline, AnimationTimeline)
|
2021-12-08 01:16:28 +00:00
|
|
|
|
|
|
|
JSObject* WrapObject(JSContext* aCx,
|
|
|
|
JS::Handle<JSObject*> aGivenProto) override {
|
|
|
|
// FIXME: Bug 1676794: Implement ScrollTimeline interface.
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
// AnimationTimeline methods.
|
2021-12-08 01:16:29 +00:00
|
|
|
Nullable<TimeDuration> GetCurrentTimeAsDuration() const override;
|
2021-12-08 01:16:28 +00:00
|
|
|
bool TracksWallclockTime() const override { return false; }
|
|
|
|
Nullable<TimeDuration> ToTimelineTime(
|
|
|
|
const TimeStamp& aTimeStamp) const override {
|
|
|
|
// It's unclear to us what should we do for this function now, so return
|
|
|
|
// nullptr.
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
TimeStamp ToTimeStamp(const TimeDuration& aTimelineTime) const override {
|
|
|
|
// It's unclear to us what should we do for this function now, so return
|
|
|
|
// zero time.
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
Document* GetDocument() const override { return mDocument; }
|
2021-12-08 01:16:30 +00:00
|
|
|
bool IsMonotonicallyIncreasing() const override { return false; }
|
2021-12-08 01:16:29 +00:00
|
|
|
bool IsScrollTimeline() const override { return true; }
|
2021-12-08 01:16:31 +00:00
|
|
|
const ScrollTimeline* AsScrollTimeline() const override { return this; }
|
2023-04-12 20:52:03 +00:00
|
|
|
bool IsViewTimeline() const override { return false; }
|
|
|
|
|
2022-07-07 18:33:41 +00:00
|
|
|
Nullable<TimeDuration> TimelineDuration() const override {
|
|
|
|
// We are using this magic number for progress-based timeline duration
|
|
|
|
// because we don't support percentage for duration.
|
|
|
|
return TimeDuration::FromMilliseconds(PROGRESS_TIMELINE_DURATION_MILLISEC);
|
|
|
|
}
|
2021-12-08 01:16:28 +00:00
|
|
|
|
2021-12-08 01:16:28 +00:00
|
|
|
void ScheduleAnimations() {
|
|
|
|
// FIXME: Bug 1737927: Need to check the animation mutation observers for
|
|
|
|
// animations with scroll timelines.
|
|
|
|
// nsAutoAnimationMutationBatch mb(mDocument);
|
2023-11-20 09:31:41 +00:00
|
|
|
TickState state;
|
|
|
|
Tick(state);
|
|
|
|
// TODO: Do we need to synchronize scroll animations?
|
2021-12-08 01:16:28 +00:00
|
|
|
}
|
|
|
|
|
2022-04-05 18:48:16 +00:00
|
|
|
// If the source of a ScrollTimeline is an element whose principal box does
|
|
|
|
// not exist or is not a scroll container, then its phase is the timeline
|
|
|
|
// inactive phase. It is otherwise in the active phase. This returns true if
|
|
|
|
// the timeline is in active phase.
|
|
|
|
// https://drafts.csswg.org/web-animations-1/#inactive-timeline
|
|
|
|
// Note: This function is called only for compositor animations, so we must
|
|
|
|
// have the primary frame (principal box) for the source element if it exists.
|
2024-05-30 06:32:20 +00:00
|
|
|
bool IsActive() const { return GetScrollContainerFrame(); }
|
2022-04-05 18:48:16 +00:00
|
|
|
|
|
|
|
Element* SourceElement() const {
|
|
|
|
MOZ_ASSERT(mSource);
|
|
|
|
return mSource.mElement;
|
|
|
|
}
|
|
|
|
|
|
|
|
// A helper to get the physical orientation of this scroll-timeline.
|
|
|
|
layers::ScrollDirection Axis() const;
|
|
|
|
|
2022-04-05 18:48:17 +00:00
|
|
|
StyleOverflow SourceScrollStyle() const;
|
|
|
|
|
|
|
|
bool APZIsActiveForSource() const;
|
|
|
|
|
|
|
|
bool ScrollingDirectionIsAvailable() const;
|
|
|
|
|
2023-03-07 23:57:54 +00:00
|
|
|
void ReplacePropertiesWith(const Element* aReferenceElement,
|
2023-03-16 20:00:00 +00:00
|
|
|
PseudoStyleType aPseudoType,
|
2023-03-07 23:57:54 +00:00
|
|
|
const StyleScrollTimeline& aNew);
|
|
|
|
|
2023-12-06 13:36:59 +00:00
|
|
|
void NotifyAnimationContentVisibilityChanged(Animation* aAnimation,
|
|
|
|
bool aIsVisible) override;
|
|
|
|
|
2021-12-08 01:16:28 +00:00
|
|
|
protected:
|
2021-12-08 01:16:28 +00:00
|
|
|
virtual ~ScrollTimeline() { Teardown(); }
|
2022-02-08 18:35:23 +00:00
|
|
|
ScrollTimeline() = delete;
|
|
|
|
ScrollTimeline(Document* aDocument, const Scroller& aScroller,
|
2022-04-21 17:05:18 +00:00
|
|
|
StyleScrollAxis aAxis);
|
2022-02-08 18:35:23 +00:00
|
|
|
|
Bug 1737920 - Part 2: Calculate offsets for ViewTimeline. r=emilio
The definition of at-progress-timeline-boundary is updated to use the
unconstructed current timeline if we have, so we update the
implementation as well. It is necessary for view-timeline.
Basically, we use offsets to control the animation progress.
For scroll-timeline, it's simply 0 to the scroll range.
For view-timeline, its progress is between 0% and 100% if the subject element
is in the view. Otherwise, its progress is outside the range.
This patch series doesn't take Named Timeline Range into account because
I expect we will handle them in different bugs, e.g. support the keyframe
selector with `<timeline-range-name>` in Bug 1823509.
So only the basic scenario is implemented:
1. 0% progress represents the position at which the start border edge of the
element’s principal box coincides with the end edge of its view progress
visibility range. (e.g. the top of the subject touches the bottom of
the scrollport, for the vertical axis.)
2. 100% progress represents the position at which the end border edge of the
element’s principal box coincides with the start edge of its view progress
visibility range. (e.g. the bottom of the subject touches the top of
the scrollport, for the vertical axis.)
So basically, it is equal to `cover` range (i.e. we run the animation
when the scrollport covers the subject), per
https://drafts.csswg.org/scroll-animations-1/#valdef-animation-timeline-range-cover
Note: OMTA will be disabled for view timeline in the next patch. So we
implement this only on the main thread.
Differential Revision: https://phabricator.services.mozilla.com/D170002
2023-04-12 20:52:02 +00:00
|
|
|
struct ScrollOffsets {
|
|
|
|
nscoord mStart = 0;
|
|
|
|
nscoord mEnd = 0;
|
|
|
|
};
|
|
|
|
virtual Maybe<ScrollOffsets> ComputeOffsets(
|
2024-05-30 06:32:20 +00:00
|
|
|
const ScrollContainerFrame* aScrollFrame,
|
Bug 1737920 - Part 2: Calculate offsets for ViewTimeline. r=emilio
The definition of at-progress-timeline-boundary is updated to use the
unconstructed current timeline if we have, so we update the
implementation as well. It is necessary for view-timeline.
Basically, we use offsets to control the animation progress.
For scroll-timeline, it's simply 0 to the scroll range.
For view-timeline, its progress is between 0% and 100% if the subject element
is in the view. Otherwise, its progress is outside the range.
This patch series doesn't take Named Timeline Range into account because
I expect we will handle them in different bugs, e.g. support the keyframe
selector with `<timeline-range-name>` in Bug 1823509.
So only the basic scenario is implemented:
1. 0% progress represents the position at which the start border edge of the
element’s principal box coincides with the end edge of its view progress
visibility range. (e.g. the top of the subject touches the bottom of
the scrollport, for the vertical axis.)
2. 100% progress represents the position at which the end border edge of the
element’s principal box coincides with the start edge of its view progress
visibility range. (e.g. the bottom of the subject touches the top of
the scrollport, for the vertical axis.)
So basically, it is equal to `cover` range (i.e. we run the animation
when the scrollport covers the subject), per
https://drafts.csswg.org/scroll-animations-1/#valdef-animation-timeline-range-cover
Note: OMTA will be disabled for view timeline in the next patch. So we
implement this only on the main thread.
Differential Revision: https://phabricator.services.mozilla.com/D170002
2023-04-12 20:52:02 +00:00
|
|
|
layers::ScrollDirection aOrientation) const;
|
|
|
|
|
2021-12-08 01:16:28 +00:00
|
|
|
// Note: This function is required to be idempotent, as it can be called from
|
|
|
|
// both cycleCollection::Unlink() and ~ScrollTimeline(). When modifying this
|
|
|
|
// function, be sure to preserve this property.
|
|
|
|
void Teardown() { UnregisterFromScrollSource(); }
|
|
|
|
|
2023-03-07 23:57:53 +00:00
|
|
|
// Register this scroll timeline to the element property.
|
|
|
|
void RegisterWithScrollSource();
|
|
|
|
|
|
|
|
// Unregister this scroll timeline from the element property.
|
2021-12-08 01:16:28 +00:00
|
|
|
void UnregisterFromScrollSource();
|
2021-12-08 01:16:28 +00:00
|
|
|
|
2024-05-30 06:32:20 +00:00
|
|
|
const ScrollContainerFrame* GetScrollContainerFrame() const;
|
Bug 1676791 - Part 9: Define Scroller to handle the source of ScrollTimeline. r=emilio
Per spec, "auto" represents the scrolling element of the document.
However, the scrolling element might be changed, based on the layout, in
quirks mode. Besides, the content of the root scroll frame is the root
element, instead of the scrolling element (e.g. body element) in both
standard and quirks modes. So now we define a special type, Scroller, to
represent the source of scroll-timeline, and use its |mType| to decide
which scroll frame we would like to use. In addition, hope this change let
us easier to implement nearest scroller.
Note: for auto scroller, we register this ScrollTimeline to the root
element, in both modes. Once we expose ScrollTimeline interface to the
script, we can rely on the |mType| of Scroller to return the correct
source element, whether it is scrolling element or not.
Differential Revision: https://phabricator.services.mozilla.com/D131578
2021-12-08 01:16:31 +00:00
|
|
|
|
2023-04-12 20:52:02 +00:00
|
|
|
static std::pair<const Element*, PseudoStyleType> FindNearestScroller(
|
|
|
|
Element* aSubject, PseudoStyleType aPseudoType);
|
|
|
|
|
2021-12-08 01:16:28 +00:00
|
|
|
RefPtr<Document> mDocument;
|
2021-12-08 01:16:29 +00:00
|
|
|
|
2022-04-21 17:05:19 +00:00
|
|
|
// FIXME: Bug 1765211: We may have to update the source element once the
|
|
|
|
// overflow property of the scroll-container is updated when we are using
|
|
|
|
// nearest scroller.
|
Bug 1676791 - Part 9: Define Scroller to handle the source of ScrollTimeline. r=emilio
Per spec, "auto" represents the scrolling element of the document.
However, the scrolling element might be changed, based on the layout, in
quirks mode. Besides, the content of the root scroll frame is the root
element, instead of the scrolling element (e.g. body element) in both
standard and quirks modes. So now we define a special type, Scroller, to
represent the source of scroll-timeline, and use its |mType| to decide
which scroll frame we would like to use. In addition, hope this change let
us easier to implement nearest scroller.
Note: for auto scroller, we register this ScrollTimeline to the root
element, in both modes. Once we expose ScrollTimeline interface to the
script, we can rely on the |mType| of Scroller to return the correct
source element, whether it is scrolling element or not.
Differential Revision: https://phabricator.services.mozilla.com/D131578
2021-12-08 01:16:31 +00:00
|
|
|
Scroller mSource;
|
2022-04-21 17:05:18 +00:00
|
|
|
StyleScrollAxis mAxis;
|
2021-12-08 01:16:28 +00:00
|
|
|
};
|
|
|
|
|
2021-12-08 01:16:28 +00:00
|
|
|
/**
|
2023-03-07 23:57:53 +00:00
|
|
|
* A wrapper around a hashset of ScrollTimeline objects to handle the scheduling
|
|
|
|
* of scroll driven animations. This is used for all kinds of progress
|
|
|
|
* timelines, i.e. anonymous/named scroll timelines and anonymous/named view
|
2023-03-16 20:00:00 +00:00
|
|
|
* timelines. And this object is owned by the scroll source (See
|
2024-05-15 17:50:48 +00:00
|
|
|
* ElementAnimationData and ScrollContainerFrame for the usage).
|
2021-12-08 01:16:28 +00:00
|
|
|
*/
|
2023-03-16 20:00:00 +00:00
|
|
|
class ProgressTimelineScheduler {
|
2021-12-08 01:16:28 +00:00
|
|
|
public:
|
2023-03-16 20:00:00 +00:00
|
|
|
ProgressTimelineScheduler() { MOZ_COUNT_CTOR(ProgressTimelineScheduler); }
|
|
|
|
~ProgressTimelineScheduler() { MOZ_COUNT_DTOR(ProgressTimelineScheduler); }
|
2021-12-08 01:16:28 +00:00
|
|
|
|
2023-03-16 20:00:00 +00:00
|
|
|
static ProgressTimelineScheduler* Get(const Element* aElement,
|
|
|
|
PseudoStyleType aPseudoType);
|
|
|
|
static ProgressTimelineScheduler& Ensure(Element* aElement,
|
|
|
|
PseudoStyleType aPseudoType);
|
|
|
|
static void Destroy(const Element* aElement, PseudoStyleType aPseudoType);
|
2021-12-08 01:16:28 +00:00
|
|
|
|
2023-03-16 20:00:00 +00:00
|
|
|
void AddTimeline(ScrollTimeline* aScrollTimeline) {
|
|
|
|
Unused << mTimelines.put(aScrollTimeline);
|
2021-12-08 01:16:28 +00:00
|
|
|
}
|
2023-03-16 20:00:00 +00:00
|
|
|
void RemoveTimeline(ScrollTimeline* aScrollTimeline) {
|
|
|
|
mTimelines.remove(aScrollTimeline);
|
2021-12-08 01:16:28 +00:00
|
|
|
}
|
|
|
|
|
2023-03-16 20:00:00 +00:00
|
|
|
bool IsEmpty() const { return mTimelines.empty(); }
|
2021-12-08 01:16:28 +00:00
|
|
|
|
|
|
|
void ScheduleAnimations() const {
|
2023-03-16 20:00:00 +00:00
|
|
|
for (auto iter = mTimelines.iter(); !iter.done(); iter.next()) {
|
2023-03-07 23:57:53 +00:00
|
|
|
iter.get()->ScheduleAnimations();
|
2021-12-08 01:16:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2023-03-16 20:00:00 +00:00
|
|
|
// We let Animations own its scroll timeline or view timeline if it is
|
|
|
|
// anonymous. For named progress timelines, they are created and destroyed by
|
|
|
|
// TimelineCollection.
|
|
|
|
HashSet<ScrollTimeline*> mTimelines;
|
2021-12-08 01:16:28 +00:00
|
|
|
};
|
|
|
|
|
2021-12-08 01:16:28 +00:00
|
|
|
} // namespace dom
|
|
|
|
} // namespace mozilla
|
|
|
|
|
|
|
|
#endif // mozilla_dom_ScrollTimeline_h
|