Make viewport units work in CSS gradients
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 23 May 2014 05:18:23 +0000 (05:18 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 23 May 2014 05:18:23 +0000 (05:18 +0000)
https://bugs.webkit.org/show_bug.cgi?id=133204
<rdar://problem/17012259>

Source/WebCore:

Reviewed by Tim Horton.

Make viewport percentage lengths work in gradients.

Test: fast/gradients/viewport-units-gradient.html

* css/CSSGradientValue.cpp:
(WebCore::CSSGradientValue::addStops):
(WebCore::CSSLinearGradientValue::createGradient):
(WebCore::CSSRadialGradientValue::createGradient):
* css/CSSGradientValue.h:

LayoutTests:

Reviewed by Tim Horton.

Make viewport percentage lengths work in gradients.

* fast/gradients/viewport-units-gradient-expected.html: Added.
* fast/gradients/viewport-units-gradient.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@169248 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/gradients/viewport-units-gradient-expected.html [new file with mode: 0644]
LayoutTests/fast/gradients/viewport-units-gradient.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/css/CSSGradientValue.cpp
Source/WebCore/css/CSSGradientValue.h

index 80e0741..209b7f3 100644 (file)
@@ -1,3 +1,16 @@
+2014-05-22  Simon Fraser  <simon.fraser@apple.com>
+
+        Make viewport units work in CSS gradients
+        https://bugs.webkit.org/show_bug.cgi?id=133204
+        <rdar://problem/17012259>
+
+        Reviewed by Tim Horton.
+
+        Make viewport percentage lengths work in gradients.
+
+        * fast/gradients/viewport-units-gradient-expected.html: Added.
+        * fast/gradients/viewport-units-gradient.html: Added.
+
 2014-05-22  Ryosuke Niwa  <rniwa@webkit.org>
 
         Can't type in status in facebook.com on iOS Safari because keyboard disappears
diff --git a/LayoutTests/fast/gradients/viewport-units-gradient-expected.html b/LayoutTests/fast/gradients/viewport-units-gradient-expected.html
new file mode 100644 (file)
index 0000000..ef1fea5
--- /dev/null
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        html {
+            background-image: linear-gradient(white, white 300px, black 300px, black 600px);
+        }
+        
+        body {
+            height: 600px;
+        }
+    </style>
+</head>
+<body>
+
+</body>
+</html>
diff --git a/LayoutTests/fast/gradients/viewport-units-gradient.html b/LayoutTests/fast/gradients/viewport-units-gradient.html
new file mode 100644 (file)
index 0000000..facdbe2
--- /dev/null
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        html {
+            background-image: linear-gradient(white, white 50vh, black 50vh, black 100vh);
+        }
+        
+        body {
+            height: 600px;
+        }
+    </style>
+</head>
+<body>
+</body>
+</html>
index 5aaedec..f5422ec 100644 (file)
@@ -1,3 +1,21 @@
+2014-05-22  Simon Fraser  <simon.fraser@apple.com>
+
+        Make viewport units work in CSS gradients
+        https://bugs.webkit.org/show_bug.cgi?id=133204
+        <rdar://problem/17012259>
+        
+        Reviewed by Tim Horton.
+        
+        Make viewport percentage lengths work in gradients.
+
+        Test: fast/gradients/viewport-units-gradient.html
+
+        * css/CSSGradientValue.cpp:
+        (WebCore::CSSGradientValue::addStops):
+        (WebCore::CSSLinearGradientValue::createGradient):
+        (WebCore::CSSRadialGradientValue::createGradient):
+        * css/CSSGradientValue.h:
+
 2014-05-22  Benjamin Poulain  <bpoulain@apple.com>
 
         [iOS][WK2] Add support for minimal-ui viewports
index ea5984e..0d85d94 100644 (file)
@@ -129,7 +129,7 @@ PassRefPtr<CSSGradientValue> CSSGradientValue::gradientWithStylesResolved(StyleR
     return result.release();
 }
 
-void CSSGradientValue::addStops(Gradient* gradient, const CSSToLengthConversionData& conversionData, float maxLengthForRepeat)
+void CSSGradientValue::addStops(Gradient* gradient, RenderView* renderView, const CSSToLengthConversionData& conversionData, float maxLengthForRepeat)
 {
     if (m_gradientType == CSSDeprecatedLinearGradient || m_gradientType == CSSDeprecatedRadialGradient) {
         sortStopsIfNeeded();
@@ -171,18 +171,21 @@ void CSSGradientValue::addStops(Gradient* gradient, const CSSToLengthConversionD
         stops[i].color = stop.m_resolvedColor;
 
         if (stop.m_position) {
-            if (stop.m_position->isPercentage())
-                stops[i].offset = stop.m_position->getFloatValue(CSSPrimitiveValue::CSS_PERCENTAGE) / 100;
-            else if (stop.m_position->isLength() || stop.m_position->isCalculatedPercentageWithLength()) {
+            const CSSPrimitiveValue& positionValue = *stop.m_position;
+            if (positionValue.isPercentage())
+                stops[i].offset = positionValue.getFloatValue(CSSPrimitiveValue::CSS_PERCENTAGE) / 100;
+            else if (positionValue.isLength() || positionValue.isViewportPercentageLength() || positionValue.isCalculatedPercentageWithLength()) {
                 if (!computedGradientLength) {
                     FloatSize gradientSize(gradientStart - gradientEnd);
                     gradientLength = gradientSize.diagonalLength();
                 }
                 float length;
-                if (stop.m_position->isLength())
-                    length = stop.m_position->computeLength<float>(conversionData);
+                if (positionValue.isLength())
+                    length = positionValue.computeLength<float>(conversionData);
+                else if (positionValue.isViewportPercentageLength())
+                    length = valueForLength(positionValue.viewportPercentageLength(), 0, renderView);
                 else {
-                    Ref<CalculationValue> calculationValue { stop.m_position->cssCalcValue()->createCalculationValue(conversionData) };
+                    Ref<CalculationValue> calculationValue { positionValue.cssCalcValue()->createCalculationValue(conversionData) };
                     length = calculationValue->evaluate(gradientLength);
                 }
                 stops[i].offset = (gradientLength > 0) ? length / gradientLength : 0;
@@ -701,7 +704,7 @@ PassRefPtr<Gradient> CSSLinearGradientValue::createGradient(RenderElement* rende
     RefPtr<Gradient> gradient = Gradient::create(firstPoint, secondPoint);
 
     // Now add the stops.
-    addStops(gradient.get(), conversionData, 1);
+    addStops(gradient.get(), &renderer->view(), conversionData, 1);
 
     return gradient.release();
 }
@@ -1115,7 +1118,7 @@ PassRefPtr<Gradient> CSSRadialGradientValue::createGradient(RenderElement* rende
     }
 
     // Now add the stops.
-    addStops(gradient.get(), conversionData, maxExtent);
+    addStops(gradient.get(), &renderer->view(), conversionData, maxExtent);
 
     return gradient.release();
 }
index 75e10b7..4e5bac0 100644 (file)
@@ -35,6 +35,7 @@ namespace WebCore {
 
 class FloatPoint;
 class Gradient;
+class RenderView;
 
 enum CSSGradientType {
     CSSDeprecatedLinearGradient,
@@ -109,7 +110,7 @@ protected:
     {
     }
 
-    void addStops(Gradient*, const CSSToLengthConversionData&, float maxLengthForRepeat = 0);
+    void addStops(Gradient*, RenderView*, const CSSToLengthConversionData&, float maxLengthForRepeat = 0);
 
     // Resolve points/radii to front end values.
     FloatPoint computeEndPoint(CSSPrimitiveValue*, CSSPrimitiveValue*, const CSSToLengthConversionData&, const FloatSize&);