From 9e5f85edc2f0a063c82fc5881b939eb16af31658 Mon Sep 17 00:00:00 2001 From: Mats Palmgren Date: Tue, 26 Mar 2019 05:48:26 +0100 Subject: [PATCH 1/2] Bug 1538618 - [css-pseudo] implement animation support for ::marker pseudos. r=emilio Differential Revision: https://phabricator.services.mozilla.com/D25003 --HG-- extra : rebase_source : 999373f16c816cdd0dd64b1cc3f9f3f30bb12003 extra : amend_source : 829c0fc25afc55d50b70aebc1f3b9f0e8f06c458 --- dom/animation/CSSPseudoElement.cpp | 9 +++- dom/animation/CSSPseudoElement.h | 2 +- dom/animation/EffectCompositor.cpp | 36 ++++++++++------ dom/animation/EffectCompositor.h | 4 +- dom/animation/EffectSet.cpp | 9 +++- dom/animation/KeyframeEffect.cpp | 3 ++ dom/base/Element.cpp | 19 +++++++-- layout/base/RestyleManager.cpp | 5 +++ layout/base/RestyleManager.h | 11 +++-- ...arker-pseudo-element-at-beginning-ref.html | 13 ++++++ ...on-marker-pseudo-element-at-beginning.html | 18 ++++++++ ...tent-on-marker-pseudo-element-at-half.html | 18 ++++++++ ...n-animation-marker-pseudo-element-ref.html | 20 +++++++++ ...idden-animation-marker-pseudo-element.html | 39 +++++++++++++++++ ...animation-starts-at-the-same-time-ref.html | 17 ++++++++ ...and-animation-starts-at-the-same-time.html | 33 +++++++++++++++ layout/reftests/css-animations/reftest.list | 5 +++ ...nimation-on-marker-pseudo-element-ref.html | 15 +++++++ ...ng-animation-on-marker-pseudo-element.html | 42 +++++++++++++++++++ layout/style/AnimationCollection.cpp | 2 + layout/style/AnimationCommon.h | 6 ++- layout/style/GeckoBindings.cpp | 5 +++ layout/style/ServoStyleSet.cpp | 5 +++ layout/style/nsAnimationManager.h | 3 ++ layout/style/nsCSSPseudoElements.cpp | 2 + layout/style/nsComputedDOMStyle.cpp | 4 ++ layout/style/nsTransitionManager.h | 3 ++ .../animationevent-marker-pseudoelement.html | 35 ++++++++++++++++ .../interfaces/Animatable/animate.html | 14 +++++++ .../tests/web-animations/testcommon.js | 3 ++ xpcom/ds/StaticAtoms.py | 4 ++ 31 files changed, 377 insertions(+), 27 deletions(-) create mode 100644 layout/reftests/css-animations/content-on-marker-pseudo-element-at-beginning-ref.html create mode 100644 layout/reftests/css-animations/content-on-marker-pseudo-element-at-beginning.html create mode 100644 layout/reftests/css-animations/content-on-marker-pseudo-element-at-half.html create mode 100644 layout/reftests/css-animations/in-visibility-hidden-animation-marker-pseudo-element-ref.html create mode 100644 layout/reftests/css-animations/in-visibility-hidden-animation-marker-pseudo-element.html create mode 100644 layout/reftests/css-animations/marker-reframe-and-animation-starts-at-the-same-time-ref.html create mode 100644 layout/reftests/css-animations/marker-reframe-and-animation-starts-at-the-same-time.html create mode 100644 layout/reftests/css-animations/updating-animation-on-marker-pseudo-element-ref.html create mode 100644 layout/reftests/css-animations/updating-animation-on-marker-pseudo-element.html create mode 100644 testing/web-platform/tests/css/css-animations/animationevent-marker-pseudoelement.html diff --git a/dom/animation/CSSPseudoElement.cpp b/dom/animation/CSSPseudoElement.cpp index 01246a24aa8f..802fa72fcb3d 100644 --- a/dom/animation/CSSPseudoElement.cpp +++ b/dom/animation/CSSPseudoElement.cpp @@ -23,7 +23,9 @@ CSSPseudoElement::CSSPseudoElement(dom::Element* aElement, : mOriginatingElement(aElement), mPseudoType(aType) { MOZ_ASSERT(aElement); MOZ_ASSERT( - aType == PseudoStyleType::after || aType == PseudoStyleType::before, + aType == PseudoStyleType::after || + aType == PseudoStyleType::before || + aType == PseudoStyleType::marker, "Unexpected Pseudo Type"); } @@ -106,10 +108,13 @@ nsAtom* CSSPseudoElement::GetCSSPseudoElementPropertyAtom( case PseudoStyleType::after: return nsGkAtoms::cssPseudoElementAfterProperty; + case PseudoStyleType::marker: + return nsGkAtoms::cssPseudoElementMarkerProperty; + default: MOZ_ASSERT_UNREACHABLE( "Should not try to get CSSPseudoElement " - "other than ::before or ::after"); + "other than ::before, ::after or ::marker"); return nullptr; } } diff --git a/dom/animation/CSSPseudoElement.h b/dom/animation/CSSPseudoElement.h index 5cd7de08bd99..e261d5b1e1bb 100644 --- a/dom/animation/CSSPseudoElement.h +++ b/dom/animation/CSSPseudoElement.h @@ -69,7 +69,7 @@ class CSSPseudoElement final : public nsWrapperCache { dom::Element* aElement, PseudoStyleType aType); private: - // Only ::before and ::after are supported. + // Only ::before, ::after and ::marker are supported. CSSPseudoElement(dom::Element* aElement, PseudoStyleType aType); static nsAtom* GetCSSPseudoElementPropertyAtom(PseudoStyleType aType); diff --git a/dom/animation/EffectCompositor.cpp b/dom/animation/EffectCompositor.cpp index fe2c50462473..9ed4d2285c5d 100644 --- a/dom/animation/EffectCompositor.cpp +++ b/dom/animation/EffectCompositor.cpp @@ -335,18 +335,22 @@ void EffectCompositor::ClearRestyleRequestsFor(Element* aElement) { PseudoStyleType pseudoType = aElement->GetPseudoElementType(); if (pseudoType == PseudoStyleType::NotPseudo) { - PseudoElementHashEntry::KeyType notPseudoKey = {aElement, - PseudoStyleType::NotPseudo}; - PseudoElementHashEntry::KeyType beforePseudoKey = {aElement, - PseudoStyleType::before}; - PseudoElementHashEntry::KeyType afterPseudoKey = {aElement, - PseudoStyleType::after}; + PseudoElementHashEntry::KeyType notPseudoKey = + {aElement, PseudoStyleType::NotPseudo}; + PseudoElementHashEntry::KeyType beforePseudoKey = + {aElement, PseudoStyleType::before}; + PseudoElementHashEntry::KeyType afterPseudoKey = + {aElement, PseudoStyleType::after}; + PseudoElementHashEntry::KeyType markerPseudoKey = + {aElement, PseudoStyleType::marker}; elementsToRestyle.Remove(notPseudoKey); elementsToRestyle.Remove(beforePseudoKey); elementsToRestyle.Remove(afterPseudoKey); + elementsToRestyle.Remove(markerPseudoKey); } else if (pseudoType == PseudoStyleType::before || - pseudoType == PseudoStyleType::after) { + pseudoType == PseudoStyleType::after || + pseudoType == PseudoStyleType::marker) { Element* parentElement = aElement->GetParentElement(); MOZ_ASSERT(parentElement); PseudoElementHashEntry::KeyType key = {parentElement, pseudoType}; @@ -444,9 +448,13 @@ bool EffectCompositor::GetServoAnimationRule( return nsLayoutUtils::GetAfterPseudo(aElement); } + if (aPseudoType == PseudoStyleType::marker) { + return nsLayoutUtils::GetMarkerPseudo(aElement); + } + MOZ_ASSERT_UNREACHABLE( "Should not try to get the element to restyle for " - "a pseudo other that :before or :after"); + "a pseudo other that :before, :after or ::marker"); return nullptr; } @@ -520,7 +528,8 @@ EffectCompositor::GetAnimationElementAndPseudoForFrame(const nsIFrame* aFrame) { if (pseudoType != PseudoStyleType::NotPseudo && pseudoType != PseudoStyleType::before && - pseudoType != PseudoStyleType::after) { + pseudoType != PseudoStyleType::after && + pseudoType != PseudoStyleType::marker) { return result; } @@ -530,7 +539,8 @@ EffectCompositor::GetAnimationElementAndPseudoForFrame(const nsIFrame* aFrame) { } if (pseudoType == PseudoStyleType::before || - pseudoType == PseudoStyleType::after) { + pseudoType == PseudoStyleType::after || + pseudoType == PseudoStyleType::marker) { content = content->GetParent(); if (!content) { return result; @@ -722,7 +732,8 @@ bool EffectCompositor::PreTraverseInSubtree(ServoTraversalFlags aFlags, // of the root element later in this function, but for pseudo elements the // element in mElementsToRestyle is the parent of the pseudo. if (aRoot && (aRoot->IsGeneratedContentContainerForBefore() || - aRoot->IsGeneratedContentContainerForAfter())) { + aRoot->IsGeneratedContentContainerForAfter() || + aRoot->IsGeneratedContentContainerForMarker())) { aRoot = aRoot->GetParentElement(); } @@ -865,7 +876,8 @@ bool EffectCompositor::PreTraverse(dom::Element* aElement, bool found = false; if (aPseudoType != PseudoStyleType::NotPseudo && aPseudoType != PseudoStyleType::before && - aPseudoType != PseudoStyleType::after) { + aPseudoType != PseudoStyleType::after && + aPseudoType != PseudoStyleType::marker) { return found; } diff --git a/dom/animation/EffectCompositor.h b/dom/animation/EffectCompositor.h index 30bec4770e6b..4fd7faaac122 100644 --- a/dom/animation/EffectCompositor.h +++ b/dom/animation/EffectCompositor.h @@ -104,7 +104,7 @@ class EffectCompositor { void PostRestyleForThrottledAnimations(); // Clear all pending restyle requests for the given (pseudo-) element (and its - // ::before and ::after elements if the given element is not pseudo). + // ::before, ::after and ::marker elements if the given element is not pseudo). void ClearRestyleRequestsFor(dom::Element* aElement); // Called when computed style on the specified (pseudo-) element might @@ -203,7 +203,7 @@ class EffectCompositor { // Returns the target element for restyling. // - // If |aPseudoType| is ::after or ::before, returns the generated content + // If |aPseudoType| is ::after, ::before or ::marker, returns the generated content // element of which |aElement| is the parent. If |aPseudoType| is any other // pseudo type (other than PseudoStyleType::NotPseudo) returns nullptr. // Otherwise, returns |aElement|. diff --git a/dom/animation/EffectSet.cpp b/dom/animation/EffectSet.cpp index 296f7a36e945..b1ea674618d1 100644 --- a/dom/animation/EffectSet.cpp +++ b/dom/animation/EffectSet.cpp @@ -150,7 +150,9 @@ nsAtom** EffectSet::GetEffectSetPropertyAtoms() { static nsAtom* effectSetPropertyAtoms[] = { nsGkAtoms::animationEffectsProperty, nsGkAtoms::animationEffectsForBeforeProperty, - nsGkAtoms::animationEffectsForAfterProperty, nullptr}; + nsGkAtoms::animationEffectsForAfterProperty, + nsGkAtoms::animationEffectsForMarkerProperty, + nullptr}; return effectSetPropertyAtoms; } @@ -167,10 +169,13 @@ nsAtom* EffectSet::GetEffectSetPropertyAtom(PseudoStyleType aPseudoType) { case PseudoStyleType::after: return nsGkAtoms::animationEffectsForAfterProperty; + case PseudoStyleType::marker: + return nsGkAtoms::animationEffectsForMarkerProperty; + default: MOZ_ASSERT_UNREACHABLE( "Should not try to get animation effects for " - "a pseudo other that :before or :after"); + "a pseudo other that :before, :after or ::marker"); return nullptr; } } diff --git a/dom/animation/KeyframeEffect.cpp b/dom/animation/KeyframeEffect.cpp index fc7c3eece0eb..fa6ac716fd2c 100644 --- a/dom/animation/KeyframeEffect.cpp +++ b/dom/animation/KeyframeEffect.cpp @@ -942,6 +942,7 @@ void KeyframeEffect::GetTarget( switch (mTarget->mPseudoType) { case PseudoStyleType::before: case PseudoStyleType::after: + case PseudoStyleType::marker: aRv.SetValue().SetAsCSSPseudoElement() = CSSPseudoElement::GetCSSPseudoElement(mTarget->mElement, mTarget->mPseudoType); @@ -1389,6 +1390,8 @@ nsIFrame* KeyframeEffect::GetPrimaryFrame() const { frame = nsLayoutUtils::GetBeforeFrame(mTarget->mElement); } else if (mTarget->mPseudoType == PseudoStyleType::after) { frame = nsLayoutUtils::GetAfterFrame(mTarget->mElement); + } else if (mTarget->mPseudoType == PseudoStyleType::marker) { + frame = nsLayoutUtils::GetMarkerFrame(mTarget->mElement); } else { frame = mTarget->mElement->GetPrimaryFrame(); MOZ_ASSERT(mTarget->mPseudoType == PseudoStyleType::NotPseudo, diff --git a/dom/base/Element.cpp b/dom/base/Element.cpp index 6afa64d3a104..85c50081958e 100644 --- a/dom/base/Element.cpp +++ b/dom/base/Element.cpp @@ -1777,7 +1777,8 @@ nsresult Element::BindToTree(Document* aDocument, nsIContent* aParent, PseudoStyleType pseudoType = GetPseudoElementType(); if ((pseudoType == PseudoStyleType::NotPseudo || pseudoType == PseudoStyleType::before || - pseudoType == PseudoStyleType::after) && + pseudoType == PseudoStyleType::after || + pseudoType == PseudoStyleType::marker) && EffectSet::GetEffectSet(this, pseudoType)) { if (nsPresContext* presContext = aDocument->GetPresContext()) { presContext->EffectCompositor()->RequestRestyle( @@ -1913,9 +1914,11 @@ void Element::UnbindFromTree(bool aDeep, bool aNullParent) { if (MayHaveAnimations()) { DeleteProperty(nsGkAtoms::transitionsOfBeforeProperty); DeleteProperty(nsGkAtoms::transitionsOfAfterProperty); + DeleteProperty(nsGkAtoms::transitionsOfMarkerProperty); DeleteProperty(nsGkAtoms::transitionsProperty); DeleteProperty(nsGkAtoms::animationsOfBeforeProperty); DeleteProperty(nsGkAtoms::animationsOfAfterProperty); + DeleteProperty(nsGkAtoms::animationsOfMarkerProperty); DeleteProperty(nsGkAtoms::animationsProperty); if (document) { if (nsPresContext* presContext = document->GetPresContext()) { @@ -3493,14 +3496,19 @@ void Element::GetAnimations(const AnimationFilter& filter, } else if (IsGeneratedContentContainerForAfter()) { elem = GetParentElement(); pseudoType = PseudoStyleType::after; + } else if (IsGeneratedContentContainerForMarker()) { + elem = GetParentElement(); + pseudoType = PseudoStyleType::marker; } if (!elem) { return; } - if (!filter.mSubtree || pseudoType == PseudoStyleType::before || - pseudoType == PseudoStyleType::after) { + if (!filter.mSubtree || + pseudoType == PseudoStyleType::before || + pseudoType == PseudoStyleType::after || + pseudoType == PseudoStyleType::marker) { GetAnimationsUnsorted(elem, pseudoType, aAnimations); } else { for (nsIContent* node = this; node; node = node->GetNextNode(this)) { @@ -3514,6 +3522,8 @@ void Element::GetAnimations(const AnimationFilter& filter, aAnimations); Element::GetAnimationsUnsorted(element, PseudoStyleType::after, aAnimations); + Element::GetAnimationsUnsorted(element, PseudoStyleType::marker, + aAnimations); } } aAnimations.Sort(AnimationPtrComparator>()); @@ -3525,7 +3535,8 @@ void Element::GetAnimationsUnsorted(Element* aElement, nsTArray>& aAnimations) { MOZ_ASSERT(aPseudoType == PseudoStyleType::NotPseudo || aPseudoType == PseudoStyleType::after || - aPseudoType == PseudoStyleType::before, + aPseudoType == PseudoStyleType::before || + aPseudoType == PseudoStyleType::marker, "Unsupported pseudo type"); MOZ_ASSERT(aElement, "Null element"); diff --git a/layout/base/RestyleManager.cpp b/layout/base/RestyleManager.cpp index d0cdcc39c9f0..74772ad059b9 100644 --- a/layout/base/RestyleManager.cpp +++ b/layout/base/RestyleManager.cpp @@ -1983,6 +1983,7 @@ void RestyleManager::AnimationsWithDestroyedFrame :: StopAnimationsWithoutFrame(mContents, PseudoStyleType::NotPseudo); StopAnimationsWithoutFrame(mBeforeContents, PseudoStyleType::before); StopAnimationsWithoutFrame(mAfterContents, PseudoStyleType::after); + StopAnimationsWithoutFrame(mAfterContents, PseudoStyleType::marker); } void RestyleManager::AnimationsWithDestroyedFrame ::StopAnimationsWithoutFrame( @@ -2004,6 +2005,10 @@ void RestyleManager::AnimationsWithDestroyedFrame ::StopAnimationsWithoutFrame( if (nsLayoutUtils::GetAfterFrame(content)) { continue; } + } else if (aPseudoType == PseudoStyleType::marker) { + if (nsLayoutUtils::GetMarkerFrame(content)) { + continue; + } } dom::Element* element = content->AsElement(); diff --git a/layout/base/RestyleManager.h b/layout/base/RestyleManager.h index f5e8d7039d88..28bba9bdb8f9 100644 --- a/layout/base/RestyleManager.h +++ b/layout/base/RestyleManager.h @@ -263,6 +263,10 @@ class RestyleManager { MOZ_ASSERT(aContent->NodeInfo()->NameAtom() == nsGkAtoms::mozgeneratedcontentafter); mAfterContents.AppendElement(aContent->GetParent()); + } else if (pseudoType == PseudoStyleType::marker) { + MOZ_ASSERT(aContent->NodeInfo()->NameAtom() == + nsGkAtoms::mozgeneratedcontentmarker); + mMarkerContents.AppendElement(aContent->GetParent()); } } @@ -278,12 +282,13 @@ class RestyleManager { // Below three arrays might include elements that have already had their // animations or transitions stopped. // - // mBeforeContents and mAfterContents hold the real element rather than - // the content node for the generated content (which might change during - // a reframe) + // mBeforeContents, mAfterContents and mMarkerContents hold the real element + // rather than the content node for the generated content (which might + // change during a reframe) nsTArray> mContents; nsTArray> mBeforeContents; nsTArray> mAfterContents; + nsTArray> mMarkerContents; }; /** diff --git a/layout/reftests/css-animations/content-on-marker-pseudo-element-at-beginning-ref.html b/layout/reftests/css-animations/content-on-marker-pseudo-element-at-beginning-ref.html new file mode 100644 index 000000000000..fb4a55510afd --- /dev/null +++ b/layout/reftests/css-animations/content-on-marker-pseudo-element-at-beginning-ref.html @@ -0,0 +1,13 @@ + + + +
+ diff --git a/layout/reftests/css-animations/content-on-marker-pseudo-element-at-beginning.html b/layout/reftests/css-animations/content-on-marker-pseudo-element-at-beginning.html new file mode 100644 index 000000000000..76155708df4a --- /dev/null +++ b/layout/reftests/css-animations/content-on-marker-pseudo-element-at-beginning.html @@ -0,0 +1,18 @@ + + + +
+ diff --git a/layout/reftests/css-animations/content-on-marker-pseudo-element-at-half.html b/layout/reftests/css-animations/content-on-marker-pseudo-element-at-half.html new file mode 100644 index 000000000000..0eaffcc6cbbf --- /dev/null +++ b/layout/reftests/css-animations/content-on-marker-pseudo-element-at-half.html @@ -0,0 +1,18 @@ + + + +
+ diff --git a/layout/reftests/css-animations/in-visibility-hidden-animation-marker-pseudo-element-ref.html b/layout/reftests/css-animations/in-visibility-hidden-animation-marker-pseudo-element-ref.html new file mode 100644 index 000000000000..4d08b92e4965 --- /dev/null +++ b/layout/reftests/css-animations/in-visibility-hidden-animation-marker-pseudo-element-ref.html @@ -0,0 +1,20 @@ + + +In visibility hidden color animation on pseudo element + +
color animation on visible psuedo element attached to invisible element
diff --git a/layout/reftests/css-animations/in-visibility-hidden-animation-marker-pseudo-element.html b/layout/reftests/css-animations/in-visibility-hidden-animation-marker-pseudo-element.html new file mode 100644 index 000000000000..8a61cdcaa462 --- /dev/null +++ b/layout/reftests/css-animations/in-visibility-hidden-animation-marker-pseudo-element.html @@ -0,0 +1,39 @@ + + +In visibility hidden color animation on pseudo element + +
color animation on visible pseudo element attached to invisible element
+ diff --git a/layout/reftests/css-animations/marker-reframe-and-animation-starts-at-the-same-time-ref.html b/layout/reftests/css-animations/marker-reframe-and-animation-starts-at-the-same-time-ref.html new file mode 100644 index 000000000000..a71f9e85d27f --- /dev/null +++ b/layout/reftests/css-animations/marker-reframe-and-animation-starts-at-the-same-time-ref.html @@ -0,0 +1,17 @@ + + + +
+ diff --git a/layout/reftests/css-animations/marker-reframe-and-animation-starts-at-the-same-time.html b/layout/reftests/css-animations/marker-reframe-and-animation-starts-at-the-same-time.html new file mode 100644 index 000000000000..42b9ca543deb --- /dev/null +++ b/layout/reftests/css-animations/marker-reframe-and-animation-starts-at-the-same-time.html @@ -0,0 +1,33 @@ + + + +
+ + diff --git a/layout/reftests/css-animations/reftest.list b/layout/reftests/css-animations/reftest.list index 77bdc87e1829..b30c73077238 100644 --- a/layout/reftests/css-animations/reftest.list +++ b/layout/reftests/css-animations/reftest.list @@ -8,6 +8,7 @@ fails != print-no-animations.html print-no-animations-notref.html # reftest harn == animation-on-empty-height-frame.html about:blank == in-visibility-hidden-animation.html in-visibility-hidden-animation-ref.html == in-visibility-hidden-animation-pseudo-element.html in-visibility-hidden-animation-pseudo-element-ref.html +== in-visibility-hidden-animation-marker-pseudo-element.html in-visibility-hidden-animation-marker-pseudo-element-ref.html == partially-out-of-view-animation.html partially-out-of-view-animation-ref.html == animate-display-table-opacity.html animate-display-table-opacity-ref.html # We need to run 100% opacity test case when OMTA is disabled to check that the animation creates a stacking context even if the animation is not running on the compositor @@ -57,9 +58,13 @@ fails-if(layerChecksEnabled) == background-position-important.html background-po == stop-animation-on-discarded-pseudo-element.html about:blank == updating-animation-on-pseudo-element.html updating-animation-on-pseudo-element-ref.html +== updating-animation-on-marker-pseudo-element.html updating-animation-on-marker-pseudo-element-ref.html == content-on-pseudo-element-at-beginning.html content-on-pseudo-element-ref.html == content-on-pseudo-element-at-half.html content-on-pseudo-element-ref.html +== content-on-marker-pseudo-element-at-beginning.html content-on-marker-pseudo-element-at-beginning-ref.html +== content-on-marker-pseudo-element-at-half.html content-on-marker-pseudo-element-at-beginning-ref.html == reframe-and-animation-starts-at-the-same-time.html reframe-and-animation-starts-at-the-same-time-ref.html +== marker-reframe-and-animation-starts-at-the-same-time.html marker-reframe-and-animation-starts-at-the-same-time-ref.html == change-animation-name-to-none-in-rule.html change-animation-name-in-rule-ref.html == change-animation-name-to-other-in-rule.html change-animation-name-in-rule-ref.html == change-animation-name-to-non-existent-in-rule.html change-animation-name-in-rule-ref.html diff --git a/layout/reftests/css-animations/updating-animation-on-marker-pseudo-element-ref.html b/layout/reftests/css-animations/updating-animation-on-marker-pseudo-element-ref.html new file mode 100644 index 000000000000..9eab1517b7ea --- /dev/null +++ b/layout/reftests/css-animations/updating-animation-on-marker-pseudo-element-ref.html @@ -0,0 +1,15 @@ + + + +
+ diff --git a/layout/reftests/css-animations/updating-animation-on-marker-pseudo-element.html b/layout/reftests/css-animations/updating-animation-on-marker-pseudo-element.html new file mode 100644 index 000000000000..fc1d29cd38cd --- /dev/null +++ b/layout/reftests/css-animations/updating-animation-on-marker-pseudo-element.html @@ -0,0 +1,42 @@ + + + +
+ + diff --git a/layout/style/AnimationCollection.cpp b/layout/style/AnimationCollection.cpp index adbdc32463ca..66335887cf21 100644 --- a/layout/style/AnimationCollection.cpp +++ b/layout/style/AnimationCollection.cpp @@ -117,6 +117,8 @@ AnimationCollection::GetPropertyAtomForPseudoType( propName = TraitsType::BeforePropertyAtom(); } else if (aPseudoType == PseudoStyleType::after) { propName = TraitsType::AfterPropertyAtom(); + } else if (aPseudoType == PseudoStyleType::marker) { + propName = TraitsType::MarkerPropertyAtom(); } return propName; diff --git a/layout/style/AnimationCommon.h b/layout/style/AnimationCommon.h index f8ebdf645483..d4e536c1d012 100644 --- a/layout/style/AnimationCommon.h +++ b/layout/style/AnimationCommon.h @@ -47,7 +47,7 @@ class CommonAnimationManager { /** * Stop animations on the element. This method takes the real element * rather than the element for the generated content for animations on - * ::before and ::after. + * ::before, ::after and ::marker. */ void StopAnimationsForElement(dom::Element* aElement, PseudoStyleType aPseudoType) { @@ -123,6 +123,10 @@ class OwningElementRef final { return mTarget.mPseudoType == PseudoStyleType::NotPseudo || (mTarget.mPseudoType == PseudoStyleType::before && + aOther.mTarget.mPseudoType == PseudoStyleType::after) || + (mTarget.mPseudoType == PseudoStyleType::marker && + aOther.mTarget.mPseudoType == PseudoStyleType::before) || + (mTarget.mPseudoType == PseudoStyleType::marker && aOther.mTarget.mPseudoType == PseudoStyleType::after); } diff --git a/layout/style/GeckoBindings.cpp b/layout/style/GeckoBindings.cpp index f732b6fa30d3..d12918d2a745 100644 --- a/layout/style/GeckoBindings.cpp +++ b/layout/style/GeckoBindings.cpp @@ -480,6 +480,11 @@ static PseudoStyleType GetPseudoTypeFromElementForAnimation( return PseudoStyleType::after; } + if (aElementOrPseudo->IsGeneratedContentContainerForMarker()) { + aElementOrPseudo = aElementOrPseudo->GetParent()->AsElement(); + return PseudoStyleType::marker; + } + return PseudoStyleType::NotPseudo; } diff --git a/layout/style/ServoStyleSet.cpp b/layout/style/ServoStyleSet.cpp index cd7005b16406..aa9f577f737c 100644 --- a/layout/style/ServoStyleSet.cpp +++ b/layout/style/ServoStyleSet.cpp @@ -1228,6 +1228,11 @@ already_AddRefed ServoStyleSet::ResolveStyleLazilyInternal( elementForStyleResolution = pseudo; pseudoTypeForStyleResolution = PseudoStyleType::NotPseudo; } + } else if (aPseudoType == PseudoStyleType::marker) { + if (Element* pseudo = nsLayoutUtils::GetMarkerPseudo(aElement)) { + elementForStyleResolution = pseudo; + pseudoTypeForStyleResolution = PseudoStyleType::NotPseudo; + } } RefPtr computedValues = diff --git a/layout/style/nsAnimationManager.h b/layout/style/nsAnimationManager.h index 4f40c79c454f..44cbdae9bd37 100644 --- a/layout/style/nsAnimationManager.h +++ b/layout/style/nsAnimationManager.h @@ -255,6 +255,9 @@ struct AnimationTypeTraits { static nsAtom* AfterPropertyAtom() { return nsGkAtoms::animationsOfAfterProperty; } + static nsAtom* MarkerPropertyAtom() { + return nsGkAtoms::animationsOfMarkerProperty; + } }; } /* namespace mozilla */ diff --git a/layout/style/nsCSSPseudoElements.cpp b/layout/style/nsCSSPseudoElements.cpp index 7adc20630135..ebc5bbb859f0 100644 --- a/layout/style/nsCSSPseudoElements.cpp +++ b/layout/style/nsCSSPseudoElements.cpp @@ -119,6 +119,8 @@ nsString nsCSSPseudoElements::PseudoTypeAsString(Type aPseudoType) { return NS_LITERAL_STRING("::before"); case PseudoStyleType::after: return NS_LITERAL_STRING("::after"); + case PseudoStyleType::marker: + return NS_LITERAL_STRING("::marker"); default: MOZ_ASSERT(aPseudoType == PseudoStyleType::NotPseudo, "Unexpected pseudo type"); diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index 05d05007c937..62a6117f00eb 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -135,6 +135,10 @@ static bool DocumentNeedsRestyle(const Document* aDocument, Element* aElement, if (EffectSet::GetEffectSet(aElement, PseudoStyleType::after)) { return true; } + } else if (aPseudo == nsCSSPseudoElements::marker()) { + if (EffectSet::GetEffectSet(aElement, PseudoStyleType::marker)) { + return true; + } } } diff --git a/layout/style/nsTransitionManager.h b/layout/style/nsTransitionManager.h index ffbdad7986dc..567331dea1f3 100644 --- a/layout/style/nsTransitionManager.h +++ b/layout/style/nsTransitionManager.h @@ -276,6 +276,9 @@ struct AnimationTypeTraits { static nsAtom* AfterPropertyAtom() { return nsGkAtoms::transitionsOfAfterProperty; } + static nsAtom* MarkerPropertyAtom() { + return nsGkAtoms::transitionsOfMarkerProperty; + } }; } // namespace mozilla diff --git a/testing/web-platform/tests/css/css-animations/animationevent-marker-pseudoelement.html b/testing/web-platform/tests/css/css-animations/animationevent-marker-pseudoelement.html new file mode 100644 index 000000000000..90c7b86ab9d7 --- /dev/null +++ b/testing/web-platform/tests/css/css-animations/animationevent-marker-pseudoelement.html @@ -0,0 +1,35 @@ + + +CSS Animations Test: AnimationEvent pseudoElement + + + + + +
+ + diff --git a/testing/web-platform/tests/web-animations/interfaces/Animatable/animate.html b/testing/web-platform/tests/web-animations/interfaces/Animatable/animate.html index b7c590e67a03..fcf753baef30 100644 --- a/testing/web-platform/tests/web-animations/interfaces/Animatable/animate.html +++ b/testing/web-platform/tests/web-animations/interfaces/Animatable/animate.html @@ -243,6 +243,12 @@ test(t => { assert_class_string(anim, 'Animation', 'The returned object is an Animation'); }, 'CSSPseudoElement.animate() creates an Animation object'); +test(t => { + const pseudoTarget = getPseudoElement(t, 'marker'); + const anim = pseudoTarget.animate(null); + assert_class_string(anim, 'Animation', 'The returned object is an Animation for ::marker'); +}, 'CSSPseudoElement.animate() creates an Animation object for ::marker'); + test(t => { const pseudoTarget = getPseudoElement(t, 'before'); const anim = pseudoTarget.animate(null); @@ -250,5 +256,13 @@ test(t => { 'The returned Animation targets to the correct object'); }, 'CSSPseudoElement.animate() creates an Animation object targeting ' + 'to the correct CSSPseudoElement object'); + +test(t => { + const pseudoTarget = getPseudoElement(t, 'marker'); + const anim = pseudoTarget.animate(null); + assert_equals(anim.effect.target, pseudoTarget, + 'The returned Animation targets to the correct object for ::marker'); +}, 'CSSPseudoElement.animate() creates an Animation object targeting ' + + 'to the correct CSSPseudoElement object for ::marker'); diff --git a/testing/web-platform/tests/web-animations/testcommon.js b/testing/web-platform/tests/web-animations/testcommon.js index 889cab8bd31e..82b705323214 100644 --- a/testing/web-platform/tests/web-animations/testcommon.js +++ b/testing/web-platform/tests/web-animations/testcommon.js @@ -93,6 +93,9 @@ function getPseudoElement(test, type) { [`.pseudo::${type}`]: 'animation: anim 10s; ' + 'content: \'\';' }); const div = createDiv(test); + if (type == 'marker') { + div.style.display = 'list-item'; + } div.classList.add('pseudo'); const anims = document.getAnimations(); assert_true(anims.length >= 1); diff --git a/xpcom/ds/StaticAtoms.py b/xpcom/ds/StaticAtoms.py index d2ae5b098d6d..4865842f7975 100644 --- a/xpcom/ds/StaticAtoms.py +++ b/xpcom/ds/StaticAtoms.py @@ -2049,15 +2049,19 @@ STATIC_ATOMS = [ Atom("animationsProperty", "AnimationsProperty"), # FrameAnimations* Atom("animationsOfBeforeProperty", "AnimationsOfBeforeProperty"), # FrameAnimations* Atom("animationsOfAfterProperty", "AnimationsOfAfterProperty"), # FrameAnimations* + Atom("animationsOfMarkerProperty", "AnimationsOfMarkerProperty"), # FrameAnimations* Atom("animationEffectsProperty", "AnimationEffectsProperty"), # EffectSet* Atom("animationEffectsForBeforeProperty", "AnimationsEffectsForBeforeProperty"), # EffectSet* Atom("animationEffectsForAfterProperty", "AnimationsEffectsForAfterProperty"), # EffectSet* + Atom("animationEffectsForMarkerProperty", "AnimationsEffectsForMarkerProperty"), # EffectSet* Atom("beforePseudoProperty", "beforePseudoProperty"), # nsXMLElement* Atom("cssPseudoElementBeforeProperty", "CSSPseudoElementBeforeProperty"), # CSSPseudoElement* Atom("cssPseudoElementAfterProperty", "CSSPseudoElementAfterProperty"), # CSSPseudoElement* + Atom("cssPseudoElementMarkerProperty", "CSSPseudoElementMarkerProperty"), # CSSPseudoElement* Atom("transitionsProperty", "TransitionsProperty"), # FrameTransitions* Atom("transitionsOfBeforeProperty", "TransitionsOfBeforeProperty"), # FrameTransitions* Atom("transitionsOfAfterProperty", "TransitionsOfAfterProperty"), # FrameTransitions* + Atom("transitionsOfMarkerProperty", "TransitionsOfMarkerProperty"), # FrameTransitions* Atom("genConInitializerProperty", "QuoteNodeProperty"), Atom("labelMouseDownPtProperty", "LabelMouseDownPtProperty"), Atom("lockedStyleStates", "lockedStyleStates"), From 21ec7510bf4f9d4ba4f83fe5de74f662cda8f3db Mon Sep 17 00:00:00 2001 From: Jan Varga Date: Tue, 26 Mar 2019 18:31:16 +0100 Subject: [PATCH 2/2] Bug 1533651 - Clear LocalStorage and SessionStorage in nsGlobalWindowInner::FreeInnerObjects; r=asuth Differential Revision: https://phabricator.services.mozilla.com/D24934 --- dom/base/nsGlobalWindowInner.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dom/base/nsGlobalWindowInner.cpp b/dom/base/nsGlobalWindowInner.cpp index 651ee7f9d4f5..5d4d113d434f 100644 --- a/dom/base/nsGlobalWindowInner.cpp +++ b/dom/base/nsGlobalWindowInner.cpp @@ -1230,6 +1230,8 @@ void nsGlobalWindowInner::FreeInnerObjects() { mExternal = nullptr; mInstallTrigger = nullptr; + mLocalStorage = nullptr; + mSessionStorage = nullptr; mPerformance = nullptr; mSharedWorkers.Clear();