+2012-06-27 Mike Lawther <mikelawther@chromium.org>
+
+ CSS3 calc: blending involving expressions
+ https://bugs.webkit.org/show_bug.cgi?id=86160
+
+ Reviewed by Tony Chang.
+
+ Removed existing test as it was folded into transitions.html.
+
+ * css3/calc/transition-start-end-with-calc-expected.txt: Removed.
+ * css3/calc/transition-start-end-with-calc.html: Removed.
+ * css3/calc/transitions-dependent-expected.txt: Added.
+ * css3/calc/transitions-dependent.html: Added.
+ * css3/calc/transitions-expected.txt: Added.
+ * css3/calc/transitions.html: Added.
+
2012-06-27 Shinya Kawanaka <shinyak@chromium.org>
[Shadow] Triggers assertion in VisibleSelection::adjustSelectionToAvoidCrossingBoundaries()
+++ /dev/null
-This tests that transitions beginning and ending with calc() expressions move to the final state.
-PASS - "width" property for "rect" element at 0.0s was: 51
-PASS - "width" property for "rect" element at 1s saw something close to: 400
-
+++ /dev/null
-<!DOCTYPE html>
-<style>
-#rect {
- background-color: green;
- height: 100px;
- -webkit-transition: all 1s;
- -moz-transition: all 1s;
- width: -webkit-calc(10% + 1px);
- width: -moz-calc(10% + 1px);
-}
-#rect.go {
- width: -webkit-calc(100% - 100px);
- width: -moz-calc(100% - 100px);
-}
-</style>
-
-This tests that transitions beginning and ending with calc() expressions move to the final state.
-<div style="width:500px; border: 1px solid black;">
- <div id="rect"></div>
-</div>
-<div id="result"></div>
-
-<script src="../../transitions/resources/transition-test-helpers.js"></script>
-<script>
-const expectedValues = [
- // [time, element-id, property, expected-value, tolerance]
- [1.0, 'rect', 'width', 400, 0],
-];
-
-function setupTest()
-{
- var expectedStartWidth = 51; // (10% + 1px) where 100% = 500px
- var rect = document.getElementById("rect");
- var width = rect.offsetWidth;
- if (width == expectedStartWidth)
- rect.innerHTML += 'PASS - "width" property for "rect" element at 0.0s was: ' + width;
- else
- rect.innerHTML += 'FAIL - "width" property for "rect" element at 0.0s expected: ' + expectedStartWidth + 'but saw: ' + width;
-
- rect.className = "go";
-}
-
-runTransitionTest(expectedValues, setupTest, true, false /* pixel test */);
-
-</script>
--- /dev/null
+This tests that calc() expressions depending on transitioning elements behave correctly.
+PASS - "width" property for "inner" element at 0s was: 60
+PASS - "width" property for "inner" element at 0.25s was: 110
+PASS - "width" property for "inner" element at 0.5s was: 160
+PASS - "width" property for "inner" element at 0.75s was: 210
+PASS - "width" property for "inner" element at 1s was: 260
+PASS - "width" property for "innerTransition" element at 0s was: 20
+PASS - "width" property for "innerTransition" element at 0.25s was: 70
+PASS - "width" property for "innerTransition" element at 0.5s was: 165
+PASS - "width" property for "innerTransition" element at 0.75s was: 305
+PASS - "width" property for "innerTransition" element at 1s was: 490
+
--- /dev/null
+<!DOCTYPE html>
+<style>
+.outerBlock {
+ border: 1px solid black;
+ -webkit-transition: all 1s linear;
+ -moz-transition: all 1s linear;
+}
+
+.innerBlock {
+ background-color: green;
+ height: 100px;
+ -webkit-transition: all 1s linear;
+ -moz-transition: all 1s linear;
+}
+
+#outer {
+ width: 100px;
+}
+
+#outer.go {
+ width: 500px;
+}
+
+#inner {
+ width: -webkit-calc(50% + 10px);
+}
+
+#innerTransition {
+ width: -webkit-calc(10% + 10px);
+}
+
+#innerTransition.go {
+ width: -webkit-calc(100% - 10px);
+}
+
+</style>
+
+This tests that calc() expressions depending on transitioning elements behave correctly.
+<div class="outerBlock" id="outer">
+ <div class="innerBlock" id="inner"></div>
+ <div class="innerBlock" id="innerTransition"></div>
+</div>
+<div id="result"></div>
+
+<script src="../../transitions/resources/transition-test-helpers.js"></script>
+<script>
+
+if (window.testRunner)
+ window.testRunner.dumpAsText();
+
+const transitioningElements = ["outer", "innerTransition"];
+
+expectedValues = [
+ // time, element, property, expected-value, depends-on
+ [0.00, "inner", 'width', 60, "outer"],
+ [0.25, "inner", 'width', 110, "outer"],
+ [0.50, "inner", 'width', 160, "outer"],
+ [0.75, "inner", 'width', 210, "outer"],
+ [1.00, "inner", 'width', 260, "outer"],
+
+ [0.00, "innerTransition", 'width', 20, "outer"],
+ [0.25, "innerTransition", 'width', 70, "outer"],
+ [0.50, "innerTransition", 'width', 165, "outer"],
+ [0.75, "innerTransition", 'width', 305, "outer"],
+ [1.00, "innerTransition", 'width', 490, "outer"],
+];
+
+function runTest(expected)
+{
+ for (var i = 0; i < expected.length; ++i) {
+ var time = expected[i][0];
+ var elementId = expected[i][1];
+ var property = expected[i][2];
+ var expectedValue = expected[i][3];
+ var dependsOn = expected[i][4];
+
+ if (window.testRunner) {
+ window.testRunner.pauseTransitionAtTimeOnElementWithId(property, time, dependsOn);
+ window.testRunner.pauseTransitionAtTimeOnElementWithId(property, time, elementId);
+ var actual = window.getComputedStyle(document.getElementById(elementId)).getPropertyCSSValue(property).getFloatValue(CSSPrimitiveValue.CSS_NUMBER);
+ var result = document.getElementById("result");
+
+ if (actual == expectedValue)
+ result.innerHTML += 'PASS - "' + property + '" property for "' + elementId +'" element at ' + time + 's was: ' + actual + '<br/>';
+ else
+ result.innerHTML += 'FAIL - "' + property + '" property for "' + elementId +'" element at ' + time + 's expected: ' + expectedValue + ' but saw: ' + actual + '<br/>';
+ }
+
+ }
+}
+
+for (var i = 0; i < transitioningElements.length; i++) {
+ var element = document.getElementById(transitioningElements[i]);
+ element.className += " go";
+}
+
+window.addEventListener("load", function() { waitForAnimationStart(runTest(expectedValues)); }, false);
+
+</script>
--- /dev/null
+This tests that transitions containing calc() expressions transition correctly.
+PASS - "width" property for "startCalcEndCalc" element at 0.0s was: 100
+PASS - "width" property for "startPxEndCalc" element at 0.0s was: 100
+PASS - "width" property for "startPercentEndCalc" element at 0.0s was: 100
+PASS - "width" property for "startCalcEndPx" element at 0.0s was: 100
+PASS - "width" property for "startCalcEndPercent" element at 0.0s was: 100
+PASS - "width" property for "startCalcEndCalc" element at 0.25s saw something close to: 175
+PASS - "width" property for "startCalcEndCalc" element at 0.5s saw something close to: 250
+PASS - "width" property for "startCalcEndCalc" element at 0.75s saw something close to: 325
+PASS - "width" property for "startCalcEndCalc" element at 1s saw something close to: 400
+PASS - "width" property for "startPxEndCalc" element at 0.25s saw something close to: 175
+PASS - "width" property for "startPxEndCalc" element at 0.5s saw something close to: 250
+PASS - "width" property for "startPxEndCalc" element at 0.75s saw something close to: 325
+PASS - "width" property for "startPxEndCalc" element at 1s saw something close to: 400
+PASS - "width" property for "startPercentEndCalc" element at 0.25s saw something close to: 175
+PASS - "width" property for "startPercentEndCalc" element at 0.5s saw something close to: 250
+PASS - "width" property for "startPercentEndCalc" element at 0.75s saw something close to: 325
+PASS - "width" property for "startPercentEndCalc" element at 1s saw something close to: 400
+PASS - "width" property for "startCalcEndPx" element at 0.25s saw something close to: 175
+PASS - "width" property for "startCalcEndPx" element at 0.5s saw something close to: 250
+PASS - "width" property for "startCalcEndPx" element at 0.75s saw something close to: 325
+PASS - "width" property for "startCalcEndPx" element at 1s saw something close to: 400
+PASS - "width" property for "startCalcEndPercent" element at 0.25s saw something close to: 175
+PASS - "width" property for "startCalcEndPercent" element at 0.5s saw something close to: 250
+PASS - "width" property for "startCalcEndPercent" element at 0.75s saw something close to: 325
+PASS - "width" property for "startCalcEndPercent" element at 1s saw something close to: 400
+
--- /dev/null
+<!DOCTYPE html>
+<style>
+.transitionTest {
+ background-color: green;
+ height: 100px;
+ -webkit-transition: all 1s linear;
+ -moz-transition: all 1s linear;
+}
+
+#startCalcEndCalc, #startCalcEndPx, #startCalcEndPercent {
+ width: -webkit-calc(10% + 50px);
+ width: -moz-calc(10% + 50px);
+}
+
+#startPxEndCalc {
+ width: 100px;
+}
+
+#startPercentEndCalc {
+ width: 20%;
+}
+
+#startCalcEndCalc.go, #startPxEndCalc.go, #startPercentEndCalc.go {
+ width: -webkit-calc(100% - 100px);
+ width: -moz-calc(100% - 100px);
+}
+
+#startCalcEndPx.go {
+ width: 400px;
+}
+
+#startCalcEndPercent.go {
+ width: 80%;
+}
+</style>
+
+This tests that transitions containing calc() expressions transition correctly.
+<div style="width:500px; border: 1px solid black;">
+ <div class="transitionTest" id="startCalcEndCalc"></div>
+ <div class="transitionTest" id="startPxEndCalc"></div>
+ <div class="transitionTest" id="startPercentEndCalc"></div>
+ <div class="transitionTest" id="startCalcEndPx"></div>
+ <div class="transitionTest" id="startCalcEndPercent"></div>
+</div>
+<div id="result"></div>
+
+<script src="../../transitions/resources/transition-test-helpers.js"></script>
+<script>
+
+const tests = ["startCalcEndCalc", "startPxEndCalc", "startPercentEndCalc", "startCalcEndPx", "startCalcEndPercent"];
+
+expectedValues = [];
+
+for (var i = 0; i < tests.length; i++) {
+ expectedValues = expectedValues.concat([[0.25, tests[i], 'width', 175, 2]]);
+ expectedValues = expectedValues.concat([[0.5, tests[i], 'width', 250, 2]]);
+ expectedValues = expectedValues.concat([[0.75, tests[i], 'width', 325, 2]]);
+ expectedValues = expectedValues.concat([[1.0, tests[i], 'width', 400, 2]]);
+}
+
+function initialize(id)
+{
+ var expectedStartWidth = 100;
+ var element = document.getElementById(id);
+ var width = element.offsetWidth;
+ if (width == expectedStartWidth)
+ element.innerHTML += 'PASS - "width" property for "' + id +'" element at 0.0s was: ' + width;
+ else
+ element.innerHTML += 'FAIL - "width" property for "' + id +'" element at 0.0s expected: ' + expectedStartWidth + ' but saw: ' + width;
+
+ element.className += " go";
+}
+
+function setupTest()
+{
+ for (var i = 0; i < tests.length; i++)
+ initialize(tests[i]);
+}
+
+runTransitionTest(expectedValues, setupTest, true, false /* pixel test */);
+
+</script>
+2012-06-27 Mike Lawther <mikelawther@chromium.org>
+
+ CSS3 calc: blending involving expressions
+ https://bugs.webkit.org/show_bug.cgi?id=86160
+
+ Reviewed by Tony Chang.
+
+ If either endpoint of a blend involves a calc expression, we create a new
+ expression to perform the blend calculation.
+
+ Test: css3/calc/transitions.html
+ css3/calc/transitions-dependent.html
+
+ * platform/Length.cpp:
+ (WebCore):
+ (WebCore::Length::blendCalculation):
+ * platform/Length.h:
+ (WebCore::Length::blend):
+ (Length):
+
2012-06-27 Hans Muller <hmuller@adobe.com>
Move CSSWrapShape style resolution from StyleResolver to StyleBuilder
{
m_intValue = calcHandles().insert(calc);
}
+
+Length Length::blendCalculation(const Length& from, double progress) const
+{
+ if (progress <= 0.0)
+ return from;
+
+ if (progress >= 1.0)
+ return *this;
+
+ // FIXME: https://webkit.org/b/90037 - some of these allocations can be eliminated
+ OwnPtr<CalcExpressionNode> startScale = adoptPtr(new CalcExpressionNumber(1.0 - progress));
+ OwnPtr<CalcExpressionNode> startLength = adoptPtr(new CalcExpressionLength(from));
+ OwnPtr<CalcExpressionNode> startNode = adoptPtr(new CalcExpressionBinaryOperation(startScale.release(), startLength.release(), CalcMultiply));
+ OwnPtr<CalcExpressionNode> endScale = adoptPtr(new CalcExpressionNumber(progress));
+ OwnPtr<CalcExpressionNode> endLength = adoptPtr(new CalcExpressionLength(*this));
+ OwnPtr<CalcExpressionNode> endNode = adoptPtr(new CalcExpressionBinaryOperation(endScale.release(), endLength.release(), CalcMultiply));
+
+ OwnPtr<CalcExpressionNode> blend = adoptPtr(new CalcExpressionBinaryOperation(startNode.release(), endNode.release(), CalcAdd));
+
+ return Length(CalculationValue::create(blend.release(), CalculationRangeAll));
+}
+
PassRefPtr<CalculationValue> Length::calculationValue() const
{
ASSERT(isCalculated());
Length blend(const Length& from, double progress) const
{
// Blend two lengths to produce a new length that is in between them. Used for animation.
+ if (from.type() == Calculated || type() == Calculated)
+ return blendCalculation(from, progress);
+
if (!from.isZero() && !isZero() && from.type() != type())
return *this;
if (from.isZero() && isZero())
return *this;
-
- // FIXME http://webkit.org/b/86160 - Blending doesn't work with calculated expressions
- if (from.type() == Calculated || type() == Calculated)
- return *this;
LengthType resultType = type();
if (isZero())
incrementCalculatedRef();
}
+ Length blendCalculation(const Length& from, double progress) const;
+
int calculationHandle() const
{
ASSERT(isCalculated());