Title: [217236] trunk
Revision
217236
Author
[email protected]
Date
2017-05-22 12:19:24 -0700 (Mon, 22 May 2017)

Log Message

Support transform-box to switch sizing box in SVG
https://bugs.webkit.org/show_bug.cgi?id=145783

Reviewed by Dean Jackson.

Source/WebCore:

Add support for the CSS "transform-box" property, as described at
<https://drafts.csswg.org/css-transforms/#transform-box>.

This changes the behavior of percentage values in transform-origin in SVG.
When these were added in r110532, percentage values in transform-origin were made
relative to the bounding box, but absolute values relative to the view box.
<https://github.com/w3c/csswg-drafts/issues/895> has concluded that this behavior
is confusing. The new behavior is that, for SVG elements, both absolute and
percentage values are relative to the reference box, which is specified by the
new transform-box property.

The initial value for transform-box is border-box, with the svg.css UA stylesheet
supplying a default of view-box for the relevant SVG elements per
<https://www.w3.org/TR/SVG2/styling.html#UAStyleSheet>.

For non-SVG elements, the used value is always border-box, so there is no change
in behavior.

Tests: fast/css/transform-box-parsing.html
       svg/transforms/svg-transform-box.html

* css/CSSComputedStyleDeclaration.cpp:
(WebCore::ComputedStyleExtractor::propertyValue):
* css/CSSPrimitiveValueMappings.h:
(WebCore::CSSPrimitiveValue::CSSPrimitiveValue):
(WebCore::CSSPrimitiveValue::operator TransformBox):
* css/CSSProperties.json:
* css/CSSValueKeywords.in:
* css/parser/CSSPropertyParser.cpp:
(WebCore::CSSPropertyParser::parseSingleValue):
* css/svg.css:
(*:not(svg),):
(*): Deleted.
(html|* > svg): Deleted.
* page/animation/AnimationBase.cpp:
(WebCore::AnimationBase::computeTransformedExtentViaTransformList):
* rendering/style/RenderStyle.cpp:
(WebCore::RenderStyle::applyTransform): The transformOriginX().isPercent() tests
were added to support the weird "% values are relative to bounding box" in SVG. Now
it's up to the caller to pass a non-zero origin when that matters, and
SVGGraphicsElement::animatedLocalTransform() is the only caller that does so.
* rendering/style/RenderStyle.h:
(WebCore::RenderStyle::hasTransform):
(WebCore::RenderStyle::transformBox):
(WebCore::RenderStyle::setTransformBox):
(WebCore::RenderStyle::initialTransformBox):
* rendering/style/RenderStyleConstants.h:
* rendering/style/StyleTransformData.cpp:
(WebCore::StyleTransformData::StyleTransformData):
(WebCore::StyleTransformData::operator==):
* rendering/style/StyleTransformData.h:
* svg/SVGGraphicsElement.cpp:
(WebCore::SVGGraphicsElement::animatedLocalTransform): Consult the transform-box
style to compute the reference box as the bounding box, or the view box.

Source/WebInspectorUI:

Add transform-box to the list of autocompletions.

* UserInterface/External/CodeMirror/css.js:

LayoutTests:

Modify tests that relied on the old "% values relative to the bounding box" behavior,
and new tests for parsing and rendering with transform-box.

* fast/css/transform-box-parsing.html: Added.
* svg/transforms/change-transform-origin-css.xhtml:
* svg/transforms/change-transform-origin-presentation-attribute.xhtml:
* svg/transforms/percent-transform-values.xhtml:
* svg/transforms/svg-transform-box-expected.html: Added.
* svg/transforms/svg-transform-box.html: Added.
* svg/transforms/transform-origin-css-property.xhtml:
* transforms/svg-vs-css.xhtml:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (217235 => 217236)


--- trunk/LayoutTests/ChangeLog	2017-05-22 19:14:14 UTC (rev 217235)
+++ trunk/LayoutTests/ChangeLog	2017-05-22 19:19:24 UTC (rev 217236)
@@ -1,3 +1,22 @@
+2017-05-22  Simon Fraser  <[email protected]>
+
+        Support transform-box to switch sizing box in SVG
+        https://bugs.webkit.org/show_bug.cgi?id=145783
+
+        Reviewed by Dean Jackson.
+
+        Modify tests that relied on the old "% values relative to the bounding box" behavior,
+        and new tests for parsing and rendering with transform-box.
+
+        * fast/css/transform-box-parsing.html: Added.
+        * svg/transforms/change-transform-origin-css.xhtml:
+        * svg/transforms/change-transform-origin-presentation-attribute.xhtml:
+        * svg/transforms/percent-transform-values.xhtml:
+        * svg/transforms/svg-transform-box-expected.html: Added.
+        * svg/transforms/svg-transform-box.html: Added.
+        * svg/transforms/transform-origin-css-property.xhtml:
+        * transforms/svg-vs-css.xhtml:
+
 2017-05-22  Antti Koivisto  <[email protected]>
 
         Crash in WebCore::StyleRuleKeyframes::findKeyframeIndex

Added: trunk/LayoutTests/fast/css/transform-box-parsing-expected.txt (0 => 217236)


--- trunk/LayoutTests/fast/css/transform-box-parsing-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/css/transform-box-parsing-expected.txt	2017-05-22 19:19:24 UTC (rev 217236)
@@ -0,0 +1,28 @@
+This tests checks parsing of the 'transform-box' property
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS testPropertyValue("transform-box: border-box", "transform-box") is "border-box"
+PASS testPropertyValue("transform-box: fill-box", "transform-box") is "fill-box"
+PASS testPropertyValue("transform-box: view-box", "transform-box") is "view-box"
+
+PASS testComputedStyle("", "transform-box") is "border-box"
+PASS testComputedStyle("transform-box: fill-box", "transform-box") is "fill-box"
+PASS testComputedStyle("transform-box: view-box", "transform-box") is "view-box"
+
+PASS testSVGComputedStyle("", "transform-box") is "view-box"
+PASS testSVGComputedStyle("transform-box: fill-box", "transform-box") is "fill-box"
+PASS testSVGComputedStyle("transform-box: border-box", "transform-box") is "border-box"
+
+PASS testComputedStyleOnElementWithId("foreignObject") is "view-box"
+
+Test default value on elements with CSS layout boxes
+PASS testComputedStyleOnElementWithId("svgRoot") is "border-box"
+PASS testComputedStyleOnElementWithId("nested-svg") is "border-box"
+PASS testComputedStyleOnElementWithId("inside-foreign-object") is "border-box"
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/css/transform-box-parsing.html (0 => 217236)


--- trunk/LayoutTests/fast/css/transform-box-parsing.html	                        (rev 0)
+++ trunk/LayoutTests/fast/css/transform-box-parsing.html	2017-05-22 19:19:24 UTC (rev 217236)
@@ -0,0 +1,90 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<script src=""
+</head>
+<body>
+    <svg id="svgRoot" xmlns="http://www.w3.org/2000/svg">
+        <foreignObject id="foreignObject">
+            <html>
+                <div id="inside-foreign-object"></div>
+            </html>
+        </foreignObject>
+        <foreignObject>
+            <svg id="nested-svg" xmlns="http://www.w3.org/2000/svg" />
+        </foreignObject>
+    </svg>
+    <script>
+        description("This tests checks parsing of the 'transform-box' property");
+
+        function testPropertyValue(declaration, property)
+        {
+            var div = document.createElement("div");
+            div.setAttribute("style", declaration);
+            document.body.appendChild(div);
+
+            var result = div.style.getPropertyValue(property);
+            document.body.removeChild(div);
+            return result;
+        }
+
+        function testComputedStyle(declaration, property)
+        {
+            var div = document.createElement("div");
+            div.setAttribute("style", declaration);
+            document.body.appendChild(div);
+
+            var result = window.getComputedStyle(div).getPropertyValue(property);
+            document.body.removeChild(div);
+            return result;
+        }
+
+        const svgNS = "http://www.w3.org/2000/svg";
+
+        function testSVGComputedStyle(declaration, property)
+        {
+            var svgRoot = document.getElementById('svgRoot');
+
+            var rect = document.createElementNS(svgNS, "rect");
+            rect.setAttribute("style", declaration);
+            svgRoot.appendChild(rect);
+
+            var result = window.getComputedStyle(rect).getPropertyValue(property);
+            svgRoot.removeChild(rect);
+            return result;
+        }
+        
+        function testComputedStyleOnElementWithId(elementId)
+        {
+            return window.getComputedStyle(document.getElementById(elementId)).getPropertyValue("transform-box");
+        }
+
+        shouldBeEqualToString('testPropertyValue("transform-box: border-box", "transform-box")', 'border-box');
+        shouldBeEqualToString('testPropertyValue("transform-box: fill-box", "transform-box")', 'fill-box');
+        shouldBeEqualToString('testPropertyValue("transform-box: view-box", "transform-box")', 'view-box');
+
+        debug('');
+        shouldBeEqualToString('testComputedStyle("", "transform-box")', 'border-box');
+        shouldBeEqualToString('testComputedStyle("transform-box: fill-box", "transform-box")', 'fill-box');
+        shouldBeEqualToString('testComputedStyle("transform-box: view-box", "transform-box")', 'view-box');
+
+        debug('');
+        shouldBeEqualToString('testSVGComputedStyle("", "transform-box")', 'view-box');
+        shouldBeEqualToString('testSVGComputedStyle("transform-box: fill-box", "transform-box")', 'fill-box');
+        shouldBeEqualToString('testSVGComputedStyle("transform-box: border-box", "transform-box")', 'border-box');
+
+        debug('');
+        shouldBeEqualToString('testComputedStyleOnElementWithId("foreignObject")', 'view-box');
+
+        debug('');
+        debug('Test default value on elements with CSS layout boxes');
+        shouldBeEqualToString('testComputedStyleOnElementWithId("svgRoot")', 'border-box');
+        shouldBeEqualToString('testComputedStyleOnElementWithId("nested-svg")', 'border-box');
+        shouldBeEqualToString('testComputedStyleOnElementWithId("inside-foreign-object")', 'border-box');
+
+        debug('');
+    </script>
+
+<script src=""
+</body>
+</html>

Modified: trunk/LayoutTests/svg/transforms/change-transform-origin-css.xhtml (217235 => 217236)


--- trunk/LayoutTests/svg/transforms/change-transform-origin-css.xhtml	2017-05-22 19:14:14 UTC (rev 217235)
+++ trunk/LayoutTests/svg/transforms/change-transform-origin-css.xhtml	2017-05-22 19:19:24 UTC (rev 217236)
@@ -9,11 +9,11 @@
 
 <body>
   <svg xmlns="http://www.w3.org/2000/svg" style="position: absolute; top: 0px; left: 0px;">
-      <rect id="rect" width="50px" height="50px" x="50" y="50" fill="green" style="-webkit-transform: scale(2, 2);"/>
+      <rect id="rect" width="50px" height="50px" x="50" y="50" fill="green" style="transform: scale(2, 2); transform-box: fill-box;"/>
   </svg>
 
   <script><![CDATA[
-      document.getElementById('rect').style.webkitTransformOrigin = "50% 50%";
+      document.getElementById('rect').style.transformOrigin = "50% 50%";
   ]]></script>
 </body>
 </html>

Modified: trunk/LayoutTests/svg/transforms/change-transform-origin-presentation-attribute.xhtml (217235 => 217236)


--- trunk/LayoutTests/svg/transforms/change-transform-origin-presentation-attribute.xhtml	2017-05-22 19:14:14 UTC (rev 217235)
+++ trunk/LayoutTests/svg/transforms/change-transform-origin-presentation-attribute.xhtml	2017-05-22 19:19:24 UTC (rev 217236)
@@ -8,7 +8,7 @@
 
 <body>
   <svg xmlns="http://www.w3.org/2000/svg" style="position: absolute; top: 0px; left: 0px;">
-      <rect id="rect" width="50px" height="50px" x="50" y="50" fill="green" transform-origin="0 0" style="-webkit-transform: scale(2, 2);"/>
+      <rect id="rect" width="50px" height="50px" x="50" y="50" fill="green" transform-origin="0 0" style="transform: scale(2, 2); transform-box: fill-box;"/>
   </svg>
 
   <script><![CDATA[

Modified: trunk/LayoutTests/svg/transforms/percent-transform-values.xhtml (217235 => 217236)


--- trunk/LayoutTests/svg/transforms/percent-transform-values.xhtml	2017-05-22 19:14:14 UTC (rev 217235)
+++ trunk/LayoutTests/svg/transforms/percent-transform-values.xhtml	2017-05-22 19:19:24 UTC (rev 217236)
@@ -1,6 +1,6 @@
 <html xmlns="http://www.w3.org/1999/xhtml">
 <body>
-  <p>Test for bug <a href="" - SVG should support transform-origin and relative values
+  <p>Test for bug <a href="" - SVG should support transform-origin and relative values
   Verify that CSS transform translate values can be specified with percentages.
   </p>
   You should see a series of "PASS" messages and one 80x60 green rectangle.   The green rectangle obscures two
@@ -8,9 +8,9 @@
   <p>
   </p>
   <svg style="position:absolute; left:0px; top:0px;" xmlns="http://www.w3.org/2000/svg">
-    <rect id="r1" x="10" y="200" width="80" height="60" fill="red" style="-webkit-transform: translate(50%)"/>
-    <rect id="r2" x="90" y="260" width="80" height="60" fill="red" style="-webkit-transform: translate(-50%, -100%)"/>
-    <rect id="r3" x="10" y="200" width="80" height="60" fill="green" style="-webkit-transform: translate(50%, 0%)"/>
+    <rect id="r1" x="10" y="200" width="80" height="60" fill="red" style="transform-box: fill-box; transform: translate(50%)"/>
+    <rect id="r2" x="90" y="260" width="80" height="60" fill="red" style="transform-box: fill-box; transform: translate(-50%, -100%)"/>
+    <rect id="r3" x="10" y="200" width="80" height="60" fill="green" style="transform-box: fill-box; transform: translate(50%, 0%)"/>
   </svg>
   <pre id="log"></pre>
 </body>

Added: trunk/LayoutTests/svg/transforms/svg-transform-box-expected.html (0 => 217236)


--- trunk/LayoutTests/svg/transforms/svg-transform-box-expected.html	                        (rev 0)
+++ trunk/LayoutTests/svg/transforms/svg-transform-box-expected.html	2017-05-22 19:19:24 UTC (rev 217236)
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+  <style>
+    svg {
+        border: 1px solid black;
+    }
+  </style>
+</head>
+
+<body>
+
+    <div class="container">
+        <p>You should see no red boxes below</p>
+        <svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 600 400" style=" width: 600px; height: 400px;">
+            <!-- transform-box: view-box -->
+            <rect x="20" y="10" width="100" height="50" fill="green" />
+            <rect x="480" y="40" width="50" height="50" fill="green" />
+            <rect x="120" y="120" width="50" height="50" fill="green" />
+            <rect x="20" y="200" width="100" height="50" fill="green" />
+            <rect x="480" y="260" width="50" height="50" fill="green" />
+            <rect x="120" y="320" width="50" height="50" fill="green" />
+        </svg>
+    </div>
+
+</body>
+</html>

Added: trunk/LayoutTests/svg/transforms/svg-transform-box.html (0 => 217236)


--- trunk/LayoutTests/svg/transforms/svg-transform-box.html	                        (rev 0)
+++ trunk/LayoutTests/svg/transforms/svg-transform-box.html	2017-05-22 19:19:24 UTC (rev 217236)
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+  <style>
+    svg {
+        border: 1px solid black;
+    }
+  </style>
+</head>
+
+<body>
+
+    <div class="container">
+        <p>You should see no red boxes below</p>
+        <svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 600 400" style=" width: 600px; height: 400px;">
+            <!-- transform-box: view-box -->
+            <rect x="20" y="10" width="100" height="50" fill="red" />
+            <rect x="20" y="5" width="50" height="25" fill="green" style="transform: scale(2, 2); transform-origin: 20px 0; transform-box: view-box;" />
+
+            <rect x="480" y="40" width="50" height="50" fill="red" />
+            <rect x="0" y="0" width="50" height="50" fill="green" style="transform: translate(80%, 10%); transform-box: view-box;" />
+
+            <rect x="120" y="120" width="50" height="50" fill="red" />
+            <rect x="180" y="10" width="50" height="50" fill="green" style="transform: rotate(90deg); transform-origin: 120px 60px; transform-box: view-box;" />
+            <rect x="180" y="10" width="50" height="50" fill="green" style="transform: rotate(90deg); transform-origin: 20% 15%; transform-box: view-box;" />
+
+            <!-- transform-box: fill-box -->
+            <rect x="20" y="200" width="100" height="50" fill="red" />
+            <rect x="20" y="200" width="50" height="25" fill="green" style="transform: scale(2, 2); transform-box: fill-box;" />
+
+            <rect x="480" y="260" width="50" height="50" fill="red" />
+            <rect x="430" y="310" width="50" height="50" fill="green" style="transform: translate(100%, -100%); transform-box: fill-box;" />
+
+            <rect x="120" y="320" width="50" height="50" fill="red" />
+            <rect x="70" y="270" width="50" height="50" fill="green" style="transform: rotate(180deg); transform-origin: 50px 50px; transform-box: fill-box;" />
+            <rect x="95" y="345" width="50" height="50" fill="green" style="transform: rotate(90deg); transform-origin: 100% 50%; transform-box: fill-box;" />
+        </svg>
+    </div>
+
+</body>
+</html>

Modified: trunk/LayoutTests/svg/transforms/transform-origin-css-property.xhtml (217235 => 217236)


--- trunk/LayoutTests/svg/transforms/transform-origin-css-property.xhtml	2017-05-22 19:14:14 UTC (rev 217235)
+++ trunk/LayoutTests/svg/transforms/transform-origin-css-property.xhtml	2017-05-22 19:19:24 UTC (rev 217236)
@@ -10,7 +10,7 @@
 
 #transformOriginRect {
     fill: green;
-    -webkit-transform: rotate(90deg);
+    transform: rotate(90deg);
 }
 </style>
 
@@ -30,13 +30,13 @@
     function addTransformOriginRect(x, y, s)
     {
        var rect = document.createElementNS(svgNS, "rect");
-       var transformOrigin = (typeof(s) == "string") ? s :  (x + s[0]) + " " + (y + s[1]);
+       var transformOrigin = (typeof(s) == "string") ? s :  (x + s[0]) + "px " + (y + s[1]) + "px";
        rect.setAttribute("id", "transformOriginRect");
        rect.setAttribute("x", x);
        rect.setAttribute("y", y);
        rect.setAttribute("width", 30);
        rect.setAttribute("height", 30);
-       rect.setAttribute("style", "-webkit-transform-origin: " + transformOrigin + ";");
+       rect.setAttribute("style", "transform-box: view-box; transform-origin: " + transformOrigin + ";");
        document.getElementById("svgRoot").appendChild(rect);
     }
 

Modified: trunk/LayoutTests/transforms/svg-vs-css.xhtml (217235 => 217236)


--- trunk/LayoutTests/transforms/svg-vs-css.xhtml	2017-05-22 19:14:14 UTC (rev 217235)
+++ trunk/LayoutTests/transforms/svg-vs-css.xhtml	2017-05-22 19:19:24 UTC (rev 217236)
@@ -97,9 +97,9 @@
     <div class="container">
       <svg xmlns="http://www.w3.org/2000/svg" version="1.1"  
           viewBox="0 0 200 200" style="width:200px; height:200px;">
-          <g id="group1" x="0" y="0" width="60" height="60" transform="translate(75, 25)">
+          <g id="group1" transform="translate(75, 25)">
             <rect x="0" y="0" width="60" height="60" stroke="black" stroke-width="1px" stroke-dasharray="1 1" fill="none" />
-            <g id="group2" x="0" y="0" width="60" height="60" transform="scale(2)" >
+            <g id="group2" transform="scale(2)">
               <rect x="0" y="0" width="60" height="60" stroke="black" stroke-dasharray="1 1" stroke-width="1px" fill="none" />
               <rect id="group3" x="0" y="0" width="60" height="60" stroke="blue" fill="none" transform="rotate(45)" />
             </g>

Modified: trunk/Source/WebCore/ChangeLog (217235 => 217236)


--- trunk/Source/WebCore/ChangeLog	2017-05-22 19:14:14 UTC (rev 217235)
+++ trunk/Source/WebCore/ChangeLog	2017-05-22 19:19:24 UTC (rev 217236)
@@ -1,3 +1,65 @@
+2017-05-22  Simon Fraser  <[email protected]>
+
+        Support transform-box to switch sizing box in SVG
+        https://bugs.webkit.org/show_bug.cgi?id=145783
+
+        Reviewed by Dean Jackson.
+
+        Add support for the CSS "transform-box" property, as described at
+        <https://drafts.csswg.org/css-transforms/#transform-box>.
+        
+        This changes the behavior of percentage values in transform-origin in SVG.
+        When these were added in r110532, percentage values in transform-origin were made
+        relative to the bounding box, but absolute values relative to the view box.
+        <https://github.com/w3c/csswg-drafts/issues/895> has concluded that this behavior
+        is confusing. The new behavior is that, for SVG elements, both absolute and
+        percentage values are relative to the reference box, which is specified by the
+        new transform-box property.
+
+        The initial value for transform-box is border-box, with the svg.css UA stylesheet
+        supplying a default of view-box for the relevant SVG elements per
+        <https://www.w3.org/TR/SVG2/styling.html#UAStyleSheet>.
+
+        For non-SVG elements, the used value is always border-box, so there is no change
+        in behavior.
+
+        Tests: fast/css/transform-box-parsing.html
+               svg/transforms/svg-transform-box.html
+
+        * css/CSSComputedStyleDeclaration.cpp:
+        (WebCore::ComputedStyleExtractor::propertyValue):
+        * css/CSSPrimitiveValueMappings.h:
+        (WebCore::CSSPrimitiveValue::CSSPrimitiveValue):
+        (WebCore::CSSPrimitiveValue::operator TransformBox):
+        * css/CSSProperties.json:
+        * css/CSSValueKeywords.in:
+        * css/parser/CSSPropertyParser.cpp:
+        (WebCore::CSSPropertyParser::parseSingleValue):
+        * css/svg.css:
+        (*:not(svg),):
+        (*): Deleted.
+        (html|* > svg): Deleted.
+        * page/animation/AnimationBase.cpp:
+        (WebCore::AnimationBase::computeTransformedExtentViaTransformList):
+        * rendering/style/RenderStyle.cpp:
+        (WebCore::RenderStyle::applyTransform): The transformOriginX().isPercent() tests
+        were added to support the weird "% values are relative to bounding box" in SVG. Now
+        it's up to the caller to pass a non-zero origin when that matters, and
+        SVGGraphicsElement::animatedLocalTransform() is the only caller that does so.
+        * rendering/style/RenderStyle.h:
+        (WebCore::RenderStyle::hasTransform):
+        (WebCore::RenderStyle::transformBox):
+        (WebCore::RenderStyle::setTransformBox):
+        (WebCore::RenderStyle::initialTransformBox):
+        * rendering/style/RenderStyleConstants.h:
+        * rendering/style/StyleTransformData.cpp:
+        (WebCore::StyleTransformData::StyleTransformData):
+        (WebCore::StyleTransformData::operator==):
+        * rendering/style/StyleTransformData.h:
+        * svg/SVGGraphicsElement.cpp:
+        (WebCore::SVGGraphicsElement::animatedLocalTransform): Consult the transform-box
+        style to compute the reference box as the bounding box, or the view box.
+
 2017-05-22  Chris Dumez  <[email protected]>
 
         Add support for [LegacyWindowAlias] IDL extended attribute

Modified: trunk/Source/WebCore/css/CSSComputedStyleDeclaration.cpp (217235 => 217236)


--- trunk/Source/WebCore/css/CSSComputedStyleDeclaration.cpp	2017-05-22 19:14:14 UTC (rev 217235)
+++ trunk/Source/WebCore/css/CSSComputedStyleDeclaration.cpp	2017-05-22 19:19:24 UTC (rev 217236)
@@ -231,6 +231,7 @@
     CSSPropertyTextTransform,
     CSSPropertyTop,
     CSSPropertyTransform,
+    CSSPropertyTransformBox,
     CSSPropertyTransformOrigin,
     CSSPropertyTransformStyle,
     CSSPropertyTransitionDelay,
@@ -3682,6 +3683,8 @@
             return cssValuePool.createValue(style->speak());
         case CSSPropertyTransform:
             return computedTransform(renderer, *style);
+        case CSSPropertyTransformBox:
+            return CSSPrimitiveValue::create(style->transformBox());
         case CSSPropertyTransformOrigin: {
             auto list = CSSValueList::createSpaceSeparated();
             if (renderer) {

Modified: trunk/Source/WebCore/css/CSSPrimitiveValueMappings.h (217235 => 217236)


--- trunk/Source/WebCore/css/CSSPrimitiveValueMappings.h	2017-05-22 19:14:14 UTC (rev 217235)
+++ trunk/Source/WebCore/css/CSSPrimitiveValueMappings.h	2017-05-22 19:19:24 UTC (rev 217236)
@@ -4414,6 +4414,42 @@
     return TransformStyle3DFlat;
 }
 
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(TransformBox box)
+    : CSSValue(PrimitiveClass)
+{
+    m_primitiveUnitType = CSS_VALUE_ID;
+    switch (box) {
+    case TransformBox::BorderBox:
+        m_value.valueID = CSSValueBorderBox;
+        break;
+    case TransformBox::FillBox:
+        m_value.valueID = CSSValueFillBox;
+        break;
+    case TransformBox::ViewBox:
+        m_value.valueID = CSSValueViewBox;
+        break;
+    }
+}
+
+template<> inline CSSPrimitiveValue::operator TransformBox() const
+{
+    ASSERT(isValueID());
+
+    switch (m_value.valueID) {
+    case CSSValueBorderBox:
+        return TransformBox::BorderBox;
+    case CSSValueFillBox:
+        return TransformBox::FillBox;
+    case CSSValueViewBox:
+        return TransformBox::ViewBox;
+    default:
+        break;
+    }
+
+    ASSERT_NOT_REACHED();
+    return TransformBox::BorderBox;
+}
+
 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(ColumnAxis e)
     : CSSValue(PrimitiveClass)
 {

Modified: trunk/Source/WebCore/css/CSSProperties.json (217235 => 217236)


--- trunk/Source/WebCore/css/CSSProperties.json	2017-05-22 19:14:14 UTC (rev 217235)
+++ trunk/Source/WebCore/css/CSSProperties.json	2017-05-22 19:19:24 UTC (rev 217236)
@@ -5953,6 +5953,19 @@
                 "url": "https://www.w3.org/TR/css-transforms-1/#transform-property"
             }
         },
+        "transform-box": {
+            "values" : [
+                "border-box",
+                "fill-box",
+                "view-box"
+            ],
+            "codegen-properties": {
+            },
+            "specification": {
+                "category": "css-transforms",
+                "url": "https://www.w3.org/TR/css-transforms/#propdef-transform-box"
+            }
+        },
         "transform-origin": {
             "codegen-properties": {
                 "aliases": [

Modified: trunk/Source/WebCore/css/CSSValueKeywords.in (217235 => 217236)


--- trunk/Source/WebCore/css/CSSValueKeywords.in	2017-05-22 19:14:14 UTC (rev 217235)
+++ trunk/Source/WebCore/css/CSSValueKeywords.in	2017-05-22 19:19:24 UTC (rev 217236)
@@ -1247,6 +1247,11 @@
 translateZ
 translate3d
 
+// transform-box
+// border-box
+// view-box
+fill-box
+
 // motion path
 path
 

Modified: trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp (217235 => 217236)


--- trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp	2017-05-22 19:14:14 UTC (rev 217235)
+++ trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp	2017-05-22 19:19:24 UTC (rev 217236)
@@ -4071,6 +4071,8 @@
         return consumeLineWidth(m_range, m_context.mode, UnitlessQuirk::Forbid);
     case CSSPropertyTransform:
         return consumeTransform(m_range, m_context.mode);
+    case CSSPropertyTransformBox:
+        return consumeIdent<CSSValueBorderBox, CSSValueViewBox, CSSValueFillBox>(m_range);
     case CSSPropertyTransformOriginX:
     case CSSPropertyPerspectiveOriginX:
         return consumePositionX(m_range, m_context.mode);

Modified: trunk/Source/WebCore/css/svg.css (217235 => 217236)


--- trunk/Source/WebCore/css/svg.css	2017-05-22 19:14:14 UTC (rev 217235)
+++ trunk/Source/WebCore/css/svg.css	2017-05-22 19:19:24 UTC (rev 217236)
@@ -72,12 +72,8 @@
     outline: auto 5px -webkit-focus-ring-color
 }
 
-/* CSS transform specification: "transform-origin 0 0 for SVG elements without associated CSS layout box, 50% 50% for all other elements". */
- 
-* {
-    -webkit-transform-origin: 0 0;
+*:not(svg),
+*:not(foreignObject) > svg {
+    transform-origin: 0 0;
+    transform-box: view-box;
 }
-
-html|* > svg {
-    -webkit-transform-origin: 50% 50%;
-}

Modified: trunk/Source/WebCore/page/animation/AnimationBase.cpp (217235 => 217236)


--- trunk/Source/WebCore/page/animation/AnimationBase.cpp	2017-05-22 19:14:14 UTC (rev 217235)
+++ trunk/Source/WebCore/page/animation/AnimationBase.cpp	2017-05-22 19:19:24 UTC (rev 217236)
@@ -802,13 +802,10 @@
     
     bool applyTransformOrigin = containsRotation(style.transform().operations()) || style.transform().affectedByTransformOrigin();
     if (applyTransformOrigin) {
-        float offsetX = style.transformOriginX().isPercent() ? rendererBox.x() : 0;
-        float offsetY = style.transformOriginY().isPercent() ? rendererBox.y() : 0;
+        transformOrigin.setX(rendererBox.x() + floatValueForLength(style.transformOriginX(), rendererBox.width()));
+        transformOrigin.setY(rendererBox.y() + floatValueForLength(style.transformOriginY(), rendererBox.height()));
+        // Ignore transformOriginZ because we'll bail if we encounter any 3D transforms.
 
-        transformOrigin.setX(floatValueForLength(style.transformOriginX(), rendererBox.width()) + offsetX);
-        transformOrigin.setY(floatValueForLength(style.transformOriginY(), rendererBox.height()) + offsetY);
-        // Ignore transformOriginZ because we'll bail if we encounter any 3D transforms.
-        
         floatBounds.moveBy(-transformOrigin);
     }
 

Modified: trunk/Source/WebCore/rendering/style/RenderStyle.cpp (217235 => 217236)


--- trunk/Source/WebCore/rendering/style/RenderStyle.cpp	2017-05-22 19:14:14 UTC (rev 217235)
+++ trunk/Source/WebCore/rendering/style/RenderStyle.cpp	2017-05-22 19:19:24 UTC (rev 217236)
@@ -1130,24 +1130,20 @@
 {
     auto& operations = m_rareNonInheritedData->transform->operations.operations();
     bool applyTransformOrigin = requireTransformOrigin(operations, applyOrigin);
-
-    float offsetX = transformOriginX().isPercent() ? boundingBox.x() : 0;
-    float offsetY = transformOriginY().isPercent() ? boundingBox.y() : 0;
-
+    
+    FloatPoint3D originTranslate;
     if (applyTransformOrigin) {
-        transform.translate3d(floatValueForLength(transformOriginX(), boundingBox.width()) + offsetX,
-                              floatValueForLength(transformOriginY(), boundingBox.height()) + offsetY,
-                              transformOriginZ());
+        originTranslate.setX(boundingBox.x() + floatValueForLength(transformOriginX(), boundingBox.width()));
+        originTranslate.setY(boundingBox.y() + floatValueForLength(transformOriginY(), boundingBox.height()));
+        originTranslate.setZ(transformOriginZ());
+        transform.translate3d(originTranslate.x(), originTranslate.y(), originTranslate.z());
     }
 
     for (auto& operation : operations)
         operation->apply(transform, boundingBox.size());
 
-    if (applyTransformOrigin) {
-        transform.translate3d(-floatValueForLength(transformOriginX(), boundingBox.width()) - offsetX,
-                              -floatValueForLength(transformOriginY(), boundingBox.height()) - offsetY,
-                              -transformOriginZ());
-    }
+    if (applyTransformOrigin)
+        transform.translate3d(-originTranslate.x(), -originTranslate.y(), -originTranslate.z());
 }
 
 void RenderStyle::setPageScaleTransform(float scale)

Modified: trunk/Source/WebCore/rendering/style/RenderStyle.h (217235 => 217236)


--- trunk/Source/WebCore/rendering/style/RenderStyle.h	2017-05-22 19:14:14 UTC (rev 217235)
+++ trunk/Source/WebCore/rendering/style/RenderStyle.h	2017-05-22 19:19:24 UTC (rev 217236)
@@ -608,10 +608,11 @@
     ColumnSpan columnSpan() const { return static_cast<ColumnSpan>(m_rareNonInheritedData->multiCol->columnSpan); }
 
     const TransformOperations& transform() const { return m_rareNonInheritedData->transform->operations; }
+    bool hasTransform() const { return !m_rareNonInheritedData->transform->operations.operations().isEmpty(); }
     const Length& transformOriginX() const { return m_rareNonInheritedData->transform->x; }
     const Length& transformOriginY() const { return m_rareNonInheritedData->transform->y; }
     float transformOriginZ() const { return m_rareNonInheritedData->transform->z; }
-    bool hasTransform() const { return !m_rareNonInheritedData->transform->operations.operations().isEmpty(); }
+    TransformBox transformBox() const { return m_rareNonInheritedData->transform->transformBox; }
 
     TextEmphasisFill textEmphasisFill() const { return static_cast<TextEmphasisFill>(m_rareInheritedData->textEmphasisFill); }
     TextEmphasisMark textEmphasisMark() const;
@@ -1135,10 +1136,13 @@
     void resetColumnRule() { SET_NESTED_VAR(m_rareNonInheritedData, multiCol, rule, BorderValue()); }
     void setColumnSpan(ColumnSpan columnSpan) { SET_NESTED_VAR(m_rareNonInheritedData, multiCol, columnSpan, columnSpan); }
     void inheritColumnPropertiesFrom(const RenderStyle& parent) { m_rareNonInheritedData.access().multiCol = parent.m_rareNonInheritedData->multiCol; }
+
     void setTransform(const TransformOperations& ops) { SET_NESTED_VAR(m_rareNonInheritedData, transform, operations, ops); }
     void setTransformOriginX(Length&& length) { SET_NESTED_VAR(m_rareNonInheritedData, transform, x, WTFMove(length)); }
     void setTransformOriginY(Length&& length) { SET_NESTED_VAR(m_rareNonInheritedData, transform, y, WTFMove(length)); }
     void setTransformOriginZ(float f) { SET_NESTED_VAR(m_rareNonInheritedData, transform, z, f); }
+    void setTransformBox(TransformBox box) { SET_NESTED_VAR(m_rareNonInheritedData, transform, transformBox, box); }
+
     void setSpeak(ESpeak s) { SET_VAR(m_rareInheritedData, speak, s); }
     void setTextCombine(TextCombine v) { SET_VAR(m_rareNonInheritedData, textCombine, v); }
     void setTextDecorationColor(const Color& c) { SET_VAR(m_rareNonInheritedData, textDecorationColor, c); }
@@ -1532,6 +1536,7 @@
     static const TransformOperations& initialTransform() { static NeverDestroyed<TransformOperations> ops; return ops; }
     static Length initialTransformOriginX() { return Length(50.0f, Percent); }
     static Length initialTransformOriginY() { return Length(50.0f, Percent); }
+    static TransformBox initialTransformBox() { return TransformBox::BorderBox; }
     static EPointerEvents initialPointerEvents() { return PE_AUTO; }
     static float initialTransformOriginZ() { return 0; }
     static ETransformStyle3D initialTransformStyle3D() { return TransformStyle3DFlat; }

Modified: trunk/Source/WebCore/rendering/style/RenderStyleConstants.h (217235 => 217236)


--- trunk/Source/WebCore/rendering/style/RenderStyleConstants.h	2017-05-22 19:14:14 UTC (rev 217235)
+++ trunk/Source/WebCore/rendering/style/RenderStyleConstants.h	2017-05-22 19:19:24 UTC (rev 217236)
@@ -583,7 +583,13 @@
 enum EBackfaceVisibility {
     BackfaceVisibilityVisible, BackfaceVisibilityHidden
 };
-    
+
+enum class TransformBox {
+    BorderBox,
+    FillBox,
+    ViewBox
+};
+
 enum ELineClampType { LineClampLineCount, LineClampPercentage };
 
 enum Hyphens { HyphensNone, HyphensManual, HyphensAuto };

Modified: trunk/Source/WebCore/rendering/style/StyleTransformData.cpp (217235 => 217236)


--- trunk/Source/WebCore/rendering/style/StyleTransformData.cpp	2017-05-22 19:14:14 UTC (rev 217235)
+++ trunk/Source/WebCore/rendering/style/StyleTransformData.cpp	2017-05-22 19:19:24 UTC (rev 217236)
@@ -31,6 +31,7 @@
     , x(RenderStyle::initialTransformOriginX())
     , y(RenderStyle::initialTransformOriginY())
     , z(RenderStyle::initialTransformOriginZ())
+    , transformBox(RenderStyle::initialTransformBox())
 {
 }
 
@@ -40,6 +41,7 @@
     , x(other.x)
     , y(other.y)
     , z(other.z)
+    , transformBox(other.transformBox)
 {
 }
 
@@ -50,7 +52,7 @@
 
 bool StyleTransformData::operator==(const StyleTransformData& other) const
 {
-    return x == other.x && y == other.y && z == other.z && operations == other.operations;
+    return x == other.x && y == other.y && z == other.z && transformBox == other.transformBox && operations == other.operations;
 }
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/rendering/style/StyleTransformData.h (217235 => 217236)


--- trunk/Source/WebCore/rendering/style/StyleTransformData.h	2017-05-22 19:14:14 UTC (rev 217235)
+++ trunk/Source/WebCore/rendering/style/StyleTransformData.h	2017-05-22 19:19:24 UTC (rev 217236)
@@ -25,6 +25,7 @@
 #pragma once
 
 #include "Length.h"
+#include "RenderStyleConstants.h"
 #include "TransformOperations.h"
 #include <wtf/Ref.h>
 #include <wtf/RefCounted.h>
@@ -48,6 +49,7 @@
     Length x;
     Length y;
     float z;
+    TransformBox transformBox;
 
 private:
     StyleTransformData();

Modified: trunk/Source/WebCore/svg/SVGGraphicsElement.cpp (217235 => 217236)


--- trunk/Source/WebCore/svg/SVGGraphicsElement.cpp	2017-05-22 19:14:14 UTC (rev 217235)
+++ trunk/Source/WebCore/svg/SVGGraphicsElement.cpp	2017-05-22 19:19:24 UTC (rev 217236)
@@ -27,6 +27,7 @@
 #include "SVGNames.h"
 #include "SVGPathData.h"
 #include "SVGRect.h"
+#include "SVGSVGElement.h"
 #include "SVGStringList.h"
 #include <wtf/NeverDestroyed.h>
 
@@ -79,10 +80,26 @@
 
     // If CSS property was set, use that, otherwise fallback to attribute (if set).
     if (style && style->hasTransform()) {
+        
+        FloatRect boundingBox;
+        switch (style->transformBox()) {
+        case TransformBox::FillBox:
+            boundingBox = renderer()->objectBoundingBox();
+            break;
+        case TransformBox::BorderBox:
+            // For SVG elements without an associated CSS layout box, the used value for border-box is view-box.
+        case TransformBox::ViewBox:
+            if (auto *viewportElement = nearestViewportElement()) {
+                if (is<SVGSVGElement>(*viewportElement))
+                    boundingBox = downcast<SVGSVGElement>(*viewportElement).viewBox();
+            }
+            break;
+        }
+        
         // Note: objectBoundingBox is an emptyRect for elements like pattern or clipPath.
         // See the "Object bounding box units" section of http://dev.w3.org/csswg/css3-transforms/
         TransformationMatrix transform;
-        style->applyTransform(transform, renderer()->objectBoundingBox());
+        style->applyTransform(transform, boundingBox);
 
         // Flatten any 3D transform.
         matrix = transform.toAffineTransform();

Modified: trunk/Source/WebInspectorUI/ChangeLog (217235 => 217236)


--- trunk/Source/WebInspectorUI/ChangeLog	2017-05-22 19:14:14 UTC (rev 217235)
+++ trunk/Source/WebInspectorUI/ChangeLog	2017-05-22 19:19:24 UTC (rev 217236)
@@ -1,3 +1,14 @@
+2017-05-22  Simon Fraser  <[email protected]>
+
+        Support transform-box to switch sizing box in SVG
+        https://bugs.webkit.org/show_bug.cgi?id=145783
+
+        Reviewed by Dean Jackson.
+
+        Add transform-box to the list of autocompletions.
+
+        * UserInterface/External/CodeMirror/css.js:
+
 2017-05-22  Brian Burg  <[email protected]>
 
         Web Inspector: RTL: In Timelines > _javascript_ & Events, digits for sample count are not localized

Modified: trunk/Source/WebInspectorUI/UserInterface/External/CodeMirror/css.js (217235 => 217236)


--- trunk/Source/WebInspectorUI/UserInterface/External/CodeMirror/css.js	2017-05-22 19:14:14 UTC (rev 217235)
+++ trunk/Source/WebInspectorUI/UserInterface/External/CodeMirror/css.js	2017-05-22 19:19:24 UTC (rev 217236)
@@ -519,7 +519,7 @@
     "text-emphasis-position", "text-emphasis-style", "text-height",
     "text-indent", "text-justify", "text-outline", "text-overflow", "text-shadow",
     "text-size-adjust", "text-space-collapse", "text-transform", "text-underline-position",
-    "text-wrap", "top", "transform", "transform-origin", "transform-style",
+    "text-wrap", "top", "transform", "transform-box", "transform-origin", "transform-style",
     "transition", "transition-delay", "transition-duration",
     "transition-property", "transition-timing-function", "unicode-bidi",
     "user-select", "vertical-align", "visibility", "voice-balance", "voice-duration",
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to