Specifying a longhand property should not serialize to a shorthand property
authordino@apple.com <dino@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 3 May 2016 02:25:31 +0000 (02:25 +0000)
committerdino@apple.com <dino@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 3 May 2016 02:25:31 +0000 (02:25 +0000)
https://bugs.webkit.org/show_bug.cgi?id=157180

Patch by Antoine Quint <graouts@apple.com> on 2016-05-02
Reviewed by Dean Jackson.

Source/WebCore:

Ensure that we don't serialize to a shorthand property when the required longhand components
are not specified, per http://www.w3.org/TR/cssom-1/#serialize-a-css-declaration-block.

Test: fast/css/no-shorthand-with-incomplete-longhands.html

* css/StyleProperties.cpp:
(WebCore::StyleProperties::getLayeredShorthandValue):
Returning an empty string here means that calling getPropertyValue() with
the shorthand property matching the currently processed longhand property
in asText() will return an empty string as well and the shorthand property
will be disregarded.

LayoutTests:

A fair few tests relied on reading from a shorthand value when it was incorrect
to produce one, so we fix those incorrect assertions. We also add a new test that
goes through all the longhand properties for a given shorthand property and checks
that none of the longhand properties will yield a shorthand value.

* cssom/cssvalue-comparison-expected.txt:
* cssom/cssvalue-comparison.html:
* fast/css/background-position-serialize-expected.txt:
* fast/css/background-position-serialize.html:
* fast/css/no-shorthand-with-incomplete-longhands-expected.txt: Added.
* fast/css/no-shorthand-with-incomplete-longhands.html: Added.
* fast/css/remove-shorthand-expected.txt:
* fast/css/script-tests/image-set-setting.js:
(testComputedStyle):
* fast/css/uri-token-parsing-expected.txt:
* fast/css/uri-token-parsing.html:
* fast/css/webkit-mask-crash-implicit-expected.txt:
* fast/css/webkit-mask-crash-implicit.html:
* fast/dom/Element/setAttributeNode-for-existing-attribute.html:
* fast/dom/background-shorthand-csstext-expected.txt:
* fast/dom/background-shorthand-csstext.html:
* http/tests/security/contentSecurityPolicy/inline-style-allowed-while-cloning-objects-expected.txt:
* http/tests/security/contentSecurityPolicy/inline-style-allowed-while-cloning-objects.html:

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

20 files changed:
LayoutTests/ChangeLog
LayoutTests/cssom/cssvalue-comparison-expected.txt
LayoutTests/cssom/cssvalue-comparison.html
LayoutTests/fast/css/background-position-serialize-expected.txt
LayoutTests/fast/css/background-position-serialize.html
LayoutTests/fast/css/no-shorthand-with-incomplete-longhands-expected.txt [new file with mode: 0644]
LayoutTests/fast/css/no-shorthand-with-incomplete-longhands.html [new file with mode: 0644]
LayoutTests/fast/css/remove-shorthand-expected.txt
LayoutTests/fast/css/script-tests/image-set-setting.js
LayoutTests/fast/css/uri-token-parsing-expected.txt
LayoutTests/fast/css/uri-token-parsing.html
LayoutTests/fast/css/webkit-mask-crash-implicit-expected.txt
LayoutTests/fast/css/webkit-mask-crash-implicit.html
LayoutTests/fast/dom/Element/setAttributeNode-for-existing-attribute.html
LayoutTests/fast/dom/background-shorthand-csstext-expected.txt
LayoutTests/fast/dom/background-shorthand-csstext.html
LayoutTests/http/tests/security/contentSecurityPolicy/inline-style-allowed-while-cloning-objects-expected.txt
LayoutTests/http/tests/security/contentSecurityPolicy/inline-style-allowed-while-cloning-objects.html
Source/WebCore/ChangeLog
Source/WebCore/css/StyleProperties.cpp

index 9b2a741..4370a0d 100644 (file)
@@ -1,3 +1,34 @@
+2016-05-02  Antoine Quint  <graouts@apple.com>
+
+        Specifying a longhand property should not serialize to a shorthand property
+        https://bugs.webkit.org/show_bug.cgi?id=157180
+
+        Reviewed by Dean Jackson.
+
+        A fair few tests relied on reading from a shorthand value when it was incorrect
+        to produce one, so we fix those incorrect assertions. We also add a new test that
+        goes through all the longhand properties for a given shorthand property and checks
+        that none of the longhand properties will yield a shorthand value.
+
+        * cssom/cssvalue-comparison-expected.txt:
+        * cssom/cssvalue-comparison.html:
+        * fast/css/background-position-serialize-expected.txt:
+        * fast/css/background-position-serialize.html:
+        * fast/css/no-shorthand-with-incomplete-longhands-expected.txt: Added.
+        * fast/css/no-shorthand-with-incomplete-longhands.html: Added.
+        * fast/css/remove-shorthand-expected.txt:
+        * fast/css/script-tests/image-set-setting.js:
+        (testComputedStyle):
+        * fast/css/uri-token-parsing-expected.txt:
+        * fast/css/uri-token-parsing.html:
+        * fast/css/webkit-mask-crash-implicit-expected.txt:
+        * fast/css/webkit-mask-crash-implicit.html:
+        * fast/dom/Element/setAttributeNode-for-existing-attribute.html:
+        * fast/dom/background-shorthand-csstext-expected.txt:
+        * fast/dom/background-shorthand-csstext.html:
+        * http/tests/security/contentSecurityPolicy/inline-style-allowed-while-cloning-objects-expected.txt:
+        * http/tests/security/contentSecurityPolicy/inline-style-allowed-while-cloning-objects.html:
+
 2016-05-02  Joseph Pecoraro  <pecoraro@apple.com>
 
         Make console a namespace object (like Math/JSON), allowing functions to be called unbound
index 1b91484..831cf1e 100644 (file)
@@ -20,9 +20,9 @@ PASS Two CSSValues "rotate(1.55rad)" for property "-webkit-transform" are equal.
 PASS Two CSSValues "rotate(200grad)" for property "-webkit-transform" are equal. 
 PASS Two CSSValues "rotate(0.5turn)" for property "-webkit-transform" are equal. 
 PASS Two CSSValues "rotate(15deg)" and "rotate(1.55rad)" for property "-webkit-transform" are not equal. 
-PASS Two CSSValues "url(dummy://test.png)" for property "background" are equal. 
-PASS Two CSSValues "url(dummy://green.png)" for property "background" are equal. 
-PASS Two CSSValues "url(dummy://test.png)" and "url(dummy://green.png)" for property "background" are not equal. 
+PASS Two CSSValues "url(dummy://test.png)" for property "background-image" are equal. 
+PASS Two CSSValues "url(dummy://green.png)" for property "background-image" are equal. 
+PASS Two CSSValues "url(dummy://test.png)" and "url(dummy://green.png)" for property "background-image" are not equal. 
 PASS Two CSSValues "bold" for property "font-weight" are equal. 
 PASS Two CSSValues "inherit" for property "font-weight" are equal. 
 PASS Two CSSValues "bold" and "inherit" for property "font-weight" are not equal. 
@@ -63,13 +63,13 @@ PASS Two CSSValues "url(resources/greenbox.png) 0 0, pointer" and "url(resources
 PASS Two CSSValues "italic bold 12px/30px arial" for property "font" are equal. 
 PASS Two CSSValues "italic bold 8px/16px helvetica" for property "font" are equal. 
 PASS Two CSSValues "italic bold 12px/30px arial" and "italic bold 8px/16px helvetica" for property "font" are not equal. 
-PASS Two CSSValues "-webkit-gradient(linear, left top, left bottom, from(#ccc), to(#000))" for property "background" are equal. 
-PASS Two CSSValues "-webkit-gradient(radial, 45 45, 0, 52 50, 0, from(#A7D30C), to(rgba(1,159,98,0)), color-stop(90%, #019F62))" for property "background" are equal. 
-PASS Two CSSValues "-webkit-gradient(linear, left top, left bottom, from(#ccc), to(#000))" and "-webkit-gradient(radial, 45 45, 0, 52 50, 0, from(#A7D30C), to(rgba(1,159,98,0)), color-stop(90%, #019F62))" for property "background" are not equal. 
-PASS Two CSSValues "radial-gradient(circle, #ccc, #000)" for property "background" are equal. 
-PASS Two CSSValues "linear-gradient(#000, #234)" for property "background" are equal. 
-PASS Two CSSValues "linear-gradient(to top, #000, #234)" for property "background" are equal. 
-PASS Two CSSValues "linear-gradient(#000, #234)" and "linear-gradient(to top, #000, #234)" for property "background" are not equal. 
+PASS Two CSSValues "-webkit-gradient(linear, left top, left bottom, from(#ccc), to(#000))" for property "background-image" are equal. 
+PASS Two CSSValues "-webkit-gradient(radial, 45 45, 0, 52 50, 0, from(#A7D30C), to(rgba(1,159,98,0)), color-stop(90%, #019F62))" for property "background-image" are equal. 
+PASS Two CSSValues "-webkit-gradient(linear, left top, left bottom, from(#ccc), to(#000))" and "-webkit-gradient(radial, 45 45, 0, 52 50, 0, from(#A7D30C), to(rgba(1,159,98,0)), color-stop(90%, #019F62))" for property "background-image" are not equal. 
+PASS Two CSSValues "radial-gradient(circle, #ccc, #000)" for property "background-image" are equal. 
+PASS Two CSSValues "linear-gradient(#000, #234)" for property "background-image" are equal. 
+PASS Two CSSValues "linear-gradient(to top, #000, #234)" for property "background-image" are equal. 
+PASS Two CSSValues "linear-gradient(#000, #234)" and "linear-gradient(to top, #000, #234)" for property "background-image" are not equal. 
 PASS Two CSSValues "-webkit-cross-fade(url(dummy://example.png), url(dummy://example.png), 50%)" for property "background-image" are equal. 
 PASS Two CSSValues "-webkit-cross-fade(url(dummy://background.png), url(dummy://foreground.png), 80%)" for property "background-image" are equal. 
 PASS Two CSSValues "-webkit-cross-fade(url(dummy://example.png), url(dummy://example.png), 50%)" and "-webkit-cross-fade(url(dummy://background.png), url(dummy://foreground.png), 80%)" for property "background-image" are not equal. 
index cbbac86..db26591 100644 (file)
@@ -35,7 +35,7 @@ function run() {
 
    var tests = [ {"width" : ["20%", "2em", "2rem", "20px", "2cm", "20mm", "4in", "20pt", "10pc", "6vw", "6vh", "4vmin", "-webkit-calc(-100px + 100%)"]}, // lengths, calc
                   {"-webkit-transform" : ["rotate(15deg)", "rotate(1.55rad)", "rotate(200grad)", "rotate(0.5turn)"]}, // angle
-                  {"background" : ["url(dummy://test.png)", "url(dummy://green.png)"]}, // uri
+                  {"background-image" : ["url(dummy://test.png)", "url(dummy://green.png)"]}, // uri
                   {"font-weight" : ["bold", "inherit"]}, // ident
                   {"content" : ["counter(a)", "counters(a, '.')"]}, // counter
                   {"content" : ["attr(a)", "attr(p)"]}, // attr
@@ -49,9 +49,9 @@ function run() {
                   {"border-image-slice" : ["1 2 3 4", "2 3 4 5"]}, // border image slice
                   {"cursor" : ["url(resources/greenbox.png) 0 0, pointer", "url(resources/cursor.png) 1 1, wait"]}, // cursor
                   {"font" : ["italic bold 12px/30px arial", "italic bold 8px/16px helvetica"]}, // font
-                  {"background" : ["-webkit-gradient(linear, left top, left bottom, from(#ccc), to(#000))", "-webkit-gradient(radial, 45 45, 0, 52 50, 0, from(#A7D30C), to(rgba(1,159,98,0)), color-stop(90%, #019F62))"]}, // gradients
-                  {"background" : ["radial-gradient(circle, #ccc, #000)"]}, // gradients
-                  {"background" : ["linear-gradient(#000, #234)", "linear-gradient(to top, #000, #234)"]}, // gradients
+                  {"background-image" : ["-webkit-gradient(linear, left top, left bottom, from(#ccc), to(#000))", "-webkit-gradient(radial, 45 45, 0, 52 50, 0, from(#A7D30C), to(rgba(1,159,98,0)), color-stop(90%, #019F62))"]}, // gradients
+                  {"background-image" : ["radial-gradient(circle, #ccc, #000)"]}, // gradients
+                  {"background-image" : ["linear-gradient(#000, #234)", "linear-gradient(to top, #000, #234)"]}, // gradients
                   {"background-image" : ["-webkit-cross-fade(url(dummy://example.png), url(dummy://example.png), 50%)", "-webkit-cross-fade(url(dummy://background.png), url(dummy://foreground.png), 80%)"]}, // crossfade
                   {"-webkit-box-reflect" : ["below 10px", "below 0px -webkit-gradient(linear, left top, left bottom, from(transparent), to(rgba(10, 55, 234, 1)))"]}, // reflect
                   {"-webkit-box-shadow" : ["0 -20px 10px red, 0 20px 10px blue", "0 20px 10px blue", "5px 5px 5px rgba(0, 0, 0, 0.3)"]}, // shadow
index c0fb3be..abac61f 100644 (file)
@@ -1,5 +1,5 @@
 t.style.backgroundPositionX = '5%';
-PASS: t.style.backgroundPosition should be 5% and is.
+PASS: t.style.backgroundPosition should be and is.
 PASS: t.style.backgroundPositionX should be 5% and is.
 PASS: t.style.backgroundPositionY should be and is.
 PASS: t.style.cssText should be background-position-x: 5%; and is.
index fc21eeb..733fa33 100644 (file)
@@ -44,7 +44,7 @@ if (window.testRunner)
 var t = document.getElementById('t');
 
 run("t.style.backgroundPositionX = '5%';");
-shouldBe("t.style.backgroundPosition", "5%");
+shouldBe("t.style.backgroundPosition", "");
 shouldBe("t.style.backgroundPositionX", "5%");
 shouldBe("t.style.backgroundPositionY", "");
 shouldBe("t.style.cssText", "background-position-x: 5%;");
diff --git a/LayoutTests/fast/css/no-shorthand-with-incomplete-longhands-expected.txt b/LayoutTests/fast/css/no-shorthand-with-incomplete-longhands-expected.txt
new file mode 100644 (file)
index 0000000..c9e591e
--- /dev/null
@@ -0,0 +1,19 @@
+Tests that setting a longhand property does not produces a valid shorthand value.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS Setting style="background-image: url(foo.png)" should not return a value for element.style.getPropertyValue("background").
+PASS Setting style="background-position-x: 10px" should not return a value for element.style.getPropertyValue("background").
+PASS Setting style="background-position-y: 10px" should not return a value for element.style.getPropertyValue("background").
+PASS Setting style="background-size: cover" should not return a value for element.style.getPropertyValue("background").
+PASS Setting style="background-repeat-x: no-repeat" should not return a value for element.style.getPropertyValue("background").
+PASS Setting style="background-repeat-y: no-repeat" should not return a value for element.style.getPropertyValue("background").
+PASS Setting style="background-attachment: scroll" should not return a value for element.style.getPropertyValue("background").
+PASS Setting style="background-origin: padding-box" should not return a value for element.style.getPropertyValue("background").
+PASS Setting style="background-clip: padding-box" should not return a value for element.style.getPropertyValue("background").
+PASS Setting style="background-color: green" should not return a value for element.style.getPropertyValue("background").
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/css/no-shorthand-with-incomplete-longhands.html b/LayoutTests/fast/css/no-shorthand-with-incomplete-longhands.html
new file mode 100644 (file)
index 0000000..1180b85
--- /dev/null
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src="../../resources/js-test-pre.js"></script>
+<script>
+
+description("Tests that setting a longhand property does not produces a valid shorthand value.");
+
+var shorthands = { "background": ["background-image: url(foo.png)", "background-position-x: 10px", "background-position-y: 10px", "background-size: cover", "background-repeat-x: no-repeat", "background-repeat-y: no-repeat", "background-attachment: scroll", "background-origin: padding-box", "background-clip: padding-box", "background-color: green"] }
+
+for (var shorthand in shorthands) {
+
+    // Test each longhand in isolation.
+    shorthands[shorthand].forEach(function(styleDeclaration) {
+        var description = `Setting style="${styleDeclaration}" should not return a value for element.style.getPropertyValue("${shorthand}").`;
+        var element = document.createElement("div");
+        element.setAttribute("style", styleDeclaration);
+        if (element.style.getPropertyValue(shorthand) === "")
+            testPassed(description);
+        else
+            testFailed(description);
+    });
+}
+
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
index a5a6478..c1c20ff 100644 (file)
@@ -64,7 +64,7 @@ removes "-webkit-mask"
 and adds "".
 Removing -webkit-mask-position
 removes "-webkit-mask"
-and adds "-webkit-mask".
+and adds "-webkit-mask-image, -webkit-mask-repeat-x, -webkit-mask-repeat-y".
 Removing overflow
 removes "overflow"
 and adds "".
index 734c9ad..1488e25 100644 (file)
@@ -5,7 +5,7 @@ function testComputedStyle(property, fullRule)
     var div = document.createElement("div");
     document.body.appendChild(div);
     div.setAttribute("style", property + ": " + fullRule);
-    var computedValue = div.style.background;
+    var computedValue = div.style.backgroundImage;
     document.body.removeChild(div);
     return computedValue;
 }
index e4c0371..42afbb9 100644 (file)
@@ -21,7 +21,7 @@ Rules from the stylesheet:
 #q { cursor: url('url(q)'); }
 #r { list-style-image: url('url(r)'); }
 #s { background-image: url('url(s)'); }
-#t { -webkit-mask: url('url(t)'); }
+#t { -webkit-mask-image: url('url(t)'); }
 #u { -webkit-border-image: url('url(u)') 1 2 3 4 fill stretch round; }
 #v { -webkit-mask-box-image: url('url(v)') 1 2 3 4 fill stretch round; }
 #w { content: url(ww); }
@@ -46,7 +46,7 @@ Expected result:
 #q { cursor: url('url(q)'); }
 #r { list-style-image: url('url(r)'); }
 #s { background-image: url('url(s)'); }
-#t { -webkit-mask: url('url(t)'); }
+#t { -webkit-mask-image: url('url(t)'); }
 #u { -webkit-border-image: url('url(u)') 1 2 3 4 fill stretch round; }
 #v { -webkit-mask-box-image: url('url(v)') 1 2 3 4 fill stretch round; }
 #w { content: url(ww); }
index 4a141a4..a1d68ff 100644 (file)
@@ -95,7 +95,7 @@ function runTest()
 #q { cursor: url('url(q)'); }
 #r { list-style-image: url('url(r)'); }
 #s { background-image: url('url(s)'); }
-#t { -webkit-mask: url('url(t)'); }
+#t { -webkit-mask-image: url('url(t)'); }
 #u { -webkit-border-image: url('url(u)') 1 2 3 4 fill stretch round; }
 #v { -webkit-mask-box-image: url('url(v)') 1 2 3 4 fill stretch round; }
 #w { content: url(ww); }
index 07f4435..813a9ab 100644 (file)
@@ -1,4 +1,4 @@
-FAIL document.styleSheets[1].rules[0].style.cssText should be -webkit-mask-repeat: repeat-x; -webkit-mask-repeat-y: inherit;. Was -webkit-mask: inherit;.
-FAIL document.styleSheets[1].rules[0].style.getPropertyValue('-webkit-mask') should be . Was inherit.
-FAIL document.styleSheets[1].rules[0].style.getPropertyValue('-webkit-mask-repeat') should be repeat inherit. Was inherit.
+PASS document.styleSheets[1].rules[0].style.cssText is "-webkit-mask-repeat-x: repeat; -webkit-mask-repeat-y: inherit;"
+PASS document.styleSheets[1].rules[0].style.getPropertyValue('-webkit-mask') is ""
+PASS document.styleSheets[1].rules[0].style.getPropertyValue('-webkit-mask-repeat') is "inherit"
 
index 746f81e..f49c01f 100644 (file)
@@ -9,9 +9,9 @@
 <script>
 if (window.internals)
     testRunner.dumpAsText();
-shouldBeEqualToString("document.styleSheets[1].rules[0].style.cssText", "-webkit-mask-repeat: repeat-x; -webkit-mask-repeat-y: inherit;");
+shouldBeEqualToString("document.styleSheets[1].rules[0].style.cssText", "-webkit-mask-repeat-x: repeat; -webkit-mask-repeat-y: inherit;");
 shouldBeEqualToString("document.styleSheets[1].rules[0].style.getPropertyValue('-webkit-mask')", "");
-shouldBeEqualToString("document.styleSheets[1].rules[0].style.getPropertyValue('-webkit-mask-repeat')", "repeat inherit");
+shouldBeEqualToString("document.styleSheets[1].rules[0].style.getPropertyValue('-webkit-mask-repeat')", "inherit");
 </script>
 </head>
 <body>
index 0d8dc8f..c1ee7bb 100644 (file)
@@ -7,12 +7,12 @@ function runTest() {
         testRunner.dumpAsText();
         
     var testElement = document.getElementById('test');
-    var testElementBgColor = testElement.style.background;
+    var testElementBgColor = testElement.style.backgroundColor;
     
     var newAttr = document.createAttribute("STYLE");
     newAttr.value = "background-color: green";
     testElement.setAttributeNode(newAttr);
-    var testElementBgColorAfterReset = testElement.style.background;
+    var testElementBgColorAfterReset = testElement.style.backgroundColor;
     
     document.getElementById('result').innerHTML = "background-color specified with lowercase style attribute was: "+testElementBgColor+" and specified with uppercase style attribute is: "+testElementBgColorAfterReset;
 }
index 31488c1..170862a 100644 (file)
@@ -1,6 +1,6 @@
 This page tests whether or not the background shorthand properly omits initial values.
 
 PASS: document.body.style.background == 'green' should be true and is.
-PASS: document.getElementById('div1').style.background == 'repeat-x, repeat-y white' should be true and is.
+PASS: document.getElementById('div1').style.background == '' should be true and is.
 PASS: document.getElementById('div2').style.background == '50% 50% blue' should be true and is.
 PASS: document.getElementById('div3').style.background == 'none repeat scroll rgb(255, 255, 255)' should be true and is.
index c7e10a2..96be581 100644 (file)
@@ -32,7 +32,7 @@ function test()
         testRunner.dumpAsText();
     
     shouldBe("document.body.style.background == 'green'", true);
-    shouldBe("document.getElementById('div1').style.background == 'repeat-x, repeat-y white'", true);
+    shouldBe("document.getElementById('div1').style.background == ''", true);
     shouldBe("document.getElementById('div2').style.background == '50% 50% blue'", true);
     shouldBe("document.getElementById('div3').style.background == 'none repeat scroll rgb(255, 255, 255)'", true);
 }
index 2f9899b..6222107 100644 (file)
@@ -1,10 +1,10 @@
 CONSOLE MESSAGE: line 1: Refused to apply a stylesheet because its hash, its nonce, or 'unsafe-inline' does not appear in the style-src directive of the Content Security Policy.
 CONSOLE MESSAGE: line 79: Refused to apply a stylesheet because its hash, its nonce, or 'unsafe-inline' does not appear in the style-src directive of the Content Security Policy.
 This test ensures that styles can be set by object.cloneNode()
-PASS node1.style.background is "yellow"
-PASS node2.style.background is "yellow"
-PASS node3.style.background is "blue"
-PASS node4.style.background is "blue"
+PASS node1.style.backgroundColor is "yellow"
+PASS node2.style.backgroundColor is "yellow"
+PASS node3.style.backgroundColor is "blue"
+PASS node4.style.backgroundColor is "blue"
 PASS node1.style.color is "red"
 PASS node2.style.color is "red"
 PASS node3.style.color is "green"
index fe25ebb..75b6f07 100644 (file)
             nodes.appendChild(node3);
             nodes.appendChild(node4);
 
-            shouldBeEqualToString("node1.style.background", "yellow");
-            shouldBeEqualToString("node2.style.background", "yellow");
-            shouldBeEqualToString("node3.style.background", "blue");
-            shouldBeEqualToString("node4.style.background", "blue");
+            shouldBeEqualToString("node1.style.backgroundColor", "yellow");
+            shouldBeEqualToString("node2.style.backgroundColor", "yellow");
+            shouldBeEqualToString("node3.style.backgroundColor", "blue");
+            shouldBeEqualToString("node4.style.backgroundColor", "blue");
   
             shouldBeEqualToString("node1.style.color", "red");
             shouldBeEqualToString("node2.style.color", "red");
index 0b06834..47e21b7 100644 (file)
@@ -1,3 +1,22 @@
+2016-05-02  Antoine Quint  <graouts@apple.com>
+
+        Specifying a longhand property should not serialize to a shorthand property
+        https://bugs.webkit.org/show_bug.cgi?id=157180
+
+        Reviewed by Dean Jackson.
+
+        Ensure that we don't serialize to a shorthand property when the required longhand components
+        are not specified, per http://www.w3.org/TR/cssom-1/#serialize-a-css-declaration-block.
+
+        Test: fast/css/no-shorthand-with-incomplete-longhands.html
+
+        * css/StyleProperties.cpp:
+        (WebCore::StyleProperties::getLayeredShorthandValue):
+        Returning an empty string here means that calling getPropertyValue() with
+        the shorthand property matching the currently processed longhand property
+        in asText() will return an empty string as well and the shorthand property
+        will be disregarded.
+
 2016-05-02  Dean Jackson  <dino@apple.com>
 
         REGRESSION: Page layout of Manga/Picture books and all Fixed Layout ePubs corrupted
index 10bb284..e8bb293 100644 (file)
@@ -382,14 +382,18 @@ String StyleProperties::getLayeredShorthandValue(const StylePropertyShorthand& s
 
     for (unsigned i = 0; i < size; ++i) {
         values[i] = getPropertyCSSValueInternal(shorthand.properties()[i]);
-        if (values[i]) {
-            if (values[i]->isVariableDependentValue())
-                return values[i]->cssText();
-            if (values[i]->isBaseValueList())
-                numLayers = std::max(downcast<CSSValueList>(*values[i]).length(), numLayers);
-            else
-                numLayers = std::max<size_t>(1U, numLayers);
+        if (!values[i]) {
+            // We don't have all longhand properties defined as required for the shorthand
+            // property and thus should not serialize to a shorthand value. See spec at
+            // http://www.w3.org/TR/cssom-1/#serialize-a-css-declaration-block.
+            return String();
         }
+        if (values[i]->isVariableDependentValue())
+            return values[i]->cssText();
+        if (values[i]->isBaseValueList())
+            numLayers = std::max(downcast<CSSValueList>(*values[i]).length(), numLayers);
+        else
+            numLayers = std::max<size_t>(1U, numLayers);
     }
 
     String commonValue;