Title: [87319] trunk
Revision
87319
Author
[email protected]
Date
2011-05-25 14:29:32 -0700 (Wed, 25 May 2011)

Log Message

2011-05-25  Kulanthaivel Palanichamy  <[email protected]>

        Reviewed by David Hyatt.

        Selector matching doesn't update when DOM changes ("[data-a=x] #x")
        https://bugs.webkit.org/show_bug.cgi?id=60752

        Added test cases for all the attribute selector types (CSS2.1 & CSS3).

        * fast/css/attribute-selector-begin-dynamic-no-elementstyle-expected.txt: Added.
        * fast/css/attribute-selector-begin-dynamic-no-elementstyle.html: Added.
        * fast/css/attribute-selector-contain-dynamic-no-elementstyle-expected.txt: Added.
        * fast/css/attribute-selector-contain-dynamic-no-elementstyle.html: Added.
        * fast/css/attribute-selector-end-dynamic-no-elementstyle-expected.txt: Added.
        * fast/css/attribute-selector-end-dynamic-no-elementstyle.html: Added.
        * fast/css/attribute-selector-exact-dynamic-no-elementstyle-expected.txt: Added.
        * fast/css/attribute-selector-exact-dynamic-no-elementstyle.html: Added.
        * fast/css/attribute-selector-hyphen-dynamic-no-elementstyle-expected.txt: Added.
        * fast/css/attribute-selector-hyphen-dynamic-no-elementstyle.html: Added.
        * fast/css/attribute-selector-list-dynamic-no-elementstyle-expected.txt: Added.
        * fast/css/attribute-selector-list-dynamic-no-elementstyle.html: Added.
        * fast/css/attribute-selector-set-dynamic-no-elementstyle-expected.txt: Added.
        * fast/css/attribute-selector-set-dynamic-no-elementstyle.html: Added.
2011-05-25  Kulanthaivel Palanichamy  <[email protected]>

        Reviewed by David Hyatt.

        Selector matching doesn't update when DOM changes ("[data-a=x] #x")
        https://bugs.webkit.org/show_bug.cgi?id=60752

        Currently CSSStyleSelector maintains a HashSet of attributes (m_selectorAttrs)
        which are used in CSS attribute selectors to determine the need for style
        recalculation whenever element attributes are manipulated in DOM.
        In certain conditions (element with no style, element is styled and attribute
        is not a mapped attribute, attribute is of type 'type' or read-only)
        even when attribute selector matches for an element, the attribute is not
        added to m_selectorAttrs. This results in missing style recalculations
        when a DOM element attribute is changed and is not found in m_selectorAttrs.

        Removing the above said conditions in
        CSSStyleSelector::SelectorChecker::checkOneSelector() for registering
        attributes in m_selectorAttrs will solve this issue. But this particular
        function is called numerous times which triggers adding duplicate attributes
        again and again.

        This patch follows the approach taken for collecting ids in selectors, where
        all the attributes in selectors are added to a HashSet at the time of adding
        style rules to CSSStyleSelector from StyleSheets and when
        CSSStyleSelector::hasSelectorForAttribute() is called, the attribute is
        simply looked up in this pre-populated hash set.

        Test: fast/css/attribute-selector-dynamic-no-elementstyle.html

        * css/CSSStyleSelector.cpp:
        (WebCore::CSSStyleSelector::SelectorChecker::checkSelector):
        (WebCore::CSSStyleSelector::checkSelector):
        (WebCore::CSSStyleSelector::SelectorChecker::checkOneSelector):
        (WebCore::collectFeaturesFromSelector):
        (WebCore::CSSStyleSelector::applyProperty):
        (WebCore::CSSStyleSelector::hasSelectorForAttribute):
        * css/CSSStyleSelector.h:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (87318 => 87319)


--- trunk/LayoutTests/ChangeLog	2011-05-25 21:23:05 UTC (rev 87318)
+++ trunk/LayoutTests/ChangeLog	2011-05-25 21:29:32 UTC (rev 87319)
@@ -1,3 +1,27 @@
+2011-05-25  Kulanthaivel Palanichamy  <[email protected]>
+
+        Reviewed by David Hyatt.
+
+        Selector matching doesn't update when DOM changes ("[data-a=x] #x")
+        https://bugs.webkit.org/show_bug.cgi?id=60752
+        
+        Added test cases for all the attribute selector types (CSS2.1 & CSS3).
+
+        * fast/css/attribute-selector-begin-dynamic-no-elementstyle-expected.txt: Added.
+        * fast/css/attribute-selector-begin-dynamic-no-elementstyle.html: Added.
+        * fast/css/attribute-selector-contain-dynamic-no-elementstyle-expected.txt: Added.
+        * fast/css/attribute-selector-contain-dynamic-no-elementstyle.html: Added.
+        * fast/css/attribute-selector-end-dynamic-no-elementstyle-expected.txt: Added.
+        * fast/css/attribute-selector-end-dynamic-no-elementstyle.html: Added.
+        * fast/css/attribute-selector-exact-dynamic-no-elementstyle-expected.txt: Added.
+        * fast/css/attribute-selector-exact-dynamic-no-elementstyle.html: Added.
+        * fast/css/attribute-selector-hyphen-dynamic-no-elementstyle-expected.txt: Added.
+        * fast/css/attribute-selector-hyphen-dynamic-no-elementstyle.html: Added.
+        * fast/css/attribute-selector-list-dynamic-no-elementstyle-expected.txt: Added.
+        * fast/css/attribute-selector-list-dynamic-no-elementstyle.html: Added.
+        * fast/css/attribute-selector-set-dynamic-no-elementstyle-expected.txt: Added.
+        * fast/css/attribute-selector-set-dynamic-no-elementstyle.html: Added.
+
 2011-05-25  Adam Klein  <[email protected]>
 
         Unreviewed. Update chromium expectations after r87307.

Added: trunk/LayoutTests/fast/css/attribute-selector-begin-dynamic-no-elementstyle-expected.txt (0 => 87319)


--- trunk/LayoutTests/fast/css/attribute-selector-begin-dynamic-no-elementstyle-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/css/attribute-selector-begin-dynamic-no-elementstyle-expected.txt	2011-05-25 21:29:32 UTC (rev 87319)
@@ -0,0 +1,5 @@
+Test for bug https://bugs.webkit.org/show_bug.cgi?id=60752
+
+This test checks whether CSS attribute selector [att^=val] is re-evaluated after attribute changes in DOM elements which have no style associated with them.
+
+PASSED

Added: trunk/LayoutTests/fast/css/attribute-selector-begin-dynamic-no-elementstyle.html (0 => 87319)


--- trunk/LayoutTests/fast/css/attribute-selector-begin-dynamic-no-elementstyle.html	                        (rev 0)
+++ trunk/LayoutTests/fast/css/attribute-selector-begin-dynamic-no-elementstyle.html	2011-05-25 21:29:32 UTC (rev 87319)
@@ -0,0 +1,37 @@
+<!doctype html>
+<html>
+<head>
+    <style>
+        span { display: none }
+        *[test^="0"] #sp { color: green; display: block}
+    </style>
+</head>
+<body _onload_="startTest();">
+    <div test="1">
+    <p>
+    Test for bug <a href=""
+    </p>
+    <p>This test checks whether CSS attribute selector [att^=val] is re-evaluated after attribute changes in DOM elements which have no style associated with them.</p>
+    <span id="sp">PASSED</span>
+    </div>
+
+    <script>
+        function change() {
+            var element = document.getElementsByTagName('div')[0];
+            element.attributes.test.value = '0XYZ';
+            if (window.layoutTestController) {
+                layoutTestController.notifyDone();
+            }
+        }
+        function startTest() {
+            if (window.layoutTestController) {
+                layoutTestController.dumpAsText();
+                layoutTestController.waitUntilDone();
+            }
+            // Trigger an attribute change after all load processing is done. Doing the change
+            // here immediately does not exhibit the problem.
+            setTimeout("change();", 0);
+        }
+    </script>
+</body>
+</html>

Added: trunk/LayoutTests/fast/css/attribute-selector-contain-dynamic-no-elementstyle-expected.txt (0 => 87319)


--- trunk/LayoutTests/fast/css/attribute-selector-contain-dynamic-no-elementstyle-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/css/attribute-selector-contain-dynamic-no-elementstyle-expected.txt	2011-05-25 21:29:32 UTC (rev 87319)
@@ -0,0 +1,5 @@
+Test for bug https://bugs.webkit.org/show_bug.cgi?id=60752
+
+This test checks whether CSS attribute selector [att*=val] is re-evaluated after attribute changes in DOM elements which have no style associated with them.
+
+PASSED

Added: trunk/LayoutTests/fast/css/attribute-selector-contain-dynamic-no-elementstyle.html (0 => 87319)


--- trunk/LayoutTests/fast/css/attribute-selector-contain-dynamic-no-elementstyle.html	                        (rev 0)
+++ trunk/LayoutTests/fast/css/attribute-selector-contain-dynamic-no-elementstyle.html	2011-05-25 21:29:32 UTC (rev 87319)
@@ -0,0 +1,37 @@
+<!doctype html>
+<html>
+<head>
+    <style>
+        span { display: none }
+        *[test*="0"] #sp { color: green; display: block}
+    </style>
+</head>
+<body _onload_="startTest();">
+    <div test="1">
+    <p>
+    Test for bug <a href=""
+    </p>
+    <p>This test checks whether CSS attribute selector [att*=val] is re-evaluated after attribute changes in DOM elements which have no style associated with them.</p>
+    <span id="sp">PASSED</span>
+    </div>
+
+    <script>
+        function change() {
+            var element = document.getElementsByTagName('div')[0];
+            element.attributes.test.value = "updated0value";
+            if (window.layoutTestController) {
+                layoutTestController.notifyDone();
+            }
+        }
+        function startTest() {
+            if (window.layoutTestController) {
+                layoutTestController.dumpAsText();
+                layoutTestController.waitUntilDone();
+            }
+            // Trigger an attribute change after all load processing is done. Doing the change
+            // here immediately does not exhibit the problem.
+            setTimeout("change();", 0);
+        }
+    </script>
+</body>
+</html>

Added: trunk/LayoutTests/fast/css/attribute-selector-end-dynamic-no-elementstyle-expected.txt (0 => 87319)


--- trunk/LayoutTests/fast/css/attribute-selector-end-dynamic-no-elementstyle-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/css/attribute-selector-end-dynamic-no-elementstyle-expected.txt	2011-05-25 21:29:32 UTC (rev 87319)
@@ -0,0 +1,5 @@
+Test for bug https://bugs.webkit.org/show_bug.cgi?id=60752
+
+This test checks whether CSS attribute selector [att$=val] is re-evaluated after attribute changes in DOM elements which have no style associated with them.
+
+PASSED

Added: trunk/LayoutTests/fast/css/attribute-selector-end-dynamic-no-elementstyle.html (0 => 87319)


--- trunk/LayoutTests/fast/css/attribute-selector-end-dynamic-no-elementstyle.html	                        (rev 0)
+++ trunk/LayoutTests/fast/css/attribute-selector-end-dynamic-no-elementstyle.html	2011-05-25 21:29:32 UTC (rev 87319)
@@ -0,0 +1,37 @@
+<!doctype html>
+<html>
+<head>
+    <style>
+        span { display: none }
+        *[test$="0"] #sp { color: green; display: block}
+    </style>
+</head>
+<body _onload_="startTest();">
+    <div test="1">
+    <p>
+    Test for bug <a href=""
+    </p>
+    <p>This test checks whether CSS attribute selector [att$=val] is re-evaluated after attribute changes in DOM elements which have no style associated with them.</p>
+    <span id="sp">PASSED</span>
+    </div>
+
+    <script>
+        function change() {
+            var element = document.getElementsByTagName('div')[0];
+            element.attributes.test.value = "updated0";
+            if (window.layoutTestController) {
+                layoutTestController.notifyDone();
+            }
+        }
+        function startTest() {
+            if (window.layoutTestController) {
+                layoutTestController.dumpAsText();
+                layoutTestController.waitUntilDone();
+            }
+            // Trigger an attribute change after all load processing is done. Doing the change
+            // here immediately does not exhibit the problem.
+            setTimeout("change();", 0);
+        }
+    </script>
+</body>
+</html>

Added: trunk/LayoutTests/fast/css/attribute-selector-exact-dynamic-no-elementstyle-expected.txt (0 => 87319)


--- trunk/LayoutTests/fast/css/attribute-selector-exact-dynamic-no-elementstyle-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/css/attribute-selector-exact-dynamic-no-elementstyle-expected.txt	2011-05-25 21:29:32 UTC (rev 87319)
@@ -0,0 +1,5 @@
+Test for bug https://bugs.webkit.org/show_bug.cgi?id=60752
+
+This test checks whether CSS attribute selector [att=val] is re-evaluated after attribute changes in DOM elements which have no style associated with them.
+
+PASSED

Added: trunk/LayoutTests/fast/css/attribute-selector-exact-dynamic-no-elementstyle.html (0 => 87319)


--- trunk/LayoutTests/fast/css/attribute-selector-exact-dynamic-no-elementstyle.html	                        (rev 0)
+++ trunk/LayoutTests/fast/css/attribute-selector-exact-dynamic-no-elementstyle.html	2011-05-25 21:29:32 UTC (rev 87319)
@@ -0,0 +1,37 @@
+<!doctype html>
+<html>
+<head>
+    <style>
+        span { display: none }
+        *[test="0"] #sp { color: green; display: block}
+    </style>
+</head>
+<body _onload_="startTest();">
+    <div test="1">
+    <p>
+    Test for bug <a href=""
+    </p>
+    <p>This test checks whether CSS attribute selector [att=val] is re-evaluated after attribute changes in DOM elements which have no style associated with them.</p>
+    <span id="sp">PASSED</span>
+    </div>
+
+    <script>
+        function change() {
+            var element = document.getElementsByTagName('div')[0];
+            element.attributes.test.value = 0;
+            if (window.layoutTestController) {
+                layoutTestController.notifyDone();
+            }
+        }
+        function startTest() {
+            if (window.layoutTestController) {
+                layoutTestController.dumpAsText();
+                layoutTestController.waitUntilDone();
+            }
+            // Trigger an attribute change after all load processing is done. Doing the change
+            // here immediately does not exhibit the problem.
+            setTimeout("change();", 0);
+        }
+    </script>
+</body>
+</html>

Added: trunk/LayoutTests/fast/css/attribute-selector-hyphen-dynamic-no-elementstyle-expected.txt (0 => 87319)


--- trunk/LayoutTests/fast/css/attribute-selector-hyphen-dynamic-no-elementstyle-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/css/attribute-selector-hyphen-dynamic-no-elementstyle-expected.txt	2011-05-25 21:29:32 UTC (rev 87319)
@@ -0,0 +1,5 @@
+Test for bug https://bugs.webkit.org/show_bug.cgi?id=60752
+
+This test checks whether CSS attribute selector [att|=val] is re-evaluated after attribute changes in DOM elements which have no style associated with them.
+
+PASSED

Added: trunk/LayoutTests/fast/css/attribute-selector-hyphen-dynamic-no-elementstyle.html (0 => 87319)


--- trunk/LayoutTests/fast/css/attribute-selector-hyphen-dynamic-no-elementstyle.html	                        (rev 0)
+++ trunk/LayoutTests/fast/css/attribute-selector-hyphen-dynamic-no-elementstyle.html	2011-05-25 21:29:32 UTC (rev 87319)
@@ -0,0 +1,37 @@
+<!doctype html>
+<html>
+<head>
+    <style>
+        span { display: none }
+        *[test|="0"] #sp { color: green; display: block}
+    </style>
+</head>
+<body _onload_="startTest();">
+    <div test="1">
+    <p>
+    Test for bug <a href=""
+    </p>
+    <p>This test checks whether CSS attribute selector [att|=val] is re-evaluated after attribute changes in DOM elements which have no style associated with them.</p>
+    <span id="sp">PASSED</span>
+    </div>
+
+    <script>
+        function change() {
+            var element = document.getElementsByTagName('div')[0];
+            element.attributes.test.value = "0-updated";
+            if (window.layoutTestController) {
+                layoutTestController.notifyDone();
+            }
+        }
+        function startTest() {
+            if (window.layoutTestController) {
+                layoutTestController.dumpAsText();
+                layoutTestController.waitUntilDone();
+            }
+            // Trigger an attribute change after all load processing is done. Doing the change
+            // here immediately does not exhibit the problem.
+            setTimeout("change();", 0);
+        }
+    </script>
+</body>
+</html>

Added: trunk/LayoutTests/fast/css/attribute-selector-list-dynamic-no-elementstyle-expected.txt (0 => 87319)


--- trunk/LayoutTests/fast/css/attribute-selector-list-dynamic-no-elementstyle-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/css/attribute-selector-list-dynamic-no-elementstyle-expected.txt	2011-05-25 21:29:32 UTC (rev 87319)
@@ -0,0 +1,5 @@
+Test for bug https://bugs.webkit.org/show_bug.cgi?id=60752
+
+This test checks whether CSS attribute selector [att~=val] is re-evaluated after attribute changes in DOM elements which have no style associated with them.
+
+PASSED

Added: trunk/LayoutTests/fast/css/attribute-selector-list-dynamic-no-elementstyle.html (0 => 87319)


--- trunk/LayoutTests/fast/css/attribute-selector-list-dynamic-no-elementstyle.html	                        (rev 0)
+++ trunk/LayoutTests/fast/css/attribute-selector-list-dynamic-no-elementstyle.html	2011-05-25 21:29:32 UTC (rev 87319)
@@ -0,0 +1,37 @@
+<!doctype html>
+<html>
+<head>
+    <style>
+        span { display: none }
+        *[test~="0"] #sp { color: green; display: block}
+    </style>
+</head>
+<body _onload_="startTest();">
+    <div test="1">
+    <p>
+    Test for bug <a href=""
+    </p>
+    <p>This test checks whether CSS attribute selector [att~=val] is re-evaluated after attribute changes in DOM elements which have no style associated with them.</p>
+    <span id="sp">PASSED</span>
+    </div>
+
+    <script>
+        function change() {
+            var element = document.getElementsByTagName('div')[0];
+            element.attributes.test.value = "updated attributed value 0";
+            if (window.layoutTestController) {
+                layoutTestController.notifyDone();
+            }
+        }
+        function startTest() {
+            if (window.layoutTestController) {
+                layoutTestController.dumpAsText();
+                layoutTestController.waitUntilDone();
+            }
+            // Trigger an attribute change after all load processing is done. Doing the change
+            // here immediately does not exhibit the problem.
+            setTimeout("change();", 0);
+        }
+    </script>
+</body>
+</html>

Added: trunk/LayoutTests/fast/css/attribute-selector-set-dynamic-no-elementstyle-expected.txt (0 => 87319)


--- trunk/LayoutTests/fast/css/attribute-selector-set-dynamic-no-elementstyle-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/css/attribute-selector-set-dynamic-no-elementstyle-expected.txt	2011-05-25 21:29:32 UTC (rev 87319)
@@ -0,0 +1,5 @@
+Test for bug https://bugs.webkit.org/show_bug.cgi?id=60752
+
+This test checks whether CSS attribute selector [att] is re-evaluated after attribute changes in DOM elements which have no style associated with them.
+
+PASSED

Added: trunk/LayoutTests/fast/css/attribute-selector-set-dynamic-no-elementstyle.html (0 => 87319)


--- trunk/LayoutTests/fast/css/attribute-selector-set-dynamic-no-elementstyle.html	                        (rev 0)
+++ trunk/LayoutTests/fast/css/attribute-selector-set-dynamic-no-elementstyle.html	2011-05-25 21:29:32 UTC (rev 87319)
@@ -0,0 +1,37 @@
+<!doctype html>
+<html>
+<head>
+    <style>
+        span { display: none }
+        *[test] #sp { color: green; display: block}
+    </style>
+</head>
+<body _onload_="startTest();">
+    <div>
+    <p>
+    Test for bug <a href=""
+    </p>
+    <p>This test checks whether CSS attribute selector [att] is re-evaluated after attribute changes in DOM elements which have no style associated with them.</p>
+    <span id="sp">PASSED</span>
+    </div>
+
+    <script>
+        function change() {
+            var element = document.getElementsByTagName('div')[0];
+            element.setAttribute("test", "0");
+            if (window.layoutTestController) {
+                layoutTestController.notifyDone();
+            }
+        }
+        function startTest() {
+            if (window.layoutTestController) {
+                layoutTestController.dumpAsText();
+                layoutTestController.waitUntilDone();
+            }
+            // Trigger an attribute change after all load processing is done. Doing the change
+            // here immediately does not exhibit the problem.
+            setTimeout("change();", 0);
+        }
+    </script>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (87318 => 87319)


--- trunk/Source/WebCore/ChangeLog	2011-05-25 21:23:05 UTC (rev 87318)
+++ trunk/Source/WebCore/ChangeLog	2011-05-25 21:29:32 UTC (rev 87319)
@@ -1,3 +1,42 @@
+2011-05-25  Kulanthaivel Palanichamy  <[email protected]>
+
+        Reviewed by David Hyatt.
+
+        Selector matching doesn't update when DOM changes ("[data-a=x] #x")
+        https://bugs.webkit.org/show_bug.cgi?id=60752
+
+        Currently CSSStyleSelector maintains a HashSet of attributes (m_selectorAttrs)
+        which are used in CSS attribute selectors to determine the need for style
+        recalculation whenever element attributes are manipulated in DOM.
+        In certain conditions (element with no style, element is styled and attribute
+        is not a mapped attribute, attribute is of type 'type' or read-only)
+        even when attribute selector matches for an element, the attribute is not
+        added to m_selectorAttrs. This results in missing style recalculations
+        when a DOM element attribute is changed and is not found in m_selectorAttrs.
+
+        Removing the above said conditions in
+        CSSStyleSelector::SelectorChecker::checkOneSelector() for registering
+        attributes in m_selectorAttrs will solve this issue. But this particular
+        function is called numerous times which triggers adding duplicate attributes
+        again and again.
+
+        This patch follows the approach taken for collecting ids in selectors, where
+        all the attributes in selectors are added to a HashSet at the time of adding
+        style rules to CSSStyleSelector from StyleSheets and when
+        CSSStyleSelector::hasSelectorForAttribute() is called, the attribute is
+        simply looked up in this pre-populated hash set.
+
+        Test: fast/css/attribute-selector-dynamic-no-elementstyle.html
+
+        * css/CSSStyleSelector.cpp:
+        (WebCore::CSSStyleSelector::SelectorChecker::checkSelector):
+        (WebCore::CSSStyleSelector::checkSelector):
+        (WebCore::CSSStyleSelector::SelectorChecker::checkOneSelector):
+        (WebCore::collectFeaturesFromSelector):
+        (WebCore::CSSStyleSelector::applyProperty):
+        (WebCore::CSSStyleSelector::hasSelectorForAttribute):
+        * css/CSSStyleSelector.h:
+
 2011-05-25  Ryosuke Niwa  <[email protected]>
 
         Reviewed by James Robinson.

Modified: trunk/Source/WebCore/css/CSSStyleSelector.cpp (87318 => 87319)


--- trunk/Source/WebCore/css/CSSStyleSelector.cpp	2011-05-25 21:23:05 UTC (rev 87318)
+++ trunk/Source/WebCore/css/CSSStyleSelector.cpp	2011-05-25 21:29:32 UTC (rev 87319)
@@ -961,7 +961,7 @@
 bool CSSStyleSelector::SelectorChecker::checkSelector(CSSSelector* sel, Element* element) const
 {
     PseudoId dynamicPseudo = NOPSEUDO;
-    return checkSelector(sel, element, 0, dynamicPseudo, false, false) == SelectorMatches;
+    return checkSelector(sel, element, dynamicPseudo, false, false) == SelectorMatches;
 }
 
 static const unsigned cStyleSearchThreshold = 10;
@@ -2051,7 +2051,7 @@
     }
 
     // Slow path.
-    SelectorMatch match = m_checker.checkSelector(ruleData.selector(), m_element, &m_selectorAttrs, m_dynamicPseudo, false, false, style(), m_parentNode ? m_parentNode->renderStyle() : 0);
+    SelectorMatch match = m_checker.checkSelector(ruleData.selector(), m_element, m_dynamicPseudo, false, false, style(), m_parentNode ? m_parentNode->renderStyle() : 0);
     if (match != SelectorMatches)
         return false;
     if (m_checker.m_pseudoStyle != NOPSEUDO && m_checker.m_pseudoStyle != m_dynamicPseudo)
@@ -2180,7 +2180,7 @@
 // * SelectorMatches         - the selector matches the element e
 // * SelectorFailsLocally    - the selector fails for the element e
 // * SelectorFailsCompletely - the selector fails for e and any sibling or ancestor of e
-CSSStyleSelector::SelectorMatch CSSStyleSelector::SelectorChecker::checkSelector(CSSSelector* sel, Element* e, HashSet<AtomicStringImpl*>* selectorAttrs, PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, RenderStyle* elementStyle, RenderStyle* elementParentStyle) const
+CSSStyleSelector::SelectorMatch CSSStyleSelector::SelectorChecker::checkSelector(CSSSelector* sel, Element* e, PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, RenderStyle* elementStyle, RenderStyle* elementParentStyle) const
 {
 #if ENABLE(SVG)
     // Spec: CSS2 selectors cannot be applied to the (conceptually) cloned DOM tree
@@ -2190,7 +2190,7 @@
 #endif
 
     // first selector has to match
-    if (!checkOneSelector(sel, e, selectorAttrs, dynamicPseudo, isSubSelector, encounteredLink, elementStyle, elementParentStyle))
+    if (!checkOneSelector(sel, e, dynamicPseudo, isSubSelector, encounteredLink, elementStyle, elementParentStyle))
         return SelectorFailsLocally;
 
     // The rest of the selectors has to match
@@ -2224,7 +2224,7 @@
                 if (!n || !n->isElementNode())
                     return SelectorFailsCompletely;
                 e = static_cast<Element*>(n);
-                SelectorMatch match = checkSelector(sel, e, selectorAttrs, dynamicPseudo, false, encounteredLink);
+                SelectorMatch match = checkSelector(sel, e, dynamicPseudo, false, encounteredLink);
                 if (match != SelectorFailsLocally)
                     return match;
             }
@@ -2235,7 +2235,7 @@
             if (!n || !n->isElementNode())
                 return SelectorFailsCompletely;
             e = static_cast<Element*>(n);
-            return checkSelector(sel, e, selectorAttrs, dynamicPseudo, false, encounteredLink);
+            return checkSelector(sel, e, dynamicPseudo, false, encounteredLink);
         }
         case CSSSelector::DirectAdjacent:
         {
@@ -2251,7 +2251,7 @@
                 return SelectorFailsLocally;
             e = static_cast<Element*>(n);
             m_matchVisitedPseudoClass = false;
-            return checkSelector(sel, e, selectorAttrs, dynamicPseudo, false, encounteredLink); 
+            return checkSelector(sel, e, dynamicPseudo, false, encounteredLink);
         }
         case CSSSelector::IndirectAdjacent:
             if (!m_collectRulesOnly && e->parentNode() && e->parentNode()->isElementNode()) {
@@ -2267,7 +2267,7 @@
                     return SelectorFailsLocally;
                 e = static_cast<Element*>(n);
                 m_matchVisitedPseudoClass = false;
-                SelectorMatch match = checkSelector(sel, e, selectorAttrs, dynamicPseudo, false, encounteredLink);
+                SelectorMatch match = checkSelector(sel, e, dynamicPseudo, false, encounteredLink);
                 if (match != SelectorFailsLocally)
                     return match;
             };
@@ -2279,14 +2279,14 @@
             if ((elementStyle || m_collectRulesOnly) && dynamicPseudo != NOPSEUDO && dynamicPseudo != SELECTION &&
                 !((RenderScrollbar::scrollbarForStyleResolve() || dynamicPseudo == SCROLLBAR_CORNER || dynamicPseudo == RESIZER) && sel->m_match == CSSSelector::PseudoClass))
                 return SelectorFailsCompletely;
-            return checkSelector(sel, e, selectorAttrs, dynamicPseudo, true, encounteredLink, elementStyle, elementParentStyle);
+            return checkSelector(sel, e, dynamicPseudo, true, encounteredLink, elementStyle, elementParentStyle);
         case CSSSelector::ShadowDescendant:
         {
             Node* shadowHostNode = e->shadowAncestorNode();
             if (shadowHostNode == e || !shadowHostNode->isElementNode())
                 return SelectorFailsCompletely;
             e = static_cast<Element*>(shadowHostNode);
-            return checkSelector(sel, e, selectorAttrs, dynamicPseudo, false, encounteredLink);
+            return checkSelector(sel, e, dynamicPseudo, false, encounteredLink);
         }
     }
 
@@ -2360,7 +2360,7 @@
     return isPossibleHTMLAttr && htmlCaseInsensitiveAttributesSet->contains(attr.localName().impl());
 }
 
-bool CSSStyleSelector::SelectorChecker::checkOneSelector(CSSSelector* sel, Element* e, HashSet<AtomicStringImpl*>* selectorAttrs, PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, RenderStyle* elementStyle, RenderStyle* elementParentStyle) const
+bool CSSStyleSelector::SelectorChecker::checkOneSelector(CSSSelector* sel, Element* e, PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, RenderStyle* elementStyle, RenderStyle* elementParentStyle) const
 {
     ASSERT(e);
     if (!e)
@@ -2381,8 +2381,6 @@
         // FIXME: Handle the case were elementStyle is 0.
         if (elementStyle && (!e->isStyledElement() || (!static_cast<StyledElement*>(e)->isMappedAttribute(attr) && attr != typeAttr && attr != readonlyAttr))) {
             elementStyle->setAffectedByAttributeSelectors(); // Special-case the "type" and "readonly" attributes so input form controls can share style.
-            if (selectorAttrs)
-                selectorAttrs->add(attr.localName().impl());
         }
 
         const AtomicString& value = e->getAttribute(attr);
@@ -2456,7 +2454,7 @@
                 // the parser enforces that this never occurs
                 ASSERT(subSel->pseudoType() != CSSSelector::PseudoNot);
 
-                if (!checkOneSelector(subSel, e, selectorAttrs, dynamicPseudo, true, encounteredLink, elementStyle, elementParentStyle))
+                if (!checkOneSelector(subSel, e, dynamicPseudo, true, encounteredLink, elementStyle, elementParentStyle))
                     return true;
             }
         } else if (dynamicPseudo != NOPSEUDO && (RenderScrollbar::scrollbarForStyleResolve() || dynamicPseudo == SCROLLBAR_CORNER || dynamicPseudo == RESIZER)) {
@@ -2765,7 +2763,7 @@
                 break;
             case CSSSelector::PseudoAny:
                 for (CSSSelector* selector = sel->selectorList()->first(); selector; selector = CSSSelectorList::next(selector)) {
-                    if (checkSelector(selector, e, selectorAttrs, dynamicPseudo, true, encounteredLink, elementStyle, elementParentStyle) == SelectorMatches)
+                    if (checkSelector(selector, e, dynamicPseudo, true, encounteredLink, elementStyle, elementParentStyle) == SelectorMatches)
                         return true;
                 }
                 break;
@@ -3234,6 +3232,21 @@
 {
     if (selector->m_match == CSSSelector::Id && !selector->value().isEmpty())
         features.idsInRules.add(selector->value().impl());
+    if (selector->hasAttribute()) {
+        switch (selector->m_match) {
+        case CSSSelector::Exact:
+        case CSSSelector::Set:
+        case CSSSelector::List:
+        case CSSSelector::Hyphen:
+        case CSSSelector::Contain:
+        case CSSSelector::Begin:
+        case CSSSelector::End:
+            features.attrsInRules.add(selector->attribute().localName().impl());
+            break;
+        default:
+            break;
+        }
+    }
     switch (selector->pseudoType()) {
     case CSSSelector::PseudoFirstLine:
         features.usesFirstLineRules = true;
@@ -4222,7 +4235,7 @@
                 m_style->setContent(m_element->getAttribute(attr).impl(), didSet);
                 didSet = true;
                 // register the fact that the attribute value affects the style
-                m_selectorAttrs.add(attr.localName().impl());
+                m_features.attrsInRules.add(attr.localName().impl());
                 break;
             }
             case CSSPrimitiveValue::CSS_URI: {
@@ -6521,7 +6534,7 @@
 
 bool CSSStyleSelector::hasSelectorForAttribute(const AtomicString &attrname) const
 {
-    return m_selectorAttrs.contains(attrname.impl());
+    return m_features.attrsInRules.contains(attrname.impl());
 }
 
 void CSSStyleSelector::addViewportDependentMediaQueryResult(const MediaQueryExp* expr, bool result)

Modified: trunk/Source/WebCore/css/CSSStyleSelector.h (87318 => 87319)


--- trunk/Source/WebCore/css/CSSStyleSelector.h	2011-05-25 21:23:05 UTC (rev 87318)
+++ trunk/Source/WebCore/css/CSSStyleSelector.h	2011-05-25 21:29:32 UTC (rev 87319)
@@ -191,6 +191,7 @@
             Features();
             ~Features();
             HashSet<AtomicStringImpl*> idsInRules;
+            HashSet<AtomicStringImpl*> attrsInRules;
             OwnPtr<RuleSet> siblingRules;
             bool usesFirstLineRules;
             bool usesBeforeAfterRules;
@@ -261,8 +262,8 @@
             SelectorChecker(Document*, bool strictParsing);
 
             bool checkSelector(CSSSelector*, Element*) const;
-            SelectorMatch checkSelector(CSSSelector*, Element*, HashSet<AtomicStringImpl*>* selectorAttrs, PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, RenderStyle* = 0, RenderStyle* elementParentStyle = 0) const;
-            bool checkOneSelector(CSSSelector*, Element*, HashSet<AtomicStringImpl*>* selectorAttrs, PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, RenderStyle*, RenderStyle* elementParentStyle) const;
+            SelectorMatch checkSelector(CSSSelector*, Element*, PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, RenderStyle* = 0, RenderStyle* elementParentStyle = 0) const;
+            bool checkOneSelector(CSSSelector*, Element*, PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, RenderStyle*, RenderStyle* elementParentStyle) const;
             bool checkScrollbarPseudoClass(CSSSelector*, PseudoId& dynamicPseudo) const;
             static bool fastCheckSelector(const CSSSelector*, const Element*);
 
@@ -359,7 +360,6 @@
         bool m_matchAuthorAndUserStyles;
         
         RefPtr<CSSFontSelector> m_fontSelector;
-        HashSet<AtomicStringImpl*> m_selectorAttrs;
         Vector<CSSMutableStyleDeclaration*> m_additionalAttributeStyleDecls;
         Vector<MediaQueryResult*> m_viewportDependentMediaQueryResults;
 
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to