⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 267571 in webkit


Ignore:
Timestamp:
Sep 25, 2020, 8:22:00 AM (6 years ago)
Author:
graouts@webkit.org
Message:

Reduce the reliance on PseudoElement in the animation code
https://bugs.webkit.org/show_bug.cgi?id=216931
LayoutTests/imported/w3c:

Reviewed by Antti Koivisto.

Mark a WPT test progression.

  • web-platform-tests/css/css-transitions/non-rendered-element-002-expected.txt:

Source/WebCore:

<rdar://problem/69511682>

Reviewed by Antti Koivisto.

We have so far relied on PseudoElement as a foundation for supporting animations of pseudo-elements. This is not a
great choice since PseudoElement is currently limited to ::before and ::after pseudo-elements only. This patch
refactors animation-related code to rely on PseudoElement as little as possible without making changes outside
of the animation code, as a first step towards supporting animation of more pseudo-elements.

This patch introduces a new struct Styleable which combines an Element& and PseudoId. We use this struct instead
of Element objects wherever necessary in the animation code. On top of that, we add a PseudoId parameter to all the
Element methods wrapping access to ElementAnimationRareData and use a HashMap<PseudoId, std::unique_ptr<ElementAnimationRareData>>
to be able to separate animation data per pseudo-element.

  • Headers.cmake:
  • WebCore.xcodeproj/project.pbxproj:
  • animation/AnimationTimeline.cpp:

(WebCore::AnimationTimeline::removeAnimation):
(WebCore::AnimationTimeline::animationWasAddedToStyleable):
(WebCore::AnimationTimeline::animationWasRemovedFromStyleable):
(WebCore::AnimationTimeline::removeDeclarativeAnimationFromListsForOwningElement):
(WebCore::AnimationTimeline::removeCSSAnimationCreatedByMarkup):
(WebCore::AnimationTimeline::elementWasRemoved):
(WebCore::AnimationTimeline::willChangeRendererForStyleable):
(WebCore::AnimationTimeline::cancelDeclarativeAnimationsForStyleable):
(WebCore::shouldConsiderAnimation):
(WebCore::AnimationTimeline::updateCSSAnimationsForStyleable):
(WebCore::keyframeEffectForElementAndProperty):
(WebCore::AnimationTimeline::updateCSSTransitionsForStyleableAndProperty):
(WebCore::AnimationTimeline::updateCSSTransitionsForStyleable):
(WebCore::AnimationTimeline::animationWasAddedToElement): Deleted.
(WebCore::AnimationTimeline::animationWasRemovedFromElement): Deleted.
(WebCore::AnimationTimeline::willChangeRendererForElement): Deleted.
(WebCore::AnimationTimeline::cancelDeclarativeAnimationsForElement): Deleted.
(WebCore::AnimationTimeline::updateCSSAnimationsForElement): Deleted.
(WebCore::AnimationTimeline::updateCSSTransitionsForElementAndProperty): Deleted.
(WebCore::AnimationTimeline::updateCSSTransitionsForElement): Deleted.

  • animation/AnimationTimeline.h:
  • animation/CSSAnimation.cpp:

(WebCore::CSSAnimation::create):
(WebCore::CSSAnimation::CSSAnimation):

  • animation/CSSAnimation.h:
  • animation/CSSTransition.cpp:

(WebCore::CSSTransition::create):
(WebCore::CSSTransition::CSSTransition):

  • animation/CSSTransition.h:
  • animation/DeclarativeAnimation.cpp:

(WebCore::DeclarativeAnimation::DeclarativeAnimation):
(WebCore::DeclarativeAnimation::owningElement const):
(WebCore::DeclarativeAnimation::disassociateFromOwningElement):
(WebCore::DeclarativeAnimation::initialize):
(WebCore::DeclarativeAnimation::enqueueDOMEvent):

  • animation/DeclarativeAnimation.h:
  • animation/DocumentTimeline.cpp:

(WebCore::DocumentTimeline::animationCanBeRemoved):
(WebCore::DocumentTimeline::transitionDidComplete):
(WebCore::DocumentTimeline::computeExtentOfAnimation const):
(WebCore::DocumentTimeline::isRunningAnimationOnRenderer const):
(WebCore::DocumentTimeline::isRunningAcceleratedAnimationOnRenderer const):
(WebCore::DocumentTimeline::animatedStyleForRenderer):
(WebCore::DocumentTimeline::runningAnimationsForRendererAreAllAccelerated const):
(WebCore::DocumentTimeline::runningAnimationsForElementAreAllAccelerated const): Deleted.

  • animation/DocumentTimeline.h:
  • animation/ElementAnimationRareData.cpp:

(WebCore::ElementAnimationRareData::ElementAnimationRareData):

  • animation/ElementAnimationRareData.h:

(WebCore::ElementAnimationRareData::pseudoId const):

  • animation/KeyframeEffect.cpp:

(WebCore::elementOrPseudoElementForStyleable):
(WebCore::invalidateElement):
(WebCore::KeyframeEffect::animationTimelineDidChange):
(WebCore::KeyframeEffect::updateEffectStackMembership):
(WebCore::KeyframeEffect::targetStyleable const):
(WebCore::KeyframeEffect::setTarget):
(WebCore::KeyframeEffect::setPseudoElement):
(WebCore::KeyframeEffect::didChangeTargetStyleable):
(WebCore::KeyframeEffect::invalidate):
(WebCore::KeyframeEffect::applyPendingAcceleratedActions):
(WebCore::KeyframeEffect::didChangeTargetElementOrPseudoElement): Deleted.

  • animation/KeyframeEffect.h:
  • animation/KeyframeEffectStack.cpp:

(WebCore::KeyframeEffectStack::addEffect):

  • animation/WebAnimation.cpp:

(WebCore::WebAnimation::setEffectInternal):
(WebCore::WebAnimation::setTimeline):
(WebCore::WebAnimation::effectTargetDidChange):
(WebCore::WebAnimation::persist):
(WebCore::WebAnimation::commitStyles):

  • animation/WebAnimation.h:
  • animation/WebAnimationUtilities.cpp:

(WebCore::compareDeclarativeAnimationOwningElementPositionsInDocumentTreeOrder):
(WebCore::compareCSSTransitions):
(WebCore::compareCSSAnimations):

  • dom/Element.cpp:

(WebCore::Element::removedFromAncestor):
(WebCore::Element::animationRareData const):
(WebCore::Element::ensureAnimationRareData):
(WebCore::Element::keyframeEffectStack const):
(WebCore::Element::ensureKeyframeEffectStack):
(WebCore::Element::hasKeyframeEffects const):
(WebCore::Element::applyKeyframeEffects):
(WebCore::Element::animations const):
(WebCore::Element::hasCompletedTransitionsForProperty const):
(WebCore::Element::hasRunningTransitionsForProperty const):
(WebCore::Element::hasRunningTransitions const):
(WebCore::Element::ensureAnimations):
(WebCore::Element::animationsCreatedByMarkup):
(WebCore::Element::setAnimationsCreatedByMarkup):
(WebCore::Element::ensureCompletedTransitionsByProperty):
(WebCore::Element::ensureRunningTransitionsByProperty):
(WebCore::Element::lastStyleChangeEventStyle const):
(WebCore::Element::setLastStyleChangeEventStyle):
(WebCore::Element::getAnimations):

  • dom/Element.h:
  • dom/ElementRareData.cpp:
  • dom/ElementRareData.h:

(WebCore::ElementRareData::useTypes const):
(WebCore::ElementRareData::animationRareData const):
(WebCore::ElementRareData::ensureAnimationRareData):
(WebCore::ElementRareData::elementAnimationRareData): Deleted.

  • dom/PseudoElement.cpp:

(WebCore::PseudoElement::clearHostElement):
(WebCore::PseudoElement::isTargetedByKeyframeEffectRequiringPseudoElement):

  • rendering/RenderBoxModelObject.cpp:

(WebCore::RenderBoxModelObject::hasRunningAcceleratedAnimations const):

  • rendering/RenderLayerCompositor.cpp:

(WebCore::RenderLayerCompositor::requiresCompositingForAnimation const):
(WebCore::RenderLayerCompositor::isRunningTransformAnimation const):

  • rendering/style/RenderStyleConstants.cpp:

(WebCore::operator<<):

  • rendering/updating/RenderTreeUpdater.cpp:

(WebCore::RenderTreeUpdater::tearDownRenderers):

  • style/StyleTreeResolver.cpp:

(WebCore::Style::TreeResolver::resolveElement):
(WebCore::Style::TreeResolver::resolvePseudoStyle):
(WebCore::Style::TreeResolver::createAnimatedElementUpdate):

  • style/StyleTreeResolver.h:
  • style/Styleable.h: Added.

(WebCore::Styleable::Styleable):
(WebCore::Styleable::fromElement):
(WebCore::Styleable::fromRenderer):
(WebCore::Styleable::operator== const):
(WebCore::Styleable::operator!= const):
(WebCore::Styleable::keyframeEffectStack const):
(WebCore::Styleable::ensureKeyframeEffectStack const):
(WebCore::Styleable::hasKeyframeEffects const):
(WebCore::Styleable::applyKeyframeEffects const):
(WebCore::Styleable::animations const):
(WebCore::Styleable::hasCompletedTransitionsForProperty const):
(WebCore::Styleable::hasRunningTransitionsForProperty const):
(WebCore::Styleable::hasRunningTransitions const):
(WebCore::Styleable::ensureAnimations const):
(WebCore::Styleable::ensureCompletedTransitionsByProperty const):
(WebCore::Styleable::ensureRunningTransitionsByProperty const):
(WebCore::Styleable::animationsCreatedByMarkup const):
(WebCore::Styleable::setAnimationsCreatedByMarkup const):
(WebCore::Styleable::lastStyleChangeEventStyle const):
(WebCore::Styleable::setLastStyleChangeEventStyle const):

LayoutTests:

<rdar://problem/69511682>

Reviewed by Antti Koivisto.

Update a couple of tests which relied on an internals method to get a pseudo element and instead use
the Web Animations API to determine whether a given animation targets a pseudo-element. This has the
added benefit of having the same code run in a testing environment as in a regular browser.

  • fast/css-generated-content/pseudo-animation.html:
  • fast/css-generated-content/pseudo-transition.html:
Location:
trunk
Files:
1 added
37 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r267564 r267571  
     12020-09-25  Antoine Quint  <graouts@webkit.org>
     2
     3        Reduce the reliance on PseudoElement in the animation code
     4        https://bugs.webkit.org/show_bug.cgi?id=216931
     5        <rdar://problem/69511682>
     6
     7        Reviewed by Antti Koivisto.
     8
     9        Update a couple of tests which relied on an internals method to get a pseudo element and instead use
     10        the Web Animations API to determine whether a given animation targets a pseudo-element. This has the
     11        added benefit of having the same code run in a testing environment as in a regular browser.
     12
     13        * fast/css-generated-content/pseudo-animation.html:
     14        * fast/css-generated-content/pseudo-transition.html:
     15
    1162020-09-25  Alexey Shvayka  <shvaikalesh@gmail.com>
    217
  • trunk/LayoutTests/fast/css-generated-content/pseudo-animation.html

    r236541 r267571  
    7979// below and it no longer needs shouldBeCloseTo.
    8080
    81 function pauseAnimationAtTimeOnPseudoElement(animationName, time, element, pseudoId)
     81function pauseAnimationAtTimeOnPseudoElement(animationName, time, element, pseudoElement)
    8282{
    83     const pseudoElement = internals.pseudoElement(element, pseudoId);
    84     if (!pseudoElement) {
    85         console.log("Failed to find pseudo element");
    86         return;
    87     }
    88 
    89     const animations = pseudoElement.getAnimations();
    90     for (let animation of animations) {
    91         if (animation instanceof CSSAnimation && animation.animationName == animationName && animation.effect.getKeyframes().length) {
     83    for (let animation of element.getAnimations({ subtree: true })) {
     84        if (animation instanceof CSSAnimation && animation.animationName == animationName && animation.effect.target == element && animation.effect.pseudoElement == pseudoElement) {
    9285            animation.currentTime = time * 1000;
    9386            animation.pause();
     
    10093function testAnimation(id)
    10194{
     95    const pseudoElement = `::${id}`;
    10296    var div = document.getElementById(id);
    10397    div.className = 'animate';
    10498    window.div = div;
    10599    shouldBe('div.offsetWidth', '52');
    106     if (window.internals) {
    107         pauseAnimationAtTimeOnPseudoElement('example', 1.0, div, id);
    108         shouldBeCloseTo('div.offsetWidth', 20, 1);
    109         computedTop = getPseudoComputedTop(id);
    110         shouldBeCloseTo('computedTop', 170, 1);
    111         pauseAnimationAtTimeOnPseudoElement('example', 2.0, div, id);
    112         shouldBeCloseTo('div.offsetWidth', 12, 1);
    113         computedTop = getPseudoComputedTop(id);
    114         shouldBeCloseTo('computedTop', 200, 1);
    115     } else {
    116         // This will be flaky, but it's a reasonable approximation for testing
    117         // in a browser instead of DRT.
    118         setTimeout(function() {
    119             window.div = div;
    120             shouldBeCloseTo('div.offsetWidth', 20, 1);
    121             computedTop = getPseudoComputedTop(id);
    122             shouldBeCloseTo('computedTop', 170, 1);
    123         }, 1000);
    124         setTimeout(function() {
    125             window.div = div;
    126             shouldBeCloseTo('div.offsetWidth', 12, 1);
    127             computedTop = getPseudoComputedTop(id);
    128             shouldBeCloseTo('computedTop', 200, 1);
    129         }, 2000);
    130     }
     100
     101    pauseAnimationAtTimeOnPseudoElement('example', 1.0, div, pseudoElement);
     102    shouldBeCloseTo('div.offsetWidth', 20, 1);
     103    computedTop = getPseudoComputedTop(id);
     104    shouldBeCloseTo('computedTop', 170, 1);
     105    pauseAnimationAtTimeOnPseudoElement('example', 2.0, div, pseudoElement);
     106    shouldBeCloseTo('div.offsetWidth', 12, 1);
     107    computedTop = getPseudoComputedTop(id);
     108    shouldBeCloseTo('computedTop', 200, 1);
    131109}
    132110
  • trunk/LayoutTests/fast/css-generated-content/pseudo-transition.html

    r236541 r267571  
    5757const propertiesRequiringPrefix = ["-webkit-text-stroke-color", "-webkit-text-fill-color"];
    5858
    59 function pauseTransitionAtTimeOnPseudoElement(transitionProperty, time, element, pseudoId)
     59function pauseTransitionAtTimeOnPseudoElement(transitionProperty, time, element, pseudoElement)
    6060{
    61     const pseudoElement = internals.pseudoElement(element, pseudoId);
    62     if (!pseudoElement) {
    63         console.log("Failed to find pseudo element");
    64         return;
    65     }
    66 
    6761    if (transitionProperty.startsWith(prefix) && !propertiesRequiringPrefix.includes(transitionProperty))
    6862        transitionProperty = transitionProperty.substr(prefix.length);
    6963
    70     // Otherwise, use the Web Animations API.
    71     const animations = pseudoElement.getAnimations();
    72     for (let animation of animations) {
    73         if (animation instanceof CSSTransition && animation.transitionProperty == transitionProperty) {
     64    for (let animation of element.getAnimations({ subtree: true })) {
     65        if (animation instanceof CSSTransition && animation.transitionProperty == transitionProperty && animation.effect.target == element && animation.effect.pseudoElement == pseudoElement) {
    7466            animation.currentTime = time * 1000;
    7567            animation.pause();
     
    7769        }
    7870    }
     71
    7972    console.log(`A transition for property ${transitionProperty} could not be found`);
    8073    return false;
     
    8376function testTransition(id)
    8477{
     78    const pseudoElement = `::${id}`;
    8579    var div = document.getElementById(id);
    8680    div.className = 'transition';
    8781    window.div = div;
    8882    shouldBe('div.offsetWidth', '52');
    89     if (window.internals) {
    90         pauseTransitionAtTimeOnPseudoElement('width', 1.0, div, id);
    91         shouldBeCloseTo('div.offsetWidth', 20, 1);
    92         pauseTransitionAtTimeOnPseudoElement('top', 1.0, div, id);
    93         computedTop = getPseudoComputedTop(id);
    94         shouldBeCloseTo('computedTop', 170, 1);
    95         pauseTransitionAtTimeOnPseudoElement('width', 2.0, div, id);
    96         shouldBeCloseTo('div.offsetWidth', 12, 1);
    97         pauseTransitionAtTimeOnPseudoElement('top', 2.0, div, id);
    98         computedTop = getPseudoComputedTop(id);
    99         shouldBeCloseTo('computedTop', 200, 1);
    100     } else {
    101         // This will be flaky, but it's a reasonable approximation for testing
    102         // in a browser instead of DRT.
    103         setTimeout(function() {
    104             window.div = div;
    105             shouldBeCloseTo('div.offsetWidth', 20, 1);
    106             computedTop = getPseudoComputedTop(id);
    107             shouldBeCloseTo('computedTop', 170, 1);
    108         }, 1000);
    109         setTimeout(function() {
    110             window.div = div;
    111             shouldBeCloseTo('div.offsetWidth', 12, 1);
    112             computedTop = getPseudoComputedTop(id);
    113             shouldBeCloseTo('computedTop', 200, 1);
    114         }, 2000);
    115     }
     83
     84    pauseTransitionAtTimeOnPseudoElement('width', 1.0, div, pseudoElement);
     85    shouldBeCloseTo('div.offsetWidth', 20, 1);
     86    pauseTransitionAtTimeOnPseudoElement('top', 1.0, div, pseudoElement);
     87    computedTop = getPseudoComputedTop(id);
     88    shouldBeCloseTo('computedTop', 170, 1);
     89    pauseTransitionAtTimeOnPseudoElement('width', 2.0, div, pseudoElement);
     90    shouldBeCloseTo('div.offsetWidth', 12, 1);
     91    pauseTransitionAtTimeOnPseudoElement('top', 2.0, div, pseudoElement);
     92    computedTop = getPseudoComputedTop(id);
     93    shouldBeCloseTo('computedTop', 200, 1);
    11694}
    11795
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r267570 r267571  
     12020-09-25  Antoine Quint  <graouts@webkit.org>
     2
     3        Reduce the reliance on PseudoElement in the animation code
     4        https://bugs.webkit.org/show_bug.cgi?id=216931
     5
     6        Reviewed by Antti Koivisto.
     7
     8        Mark a WPT test progression.
     9
     10        * web-platform-tests/css/css-transitions/non-rendered-element-002-expected.txt:
     11
    1122020-09-25  Antoine Quint  <graouts@webkit.org>
    213
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/non-rendered-element-002-expected.txt

    r264522 r267571  
    11
    2 Harness Error (TIMEOUT), message = null
     2PASS Transitions on ::before/::after pseudo-elements are canceled when the content property is cleared
    33
    4 TIMEOUT Transitions on ::before/::after pseudo-elements are canceled when the content property is cleared Test timed out
    5 
  • trunk/Source/WebCore/ChangeLog

    r267566 r267571  
     12020-09-25  Antoine Quint  <graouts@webkit.org>
     2
     3        Reduce the reliance on PseudoElement in the animation code
     4        https://bugs.webkit.org/show_bug.cgi?id=216931
     5        <rdar://problem/69511682>
     6
     7        Reviewed by Antti Koivisto.
     8
     9        We have so far relied on PseudoElement as a foundation for supporting animations of pseudo-elements. This is not a
     10        great choice since PseudoElement is currently limited to ::before and ::after pseudo-elements only. This patch
     11        refactors animation-related code to rely on PseudoElement as little as possible without making changes outside
     12        of the animation code, as a first step towards supporting animation of more pseudo-elements.
     13
     14        This patch introduces a new struct Styleable which combines an Element& and PseudoId. We use this struct instead
     15        of Element objects wherever necessary in the animation code. On top of that, we add a PseudoId parameter to all the
     16        Element methods wrapping access to ElementAnimationRareData and use a HashMap<PseudoId, std::unique_ptr<ElementAnimationRareData>>
     17        to be able to separate animation data per pseudo-element.
     18
     19        * Headers.cmake:
     20        * WebCore.xcodeproj/project.pbxproj:
     21        * animation/AnimationTimeline.cpp:
     22        (WebCore::AnimationTimeline::removeAnimation):
     23        (WebCore::AnimationTimeline::animationWasAddedToStyleable):
     24        (WebCore::AnimationTimeline::animationWasRemovedFromStyleable):
     25        (WebCore::AnimationTimeline::removeDeclarativeAnimationFromListsForOwningElement):
     26        (WebCore::AnimationTimeline::removeCSSAnimationCreatedByMarkup):
     27        (WebCore::AnimationTimeline::elementWasRemoved):
     28        (WebCore::AnimationTimeline::willChangeRendererForStyleable):
     29        (WebCore::AnimationTimeline::cancelDeclarativeAnimationsForStyleable):
     30        (WebCore::shouldConsiderAnimation):
     31        (WebCore::AnimationTimeline::updateCSSAnimationsForStyleable):
     32        (WebCore::keyframeEffectForElementAndProperty):
     33        (WebCore::AnimationTimeline::updateCSSTransitionsForStyleableAndProperty):
     34        (WebCore::AnimationTimeline::updateCSSTransitionsForStyleable):
     35        (WebCore::AnimationTimeline::animationWasAddedToElement): Deleted.
     36        (WebCore::AnimationTimeline::animationWasRemovedFromElement): Deleted.
     37        (WebCore::AnimationTimeline::willChangeRendererForElement): Deleted.
     38        (WebCore::AnimationTimeline::cancelDeclarativeAnimationsForElement): Deleted.
     39        (WebCore::AnimationTimeline::updateCSSAnimationsForElement): Deleted.
     40        (WebCore::AnimationTimeline::updateCSSTransitionsForElementAndProperty): Deleted.
     41        (WebCore::AnimationTimeline::updateCSSTransitionsForElement): Deleted.
     42        * animation/AnimationTimeline.h:
     43        * animation/CSSAnimation.cpp:
     44        (WebCore::CSSAnimation::create):
     45        (WebCore::CSSAnimation::CSSAnimation):
     46        * animation/CSSAnimation.h:
     47        * animation/CSSTransition.cpp:
     48        (WebCore::CSSTransition::create):
     49        (WebCore::CSSTransition::CSSTransition):
     50        * animation/CSSTransition.h:
     51        * animation/DeclarativeAnimation.cpp:
     52        (WebCore::DeclarativeAnimation::DeclarativeAnimation):
     53        (WebCore::DeclarativeAnimation::owningElement const):
     54        (WebCore::DeclarativeAnimation::disassociateFromOwningElement):
     55        (WebCore::DeclarativeAnimation::initialize):
     56        (WebCore::DeclarativeAnimation::enqueueDOMEvent):
     57        * animation/DeclarativeAnimation.h:
     58        * animation/DocumentTimeline.cpp:
     59        (WebCore::DocumentTimeline::animationCanBeRemoved):
     60        (WebCore::DocumentTimeline::transitionDidComplete):
     61        (WebCore::DocumentTimeline::computeExtentOfAnimation const):
     62        (WebCore::DocumentTimeline::isRunningAnimationOnRenderer const):
     63        (WebCore::DocumentTimeline::isRunningAcceleratedAnimationOnRenderer const):
     64        (WebCore::DocumentTimeline::animatedStyleForRenderer):
     65        (WebCore::DocumentTimeline::runningAnimationsForRendererAreAllAccelerated const):
     66        (WebCore::DocumentTimeline::runningAnimationsForElementAreAllAccelerated const): Deleted.
     67        * animation/DocumentTimeline.h:
     68        * animation/ElementAnimationRareData.cpp:
     69        (WebCore::ElementAnimationRareData::ElementAnimationRareData):
     70        * animation/ElementAnimationRareData.h:
     71        (WebCore::ElementAnimationRareData::pseudoId const):
     72        * animation/KeyframeEffect.cpp:
     73        (WebCore::elementOrPseudoElementForStyleable):
     74        (WebCore::invalidateElement):
     75        (WebCore::KeyframeEffect::animationTimelineDidChange):
     76        (WebCore::KeyframeEffect::updateEffectStackMembership):
     77        (WebCore::KeyframeEffect::targetStyleable const):
     78        (WebCore::KeyframeEffect::setTarget):
     79        (WebCore::KeyframeEffect::setPseudoElement):
     80        (WebCore::KeyframeEffect::didChangeTargetStyleable):
     81        (WebCore::KeyframeEffect::invalidate):
     82        (WebCore::KeyframeEffect::applyPendingAcceleratedActions):
     83        (WebCore::KeyframeEffect::didChangeTargetElementOrPseudoElement): Deleted.
     84        * animation/KeyframeEffect.h:
     85        * animation/KeyframeEffectStack.cpp:
     86        (WebCore::KeyframeEffectStack::addEffect):
     87        * animation/WebAnimation.cpp:
     88        (WebCore::WebAnimation::setEffectInternal):
     89        (WebCore::WebAnimation::setTimeline):
     90        (WebCore::WebAnimation::effectTargetDidChange):
     91        (WebCore::WebAnimation::persist):
     92        (WebCore::WebAnimation::commitStyles):
     93        * animation/WebAnimation.h:
     94        * animation/WebAnimationUtilities.cpp:
     95        (WebCore::compareDeclarativeAnimationOwningElementPositionsInDocumentTreeOrder):
     96        (WebCore::compareCSSTransitions):
     97        (WebCore::compareCSSAnimations):
     98        * dom/Element.cpp:
     99        (WebCore::Element::removedFromAncestor):
     100        (WebCore::Element::animationRareData const):
     101        (WebCore::Element::ensureAnimationRareData):
     102        (WebCore::Element::keyframeEffectStack const):
     103        (WebCore::Element::ensureKeyframeEffectStack):
     104        (WebCore::Element::hasKeyframeEffects const):
     105        (WebCore::Element::applyKeyframeEffects):
     106        (WebCore::Element::animations const):
     107        (WebCore::Element::hasCompletedTransitionsForProperty const):
     108        (WebCore::Element::hasRunningTransitionsForProperty const):
     109        (WebCore::Element::hasRunningTransitions const):
     110        (WebCore::Element::ensureAnimations):
     111        (WebCore::Element::animationsCreatedByMarkup):
     112        (WebCore::Element::setAnimationsCreatedByMarkup):
     113        (WebCore::Element::ensureCompletedTransitionsByProperty):
     114        (WebCore::Element::ensureRunningTransitionsByProperty):
     115        (WebCore::Element::lastStyleChangeEventStyle const):
     116        (WebCore::Element::setLastStyleChangeEventStyle):
     117        (WebCore::Element::getAnimations):
     118        * dom/Element.h:
     119        * dom/ElementRareData.cpp:
     120        * dom/ElementRareData.h:
     121        (WebCore::ElementRareData::useTypes const):
     122        (WebCore::ElementRareData::animationRareData const):
     123        (WebCore::ElementRareData::ensureAnimationRareData):
     124        (WebCore::ElementRareData::elementAnimationRareData): Deleted.
     125        * dom/PseudoElement.cpp:
     126        (WebCore::PseudoElement::clearHostElement):
     127        (WebCore::PseudoElement::isTargetedByKeyframeEffectRequiringPseudoElement):
     128        * rendering/RenderBoxModelObject.cpp:
     129        (WebCore::RenderBoxModelObject::hasRunningAcceleratedAnimations const):
     130        * rendering/RenderLayerCompositor.cpp:
     131        (WebCore::RenderLayerCompositor::requiresCompositingForAnimation const):
     132        (WebCore::RenderLayerCompositor::isRunningTransformAnimation const):
     133        * rendering/style/RenderStyleConstants.cpp:
     134        (WebCore::operator<<):
     135        * rendering/updating/RenderTreeUpdater.cpp:
     136        (WebCore::RenderTreeUpdater::tearDownRenderers):
     137        * style/StyleTreeResolver.cpp:
     138        (WebCore::Style::TreeResolver::resolveElement):
     139        (WebCore::Style::TreeResolver::resolvePseudoStyle):
     140        (WebCore::Style::TreeResolver::createAnimatedElementUpdate):
     141        * style/StyleTreeResolver.h:
     142        * style/Styleable.h: Added.
     143        (WebCore::Styleable::Styleable):
     144        (WebCore::Styleable::fromElement):
     145        (WebCore::Styleable::fromRenderer):
     146        (WebCore::Styleable::operator== const):
     147        (WebCore::Styleable::operator!= const):
     148        (WebCore::Styleable::keyframeEffectStack const):
     149        (WebCore::Styleable::ensureKeyframeEffectStack const):
     150        (WebCore::Styleable::hasKeyframeEffects const):
     151        (WebCore::Styleable::applyKeyframeEffects const):
     152        (WebCore::Styleable::animations const):
     153        (WebCore::Styleable::hasCompletedTransitionsForProperty const):
     154        (WebCore::Styleable::hasRunningTransitionsForProperty const):
     155        (WebCore::Styleable::hasRunningTransitions const):
     156        (WebCore::Styleable::ensureAnimations const):
     157        (WebCore::Styleable::ensureCompletedTransitionsByProperty const):
     158        (WebCore::Styleable::ensureRunningTransitionsByProperty const):
     159        (WebCore::Styleable::animationsCreatedByMarkup const):
     160        (WebCore::Styleable::setAnimationsCreatedByMarkup const):
     161        (WebCore::Styleable::lastStyleChangeEventStyle const):
     162        (WebCore::Styleable::setLastStyleChangeEventStyle const):
     163
    11642020-09-25  Youenn Fablet  <youenn@apple.com>
    2165
  • trunk/Source/WebCore/Headers.cmake

    r267565 r267571  
    14951495    style/StyleUpdate.h
    14961496    style/StyleValidity.h
     1497    style/Styleable.h
    14971498
    14981499    svg/SVGLengthContext.h
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r267565 r267571  
    21242124                7132445120109DA500AE7FB2 /* WebAnimationUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 7132444F20109D9B00AE7FB2 /* WebAnimationUtilities.h */; settings = {ATTRIBUTES = (Private, ); }; };
    21252125                7134496E146941B300720312 /* SVGLengthContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 7134496C146941B300720312 /* SVGLengthContext.h */; settings = {ATTRIBUTES = (Private, ); }; };
     2126                713922BE2518AB77005DB3C2 /* Styleable.h in Headers */ = {isa = PBXBuildFile; fileRef = 713922BC2518AB70005DB3C2 /* Styleable.h */; settings = {ATTRIBUTES = (Private, ); }; };
    21262127                713F1D5A23DF1D8D003F5EFA /* GetAnimationsOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 713F1D5923DF1D7D003F5EFA /* GetAnimationsOptions.h */; settings = {ATTRIBUTES = (Private, ); }; };
    21272128                713F1D5D23DF2582003F5EFA /* JSGetAnimationsOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 713F1D5B23DF2560003F5EFA /* JSGetAnimationsOptions.h */; };
     
    97399740                7134496B146941B300720312 /* SVGLengthContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGLengthContext.cpp; sourceTree = "<group>"; };
    97409741                7134496C146941B300720312 /* SVGLengthContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGLengthContext.h; sourceTree = "<group>"; };
     9742                713922BC2518AB70005DB3C2 /* Styleable.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Styleable.h; sourceTree = "<group>"; };
    97419743                713E70AF1733E8B300A22D00 /* plugIns.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; path = plugIns.js; sourceTree = "<group>"; };
    97429744                713F1D5723DF1D7D003F5EFA /* GetAnimationsOptions.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = GetAnimationsOptions.idl; sourceTree = "<group>"; };
     
    2838028382                                A79BAD9F161E7F3F00C2E652 /* RuleSet.cpp */,
    2838128383                                A79BADA0161E7F3F00C2E652 /* RuleSet.h */,
     28384                                713922BC2518AB70005DB3C2 /* Styleable.h */,
    2838228385                                E45BA6B22376227E004DFC07 /* StyleAdjuster.cpp */,
    2838328386                                E45BA6B52376229F004DFC07 /* StyleAdjuster.h */,
     
    3274632749                                6F0B98B523F268EC00EEC2F2 /* LayoutInlineTextBox.h in Headers */,
    3274732750                                E418025523D4549B00FFB071 /* LayoutIntegrationBoxTree.h in Headers */,
     32751                                E403B7A2251B11930019E800 /* LayoutIntegrationCoverage.h in Headers */,
    3274832752                                E4ABABDD236088FE00FA4345 /* LayoutIntegrationLineLayout.h in Headers */,
     32753                                E403B7A3251B11C10019E800 /* LayoutIntegrationPagination.h in Headers */,
    3274932754                                11310CF420BA4A3D0065A8D0 /* LayoutIterator.h in Headers */,
    3275032755                                6FFA4C0123F2FED9007E4EBC /* LayoutLineBreakBox.h in Headers */,
     
    3279132796                                AB31C91E10AE1B8E000C7B92 /* LineClampValue.h in Headers */,
    3279232797                                FFEFAB2A18380DA000514534 /* LineLayoutState.h in Headers */,
    32793                                 E403B7A2251B11930019E800 /* LayoutIntegrationCoverage.h in Headers */,
    3279432798                                E484A33E23055325009ADE6A /* LineLayoutTraversal.h in Headers */,
    3279532799                                E4343D252392779000EBBB66 /* LineLayoutTraversalComplexPath.h in Headers */,
     
    3365933663                                1400D7A817136EA70077CE05 /* ScriptWrappableInlines.h in Headers */,
    3366033664                                BC8AE34F12EA096A00EB3AE6 /* ScrollableArea.h in Headers */,
    33661                                 E403B7A3251B11C10019E800 /* LayoutIntegrationPagination.h in Headers */,
    3366233665                                5D925B680F64D4DD00B847F0 /* ScrollAlignment.h in Headers */,
    3366333666                                CA3BF67E10D99BAE00E6CE53 /* ScrollAnimator.h in Headers */,
     
    3389233895                                849F77760EFEC6200090849D /* StrokeStyleApplier.h in Headers */,
    3389333896                                414B82051D6DF0E50077EBE3 /* StructuredClone.h in Headers */,
     33897                                713922BE2518AB77005DB3C2 /* Styleable.h in Headers */,
    3389433898                                E45BA6B6237622A3004DFC07 /* StyleAdjuster.h in Headers */,
    3389533899                                BC5EB6A30E81DC4F00B25965 /* StyleBackgroundData.h in Headers */,
  • trunk/Source/WebCore/animation/AnimationTimeline.cpp

    r267204 r267571  
    4343#include "StylePropertyShorthand.h"
    4444#include "StyleResolver.h"
     45#include "Styleable.h"
    4546#include "WebAnimationUtilities.h"
    4647#include <wtf/text/TextStream.h>
     
    8182    m_animations.remove(&animation);
    8283    if (is<KeyframeEffect>(animation.effect())) {
    83         if (auto* target = downcast<KeyframeEffect>(animation.effect())->targetElementOrPseudoElement()) {
    84             animationWasRemovedFromElement(animation, *target);
    85             target->ensureKeyframeEffectStack().removeEffect(*downcast<KeyframeEffect>(animation.effect()));
     84        if (auto styleable = downcast<KeyframeEffect>(animation.effect())->targetStyleable()) {
     85            animationWasRemovedFromStyleable(animation, *styleable);
     86            styleable->ensureKeyframeEffectStack().removeEffect(*downcast<KeyframeEffect>(animation.effect()));
    8687        }
    8788    }
     
    9697}
    9798
    98 void AnimationTimeline::animationWasAddedToElement(WebAnimation& animation, Element& element)
    99 {
    100     element.ensureAnimations().add(&animation);
     99void AnimationTimeline::animationWasAddedToStyleable(WebAnimation& animation, const Styleable& styleable)
     100{
     101    styleable.ensureAnimations().add(&animation);
    101102}
    102103
     
    111112}
    112113
    113 void AnimationTimeline::animationWasRemovedFromElement(WebAnimation& animation, Element& element)
    114 {
    115     element.ensureAnimations().remove(&animation);
     114void AnimationTimeline::animationWasRemovedFromStyleable(WebAnimation& animation, const Styleable& styleable)
     115{
     116    styleable.ensureAnimations().remove(&animation);
    116117
    117118    // Now, if we're dealing with a CSS Transition, we remove it from the m_elementToRunningCSSTransitionByCSSPropertyID map.
     
    120121    // to the JS API or changing the target element's animation-name property.
    121122    if (is<CSSTransition>(animation))
    122         removeDeclarativeAnimationFromListsForOwningElement(animation, element);
    123 }
    124 
    125 void AnimationTimeline::removeDeclarativeAnimationFromListsForOwningElement(WebAnimation& animation, Element& element)
     123        removeDeclarativeAnimationFromListsForOwningElement(animation, styleable);
     124}
     125
     126void AnimationTimeline::removeDeclarativeAnimationFromListsForOwningElement(WebAnimation& animation, const Styleable& styleable)
    126127{
    127128    ASSERT(is<DeclarativeAnimation>(animation));
     
    129130    if (is<CSSTransition>(animation)) {
    130131        auto& transition = downcast<CSSTransition>(animation);
    131         if (!removeCSSTransitionFromMap(transition, element.ensureRunningTransitionsByProperty()))
    132             removeCSSTransitionFromMap(transition, element.ensureCompletedTransitionsByProperty());
    133     }
    134 }
    135 
    136 void AnimationTimeline::removeCSSAnimationCreatedByMarkup(Element& element, CSSAnimation& cssAnimation)
    137 {
    138     element.animationsCreatedByMarkup().remove(&cssAnimation);
    139 
    140     if (!element.hasKeyframeEffects())
    141         return;
    142 
    143     auto& keyframeEffectStack = element.ensureKeyframeEffectStack();
     132        if (!removeCSSTransitionFromMap(transition, styleable.ensureRunningTransitionsByProperty()))
     133            removeCSSTransitionFromMap(transition, styleable.ensureCompletedTransitionsByProperty());
     134    }
     135}
     136
     137void AnimationTimeline::removeCSSAnimationCreatedByMarkup(const Styleable& styleable, CSSAnimation& cssAnimation)
     138{
     139    styleable.animationsCreatedByMarkup().remove(&cssAnimation);
     140
     141    if (!styleable.hasKeyframeEffects())
     142        return;
     143
     144    auto& keyframeEffectStack = styleable.ensureKeyframeEffectStack();
    144145    auto* cssAnimationList = keyframeEffectStack.cssAnimationList();
    145146    if (!cssAnimationList || cssAnimationList->isEmpty())
     
    157158}
    158159
    159 void AnimationTimeline::elementWasRemoved(Element& element)
    160 {
    161     cancelDeclarativeAnimationsForElement(element, WebAnimation::Silently::Yes);
    162 }
    163 
    164 void AnimationTimeline::willChangeRendererForElement(Element& element)
    165 {
    166     if (auto* animations = element.animations()) {
     160void AnimationTimeline::elementWasRemoved(const Styleable& styleable)
     161{
     162    cancelDeclarativeAnimationsForStyleable(styleable, WebAnimation::Silently::Yes);
     163}
     164
     165void AnimationTimeline::willChangeRendererForStyleable(const Styleable& styleable)
     166{
     167    if (auto* animations = styleable.animations()) {
    167168        for (const auto& animation : *animations)
    168169            animation->willChangeRenderer();
     
    170171}
    171172
    172 void AnimationTimeline::cancelDeclarativeAnimationsForElement(Element& element, WebAnimation::Silently silently)
    173 {
    174     if (auto* animations = element.animations()) {
     173void AnimationTimeline::cancelDeclarativeAnimationsForStyleable(const Styleable& styleable, WebAnimation::Silently silently)
     174{
     175    if (auto* animations = styleable.animations()) {
    175176        for (auto& animation : *animations) {
    176177            if (is<DeclarativeAnimation>(animation)) {
    177178                if (is<CSSAnimation>(animation))
    178                     removeCSSAnimationCreatedByMarkup(element, downcast<CSSAnimation>(*animation));
     179                    removeCSSAnimationCreatedByMarkup(styleable, downcast<CSSAnimation>(*animation));
    179180                animation->cancel(silently);
    180181            }
     
    183184}
    184185
    185 static bool shouldConsiderAnimation(Element& elementOrPseudoElement, const Animation& animation)
     186static bool shouldConsiderAnimation(Element& element, const Animation& animation)
    186187{
    187188    if (!animation.isValidAnimation())
     
    194195        return false;
    195196
    196     auto& element = is<PseudoElement>(elementOrPseudoElement) ? *downcast<PseudoElement>(elementOrPseudoElement).hostElement() : elementOrPseudoElement;
    197 
    198197    if (auto* styleScope = Style::Scope::forOrdinal(element, animation.nameStyleScopeOrdinal()))
    199198        return styleScope->resolver().isAnimationNameValid(name);
     
    202201}
    203202
    204 void AnimationTimeline::updateCSSAnimationsForElement(Element& element, const RenderStyle* currentStyle, const RenderStyle& newStyle)
    205 {
    206     auto& keyframeEffectStack = element.ensureKeyframeEffectStack();
     203void AnimationTimeline::updateCSSAnimationsForStyleable(const Styleable& styleable, const RenderStyle* currentStyle, const RenderStyle& newStyle)
     204{
     205    auto& keyframeEffectStack = styleable.ensureKeyframeEffectStack();
    207206
    208207    // In case this element is newly getting a "display: none" we need to cancel all of its animations and disregard new ones.
    209208    if (currentStyle && currentStyle->display() != DisplayType::None && newStyle.display() == DisplayType::None) {
    210         for (auto& cssAnimation : element.animationsCreatedByMarkup())
     209        for (auto& cssAnimation : styleable.animationsCreatedByMarkup())
    211210            cssAnimation->cancelFromStyle();
    212211        keyframeEffectStack.setCSSAnimationList(nullptr);
     
    220219
    221220    CSSAnimationCollection newAnimations;
    222     auto& previousAnimations = element.animationsCreatedByMarkup();
     221    auto& previousAnimations = styleable.animationsCreatedByMarkup();
    223222
    224223    // https://www.w3.org/TR/css-animations-1/#animations
     
    234233        for (size_t i = currentAnimationList->size(); i > 0; --i) {
    235234            auto& currentAnimation = currentAnimationList->animation(i - 1);
    236             if (!shouldConsiderAnimation(element, currentAnimation))
     235            if (!shouldConsiderAnimation(styleable.element, currentAnimation))
    237236                continue;
    238237
     
    252251
    253252            if (!foundMatchingAnimation)
    254                 newAnimations.add(CSSAnimation::create(element, currentAnimation, currentStyle, newStyle));
     253                newAnimations.add(CSSAnimation::create(styleable, currentAnimation, currentStyle, newStyle));
    255254        }
    256255    }
     
    264263    }
    265264
    266     element.setAnimationsCreatedByMarkup(WTFMove(newAnimations));
     265    styleable.setAnimationsCreatedByMarkup(WTFMove(newAnimations));
    267266
    268267    keyframeEffectStack.setCSSAnimationList(currentAnimationList);
    269268}
    270269
    271 static KeyframeEffect* keyframeEffectForElementAndProperty(Element& element, CSSPropertyID property)
    272 {
    273     if (auto* keyframeEffectStack = element.keyframeEffectStack()) {
     270static KeyframeEffect* keyframeEffectForElementAndProperty(const Styleable& styleable, CSSPropertyID property)
     271{
     272    if (auto* keyframeEffectStack = styleable.keyframeEffectStack()) {
    274273        auto effects = keyframeEffectStack->sortedEffects();
    275274        for (const auto& effect : makeReversedRange(effects)) {
     
    340339}
    341340
    342 void AnimationTimeline::updateCSSTransitionsForElementAndProperty(Element& element, CSSPropertyID property, const RenderStyle& currentStyle, const RenderStyle& newStyle, const MonotonicTime generationTime)
    343 {
    344     auto* keyframeEffect = keyframeEffectForElementAndProperty(element, property);
     341void AnimationTimeline::updateCSSTransitionsForStyleableAndProperty(const Styleable& styleable, CSSPropertyID property, const RenderStyle& currentStyle, const RenderStyle& newStyle, const MonotonicTime generationTime)
     342{
     343    auto* keyframeEffect = keyframeEffectForElementAndProperty(styleable, property);
    345344    auto* animation = keyframeEffect ? keyframeEffect->animation() : nullptr;
    346     bool isDeclarative = animation && is<DeclarativeAnimation>(animation) && downcast<DeclarativeAnimation>(*animation).owningElement() == &element;
     345
     346    bool isDeclarative = false;
     347    if (is<DeclarativeAnimation>(animation)) {
     348        if (auto owningElement = downcast<DeclarativeAnimation>(*animation).owningElement())
     349            isDeclarative = *owningElement == styleable;
     350    }
     351
    347352    if (animation && !isDeclarative)
    348353        return;
     
    359364    // A CSS Transition might have completed since the last time animations were updated so we must
    360365    // update the running and completed transitions membership in that case.
    361     if (is<CSSTransition>(animation) && matchingBackingAnimation && element.hasRunningTransitionsForProperty(property) && animation->playState() == WebAnimation::PlayState::Finished) {
    362         element.ensureCompletedTransitionsByProperty().set(property, element.ensureRunningTransitionsByProperty().take(property));
     366    if (is<CSSTransition>(animation) && matchingBackingAnimation && styleable.hasRunningTransitionsForProperty(property) && animation->playState() == WebAnimation::PlayState::Finished) {
     367        styleable.ensureCompletedTransitionsByProperty().set(property, styleable.ensureRunningTransitionsByProperty().take(property));
    363368        animation = nullptr;
    364369    }
     
    378383
    379384        // If it exists, use the recorded RenderStyle for this element during a previous call to Style::TreeResolver::createAnimatedElementUpdate().
    380         if (auto* lastStyleChangeEventStyle = element.lastStyleChangeEventStyle())
     385        if (auto* lastStyleChangeEventStyle = styleable.lastStyleChangeEventStyle())
    381386            return RenderStyle::clone(*lastStyleChangeEventStyle);
    382387
     
    400405    }();
    401406
    402     if (!element.hasRunningTransitionsForProperty(property)
     407    if (!styleable.hasRunningTransitionsForProperty(property)
    403408        && !CSSPropertyAnimation::propertiesEqual(property, &beforeChangeStyle, &afterChangeStyle)
    404409        && CSSPropertyAnimation::canPropertyBeInterpolated(property, &beforeChangeStyle, &afterChangeStyle)
    405         && !propertyInStyleMatchesValueForTransitionInMap(property, afterChangeStyle, element.ensureCompletedTransitionsByProperty())
     410        && !propertyInStyleMatchesValueForTransitionInMap(property, afterChangeStyle, styleable.ensureCompletedTransitionsByProperty())
    406411        && matchingBackingAnimation && transitionCombinedDuration(matchingBackingAnimation) > 0) {
    407412        // 1. If all of the following are true:
     
    413418
    414419        // then implementations must remove the completed transition (if present) from the set of completed transitions
    415         element.ensureCompletedTransitionsByProperty().remove(property);
     420        styleable.ensureCompletedTransitionsByProperty().remove(property);
    416421
    417422        // and start a transition whose:
     
    426431        auto& reversingAdjustedStartStyle = beforeChangeStyle;
    427432        auto reversingShorteningFactor = 1;
    428         element.ensureRunningTransitionsByProperty().set(property, CSSTransition::create(element, property, generationTime, *matchingBackingAnimation, &beforeChangeStyle, afterChangeStyle, delay, duration, reversingAdjustedStartStyle, reversingShorteningFactor));
    429     } else if (element.hasCompletedTransitionsForProperty(property) && !propertyInStyleMatchesValueForTransitionInMap(property, afterChangeStyle, element.ensureCompletedTransitionsByProperty())) {
     433        styleable.ensureRunningTransitionsByProperty().set(property, CSSTransition::create(styleable, property, generationTime, *matchingBackingAnimation, &beforeChangeStyle, afterChangeStyle, delay, duration, reversingAdjustedStartStyle, reversingShorteningFactor));
     434    } else if (styleable.hasCompletedTransitionsForProperty(property) && !propertyInStyleMatchesValueForTransitionInMap(property, afterChangeStyle, styleable.ensureCompletedTransitionsByProperty())) {
    430435        // 2. Otherwise, if the element has a completed transition for the property and the end value of the completed transition is different from
    431436        //    the after-change style for the property, then implementations must remove the completed transition from the set of completed transitions.
    432         element.ensureCompletedTransitionsByProperty().remove(property);
    433     }
    434 
    435     bool hasRunningTransition = element.hasRunningTransitionsForProperty(property);
    436     if ((hasRunningTransition || element.hasCompletedTransitionsForProperty(property)) && !matchingBackingAnimation) {
     437        styleable.ensureCompletedTransitionsByProperty().remove(property);
     438    }
     439
     440    bool hasRunningTransition = styleable.hasRunningTransitionsForProperty(property);
     441    if ((hasRunningTransition || styleable.hasCompletedTransitionsForProperty(property)) && !matchingBackingAnimation) {
    437442        // 3. If the element has a running transition or completed transition for the property, and there is not a matching transition-property
    438443        //    value, then implementations must cancel the running transition or remove the completed transition from the set of completed transitions.
    439444        if (hasRunningTransition)
    440             element.ensureRunningTransitionsByProperty().take(property)->cancel();
     445            styleable.ensureRunningTransitionsByProperty().take(property)->cancel();
    441446        else
    442             element.ensureCompletedTransitionsByProperty().remove(property);
    443     }
    444 
    445     if (matchingBackingAnimation && element.hasRunningTransitionsForProperty(property) && !propertyInStyleMatchesValueForTransitionInMap(property, afterChangeStyle, element.ensureRunningTransitionsByProperty())) {
    446         auto previouslyRunningTransition = element.ensureRunningTransitionsByProperty().take(property);
     447            styleable.ensureCompletedTransitionsByProperty().remove(property);
     448    }
     449
     450    if (matchingBackingAnimation && styleable.hasRunningTransitionsForProperty(property) && !propertyInStyleMatchesValueForTransitionInMap(property, afterChangeStyle, styleable.ensureRunningTransitionsByProperty())) {
     451        auto previouslyRunningTransition = styleable.ensureRunningTransitionsByProperty().take(property);
    447452        auto& previouslyRunningTransitionCurrentStyle = previouslyRunningTransition->currentStyle();
    448453        // 4. If the element has a running transition for the property, there is a matching transition-property value, and the end value of the running
     
    482487            auto duration = Seconds(matchingBackingAnimation->duration()) * reversingShorteningFactor;
    483488
    484             element.ensureRunningTransitionsByProperty().set(property, CSSTransition::create(element, property, generationTime, *matchingBackingAnimation, &previouslyRunningTransitionCurrentStyle, afterChangeStyle, delay, duration, reversingAdjustedStartStyle, reversingShorteningFactor));
     489            styleable.ensureRunningTransitionsByProperty().set(property, CSSTransition::create(styleable, property, generationTime, *matchingBackingAnimation, &previouslyRunningTransitionCurrentStyle, afterChangeStyle, delay, duration, reversingAdjustedStartStyle, reversingShorteningFactor));
    485490        } else {
    486491            // 4. Otherwise, implementations must cancel the running transition
     
    498503            auto& reversingAdjustedStartStyle = currentStyle;
    499504            auto reversingShorteningFactor = 1;
    500             element.ensureRunningTransitionsByProperty().set(property, CSSTransition::create(element, property, generationTime, *matchingBackingAnimation, &previouslyRunningTransitionCurrentStyle, afterChangeStyle, delay, duration, reversingAdjustedStartStyle, reversingShorteningFactor));
    501         }
    502     }
    503 }
    504 
    505 void AnimationTimeline::updateCSSTransitionsForElement(Element& element, const RenderStyle& currentStyle, const RenderStyle& newStyle)
     505            styleable.ensureRunningTransitionsByProperty().set(property, CSSTransition::create(styleable, property, generationTime, *matchingBackingAnimation, &previouslyRunningTransitionCurrentStyle, afterChangeStyle, delay, duration, reversingAdjustedStartStyle, reversingShorteningFactor));
     506        }
     507    }
     508}
     509
     510void AnimationTimeline::updateCSSTransitionsForStyleable(const Styleable& styleable, const RenderStyle& currentStyle, const RenderStyle& newStyle)
    506511{
    507512    // In case this element is newly getting a "display: none" we need to cancel all of its transitions and disregard new ones.
    508513    if (currentStyle.hasTransitions() && currentStyle.display() != DisplayType::None && newStyle.display() == DisplayType::None) {
    509         if (element.hasRunningTransitions()) {
    510             auto runningTransitions = element.ensureRunningTransitionsByProperty();
     514        if (styleable.hasRunningTransitions()) {
     515            auto runningTransitions = styleable.ensureRunningTransitionsByProperty();
    511516            for (const auto& cssTransitionsByCSSPropertyIDMapItem : runningTransitions)
    512517                cssTransitionsByCSSPropertyIDMapItem.value->cancelFromStyle();
     
    533538            if (isShorthand && *isShorthand)
    534539                continue;
    535             updateCSSTransitionsForElementAndProperty(element, property, currentStyle, newStyle, generationTime);
     540            updateCSSTransitionsForStyleableAndProperty(styleable, property, currentStyle, newStyle, generationTime);
    536541        }
    537542        return;
     
    539544
    540545    for (auto property : transitionProperties)
    541         updateCSSTransitionsForElementAndProperty(element, property, currentStyle, newStyle, generationTime);
     546        updateCSSTransitionsForStyleableAndProperty(styleable, property, currentStyle, newStyle, generationTime);
    542547}
    543548
  • trunk/Source/WebCore/animation/AnimationTimeline.h

    r267347 r267571  
    3030#include "ComputedEffectTiming.h"
    3131#include "RenderStyle.h"
     32#include "Styleable.h"
    3233#include "WebAnimation.h"
    3334#include <wtf/Forward.h>
     
    4546class CSSTransition;
    4647class DeclarativeAnimation;
    47 class Element;
    4848
    4949class AnimationTimeline : public RefCounted<AnimationTimeline>, public CanMakeWeakPtr<AnimationTimeline> {
     
    6262    virtual Optional<Seconds> currentTime() { return m_currentTime; }
    6363
    64     void elementWasRemoved(Element&);
     64    void elementWasRemoved(const Styleable&);
    6565
    66     void willChangeRendererForElement(Element&);
    67     void cancelDeclarativeAnimationsForElement(Element&, WebAnimation::Silently);
     66    void willChangeRendererForStyleable(const Styleable&);
     67    void cancelDeclarativeAnimationsForStyleable(const Styleable&, WebAnimation::Silently);
    6868
    69     void animationWasAddedToElement(WebAnimation&, Element&);
    70     void animationWasRemovedFromElement(WebAnimation&, Element&);
     69    void animationWasAddedToStyleable(WebAnimation&, const Styleable&);
     70    void animationWasRemovedFromStyleable(WebAnimation&, const Styleable&);
    7171
    72     void removeDeclarativeAnimationFromListsForOwningElement(WebAnimation&, Element&);
     72    void removeDeclarativeAnimationFromListsForOwningElement(WebAnimation&, const Styleable&);
    7373
    74     void updateCSSAnimationsForElement(Element&, const RenderStyle* currentStyle, const RenderStyle& afterChangeStyle);
    75     void updateCSSTransitionsForElement(Element&, const RenderStyle& currentStyle, const RenderStyle& newStyle);
     74    void updateCSSAnimationsForStyleable(const Styleable&, const RenderStyle* currentStyle, const RenderStyle& afterChangeStyle);
     75    void updateCSSTransitionsForStyleable(const Styleable&, const RenderStyle& currentStyle, const RenderStyle& newStyle);
    7676
    7777protected:
     
    8383private:
    8484    void updateGlobalPosition(WebAnimation&);
    85     void updateCSSTransitionsForElementAndProperty(Element&, CSSPropertyID, const RenderStyle& currentStyle, const RenderStyle& afterChangeStyle, const MonotonicTime);
    86     void removeCSSAnimationCreatedByMarkup(Element&, CSSAnimation&);
     85    void updateCSSTransitionsForStyleableAndProperty(const Styleable&, CSSPropertyID, const RenderStyle& currentStyle, const RenderStyle& afterChangeStyle, const MonotonicTime);
     86    void removeCSSAnimationCreatedByMarkup(const Styleable&, CSSAnimation&);
    8787
    8888    Markable<Seconds, Seconds::MarkableTraits> m_currentTime;
  • trunk/Source/WebCore/animation/CSSAnimation.cpp

    r261637 r267571  
    2929#include "Animation.h"
    3030#include "AnimationEvent.h"
    31 #include "Element.h"
    3231#include "InspectorInstrumentation.h"
    3332#include "RenderStyle.h"
     
    3837WTF_MAKE_ISO_ALLOCATED_IMPL(CSSAnimation);
    3938
    40 Ref<CSSAnimation> CSSAnimation::create(Element& owningElement, const Animation& backingAnimation, const RenderStyle* oldStyle, const RenderStyle& newStyle)
     39Ref<CSSAnimation> CSSAnimation::create(const Styleable& owningElement, const Animation& backingAnimation, const RenderStyle* oldStyle, const RenderStyle& newStyle)
    4140{
    4241    auto result = adoptRef(*new CSSAnimation(owningElement, backingAnimation));
     
    4847}
    4948
    50 CSSAnimation::CSSAnimation(Element& element, const Animation& backingAnimation)
     49CSSAnimation::CSSAnimation(const Styleable& element, const Animation& backingAnimation)
    5150    : DeclarativeAnimation(element, backingAnimation)
    5251    , m_animationName(backingAnimation.name())
  • trunk/Source/WebCore/animation/CSSAnimation.h

    r260671 r267571  
    2727
    2828#include "DeclarativeAnimation.h"
     29#include "Styleable.h"
    2930#include <wtf/OptionSet.h>
    3031#include <wtf/Ref.h>
     
    3334
    3435class Animation;
    35 class Element;
    3636class RenderStyle;
    3737
     
    3939    WTF_MAKE_ISO_ALLOCATED(CSSAnimation);
    4040public:
    41     static Ref<CSSAnimation> create(Element&, const Animation&, const RenderStyle* oldStyle, const RenderStyle& newStyle);
     41    static Ref<CSSAnimation> create(const Styleable&, const Animation&, const RenderStyle* oldStyle, const RenderStyle& newStyle);
    4242    ~CSSAnimation() = default;
    4343
     
    4949
    5050private:
    51     CSSAnimation(Element&, const Animation&);
     51    CSSAnimation(const Styleable&, const Animation&);
    5252
    5353    void syncPropertiesWithBackingAnimation() final;
  • trunk/Source/WebCore/animation/CSSTransition.cpp

    r264332 r267571  
    2929#include "Animation.h"
    3030#include "DocumentTimeline.h"
    31 #include "Element.h"
    3231#include "InspectorInstrumentation.h"
    3332#include "KeyframeEffect.h"
     
    3938WTF_MAKE_ISO_ALLOCATED_IMPL(CSSTransition);
    4039
    41 Ref<CSSTransition> CSSTransition::create(Element& owningElement, CSSPropertyID property, MonotonicTime generationTime, const Animation& backingAnimation, const RenderStyle* oldStyle, const RenderStyle& newStyle, Seconds delay, Seconds duration, const RenderStyle& reversingAdjustedStartStyle, double reversingShorteningFactor)
     40Ref<CSSTransition> CSSTransition::create(const Styleable& owningElement, CSSPropertyID property, MonotonicTime generationTime, const Animation& backingAnimation, const RenderStyle* oldStyle, const RenderStyle& newStyle, Seconds delay, Seconds duration, const RenderStyle& reversingAdjustedStartStyle, double reversingShorteningFactor)
    4241{
    4342    ASSERT(oldStyle);
     
    5150}
    5251
    53 CSSTransition::CSSTransition(Element& element, CSSPropertyID property, MonotonicTime generationTime, const Animation& backingAnimation, const RenderStyle& oldStyle, const RenderStyle& targetStyle, const RenderStyle& reversingAdjustedStartStyle, double reversingShorteningFactor)
    54     : DeclarativeAnimation(element, backingAnimation)
     52CSSTransition::CSSTransition(const Styleable& styleable, CSSPropertyID property, MonotonicTime generationTime, const Animation& backingAnimation, const RenderStyle& oldStyle, const RenderStyle& targetStyle, const RenderStyle& reversingAdjustedStartStyle, double reversingShorteningFactor)
     53    : DeclarativeAnimation(styleable, backingAnimation)
    5554    , m_property(property)
    5655    , m_generationTime(generationTime)
    57     , m_timelineTimeAtCreation(element.document().timeline().currentTime())
     56    , m_timelineTimeAtCreation(styleable.element.document().timeline().currentTime())
    5857    , m_targetStyle(RenderStyle::clonePtr(targetStyle))
    5958    , m_currentStyle(RenderStyle::clonePtr(oldStyle))
  • trunk/Source/WebCore/animation/CSSTransition.h

    r263464 r267571  
    2828#include "CSSPropertyNames.h"
    2929#include "DeclarativeAnimation.h"
     30#include "Styleable.h"
    3031#include <wtf/Markable.h>
    3132#include <wtf/MonotonicTime.h>
     
    3738
    3839class Animation;
    39 class Element;
    4040class RenderStyle;
    4141
     
    4343    WTF_MAKE_ISO_ALLOCATED(CSSTransition);
    4444public:
    45     static Ref<CSSTransition> create(Element&, CSSPropertyID, MonotonicTime generationTime, const Animation&, const RenderStyle* oldStyle, const RenderStyle& newStyle, Seconds delay, Seconds duration, const RenderStyle& reversingAdjustedStartStyle, double);
     45    static Ref<CSSTransition> create(const Styleable&, CSSPropertyID, MonotonicTime generationTime, const Animation&, const RenderStyle* oldStyle, const RenderStyle& newStyle, Seconds delay, Seconds duration, const RenderStyle& reversingAdjustedStartStyle, double);
    4646    ~CSSTransition() = default;
    4747
     
    5757
    5858private:
    59     CSSTransition(Element&, CSSPropertyID, MonotonicTime generationTime, const Animation&, const RenderStyle& oldStyle, const RenderStyle& targetStyle, const RenderStyle& reversingAdjustedStartStyle, double);
     59    CSSTransition(const Styleable&, CSSPropertyID, MonotonicTime generationTime, const Animation&, const RenderStyle& oldStyle, const RenderStyle& targetStyle, const RenderStyle& reversingAdjustedStartStyle, double);
    6060    void setTimingProperties(Seconds delay, Seconds duration);
    6161    Ref<AnimationEventBase> createEvent(const AtomString& eventType, double elapsedTime, const String& pseudoId, Optional<Seconds> timelineTime) final;
  • trunk/Source/WebCore/animation/DeclarativeAnimation.cpp

    r265319 r267571  
    4444WTF_MAKE_ISO_ALLOCATED_IMPL(DeclarativeAnimation);
    4545
    46 DeclarativeAnimation::DeclarativeAnimation(Element& owningElement, const Animation& backingAnimation)
    47     : WebAnimation(owningElement.document())
    48     , m_owningElement(makeWeakPtr(owningElement))
     46DeclarativeAnimation::DeclarativeAnimation(const Styleable& styleable, const Animation& backingAnimation)
     47    : WebAnimation(styleable.element.document())
     48    , m_owningElement(makeWeakPtr(styleable.element))
     49    , m_owningPseudoId(styleable.pseudoId)
    4950    , m_backingAnimation(const_cast<Animation&>(backingAnimation))
    5051{
     
    5556}
    5657
    57 Element* DeclarativeAnimation::owningElement() const
    58 {
    59     return m_owningElement.get();
     58const Optional<const Styleable> DeclarativeAnimation::owningElement() const
     59{
     60    if (m_owningElement)
     61        return Styleable(*m_owningElement.get(), m_owningPseudoId);
     62    return WTF::nullopt;
    6063}
    6164
     
    9497
    9598    if (auto* animationTimeline = timeline())
    96         animationTimeline->removeDeclarativeAnimationFromListsForOwningElement(*this, *m_owningElement);
     99        animationTimeline->removeDeclarativeAnimationFromListsForOwningElement(*this, *owningElement());
    97100    m_owningElement = nullptr;
    98101}
     
    113116    ASSERT(m_owningElement);
    114117
    115     if (is<PseudoElement>(m_owningElement.get())) {
    116         auto& pseudoOwningElement = downcast<PseudoElement>(*m_owningElement);
    117         ASSERT(pseudoOwningElement.hostElement());
    118         setEffect(KeyframeEffect::create(*pseudoOwningElement.hostElement(), pseudoOwningElement.pseudoId()));
    119     } else
    120         setEffect(KeyframeEffect::create(*m_owningElement, m_owningElement->pseudoId()));
     118    setEffect(KeyframeEffect::create(*m_owningElement, m_owningPseudoId));
    121119    setTimeline(&m_owningElement->document().timeline());
    122120    downcast<KeyframeEffect>(effect())->computeDeclarativeAnimationBlendingKeyframes(oldStyle, newStyle);
     
    353351
    354352    auto time = secondsToWebAnimationsAPITime(elapsedTime) / 1000;
    355     const auto& pseudoId = PseudoElement::pseudoElementNameForEvents(m_owningElement->pseudoId());
     353    const auto& pseudoId = PseudoElement::pseudoElementNameForEvents(m_owningPseudoId);
    356354    auto timelineTime = timeline() ? timeline()->currentTime() : WTF::nullopt;
    357355    auto event = createEvent(eventType, time, pseudoId, timelineTime);
  • trunk/Source/WebCore/animation/DeclarativeAnimation.h

    r260671 r267571  
    2828#include "AnimationEffect.h"
    2929#include "AnimationEffectPhase.h"
     30#include "Styleable.h"
    3031#include "WebAnimation.h"
    3132#include <wtf/Ref.h>
     
    4647    bool isDeclarativeAnimation() const final { return true; }
    4748
    48     Element* owningElement() const;
     49    const Optional<const Styleable> owningElement() const;
    4950    const Animation& backingAnimation() const { return m_backingAnimation; }
    5051    void setBackingAnimation(const Animation&);
     
    7374
    7475protected:
    75     DeclarativeAnimation(Element&, const Animation&);
     76    DeclarativeAnimation(const Styleable&, const Animation&);
    7677
    7778    virtual void initialize(const RenderStyle* oldStyle, const RenderStyle& newStyle);
     
    9192
    9293    WeakPtr<Element> m_owningElement;
     94    PseudoId m_owningPseudoId;
    9395    Ref<Animation> m_backingAnimation;
    9496    double m_previousIteration;
  • trunk/Source/WebCore/animation/DocumentTimeline.cpp

    r267347 r267571  
    3838#include "Node.h"
    3939#include "Page.h"
     40#include "RenderBoxModelObject.h"
    4041#include "RenderElement.h"
    4142#include "RenderLayer.h"
     
    227228
    228229    auto* keyframeEffect = downcast<KeyframeEffect>(effect);
    229     auto* target = keyframeEffect->target();
    230     if (!target || !target->isDescendantOf(*m_document))
     230    auto target = keyframeEffect->targetStyleable();
     231    if (!target || !target->element.isDescendantOf(*m_document))
    231232        return false;
    232233
     
    297298    removeAnimation(*transition);
    298299    if (is<KeyframeEffect>(transition->effect())) {
    299         if (auto* target = downcast<KeyframeEffect>(transition->effect())->targetElementOrPseudoElement())
    300             target->ensureCompletedTransitionsByProperty().set(transition->property(), transition);
     300        if (auto styleable = downcast<KeyframeEffect>(transition->effect())->targetStyleable())
     301            styleable->ensureCompletedTransitionsByProperty().set(transition->property(), transition);
    301302    }
    302303}
     
    331332bool DocumentTimeline::computeExtentOfAnimation(RenderElement& renderer, LayoutRect& bounds) const
    332333{
    333     if (!renderer.element())
    334         return true;
    335 
    336     auto* animations = renderer.element()->animations();
     334    auto styleable = Styleable::fromRenderer(renderer);
     335    if (!styleable)
     336        return false;
     337
     338    auto* animations = styleable->animations();
    337339    if (!animations)
    338340        return false;
     
    356358bool DocumentTimeline::isRunningAnimationOnRenderer(RenderElement& renderer, CSSPropertyID property) const
    357359{
    358     if (!renderer.element())
    359         return false;
    360 
    361     auto* animations = renderer.element()->animations();
     360    auto styleable = Styleable::fromRenderer(renderer);
     361    if (!styleable)
     362        return false;
     363
     364    auto* animations = styleable->animations();
    362365    if (!animations)
    363366        return false;
     
    377380bool DocumentTimeline::isRunningAcceleratedAnimationOnRenderer(RenderElement& renderer, CSSPropertyID property) const
    378381{
    379     if (!renderer.element())
    380         return false;
    381 
    382     auto* animations = renderer.element()->animations();
     382    auto styleable = Styleable::fromRenderer(renderer);
     383    if (!styleable)
     384        return false;
     385
     386    auto* animations = styleable->animations();
    383387    if (!animations)
    384388        return false;
     
    401405std::unique_ptr<RenderStyle> DocumentTimeline::animatedStyleForRenderer(RenderElement& renderer)
    402406{
    403     auto* element = renderer.element();
    404     if (!element)
     407    auto styleable = Styleable::fromRenderer(renderer);
     408    if (!styleable)
    405409        return RenderStyle::clonePtr(renderer.style());
    406410
    407     auto* animations = renderer.element()->animations();
     411    auto* animations = styleable->animations();
    408412    if (!animations)
    409413        return RenderStyle::clonePtr(renderer.style());
     
    447451}
    448452
    449 bool DocumentTimeline::runningAnimationsForElementAreAllAccelerated(Element& element) const
    450 {
    451     auto* animations = element.animations();
     453bool DocumentTimeline::runningAnimationsForRendererAreAllAccelerated(const RenderBoxModelObject& renderer) const
     454{
     455    auto styleable = Styleable::fromRenderer(renderer);
     456    if (!styleable)
     457        return false;
     458
     459    auto* animations = styleable->animations();
    452460    if (!animations || animations->isEmpty())
    453461        return false;
  • trunk/Source/WebCore/animation/DocumentTimeline.h

    r267347 r267571  
    3636class AnimationEventBase;
    3737class DocumentTimelinesController;
     38class RenderBoxModelObject;
    3839class RenderElement;
    3940
     
    6364    bool isRunningAcceleratedAnimationOnRenderer(RenderElement&, CSSPropertyID) const;
    6465    void animationAcceleratedRunningStateDidChange(WebAnimation&);
    65     bool runningAnimationsForElementAreAllAccelerated(Element&) const;
     66    bool runningAnimationsForRendererAreAllAccelerated(const RenderBoxModelObject&) const;
    6667    void detachFromDocument();
    6768
  • trunk/Source/WebCore/animation/ElementAnimationRareData.cpp

    r262621 r267571  
    3434namespace WebCore {
    3535
    36 ElementAnimationRareData::ElementAnimationRareData()
     36ElementAnimationRareData::ElementAnimationRareData(PseudoId pseudoId)
     37    : m_pseudoId(pseudoId)
    3738{
    3839}
  • trunk/Source/WebCore/animation/ElementAnimationRareData.h

    r267204 r267571  
    4040    WTF_MAKE_FAST_ALLOCATED;
    4141public:
    42     explicit ElementAnimationRareData();
     42    explicit ElementAnimationRareData(PseudoId);
    4343    ~ElementAnimationRareData();
     44
     45    PseudoId pseudoId() const { return m_pseudoId; }
    4446
    4547    KeyframeEffectStack* keyframeEffectStack() { return m_keyframeEffectStack.get(); }
     
    6264    PropertyToTransitionMap m_completedTransitionsByProperty;
    6365    PropertyToTransitionMap m_runningTransitionsByProperty;
     66    PseudoId m_pseudoId;
    6467};
    6568
  • trunk/Source/WebCore/animation/KeyframeEffect.cpp

    r266789 r267571  
    6767using namespace JSC;
    6868
    69 static inline void invalidateElement(Element* element)
    70 {
    71     if (element)
    72         element->invalidateStyleInternal();
     69static Element* elementOrPseudoElementForStyleable(const Optional<const Styleable>& styleable)
     70{
     71    if (!styleable)
     72        return nullptr;
     73
     74    switch (styleable->pseudoId) {
     75    case PseudoId::None:
     76        return &styleable->element;
     77    case PseudoId::Before:
     78        return styleable->element.beforePseudoElement();
     79    case PseudoId::After:
     80        return styleable->element.afterPseudoElement();
     81    default:
     82        return nullptr;
     83    }
     84}
     85
     86static inline void invalidateElement(const Optional<const Styleable>& styleable)
     87{
     88    if (auto* elementOrPseudoElement = elementOrPseudoElementForStyleable(styleable))
     89        elementOrPseudoElement->invalidateStyleInternal();
    7390}
    7491
     
    10521069void KeyframeEffect::animationTimelineDidChange(AnimationTimeline* timeline)
    10531070{
    1054     if (!targetElementOrPseudoElement())
     1071    auto target = targetStyleable();
     1072    if (!target)
    10551073        return;
    10561074
    10571075    if (timeline)
    1058         m_inTargetEffectStack = targetElementOrPseudoElement()->ensureKeyframeEffectStack().addEffect(*this);
     1076        m_inTargetEffectStack = target->ensureKeyframeEffectStack().addEffect(*this);
    10591077    else {
    1060         targetElementOrPseudoElement()->ensureKeyframeEffectStack().removeEffect(*this);
     1078        target->ensureKeyframeEffectStack().removeEffect(*this);
    10611079        m_inTargetEffectStack = false;
    10621080    }
     
    10701088void KeyframeEffect::updateEffectStackMembership()
    10711089{
    1072     if (!targetElementOrPseudoElement())
     1090    auto target = targetStyleable();
     1091    if (!target)
    10731092        return;
    10741093
    10751094    bool isRelevant = animation() && animation()->isRelevant();
    10761095    if (isRelevant && !m_inTargetEffectStack)
    1077         m_inTargetEffectStack = targetElementOrPseudoElement()->ensureKeyframeEffectStack().addEffect(*this);
     1096        m_inTargetEffectStack = target->ensureKeyframeEffectStack().addEffect(*this);
    10781097    else if (!isRelevant && m_inTargetEffectStack) {
    1079         targetElementOrPseudoElement()->ensureKeyframeEffectStack().removeEffect(*this);
     1098        target->ensureKeyframeEffectStack().removeEffect(*this);
    10801099        m_inTargetEffectStack = false;
    10811100    }
     
    10951114}
    10961115
     1116const Optional<const Styleable> KeyframeEffect::targetStyleable() const
     1117{
     1118    if (m_target)
     1119        return Styleable(*m_target, m_pseudoId);
     1120    return WTF::nullopt;
     1121}
     1122
    10971123bool KeyframeEffect::targetsPseudoElement() const
    10981124{
     
    11201146        return;
    11211147
    1122     auto* previousTargetElementOrPseudoElement = targetElementOrPseudoElement();
     1148    auto& previousTargetStyleable = targetStyleable();
    11231149    m_target = WTFMove(newTarget);
    1124     didChangeTargetElementOrPseudoElement(previousTargetElementOrPseudoElement);
     1150    didChangeTargetStyleable(previousTargetStyleable);
    11251151}
    11261152
     
    11621188        return { };
    11631189
    1164     auto* previousTargetElementOrPseudoElement = targetElementOrPseudoElement();
     1190    auto& previousTargetStyleable = targetStyleable();
    11651191    m_pseudoId = pseudoId;
    1166     didChangeTargetElementOrPseudoElement(previousTargetElementOrPseudoElement);
     1192    didChangeTargetStyleable(previousTargetStyleable);
    11671193
    11681194    return { };
    11691195}
    11701196
    1171 void KeyframeEffect::didChangeTargetElementOrPseudoElement(Element* previousTargetElementOrPseudoElement)
    1172 {
    1173     auto* newTargetElementOrPseudoElement = targetElementOrPseudoElement();
     1197void KeyframeEffect::didChangeTargetStyleable(const Optional<const Styleable>& previousTargetStyleable)
     1198{
     1199    auto newTargetStyleable = targetStyleable();
    11741200
    11751201    // We must ensure a PseudoElement exists for this m_target / m_pseudoId pair if both are specified.
     1202    // FIXME: Ideally this wouldn't be necessary.
     1203    auto* newTargetElementOrPseudoElement = elementOrPseudoElementForStyleable(newTargetStyleable);
    11761204    if (!newTargetElementOrPseudoElement && m_target.get() && m_pseudoId != PseudoId::None) {
    1177         // We only support targeting ::before and ::after pseudo-elements at the moment.
     1205        // FIXME: We only support targeting ::before and ::after pseudo-elements at the moment.
    11781206        if (m_pseudoId == PseudoId::Before || m_pseudoId == PseudoId::After)
    11791207            newTargetElementOrPseudoElement = &m_target->ensurePseudoElement(m_pseudoId);
     
    11811209
    11821210    if (auto* effectAnimation = animation())
    1183         effectAnimation->effectTargetDidChange(previousTargetElementOrPseudoElement, newTargetElementOrPseudoElement);
     1211        effectAnimation->effectTargetDidChange(previousTargetStyleable, newTargetStyleable);
    11841212
    11851213    clearBlendingKeyframes();
     
    11911219    // Likewise, we need to invalidate styles on the previous target so that
    11921220    // any animated styles are removed immediately.
    1193     invalidateElement(previousTargetElementOrPseudoElement);
    1194 
    1195     if (previousTargetElementOrPseudoElement) {
    1196         previousTargetElementOrPseudoElement->ensureKeyframeEffectStack().removeEffect(*this);
     1221    invalidateElement(previousTargetStyleable);
     1222
     1223    if (previousTargetStyleable) {
     1224        previousTargetStyleable->ensureKeyframeEffectStack().removeEffect(*this);
    11971225        m_inTargetEffectStack = false;
    11981226    }
    1199     if (newTargetElementOrPseudoElement)
    1200         m_inTargetEffectStack = newTargetElementOrPseudoElement->ensureKeyframeEffectStack().addEffect(*this);
     1227
     1228    if (newTargetStyleable)
     1229        m_inTargetEffectStack = newTargetStyleable->ensureKeyframeEffectStack().addEffect(*this);
    12011230}
    12021231
     
    12391268{
    12401269    LOG_WITH_STREAM(Animations, stream << "KeyframeEffect::invalidate on element " << ValueOrNull(targetElementOrPseudoElement()));
    1241     invalidateElement(targetElementOrPseudoElement());
     1270    invalidateElement(targetStyleable());
    12421271}
    12431272
     
    16241653        ASSERT(m_target);
    16251654
    1626         auto* lastStyleChangeEventStyle = m_target->lastStyleChangeEventStyle();
     1655        auto* lastStyleChangeEventStyle = m_target->lastStyleChangeEventStyle(m_pseudoId);
    16271656        ASSERT(lastStyleChangeEventStyle);
    16281657
  • trunk/Source/WebCore/animation/KeyframeEffect.h

    r266789 r267571  
    3838#include "RenderStyle.h"
    3939#include "StyleProperties.h"
     40#include "Styleable.h"
    4041#include "WebAnimationTypes.h"
    4142#include <wtf/Ref.h>
     
    109110    const String pseudoElement() const;
    110111    ExceptionOr<void> setPseudoElement(const String&);
     112
     113    const Optional<const Styleable> targetStyleable() const;
    111114
    112115    Vector<JSC::Strong<JSC::JSObject>> getBindingsKeyframes(JSC::JSGlobalObject&);
     
    179182    void updateEffectStackMembership();
    180183    void copyPropertiesFromSource(Ref<KeyframeEffect>&&);
    181     void didChangeTargetElementOrPseudoElement(Element*);
     184    void didChangeTargetStyleable(const Optional<const Styleable>&);
    182185    ExceptionOr<void> processKeyframes(JSC::JSGlobalObject&, JSC::Strong<JSC::JSObject>&&);
    183186    void addPendingAcceleratedAction(AcceleratedAction);
  • trunk/Source/WebCore/animation/KeyframeEffectStack.cpp

    r261470 r267571  
    4747    // To qualify for membership in an effect stack, an effect must have a target, an animation, a timeline and be relevant.
    4848    // This method will be called in WebAnimation and KeyframeEffect as those properties change.
    49     if (!effect.targetElementOrPseudoElement() || !effect.animation() || !effect.animation()->timeline() || !effect.animation()->isRelevant())
     49    if (!effect.targetStyleable() || !effect.animation() || !effect.animation()->timeline() || !effect.animation()->isRelevant())
    5050        return false;
    5151
  • trunk/Source/WebCore/animation/WebAnimation.cpp

    r263729 r267571  
    207207    auto oldEffect = std::exchange(m_effect, WTFMove(newEffect));
    208208
    209     Element* previousTarget = nullptr;
    210     if (is<KeyframeEffect>(oldEffect))
    211         previousTarget = downcast<KeyframeEffect>(oldEffect.get())->targetElementOrPseudoElement();
    212 
    213     Element* newTarget = nullptr;
    214     if (is<KeyframeEffect>(m_effect))
    215         newTarget = downcast<KeyframeEffect>(m_effect.get())->targetElementOrPseudoElement();
     209    Optional<const Styleable> previousTarget = is<KeyframeEffect>(oldEffect) ? downcast<KeyframeEffect>(oldEffect.get())->targetStyleable() : WTF::nullopt;
     210    Optional<const Styleable> newTarget = is<KeyframeEffect>(m_effect) ? downcast<KeyframeEffect>(m_effect.get())->targetStyleable() : WTF::nullopt;
    216211
    217212    // Update the effect-to-animation relationships and the timeline's animation map.
     
    219214        oldEffect->setAnimation(nullptr);
    220215        if (!doNotRemoveFromTimeline && m_timeline && previousTarget && previousTarget != newTarget)
    221             m_timeline->animationWasRemovedFromElement(*this, *previousTarget);
     216            m_timeline->animationWasRemovedFromStyleable(*this, *previousTarget);
    222217        updateRelevance();
    223218    }
     
    226221        m_effect->setAnimation(this);
    227222        if (m_timeline && newTarget && previousTarget != newTarget)
    228             m_timeline->animationWasAddedToElement(*this, *newTarget);
     223            m_timeline->animationWasAddedToStyleable(*this, *newTarget);
    229224    }
    230225
     
    246241
    247242    if (is<KeyframeEffect>(m_effect)) {
    248         auto* keyframeEffect = downcast<KeyframeEffect>(m_effect.get());
    249         auto* target = keyframeEffect->targetElementOrPseudoElement();
    250         if (target) {
     243        if (auto target = downcast<KeyframeEffect>(m_effect.get())->targetStyleable()) {
    251244            // In the case of a declarative animation, we don't want to remove the animation from the relevant maps because
    252245            // while the timeline was set via the API, the element still has a transition or animation set up and we must
    253246            // not break the relationship.
    254247            if (m_timeline && !isDeclarativeAnimation())
    255                 m_timeline->animationWasRemovedFromElement(*this, *target);
     248                m_timeline->animationWasRemovedFromStyleable(*this, *target);
    256249            if (timeline)
    257                 timeline->animationWasAddedToElement(*this, *target);
     250                timeline->animationWasAddedToStyleable(*this, *target);
    258251        }
    259252    }
     
    286279}
    287280
    288 void WebAnimation::effectTargetDidChange(Element* previousTarget, Element* newTarget)
     281void WebAnimation::effectTargetDidChange(const Optional<const Styleable>& previousTarget, const Optional<const Styleable>& newTarget)
    289282{
    290283    if (m_timeline) {
    291284        if (previousTarget)
    292             m_timeline->animationWasRemovedFromElement(*this, *previousTarget);
     285            m_timeline->animationWasRemovedFromStyleable(*this, *previousTarget);
    293286
    294287        if (newTarget)
    295             m_timeline->animationWasAddedToElement(*this, *newTarget);
     288            m_timeline->animationWasAddedToStyleable(*this, *newTarget);
    296289
    297290        // This could have changed whether we have replaced animations, so we may need to schedule an update.
     
    13831376        if (is<KeyframeEffect>(m_effect)) {
    13841377            auto& keyframeEffect = downcast<KeyframeEffect>(*m_effect);
    1385             auto& target = *keyframeEffect.targetElementOrPseudoElement();
    1386             m_timeline->animationWasAddedToElement(*this, target);
    1387             target.ensureKeyframeEffectStack().addEffect(keyframeEffect);
     1378            auto styleable = keyframeEffect.targetStyleable();
     1379            m_timeline->animationWasAddedToStyleable(*this, *styleable);
     1380            styleable->ensureKeyframeEffectStack().addEffect(keyframeEffect);
    13881381        }
    13891382    }
     
    14241417    inlineStyle->setCssText(styledElement.getAttribute("style"));
    14251418
    1426     auto& keyframeStack = styledElement.ensureKeyframeEffectStack();
     1419    auto& keyframeStack = styledElement.ensureKeyframeEffectStack(PseudoId::None);
    14271420
    14281421    // 2.5 For each property, property, in targeted properties:
  • trunk/Source/WebCore/animation/WebAnimation.h

    r263729 r267571  
    3030#include "ExceptionOr.h"
    3131#include "IDLTypes.h"
     32#include "Styleable.h"
    3233#include "WebAnimationTypes.h"
    3334#include <wtf/Forward.h>
     
    4546class AnimationTimeline;
    4647class Document;
    47 class Element;
    4848class RenderStyle;
    4949
     
    123123    WEBCORE_EXPORT Seconds timeToNextTick() const;
    124124    virtual void resolve(RenderStyle&, Optional<Seconds> = WTF::nullopt);
    125     void effectTargetDidChange(Element* previousTarget, Element* newTarget);
     125    void effectTargetDidChange(const Optional<const Styleable>& previousTarget, const Optional<const Styleable>& newTarget);
    126126    void acceleratedStateDidChange();
    127127    void applyPendingAcceleratedActions();
  • trunk/Source/WebCore/animation/WebAnimationUtilities.cpp

    r261470 r267571  
    3939namespace WebCore {
    4040
    41 static bool compareDeclarativeAnimationOwningElementPositionsInDocumentTreeOrder(Element& a, Element& b)
     41static bool compareDeclarativeAnimationOwningElementPositionsInDocumentTreeOrder(const Styleable& a, const Styleable& b)
    4242{
    4343    // We should not ever be calling this function with two Elements that are the same. If that were the case,
    4444    // then comparing objects of this kind would yield inconsistent results when comparing A == B and B == A.
    4545    // As such, this function should be called with std::stable_sort().
    46     RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(&a != &b);
     46    RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(a != b);
    4747
    4848    // With regard to pseudo-elements, the sort order is as follows:
     49    //
    4950    //     - element
     51    //     - ::marker
    5052    //     - ::before
     53    //     - any other pseudo-elements not mentioned specifically in this list, sorted in ascending order by the Unicode codepoints that make up each selector
    5154    //     - ::after
    5255    //     - element children
     56    enum SortingIndex : uint8_t { NotPseudo, Marker, Before, FirstLetter, FirstLine, Highlight, Scrollbar, Selection, After, Other };
     57    auto sortingIndex = [](PseudoId pseudoId) -> SortingIndex {
     58        switch (pseudoId) {
     59        case PseudoId::None:
     60            return NotPseudo;
     61        case PseudoId::Marker:
     62            return Marker;
     63        case PseudoId::Before:
     64            return Before;
     65        case PseudoId::FirstLetter:
     66            return FirstLetter;
     67        case PseudoId::FirstLine:
     68            return FirstLine;
     69        case PseudoId::Highlight:
     70            return Highlight;
     71        case PseudoId::Scrollbar:
     72            return Scrollbar;
     73        case PseudoId::Selection:
     74            return Selection;
     75        case PseudoId::After:
     76            return After;
     77        default:
     78            ASSERT_NOT_REACHED();
     79            return Other;
     80        }
     81    };
    5382
    54     enum SortingIndex : uint8_t { NotPseudo, Before, After };
     83    auto& aReferenceElement = a.element;
     84    int aSortingIndex = sortingIndex(a.pseudoId);
    5585
    56     int aSortingIndex = NotPseudo;
    57     Element* aReferenceElement = &a;
    58     if (is<PseudoElement>(a)) {
    59         auto& aPseudo = downcast<PseudoElement>(a);
    60         aSortingIndex = aPseudo.isBeforePseudoElement() ? Before : After;
    61         aReferenceElement = aPseudo.hostElement();
    62         ASSERT(aReferenceElement);
     86    auto& bReferenceElement = b.element;
     87    int bSortingIndex = sortingIndex(b.pseudoId);
     88
     89    if (&aReferenceElement == &bReferenceElement) {
     90        ASSERT(aSortingIndex != bSortingIndex);
     91        return aSortingIndex < bSortingIndex;
    6392    }
    64 
    65     int bSortingIndex = NotPseudo;
    66     Element* bReferenceElement = &b;
    67     if (is<PseudoElement>(b)) {
    68         auto& bPseudo = downcast<PseudoElement>(b);
    69         bSortingIndex = bPseudo.isBeforePseudoElement() ? Before : After;
    70         bReferenceElement = bPseudo.hostElement();
    71         ASSERT(bReferenceElement);
    72     }
    73 
    74     if (aReferenceElement == bReferenceElement)
    75         return aSortingIndex < bSortingIndex;
    76     return aReferenceElement->compareDocumentPosition(*bReferenceElement) & Node::DOCUMENT_POSITION_FOLLOWING;
     93    return aReferenceElement.compareDocumentPosition(bReferenceElement) & Node::DOCUMENT_POSITION_FOLLOWING;
    7794}
    7895
     
    8198    ASSERT(a.owningElement());
    8299    ASSERT(b.owningElement());
    83     auto& aOwningElement = *a.owningElement();
    84     auto& bOwningElement = *b.owningElement();
     100    auto& aOwningElement = a.owningElement();
     101    auto& bOwningElement = b.owningElement();
    85102
    86103    // If the owning element of A and B differs, sort A and B by tree order of their corresponding owning elements.
    87     if (&aOwningElement != &bOwningElement)
    88         return compareDeclarativeAnimationOwningElementPositionsInDocumentTreeOrder(aOwningElement, bOwningElement);
     104    if (*aOwningElement != *bOwningElement)
     105        return compareDeclarativeAnimationOwningElementPositionsInDocumentTreeOrder(*aOwningElement, *bOwningElement);
    89106
    90107    // Otherwise, if A and B have different transition generation values, sort by their corresponding transition generation in ascending order.
     
    102119    ASSERT(a.owningElement());
    103120    ASSERT(b.owningElement());
    104     auto& aOwningElement = *a.owningElement();
    105     auto& bOwningElement = *b.owningElement();
     121    auto& aOwningElement = a.owningElement();
     122    auto& bOwningElement = b.owningElement();
    106123
    107124    // If the owning element of A and B differs, sort A and B by tree order of their corresponding owning elements.
    108     if (&aOwningElement != &bOwningElement)
    109         return compareDeclarativeAnimationOwningElementPositionsInDocumentTreeOrder(aOwningElement, bOwningElement);
     125    if (*aOwningElement != *bOwningElement)
     126        return compareDeclarativeAnimationOwningElementPositionsInDocumentTreeOrder(*aOwningElement, *bOwningElement);
    110127
    111128    // Sort A and B based on their position in the computed value of the animation-name property of the (common) owning element.
    112     auto* cssAnimationList = aOwningElement.ensureKeyframeEffectStack().cssAnimationList();
     129    auto* cssAnimationList = aOwningElement->ensureKeyframeEffectStack().cssAnimationList();
    113130    ASSERT(cssAnimationList);
    114131    ASSERT(!cssAnimationList->isEmpty());
  • trunk/Source/WebCore/dom/Element.cpp

    r267345 r267571  
    22842284    RefPtr<Frame> frame = document().frame();
    22852285    if (auto* timeline = document().existingTimeline())
    2286         timeline->elementWasRemoved(*this);
     2286        timeline->elementWasRemoved({ *this, pseudoId() });
    22872287
    22882288#if ENABLE(WHEEL_EVENT_LATCHING)
     
    38043804#endif
    38053805
    3806 ElementAnimationRareData* Element::animationRareData() const
    3807 {
    3808     return hasRareData() ? elementRareData()->elementAnimationRareData() : nullptr;
    3809 }
    3810 
    3811 ElementAnimationRareData& Element::ensureAnimationRareData()
    3812 {
    3813     return ensureElementRareData().ensureAnimationRareData();
    3814 }
    3815 
    3816 KeyframeEffectStack* Element::keyframeEffectStack() const
    3817 {
    3818     if (auto* animationData = animationRareData())
     3806ElementAnimationRareData* Element::animationRareData(PseudoId pseudoId) const
     3807{
     3808    return hasRareData() ? elementRareData()->animationRareData(pseudoId) : nullptr;
     3809}
     3810
     3811ElementAnimationRareData& Element::ensureAnimationRareData(PseudoId pseudoId)
     3812{
     3813    return ensureElementRareData().ensureAnimationRareData(pseudoId);
     3814}
     3815
     3816KeyframeEffectStack* Element::keyframeEffectStack(PseudoId pseudoId) const
     3817{
     3818    if (auto* animationData = animationRareData(pseudoId))
    38193819        return animationData->keyframeEffectStack();
    38203820    return nullptr;
    38213821}
    38223822
    3823 KeyframeEffectStack& Element::ensureKeyframeEffectStack()
    3824 {
    3825     return ensureAnimationRareData().ensureKeyframeEffectStack();
    3826 }
    3827 
    3828 bool Element::hasKeyframeEffects() const
    3829 {
    3830     if (auto* animationData = animationRareData()) {
     3823KeyframeEffectStack& Element::ensureKeyframeEffectStack(PseudoId pseudoId)
     3824{
     3825    return ensureAnimationRareData(pseudoId).ensureKeyframeEffectStack();
     3826}
     3827
     3828bool Element::hasKeyframeEffects(PseudoId pseudoId) const
     3829{
     3830    if (auto* animationData = animationRareData(pseudoId)) {
    38313831        if (auto* keyframeEffectStack = animationData->keyframeEffectStack())
    38323832            return keyframeEffectStack->hasEffects();
     
    38353835}
    38363836
    3837 OptionSet<AnimationImpact> Element::applyKeyframeEffects(RenderStyle& targetStyle)
     3837OptionSet<AnimationImpact> Element::applyKeyframeEffects(PseudoId pseudoId, RenderStyle& targetStyle)
    38383838{
    38393839    OptionSet<AnimationImpact> impact;
    38403840
    3841     for (const auto& effect : ensureKeyframeEffectStack().sortedEffects()) {
     3841    for (const auto& effect : ensureKeyframeEffectStack(pseudoId).sortedEffects()) {
    38423842        ASSERT(effect->animation());
    38433843        effect->animation()->resolve(targetStyle);
     
    38533853}
    38543854
    3855 const AnimationCollection* Element::animations() const
    3856 {
    3857     if (auto* animationData = animationRareData())
     3855const AnimationCollection* Element::animations(PseudoId pseudoId) const
     3856{
     3857    if (auto* animationData = animationRareData(pseudoId))
    38583858        return &animationData->animations();
    38593859    return nullptr;
    38603860}
    38613861
    3862 bool Element::hasCompletedTransitionsForProperty(CSSPropertyID property) const
    3863 {
    3864     if (auto* animationData = animationRareData())
     3862bool Element::hasCompletedTransitionsForProperty(PseudoId pseudoId, CSSPropertyID property) const
     3863{
     3864    if (auto* animationData = animationRareData(pseudoId))
    38653865        return animationData->completedTransitionsByProperty().contains(property);
    38663866    return false;
    38673867}
    38683868
    3869 bool Element::hasRunningTransitionsForProperty(CSSPropertyID property) const
    3870 {
    3871     if (auto* animationData = animationRareData())
     3869bool Element::hasRunningTransitionsForProperty(PseudoId pseudoId, CSSPropertyID property) const
     3870{
     3871    if (auto* animationData = animationRareData(pseudoId))
    38723872        return animationData->runningTransitionsByProperty().contains(property);
    38733873    return false;
    38743874}
    38753875
    3876 bool Element::hasRunningTransitions() const
    3877 {
    3878     if (auto* animationData = animationRareData())
     3876bool Element::hasRunningTransitions(PseudoId pseudoId) const
     3877{
     3878    if (auto* animationData = animationRareData(pseudoId))
    38793879        return !animationData->runningTransitionsByProperty().isEmpty();
    38803880    return false;
    38813881}
    38823882
    3883 AnimationCollection& Element::ensureAnimations()
    3884 {
    3885     return ensureAnimationRareData().animations();
    3886 }
    3887 
    3888 CSSAnimationCollection& Element::animationsCreatedByMarkup()
    3889 {
    3890     return ensureAnimationRareData().animationsCreatedByMarkup();
    3891 }
    3892 
    3893 void Element::setAnimationsCreatedByMarkup(CSSAnimationCollection&& animations)
    3894 {
    3895     ensureAnimationRareData().setAnimationsCreatedByMarkup(WTFMove(animations));
    3896 }
    3897 
    3898 PropertyToTransitionMap& Element::ensureCompletedTransitionsByProperty()
    3899 {
    3900     return ensureAnimationRareData().completedTransitionsByProperty();
    3901 }
    3902 
    3903 PropertyToTransitionMap& Element::ensureRunningTransitionsByProperty()
    3904 {
    3905     return ensureAnimationRareData().runningTransitionsByProperty();
    3906 }
    3907 
    3908 const RenderStyle* Element::lastStyleChangeEventStyle() const
    3909 {
    3910     if (auto* animationData = animationRareData())
     3883AnimationCollection& Element::ensureAnimations(PseudoId pseudoId)
     3884{
     3885    return ensureAnimationRareData(pseudoId).animations();
     3886}
     3887
     3888CSSAnimationCollection& Element::animationsCreatedByMarkup(PseudoId pseudoId)
     3889{
     3890    return ensureAnimationRareData(pseudoId).animationsCreatedByMarkup();
     3891}
     3892
     3893void Element::setAnimationsCreatedByMarkup(PseudoId pseudoId, CSSAnimationCollection&& animations)
     3894{
     3895    ensureAnimationRareData(pseudoId).setAnimationsCreatedByMarkup(WTFMove(animations));
     3896}
     3897
     3898PropertyToTransitionMap& Element::ensureCompletedTransitionsByProperty(PseudoId pseudoId)
     3899{
     3900    return ensureAnimationRareData(pseudoId).completedTransitionsByProperty();
     3901}
     3902
     3903PropertyToTransitionMap& Element::ensureRunningTransitionsByProperty(PseudoId pseudoId)
     3904{
     3905    return ensureAnimationRareData(pseudoId).runningTransitionsByProperty();
     3906}
     3907
     3908const RenderStyle* Element::lastStyleChangeEventStyle(PseudoId pseudoId) const
     3909{
     3910    if (auto* animationData = animationRareData(pseudoId))
    39113911        return animationData->lastStyleChangeEventStyle();
    39123912    return nullptr;
    39133913}
    39143914
    3915 void Element::setLastStyleChangeEventStyle(std::unique_ptr<const RenderStyle>&& style)
    3916 {
    3917     if (auto* animationData = animationRareData())
     3915void Element::setLastStyleChangeEventStyle(PseudoId pseudoId, std::unique_ptr<const RenderStyle>&& style)
     3916{
     3917    if (auto* animationData = animationRareData(pseudoId))
    39183918        animationData->setLastStyleChangeEventStyle(WTFMove(style));
    39193919    else if (style)
    3920         ensureAnimationRareData().setLastStyleChangeEventStyle(WTFMove(style));
     3920        ensureAnimationRareData(pseudoId).setLastStyleChangeEventStyle(WTFMove(style));
    39213921}
    39223922
     
    45434543
    45444544    Vector<RefPtr<WebAnimation>> animations;
    4545     if (keyframeEffectStack()) {
    4546         for (auto& effect : keyframeEffectStack()->sortedEffects()) {
     4545    if (auto* effectStack = keyframeEffectStack(PseudoId::None)) {
     4546        for (auto& effect : effectStack->sortedEffects()) {
    45474547            if (effect->animation()->isRelevant())
    45484548                animations.append(effect->animation());
  • trunk/Source/WebCore/dom/Element.h

    r267377 r267571  
    487487    virtual void buildPendingResource() { };
    488488
    489     KeyframeEffectStack* keyframeEffectStack() const;
    490     KeyframeEffectStack& ensureKeyframeEffectStack();
    491     bool hasKeyframeEffects() const;
    492     OptionSet<AnimationImpact> applyKeyframeEffects(RenderStyle&);
    493 
    494     const AnimationCollection* animations() const;
    495     bool hasCompletedTransitionsForProperty(CSSPropertyID) const;
    496     bool hasRunningTransitionsForProperty(CSSPropertyID) const;
    497     bool hasRunningTransitions() const;
    498     AnimationCollection& ensureAnimations();
    499     PropertyToTransitionMap& ensureCompletedTransitionsByProperty();
    500     PropertyToTransitionMap& ensureRunningTransitionsByProperty();
    501     CSSAnimationCollection& animationsCreatedByMarkup();
    502     void setAnimationsCreatedByMarkup(CSSAnimationCollection&&);
    503 
    504     const RenderStyle* lastStyleChangeEventStyle() const;
    505     void setLastStyleChangeEventStyle(std::unique_ptr<const RenderStyle>&&);
     489    KeyframeEffectStack* keyframeEffectStack(PseudoId) const;
     490    KeyframeEffectStack& ensureKeyframeEffectStack(PseudoId);
     491    bool hasKeyframeEffects(PseudoId) const;
     492    OptionSet<AnimationImpact> applyKeyframeEffects(PseudoId, RenderStyle&);
     493
     494    const AnimationCollection* animations(PseudoId) const;
     495    bool hasCompletedTransitionsForProperty(PseudoId, CSSPropertyID) const;
     496    bool hasRunningTransitionsForProperty(PseudoId, CSSPropertyID) const;
     497    bool hasRunningTransitions(PseudoId) const;
     498    AnimationCollection& ensureAnimations(PseudoId);
     499
     500    PropertyToTransitionMap& ensureCompletedTransitionsByProperty(PseudoId);
     501    PropertyToTransitionMap& ensureRunningTransitionsByProperty(PseudoId);
     502    CSSAnimationCollection& animationsCreatedByMarkup(PseudoId);
     503    void setAnimationsCreatedByMarkup(PseudoId, CSSAnimationCollection&&);
     504
     505    const RenderStyle* lastStyleChangeEventStyle(PseudoId) const;
     506    void setLastStyleChangeEventStyle(PseudoId, std::unique_ptr<const RenderStyle>&&);
    506507
    507508#if ENABLE(FULLSCREEN_API)
     
    717718    ElementRareData& ensureElementRareData();
    718719
    719     ElementAnimationRareData* animationRareData() const;
    720     ElementAnimationRareData& ensureAnimationRareData();
     720    ElementAnimationRareData* animationRareData(PseudoId) const;
     721    ElementAnimationRareData& ensureAnimationRareData(PseudoId);
    721722
    722723    virtual int defaultTabIndex() const;
  • trunk/Source/WebCore/dom/ElementRareData.cpp

    r266769 r267571  
    3737    LayoutSize sizeForResizing;
    3838    IntPoint savedLayerScrollPosition;
    39     void* pointers[11];
     39    Vector<std::unique_ptr<ElementAnimationRareData>> animationRareData;
     40    void* pointers[10];
    4041#if ENABLE(INTERSECTION_OBSERVER)
    4142    void* intersectionObserverData;
  • trunk/Source/WebCore/dom/ElementRareData.h

    r266769 r267571  
    9090    void setSavedLayerScrollPosition(IntPoint position) { m_savedLayerScrollPosition = position; }
    9191
    92     ElementAnimationRareData* elementAnimationRareData() { return m_animationRareData.get(); }
    93     ElementAnimationRareData& ensureAnimationRareData();
     92    ElementAnimationRareData* animationRareData(PseudoId) const;
     93    ElementAnimationRareData& ensureAnimationRareData(PseudoId);
    9494
    9595    DOMTokenList* partList() const { return m_partList.get(); }
     
    142142            result.add(UseType::ResizeObserver);
    143143#endif
    144         if (m_animationRareData)
     144        if (!m_animationRareData.isEmpty())
    145145            result.add(UseType::Animations);
    146146        if (m_beforePseudoElement || m_afterPseudoElement)
     
    176176#endif
    177177
    178     std::unique_ptr<ElementAnimationRareData> m_animationRareData;
     178    Vector<std::unique_ptr<ElementAnimationRareData>> m_animationRareData;
    179179
    180180    RefPtr<PseudoElement> m_beforePseudoElement;
     
    238238}
    239239
    240 inline ElementAnimationRareData& ElementRareData::ensureAnimationRareData()
    241 {
    242     if (!m_animationRareData)
    243         m_animationRareData = makeUnique<ElementAnimationRareData>();
    244     return *m_animationRareData.get();
     240inline ElementAnimationRareData* ElementRareData::animationRareData(PseudoId pseudoId) const
     241{
     242    for (auto& animationRareData : m_animationRareData) {
     243        if (animationRareData->pseudoId() == pseudoId)
     244            return animationRareData.get();
     245    }
     246    return nullptr;
     247}
     248
     249inline ElementAnimationRareData& ElementRareData::ensureAnimationRareData(PseudoId pseudoId)
     250{
     251    if (auto* animationRareData = this->animationRareData(pseudoId))
     252        return *animationRareData;
     253
     254    m_animationRareData.append(makeUnique<ElementAnimationRareData>(pseudoId));
     255    return *m_animationRareData.last().get();
    245256}
    246257
  • trunk/Source/WebCore/dom/PseudoElement.cpp

    r267188 r267571  
    9191
    9292    if (auto* timeline = document().existingTimeline())
    93         timeline->elementWasRemoved(*this);
     93        timeline->elementWasRemoved(Styleable::fromElement(*this));
    9494   
    9595    m_hostElement = nullptr;
     
    103103bool PseudoElement::isTargetedByKeyframeEffectRequiringPseudoElement()
    104104{
    105     if (auto* stack = keyframeEffectStack())
    106         return stack->requiresPseudoElement();
     105    if (m_hostElement) {
     106        if (auto* stack = m_hostElement->keyframeEffectStack(pseudoId()))
     107            return stack->requiresPseudoElement();
     108    }
    107109    return false;
    108110}
  • trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp

    r266716 r267571  
    27092709    if (auto* node = element()) {
    27102710        if (auto* timeline = node->document().existingTimeline())
    2711             return timeline->runningAnimationsForElementAreAllAccelerated(*node);
     2711            return timeline->runningAnimationsForRendererAreAllAccelerated(*this);
    27122712    }
    27132713    return false;
  • trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp

    r267188 r267571  
    29602960        return false;
    29612961
    2962     if (auto* element = renderer.element()) {
    2963         if (auto* effectsStack = element->keyframeEffectStack()) {
     2962    if (auto styleable = Styleable::fromRenderer(renderer)) {
     2963        if (auto* effectsStack = styleable->keyframeEffectStack()) {
    29642964            return (effectsStack->isCurrentlyAffectingProperty(CSSPropertyOpacity)
    29652965                && (usesCompositing() || (m_compositingTriggers & ChromeClient::AnimatedOpacityTrigger)))
     
    34953495        return false;
    34963496
    3497     if (auto* element = renderer.element()) {
    3498         if (auto* effectsStack = element->keyframeEffectStack())
     3497    if (auto styleable = Styleable::fromRenderer(renderer)) {
     3498        if (auto* effectsStack = styleable->keyframeEffectStack())
    34993499            return effectsStack->isCurrentlyAffectingProperty(CSSPropertyTransform);
    35003500    }
  • trunk/Source/WebCore/rendering/style/RenderStyleConstants.cpp

    r262620 r267571  
    944944    case PseudoId::FirstLine: ts << "first-line"; break;
    945945    case PseudoId::FirstLetter: ts << "first-letter"; break;
     946    case PseudoId::Highlight: ts << "highlight"; break;
    946947    case PseudoId::Marker: ts << "marker"; break;
    947948    case PseudoId::Before: ts << "before"; break;
  • trunk/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp

    r267191 r267571  
    559559                if (timeline) {
    560560                    if (document.renderTreeBeingDestroyed())
    561                         timeline->cancelDeclarativeAnimationsForElement(element, WebAnimation::Silently::Yes);
     561                        timeline->cancelDeclarativeAnimationsForStyleable(Styleable::fromElement(element), WebAnimation::Silently::Yes);
    562562                    else if (teardownType == TeardownType::RendererUpdateCancelingAnimations)
    563                         timeline->cancelDeclarativeAnimationsForElement(element, WebAnimation::Silently::No);
     563                        timeline->cancelDeclarativeAnimationsForStyleable(Styleable::fromElement(element), WebAnimation::Silently::No);
    564564                }
    565565                break;
    566566            case TeardownType::RendererUpdate:
    567567                if (timeline)
    568                     timeline->willChangeRendererForElement(element);
     568                    timeline->willChangeRendererForStyleable(Styleable::fromElement(element));
    569569                break;
    570570            }
  • trunk/Source/WebCore/style/StyleTreeResolver.cpp

    r267191 r267571  
    218218    }
    219219
    220     auto update = createAnimatedElementUpdate(WTFMove(newStyle), element, parent().change);
     220    auto update = createAnimatedElementUpdate(WTFMove(newStyle), { element, PseudoId::None }, parent().change);
    221221    auto descendantsToResolve = computeDescendantsToResolve(update.change, element.styleValidity(), parent().descendantsToResolve);
    222222
     
    278278        return { };
    279279
    280     return createAnimatedElementUpdate(WTFMove(pseudoStyle), element.ensurePseudoElement(pseudoId), elementUpdate.change);
     280    return createAnimatedElementUpdate(WTFMove(pseudoStyle), { element, pseudoId }, elementUpdate.change);
    281281}
    282282
     
    307307}
    308308
    309 ElementUpdate TreeResolver::createAnimatedElementUpdate(std::unique_ptr<RenderStyle> newStyle, Element& element, Change parentChange)
    310 {
    311     auto* oldStyle = element.renderOrDisplayContentsStyle();
     309ElementUpdate TreeResolver::createAnimatedElementUpdate(std::unique_ptr<RenderStyle> newStyle, const Styleable& styleable, Change parentChange)
     310{
     311    auto& element = styleable.element;
     312
     313    // FIXME: Ideally we could just call Element::renderOrDisplayContentsStyle() with a PseudoId
     314    // and get the style for any PseudoId, not just PseudoId::Before or PseudoId::After.
     315    auto* pseudoElement = [styleable]() -> PseudoElement* {
     316        switch (styleable.pseudoId) {
     317        case PseudoId::Before:
     318            return styleable.element.beforePseudoElement();
     319        case PseudoId::After:
     320            return styleable.element.afterPseudoElement();
     321        default:
     322            return nullptr;
     323        }
     324    }();
     325    auto* oldStyle = pseudoElement ? pseudoElement->renderOrDisplayContentsStyle() : element.renderOrDisplayContentsStyle();
    312326
    313327    OptionSet<AnimationImpact> animationImpact;
     
    318332    if (element.document().backForwardCacheState() == Document::NotInBackForwardCache && !element.document().renderView()->printing()) {
    319333        if (oldStyle && (oldStyle->hasTransitions() || newStyle->hasTransitions()))
    320             m_document.timeline().updateCSSTransitionsForElement(element, *oldStyle, *newStyle);
     334            m_document.timeline().updateCSSTransitionsForStyleable(styleable, *oldStyle, *newStyle);
    321335
    322336        // The order in which CSS Transitions and CSS Animations are updated matters since CSS Transitions define the after-change style
     
    324338        // such that when CSS Transitions are updated the CSS Animations data is the same as during the previous style change event.
    325339        if ((oldStyle && oldStyle->hasAnimations()) || newStyle->hasAnimations()) {
    326             // FIXME: Remove this hack and pass the parent style via updateCSSAnimationsForElement.
     340            // FIXME: Remove this hack and pass the parent style via updateCSSAnimationsForStyleable.
    327341            scope().resolver.setParentElementStyleForKeyframes(&parent().style);
    328342
    329             m_document.timeline().updateCSSAnimationsForElement(element, oldStyle, *newStyle);
     343            m_document.timeline().updateCSSAnimationsForStyleable(styleable, oldStyle, *newStyle);
    330344
    331345            scope().resolver.setParentElementStyleForKeyframes(nullptr);
     
    335349    // Now we can update all Web animations, which will include CSS Animations as well
    336350    // as animations created via the JS API.
    337     if (element.hasKeyframeEffects()) {
     351    if (styleable.hasKeyframeEffects()) {
    338352        // Record the style prior to applying animations for this style change event.
    339         element.setLastStyleChangeEventStyle(RenderStyle::clonePtr(*newStyle));
     353        styleable.setLastStyleChangeEventStyle(RenderStyle::clonePtr(*newStyle));
    340354        // Apply all keyframe effects to the new style.
    341355        auto animatedStyle = RenderStyle::clonePtr(*newStyle);
    342         animationImpact = element.applyKeyframeEffects(*animatedStyle);
     356        animationImpact = styleable.applyKeyframeEffects(*animatedStyle);
    343357        newStyle = WTFMove(animatedStyle);
    344358    } else
    345         element.setLastStyleChangeEventStyle(nullptr);
     359        styleable.setLastStyleChangeEventStyle(nullptr);
    346360
    347361    if (animationImpact)
  • trunk/Source/WebCore/style/StyleTreeResolver.h

    r267191 r267571  
    3131#include "StyleSharingResolver.h"
    3232#include "StyleUpdate.h"
     33#include "Styleable.h"
    3334#include <wtf/Function.h>
    3435#include <wtf/Ref.h>
     
    6162    ElementUpdates resolveElement(Element&);
    6263
    63     ElementUpdate createAnimatedElementUpdate(std::unique_ptr<RenderStyle>, Element&, Change);
     64    ElementUpdate createAnimatedElementUpdate(std::unique_ptr<RenderStyle>, const Styleable&, Change);
    6465    ElementUpdate resolvePseudoStyle(Element&, const ElementUpdate&, PseudoId);
    6566
Note: See TracChangeset for help on using the changeset viewer.