mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 21:01:08 +00:00
Bug 1814786 - Part 6: Create timeline objects when mutating scroll-timeline property. r=emilio
And so we can lookup the timeline from TimelineCollection. Differential Revision: https://phabricator.services.mozilla.com/D169273
This commit is contained in:
parent
95a2a27769
commit
4fa8c3ce41
@ -63,6 +63,7 @@
|
||||
#include "mozilla/ServoBindings.h"
|
||||
#include "mozilla/ServoTraversalStatistics.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/TimelineManager.h"
|
||||
#include "mozilla/RWLock.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/ElementInlines.h"
|
||||
@ -508,6 +509,18 @@ bool Gecko_StyleAnimationsEquals(const nsStyleAutoArray<StyleAnimation>* aA,
|
||||
return *aA == *aB;
|
||||
}
|
||||
|
||||
bool Gecko_StyleScrollTimelinesEquals(
|
||||
const nsStyleAutoArray<StyleScrollTimeline>* aA,
|
||||
const nsStyleAutoArray<StyleScrollTimeline>* aB) {
|
||||
return *aA == *aB;
|
||||
}
|
||||
|
||||
bool Gecko_StyleViewTimelinesEquals(
|
||||
const nsStyleAutoArray<StyleViewTimeline>* aA,
|
||||
const nsStyleAutoArray<StyleViewTimeline>* aB) {
|
||||
return *aA == *aB;
|
||||
}
|
||||
|
||||
void Gecko_CopyAnimationNames(nsStyleAutoArray<StyleAnimation>* aDest,
|
||||
const nsStyleAutoArray<StyleAnimation>* aSrc) {
|
||||
size_t srcLength = aSrc->Length();
|
||||
@ -544,7 +557,17 @@ void Gecko_UpdateAnimations(const Element* aElement,
|
||||
const auto [element, pseudoType] =
|
||||
AnimationUtils::GetElementPseudoPair(aElement);
|
||||
|
||||
// TODO: call UpdateTimelines() in the next patch.
|
||||
// Handle scroll/view timelines first because CSS animations may refer to the
|
||||
// timeline defined by itself.
|
||||
if (aTasks & UpdateAnimationsTasks::ScrollTimelines) {
|
||||
presContext->TimelineManager()->UpdateTimelines(
|
||||
const_cast<Element*>(element), pseudoType, aComputedData,
|
||||
TimelineManager::ProgressTimelineType::Scroll);
|
||||
}
|
||||
|
||||
if (aTasks & UpdateAnimationsTasks::ViewTimelines) {
|
||||
// TODO: Bug 1737920. Add support for view timelines.
|
||||
}
|
||||
|
||||
if (aTasks & UpdateAnimationsTasks::CSSAnimations) {
|
||||
presContext->AnimationManager()->UpdateAnimations(
|
||||
|
@ -216,6 +216,14 @@ bool Gecko_StyleAnimationsEquals(
|
||||
const nsStyleAutoArray<mozilla::StyleAnimation>*,
|
||||
const nsStyleAutoArray<mozilla::StyleAnimation>*);
|
||||
|
||||
bool Gecko_StyleScrollTimelinesEquals(
|
||||
const nsStyleAutoArray<mozilla::StyleScrollTimeline>*,
|
||||
const nsStyleAutoArray<mozilla::StyleScrollTimeline>*);
|
||||
|
||||
bool Gecko_StyleViewTimelinesEquals(
|
||||
const nsStyleAutoArray<mozilla::StyleViewTimeline>*,
|
||||
const nsStyleAutoArray<mozilla::StyleViewTimeline>*);
|
||||
|
||||
void Gecko_CopyAnimationNames(
|
||||
nsStyleAutoArray<mozilla::StyleAnimation>* aDest,
|
||||
const nsStyleAutoArray<mozilla::StyleAnimation>* aSrc);
|
||||
|
@ -75,6 +75,8 @@ enum class UpdateAnimationsTasks : uint8_t {
|
||||
EffectProperties = 1 << 2,
|
||||
CascadeResults = 1 << 3,
|
||||
DisplayChangedFromNone = 1 << 4,
|
||||
ScrollTimelines = 1 << 5,
|
||||
ViewTimelines = 1 << 6,
|
||||
};
|
||||
|
||||
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(UpdateAnimationsTasks)
|
||||
|
@ -38,6 +38,10 @@ class TimelineCollection final
|
||||
|
||||
~TimelineCollection();
|
||||
|
||||
already_AddRefed<TimelineType> Lookup(const nsAtom* aName) const {
|
||||
return mTimelines.Get(aName).forget();
|
||||
}
|
||||
|
||||
already_AddRefed<TimelineType> Extract(const nsAtom* aName) {
|
||||
Maybe<RefPtr<TimelineType>> timeline = mTimelines.Extract(aName);
|
||||
return timeline ? timeline->forget() : nullptr;
|
||||
|
@ -9,10 +9,12 @@
|
||||
#include "nsTransitionManager.h"
|
||||
|
||||
#include "mozilla/AnimationEventDispatcher.h"
|
||||
#include "mozilla/AnimationUtils.h"
|
||||
#include "mozilla/EffectCompositor.h"
|
||||
#include "mozilla/ElementAnimationData.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/ServoStyleSet.h"
|
||||
#include "mozilla/TimelineCollection.h"
|
||||
#include "mozilla/dom/AnimationEffect.h"
|
||||
#include "mozilla/dom/DocumentTimeline.h"
|
||||
#include "mozilla/dom/KeyframeEffect.h"
|
||||
@ -213,31 +215,23 @@ static already_AddRefed<dom::AnimationTimeline> GetNamedProgressTimeline(
|
||||
// 2. that element’s descendants
|
||||
// 3. that element’s following siblings and their descendants
|
||||
// https://drafts.csswg.org/scroll-animations-1/#timeline-scope
|
||||
for (Element* curr = aTarget.mElement; curr;
|
||||
curr = curr->GetParentElement()) {
|
||||
for (Element* curr = AnimationUtils::GetElementForRestyle(
|
||||
aTarget.mElement, aTarget.mPseudoType);
|
||||
curr; curr = curr->GetParentElement()) {
|
||||
// If multiple elements have declared the same timeline name, the matching
|
||||
// timeline is the one declared on the nearest element in tree order, which
|
||||
// considers siblings closer than parents.
|
||||
// Note: This is fine for parallel traversal because we update animations by
|
||||
// SequentialTask.
|
||||
for (Element* e = curr; e; e = e->GetPreviousElementSibling()) {
|
||||
// TODO: Look up the named timelines from the corresponding
|
||||
// TimelineCollection in the next patch.
|
||||
|
||||
const ComputedStyle* style = Servo_Element_GetMaybeOutOfDateStyle(e);
|
||||
// The elements in the shadow dom might not be in the flat tree.
|
||||
if (!style) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const nsStyleUIReset* ui = style->StyleUIReset();
|
||||
// In case of a name conflict on the same element, scroll progress
|
||||
// timelines take precedence over view progress timelines.
|
||||
// TODO: Will reuse named progress timelines in the following patches.
|
||||
for (uint32_t i = 0; i < ui->mScrollTimelineNameCount; ++i) {
|
||||
const auto& timeline = ui->mScrollTimelines[i];
|
||||
if (timeline.GetName() == aName) {
|
||||
return ScrollTimeline::MakeNamed(aDocument, e, timeline);
|
||||
const auto [element, pseudoType] =
|
||||
AnimationUtils::GetElementPseudoPair(e);
|
||||
if (auto* collection =
|
||||
TimelineCollection<ScrollTimeline>::Get(element, pseudoType)) {
|
||||
if (RefPtr<ScrollTimeline> timeline = collection->Lookup(aName)) {
|
||||
return timeline.forget();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -419,6 +419,10 @@ bitflags! {
|
||||
/// the second animation restyles for the script animations in the case where
|
||||
/// the display property was changed from 'none' to others.
|
||||
const DISPLAY_CHANGED_FROM_NONE = structs::UpdateAnimationsTasks_DisplayChangedFromNone;
|
||||
/// Update CSS named scroll progress timelines.
|
||||
const SCROLL_TIMELINES = structs::UpdateAnimationsTasks_ScrollTimelines;
|
||||
/// Update CSS named view progress timelines.
|
||||
const VIEW_TIMELINES = structs::UpdateAnimationsTasks_ViewTimelines;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -418,6 +418,21 @@ trait PrivateMatchMethods: TElement {
|
||||
// in addition to the unvisited styles.
|
||||
|
||||
let mut tasks = UpdateAnimationsTasks::empty();
|
||||
|
||||
if old_values.as_deref().map_or_else(
|
||||
|| new_values.get_ui().specifies_scroll_timelines(),
|
||||
|old| !old.get_ui().scroll_timelines_equals(new_values.get_ui()),
|
||||
) {
|
||||
tasks.insert(UpdateAnimationsTasks::SCROLL_TIMELINES);
|
||||
}
|
||||
|
||||
if old_values.as_deref().map_or_else(
|
||||
|| new_values.get_ui().specifies_view_timelines(),
|
||||
|old| !old.get_ui().view_timelines_equals(new_values.get_ui()),
|
||||
) {
|
||||
tasks.insert(UpdateAnimationsTasks::VIEW_TIMELINES);
|
||||
}
|
||||
|
||||
if self.needs_animations_update(
|
||||
context,
|
||||
old_values.as_deref(),
|
||||
|
@ -1907,9 +1907,32 @@ mask-mode mask-repeat mask-clip mask-origin mask-composite mask-position-x mask-
|
||||
${impl_coordinated_property('scroll_timeline', 'name', 'Name')}
|
||||
${impl_coordinated_property('scroll_timeline', 'axis', 'Axis')}
|
||||
|
||||
pub fn scroll_timelines_equals(&self, other: &Self) -> bool {
|
||||
self.gecko.mScrollTimelineNameCount == other.gecko.mScrollTimelineNameCount
|
||||
&& self.gecko.mScrollTimelineAxisCount == other.gecko.mScrollTimelineAxisCount
|
||||
&& unsafe {
|
||||
bindings::Gecko_StyleScrollTimelinesEquals(
|
||||
&self.gecko.mScrollTimelines,
|
||||
&other.gecko.mScrollTimelines,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
${impl_coordinated_property('view_timeline', 'name', 'Name')}
|
||||
${impl_coordinated_property('view_timeline', 'axis', 'Axis')}
|
||||
${impl_coordinated_property('view_timeline', 'inset', 'Inset')}
|
||||
|
||||
pub fn view_timelines_equals(&self, other: &Self) -> bool {
|
||||
self.gecko.mViewTimelineNameCount == other.gecko.mViewTimelineNameCount
|
||||
&& self.gecko.mViewTimelineAxisCount == other.gecko.mViewTimelineAxisCount
|
||||
&& self.gecko.mViewTimelineInsetCount == other.gecko.mViewTimelineInsetCount
|
||||
&& unsafe {
|
||||
bindings::Gecko_StyleViewTimelinesEquals(
|
||||
&self.gecko.mViewTimelines,
|
||||
&other.gecko.mViewTimelines,
|
||||
)
|
||||
}
|
||||
}
|
||||
</%self:impl_trait>
|
||||
|
||||
<%self:impl_trait style_struct_name="XUL">
|
||||
|
@ -2953,6 +2953,18 @@ pub mod style_structs {
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns whether there is any named progress timeline specified with
|
||||
/// scroll-timeline-name other than `none`.
|
||||
pub fn specifies_scroll_timelines(&self) -> bool {
|
||||
self.scroll_timeline_name_iter().any(|name| !name.is_none())
|
||||
}
|
||||
|
||||
/// Returns whether there is any named progress timeline specified with
|
||||
/// view-timeline-name other than `none`.
|
||||
pub fn specifies_view_timelines(&self) -> bool {
|
||||
self.view_timeline_name_iter().any(|name| !name.is_none())
|
||||
}
|
||||
|
||||
/// Returns true if animation properties are equal between styles, but without
|
||||
/// considering keyframe data and animation-timeline.
|
||||
#[cfg(feature = "servo")]
|
||||
|
@ -33,6 +33,3 @@
|
||||
|
||||
[Timeline lookup updates candidate when match becomes available.]
|
||||
expected: FAIL
|
||||
|
||||
[scroll-timeline-axis is mutated]
|
||||
expected: FAIL
|
||||
|
Loading…
Reference in New Issue
Block a user