Title: [134184] trunk
Revision
134184
Author
[email protected]
Date
2012-11-11 19:40:03 -0800 (Sun, 11 Nov 2012)

Log Message

[Shadow] ElementShadow should have RuleFeatureSet for select attribute selectors.
https://bugs.webkit.org/show_bug.cgi?id=101180

Reviewed by Dimitri Glazkov.

.:

Exposes necessary symbols.

* Source/autotools/symbols.filter:

Source/WebCore:

This is a preparation patch for Bug 100451.

We preserve RuleFeatureSet collected from select attributes in ShadowDOM.
When an element attribute is changed, we might have to invalidate content distribution,
however it's high cost operation. So we would like to check RuleFeatureSet used in
select attributes to determine we really need to invalidate distribution.

Like StyleResolver, ElementShadow has several rule features. When nested ShadowDOM is used,
first we collect features in nested ShadowDOM, and merge it to the parent ShadowDOM.
For the performance reason, we have a flag to check whether we need to collect features again.

Test: fast/dom/shadow/shadow-select-attribute-featureset.html

* WebCore.exp.in:
* dom/ElementShadow.cpp:
(WebCore::ElementShadow::ElementShadow):
(WebCore::ElementShadow::setShouldCollectSelectFeatureSet): Enable a flag to collect feature set of descendant
nodes (and their ShadowDOM).
(WebCore):
(WebCore::ElementShadow::ensureSelectFeatureSetCollected):
(WebCore::ElementShadow::collectSelectFeatureSetFrom): Collect RuleFeatureSet from all descendant Nodes and their
ShadowDOM. We need to collect id, class, and attribute names.
* dom/ElementShadow.h:
(WebCore::ElementShadow::shouldCollectSelectFeatureSet):
(ElementShadow):
(WebCore::ElementShadow::hasSelectorForId):
(WebCore):
(WebCore::ElementShadow::hasSelectorForClass):
(WebCore::ElementShadow::hasSelectorForAttribute):
* html/shadow/HTMLContentElement.cpp:
(WebCore::HTMLContentElement::parseAttribute): When select attribute is changed, enable a flag to recollect features.
(WebCore::HTMLContentElement::insertedInto): We have to recollect features when HTMLContentElement is moved.
(WebCore::HTMLContentElement::removedFrom): ditto.
* html/shadow/HTMLContentElement.h:
(WebCore::toHTMLContentElement):
(WebCore):
* testing/Internals.cpp:
(WebCore::Internals::hasSelectorForIdInShadow):
(WebCore):
(WebCore::Internals::hasSelectorForClassInShadow):
(WebCore::Internals::hasSelectorForAttributeInShadow):
* testing/Internals.h:
(Internals):
* testing/Internals.idl:

Source/WebKit2:

* win/WebKit2.def:
* win/WebKit2CFLite.def:

LayoutTests:

* fast/dom/shadow/shadow-select-attribute-featureset-expected.txt: Added.
* fast/dom/shadow/shadow-select-attribute-featureset.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/ChangeLog (134183 => 134184)


--- trunk/ChangeLog	2012-11-12 02:27:10 UTC (rev 134183)
+++ trunk/ChangeLog	2012-11-12 03:40:03 UTC (rev 134184)
@@ -1,3 +1,14 @@
+2012-11-11  Shinya Kawanaka  <[email protected]>
+
+        [Shadow] ElementShadow should have RuleFeatureSet for select attribute selectors.
+        https://bugs.webkit.org/show_bug.cgi?id=101180
+
+        Reviewed by Dimitri Glazkov.
+
+        Exposes necessary symbols.
+
+        * Source/autotools/symbols.filter:
+
 2012-11-11  Sheriff Bot  <[email protected]>
 
         Unreviewed, rolling out r134144.

Modified: trunk/LayoutTests/ChangeLog (134183 => 134184)


--- trunk/LayoutTests/ChangeLog	2012-11-12 02:27:10 UTC (rev 134183)
+++ trunk/LayoutTests/ChangeLog	2012-11-12 03:40:03 UTC (rev 134184)
@@ -1,3 +1,13 @@
+2012-11-11  Shinya Kawanaka  <[email protected]>
+
+        [Shadow] ElementShadow should have RuleFeatureSet for select attribute selectors.
+        https://bugs.webkit.org/show_bug.cgi?id=101180
+
+        Reviewed by Dimitri Glazkov.
+
+        * fast/dom/shadow/shadow-select-attribute-featureset-expected.txt: Added.
+        * fast/dom/shadow/shadow-select-attribute-featureset.html: Added.
+
 2012-11-11  Sheriff Bot  <[email protected]>
 
         Unreviewed, rolling out r134144.

Added: trunk/LayoutTests/fast/dom/shadow/shadow-select-attribute-featureset-expected.txt (0 => 134184)


--- trunk/LayoutTests/fast/dom/shadow/shadow-select-attribute-featureset-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/shadow/shadow-select-attribute-featureset-expected.txt	2012-11-12 03:40:03 UTC (rev 134184)
@@ -0,0 +1,75 @@
+Id should be collected
+PASS internals.hasSelectorForIdInShadow(host, "foo") is true
+PASS internals.hasSelectorForIdInShadow(host, "bar") is false
+PASS internals.hasSelectorForIdInShadow(host, "host") is false
+
+Class should be collected
+PASS internals.hasSelectorForClassInShadow(host, "foo") is true
+PASS internals.hasSelectorForClassInShadow(host, "host") is false
+
+Attribute should be collected
+PASS internals.hasSelectorForAttributeInShadow(host, "foo") is true
+PASS internals.hasSelectorForAttributeInShadow(host, "host") is false
+
+Select attribute might have several selectors
+PASS internals.hasSelectorForIdInShadow(host, "foo") is true
+PASS internals.hasSelectorForIdInShadow(host, "bar") is false
+PASS internals.hasSelectorForIdInShadow(host, "baz") is false
+PASS internals.hasSelectorForClassInShadow(host, "foo") is false
+PASS internals.hasSelectorForClassInShadow(host, "bar") is true
+PASS internals.hasSelectorForClassInShadow(host, "baz") is false
+PASS internals.hasSelectorForAttributeInShadow(host, "foo") is false
+PASS internals.hasSelectorForAttributeInShadow(host, "bar") is false
+PASS internals.hasSelectorForAttributeInShadow(host, "baz") is true
+
+Don't count shadow element
+PASS internals.hasSelectorForIdInShadow(host, "foo") is false
+PASS internals.hasSelectorForIdInShadow(host, "bar") is false
+PASS internals.hasSelectorForIdInShadow(host, "baz") is false
+PASS internals.hasSelectorForClassInShadow(host, "foo") is false
+PASS internals.hasSelectorForClassInShadow(host, "bar") is false
+PASS internals.hasSelectorForClassInShadow(host, "baz") is false
+PASS internals.hasSelectorForAttributeInShadow(host, "foo") is false
+PASS internals.hasSelectorForAttributeInShadow(host, "bar") is false
+PASS internals.hasSelectorForAttributeInShadow(host, "baz") is false
+
+Complex case for single ShadowRoot
+PASS internals.hasSelectorForIdInShadow(host, "foo") is false
+PASS internals.hasSelectorForClassInShadow(host, "foo") is false
+PASS internals.hasSelectorForAttributeInShadow(host, "foo") is true
+PASS internals.hasSelectorForAttributeInShadow(host, "piyo") is false
+
+Another complex case for single ShadowRoot
+PASS internals.hasSelectorForIdInShadow(host, "foo") is true
+PASS internals.hasSelectorForClassInShadow(host, "foo") is true
+PASS internals.hasSelectorForAttributeInShadow(host, "foo") is true
+
+Multiple ShadowRoot case
+PASS internals.hasSelectorForIdInShadow(host, "foo") is true
+PASS internals.hasSelectorForIdInShadow(host, "bar") is true
+PASS internals.hasSelectorForIdInShadow(host, "baz") is false
+PASS internals.hasSelectorForClassInShadow(host, "foo") is false
+PASS internals.hasSelectorForClassInShadow(host, "bar") is true
+PASS internals.hasSelectorForClassInShadow(host, "baz") is false
+PASS internals.hasSelectorForAttributeInShadow(host, "foo") is false
+PASS internals.hasSelectorForAttributeInShadow(host, "bar") is false
+PASS internals.hasSelectorForAttributeInShadow(host, "baz") is true
+
+Dynamic select attribute update
+PASS internals.hasSelectorForIdInShadow(host, "foo") is true
+PASS internals.hasSelectorForIdInShadow(host, "bar") is false
+PASS internals.hasSelectorForIdInShadow(host, "foo") is false
+PASS internals.hasSelectorForIdInShadow(host, "bar") is true
+
+Nested ShadowDOM case
+PASS internals.hasSelectorForIdInShadow(host, "foo") is true
+PASS internals.hasSelectorForIdInShadow(host, "bar") is true
+PASS internals.hasSelectorForIdInShadow(host, "baz") is false
+PASS internals.hasSelectorForIdInShadow(host, "foo") is true
+PASS internals.hasSelectorForIdInShadow(host, "bar") is false
+PASS internals.hasSelectorForIdInShadow(host, "baz") is true
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/dom/shadow/shadow-select-attribute-featureset.html (0 => 134184)


--- trunk/LayoutTests/fast/dom/shadow/shadow-select-attribute-featureset.html	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/shadow/shadow-select-attribute-featureset.html	2012-11-12 03:40:03 UTC (rev 134184)
@@ -0,0 +1,175 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script src=""
+<script src=""
+</head>
+<body>
+
+<div id="container"></div>
+<pre id="console"></pre>
+
+<script>
+function testCase(f)
+{
+    container.innerHTML = '';
+    container.appendChild(createDOM('div', {'id': 'host'},
+                                    createShadowRoot()));
+    shadowRoot = internals.shadowRoot(host);
+
+    f();
+    debug('');
+}
+
+testCase(function()
+{
+    debug('Id should be collected');
+
+    shadowRoot.innerHTML = '<content select="#foo"></content>';
+    shouldBe('internals.hasSelectorForIdInShadow(host, "foo")', 'true');
+    shouldBe('internals.hasSelectorForIdInShadow(host, "bar")', 'false');
+    shouldBe('internals.hasSelectorForIdInShadow(host, "host")', 'false');
+});
+
+testCase(function()
+{
+    debug('Class should be collected');
+
+    shadowRoot.innerHTML = '<content select=".foo"></content>';
+    shouldBe('internals.hasSelectorForClassInShadow(host, "foo")', 'true');
+    shouldBe('internals.hasSelectorForClassInShadow(host, "host")', 'false');
+});
+
+testCase(function()
+{
+    debug('Attribute should be collected');
+
+    shadowRoot.innerHTML = '<content select="div[foo]"></content>';
+    shouldBe('internals.hasSelectorForAttributeInShadow(host, "foo")', 'true');
+    shouldBe('internals.hasSelectorForAttributeInShadow(host, "host")', 'false');
+});
+
+testCase(function()
+{
+    debug('Select attribute might have several selectors');
+
+    shadowRoot.innerHTML = '<content select="#foo,.bar,div[baz]"></content>';
+    shouldBe('internals.hasSelectorForIdInShadow(host, "foo")', 'true');
+    shouldBe('internals.hasSelectorForIdInShadow(host, "bar")', 'false');
+    shouldBe('internals.hasSelectorForIdInShadow(host, "baz")', 'false');
+
+    shouldBe('internals.hasSelectorForClassInShadow(host, "foo")', 'false');
+    shouldBe('internals.hasSelectorForClassInShadow(host, "bar")', 'true');
+    shouldBe('internals.hasSelectorForClassInShadow(host, "baz")', 'false');
+
+    shouldBe('internals.hasSelectorForAttributeInShadow(host, "foo")', 'false');
+    shouldBe('internals.hasSelectorForAttributeInShadow(host, "bar")', 'false');
+    shouldBe('internals.hasSelectorForAttributeInShadow(host, "baz")', 'true');
+});
+
+testCase(function()
+{
+    debug('Don\'t count shadow element');
+
+    shadowRoot.innerHTML = '<shadow select="#foo,.bar,div[baz]"></shadow>';
+    shouldBe('internals.hasSelectorForIdInShadow(host, "foo")', 'false');
+    shouldBe('internals.hasSelectorForIdInShadow(host, "bar")', 'false');
+    shouldBe('internals.hasSelectorForIdInShadow(host, "baz")', 'false');
+
+    shouldBe('internals.hasSelectorForClassInShadow(host, "foo")', 'false');
+    shouldBe('internals.hasSelectorForClassInShadow(host, "bar")', 'false');
+    shouldBe('internals.hasSelectorForClassInShadow(host, "baz")', 'false');
+
+    shouldBe('internals.hasSelectorForAttributeInShadow(host, "foo")', 'false');
+    shouldBe('internals.hasSelectorForAttributeInShadow(host, "bar")', 'false');
+    shouldBe('internals.hasSelectorForAttributeInShadow(host, "baz")', 'false');
+});
+
+testCase(function()
+{
+    debug('Complex case for single ShadowRoot');
+
+    shadowRoot.innerHTML = '<div><div></div><content select="*"></content><div><content select="div[foo=piyo]"></content></div>';
+    shouldBe('internals.hasSelectorForIdInShadow(host, "foo")', 'false');
+    shouldBe('internals.hasSelectorForClassInShadow(host, "foo")', 'false');
+    shouldBe('internals.hasSelectorForAttributeInShadow(host, "foo")', 'true');
+    shouldBe('internals.hasSelectorForAttributeInShadow(host, "piyo")', 'false');
+});
+
+testCase(function()
+{
+    debug('Another complex case for single ShadowRoot');
+
+    shadowRoot.innerHTML = '<content select="#foo,.foo,div[foo]"></content>';
+    shouldBe('internals.hasSelectorForIdInShadow(host, "foo")', 'true');
+    shouldBe('internals.hasSelectorForClassInShadow(host, "foo")', 'true');
+    shouldBe('internals.hasSelectorForAttributeInShadow(host, "foo")', 'true');
+});
+
+testCase(function()
+{
+    debug('Multiple ShadowRoot case');
+
+    var anotherShadowRoot = new WebKitShadowRoot(host);
+
+    shadowRoot.innerHTML = '<content select="#foo"></content>';
+    anotherShadowRoot.innerHTML = '<content select="#bar"></content><content select="div[baz],.bar"></content>';
+
+    shouldBe('internals.hasSelectorForIdInShadow(host, "foo")', 'true');
+    shouldBe('internals.hasSelectorForIdInShadow(host, "bar")', 'true');
+    shouldBe('internals.hasSelectorForIdInShadow(host, "baz")', 'false');
+
+    shouldBe('internals.hasSelectorForClassInShadow(host, "foo")', 'false');
+    shouldBe('internals.hasSelectorForClassInShadow(host, "bar")', 'true');
+    shouldBe('internals.hasSelectorForClassInShadow(host, "baz")', 'false');
+
+    shouldBe('internals.hasSelectorForAttributeInShadow(host, "foo")', 'false');
+    shouldBe('internals.hasSelectorForAttributeInShadow(host, "bar")', 'false');
+    shouldBe('internals.hasSelectorForAttributeInShadow(host, "baz")', 'true');
+});
+
+testCase(function()
+{
+    debug('Dynamic select attribute update');
+
+    shadowRoot.innerHTML = '<content select="#foo"></content>';
+
+    shouldBe('internals.hasSelectorForIdInShadow(host, "foo")', 'true');
+    shouldBe('internals.hasSelectorForIdInShadow(host, "bar")', 'false');
+
+    var content = shadowRoot.querySelector('content');
+    content.select = '#bar';
+
+    shouldBe('internals.hasSelectorForIdInShadow(host, "foo")', 'false');
+    shouldBe('internals.hasSelectorForIdInShadow(host, "bar")', 'true');
+});
+
+testCase(function()
+{
+    debug('Nested ShadowDOM case');
+
+    shadowRoot.innerHTML = '<content select="#foo"></content>';
+
+    var div = document.createElement('div');
+    var nestedShadowRoot = new WebKitShadowRoot(div);
+    nestedShadowRoot.innerHTML = '<content select="#bar"></content>';
+    shadowRoot.appendChild(div);
+
+    shouldBe('internals.hasSelectorForIdInShadow(host, "foo")', 'true');
+    shouldBe('internals.hasSelectorForIdInShadow(host, "bar")', 'true');
+    shouldBe('internals.hasSelectorForIdInShadow(host, "baz")', 'false');
+
+    var content = nestedShadowRoot.querySelector('content');
+    content.select = '#baz';
+
+    shouldBe('internals.hasSelectorForIdInShadow(host, "foo")', 'true');
+    shouldBe('internals.hasSelectorForIdInShadow(host, "bar")', 'false');
+    shouldBe('internals.hasSelectorForIdInShadow(host, "baz")', 'true');
+});
+
+finishJSTest();
+</script>
+<script src=""
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (134183 => 134184)


--- trunk/Source/WebCore/ChangeLog	2012-11-12 02:27:10 UTC (rev 134183)
+++ trunk/Source/WebCore/ChangeLog	2012-11-12 03:40:03 UTC (rev 134184)
@@ -1,3 +1,55 @@
+2012-11-11  Shinya Kawanaka  <[email protected]>
+
+        [Shadow] ElementShadow should have RuleFeatureSet for select attribute selectors.
+        https://bugs.webkit.org/show_bug.cgi?id=101180
+
+        Reviewed by Dimitri Glazkov.
+
+        This is a preparation patch for Bug 100451.
+
+        We preserve RuleFeatureSet collected from select attributes in ShadowDOM.
+        When an element attribute is changed, we might have to invalidate content distribution,
+        however it's high cost operation. So we would like to check RuleFeatureSet used in
+        select attributes to determine we really need to invalidate distribution.
+
+        Like StyleResolver, ElementShadow has several rule features. When nested ShadowDOM is used,
+        first we collect features in nested ShadowDOM, and merge it to the parent ShadowDOM.
+        For the performance reason, we have a flag to check whether we need to collect features again.
+
+        Test: fast/dom/shadow/shadow-select-attribute-featureset.html
+
+        * WebCore.exp.in:
+        * dom/ElementShadow.cpp:
+        (WebCore::ElementShadow::ElementShadow):
+        (WebCore::ElementShadow::setShouldCollectSelectFeatureSet): Enable a flag to collect feature set of descendant
+        nodes (and their ShadowDOM).
+        (WebCore):
+        (WebCore::ElementShadow::ensureSelectFeatureSetCollected):
+        (WebCore::ElementShadow::collectSelectFeatureSetFrom): Collect RuleFeatureSet from all descendant Nodes and their
+        ShadowDOM. We need to collect id, class, and attribute names.
+        * dom/ElementShadow.h:
+        (WebCore::ElementShadow::shouldCollectSelectFeatureSet):
+        (ElementShadow):
+        (WebCore::ElementShadow::hasSelectorForId):
+        (WebCore):
+        (WebCore::ElementShadow::hasSelectorForClass):
+        (WebCore::ElementShadow::hasSelectorForAttribute):
+        * html/shadow/HTMLContentElement.cpp:
+        (WebCore::HTMLContentElement::parseAttribute): When select attribute is changed, enable a flag to recollect features.
+        (WebCore::HTMLContentElement::insertedInto): We have to recollect features when HTMLContentElement is moved.
+        (WebCore::HTMLContentElement::removedFrom): ditto.
+        * html/shadow/HTMLContentElement.h:
+        (WebCore::toHTMLContentElement):
+        (WebCore):
+        * testing/Internals.cpp:
+        (WebCore::Internals::hasSelectorForIdInShadow):
+        (WebCore):
+        (WebCore::Internals::hasSelectorForClassInShadow):
+        (WebCore::Internals::hasSelectorForAttributeInShadow):
+        * testing/Internals.h:
+        (Internals):
+        * testing/Internals.idl:
+
 2012-11-11  Sheriff Bot  <[email protected]>
 
         Unreviewed, rolling out r134144.

Modified: trunk/Source/WebCore/WebCore.exp.in (134183 => 134184)


--- trunk/Source/WebCore/WebCore.exp.in	2012-11-12 02:27:10 UTC (rev 134183)
+++ trunk/Source/WebCore/WebCore.exp.in	2012-11-12 03:40:03 UTC (rev 134184)
@@ -215,6 +215,7 @@
 __ZN7WebCore13CharacterData7setDataERKN3WTF6StringERi
 __ZN7WebCore13ContainerNode11appendChildEN3WTF10PassRefPtrINS_4NodeEEERib
 __ZN7WebCore13ContainerNode11removeChildEPNS_4NodeERi
+__ZN7WebCore13ElementShadow31ensureSelectFeatureSetCollectedEv
 __ZN7WebCore13HTTPHeaderMapC1Ev
 __ZN7WebCore13HTTPHeaderMapD1Ev
 __ZN7WebCore13HitTestResultC1ERKS0_

Modified: trunk/Source/WebCore/dom/ElementShadow.cpp (134183 => 134184)


--- trunk/Source/WebCore/dom/ElementShadow.cpp	2012-11-12 02:27:10 UTC (rev 134183)
+++ trunk/Source/WebCore/dom/ElementShadow.cpp	2012-11-12 03:40:03 UTC (rev 134184)
@@ -27,9 +27,12 @@
 #include "config.h"
 #include "ElementShadow.h"
 
+#include "CSSParser.h"
+#include "CSSSelectorList.h"
 #include "ContainerNodeAlgorithms.h"
 #include "Document.h"
 #include "Element.h"
+#include "HTMLContentElement.h"
 #include "HTMLShadowElement.h"
 #include "InspectorInstrumentation.h"
 #include "ShadowRoot.h"
@@ -39,6 +42,7 @@
 namespace WebCore {
 
 ElementShadow::ElementShadow()
+    : m_shouldCollectSelectFeatureSet(false)
 {
 }
 
@@ -203,6 +207,52 @@
         m_distributor.finishInivalidation();
 }
 
+void ElementShadow::setShouldCollectSelectFeatureSet()
+{
+    if (shouldCollectSelectFeatureSet())
+        return;
+
+    m_shouldCollectSelectFeatureSet = true;
+
+    if (ShadowRoot* parentShadowRoot = host()->shadowRoot()) {
+        if (ElementShadow* parentElementShadow = parentShadowRoot->owner())
+            parentElementShadow->setShouldCollectSelectFeatureSet();
+    }
+}
+
+void ElementShadow::ensureSelectFeatureSetCollected()
+{
+    if (!m_shouldCollectSelectFeatureSet)
+        return;
+
+    m_selectFeatures.clear();
+    for (ShadowRoot* root = oldestShadowRoot(); root; root = root->youngerShadowRoot())
+        collectSelectFeatureSetFrom(root);
+    m_shouldCollectSelectFeatureSet = false;
+}
+
+void ElementShadow::collectSelectFeatureSetFrom(ShadowRoot* root)
+{
+    if (root->hasElementShadow()) {
+        for (Node* node = root->firstChild(); node; node = node->traverseNextNode()) {
+            if (ElementShadow* elementShadow = node->isElementNode() ? toElement(node)->shadow() : 0) {
+                elementShadow->ensureSelectFeatureSetCollected();
+                m_selectFeatures.add(elementShadow->m_selectFeatures);
+            }
+        }
+    }
+
+    if (root->hasContentElement()) {
+        for (Node* node = root->firstChild(); node; node = node->traverseNextNode()) {
+            if (isHTMLContentElement(node)) {
+                const CSSSelectorList& list = toHTMLContentElement(node)->selectorList();
+                for (CSSSelector* selector = list.first(); selector; selector = list.next(selector))
+                    m_selectFeatures.collectFeaturesFromSelector(selector);                    
+            }
+        }
+    }
+}
+
 void ElementShadow::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
 {
     MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::DOM);

Modified: trunk/Source/WebCore/dom/ElementShadow.h (134183 => 134184)


--- trunk/Source/WebCore/dom/ElementShadow.h	2012-11-12 02:27:10 UTC (rev 134183)
+++ trunk/Source/WebCore/dom/ElementShadow.h	2012-11-12 03:40:03 UTC (rev 134184)
@@ -29,6 +29,7 @@
 
 #include "ContentDistributor.h"
 #include "ExceptionCode.h"
+#include "RuleFeature.h"
 #include "ShadowRoot.h"
 #include <wtf/DoublyLinkedList.h>
 #include <wtf/Noncopyable.h>
@@ -69,13 +70,25 @@
     ContentDistributor& distributor();
     const ContentDistributor& distributor() const;
 
+    bool shouldCollectSelectFeatureSet() const { return m_shouldCollectSelectFeatureSet; }
+    void setShouldCollectSelectFeatureSet();
+    void ensureSelectFeatureSetCollected();
+
+    bool hasSelectorForId(const AtomicString&) const;
+    bool hasSelectorForClass(const AtomicString&) const;
+    bool hasSelectorForAttribute(const AtomicString&) const;
+
     void reportMemoryUsage(MemoryObjectInfo*) const;
 
 private:
     void invalidateDistribution(Element* host);
 
+    void collectSelectFeatureSetFrom(ShadowRoot*);
+
     DoublyLinkedList<ShadowRoot> m_shadowRoots;
     ContentDistributor m_distributor;
+    RuleFeatureSet m_selectFeatures;
+    bool m_shouldCollectSelectFeatureSet : 1;
 };
 
 inline ShadowRoot* ElementShadow::youngestShadowRoot() const
@@ -113,6 +126,27 @@
     return 0;
 }
 
+inline bool ElementShadow::hasSelectorForId(const AtomicString& idValue) const
+{
+    ASSERT(!idValue.isEmpty());
+    ASSERT(!m_shouldCollectSelectFeatureSet);
+    return m_selectFeatures.idsInRules.contains(idValue.impl());
+}
+
+inline bool ElementShadow::hasSelectorForClass(const AtomicString& classValue) const
+{
+    ASSERT(!classValue.isEmpty());
+    ASSERT(!m_shouldCollectSelectFeatureSet);
+    return m_selectFeatures.classesInRules.contains(classValue.impl());
+}
+
+inline bool ElementShadow::hasSelectorForAttribute(const AtomicString& attributeName) const
+{
+    ASSERT(!attributeName.isEmpty());
+    ASSERT(!m_shouldCollectSelectFeatureSet);
+    return m_selectFeatures.attrsInRules.contains(attributeName.impl());
+}
+
 class ShadowRootVector : public Vector<RefPtr<ShadowRoot> > {
 public:
     explicit ShadowRootVector(ElementShadow* tree)

Modified: trunk/Source/WebCore/html/shadow/HTMLContentElement.cpp (134183 => 134184)


--- trunk/Source/WebCore/html/shadow/HTMLContentElement.cpp	2012-11-12 02:27:10 UTC (rev 134183)
+++ trunk/Source/WebCore/html/shadow/HTMLContentElement.cpp	2012-11-12 03:40:03 UTC (rev 134184)
@@ -101,8 +101,10 @@
 void HTMLContentElement::parseAttribute(const Attribute& attribute)
 {
     if (attribute.name() == selectAttr) {
-        if (ShadowRoot* root = shadowRoot())
+        if (ShadowRoot* root = shadowRoot()) {
+            root->owner()->setShouldCollectSelectFeatureSet();
             root->owner()->invalidateDistribution();
+        }
         m_shouldParseSelectorList = true;
     } else
         InsertionPoint::parseAttribute(attribute);
@@ -113,7 +115,9 @@
     InsertionPoint::insertedInto(insertionPoint);
 
     if (insertionPoint->inDocument() && isActive()) {
-        shadowRoot()->registerContentElement();
+        ShadowRoot* root = shadowRoot();
+        root->registerContentElement();
+        root->owner()->setShouldCollectSelectFeatureSet();
         m_registeredWithShadowRoot = true;
     }
 
@@ -129,6 +133,9 @@
         if (root)
             root->unregisterContentElement();
         m_registeredWithShadowRoot = false;
+
+        if (ElementShadow* elementShadow = root ? root->owner() : 0)
+            elementShadow->setShouldCollectSelectFeatureSet();
     }
     InsertionPoint::removedFrom(insertionPoint);
 }

Modified: trunk/Source/WebCore/html/shadow/HTMLContentElement.h (134183 => 134184)


--- trunk/Source/WebCore/html/shadow/HTMLContentElement.h	2012-11-12 02:27:10 UTC (rev 134183)
+++ trunk/Source/WebCore/html/shadow/HTMLContentElement.h	2012-11-12 03:40:03 UTC (rev 134184)
@@ -86,6 +86,12 @@
     return node->hasTagName(HTMLContentElement::contentTagName(node->document()));
 }
 
+inline HTMLContentElement* toHTMLContentElement(Node* node)
+{
+    ASSERT(!node || isHTMLContentElement(node));
+    return static_cast<HTMLContentElement*>(node);
 }
 
+}
+
 #endif

Modified: trunk/Source/WebCore/testing/Internals.cpp (134183 => 134184)


--- trunk/Source/WebCore/testing/Internals.cpp	2012-11-12 02:27:10 UTC (rev 134183)
+++ trunk/Source/WebCore/testing/Internals.cpp	2012-11-12 03:40:03 UTC (rev 134184)
@@ -306,6 +306,39 @@
     return parentTreeScope ? parentTreeScope->rootNode() : 0;
 }
 
+bool Internals::hasSelectorForIdInShadow(Element* host, const String& idValue, ExceptionCode& ec)
+{
+    if (!host || !host->shadow()) {
+        ec = INVALID_ACCESS_ERR;
+        return 0;
+    }
+
+    host->shadow()->ensureSelectFeatureSetCollected();
+    return host->shadow()->hasSelectorForId(idValue);
+}
+
+bool Internals::hasSelectorForClassInShadow(Element* host, const String& className, ExceptionCode& ec)
+{
+    if (!host || !host->shadow()) {
+        ec = INVALID_ACCESS_ERR;
+        return 0;
+    }
+
+    host->shadow()->ensureSelectFeatureSetCollected();
+    return host->shadow()->hasSelectorForClass(className);
+}
+
+bool Internals::hasSelectorForAttributeInShadow(Element* host, const String& attributeName, ExceptionCode& ec)
+{
+    if (!host || !host->shadow()) {
+        ec = INVALID_ACCESS_ERR;
+        return 0;
+    }
+
+    host->shadow()->ensureSelectFeatureSetCollected();
+    return host->shadow()->hasSelectorForAttribute(attributeName);
+}
+
 bool Internals::hasShadowInsertionPoint(const Node* root, ExceptionCode& ec) const
 {
     if (root && root->isShadowRoot())

Modified: trunk/Source/WebCore/testing/Internals.h (134183 => 134184)


--- trunk/Source/WebCore/testing/Internals.h	2012-11-12 02:27:10 UTC (rev 134183)
+++ trunk/Source/WebCore/testing/Internals.h	2012-11-12 03:40:03 UTC (rev 134184)
@@ -96,6 +96,9 @@
     bool isValidContentSelect(Element* insertionPoint, ExceptionCode&);
     Node* treeScopeRootNode(Node*, ExceptionCode&);
     Node* parentTreeScope(Node*, ExceptionCode&);
+    bool hasSelectorForIdInShadow(Element* host, const String& idValue, ExceptionCode&);
+    bool hasSelectorForClassInShadow(Element* host, const String& className, ExceptionCode&);
+    bool hasSelectorForAttributeInShadow(Element* host, const String& attributeName, ExceptionCode&);
 
     bool attached(Node*, ExceptionCode&);
 

Modified: trunk/Source/WebCore/testing/Internals.idl (134183 => 134184)


--- trunk/Source/WebCore/testing/Internals.idl	2012-11-12 02:27:10 UTC (rev 134183)
+++ trunk/Source/WebCore/testing/Internals.idl	2012-11-12 03:40:03 UTC (rev 134184)
@@ -59,6 +59,9 @@
     boolean isValidContentSelect(in Element contentElement) raises(DOMException);
     Node treeScopeRootNode(in Node node) raises (DOMException);
     Node parentTreeScope(in Node node) raises (DOMException);
+    boolean hasSelectorForIdInShadow(in Element host, in DOMString id) raises (DOMException);
+    boolean hasSelectorForClassInShadow(in Element host, in DOMString className) raises (DOMException);
+    boolean hasSelectorForAttributeInShadow(in Element host, in DOMString attributeName) raises (DOMException);
 
     Node nextSiblingByWalker(in Node node) raises(DOMException);
     Node firstChildByWalker(in Node node) raises(DOMException);

Modified: trunk/Source/WebKit2/ChangeLog (134183 => 134184)


--- trunk/Source/WebKit2/ChangeLog	2012-11-12 02:27:10 UTC (rev 134183)
+++ trunk/Source/WebKit2/ChangeLog	2012-11-12 03:40:03 UTC (rev 134184)
@@ -1,3 +1,13 @@
+2012-11-11  Shinya Kawanaka  <[email protected]>
+
+        [Shadow] ElementShadow should have RuleFeatureSet for select attribute selectors.
+        https://bugs.webkit.org/show_bug.cgi?id=101180
+
+        Reviewed by Dimitri Glazkov.
+
+        * win/WebKit2.def:
+        * win/WebKit2CFLite.def:
+
 2012-11-11  Sheriff Bot  <[email protected]>
 
         Unreviewed, rolling out r134144.

Modified: trunk/Source/WebKit2/win/WebKit2.def (134183 => 134184)


--- trunk/Source/WebKit2/win/WebKit2.def	2012-11-12 02:27:10 UTC (rev 134183)
+++ trunk/Source/WebKit2/win/WebKit2.def	2012-11-12 03:40:03 UTC (rev 134184)
@@ -168,6 +168,7 @@
         ?create@ShadowRoot@WebCore@@SA?AV?$PassRefPtr@VShadowRoot@WebCore@@@WTF@@PAVElement@2@AAH@Z
         ?createWrapper@WebCore@@YA?AVJSValue@JSC@@PAVExecState@3@PAVJSDOMGlobalObject@1@PAVNode@1@@Z
         ?documentState@HistoryItem@WebCore@@QBEABV?$Vector@VString@WTF@@$0A@@WTF@@XZ
+        ?ensureSelectFeatureSetCollected@ElementShadow@WebCore@@QAEXXZ
         ?equal@WTF@@YA_NPBVStringImpl@1@PBE@Z
         ?equal@WTF@@YA_NPBVStringImpl@1@0@Z
         ?equalIgnoringCase@WTF@@YA_NPAVStringImpl@1@PBE@Z

Modified: trunk/Source/WebKit2/win/WebKit2CFLite.def (134183 => 134184)


--- trunk/Source/WebKit2/win/WebKit2CFLite.def	2012-11-12 02:27:10 UTC (rev 134183)
+++ trunk/Source/WebKit2/win/WebKit2CFLite.def	2012-11-12 03:40:03 UTC (rev 134184)
@@ -161,6 +161,7 @@
         ?create@ShadowRoot@WebCore@@SA?AV?$PassRefPtr@VShadowRoot@WebCore@@@WTF@@PAVElement@2@AAH@Z
         ?createWrapper@WebCore@@YA?AVJSValue@JSC@@PAVExecState@3@PAVJSDOMGlobalObject@1@PAVNode@1@@Z
         ?documentState@HistoryItem@WebCore@@QBEABV?$Vector@VString@WTF@@$0A@@WTF@@XZ
+        ?ensureSelectFeatureSetCollected@ElementShadow@WebCore@@QAEXXZ
         ?equal@WTF@@YA_NPBVStringImpl@1@PBE@Z
         ?equal@WTF@@YA_NPBVStringImpl@1@0@Z
         ?equalIgnoringCase@WTF@@YA_NPAVStringImpl@1@PBE@Z

Modified: trunk/Source/autotools/symbols.filter (134183 => 134184)


--- trunk/Source/autotools/symbols.filter	2012-11-12 02:27:10 UTC (rev 134183)
+++ trunk/Source/autotools/symbols.filter	2012-11-12 03:40:03 UTC (rev 134184)
@@ -56,6 +56,7 @@
 _ZN7WebCore12TextIterator29getLocationAndLengthFromRangeEPNS_7ElementEPKNS_5RangeERjS6_;
 _ZN7WebCore12TextIterator29getLocationAndLengthFromRangeEPNS_7ElementEPKNS_5RangeERmS6_;
 _ZN7WebCore12PrintContext20pageNumberForElementEPNS_7ElementERKNS_9FloatSizeE;
+_ZN7WebCore13ElementShadow31ensureSelectFeatureSetCollectedEv;
 _ZN7WebCore13createWrapperEPN3JSC9ExecStateEPNS_17JSDOMGlobalObjectEPNS_4NodeE;
 _ZN7WebCore14ClientRectListC1ERKN3WTF6VectorINS_9FloatQuadELj0EEE;
 _ZN7WebCore14ClientRectListC1ERKN3WTF6VectorINS_9FloatQuadELm0EEE;
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to