Diff
Modified: trunk/LayoutTests/ChangeLog (232945 => 232946)
--- trunk/LayoutTests/ChangeLog 2018-06-18 21:14:40 UTC (rev 232945)
+++ trunk/LayoutTests/ChangeLog 2018-06-18 21:20:47 UTC (rev 232946)
@@ -1,3 +1,28 @@
+2018-06-18 Antoine Quint <[email protected]>
+
+ [Web Animations] Implement "Starting of transitions" section from CSS Transitions
+ https://bugs.webkit.org/show_bug.cgi?id=186517
+ <rdar://problem/41000798>
+
+ Reviewed by Dean Jackson.
+
+ Implementing the CSS Transitions spec for starting transitions highlighted a couple of issues with existing tests.
+
+ * TestExpectations: The test imported/mozilla/css-transitions/test_animation-ready.html now passes reliably.
+ * animations/transition-and-animation-3-expected.txt:
+ * animations/transition-and-animation-3.html: This test was mistakenly expecting a retargeted transition to pick
+ up from the underlying value (100px) rather than the interrupted transition's value (~0px). We update the test
+ to be more obvious about what it is testing and with the correct behavior per the spec.
+ * transitions/background-position-transitions-expected.txt:
+ * transitions/background-position-transitions.html: Shorthand properties are expected to yield a transitiong for
+ each shorthand property, so we update this test to check the background-position shorthand properties.
+ * transitions/resources/transition-test-helpers.js: We uncovered a crash, which is not new to this patch, that forces
+ us to work around using the background-position longhand properties. So we work around this by reading from the shorthand
+ background-position property and manually parsing the value. Fixing this crash is tracked by webkit.org/b/186766.
+ * transitions/transition-to-from-auto-expected.txt:
+ * transitions/transition-to-from-auto.html: Update the test to check that we only yield transitions when interpolating
+ between non-auto values, as mandated by the spec.
+
2018-06-18 Said Abou-Hallawa <[email protected]>
Document should not be mutated under SMILTimeContainer::updateAnimations()
Modified: trunk/LayoutTests/TestExpectations (232945 => 232946)
--- trunk/LayoutTests/TestExpectations 2018-06-18 21:14:40 UTC (rev 232945)
+++ trunk/LayoutTests/TestExpectations 2018-06-18 21:20:47 UTC (rev 232946)
@@ -1932,7 +1932,6 @@
webkit.org/b/183826 imported/mozilla/css-animations/test_animation-pausing.html [ Pass Failure Timeout ]
webkit.org/b/183828 imported/mozilla/css-animations/test_animation-playstate.html [ Pass Failure Timeout ]
webkit.org/b/183830 imported/mozilla/css-animations/test_animation-ready.html [ Pass Failure Timeout ]
-webkit.org/b/183831 imported/mozilla/css-transitions/test_animation-ready.html [ Pass Failure Timeout ]
webkit.org/b/183834 imported/mozilla/css-animations/test_animation-starttime.html [ Pass Failure Timeout ]
webkit.org/b/183836 imported/mozilla/css-animations/test_animations-dynamic-changes.html [ Pass Failure Timeout ]
webkit.org/b/183837 imported/mozilla/css-transitions/test_document-get-animations.html [ Pass Failure Timeout ]
Modified: trunk/LayoutTests/animations/transition-and-animation-3-expected.txt (232945 => 232946)
--- trunk/LayoutTests/animations/transition-and-animation-3-expected.txt 2018-06-18 21:14:40 UTC (rev 232945)
+++ trunk/LayoutTests/animations/transition-and-animation-3-expected.txt 2018-06-18 21:20:47 UTC (rev 232946)
@@ -1,4 +1,13 @@
-Once animation has finished, box should be running left transition from 100px to 200px.
+Once animation has finished, box should be running left transition from 0px to 200px.
-PASS - "left" property for "test" element at 0.2s saw something close to: 100
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS animations.length is 1
+PASS animations[0] instanceof CSSTransition is true
+PASS animations[0].effect.getKeyframes()[0].left is not "100px"
+PASS animations[0].effect.getKeyframes()[1].left is "200px"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Modified: trunk/LayoutTests/animations/transition-and-animation-3.html (232945 => 232946)
--- trunk/LayoutTests/animations/transition-and-animation-3.html 2018-06-18 21:14:40 UTC (rev 232945)
+++ trunk/LayoutTests/animations/transition-and-animation-3.html 2018-06-18 21:20:47 UTC (rev 232946)
@@ -11,58 +11,62 @@
background-color: blue;
}
- .box.animating {
- -webkit-animation: move 0.1s linear;
+ .box.transitioning {
+ transition: left 10s linear;
left: 100px;
- -webkit-transition: left 10s linear;
}
+
+ .box.animating {
+ animation: move 0.1s linear;
+ }
- /* When the animation is done, the box should be running a transition from 100px to 200px */
- .box.animating.moved {
+ .box.retargeted {
left: 200px;
}
- @-webkit-keyframes move {
- from {
- left: 500px;
- }
- to {
- left: 501px;
- }
+ @keyframes move {
+ from { left: 500px }
+ to { left: 501px }
}
- #result {
- margin-top: 130px;
- }
</style>
- <script src="" type="text/_javascript_" charset="utf-8"></script>
+ <script src=""
+</head>
+<body>
+ <div id="test" class="box"></div>
<script type="text/_javascript_" charset="utf-8">
- const expectedValues = [
- // [animation-name, time, element-id, property, expected-value, tolerance]
- [null, 0.2, "test", "left", 100, 10],
- ];
+ description("Once animation has finished, box should be running left transition from 0px to 200px.");
- function animationStarted()
- {
- document.getElementById('test').className = 'animating moved box';
- }
+ window.jsTestIsAsync = true;
- function setupTest()
- {
- document.getElementById('test').className = 'animating box';
- runAnimationTest(expectedValues, animationStarted);
- }
-
- window.addEventListener('load', function() {
- window.setTimeout(setupTest, 0);
- }, false);
+ let animations;
+ const testElement = document.getElementById('test');
+ // Start the test by starting a transition from 0 to 100px.
+ window.setTimeout(() => testElement.classList.add("transitioning"));
+
+ // Then, once the transition has started, start an animation.
+ testElement.addEventListener("transitionstart", event => {
+ setTimeout(() => testElement.classList.add("animating"));
+ });
+
+ // Then wait for the animation to start and change the underlying left value.
+ testElement.addEventListener("animationstart", event => {
+ testElement.classList.add("retargeted");
+ });
+
+ // When the animation has ended, check that we're transitioning from ~0 > 200, and not 100 > 200.
+ testElement.addEventListener("animationend", event => {
+ animations = testElement.getAnimations();
+ shouldBe("animations.length", "1");
+ shouldBeTrue("animations[0] instanceof CSSTransition");
+ shouldNotBeEqualToString("animations[0].effect.getKeyframes()[0].left", "100px");
+ shouldBeEqualToString("animations[0].effect.getKeyframes()[1].left", "200px");
+ finishJSTest();
+ });
+
</script>
-</head>
-<body>
- <p>Once animation has finished, box should be running left transition from 100px to 200px.</p>
- <div id="test" class="box"></div>
- <div id="result"></div>
+ <script src=""
</body>
</html>
Modified: trunk/LayoutTests/imported/mozilla/ChangeLog (232945 => 232946)
--- trunk/LayoutTests/imported/mozilla/ChangeLog 2018-06-18 21:14:40 UTC (rev 232945)
+++ trunk/LayoutTests/imported/mozilla/ChangeLog 2018-06-18 21:20:47 UTC (rev 232946)
@@ -1,3 +1,16 @@
+2018-06-18 Antoine Quint <[email protected]>
+
+ [Web Animations] Implement "Starting of transitions" section from CSS Transitions
+ https://bugs.webkit.org/show_bug.cgi?id=186517
+ <rdar://problem/41000798>
+
+ Reviewed by Dean Jackson.
+
+ Mark some progressions in the Mozilla CSS Animations and CSS Transitions tests.
+
+ * css-transitions/test_animation-cancel-expected.txt:
+ * css-transitions/test_animation-ready-expected.txt:
+
2018-06-15 Antoine Quint <[email protected]>
[Web Animations] CSS Animations should take precedence over CSS Transitions
Modified: trunk/LayoutTests/imported/mozilla/css-transitions/test_animation-cancel-expected.txt (232945 => 232946)
--- trunk/LayoutTests/imported/mozilla/css-transitions/test_animation-cancel-expected.txt 2018-06-18 21:14:40 UTC (rev 232945)
+++ trunk/LayoutTests/imported/mozilla/css-transitions/test_animation-cancel-expected.txt 2018-06-18 21:20:47 UTC (rev 232946)
@@ -4,10 +4,10 @@
PASS After cancelling a finished transition, it can still be re-used
PASS After cancelling a transition, updating transition properties doesn't make it live again
PASS Setting display:none on an element cancels its transitions
-PASS Setting display:none cancels transitions on a child element
+FAIL Setting display:none cancels transitions on a child element assert_equals: expected "idle" but got "running"
PASS Removing a property from transition-property cancels transitions on that property
PASS Setting zero combined duration
-FAIL Changing style to another interpolable value cancels the original transition assert_equals: expected "idle" but got "finished"
-FAIL An after-change style value can't be interpolated assert_equals: There should be no transitions expected 0 but got 1
-FAIL Reversing a running transition cancels the original transition assert_equals: expected "idle" but got "running"
+PASS Changing style to another interpolable value cancels the original transition
+PASS An after-change style value can't be interpolated
+PASS Reversing a running transition cancels the original transition
Modified: trunk/LayoutTests/imported/mozilla/css-transitions/test_animation-ready-expected.txt (232945 => 232946)
--- trunk/LayoutTests/imported/mozilla/css-transitions/test_animation-ready-expected.txt 2018-06-18 21:14:40 UTC (rev 232945)
+++ trunk/LayoutTests/imported/mozilla/css-transitions/test_animation-ready-expected.txt 2018-06-18 21:20:47 UTC (rev 232946)
@@ -1,5 +1,5 @@
PASS A new ready promise is created each time play() is called the animation property
PASS ready promise is rejected when a transition is cancelled by updating transition-property
-FAIL ready promise is rejected when a transition is cancelled by changing the transition property to something not interpolable assert_equals: Animation is idle after transition was cancelled expected "idle" but got "paused"
+PASS ready promise is rejected when a transition is cancelled by changing the transition property to something not interpolable
Modified: trunk/LayoutTests/transitions/background-position-transitions-expected.txt (232945 => 232946)
--- trunk/LayoutTests/transitions/background-position-transitions-expected.txt 2018-06-18 21:14:40 UTC (rev 232945)
+++ trunk/LayoutTests/transitions/background-position-transitions-expected.txt 2018-06-18 21:20:47 UTC (rev 232946)
@@ -1,4 +1,7 @@
-PASS - "background-position" property for "box1" element at 0.5s saw something close to: 45,60
-PASS - "background-position" property for "box2" element at 0.5s saw something close to: 45,60
-PASS - "background-position" property for "box3" element at 0.5s saw something close to: 10,0.5,100,80,0,0.5,20,0.5,100,100,0,0.5
+PASS - "background-position-x" property for "box1" element at 0.5s saw something close to: 45px
+PASS - "background-position-y" property for "box1" element at 0.5s saw something close to: 60px
+PASS - "background-position-x" property for "box2" element at 0.5s saw something close to: 45px
+PASS - "background-position-y" property for "box2" element at 0.5s saw something close to: 60px
+PASS - "background-position-x" property for "box3" element at 0.5s saw something close to: calc((10px * 0.5) + ((100% - 80px) * 0.5))
+PASS - "background-position-y" property for "box3" element at 0.5s saw something close to: calc((20px * 0.5) + ((100% - 100px) * 0.5))
Modified: trunk/LayoutTests/transitions/background-position-transitions.html (232945 => 232946)
--- trunk/LayoutTests/transitions/background-position-transitions.html 2018-06-18 21:14:40 UTC (rev 232945)
+++ trunk/LayoutTests/transitions/background-position-transitions.html 2018-06-18 21:20:47 UTC (rev 232946)
@@ -41,9 +41,12 @@
<script>
const expectedValues = [
// [time, element-id, property, expected-value, tolerance]
- [0.5, 'box1', 'background-position', [45, 60], 2],
- [0.5, 'box2', 'background-position', [45, 60], 2],
- [0.5, 'box3', 'background-position', [10,0.5,100,80,0,0.5,20,0.5,100,100,0,0.5], 2], // Numbers extracted from a calc() _expression_.
+ [0.5, 'box1', 'background-position-x', "45px"],
+ [0.5, 'box1', 'background-position-y', "60px"],
+ [0.5, 'box2', 'background-position-x', "45px"],
+ [0.5, 'box2', 'background-position-y', "60px"],
+ [0.5, 'box3', 'background-position-x', "calc((10px * 0.5) + ((100% - 80px) * 0.5))"],
+ [0.5, 'box3', 'background-position-y', "calc((20px * 0.5) + ((100% - 100px) * 0.5))"],
];
function setupTest()
Modified: trunk/LayoutTests/transitions/resources/transition-test-helpers.js (232945 => 232946)
--- trunk/LayoutTests/transitions/resources/transition-test-helpers.js 2018-06-18 21:14:40 UTC (rev 232945)
+++ trunk/LayoutTests/transitions/resources/transition-test-helpers.js 2018-06-18 21:20:47 UTC (rev 232946)
@@ -213,6 +213,30 @@
break;
}
}
+ } else if (property == "background-position-x" || property == "background-position-y") {
+ computedValue = window.getComputedStyle(document.getElementById(elementId)).backgroundPosition;
+
+ const leftCharIndex = computedValue.indexOf("left");
+ const rightCharIndex = computedValue.indexOf("right");
+ const topCharIndex = computedValue.indexOf("top");
+ const bottomCharIndex = computedValue.indexOf("bottom");
+
+ let firstCharIndex, lastCharIndex;
+ if (property == "background-position-x") {
+ if (computedValue.startsWith("left"))
+ firstCharIndex = 4;
+ else if (computedValue.startsWith("right"))
+ firstCharIndex = 5;
+ lastCharIndex = Math.max(topCharIndex, bottomCharIndex);
+ } else {
+ if (topCharIndex > -1)
+ firstCharIndex = topCharIndex + 3;
+ else
+ firstCharIndex = bottomCharIndex + 6;
+ lastCharIndex = computedValue.length;
+ }
+
+ pass = computedValue.substring(firstCharIndex, lastCharIndex).trim() == expectedValue;
} else if (property == "fill" || property == "stroke") {
computedValue = window.getComputedStyle(document.getElementById(elementId)).getPropertyCSSValue(property).rgbColor;
if (compareRGB([computedValue.red.cssText, computedValue.green.cssText, computedValue.blue.cssText], expectedValue, tolerance))
Modified: trunk/LayoutTests/transitions/transition-to-from-auto-expected.txt (232945 => 232946)
--- trunk/LayoutTests/transitions/transition-to-from-auto-expected.txt 2018-06-18 21:14:40 UTC (rev 232945)
+++ trunk/LayoutTests/transitions/transition-to-from-auto-expected.txt 2018-06-18 21:20:47 UTC (rev 232946)
@@ -1,4 +1,3 @@
-PASS - "left" property for "test1" element at 1s saw something close to: 0
-PASS - "left" property for "test2" element at 1s saw something close to: 100
+Total number of animations: 1
PASS - "left" property for "test3" element at 1s saw something close to: 50
Modified: trunk/LayoutTests/transitions/transition-to-from-auto.html (232945 => 232946)
--- trunk/LayoutTests/transitions/transition-to-from-auto.html 2018-06-18 21:14:40 UTC (rev 232945)
+++ trunk/LayoutTests/transitions/transition-to-from-auto.html 2018-06-18 21:20:47 UTC (rev 232946)
@@ -41,8 +41,6 @@
const expectedValues = [
// [time, element-id, property, expected-value, tolerance]
- [1, 'test1', 'left', '0', 2],
- [1, 'test2', 'left', '100', 2],
[1, 'test3', 'left', '50', 2],
];
@@ -49,6 +47,7 @@
function setupTest()
{
document.body.classList.add('final');
+ result += `Total number of animations: ${document.getAnimations().length} <br>`;
}
runTransitionTest(expectedValues, setupTest, usePauseAPI);
Modified: trunk/Source/WebCore/ChangeLog (232945 => 232946)
--- trunk/Source/WebCore/ChangeLog 2018-06-18 21:14:40 UTC (rev 232945)
+++ trunk/Source/WebCore/ChangeLog 2018-06-18 21:20:47 UTC (rev 232946)
@@ -1,3 +1,65 @@
+2018-06-18 Antoine Quint <[email protected]>
+
+ [Web Animations] Implement "Starting of transitions" section from CSS Transitions
+ https://bugs.webkit.org/show_bug.cgi?id=186517
+ <rdar://problem/41000798>
+
+ Reviewed by Dean Jackson.
+
+ We implement the whole section at https://drafts.csswg.org/css-transitions-1/#starting so that we have spec-compliant starting of CSS Transitions.
+ To correctly implement this we now maintain two maps of transitions for a given property, a set of running transitions (m_elementToRunningCSSTransitionByCSSPropertyID)
+ and a set of completed transition (m_elementToCompletedCSSTransitionByCSSPropertyID).
+
+ * animation/AnimationTimeline.cpp:
+ (WebCore::removeCSSTransitionFromMap): Add a utility to remove a CSSTransition from one of the two HashMap<Element*, HashMap<CSSPropertyID, RefPtr<CSSTransition>>>
+ managed by AnimationTimeline (m_elementToRunningCSSTransitionByCSSPropertyID and m_elementToCompletedCSSTransitionByCSSPropertyID).
+ (WebCore::AnimationTimeline::animationWasRemovedFromElement): Use the new removeCSSTransitionFromMap() utility.
+ (WebCore::AnimationTimeline::updateCSSAnimationsForElement): We rename "oldStyle" to "currentStyle" to align with the naming used by updateCSSAnimationsForElement().
+ We also remove an initial check that has been pushed up to Style::TreeResolver::createAnimatedElementUpdate().
+ (WebCore::propertyInStyleMatchesValueForTransitionInMap): When running the steps mandated by the spec we often need to check whether a given property has a transition
+ in an AnimationList that matches the value used in a given RenderStyle.
+ (WebCore::transitionCombinedDuration): We need to compute the combined duration twice while running the steps mandated by the spec, so we have a dedicated utility.
+ (WebCore::transitionMatchesProperty): New utility that indicates whether a WebCore::Animation matches a given property, by virtue of targeting it directly, targeting
+ a shorthand for which this property is a longhand, or targeting "all".
+ (WebCore::AnimationTimeline::updateCSSTransitionsForElement): This is where all of the new implementation for starting transitions happens. We implement the steps
+ as they appear in the spec.
+ (WebCore::shouldBackingAnimationBeConsideredForCSSTransition): Deleted.
+ * animation/AnimationTimeline.h:
+ * animation/CSSAnimation.cpp:
+ (WebCore::CSSAnimation::syncPropertiesWithBackingAnimation): Since only CSS Animations respect the delay and duration values as parsed directly in a WebCore:Animation
+ object, we move code that was previously in DeclarativeAnimation::syncPropertiesWithBackingAnimation to this method. CSS Transitions set those values based on the
+ delay and duration parameters passed to CSSTransition::create() and computed in AnimationTimeline::updateCSSTransitionsForElement().
+ * animation/CSSTransition.cpp:
+ (WebCore::CSSTransition::create): Since the transition's delay and duration is computed in AnimationTimeline::updateCSSTransitionsForElement(), we now require them
+ to be passed when creating a CSSTransition and pass those to the new setTimingProperties() function. We also expect a target style and reversing-adjusted start style,
+ as well as a reversing-shortening factor.
+ (WebCore::CSSTransition::CSSTransition):
+ (WebCore::CSSTransition::resolve): We need to be able to query the last style computed by a call to resolve() from AnimationTimeline::updateCSSTransitionsForElement(),
+ we subclass this newly-virtual WebAnimation method and clone the style after we blended the property targeted by this transition.
+ (WebCore::CSSTransition::setTimingProperties): Set the transition delay and duration as provided in the call to create().
+ (WebCore::CSSTransition::canBeListed const): Fix a crash that was found while working on this bug where we could access a null effect.
+ (WebCore::CSSTransition::initialize): Deleted.
+ (WebCore::CSSTransition::matchesBackingAnimationAndStyles const): Deleted.
+ * animation/CSSTransition.h:
+ * animation/DeclarativeAnimation.cpp:
+ (WebCore::DeclarativeAnimation::syncPropertiesWithBackingAnimation): This virtual method now has an empty definition since the timing properties are now only set
+ for CSSAnimation.
+ * animation/KeyframeEffectReadOnly.cpp:
+ (WebCore::KeyframeEffectReadOnly::stylesWouldYieldNewCSSTransitionsBlendingKeyframes const): Deleted.
+ * animation/KeyframeEffectReadOnly.h:
+ * animation/WebAnimation.h:
+ * page/animation/CSSPropertyAnimation.cpp:
+ (WebCore::AnimationPropertyWrapperBase::canInterpolate const): Since we need to be able to determine whether some property values can be interpolated, we add a new
+ canInterpolate() method to the base wrapper class so the cases where we can't interpolate values (length with an "auto" type) may return false.
+ (WebCore::LengthPropertyWrapper::LengthPropertyWrapper): Lengths can only be interpolated if both the start and end values are not "auto".
+ (WebCore::LengthVariantPropertyWrapper::LengthVariantPropertyWrapper):
+ (WebCore::CSSPropertyAnimationWrapperMap::CSSPropertyAnimationWrapperMap):
+ (WebCore::CSSPropertyAnimation::canPropertyBeInterpolated):
+ * page/animation/CSSPropertyAnimation.h:
+ * style/StyleTreeResolver.cpp:
+ (WebCore::Style::TreeResolver::createAnimatedElementUpdate): Move a check found in both updateCSSAnimationsForElement() and updateCSSTransitionsForElement() to their
+ shared call site.
+
2018-06-18 Nan Wang <[email protected]>
AX: [macOS] When zoom is enabled, focus doesn't follow text cursor
Modified: trunk/Source/WebCore/animation/AnimationTimeline.cpp (232945 => 232946)
--- trunk/Source/WebCore/animation/AnimationTimeline.cpp 2018-06-18 21:14:40 UTC (rev 232945)
+++ trunk/Source/WebCore/animation/AnimationTimeline.cpp 2018-06-18 21:20:47 UTC (rev 232946)
@@ -38,6 +38,7 @@
#include "KeyframeEffectReadOnly.h"
#include "RenderStyle.h"
#include "RenderView.h"
+#include "StylePropertyShorthand.h"
#include "WebAnimationUtilities.h"
#include <wtf/text/TextStream.h>
#include <wtf/text/WTFString.h>
@@ -95,10 +96,24 @@
}).iterator->value.add(&animation);
}
+static inline bool removeCSSTransitionFromMap(CSSTransition& transition, Element& element, HashMap<Element*, HashMap<CSSPropertyID, RefPtr<CSSTransition>>>& map)
+{
+ auto iterator = map.find(&element);
+ if (iterator == map.end())
+ return false;
+
+ auto& cssTransitionsByProperty = iterator->value;
+ cssTransitionsByProperty.remove(transition.property());
+ if (cssTransitionsByProperty.isEmpty())
+ map.remove(&element);
+ return true;
+}
+
void AnimationTimeline::animationWasRemovedFromElement(WebAnimation& animation, Element& element)
{
- // First, we clear this animation from one of the m_elementToCSSAnimationsMap, m_elementToCSSTransitionsMap
- // or m_elementToAnimationsMap map, whichever is relevant to this type of animation.
+ // First, we clear this animation from one of the m_elementToCSSAnimationsMap, m_elementToCSSTransitionsMap,
+ // m_elementToAnimationsMap or m_elementToCompletedCSSTransitionByCSSPropertyID map, whichever is relevant to
+ // this type of animation.
auto& map = relevantMapForAnimation(animation);
auto iterator = map.find(&element);
if (iterator == map.end())
@@ -110,7 +125,7 @@
map.remove(iterator);
// Now, if we're dealing with a declarative animation, we remove it from either the m_elementToCSSAnimationByName
- // or the m_elementToCSSTransitionByCSSPropertyID map, whichever is relevant to this type of animation.
+ // or the m_elementToRunningCSSTransitionByCSSPropertyID map, whichever is relevant to this type of animation.
if (is<CSSAnimation>(animation)) {
auto iterator = m_elementToCSSAnimationByName.find(&element);
if (iterator != m_elementToCSSAnimationByName.end()) {
@@ -121,14 +136,9 @@
m_elementToCSSAnimationByName.remove(&element);
}
} else if (is<CSSTransition>(animation)) {
- auto iterator = m_elementToCSSTransitionByCSSPropertyID.find(&element);
- if (iterator != m_elementToCSSTransitionByCSSPropertyID.end()) {
- auto& cssTransitionsByProperty = iterator->value;
- auto property = downcast<CSSTransition>(animation).property();
- cssTransitionsByProperty.remove(property);
- if (cssTransitionsByProperty.isEmpty())
- m_elementToCSSTransitionByCSSPropertyID.remove(&element);
- }
+ auto& transition = downcast<CSSTransition>(animation);
+ if (!removeCSSTransitionFromMap(transition, element, m_elementToRunningCSSTransitionByCSSPropertyID))
+ removeCSSTransitionFromMap(transition, element, m_elementToCompletedCSSTransitionByCSSPropertyID);
}
}
@@ -158,16 +168,10 @@
}
}
-void AnimationTimeline::updateCSSAnimationsForElement(Element& element, const RenderStyle& newStyle, const RenderStyle* oldStyle)
+void AnimationTimeline::updateCSSAnimationsForElement(Element& element, const RenderStyle* currentStyle, const RenderStyle& afterChangeStyle)
{
- if (element.document().pageCacheState() != Document::NotInPageCache)
- return;
-
- if (element.document().renderView()->printing())
- return;
-
// In case this element is newly getting a "display: none" we need to cancel all of its animations and disregard new ones.
- if (oldStyle && oldStyle->hasAnimations() && oldStyle->display() != DisplayType::None && newStyle.display() == DisplayType::None) {
+ if (currentStyle && currentStyle->hasAnimations() && currentStyle->display() != DisplayType::None && afterChangeStyle.display() == DisplayType::None) {
if (m_elementToCSSAnimationByName.contains(&element)) {
for (const auto& cssAnimationsByNameMapItem : m_elementToCSSAnimationByName.take(&element))
cancelOrRemoveDeclarativeAnimation(cssAnimationsByNameMapItem.value);
@@ -175,13 +179,13 @@
return;
}
- if (oldStyle && oldStyle->hasAnimations() && newStyle.hasAnimations() && *(oldStyle->animations()) == *(newStyle.animations()))
+ if (currentStyle && currentStyle->hasAnimations() && afterChangeStyle.hasAnimations() && *(currentStyle->animations()) == *(afterChangeStyle.animations()))
return;
// First, compile the list of animation names that were applied to this element up to this point.
HashSet<String> namesOfPreviousAnimations;
- if (oldStyle && oldStyle->hasAnimations()) {
- auto* previousAnimations = oldStyle->animations();
+ if (currentStyle && currentStyle->hasAnimations()) {
+ auto* previousAnimations = currentStyle->animations();
for (size_t i = 0; i < previousAnimations->size(); ++i) {
auto& previousAnimation = previousAnimations->animation(i);
if (previousAnimation.isValidAnimation())
@@ -194,7 +198,7 @@
return HashMap<String, RefPtr<CSSAnimation>> { };
}).iterator->value;
- if (auto* currentAnimations = newStyle.animations()) {
+ if (auto* currentAnimations = afterChangeStyle.animations()) {
for (size_t i = 0; i < currentAnimations->size(); ++i) {
auto& currentAnimation = currentAnimations->animation(i);
auto& name = currentAnimation.name();
@@ -205,7 +209,7 @@
cssAnimationsByName.get(name)->setBackingAnimation(currentAnimation);
} else if (currentAnimation.isValidAnimation()) {
// Otherwise we are dealing with a new animation name and must create a CSSAnimation for it.
- cssAnimationsByName.set(name, CSSAnimation::create(element, currentAnimation, oldStyle, newStyle));
+ cssAnimationsByName.set(name, CSSAnimation::create(element, currentAnimation, currentStyle, afterChangeStyle));
}
// Remove the name of this animation from our list since it's now known to be current.
namesOfPreviousAnimations.remove(name);
@@ -233,109 +237,183 @@
return matchingAnimation;
}
-static bool shouldBackingAnimationBeConsideredForCSSTransition(const Animation& backingAnimation)
+static bool propertyInStyleMatchesValueForTransitionInMap(CSSPropertyID property, const RenderStyle& style, HashMap<CSSPropertyID, RefPtr<CSSTransition>>& transitions)
{
- auto mode = backingAnimation.animationMode();
+ if (auto* transition = transitions.get(property)) {
+ if (CSSPropertyAnimation::propertiesEqual(property, &style, &transition->targetStyle()))
+ return true;
+ }
+ return false;
+}
+
+static double transitionCombinedDuration(const Animation* transition)
+{
+ return std::max(0.0, transition->duration()) + transition->delay();
+}
+
+static bool transitionMatchesProperty(const Animation& transition, CSSPropertyID property)
+{
+ auto mode = transition.animationMode();
if (mode == Animation::AnimateNone || mode == Animation::AnimateUnknownProperty)
return false;
- if (mode == Animation::AnimateSingleProperty && backingAnimation.property() == CSSPropertyInvalid)
- return false;
+ if (mode == Animation::AnimateSingleProperty) {
+ auto transitionProperty = transition.property();
+ if (transitionProperty != property) {
+ auto shorthand = shorthandForProperty(transitionProperty);
+ for (size_t i = 0; i < shorthand.length(); ++i) {
+ if (shorthand.properties()[i] == property)
+ return true;
+ }
+ return false;
+ }
+ }
return true;
}
-void AnimationTimeline::updateCSSTransitionsForElement(Element& element, const RenderStyle& newStyle, const RenderStyle* oldStyle)
+void AnimationTimeline::updateCSSTransitionsForElement(Element& element, const RenderStyle& currentStyle, const RenderStyle& afterChangeStyle)
{
- if (element.document().pageCacheState() != Document::NotInPageCache)
- return;
-
- if (element.document().renderView()->printing())
- return;
-
- // In case this element is newly getting a "display: none" we need to cancel all of its animations and disregard new ones.
- if (oldStyle && oldStyle->hasTransitions() && oldStyle->display() != DisplayType::None && newStyle.display() == DisplayType::None) {
- if (m_elementToCSSTransitionByCSSPropertyID.contains(&element)) {
- for (const auto& cssTransitionsByCSSPropertyIDMapItem : m_elementToCSSTransitionByCSSPropertyID.take(&element))
+ // In case this element is newly getting a "display: none" we need to cancel all of its transitions and disregard new ones.
+ if (currentStyle.hasTransitions() && currentStyle.display() != DisplayType::None && afterChangeStyle.display() == DisplayType::None) {
+ if (m_elementToRunningCSSTransitionByCSSPropertyID.contains(&element)) {
+ for (const auto& cssTransitionsByCSSPropertyIDMapItem : m_elementToRunningCSSTransitionByCSSPropertyID.take(&element))
cancelOrRemoveDeclarativeAnimation(cssTransitionsByCSSPropertyIDMapItem.value);
}
return;
}
- // Create or get the CSSTransitions by CSS property name map for this element.
- auto& cssTransitionsByProperty = m_elementToCSSTransitionByCSSPropertyID.ensure(&element, [] {
+ // Section 3 "Starting of transitions" from the CSS Transitions Level 1 specification.
+ // https://drafts.csswg.org/css-transitions-1/#starting
+
+ auto& runningTransitionsByProperty = m_elementToRunningCSSTransitionByCSSPropertyID.ensure(&element, [] {
return HashMap<CSSPropertyID, RefPtr<CSSTransition>> { };
}).iterator->value;
- // First, compile the list of backing animations and properties that were applied to this element up to this point.
- auto previousProperties = copyToVector(cssTransitionsByProperty.keys());
- HashSet<const Animation*> previousBackingAnimations;
- if (oldStyle && oldStyle->hasTransitions()) {
- auto* previousTransitions = oldStyle->transitions();
- for (size_t i = 0; i < previousTransitions->size(); ++i) {
- auto& backingAnimation = previousTransitions->animation(i);
- if (shouldBackingAnimationBeConsideredForCSSTransition(backingAnimation))
- previousBackingAnimations.add(&backingAnimation);
+ auto& completedTransitionsByProperty = m_elementToCompletedCSSTransitionByCSSPropertyID.ensure(&element, [] {
+ return HashMap<CSSPropertyID, RefPtr<CSSTransition>> { };
+ }).iterator->value;
+
+ auto numberOfProperties = CSSPropertyAnimation::getNumProperties();
+ for (int propertyIndex = 0; propertyIndex < numberOfProperties; ++propertyIndex) {
+ bool isShorthand;
+ auto property = CSSPropertyAnimation::getPropertyAtIndex(propertyIndex, isShorthand);
+ if (isShorthand)
+ continue;
+
+ const Animation* matchingBackingAnimation = nullptr;
+ if (auto* transitions = afterChangeStyle.transitions()) {
+ for (size_t i = 0; i < transitions->size(); ++i) {
+ auto& backingAnimation = transitions->animation(i);
+ if (transitionMatchesProperty(backingAnimation, property))
+ matchingBackingAnimation = &backingAnimation;
+ }
}
- }
- if (auto* currentTransitions = newStyle.transitions()) {
- for (size_t i = 0; i < currentTransitions->size(); ++i) {
- auto& backingAnimation = currentTransitions->animation(i);
- if (!shouldBackingAnimationBeConsideredForCSSTransition(backingAnimation))
- continue;
- auto property = backingAnimation.property();
- bool transitionsAllProperties = backingAnimation.animationMode() == Animation::AnimateAll;
- auto numberOfProperties = CSSPropertyAnimation::getNumProperties();
- // In the "transition-property: all" case, where the animation's mode is set to AnimateAll,
- // the property will be set to CSSPropertyInvalid and we need to iterate over all known
- // CSS properties and see if they have mis-matching values in the old and new styles, which
- // means they should have a CSSTransition created for them.
- // We implement a single loop which handles the "all" case and the specified property case
- // by using the pre-set property above in the specified property case and breaking out of
- // the loop after the first complete iteration.
- for (int propertyIndex = 0; propertyIndex < numberOfProperties; ++propertyIndex) {
- if (transitionsAllProperties) {
- bool isShorthand;
- property = CSSPropertyAnimation::getPropertyAtIndex(propertyIndex, isShorthand);
- if (isShorthand)
- continue;
- } else if (propertyIndex) {
- // We only go once through this loop if we are transitioning a single property.
- break;
- }
+ // https://drafts.csswg.org/css-transitions-1/#before-change-style
+ // Define the before-change style as the computed values of all properties on the element as of the previous style change event, except with
+ // any styles derived from declarative animations such as CSS Transitions, CSS Animations, and SMIL Animations updated to the current time.
+ auto existingAnimation = cssAnimationForElementAndProperty(element, property);
+ const auto& beforeChangeStyle = existingAnimation ? downcast<CSSAnimation>(existingAnimation.get())->unanimatedStyle() : currentStyle;
- previousProperties.removeFirst(property);
- // We've found a backing animation that we didn't know about for a valid property.
- if (!previousBackingAnimations.contains(&backingAnimation)) {
- // If we already had a CSSTransition for this property, check whether its timing properties match the current backing
- // animation's properties and whether its blending keyframes match the old and new styles. If they do, move on to the
- // next transition, otherwise delete the previous CSSTransition object, and create a new one.
- if (cssTransitionsByProperty.contains(property)) {
- if (cssTransitionsByProperty.get(property)->matchesBackingAnimationAndStyles(backingAnimation, oldStyle, newStyle))
- continue;
- removeAnimation(cssTransitionsByProperty.take(property).releaseNonNull());
- }
- // Now we can create a new CSSTransition with the new backing animation provided it has a valid
- // duration and the from and to values are distinct.
- if ((backingAnimation.duration() || backingAnimation.delay() > 0) && oldStyle) {
- auto existingAnimation = cssAnimationForElementAndProperty(element, property);
- const auto* fromStyle = existingAnimation ? &downcast<CSSAnimation>(existingAnimation.get())->unanimatedStyle() : oldStyle;
- if (!CSSPropertyAnimation::propertiesEqual(property, fromStyle, &newStyle))
- cssTransitionsByProperty.set(property, CSSTransition::create(element, property, backingAnimation, fromStyle, newStyle));
- }
- }
+ if (!runningTransitionsByProperty.contains(property)
+ && !CSSPropertyAnimation::propertiesEqual(property, &beforeChangeStyle, &afterChangeStyle)
+ && CSSPropertyAnimation::canPropertyBeInterpolated(property, &beforeChangeStyle, &afterChangeStyle)
+ && !propertyInStyleMatchesValueForTransitionInMap(property, afterChangeStyle, completedTransitionsByProperty)
+ && matchingBackingAnimation && transitionCombinedDuration(matchingBackingAnimation) > 0) {
+ // 1. If all of the following are true:
+ // - the element does not have a running transition for the property,
+ // - the before-change style is different from and can be interpolated with the after-change style for that property,
+ // - the element does not have a completed transition for the property or the end value of the completed transition is different from the after-change style for the property,
+ // - there is a matching transition-property value, and
+ // - the combined duration is greater than 0s,
+
+ // then implementations must remove the completed transition (if present) from the set of completed transitions
+ completedTransitionsByProperty.remove(property);
+
+ // and start a transition whose:
+ // - start time is the time of the style change event plus the matching transition delay,
+ // - end time is the start time plus the matching transition duration,
+ // - start value is the value of the transitioning property in the before-change style,
+ // - end value is the value of the transitioning property in the after-change style,
+ // - reversing-adjusted start value is the same as the start value, and
+ // - reversing shortening factor is 1.
+ auto delay = Seconds(matchingBackingAnimation->delay());
+ auto duration = Seconds(matchingBackingAnimation->duration());
+ auto& reversingAdjustedStartStyle = beforeChangeStyle;
+ auto reversingShorteningFactor = 1;
+ runningTransitionsByProperty.set(property, CSSTransition::create(element, property, *matchingBackingAnimation, &beforeChangeStyle, afterChangeStyle, delay, duration, reversingAdjustedStartStyle, reversingShorteningFactor));
+ } else if (completedTransitionsByProperty.contains(property) && !propertyInStyleMatchesValueForTransitionInMap(property, afterChangeStyle, completedTransitionsByProperty)) {
+ // 2. Otherwise, if the element has a completed transition for the property and the end value of the completed transition is different from
+ // the after-change style for the property, then implementations must remove the completed transition from the set of completed transitions.
+ completedTransitionsByProperty.remove(property);
+ }
+
+ bool hasRunningTransition = runningTransitionsByProperty.contains(property);
+ if ((hasRunningTransition || completedTransitionsByProperty.contains(property)) && !matchingBackingAnimation) {
+ // 3. If the element has a running transition or completed transition for the property, and there is not a matching transition-property
+ // value, then implementations must cancel the running transition or remove the completed transition from the set of completed transitions.
+ if (hasRunningTransition)
+ runningTransitionsByProperty.take(property)->cancel();
+ else
+ completedTransitionsByProperty.remove(property);
+ }
+
+ if (matchingBackingAnimation && runningTransitionsByProperty.contains(property) && !propertyInStyleMatchesValueForTransitionInMap(property, afterChangeStyle, runningTransitionsByProperty)) {
+ auto previouslyRunningTransition = runningTransitionsByProperty.take(property);
+ auto& previouslyRunningTransitionCurrentStyle = previouslyRunningTransition->currentStyle();
+ // 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
+ // transition is not equal to the value of the property in the after-change style, then:
+ if (CSSPropertyAnimation::propertiesEqual(property, &previouslyRunningTransitionCurrentStyle, &afterChangeStyle) || !CSSPropertyAnimation::canPropertyBeInterpolated(property, ¤tStyle, &afterChangeStyle)) {
+ // 1. If the current value of the property in the running transition is equal to the value of the property in the after-change style,
+ // or if these two values cannot be interpolated, then implementations must cancel the running transition.
+ previouslyRunningTransition->cancel();
+ } else if (transitionCombinedDuration(matchingBackingAnimation) <= 0.0 || !CSSPropertyAnimation::canPropertyBeInterpolated(property, &previouslyRunningTransitionCurrentStyle, &afterChangeStyle)) {
+ // 2. Otherwise, if the combined duration is less than or equal to 0s, or if the current value of the property in the running transition
+ // cannot be interpolated with the value of the property in the after-change style, then implementations must cancel the running transition.
+ previouslyRunningTransition->cancel();
+ } else if (CSSPropertyAnimation::propertiesEqual(property, &previouslyRunningTransition->reversingAdjustedStartStyle(), &afterChangeStyle)) {
+ // 3. Otherwise, if the reversing-adjusted start value of the running transition is the same as the value of the property in the after-change
+ // style (see the section on reversing of transitions for why these case exists), implementations must cancel the running transition
+ previouslyRunningTransition->cancel();
+
+ // and start a new transition whose:
+ // - reversing-adjusted start value is the end value of the running transition,
+ // - reversing shortening factor is the absolute value, clamped to the range [0, 1], of the sum of:
+ // 1. the output of the timing function of the old transition at the time of the style change event, times the reversing shortening factor of the old transition
+ // 2. 1 minus the reversing shortening factor of the old transition.
+ // - start time is the time of the style change event plus:
+ // 1. if the matching transition delay is nonnegative, the matching transition delay, or
+ // 2. if the matching transition delay is negative, the product of the new transition’s reversing shortening factor and the matching transition delay,
+ // - end time is the start time plus the product of the matching transition duration and the new transition’s reversing shortening factor,
+ // - start value is the current value of the property in the running transition,
+ // - end value is the value of the property in the after-change style
+ auto& reversingAdjustedStartStyle = previouslyRunningTransition->targetStyle();
+ double transformedProgress = 1;
+ if (auto* effect = previouslyRunningTransition->effect())
+ transformedProgress = effect->iterationProgress().value_or(transformedProgress);
+ auto reversingShorteningFactor = std::max(std::min(((transformedProgress * previouslyRunningTransition->reversingShorteningFactor()) + (1 - previouslyRunningTransition->reversingShorteningFactor())), 1.0), 0.0);
+ auto delay = matchingBackingAnimation->delay() < 0 ? Seconds(matchingBackingAnimation->delay()) * reversingShorteningFactor : Seconds(matchingBackingAnimation->delay());
+ auto duration = Seconds(matchingBackingAnimation->duration()) * reversingShorteningFactor;
+ runningTransitionsByProperty.set(property, CSSTransition::create(element, property, *matchingBackingAnimation, &previouslyRunningTransitionCurrentStyle, afterChangeStyle, delay, duration, reversingAdjustedStartStyle, reversingShorteningFactor));
+ } else {
+ // 4. Otherwise, implementations must cancel the running transition
+ previouslyRunningTransition->cancel();
+
+ // and start a new transition whose:
+ // - start time is the time of the style change event plus the matching transition delay,
+ // - end time is the start time plus the matching transition duration,
+ // - start value is the current value of the property in the running transition,
+ // - end value is the value of the property in the after-change style,
+ // - reversing-adjusted start value is the same as the start value, and
+ // - reversing shortening factor is 1.
+ auto delay = Seconds(matchingBackingAnimation->delay());
+ auto duration = Seconds(matchingBackingAnimation->duration());
+ auto& reversingAdjustedStartStyle = currentStyle;
+ auto reversingShorteningFactor = 1;
+ runningTransitionsByProperty.set(property, CSSTransition::create(element, property, *matchingBackingAnimation, &previouslyRunningTransitionCurrentStyle, afterChangeStyle, delay, duration, reversingAdjustedStartStyle, reversingShorteningFactor));
}
}
}
- // Remaining properties are no longer current and must be removed.
- for (const auto transitionPropertyToRemove : previousProperties) {
- if (cssTransitionsByProperty.contains(transitionPropertyToRemove))
- cancelOrRemoveDeclarativeAnimation(cssTransitionsByProperty.take(transitionPropertyToRemove));
- }
-
- // Remove the map of CSSTransitions by property for this element if it's now empty.
- if (cssTransitionsByProperty.isEmpty())
- m_elementToCSSTransitionByCSSPropertyID.remove(&element);
}
void AnimationTimeline::cancelOrRemoveDeclarativeAnimation(RefPtr<DeclarativeAnimation> animation)
Modified: trunk/Source/WebCore/animation/AnimationTimeline.h (232945 => 232946)
--- trunk/Source/WebCore/animation/AnimationTimeline.h 2018-06-18 21:14:40 UTC (rev 232945)
+++ trunk/Source/WebCore/animation/AnimationTimeline.h 2018-06-18 21:20:47 UTC (rev 232946)
@@ -63,8 +63,8 @@
void animationWasAddedToElement(WebAnimation&, Element&);
void animationWasRemovedFromElement(WebAnimation&, Element&);
- void updateCSSAnimationsForElement(Element&, const RenderStyle& newStyle, const RenderStyle* oldStyle);
- void updateCSSTransitionsForElement(Element&, const RenderStyle& newStyle, const RenderStyle* oldStyle);
+ void updateCSSAnimationsForElement(Element&, const RenderStyle* currentStyle, const RenderStyle& afterChangeStyle);
+ void updateCSSTransitionsForElement(Element&, const RenderStyle& currentStyle, const RenderStyle& afterChangeStyle);
virtual ~AnimationTimeline();
@@ -96,7 +96,8 @@
ListHashSet<RefPtr<WebAnimation>> m_animations;
HashMap<Element*, HashMap<String, RefPtr<CSSAnimation>>> m_elementToCSSAnimationByName;
- HashMap<Element*, HashMap<CSSPropertyID, RefPtr<CSSTransition>>> m_elementToCSSTransitionByCSSPropertyID;
+ HashMap<Element*, HashMap<CSSPropertyID, RefPtr<CSSTransition>>> m_elementToRunningCSSTransitionByCSSPropertyID;
+ HashMap<Element*, HashMap<CSSPropertyID, RefPtr<CSSTransition>>> m_elementToCompletedCSSTransitionByCSSPropertyID;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/animation/CSSAnimation.cpp (232945 => 232946)
--- trunk/Source/WebCore/animation/CSSAnimation.cpp 2018-06-18 21:14:40 UTC (rev 232945)
+++ trunk/Source/WebCore/animation/CSSAnimation.cpp 2018-06-18 21:20:47 UTC (rev 232946)
@@ -87,10 +87,13 @@
auto iterationCount = animation.iterationCount();
timing->setIterations(iterationCount == Animation::IterationCountInfinite ? std::numeric_limits<double>::infinity() : iterationCount);
+ timing->setDelay(Seconds(animation.delay()));
+ timing->setIterationDuration(Seconds(animation.duration()));
+
// Synchronize the play state
- if (backingAnimation().playState() == AnimationPlayState::Playing && playState() == WebAnimation::PlayState::Paused)
+ if (animation.playState() == AnimationPlayState::Playing && playState() == WebAnimation::PlayState::Paused)
play();
- else if (backingAnimation().playState() == AnimationPlayState::Paused && playState() == WebAnimation::PlayState::Running)
+ else if (animation.playState() == AnimationPlayState::Paused && playState() == WebAnimation::PlayState::Running)
pause();
unsuspendEffectInvalidation();
Modified: trunk/Source/WebCore/animation/CSSTransition.cpp (232945 => 232946)
--- trunk/Source/WebCore/animation/CSSTransition.cpp 2018-06-18 21:14:40 UTC (rev 232945)
+++ trunk/Source/WebCore/animation/CSSTransition.cpp 2018-06-18 21:20:47 UTC (rev 232946)
@@ -32,45 +32,52 @@
namespace WebCore {
-Ref<CSSTransition> CSSTransition::create(Element& target, CSSPropertyID property, const Animation& backingAnimation, const RenderStyle* oldStyle, const RenderStyle& newStyle)
+Ref<CSSTransition> CSSTransition::create(Element& target, CSSPropertyID property, const Animation& backingAnimation, const RenderStyle* oldStyle, const RenderStyle& newStyle, Seconds delay, Seconds duration, const RenderStyle& reversingAdjustedStartStyle, double reversingShorteningFactor)
{
- auto result = adoptRef(*new CSSTransition(target, property, backingAnimation));
+ auto result = adoptRef(*new CSSTransition(target, property, backingAnimation, newStyle, reversingAdjustedStartStyle, reversingShorteningFactor));
result->initialize(target, oldStyle, newStyle);
+ result->setTimingProperties(delay, duration);
return result;
}
-CSSTransition::CSSTransition(Element& element, CSSPropertyID property, const Animation& backingAnimation)
+CSSTransition::CSSTransition(Element& element, CSSPropertyID property, const Animation& backingAnimation, const RenderStyle& targetStyle, const RenderStyle& reversingAdjustedStartStyle, double reversingShorteningFactor)
: DeclarativeAnimation(element, backingAnimation)
, m_property(property)
+ , m_targetStyle(RenderStyle::clonePtr(targetStyle))
+ , m_reversingAdjustedStartStyle(RenderStyle::clonePtr(reversingAdjustedStartStyle))
+ , m_reversingShorteningFactor(reversingShorteningFactor)
{
}
-void CSSTransition::initialize(const Element& target, const RenderStyle* oldStyle, const RenderStyle& newStyle)
+void CSSTransition::resolve(RenderStyle& targetStyle)
{
- DeclarativeAnimation::initialize(target, oldStyle, newStyle);
+ DeclarativeAnimation::resolve(targetStyle);
+ m_currentStyle = RenderStyle::clonePtr(targetStyle);
+}
+void CSSTransition::setTimingProperties(Seconds delay, Seconds duration)
+{
suspendEffectInvalidation();
+ auto* timing = effect()->timing();
// In order for CSS Transitions to be seeked backwards, they need to have their fill mode set to backwards
// such that the original CSS value applied prior to the transition is used for a negative current time.
- effect()->timing()->setFill(FillMode::Backwards);
+
+ timing->setFill(FillMode::Backwards);
+ timing->setDelay(delay);
+ timing->setIterationDuration(duration);
unsuspendEffectInvalidation();
}
-bool CSSTransition::matchesBackingAnimationAndStyles(const Animation& newBackingAnimation, const RenderStyle* oldStyle, const RenderStyle& newStyle) const
-{
- // See if the animations match, excluding the property since we can move from an "all" transition to an explicit property transition.
- bool backingAnimationsMatch = backingAnimation().animationsMatch(newBackingAnimation, false);
- if (!oldStyle || !effect())
- return backingAnimationsMatch;
- return backingAnimationsMatch && !downcast<KeyframeEffectReadOnly>(effect())->stylesWouldYieldNewCSSTransitionsBlendingKeyframes(*oldStyle, newStyle);
-}
-
bool CSSTransition::canBeListed() const
{
- if (!downcast<KeyframeEffectReadOnly>(effect())->hasBlendingKeyframes())
- return false;
+ if (auto* transitionEffect = effect()) {
+ if (is<KeyframeEffectReadOnly>(transitionEffect)) {
+ if (!downcast<KeyframeEffectReadOnly>(effect())->hasBlendingKeyframes())
+ return false;
+ }
+ }
return WebAnimation::canBeListed();
}
Modified: trunk/Source/WebCore/animation/CSSTransition.h (232945 => 232946)
--- trunk/Source/WebCore/animation/CSSTransition.h 2018-06-18 21:14:40 UTC (rev 232945)
+++ trunk/Source/WebCore/animation/CSSTransition.h 2018-06-18 21:20:47 UTC (rev 232946)
@@ -37,23 +37,29 @@
class CSSTransition final : public DeclarativeAnimation {
public:
- static Ref<CSSTransition> create(Element&, CSSPropertyID, const Animation&, const RenderStyle* oldStyle, const RenderStyle& newStyle);
+ static Ref<CSSTransition> create(Element&, CSSPropertyID, const Animation&, const RenderStyle* oldStyle, const RenderStyle& newStyle, Seconds delay, Seconds duration, const RenderStyle& reversingAdjustedStartStyle, double);
~CSSTransition() = default;
bool isCSSTransition() const override { return true; }
String transitionProperty() const { return getPropertyNameString(m_property); }
CSSPropertyID property() const { return m_property; }
+ const RenderStyle& targetStyle() const { return *m_targetStyle; }
+ const RenderStyle& currentStyle() const { return *m_currentStyle; }
+ const RenderStyle& reversingAdjustedStartStyle() const { return *m_reversingAdjustedStartStyle; }
+ double reversingShorteningFactor() const { return m_reversingShorteningFactor; }
- bool matchesBackingAnimationAndStyles(const Animation&, const RenderStyle* oldStyle, const RenderStyle& newStyle) const;
bool canBeListed() const final;
+ void resolve(RenderStyle&) final;
-protected:
- void initialize(const Element&, const RenderStyle* oldStyle, const RenderStyle& newStyle) final;
-
private:
- CSSTransition(Element&, CSSPropertyID, const Animation&);
+ CSSTransition(Element&, CSSPropertyID, const Animation&, const RenderStyle& targetStyle, const RenderStyle& reversingAdjustedStartStyle, double);
+ void setTimingProperties(Seconds delay, Seconds duration);
CSSPropertyID m_property;
+ std::unique_ptr<RenderStyle> m_targetStyle;
+ std::unique_ptr<RenderStyle> m_currentStyle;
+ std::unique_ptr<RenderStyle> m_reversingAdjustedStartStyle;
+ double m_reversingShorteningFactor;
};
Modified: trunk/Source/WebCore/animation/DeclarativeAnimation.cpp (232945 => 232946)
--- trunk/Source/WebCore/animation/DeclarativeAnimation.cpp 2018-06-18 21:14:40 UTC (rev 232945)
+++ trunk/Source/WebCore/animation/DeclarativeAnimation.cpp 2018-06-18 21:20:47 UTC (rev 232946)
@@ -82,13 +82,6 @@
void DeclarativeAnimation::syncPropertiesWithBackingAnimation()
{
- suspendEffectInvalidation();
-
- auto* timing = effect()->timing();
- timing->setDelay(Seconds(m_backingAnimation->delay()));
- timing->setIterationDuration(Seconds(m_backingAnimation->duration()));
-
- unsuspendEffectInvalidation();
}
void DeclarativeAnimation::setTimeline(RefPtr<AnimationTimeline>&& newTimeline)
Modified: trunk/Source/WebCore/animation/KeyframeEffectReadOnly.cpp (232945 => 232946)
--- trunk/Source/WebCore/animation/KeyframeEffectReadOnly.cpp 2018-06-18 21:14:40 UTC (rev 232945)
+++ trunk/Source/WebCore/animation/KeyframeEffectReadOnly.cpp 2018-06-18 21:20:47 UTC (rev 232946)
@@ -877,25 +877,6 @@
setBlendingKeyframes(keyframeList);
}
-bool KeyframeEffectReadOnly::stylesWouldYieldNewCSSTransitionsBlendingKeyframes(const RenderStyle& oldStyle, const RenderStyle& newStyle) const
-{
- ASSERT(is<CSSTransition>(animation()));
-
- // We don't yet have blending keyframes to compare with, so these wouldn't be new keyframes, but the fisrt ones.
- if (!hasBlendingKeyframes())
- return false;
-
- auto property = downcast<CSSTransition>(animation())->property();
-
- // There cannot be new keyframes if the start and to values are the same.
- if (CSSPropertyAnimation::propertiesEqual(property, &oldStyle, &newStyle))
- return false;
-
- // Otherwise, we would create new blending keyframes provided the current end keyframe holds a different
- // value than the new end style for this property.
- return !CSSPropertyAnimation::propertiesEqual(property, m_blendingKeyframes[1].style(), &newStyle);
-}
-
void KeyframeEffectReadOnly::computedNeedsForcedLayout()
{
m_needsForcedLayout = false;
Modified: trunk/Source/WebCore/animation/KeyframeEffectReadOnly.h (232945 => 232946)
--- trunk/Source/WebCore/animation/KeyframeEffectReadOnly.h 2018-06-18 21:14:40 UTC (rev 232945)
+++ trunk/Source/WebCore/animation/KeyframeEffectReadOnly.h 2018-06-18 21:20:47 UTC (rev 232946)
@@ -114,7 +114,6 @@
bool colorFilterFunctionListsMatch() const override { return m_colorFilterFunctionListsMatch; }
void computeDeclarativeAnimationBlendingKeyframes(const RenderStyle* oldStyle, const RenderStyle& newStyle);
- bool stylesWouldYieldNewCSSTransitionsBlendingKeyframes(const RenderStyle& oldStyle, const RenderStyle& newStyle) const;
bool hasBlendingKeyframes() const { return m_blendingKeyframes.size(); }
const HashSet<CSSPropertyID>& animatedProperties() const { return m_blendingKeyframes.properties(); }
Modified: trunk/Source/WebCore/animation/WebAnimation.h (232945 => 232946)
--- trunk/Source/WebCore/animation/WebAnimation.h 2018-06-18 21:14:40 UTC (rev 232945)
+++ trunk/Source/WebCore/animation/WebAnimation.h 2018-06-18 21:20:47 UTC (rev 232946)
@@ -99,7 +99,7 @@
ExceptionOr<void> reverse();
Seconds timeToNextRequiredTick() const;
- void resolve(RenderStyle&);
+ virtual void resolve(RenderStyle&);
void effectTargetDidChange(Element* previousTarget, Element* newTarget);
void acceleratedStateDidChange();
void applyPendingAcceleratedActions();
Modified: trunk/Source/WebCore/page/animation/CSSPropertyAnimation.cpp (232945 => 232946)
--- trunk/Source/WebCore/page/animation/CSSPropertyAnimation.cpp 2018-06-18 21:14:40 UTC (rev 232945)
+++ trunk/Source/WebCore/page/animation/CSSPropertyAnimation.cpp 2018-06-18 21:20:47 UTC (rev 232946)
@@ -426,6 +426,7 @@
virtual bool isShorthandWrapper() const { return false; }
virtual bool equals(const RenderStyle* a, const RenderStyle* b) const = 0;
+ virtual bool canInterpolate(const RenderStyle*, const RenderStyle*) const { return true; }
virtual void blend(const CSSPropertyBlendingClient*, RenderStyle*, const RenderStyle*, const RenderStyle*, double) const = 0;
#if !LOG_DISABLED
@@ -513,11 +514,34 @@
void (RenderStyle::*m_setter)(RefPtr<T>&&);
};
+class LengthPropertyWrapper : public PropertyWrapperGetter<const Length&> {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ LengthPropertyWrapper(CSSPropertyID prop, const Length& (RenderStyle::*getter)() const, void (RenderStyle::*setter)(Length&&))
+ : PropertyWrapperGetter<const Length&>(prop, getter)
+ , m_setter(setter)
+ {
+ }
+
+ bool canInterpolate(const RenderStyle* a, const RenderStyle* b) const override
+ {
+ return !(a->*PropertyWrapperGetter<const Length&>::m_getter)().isAuto() && !(b->*PropertyWrapperGetter<const Length&>::m_getter)().isAuto();
+ }
+
+ void blend(const CSSPropertyBlendingClient* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const override
+ {
+ (dst->*m_setter)(blendFunc(anim, (a->*PropertyWrapperGetter<const Length&>::m_getter)(), (b->*PropertyWrapperGetter<const Length&>::m_getter)(), progress));
+ }
+
+protected:
+ void (RenderStyle::*m_setter)(Length&&);
+};
+
template <typename T>
-class LengthPropertyWrapper : public PropertyWrapperGetter<const T&> {
+class LengthVariantPropertyWrapper : public PropertyWrapperGetter<const T&> {
WTF_MAKE_FAST_ALLOCATED;
public:
- LengthPropertyWrapper(CSSPropertyID prop, const T& (RenderStyle::*getter)() const, void (RenderStyle::*setter)(T&&))
+ LengthVariantPropertyWrapper(CSSPropertyID prop, const T& (RenderStyle::*getter)() const, void (RenderStyle::*setter)(T&&))
: PropertyWrapperGetter<const T&>(prop, getter)
, m_setter(setter)
{
@@ -1469,18 +1493,18 @@
{
// build the list of property wrappers to do the comparisons and blends
AnimationPropertyWrapperBase* animatableLonghandPropertyWrappers[] = {
- new LengthPropertyWrapper<Length>(CSSPropertyLeft, &RenderStyle::left, &RenderStyle::setLeft),
- new LengthPropertyWrapper<Length>(CSSPropertyRight, &RenderStyle::right, &RenderStyle::setRight),
- new LengthPropertyWrapper<Length>(CSSPropertyTop, &RenderStyle::top, &RenderStyle::setTop),
- new LengthPropertyWrapper<Length>(CSSPropertyBottom, &RenderStyle::bottom, &RenderStyle::setBottom),
+ new LengthPropertyWrapper(CSSPropertyLeft, &RenderStyle::left, &RenderStyle::setLeft),
+ new LengthPropertyWrapper(CSSPropertyRight, &RenderStyle::right, &RenderStyle::setRight),
+ new LengthPropertyWrapper(CSSPropertyTop, &RenderStyle::top, &RenderStyle::setTop),
+ new LengthPropertyWrapper(CSSPropertyBottom, &RenderStyle::bottom, &RenderStyle::setBottom),
- new LengthPropertyWrapper<Length>(CSSPropertyWidth, &RenderStyle::width, &RenderStyle::setWidth),
- new LengthPropertyWrapper<Length>(CSSPropertyMinWidth, &RenderStyle::minWidth, &RenderStyle::setMinWidth),
- new LengthPropertyWrapper<Length>(CSSPropertyMaxWidth, &RenderStyle::maxWidth, &RenderStyle::setMaxWidth),
+ new LengthPropertyWrapper(CSSPropertyWidth, &RenderStyle::width, &RenderStyle::setWidth),
+ new LengthPropertyWrapper(CSSPropertyMinWidth, &RenderStyle::minWidth, &RenderStyle::setMinWidth),
+ new LengthPropertyWrapper(CSSPropertyMaxWidth, &RenderStyle::maxWidth, &RenderStyle::setMaxWidth),
- new LengthPropertyWrapper<Length>(CSSPropertyHeight, &RenderStyle::height, &RenderStyle::setHeight),
- new LengthPropertyWrapper<Length>(CSSPropertyMinHeight, &RenderStyle::minHeight, &RenderStyle::setMinHeight),
- new LengthPropertyWrapper<Length>(CSSPropertyMaxHeight, &RenderStyle::maxHeight, &RenderStyle::setMaxHeight),
+ new LengthPropertyWrapper(CSSPropertyHeight, &RenderStyle::height, &RenderStyle::setHeight),
+ new LengthPropertyWrapper(CSSPropertyMinHeight, &RenderStyle::minHeight, &RenderStyle::setMinHeight),
+ new LengthPropertyWrapper(CSSPropertyMaxHeight, &RenderStyle::maxHeight, &RenderStyle::setMaxHeight),
new PropertyWrapperFlex(),
@@ -1488,14 +1512,14 @@
new PropertyWrapper<float>(CSSPropertyBorderRightWidth, &RenderStyle::borderRightWidth, &RenderStyle::setBorderRightWidth),
new PropertyWrapper<float>(CSSPropertyBorderTopWidth, &RenderStyle::borderTopWidth, &RenderStyle::setBorderTopWidth),
new PropertyWrapper<float>(CSSPropertyBorderBottomWidth, &RenderStyle::borderBottomWidth, &RenderStyle::setBorderBottomWidth),
- new LengthPropertyWrapper<Length>(CSSPropertyMarginLeft, &RenderStyle::marginLeft, &RenderStyle::setMarginLeft),
- new LengthPropertyWrapper<Length>(CSSPropertyMarginRight, &RenderStyle::marginRight, &RenderStyle::setMarginRight),
- new LengthPropertyWrapper<Length>(CSSPropertyMarginTop, &RenderStyle::marginTop, &RenderStyle::setMarginTop),
- new LengthPropertyWrapper<Length>(CSSPropertyMarginBottom, &RenderStyle::marginBottom, &RenderStyle::setMarginBottom),
- new LengthPropertyWrapper<Length>(CSSPropertyPaddingLeft, &RenderStyle::paddingLeft, &RenderStyle::setPaddingLeft),
- new LengthPropertyWrapper<Length>(CSSPropertyPaddingRight, &RenderStyle::paddingRight, &RenderStyle::setPaddingRight),
- new LengthPropertyWrapper<Length>(CSSPropertyPaddingTop, &RenderStyle::paddingTop, &RenderStyle::setPaddingTop),
- new LengthPropertyWrapper<Length>(CSSPropertyPaddingBottom, &RenderStyle::paddingBottom, &RenderStyle::setPaddingBottom),
+ new LengthPropertyWrapper(CSSPropertyMarginLeft, &RenderStyle::marginLeft, &RenderStyle::setMarginLeft),
+ new LengthPropertyWrapper(CSSPropertyMarginRight, &RenderStyle::marginRight, &RenderStyle::setMarginRight),
+ new LengthPropertyWrapper(CSSPropertyMarginTop, &RenderStyle::marginTop, &RenderStyle::setMarginTop),
+ new LengthPropertyWrapper(CSSPropertyMarginBottom, &RenderStyle::marginBottom, &RenderStyle::setMarginBottom),
+ new LengthPropertyWrapper(CSSPropertyPaddingLeft, &RenderStyle::paddingLeft, &RenderStyle::setPaddingLeft),
+ new LengthPropertyWrapper(CSSPropertyPaddingRight, &RenderStyle::paddingRight, &RenderStyle::setPaddingRight),
+ new LengthPropertyWrapper(CSSPropertyPaddingTop, &RenderStyle::paddingTop, &RenderStyle::setPaddingTop),
+ new LengthPropertyWrapper(CSSPropertyPaddingBottom, &RenderStyle::paddingBottom, &RenderStyle::setPaddingBottom),
new PropertyWrapperVisitedAffectedColor(CSSPropertyCaretColor, &RenderStyle::caretColor, &RenderStyle::setCaretColor, &RenderStyle::visitedLinkCaretColor, &RenderStyle::setVisitedLinkCaretColor),
@@ -1508,9 +1532,9 @@
new StyleImagePropertyWrapper(CSSPropertyWebkitMaskImage, &RenderStyle::maskImage, &RenderStyle::setMaskImage),
new StyleImagePropertyWrapper(CSSPropertyBorderImageSource, &RenderStyle::borderImageSource, &RenderStyle::setBorderImageSource),
- new LengthPropertyWrapper<LengthBox>(CSSPropertyBorderImageSlice, &RenderStyle::borderImageSlices, &RenderStyle::setBorderImageSlices),
- new LengthPropertyWrapper<LengthBox>(CSSPropertyBorderImageWidth, &RenderStyle::borderImageWidth, &RenderStyle::setBorderImageWidth),
- new LengthPropertyWrapper<LengthBox>(CSSPropertyBorderImageOutset, &RenderStyle::borderImageOutset, &RenderStyle::setBorderImageOutset),
+ new LengthVariantPropertyWrapper<LengthBox>(CSSPropertyBorderImageSlice, &RenderStyle::borderImageSlices, &RenderStyle::setBorderImageSlices),
+ new LengthVariantPropertyWrapper<LengthBox>(CSSPropertyBorderImageWidth, &RenderStyle::borderImageWidth, &RenderStyle::setBorderImageWidth),
+ new LengthVariantPropertyWrapper<LengthBox>(CSSPropertyBorderImageOutset, &RenderStyle::borderImageOutset, &RenderStyle::setBorderImageOutset),
new StyleImagePropertyWrapper(CSSPropertyWebkitMaskBoxImageSource, &RenderStyle::maskBoxImageSource, &RenderStyle::setMaskBoxImageSource),
new PropertyWrapper<const NinePieceImage&>(CSSPropertyWebkitMaskBoxImage, &RenderStyle::maskBoxImage, &RenderStyle::setMaskBoxImage),
@@ -1526,8 +1550,8 @@
new PropertyWrapper<float>(CSSPropertyFontSize, &RenderStyle::computedFontSize, &RenderStyle::setFontSize),
new PropertyWrapper<unsigned short>(CSSPropertyColumnRuleWidth, &RenderStyle::columnRuleWidth, &RenderStyle::setColumnRuleWidth),
- new LengthPropertyWrapper<GapLength>(CSSPropertyColumnGap, &RenderStyle::columnGap, &RenderStyle::setColumnGap),
- new LengthPropertyWrapper<GapLength>(CSSPropertyRowGap, &RenderStyle::rowGap, &RenderStyle::setRowGap),
+ new LengthVariantPropertyWrapper<GapLength>(CSSPropertyColumnGap, &RenderStyle::columnGap, &RenderStyle::setColumnGap),
+ new LengthVariantPropertyWrapper<GapLength>(CSSPropertyRowGap, &RenderStyle::rowGap, &RenderStyle::setRowGap),
new PropertyWrapper<unsigned short>(CSSPropertyColumnCount, &RenderStyle::columnCount, &RenderStyle::setColumnCount),
new PropertyWrapper<float>(CSSPropertyColumnWidth, &RenderStyle::columnWidth, &RenderStyle::setColumnWidth),
new PropertyWrapper<float>(CSSPropertyWebkitBorderHorizontalSpacing, &RenderStyle::horizontalBorderSpacing, &RenderStyle::setHorizontalBorderSpacing),
@@ -1535,27 +1559,27 @@
new PropertyWrapper<int>(CSSPropertyZIndex, &RenderStyle::zIndex, &RenderStyle::setZIndex),
new PropertyWrapper<short>(CSSPropertyOrphans, &RenderStyle::orphans, &RenderStyle::setOrphans),
new PropertyWrapper<short>(CSSPropertyWidows, &RenderStyle::widows, &RenderStyle::setWidows),
- new LengthPropertyWrapper<Length>(CSSPropertyLineHeight, &RenderStyle::specifiedLineHeight, &RenderStyle::setLineHeight),
+ new LengthPropertyWrapper(CSSPropertyLineHeight, &RenderStyle::specifiedLineHeight, &RenderStyle::setLineHeight),
new PropertyWrapper<float>(CSSPropertyOutlineOffset, &RenderStyle::outlineOffset, &RenderStyle::setOutlineOffset),
new PropertyWrapper<float>(CSSPropertyOutlineWidth, &RenderStyle::outlineWidth, &RenderStyle::setOutlineWidth),
new PropertyWrapper<float>(CSSPropertyLetterSpacing, &RenderStyle::letterSpacing, &RenderStyle::setLetterSpacing),
- new LengthPropertyWrapper<Length>(CSSPropertyWordSpacing, &RenderStyle::wordSpacing, &RenderStyle::setWordSpacing),
- new LengthPropertyWrapper<Length>(CSSPropertyTextIndent, &RenderStyle::textIndent, &RenderStyle::setTextIndent),
+ new LengthPropertyWrapper(CSSPropertyWordSpacing, &RenderStyle::wordSpacing, &RenderStyle::setWordSpacing),
+ new LengthPropertyWrapper(CSSPropertyTextIndent, &RenderStyle::textIndent, &RenderStyle::setTextIndent),
new PropertyWrapper<float>(CSSPropertyPerspective, &RenderStyle::perspective, &RenderStyle::setPerspective),
- new LengthPropertyWrapper<Length>(CSSPropertyPerspectiveOriginX, &RenderStyle::perspectiveOriginX, &RenderStyle::setPerspectiveOriginX),
- new LengthPropertyWrapper<Length>(CSSPropertyPerspectiveOriginY, &RenderStyle::perspectiveOriginY, &RenderStyle::setPerspectiveOriginY),
- new LengthPropertyWrapper<Length>(CSSPropertyTransformOriginX, &RenderStyle::transformOriginX, &RenderStyle::setTransformOriginX),
- new LengthPropertyWrapper<Length>(CSSPropertyTransformOriginY, &RenderStyle::transformOriginY, &RenderStyle::setTransformOriginY),
+ new LengthPropertyWrapper(CSSPropertyPerspectiveOriginX, &RenderStyle::perspectiveOriginX, &RenderStyle::setPerspectiveOriginX),
+ new LengthPropertyWrapper(CSSPropertyPerspectiveOriginY, &RenderStyle::perspectiveOriginY, &RenderStyle::setPerspectiveOriginY),
+ new LengthPropertyWrapper(CSSPropertyTransformOriginX, &RenderStyle::transformOriginX, &RenderStyle::setTransformOriginX),
+ new LengthPropertyWrapper(CSSPropertyTransformOriginY, &RenderStyle::transformOriginY, &RenderStyle::setTransformOriginY),
new PropertyWrapper<float>(CSSPropertyTransformOriginZ, &RenderStyle::transformOriginZ, &RenderStyle::setTransformOriginZ),
- new LengthPropertyWrapper<LengthSize>(CSSPropertyBorderTopLeftRadius, &RenderStyle::borderTopLeftRadius, &RenderStyle::setBorderTopLeftRadius),
- new LengthPropertyWrapper<LengthSize>(CSSPropertyBorderTopRightRadius, &RenderStyle::borderTopRightRadius, &RenderStyle::setBorderTopRightRadius),
- new LengthPropertyWrapper<LengthSize>(CSSPropertyBorderBottomLeftRadius, &RenderStyle::borderBottomLeftRadius, &RenderStyle::setBorderBottomLeftRadius),
- new LengthPropertyWrapper<LengthSize>(CSSPropertyBorderBottomRightRadius, &RenderStyle::borderBottomRightRadius, &RenderStyle::setBorderBottomRightRadius),
+ new LengthVariantPropertyWrapper<LengthSize>(CSSPropertyBorderTopLeftRadius, &RenderStyle::borderTopLeftRadius, &RenderStyle::setBorderTopLeftRadius),
+ new LengthVariantPropertyWrapper<LengthSize>(CSSPropertyBorderTopRightRadius, &RenderStyle::borderTopRightRadius, &RenderStyle::setBorderTopRightRadius),
+ new LengthVariantPropertyWrapper<LengthSize>(CSSPropertyBorderBottomLeftRadius, &RenderStyle::borderBottomLeftRadius, &RenderStyle::setBorderBottomLeftRadius),
+ new LengthVariantPropertyWrapper<LengthSize>(CSSPropertyBorderBottomRightRadius, &RenderStyle::borderBottomRightRadius, &RenderStyle::setBorderBottomRightRadius),
new PropertyWrapper<Visibility>(CSSPropertyVisibility, &RenderStyle::visibility, &RenderStyle::setVisibility),
new PropertyWrapper<float>(CSSPropertyZoom, &RenderStyle::zoom, &RenderStyle::setZoomWithoutReturnValue),
- new LengthPropertyWrapper<LengthBox>(CSSPropertyClip, &RenderStyle::clip, &RenderStyle::setClip),
+ new LengthVariantPropertyWrapper<LengthBox>(CSSPropertyClip, &RenderStyle::clip, &RenderStyle::setClip),
new PropertyWrapperAcceleratedOpacity(),
new PropertyWrapperAcceleratedTransform(),
@@ -1569,7 +1593,7 @@
new PropertyWrapperClipPath(CSSPropertyWebkitClipPath, &RenderStyle::clipPath, &RenderStyle::setClipPath),
new PropertyWrapperShape(CSSPropertyShapeOutside, &RenderStyle::shapeOutside, &RenderStyle::setShapeOutside),
- new LengthPropertyWrapper<Length>(CSSPropertyShapeMargin, &RenderStyle::shapeMargin, &RenderStyle::setShapeMargin),
+ new LengthPropertyWrapper(CSSPropertyShapeMargin, &RenderStyle::shapeMargin, &RenderStyle::setShapeMargin),
new PropertyWrapper<float>(CSSPropertyShapeImageThreshold, &RenderStyle::shapeImageThreshold, &RenderStyle::setShapeImageThreshold),
new PropertyWrapperVisitedAffectedColor(CSSPropertyColumnRuleColor, MaybeInvalidColor, &RenderStyle::columnRuleColor, &RenderStyle::setColumnRuleColor, &RenderStyle::visitedLinkColumnRuleColor, &RenderStyle::setVisitedLinkColumnRuleColor),
@@ -1593,15 +1617,15 @@
new PropertyWrapper<Vector<SVGLengthValue>>(CSSPropertyStrokeDasharray, &RenderStyle::strokeDashArray, &RenderStyle::setStrokeDashArray),
new PropertyWrapper<float>(CSSPropertyStrokeMiterlimit, &RenderStyle::strokeMiterLimit, &RenderStyle::setStrokeMiterLimit),
- new LengthPropertyWrapper<Length>(CSSPropertyCx, &RenderStyle::cx, &RenderStyle::setCx),
- new LengthPropertyWrapper<Length>(CSSPropertyCy, &RenderStyle::cy, &RenderStyle::setCy),
- new LengthPropertyWrapper<Length>(CSSPropertyR, &RenderStyle::r, &RenderStyle::setR),
- new LengthPropertyWrapper<Length>(CSSPropertyRx, &RenderStyle::rx, &RenderStyle::setRx),
- new LengthPropertyWrapper<Length>(CSSPropertyRy, &RenderStyle::ry, &RenderStyle::setRy),
- new LengthPropertyWrapper<Length>(CSSPropertyStrokeDashoffset, &RenderStyle::strokeDashOffset, &RenderStyle::setStrokeDashOffset),
- new LengthPropertyWrapper<Length>(CSSPropertyStrokeWidth, &RenderStyle::strokeWidth, &RenderStyle::setStrokeWidth),
- new LengthPropertyWrapper<Length>(CSSPropertyX, &RenderStyle::x, &RenderStyle::setX),
- new LengthPropertyWrapper<Length>(CSSPropertyY, &RenderStyle::y, &RenderStyle::setY),
+ new LengthPropertyWrapper(CSSPropertyCx, &RenderStyle::cx, &RenderStyle::setCx),
+ new LengthPropertyWrapper(CSSPropertyCy, &RenderStyle::cy, &RenderStyle::setCy),
+ new LengthPropertyWrapper(CSSPropertyR, &RenderStyle::r, &RenderStyle::setR),
+ new LengthPropertyWrapper(CSSPropertyRx, &RenderStyle::rx, &RenderStyle::setRx),
+ new LengthPropertyWrapper(CSSPropertyRy, &RenderStyle::ry, &RenderStyle::setRy),
+ new LengthPropertyWrapper(CSSPropertyStrokeDashoffset, &RenderStyle::strokeDashOffset, &RenderStyle::setStrokeDashOffset),
+ new LengthPropertyWrapper(CSSPropertyStrokeWidth, &RenderStyle::strokeWidth, &RenderStyle::setStrokeWidth),
+ new LengthPropertyWrapper(CSSPropertyX, &RenderStyle::x, &RenderStyle::setX),
+ new LengthPropertyWrapper(CSSPropertyY, &RenderStyle::y, &RenderStyle::setY),
new PropertyWrapper<float>(CSSPropertyFloodOpacity, &RenderStyle::floodOpacity, &RenderStyle::setFloodOpacity),
new PropertyWrapperMaybeInvalidColor(CSSPropertyFloodColor, &RenderStyle::floodColor, &RenderStyle::setFloodColor),
@@ -1758,6 +1782,14 @@
return true;
}
+bool CSSPropertyAnimation::canPropertyBeInterpolated(CSSPropertyID prop, const RenderStyle* a, const RenderStyle* b)
+{
+ AnimationPropertyWrapperBase* wrapper = CSSPropertyAnimationWrapperMap::singleton().wrapperForProperty(prop);
+ if (wrapper)
+ return wrapper->canInterpolate(a, b);
+ return false;
+}
+
CSSPropertyID CSSPropertyAnimation::getPropertyAtIndex(int i, bool& isShorthand)
{
CSSPropertyAnimationWrapperMap& map = CSSPropertyAnimationWrapperMap::singleton();
Modified: trunk/Source/WebCore/page/animation/CSSPropertyAnimation.h (232945 => 232946)
--- trunk/Source/WebCore/page/animation/CSSPropertyAnimation.h 2018-06-18 21:14:40 UTC (rev 232945)
+++ trunk/Source/WebCore/page/animation/CSSPropertyAnimation.h 2018-06-18 21:20:47 UTC (rev 232946)
@@ -41,6 +41,7 @@
static bool isPropertyAnimatable(CSSPropertyID);
static bool animationOfPropertyIsAccelerated(CSSPropertyID);
static bool propertiesEqual(CSSPropertyID, const RenderStyle* a, const RenderStyle* b);
+ static bool canPropertyBeInterpolated(CSSPropertyID, const RenderStyle* a, const RenderStyle* b);
static CSSPropertyID getPropertyAtIndex(int, bool& isShorthand);
static int getNumProperties();
Modified: trunk/Source/WebCore/style/StyleTreeResolver.cpp (232945 => 232946)
--- trunk/Source/WebCore/style/StyleTreeResolver.cpp 2018-06-18 21:14:40 UTC (rev 232945)
+++ trunk/Source/WebCore/style/StyleTreeResolver.cpp 2018-06-18 21:20:47 UTC (rev 232946)
@@ -292,11 +292,13 @@
// First, we need to make sure that any new CSS animation occuring on this element has a matching WebAnimation
// on the document timeline. Note that we get timeline() on the Document here because we need a timeline created
// in case no Web Animations have been created through the JS API.
- if ((oldStyle && oldStyle->hasTransitions()) || newStyle->hasTransitions())
- m_document.timeline().updateCSSTransitionsForElement(element, *newStyle, oldStyle);
+ if (element.document().pageCacheState() == Document::NotInPageCache && !element.document().renderView()->printing()) {
+ if (oldStyle && (oldStyle->hasTransitions() || newStyle->hasTransitions()))
+ m_document.timeline().updateCSSTransitionsForElement(element, *oldStyle, *newStyle);
- if ((oldStyle && oldStyle->hasAnimations()) || newStyle->hasAnimations())
- m_document.timeline().updateCSSAnimationsForElement(element, *newStyle, oldStyle);
+ if ((oldStyle && oldStyle->hasAnimations()) || newStyle->hasAnimations())
+ m_document.timeline().updateCSSAnimationsForElement(element, oldStyle, *newStyle);
+ }
}
if (auto timeline = m_document.existingTimeline()) {