Title: [91453] trunk/Source/WebCore
Revision
91453
Author
morr...@google.com
Date
2011-07-21 02:39:37 -0700 (Thu, 21 Jul 2011)

Log Message

[Refactoring] Shadow inclusion cache should be managed by ShadowContentSelector
https://bugs.webkit.org/show_bug.cgi?id=64849

Reviewed by Dimitri Glazkov.

This change is a reorg around Shadow inclusion mechanism.
- Moved definition of ShadowInclusion, ShadowInclusionSet and ShadowInclusionList
  from ShadowContentElement.h to ShadowContentSelector.h, which is included
  from smaller number of places.
- Moved ShadowInclusionSet from ShadowRoot to ShadowContentSelector
- Made ShadowContentSelector's lifetime managed by ShadowRoot
  because ShadowInclusionSet is held by the selector.
- Thus, there is no longer "active" selector (ShadowContentSelector::s_currentInstance)
  Because the selector is associated for each ShadowRoot object.

No new tests. No behavior change.

* dom/NodeRenderingContext.cpp:
* dom/ShadowContentElement.cpp:
(WebCore::ShadowContentElement::ShadowContentElement):
(WebCore::ShadowContentElement::attach):
(WebCore::ShadowContentElement::detach):
* dom/ShadowContentElement.h:
(WebCore::ShadowContentElement::inclusions):
* dom/ShadowContentSelector.cpp:
(WebCore::ShadowInclusion::append):
(WebCore::ShadowInclusion::unlink):
(WebCore::ShadowInclusionList::ShadowInclusionList):
(WebCore::ShadowInclusionList::~ShadowInclusionList):
(WebCore::ShadowInclusionList::find):
(WebCore::ShadowInclusionList::clear):
(WebCore::ShadowInclusionList::append):
(WebCore::ShadowContentSelector::ShadowContentSelector):
(WebCore::ShadowContentSelector::~ShadowContentSelector):
(WebCore::ShadowContentSelector::selectInclusion):
(WebCore::ShadowContentSelector::unselectInclusion):
(WebCore::ShadowContentSelector::findInclusionFor):
(WebCore::ShadowContentSelector::didSelectInclusion):
(WebCore::ShadowContentSelector::willSelectInclusionOver):
* dom/ShadowContentSelector.h:
(WebCore::ShadowInclusion::includer):
(WebCore::ShadowInclusion::content):
(WebCore::ShadowInclusion::next):
(WebCore::ShadowInclusion::previous):
(WebCore::ShadowInclusion::ShadowInclusion):
(WebCore::ShadowInclusion::create):
(WebCore::ShadowInclusionList::first):
(WebCore::ShadowInclusionList::last):
(WebCore::ShadowInclusionList::isEmpty):
(WebCore::ShadowInclusionSet::add):
(WebCore::ShadowInclusionSet::remove):
(WebCore::ShadowInclusionSet::isEmpty):
(WebCore::ShadowInclusionSet::Translator::hash):
(WebCore::ShadowInclusionSet::Translator::equal):
(WebCore::ShadowInclusionSet::Hash::hash):
(WebCore::ShadowInclusionSet::Hash::equal):
(WebCore::ShadowInclusionSet::find):
(WebCore::ShadowContentSelector::hasChildren):
* dom/ShadowRoot.cpp:
(WebCore::ShadowRoot::~ShadowRoot):
(WebCore::ShadowRoot::includerFor):
(WebCore::ShadowRoot::attach):
(WebCore::ShadowRoot::inclusions):
(WebCore::ShadowRoot::ensureInclusions):
* dom/ShadowRoot.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (91452 => 91453)


--- trunk/Source/WebCore/ChangeLog	2011-07-21 09:29:23 UTC (rev 91452)
+++ trunk/Source/WebCore/ChangeLog	2011-07-21 09:39:37 UTC (rev 91453)
@@ -1,3 +1,71 @@
+2011-07-21  MORITA Hajime  <morr...@google.com>
+
+        [Refactoring] Shadow inclusion cache should be managed by ShadowContentSelector
+        https://bugs.webkit.org/show_bug.cgi?id=64849
+
+        Reviewed by Dimitri Glazkov.
+
+        This change is a reorg around Shadow inclusion mechanism.
+        - Moved definition of ShadowInclusion, ShadowInclusionSet and ShadowInclusionList
+          from ShadowContentElement.h to ShadowContentSelector.h, which is included
+          from smaller number of places.
+        - Moved ShadowInclusionSet from ShadowRoot to ShadowContentSelector
+        - Made ShadowContentSelector's lifetime managed by ShadowRoot
+          because ShadowInclusionSet is held by the selector.
+        - Thus, there is no longer "active" selector (ShadowContentSelector::s_currentInstance)
+          Because the selector is associated for each ShadowRoot object.
+        
+        No new tests. No behavior change.
+
+        * dom/NodeRenderingContext.cpp:
+        * dom/ShadowContentElement.cpp:
+        (WebCore::ShadowContentElement::ShadowContentElement):
+        (WebCore::ShadowContentElement::attach):
+        (WebCore::ShadowContentElement::detach):
+        * dom/ShadowContentElement.h:
+        (WebCore::ShadowContentElement::inclusions):
+        * dom/ShadowContentSelector.cpp:
+        (WebCore::ShadowInclusion::append):
+        (WebCore::ShadowInclusion::unlink):
+        (WebCore::ShadowInclusionList::ShadowInclusionList):
+        (WebCore::ShadowInclusionList::~ShadowInclusionList):
+        (WebCore::ShadowInclusionList::find):
+        (WebCore::ShadowInclusionList::clear):
+        (WebCore::ShadowInclusionList::append):
+        (WebCore::ShadowContentSelector::ShadowContentSelector):
+        (WebCore::ShadowContentSelector::~ShadowContentSelector):
+        (WebCore::ShadowContentSelector::selectInclusion):
+        (WebCore::ShadowContentSelector::unselectInclusion):
+        (WebCore::ShadowContentSelector::findInclusionFor):
+        (WebCore::ShadowContentSelector::didSelectInclusion):
+        (WebCore::ShadowContentSelector::willSelectInclusionOver):
+        * dom/ShadowContentSelector.h:
+        (WebCore::ShadowInclusion::includer):
+        (WebCore::ShadowInclusion::content):
+        (WebCore::ShadowInclusion::next):
+        (WebCore::ShadowInclusion::previous):
+        (WebCore::ShadowInclusion::ShadowInclusion):
+        (WebCore::ShadowInclusion::create):
+        (WebCore::ShadowInclusionList::first):
+        (WebCore::ShadowInclusionList::last):
+        (WebCore::ShadowInclusionList::isEmpty):
+        (WebCore::ShadowInclusionSet::add):
+        (WebCore::ShadowInclusionSet::remove):
+        (WebCore::ShadowInclusionSet::isEmpty):
+        (WebCore::ShadowInclusionSet::Translator::hash):
+        (WebCore::ShadowInclusionSet::Translator::equal):
+        (WebCore::ShadowInclusionSet::Hash::hash):
+        (WebCore::ShadowInclusionSet::Hash::equal):
+        (WebCore::ShadowInclusionSet::find):
+        (WebCore::ShadowContentSelector::hasChildren):
+        * dom/ShadowRoot.cpp:
+        (WebCore::ShadowRoot::~ShadowRoot):
+        (WebCore::ShadowRoot::includerFor):
+        (WebCore::ShadowRoot::attach):
+        (WebCore::ShadowRoot::inclusions):
+        (WebCore::ShadowRoot::ensureInclusions):
+        * dom/ShadowRoot.h:
+
 2011-07-21  Rohan McGovern  <ro...@mcgovern.id.au>
 
         Reviewed by Noam Rosenthal.

Modified: trunk/Source/WebCore/dom/NodeRenderingContext.cpp (91452 => 91453)


--- trunk/Source/WebCore/dom/NodeRenderingContext.cpp	2011-07-21 09:29:23 UTC (rev 91452)
+++ trunk/Source/WebCore/dom/NodeRenderingContext.cpp	2011-07-21 09:39:37 UTC (rev 91453)
@@ -31,6 +31,7 @@
 #include "RenderFullScreen.h"
 #include "RenderObject.h"
 #include "ShadowContentElement.h"
+#include "ShadowContentSelector.h"
 #include "ShadowRoot.h"
 
 namespace WebCore {

Modified: trunk/Source/WebCore/dom/ShadowContentElement.cpp (91452 => 91453)


--- trunk/Source/WebCore/dom/ShadowContentElement.cpp	2011-07-21 09:29:23 UTC (rev 91452)
+++ trunk/Source/WebCore/dom/ShadowContentElement.cpp	2011-07-21 09:39:37 UTC (rev 91453)
@@ -33,71 +33,6 @@
 
 namespace WebCore {
 
-void ShadowInclusion::append(PassRefPtr<ShadowInclusion> next)
-{
-    ASSERT(!m_next);
-    ASSERT(!next->previous());
-    m_next = next;
-    m_next->m_previous = this;
-}
-
-void ShadowInclusion::unlink()
-{
-    ASSERT(!m_previous); // Can be called only for a head.
-    RefPtr<ShadowInclusion> item = this;
-    while (item) {
-        ASSERT(!item->previous());
-        RefPtr<ShadowInclusion> nextItem = item->m_next;
-        item->m_next.clear();
-        if (nextItem)
-            nextItem->m_previous.clear();
-        item = nextItem;
-    }
-}
-
-ShadowInclusionList::ShadowInclusionList()
-{
-}
-
-ShadowInclusionList::~ShadowInclusionList()
-{
-    ASSERT(isEmpty());
-}
-
-ShadowInclusion* ShadowInclusionList::find(Node* content) const
-{
-    for (ShadowInclusion* item = first(); item; item = item->next()) {
-        if (content == item->content())
-            return item;
-    }
-    
-    return 0;
-}
-
-void ShadowInclusionList::clear()
-{
-    if (isEmpty()) {
-        ASSERT(!m_last);
-        return;
-    }
-
-    m_first->unlink();
-    m_first.clear();
-    m_last.clear();
-}
-
-void ShadowInclusionList::append(PassRefPtr<ShadowInclusion> child)
-{
-    if (isEmpty()) {
-        ASSERT(!m_last);
-        m_first = m_last = child;
-        return;
-    }
-
-    m_last->append(child);
-    m_last = m_last->next();
-}
-
 PassRefPtr<ShadowContentElement> ShadowContentElement::create(Document* document)
 {
     DEFINE_STATIC_LOCAL(QualifiedName, tagName, (nullAtom, "webkitShadowContent", HTMLNames::divTag.namespaceURI()));
@@ -106,6 +41,7 @@
 
 ShadowContentElement::ShadowContentElement(const QualifiedName& name, Document* document)
     : StyledElement(name, document, CreateHTMLElement)
+    , m_inclusions(adoptPtr(new ShadowInclusionList()))
 {
 }
 
@@ -113,32 +49,18 @@
 {
 }
 
-static void removeFromSet(ShadowInclusionList* list, ShadowInclusionSet* set)
-{
-    for (ShadowInclusion* inclusion = list->first(); inclusion; inclusion = inclusion->next())
-        set->remove(inclusion);
-}
-
-static void addToSet(ShadowInclusionList* list, ShadowInclusionSet* set)
-{
-    for (ShadowInclusion* inclusion = list->first(); inclusion; inclusion = inclusion->next())
-        set->add(inclusion);
-}
-
 void ShadowContentElement::attach()
 {
     ASSERT(!firstChild()); // Currently doesn't support any light child.
     StyledElement::attach();
-    if (ShadowContentSelector* selector = ShadowContentSelector::currentInstance()) {
 
-        removeFromSet(&m_inclusions, selector->shadowRoot()->ensureInclusions());
-        m_inclusions.clear();
-        selector->selectInclusion(this, &m_inclusions);
-        addToSet(&m_inclusions, selector->shadowRoot()->ensureInclusions());
-
-        for (ShadowInclusion* inclusion = m_inclusions.first(); inclusion; inclusion = inclusion->next())
+    if (ShadowRoot* root = toShadowRoot(shadowTreeRootNode())) {
+        ShadowContentSelector* selector = root->ensureInclusions();
+        selector->unselectInclusion(m_inclusions.get());
+        selector->selectInclusion(this, m_inclusions.get());
+        for (ShadowInclusion* inclusion = m_inclusions->first(); inclusion; inclusion = inclusion->next())
             inclusion->content()->detach();
-        for (ShadowInclusion* inclusion = m_inclusions.first(); inclusion; inclusion = inclusion->next())
+        for (ShadowInclusion* inclusion = m_inclusions->first(); inclusion; inclusion = inclusion->next())
             inclusion->content()->attach();
     }
 }
@@ -146,11 +68,11 @@
 void ShadowContentElement::detach()
 {
     if (ShadowRoot* root = toShadowRoot(shadowTreeRootNode())) {
-        removeFromSet(&m_inclusions, root->ensureInclusions());
-        m_inclusions.clear();
+        if (ShadowContentSelector* selector = root->inclusions())
+            selector->unselectInclusion(m_inclusions.get());
     }
 
-    ASSERT(m_inclusions.isEmpty());
+    ASSERT(m_inclusions->isEmpty());
     StyledElement::detach();
 }
 

Modified: trunk/Source/WebCore/dom/ShadowContentElement.h (91452 => 91453)


--- trunk/Source/WebCore/dom/ShadowContentElement.h	2011-07-21 09:29:23 UTC (rev 91452)
+++ trunk/Source/WebCore/dom/ShadowContentElement.h	2011-07-21 09:39:37 UTC (rev 91453)
@@ -33,95 +33,11 @@
 
 #include "StyledElement.h"
 #include <wtf/Forward.h>
-#include <wtf/HashSet.h>
 
 namespace WebCore {
 
-class ShadowContentElement;
+class ShadowInclusionList;
 
-class ShadowInclusion : public RefCounted<ShadowInclusion> {
-public:
-    static PassRefPtr<ShadowInclusion> create(ShadowContentElement*, Node*);
-
-    ShadowContentElement* includer() const { return m_includer; }
-    Node* content() const { return m_content.get(); }
-    ShadowInclusion* next() const { return m_next.get(); }
-    ShadowInclusion* previous() const { return m_previous.get(); }
-
-    void append(PassRefPtr<ShadowInclusion>);
-    void unlink();
-
-private:
-    explicit ShadowInclusion(ShadowContentElement* includer, Node* content)
-        : m_includer(includer), m_content(content)
-    { }
-
-    ShadowContentElement* m_includer;
-    RefPtr<Node> m_content;
-    RefPtr<ShadowInclusion> m_next;
-    RefPtr<ShadowInclusion> m_previous;
-};
-
-inline PassRefPtr<ShadowInclusion> ShadowInclusion::create(ShadowContentElement* includer, Node* content)
-{
-    return adoptRef(new ShadowInclusion(includer, content));
-}
-
-class ShadowInclusionList {
-public:
-    ShadowInclusionList();
-    ~ShadowInclusionList();
-
-    ShadowInclusion* first() const { return m_first.get(); }
-    ShadowInclusion* last() const { return m_last.get(); }
-    ShadowInclusion* find(Node*) const;
-    bool isEmpty() const { return !m_first; }
-
-    void clear();
-    void append(PassRefPtr<ShadowInclusion>);
-    void append(ShadowContentElement*, Node*);
-
-private:
-    RefPtr<ShadowInclusion> m_first;
-    RefPtr<ShadowInclusion> m_last;
-};
-
-inline void ShadowInclusionList::append(ShadowContentElement* includer, Node* node)
-{
-    append(ShadowInclusion::create(includer, node));
-}
-
-class ShadowInclusionSet {
-public:
-    void add(ShadowInclusion* value) { m_set.add(value); }
-    void remove(ShadowInclusion* value) { m_set.remove(value); }
-    bool isEmpty() const { return m_set.isEmpty(); }
-    ShadowInclusion* find(Node* key) const;
-
-private:
-    struct Translator {
-    public:
-        static unsigned hash(const Node* key) { return PtrHash<const Node*>::hash(key); }
-        static bool equal(const ShadowInclusion* inclusion, const Node* content) { return inclusion->content() == content; }
-    };
-
-    struct Hash {
-        static unsigned hash(ShadowInclusion* key) { return PtrHash<const Node*>::hash(key->content()); }
-        static bool equal(ShadowInclusion* a, ShadowInclusion* b) { return a->content() == b->content(); }
-        static const bool safeToCompareToEmptyOrDeleted = false;
-    };
-
-    typedef HashSet<ShadowInclusion*, Hash> PointerSet;
-
-    PointerSet m_set;
-};
-
-inline ShadowInclusion* ShadowInclusionSet::find(Node* key) const
-{
-    PointerSet::iterator found = m_set.find<Node*, ShadowInclusionSet::Translator>(key);
-    return found != m_set.end() ? *found : 0;
-}
-
 // NOTE: Current implementation doesn't support dynamic insertion/deletion of ShadowContentElement.
 // You should create ShadowContentElement during the host construction.
 class ShadowContentElement : public StyledElement {
@@ -133,7 +49,7 @@
     virtual void attach();
     virtual void detach();
 
-    const ShadowInclusionList* inclusions() const { return &m_inclusions; }
+    const ShadowInclusionList* inclusions() const { return m_inclusions.get(); }
 
 protected:
     ShadowContentElement(const QualifiedName&, Document*);
@@ -143,7 +59,7 @@
     virtual bool rendererIsNeeded(const NodeRenderingContext&) { return false; }
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*) { return 0; }
 
-    ShadowInclusionList m_inclusions;
+    OwnPtr<ShadowInclusionList> m_inclusions;
 };
 
 inline ShadowContentElement* toShadowContentElement(Node* node)

Modified: trunk/Source/WebCore/dom/ShadowContentSelector.cpp (91452 => 91453)


--- trunk/Source/WebCore/dom/ShadowContentSelector.cpp	2011-07-21 09:29:23 UTC (rev 91452)
+++ trunk/Source/WebCore/dom/ShadowContentSelector.cpp	2011-07-21 09:39:37 UTC (rev 91453)
@@ -33,21 +33,78 @@
 
 namespace WebCore {
 
-ShadowContentSelector* ShadowContentSelector::s_currentInstance = 0;
+void ShadowInclusion::append(PassRefPtr<ShadowInclusion> next)
+{
+    ASSERT(!m_next);
+    ASSERT(!next->previous());
+    m_next = next;
+    m_next->m_previous = this;
+}
 
-ShadowContentSelector::ShadowContentSelector(ShadowRoot* shadowRoot)
-    : m_parent(s_currentInstance)
-    , m_shadowRoot(shadowRoot)
+void ShadowInclusion::unlink()
 {
-    s_currentInstance = this;
-    for (Node* node = shadowRoot->shadowHost()->firstChild(); node; node = node->nextSibling())
-        m_children.append(node);
+    ASSERT(!m_previous); // Can be called only for a head.
+    RefPtr<ShadowInclusion> item = this;
+    while (item) {
+        ASSERT(!item->previous());
+        RefPtr<ShadowInclusion> nextItem = item->m_next;
+        item->m_next.clear();
+        if (nextItem)
+            nextItem->m_previous.clear();
+        item = nextItem;
+    }
 }
 
+ShadowInclusionList::ShadowInclusionList()
+{
+}
+
+ShadowInclusionList::~ShadowInclusionList()
+{
+    ASSERT(isEmpty());
+}
+
+ShadowInclusion* ShadowInclusionList::find(Node* content) const
+{
+    for (ShadowInclusion* item = first(); item; item = item->next()) {
+        if (content == item->content())
+            return item;
+    }
+    
+    return 0;
+}
+
+void ShadowInclusionList::clear()
+{
+    if (isEmpty()) {
+        ASSERT(!m_last);
+        return;
+    }
+
+    m_first->unlink();
+    m_first.clear();
+    m_last.clear();
+}
+
+void ShadowInclusionList::append(PassRefPtr<ShadowInclusion> child)
+{
+    if (isEmpty()) {
+        ASSERT(!m_last);
+        m_first = m_last = child;
+        return;
+    }
+
+    m_last->append(child);
+    m_last = m_last->next();
+}
+
+ShadowContentSelector::ShadowContentSelector()
+{
+}
+
 ShadowContentSelector::~ShadowContentSelector()
 {
-    ASSERT(s_currentInstance == this);
-    s_currentInstance = m_parent;
+    ASSERT(m_children.isEmpty());
 }
 
 void ShadowContentSelector::selectInclusion(ShadowContentElement* contentElement, ShadowInclusionList* inclusions)
@@ -61,9 +118,36 @@
         if (!contentElement->shouldInclude(child))
             continue;
 
-        inclusions->append(contentElement, child);
+        RefPtr<ShadowInclusion> inclusion = ShadowInclusion::create(contentElement, child);
+        inclusions->append(inclusion);
+        m_inclusionSet.add(inclusion.get());
         m_children[i] = 0;
     }
 }
 
+void ShadowContentSelector::unselectInclusion(ShadowInclusionList* list)
+{
+    for (ShadowInclusion* inclusion = list->first(); inclusion; inclusion = inclusion->next())
+        m_inclusionSet.remove(inclusion);
+    list->clear();
 }
+
+ShadowInclusion* ShadowContentSelector::findInclusionFor(Node* key) const
+{
+    return m_inclusionSet.find(key);
+}
+
+void ShadowContentSelector::didSelectInclusion()
+{
+    m_children.clear();
+}
+
+void ShadowContentSelector::willSelectInclusionOver(ShadowRoot* scope)
+{
+    if (!m_children.isEmpty())
+        return;
+    for (Node* node = scope->shadowHost()->firstChild(); node; node = node->nextSibling())
+        m_children.append(node);
+}
+
+}

Modified: trunk/Source/WebCore/dom/ShadowContentSelector.h (91452 => 91453)


--- trunk/Source/WebCore/dom/ShadowContentSelector.h	2011-07-21 09:29:23 UTC (rev 91452)
+++ trunk/Source/WebCore/dom/ShadowContentSelector.h	2011-07-21 09:39:37 UTC (rev 91453)
@@ -32,6 +32,8 @@
 #define ShadowContentSelector_h
 
 #include <wtf/Forward.h>
+#include <wtf/HashSet.h>
+#include <wtf/RefCounted.h>
 #include <wtf/Vector.h>
 
 namespace WebCore {
@@ -39,27 +41,109 @@
 class Element;
 class Node;
 class ShadowRoot;
-class ShadowInclusionList;
 class ShadowContentElement;
-class RenderObject;
 
+class ShadowInclusion : public RefCounted<ShadowInclusion> {
+public:
+    static PassRefPtr<ShadowInclusion> create(ShadowContentElement*, Node*);
+
+    ShadowContentElement* includer() const { return m_includer; }
+    Node* content() const { return m_content.get(); }
+    ShadowInclusion* next() const { return m_next.get(); }
+    ShadowInclusion* previous() const { return m_previous.get(); }
+
+    void append(PassRefPtr<ShadowInclusion>);
+    void unlink();
+
+private:
+    ShadowInclusion(ShadowContentElement*, Node*);
+
+    ShadowContentElement* m_includer;
+    RefPtr<Node> m_content;
+    RefPtr<ShadowInclusion> m_next;
+    RefPtr<ShadowInclusion> m_previous;
+};
+
+inline ShadowInclusion::ShadowInclusion(ShadowContentElement* includer, Node* content)
+    : m_includer(includer), m_content(content)
+{ }
+
+inline PassRefPtr<ShadowInclusion> ShadowInclusion::create(ShadowContentElement* includer, Node* content)
+{
+    return adoptRef(new ShadowInclusion(includer, content));
+}
+
+class ShadowInclusionList {
+public:
+    ShadowInclusionList();
+    ~ShadowInclusionList();
+
+    ShadowInclusion* first() const { return m_first.get(); }
+    ShadowInclusion* last() const { return m_last.get(); }
+    ShadowInclusion* find(Node*) const;
+    bool isEmpty() const { return !m_first; }
+
+    void clear();
+    void append(PassRefPtr<ShadowInclusion>);
+
+private:
+    RefPtr<ShadowInclusion> m_first;
+    RefPtr<ShadowInclusion> m_last;
+};
+
+
+class ShadowInclusionSet {
+public:
+    void add(ShadowInclusion* value) { m_set.add(value); }
+    void remove(ShadowInclusion* value) { m_set.remove(value); }
+    bool isEmpty() const { return m_set.isEmpty(); }
+    ShadowInclusion* find(Node* key) const;
+
+private:
+    struct Translator {
+    public:
+        static unsigned hash(const Node* key) { return PtrHash<const Node*>::hash(key); }
+        static bool equal(const ShadowInclusion* inclusion, const Node* content) { return inclusion->content() == content; }
+    };
+
+    struct Hash {
+        static unsigned hash(ShadowInclusion* key) { return PtrHash<const Node*>::hash(key->content()); }
+        static bool equal(ShadowInclusion* a, ShadowInclusion* b) { return a->content() == b->content(); }
+        static const bool safeToCompareToEmptyOrDeleted = false;
+    };
+
+    typedef HashSet<ShadowInclusion*, Hash> PointerSet;
+
+    PointerSet m_set;
+};
+
+inline ShadowInclusion* ShadowInclusionSet::find(Node* key) const
+{
+    PointerSet::iterator found = m_set.find<Node*, ShadowInclusionSet::Translator>(key);
+    return found != m_set.end() ? *found : 0;
+}
+
 class ShadowContentSelector {
     WTF_MAKE_NONCOPYABLE(ShadowContentSelector);
 public:
-    explicit ShadowContentSelector(ShadowRoot*);
+    ShadowContentSelector();
     ~ShadowContentSelector();
 
     void selectInclusion(ShadowContentElement*, ShadowInclusionList*);
+    void unselectInclusion(ShadowInclusionList*);
+    ShadowInclusion* findInclusionFor(Node* key) const;
 
-    ShadowRoot* shadowRoot() const { return m_shadowRoot; }
-    static ShadowContentSelector* currentInstance() { return s_currentInstance; }
+    void willSelectInclusionOver(ShadowRoot*);
+    void didSelectInclusion();
+    bool hasChildren() const { return !m_children.isEmpty(); }
 
+
 private:
-    ShadowContentSelector* m_parent;
-    ShadowRoot* m_shadowRoot;
+    void removeFromSet(ShadowInclusionList*);
+    void addToSet(ShadowInclusionList*);
+
     Vector<RefPtr<Node> > m_children;
-
-    static ShadowContentSelector* s_currentInstance;
+    ShadowInclusionSet m_inclusionSet;
 };
 
 }

Modified: trunk/Source/WebCore/dom/ShadowRoot.cpp (91452 => 91453)


--- trunk/Source/WebCore/dom/ShadowRoot.cpp	2011-07-21 09:29:23 UTC (rev 91452)
+++ trunk/Source/WebCore/dom/ShadowRoot.cpp	2011-07-21 09:39:37 UTC (rev 91453)
@@ -50,7 +50,6 @@
 
 ShadowRoot::~ShadowRoot()
 {
-    ASSERT(!m_inclusions || m_inclusions->isEmpty());
 }
 
 String ShadowRoot::nodeName() const
@@ -101,7 +100,7 @@
 {
     if (!m_inclusions)
         return 0;
-    ShadowInclusion* found = m_inclusions->find(node);
+    ShadowInclusion* found = m_inclusions->findInclusionFor(node);
     if (!found)
         return 0;
     return found->includer();
@@ -137,19 +136,25 @@
 
 void ShadowRoot::attach()
 {
-    ShadowContentSelector selector(this);
+    // Children of m_inclusions is populated lazily in
+    // ensureInclusions(), and here we just ensure that
+    // it is in clean state.
+    ASSERT(!m_inclusions || !m_inclusions->hasChildren());
     TreeScope::attach();
+    if (m_inclusions)
+        m_inclusions->didSelectInclusion();
 }
 
-ShadowInclusionSet* ShadowRoot::inclusions() const
+ShadowContentSelector* ShadowRoot::inclusions() const
 {
     return m_inclusions.get();
 }
 
-ShadowInclusionSet* ShadowRoot::ensureInclusions()
+ShadowContentSelector* ShadowRoot::ensureInclusions()
 {
     if (!m_inclusions)
-        m_inclusions = adoptPtr(new ShadowInclusionSet());
+        m_inclusions = adoptPtr(new ShadowContentSelector());
+    m_inclusions->willSelectInclusionOver(this);
     return m_inclusions.get();
 }
 

Modified: trunk/Source/WebCore/dom/ShadowRoot.h (91452 => 91453)


--- trunk/Source/WebCore/dom/ShadowRoot.h	2011-07-21 09:29:23 UTC (rev 91452)
+++ trunk/Source/WebCore/dom/ShadowRoot.h	2011-07-21 09:39:37 UTC (rev 91453)
@@ -33,7 +33,7 @@
 
 class Document;
 class ShadowContentElement;
-class ShadowInclusionSet;
+class ShadowContentSelector;
 
 class ShadowRoot : public TreeScope {
 public:
@@ -49,8 +49,8 @@
     virtual bool applyAuthorSheets() const;
     void setApplyAuthorSheets(bool);
 
-    ShadowInclusionSet* inclusions() const;
-    ShadowInclusionSet* ensureInclusions();
+    ShadowContentSelector* inclusions() const;
+    ShadowContentSelector* ensureInclusions();
 
 private:
     ShadowRoot(Document*);
@@ -64,7 +64,7 @@
     bool hasContentElement() const;
 
     bool m_applyAuthorSheets;
-    OwnPtr<ShadowInclusionSet> m_inclusions;
+    OwnPtr<ShadowContentSelector> m_inclusions;
 };
 
 inline PassRefPtr<ShadowRoot> ShadowRoot::create(Document* document)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to