Title: [189836] trunk
Revision
189836
Author
benja...@webkit.org
Date
2015-09-15 18:31:50 -0700 (Tue, 15 Sep 2015)

Log Message

Style invalidation affecting siblings does not work with inline-style changes
https://bugs.webkit.org/show_bug.cgi?id=149189

Patch by Benjamin Poulain <bpoul...@apple.com> on 2015-09-15
Reviewed by Antti Koivisto.

Source/WebCore:

Style::resolveTree() made the assumption that inline style changes only affect
descendants and should not participate in "StyleRecalcAffectsNextSiblingElementStyle".
That was wrong. If the inline style change through CSSOM, it can cause the creation
of a style attribute, which is observable through "StyleRecalcAffectsNextSiblingElementStyle".

This patch removes the incorrect assumption. Style invalidation is always propagated now.

Tests: fast/css/style-attribute-invalidation-propagates-to-counted-siblings.html
       fast/css/style-attribute-invalidation-propagates-to-direct-siblings.html
       fast/css/style-attribute-invalidation-propagates-to-indirect-siblings.html

* css/PropertySetCSSStyleDeclaration.cpp:
(WebCore::InlineCSSStyleDeclaration::didMutate): Deleted.
* dom/StyledElement.cpp:
(WebCore::StyledElement::inlineStyleChanged):
* dom/StyledElement.h:
(WebCore::StyledElement::invalidateStyleAttribute):
Clean up inline-style invalidation a tiny bit.

* style/StyleResolveTree.cpp:
(WebCore::Style::resolveTree):
Fix the bug.

LayoutTests:

* fast/css/style-attribute-invalidation-propagates-to-counted-siblings-expected.txt: Added.
* fast/css/style-attribute-invalidation-propagates-to-counted-siblings.html: Added.
* fast/css/style-attribute-invalidation-propagates-to-direct-siblings-expected.txt: Added.
* fast/css/style-attribute-invalidation-propagates-to-direct-siblings.html: Added.
* fast/css/style-attribute-invalidation-propagates-to-indirect-siblings-expected.txt: Added.
* fast/css/style-attribute-invalidation-propagates-to-indirect-siblings.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (189835 => 189836)


--- trunk/LayoutTests/ChangeLog	2015-09-16 01:14:29 UTC (rev 189835)
+++ trunk/LayoutTests/ChangeLog	2015-09-16 01:31:50 UTC (rev 189836)
@@ -1,3 +1,17 @@
+2015-09-15  Benjamin Poulain  <bpoul...@apple.com>
+
+        Style invalidation affecting siblings does not work with inline-style changes
+        https://bugs.webkit.org/show_bug.cgi?id=149189
+
+        Reviewed by Antti Koivisto.
+
+        * fast/css/style-attribute-invalidation-propagates-to-counted-siblings-expected.txt: Added.
+        * fast/css/style-attribute-invalidation-propagates-to-counted-siblings.html: Added.
+        * fast/css/style-attribute-invalidation-propagates-to-direct-siblings-expected.txt: Added.
+        * fast/css/style-attribute-invalidation-propagates-to-direct-siblings.html: Added.
+        * fast/css/style-attribute-invalidation-propagates-to-indirect-siblings-expected.txt: Added.
+        * fast/css/style-attribute-invalidation-propagates-to-indirect-siblings.html: Added.
+
 2015-09-15  Myles C. Maxfield  <mmaxfi...@apple.com>
 
         Nested isolates can cause an infinite loop when laying out bidi runs

Added: trunk/LayoutTests/fast/css/style-attribute-invalidation-propagates-to-counted-siblings-expected.txt (0 => 189836)


--- trunk/LayoutTests/fast/css/style-attribute-invalidation-propagates-to-counted-siblings-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/css/style-attribute-invalidation-propagates-to-counted-siblings-expected.txt	2015-09-16 01:31:50 UTC (rev 189836)
@@ -0,0 +1,19 @@
+Test that style invalidation through inline-style propagates correctly to siblings when a combinator requires it.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS getComputedStyle(document.querySelectorAll("target")[0]).color is "rgb(0, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("target")[1]).color is "rgb(0, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("target")[0]).color is "rgb(255, 192, 203)"
+PASS getComputedStyle(document.querySelectorAll("target")[1]).color is "rgb(255, 192, 203)"
+PASS getComputedStyle(document.querySelectorAll("target")[0]).color is "rgb(0, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("target")[1]).color is "rgb(0, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("target")[0]).color is "rgb(255, 192, 203)"
+PASS getComputedStyle(document.querySelectorAll("target")[1]).color is "rgb(255, 192, 203)"
+PASS getComputedStyle(document.querySelectorAll("target")[0]).color is "rgb(255, 192, 203)"
+PASS getComputedStyle(document.querySelectorAll("target")[1]).color is "rgb(255, 192, 203)"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/css/style-attribute-invalidation-propagates-to-counted-siblings.html (0 => 189836)


--- trunk/LayoutTests/fast/css/style-attribute-invalidation-propagates-to-counted-siblings.html	                        (rev 0)
+++ trunk/LayoutTests/fast/css/style-attribute-invalidation-propagates-to-counted-siblings.html	2015-09-16 01:31:50 UTC (rev 189836)
@@ -0,0 +1,91 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<style>
+target {
+    color: black;
+}
+target:nth-child(2 of target, trigger[style]) {
+    color: pink;
+}
+</style>
+</head>
+<body>
+    <div>
+        <!-- With renderer -->
+        <trigger></trigger>
+        <padding></padding>
+        <padding></padding>
+        <padding></padding>
+        <padding></padding>
+        <padding></padding>
+        <target></target>
+    </div>
+    <div style="display:none;">
+        <!-- Without renderer -->
+        <trigger></trigger>
+        <padding></padding>
+        <padding></padding>
+        <padding></padding>
+        <padding></padding>
+        <padding></padding>
+        <target></target>
+    </div>
+</body>
+<script>
+
+description('Test that style invalidation through inline-style propagates correctly to siblings when a combinator requires it.');
+
+function testTargetColor(expectedColor) {
+    let allTargets = document.querySelectorAll("target");
+    for (let i = 0; i < allTargets.length; ++i) {
+        shouldBeEqualToString('getComputedStyle(document.querySelectorAll("target")[' + i + ']).color', expectedColor);
+    }
+}
+
+testTargetColor('rgb(0, 0, 0)');
+
+// Set a style through CSS OM.
+function setPropertyWithCSSOM() {
+    let allTriggers = document.querySelectorAll("trigger");
+    for (let i = 0; i < allTriggers.length; ++i) {
+        allTriggers[i].style.cursor = "auto";
+    }
+}
+setPropertyWithCSSOM()
+testTargetColor('rgb(255, 192, 203)');
+
+// If we remove the attribute, we should be back to normal.
+function removeStyleAttribute() {
+    let allTriggers = document.querySelectorAll("trigger");
+    for (let i = 0; i < allTriggers.length; ++i) {
+        allTriggers[i].removeAttribute("style");
+    }
+}
+removeStyleAttribute();
+testTargetColor('rgb(0, 0, 0)');
+
+// Setting the style through a style attribute directly.
+function setStyleAttribute() {
+    let allTriggers = document.querySelectorAll("trigger");
+    for (let i = 0; i < allTriggers.length; ++i) {
+        allTriggers[i].setAttribute("style", "alt: \"WebKit!\"");
+    }
+}
+setStyleAttribute();
+testTargetColor('rgb(255, 192, 203)');
+
+// Removing the property on the style attribute through CSSOM.
+// This leaves an empty style attribute.
+function removePropertyWithCSSOM() {
+    let allTriggers = document.querySelectorAll("trigger");
+    for (let i = 0; i < allTriggers.length; ++i) {
+        allTriggers[i].style.removeProperty("alt");
+    }
+}
+removePropertyWithCSSOM()
+testTargetColor('rgb(255, 192, 203)');
+</script>
+<script src=""
+</html>

Added: trunk/LayoutTests/fast/css/style-attribute-invalidation-propagates-to-direct-siblings-expected.txt (0 => 189836)


--- trunk/LayoutTests/fast/css/style-attribute-invalidation-propagates-to-direct-siblings-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/css/style-attribute-invalidation-propagates-to-direct-siblings-expected.txt	2015-09-16 01:31:50 UTC (rev 189836)
@@ -0,0 +1,19 @@
+Test that style invalidation through inline-style propagates correctly to siblings when a combinator requires it.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS getComputedStyle(document.querySelectorAll("target")[0]).color is "rgb(0, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("target")[1]).color is "rgb(0, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("target")[0]).color is "rgb(255, 192, 203)"
+PASS getComputedStyle(document.querySelectorAll("target")[1]).color is "rgb(255, 192, 203)"
+PASS getComputedStyle(document.querySelectorAll("target")[0]).color is "rgb(0, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("target")[1]).color is "rgb(0, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("target")[0]).color is "rgb(255, 192, 203)"
+PASS getComputedStyle(document.querySelectorAll("target")[1]).color is "rgb(255, 192, 203)"
+PASS getComputedStyle(document.querySelectorAll("target")[0]).color is "rgb(255, 192, 203)"
+PASS getComputedStyle(document.querySelectorAll("target")[1]).color is "rgb(255, 192, 203)"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/css/style-attribute-invalidation-propagates-to-direct-siblings.html (0 => 189836)


--- trunk/LayoutTests/fast/css/style-attribute-invalidation-propagates-to-direct-siblings.html	                        (rev 0)
+++ trunk/LayoutTests/fast/css/style-attribute-invalidation-propagates-to-direct-siblings.html	2015-09-16 01:31:50 UTC (rev 189836)
@@ -0,0 +1,81 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<style>
+target {
+    color: black;
+}
+trigger[style] + target {
+    color: pink;
+}
+</style>
+</head>
+<body>
+    <div>
+        <!-- With renderer -->
+        <trigger></trigger>
+        <target></target>
+    </div>
+    <div style="display:none;">
+        <!-- Without renderer -->
+        <trigger></trigger>
+        <target></target>
+    </div>
+</body>
+<script>
+
+description('Test that style invalidation through inline-style propagates correctly to siblings when a combinator requires it.');
+
+function testTargetColor(expectedColor) {
+    let allTargets = document.querySelectorAll("target");
+    for (let i = 0; i < allTargets.length; ++i) {
+        shouldBeEqualToString('getComputedStyle(document.querySelectorAll("target")[' + i + ']).color', expectedColor);
+    }
+}
+
+testTargetColor('rgb(0, 0, 0)');
+
+// Set a style through CSS OM.
+function setPropertyWithCSSOM() {
+    let allTriggers = document.querySelectorAll("trigger");
+    for (let i = 0; i < allTriggers.length; ++i) {
+        allTriggers[i].style.cursor = "auto";
+    }
+}
+setPropertyWithCSSOM()
+testTargetColor('rgb(255, 192, 203)');
+
+// If we remove the attribute, we should be back to normal.
+function removeStyleAttribute() {
+    let allTriggers = document.querySelectorAll("trigger");
+    for (let i = 0; i < allTriggers.length; ++i) {
+        allTriggers[i].removeAttribute("style");
+    }
+}
+removeStyleAttribute();
+testTargetColor('rgb(0, 0, 0)');
+
+// Setting the style through a style attribute directly.
+function setStyleAttribute() {
+    let allTriggers = document.querySelectorAll("trigger");
+    for (let i = 0; i < allTriggers.length; ++i) {
+        allTriggers[i].setAttribute("style", "alt: \"WebKit!\"");
+    }
+}
+setStyleAttribute();
+testTargetColor('rgb(255, 192, 203)');
+
+// Removing the property on the style attribute through CSSOM.
+// This leaves an empty style attribute.
+function removePropertyWithCSSOM() {
+    let allTriggers = document.querySelectorAll("trigger");
+    for (let i = 0; i < allTriggers.length; ++i) {
+        allTriggers[i].style.removeProperty("alt");
+    }
+}
+removePropertyWithCSSOM()
+testTargetColor('rgb(255, 192, 203)');
+</script>
+<script src=""
+</html>

Added: trunk/LayoutTests/fast/css/style-attribute-invalidation-propagates-to-indirect-siblings-expected.txt (0 => 189836)


--- trunk/LayoutTests/fast/css/style-attribute-invalidation-propagates-to-indirect-siblings-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/css/style-attribute-invalidation-propagates-to-indirect-siblings-expected.txt	2015-09-16 01:31:50 UTC (rev 189836)
@@ -0,0 +1,19 @@
+Test that style invalidation through inline-style propagates correctly to siblings when a combinator requires it.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS getComputedStyle(document.querySelectorAll("target")[0]).color is "rgb(0, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("target")[1]).color is "rgb(0, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("target")[0]).color is "rgb(255, 192, 203)"
+PASS getComputedStyle(document.querySelectorAll("target")[1]).color is "rgb(255, 192, 203)"
+PASS getComputedStyle(document.querySelectorAll("target")[0]).color is "rgb(0, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("target")[1]).color is "rgb(0, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("target")[0]).color is "rgb(255, 192, 203)"
+PASS getComputedStyle(document.querySelectorAll("target")[1]).color is "rgb(255, 192, 203)"
+PASS getComputedStyle(document.querySelectorAll("target")[0]).color is "rgb(255, 192, 203)"
+PASS getComputedStyle(document.querySelectorAll("target")[1]).color is "rgb(255, 192, 203)"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/css/style-attribute-invalidation-propagates-to-indirect-siblings.html (0 => 189836)


--- trunk/LayoutTests/fast/css/style-attribute-invalidation-propagates-to-indirect-siblings.html	                        (rev 0)
+++ trunk/LayoutTests/fast/css/style-attribute-invalidation-propagates-to-indirect-siblings.html	2015-09-16 01:31:50 UTC (rev 189836)
@@ -0,0 +1,91 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<style>
+target {
+    color: black;
+}
+trigger[style] ~ target {
+    color: pink;
+}
+</style>
+</head>
+<body>
+    <div>
+        <!-- With renderer -->
+        <trigger></trigger>
+        <padding></padding>
+        <padding></padding>
+        <padding></padding>
+        <padding></padding>
+        <padding></padding>
+        <target></target>
+    </div>
+    <div style="display:none;">
+        <!-- Without renderer -->
+        <trigger></trigger>
+        <padding></padding>
+        <padding></padding>
+        <padding></padding>
+        <padding></padding>
+        <padding></padding>
+        <target></target>
+    </div>
+</body>
+<script>
+
+description('Test that style invalidation through inline-style propagates correctly to siblings when a combinator requires it.');
+
+function testTargetColor(expectedColor) {
+    let allTargets = document.querySelectorAll("target");
+    for (let i = 0; i < allTargets.length; ++i) {
+        shouldBeEqualToString('getComputedStyle(document.querySelectorAll("target")[' + i + ']).color', expectedColor);
+    }
+}
+
+testTargetColor('rgb(0, 0, 0)');
+
+// Set a style through CSS OM.
+function setPropertyWithCSSOM() {
+    let allTriggers = document.querySelectorAll("trigger");
+    for (let i = 0; i < allTriggers.length; ++i) {
+        allTriggers[i].style.cursor = "auto";
+    }
+}
+setPropertyWithCSSOM()
+testTargetColor('rgb(255, 192, 203)');
+
+// If we remove the attribute, we should be back to normal.
+function removeStyleAttribute() {
+    let allTriggers = document.querySelectorAll("trigger");
+    for (let i = 0; i < allTriggers.length; ++i) {
+        allTriggers[i].removeAttribute("style");
+    }
+}
+removeStyleAttribute();
+testTargetColor('rgb(0, 0, 0)');
+
+// Setting the style through a style attribute directly.
+function setStyleAttribute() {
+    let allTriggers = document.querySelectorAll("trigger");
+    for (let i = 0; i < allTriggers.length; ++i) {
+        allTriggers[i].setAttribute("style", "alt: \"WebKit!\"");
+    }
+}
+setStyleAttribute();
+testTargetColor('rgb(255, 192, 203)');
+
+// Removing the property on the style attribute through CSSOM.
+// This leaves an empty style attribute.
+function removePropertyWithCSSOM() {
+    let allTriggers = document.querySelectorAll("trigger");
+    for (let i = 0; i < allTriggers.length; ++i) {
+        allTriggers[i].style.removeProperty("alt");
+    }
+}
+removePropertyWithCSSOM()
+testTargetColor('rgb(255, 192, 203)');
+</script>
+<script src=""
+</html>

Modified: trunk/Source/WebCore/ChangeLog (189835 => 189836)


--- trunk/Source/WebCore/ChangeLog	2015-09-16 01:14:29 UTC (rev 189835)
+++ trunk/Source/WebCore/ChangeLog	2015-09-16 01:31:50 UTC (rev 189836)
@@ -1,3 +1,33 @@
+2015-09-15  Benjamin Poulain  <bpoul...@apple.com>
+
+        Style invalidation affecting siblings does not work with inline-style changes
+        https://bugs.webkit.org/show_bug.cgi?id=149189
+
+        Reviewed by Antti Koivisto.
+
+        Style::resolveTree() made the assumption that inline style changes only affect
+        descendants and should not participate in "StyleRecalcAffectsNextSiblingElementStyle".
+        That was wrong. If the inline style change through CSSOM, it can cause the creation
+        of a style attribute, which is observable through "StyleRecalcAffectsNextSiblingElementStyle".
+
+        This patch removes the incorrect assumption. Style invalidation is always propagated now.
+
+        Tests: fast/css/style-attribute-invalidation-propagates-to-counted-siblings.html
+               fast/css/style-attribute-invalidation-propagates-to-direct-siblings.html
+               fast/css/style-attribute-invalidation-propagates-to-indirect-siblings.html
+
+        * css/PropertySetCSSStyleDeclaration.cpp:
+        (WebCore::InlineCSSStyleDeclaration::didMutate): Deleted.
+        * dom/StyledElement.cpp:
+        (WebCore::StyledElement::inlineStyleChanged):
+        * dom/StyledElement.h:
+        (WebCore::StyledElement::invalidateStyleAttribute):
+        Clean up inline-style invalidation a tiny bit.
+
+        * style/StyleResolveTree.cpp:
+        (WebCore::Style::resolveTree):
+        Fix the bug.
+
 2015-09-15  Joseph Pecoraro  <pecor...@apple.com>
 
         Web Inspector: Paused Debugger prevents page reload

Modified: trunk/Source/WebCore/css/PropertySetCSSStyleDeclaration.cpp (189835 => 189836)


--- trunk/Source/WebCore/css/PropertySetCSSStyleDeclaration.cpp	2015-09-16 01:14:29 UTC (rev 189835)
+++ trunk/Source/WebCore/css/PropertySetCSSStyleDeclaration.cpp	2015-09-16 01:31:50 UTC (rev 189836)
@@ -365,7 +365,6 @@
     if (!m_parentElement)
         return;
 
-    m_parentElement->setNeedsStyleRecalc(InlineStyleChange);
     m_parentElement->invalidateStyleAttribute();
     StyleAttributeMutationScope(this).didInvalidateStyleAttr();
 }

Modified: trunk/Source/WebCore/dom/StyledElement.cpp (189835 => 189836)


--- trunk/Source/WebCore/dom/StyledElement.cpp	2015-09-16 01:14:29 UTC (rev 189835)
+++ trunk/Source/WebCore/dom/StyledElement.cpp	2015-09-16 01:31:50 UTC (rev 189836)
@@ -214,9 +214,7 @@
 
 void StyledElement::inlineStyleChanged()
 {
-    setNeedsStyleRecalc(InlineStyleChange);
-    ASSERT(elementData());
-    elementData()->setStyleAttributeIsDirty(true);
+    invalidateStyleAttribute();
     InspectorInstrumentation::didInvalidateStyleAttr(document(), *this);
 }
     

Modified: trunk/Source/WebCore/dom/StyledElement.h (189835 => 189836)


--- trunk/Source/WebCore/dom/StyledElement.h	2015-09-16 01:14:29 UTC (rev 189835)
+++ trunk/Source/WebCore/dom/StyledElement.h	2015-09-16 01:31:50 UTC (rev 189836)
@@ -97,6 +97,7 @@
 {
     ASSERT(elementData());
     elementData()->setStyleAttributeIsDirty(true);
+    setNeedsStyleRecalc(InlineStyleChange);
 }
 
 inline const StyleProperties* StyledElement::presentationAttributeStyle()

Modified: trunk/Source/WebCore/style/StyleResolveTree.cpp (189835 => 189836)


--- trunk/Source/WebCore/style/StyleResolveTree.cpp	2015-09-16 01:14:29 UTC (rev 189835)
+++ trunk/Source/WebCore/style/StyleResolveTree.cpp	2015-09-16 01:31:50 UTC (rev 189836)
@@ -820,7 +820,7 @@
                 if (childElement.styleIsAffectedByPreviousSibling())
                     childElement.setNeedsStyleRecalc();
                 elementNeedingStyleRecalcAffectsNextSiblingElementStyle = childElement.affectsNextSiblingElementStyle();
-            } else if (childElement.styleChangeType() >= FullStyleChange)
+            } else if (childElement.needsStyleRecalc())
                 elementNeedingStyleRecalcAffectsNextSiblingElementStyle = childElement.affectsNextSiblingElementStyle();
             if (change >= Inherit || childElement.childNeedsStyleRecalc() || childElement.needsStyleRecalc()) {
                 parentPusher.push();
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to