.: [ShadowContentElement] forwarded node should be able to access its hosting content...
authormorrita@google.com <morrita@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 19 Jul 2011 02:55:22 +0000 (02:55 +0000)
committermorrita@google.com <morrita@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 19 Jul 2011 02:55:22 +0000 (02:55 +0000)
https://bugs.webkit.org/show_bug.cgi?id=64251

Reviewed by Dimitri Glazkov.

Added GTK symbols for new window.internals methods.

* Source/autotools/symbols.filter:

Source/WebCore: [ShadowContentElement] forwarded node should be able to access its hosting content element.
https://bugs.webkit.org/show_bug.cgi?id=64251

Reviewed by Dimitri Glazkov.

- Introduced ShadowInclusionSet to manage included nodes to its includer content element.
  ShadowInclusionSet instance is owned by ShadowRoot.
- Updated the set on inclusion list changes.
- Used the set to retrieve the content element of NodeRenderingContext.

There are also related refactoring and cleanup:
- Renamed NodeRenderingContext::m_contentElement to m_includer
- ShadowContentSelector::m_activeElement is no longer used, thus removed.

Test: fast/dom/shadow/content-element-includer.html

* WebCore.exp.in:
* dom/NodeRenderingContext.cpp:
(WebCore::NodeRenderingContext::NodeRenderingContext):
(WebCore::NodeRenderingContext::nextRenderer):
(WebCore::NodeRenderingContext::previousRenderer):
* dom/NodeRenderingContext.h:
(WebCore::NodeRenderingContext::includer):
* dom/ShadowContentElement.cpp:
(WebCore::removeFromSet):
(WebCore::addToSet):
(WebCore::ShadowContentElement::attach):
(WebCore::ShadowContentElement::detach):
* dom/ShadowContentElement.h:
(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):
* dom/ShadowContentSelector.cpp:
(WebCore::ShadowContentSelector::ShadowContentSelector):
(WebCore::ShadowContentSelector::selectInclusion):
* dom/ShadowContentSelector.h:
* dom/ShadowRoot.cpp:
(WebCore::ShadowRoot::~ShadowRoot):
(WebCore::ShadowRoot::includerFor):
(WebCore::ShadowRoot::inclusions):
(WebCore::ShadowRoot::ensureInclusions):
* dom/ShadowRoot.h:
(WebCore::toShadowRoot):
* testing/Internals.cpp:
(WebCore::Internals::includerFor):
* testing/Internals.h:
* testing/Internals.idl:

Source/WebKit2: [ShadowContentElement] forwarded node should be able to access its hosting content element.
https://bugs.webkit.org/show_bug.cgi?id=64251

Reviewed by Dimitri Glazkov.

Exported additional symbols for window.internals object.

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

LayoutTests: [ShadowContentElement] forwarded node should be able to access its hosting content element.
https://bugs.webkit.org/show_bug.cgi?id=64251

Reviewed by Dimitri Glazkov.

- Added a new test.
- Updated expectations. This change make ShadowContentElement availability on NodeRenderingContext
  more strict. that makes some redundant node disappeared.

* fast/dom/shadow/content-element-includer-expected.txt: Added.
* fast/dom/shadow/content-element-includer.html: Added.
* platform/chromium-win/fast/html/details-nested-2-expected.txt:
* platform/gtk/fast/html/details-nested-2-expected.txt:
* platform/mac/fast/html/details-nested-2-expected.txt:
* platform/qt/fast/html/details-nested-2-expected.txt:

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

25 files changed:
ChangeLog
LayoutTests/ChangeLog
LayoutTests/fast/dom/shadow/content-element-includer-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/shadow/content-element-includer.html [new file with mode: 0644]
LayoutTests/platform/chromium-win/fast/html/details-nested-2-expected.txt
LayoutTests/platform/gtk/fast/html/details-nested-2-expected.txt
LayoutTests/platform/mac/fast/html/details-nested-2-expected.txt
LayoutTests/platform/qt/fast/html/details-nested-2-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/WebCore.exp.in
Source/WebCore/dom/NodeRenderingContext.cpp
Source/WebCore/dom/NodeRenderingContext.h
Source/WebCore/dom/ShadowContentElement.cpp
Source/WebCore/dom/ShadowContentElement.h
Source/WebCore/dom/ShadowContentSelector.cpp
Source/WebCore/dom/ShadowContentSelector.h
Source/WebCore/dom/ShadowRoot.cpp
Source/WebCore/dom/ShadowRoot.h
Source/WebCore/testing/Internals.cpp
Source/WebCore/testing/Internals.h
Source/WebCore/testing/Internals.idl
Source/WebKit2/ChangeLog
Source/WebKit2/win/WebKit2.def
Source/WebKit2/win/WebKit2CFLite.def
Source/autotools/symbols.filter

index 09832db..7d8b3e5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2011-07-18  MORITA Hajime  <morrita@google.com>
+
+        [ShadowContentElement] forwarded node should be able to access its hosting content element.
+        https://bugs.webkit.org/show_bug.cgi?id=64251
+
+        Reviewed by Dimitri Glazkov.
+
+        Added GTK symbols for new window.internals methods.
+        
+        * Source/autotools/symbols.filter:
+
 2011-07-15  Martin Robinson  <mrobinson@igalia.com>
 
         Build fixes for WebKit2. Ensure that all generated sources are
index 2a93618..cca7c91 100644 (file)
@@ -1,3 +1,21 @@
+2011-07-18  MORITA Hajime  <morrita@google.com>
+
+        [ShadowContentElement] forwarded node should be able to access its hosting content element.
+        https://bugs.webkit.org/show_bug.cgi?id=64251
+
+        Reviewed by Dimitri Glazkov.
+
+        - Added a new test.
+        - Updated expectations. This change make ShadowContentElement availability on NodeRenderingContext
+          more strict. that makes some redundant node disappeared.
+
+        * fast/dom/shadow/content-element-includer-expected.txt: Added.
+        * fast/dom/shadow/content-element-includer.html: Added.
+        * platform/chromium-win/fast/html/details-nested-2-expected.txt:
+        * platform/gtk/fast/html/details-nested-2-expected.txt:
+        * platform/mac/fast/html/details-nested-2-expected.txt:
+        * platform/qt/fast/html/details-nested-2-expected.txt:
+
 2011-07-18  Ryosuke Niwa  <rniwa@webkit.org>
 
         Add a failing test expectation for object-prototype-properties.html after r91225.
diff --git a/LayoutTests/fast/dom/shadow/content-element-includer-expected.txt b/LayoutTests/fast/dom/shadow/content-element-includer-expected.txt
new file mode 100644 (file)
index 0000000..c0eb073
--- /dev/null
@@ -0,0 +1,12 @@
+This tests the correctness of includers of forwarded children.
+Note that this test needs internals object thus cannot run outside DRT.
+PASS internals.includerFor(childOfElementWithoutShadow) is null
+PASS internals.includerFor(childOfElementWithShadow) is null
+PASS internals.includerFor(childOfElementWithShadowContent) is shadowContentOfElementWithShadowContent
+PASS internals.includerFor(movingChild) is null
+PASS internals.includerFor(movingChild) is null
+PASS internals.includerFor(movingChild) is anotherShadowContentOfElementWithShadowContent
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/dom/shadow/content-element-includer.html b/LayoutTests/fast/dom/shadow/content-element-includer.html
new file mode 100644 (file)
index 0000000..e2573b9
--- /dev/null
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../js/resources/js-test-pre.js"></script>
+</head>
+<body>
+<pre id="console">
+This tests the correctness of includers of forwarded children.
+Note that this test needs internals object thus cannot run outside DRT.
+</pre>
+<div id="container"></div>
+<script>
+var container = document.getElementById("container");
+
+var shadowRoot = null;
+
+var elementWithoutShadow = document.createElement("div");
+container.appendChild(elementWithoutShadow);
+var childOfElementWithoutShadow = document.createElement("span");
+elementWithoutShadow.appendChild(childOfElementWithoutShadow);
+container.offsetLeft;
+shouldBe("internals.includerFor(childOfElementWithoutShadow)", "null");
+
+var elementWithShadow = document.createElement("div");
+container.appendChild(elementWithShadow);
+var shadowRootOfElementWithShadow = internals.ensureShadowRoot(elementWithShadow);
+shadowRootOfElementWithShadow.appendChild(document.createElement("div")); // Gives non-content child. 
+var childOfElementWithShadow = document.createElement("span");
+elementWithShadow.appendChild(childOfElementWithShadow);
+container.offsetLeft;
+shouldBe("internals.includerFor(childOfElementWithShadow)", "null");
+
+var elementWithShadowContent = document.createElement("div");
+container.appendChild(elementWithShadowContent);
+var shadowRootOfElementWithShadowContent = internals.ensureShadowRoot(elementWithShadowContent);
+var shadowContentOfElementWithShadowContent = internals.createShadowContentElement(document);
+shadowRootOfElementWithShadowContent.appendChild(shadowContentOfElementWithShadowContent);
+var childOfElementWithShadowContent = document.createElement("span");
+elementWithShadowContent.appendChild(childOfElementWithShadowContent);
+container.offsetLeft;
+shouldBe("internals.includerFor(childOfElementWithShadowContent)", "shadowContentOfElementWithShadowContent");
+
+//
+// Testing dynamic change
+//
+var movingChild = childOfElementWithShadowContent;
+
+// Removing
+elementWithShadowContent.removeChild(movingChild);
+shouldBe("internals.includerFor(movingChild)", "null");
+
+// Moving to content-less tree
+elementWithShadow.appendChild(movingChild);
+shouldBe("internals.includerFor(movingChild)", "null");
+elementWithShadow.removeChild(movingChild);
+
+// Moving to another content-full tree
+var anotherElementWithShadowContent = document.createElement("div");
+container.appendChild(anotherElementWithShadowContent);
+var anotherShadowRootOfElementWithShadowContent = internals.ensureShadowRoot(anotherElementWithShadowContent);
+var anotherShadowContentOfElementWithShadowContent = internals.createShadowContentElement(document);
+anotherShadowRootOfElementWithShadowContent.appendChild(anotherShadowContentOfElementWithShadowContent);
+
+anotherElementWithShadowContent.appendChild(movingChild);
+container.offsetLeft;
+shouldBe("internals.includerFor(movingChild)", "anotherShadowContentOfElementWithShadowContent");
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/resources/js-test-post.js"></script>
+</body>
+</html>
index b11888f..1d9ff83 100644 (file)
@@ -9,7 +9,6 @@ layer at (0,0) size 800x600
           RenderText {#text} at (24,8) size 58x19
             text run at (24,8) width 4: " "
             text run at (28,8) width 54: "summary"
-        RenderBlock (anonymous) at (8,44) size 768x0
         RenderDetails {DETAILS} at (8,44) size 768x72 [border: (8px solid #995555)]
           RenderSummary {SUMMARY} at (8,8) size 752x36 [border: (8px solid #CC9999)]
             RenderDetailsMarker {DIV} at (8,13) size 10x10: down
index 11e97c9..730d49b 100644 (file)
@@ -9,7 +9,6 @@ layer at (0,0) size 800x600
           RenderText {#text} at (24,8) size 62x19
             text run at (24,8) width 4: " "
             text run at (28,8) width 58: "summary"
-        RenderBlock (anonymous) at (8,43) size 768x0
         RenderDetails {DETAILS} at (8,43) size 768x70 [border: (8px solid #995555)]
           RenderSummary {SUMMARY} at (8,8) size 752x35 [border: (8px solid #CC9999)]
             RenderDetailsMarker {DIV} at (8,13) size 10x10: down
index 35c80d8..74d8f0f 100644 (file)
@@ -9,7 +9,6 @@ layer at (0,0) size 800x600
           RenderText {#text} at (24,8) size 62x18
             text run at (24,8) width 4: " "
             text run at (28,8) width 58: "summary"
-        RenderBlock (anonymous) at (8,42) size 768x0
         RenderDetails {DETAILS} at (8,42) size 768x68 [border: (8px solid #995555)]
           RenderSummary {SUMMARY} at (8,8) size 752x34 [border: (8px solid #CC9999)]
             RenderDetailsMarker {DIV} at (8,12) size 10x10: down
index 5af2592..76b71cf 100644 (file)
@@ -9,7 +9,6 @@ layer at (0,0) size 800x600
           RenderText {#text} at (24,8) size 68x22
             text run at (24,8) width 4: " "
             text run at (28,8) width 64: "summary"
-        RenderBlock (anonymous) at (8,46) size 768x0
         RenderDetails {DETAILS} at (8,46) size 768x76 [border: (8px solid #995555)]
           RenderSummary {SUMMARY} at (8,8) size 752x38 [border: (8px solid #CC9999)]
             RenderDetailsMarker {DIV} at (8,14) size 10x10: down
index a58d820..3f76ecc 100644 (file)
@@ -1,3 +1,58 @@
+2011-07-18  MORITA Hajime  <morrita@google.com>
+
+        [ShadowContentElement] forwarded node should be able to access its hosting content element.
+        https://bugs.webkit.org/show_bug.cgi?id=64251
+        
+        Reviewed by Dimitri Glazkov.
+
+        - Introduced ShadowInclusionSet to manage included nodes to its includer content element.
+          ShadowInclusionSet instance is owned by ShadowRoot.
+        - Updated the set on inclusion list changes.
+        - Used the set to retrieve the content element of NodeRenderingContext.
+        
+        There are also related refactoring and cleanup:
+        - Renamed NodeRenderingContext::m_contentElement to m_includer
+        - ShadowContentSelector::m_activeElement is no longer used, thus removed.
+        
+        Test: fast/dom/shadow/content-element-includer.html
+
+        * WebCore.exp.in:
+        * dom/NodeRenderingContext.cpp:
+        (WebCore::NodeRenderingContext::NodeRenderingContext):
+        (WebCore::NodeRenderingContext::nextRenderer):
+        (WebCore::NodeRenderingContext::previousRenderer):
+        * dom/NodeRenderingContext.h:
+        (WebCore::NodeRenderingContext::includer):
+        * dom/ShadowContentElement.cpp:
+        (WebCore::removeFromSet):
+        (WebCore::addToSet):
+        (WebCore::ShadowContentElement::attach):
+        (WebCore::ShadowContentElement::detach):
+        * dom/ShadowContentElement.h:
+        (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):
+        * dom/ShadowContentSelector.cpp:
+        (WebCore::ShadowContentSelector::ShadowContentSelector):
+        (WebCore::ShadowContentSelector::selectInclusion):
+        * dom/ShadowContentSelector.h:
+        * dom/ShadowRoot.cpp:
+        (WebCore::ShadowRoot::~ShadowRoot):
+        (WebCore::ShadowRoot::includerFor):
+        (WebCore::ShadowRoot::inclusions):
+        (WebCore::ShadowRoot::ensureInclusions):
+        * dom/ShadowRoot.h:
+        (WebCore::toShadowRoot):
+        * testing/Internals.cpp:
+        (WebCore::Internals::includerFor):
+        * testing/Internals.h:
+        * testing/Internals.idl:
+
 2011-07-18  Dean Jackson  <dino@apple.com>
 
         https://bugs.webkit.org/show_bug.cgi?id=64742
index 7d05917..d177308 100644 (file)
@@ -541,6 +541,8 @@ __ZN7WebCore19TextResourceDecoder6decodeEPKcm
 __ZN7WebCore19TextResourceDecoderC1ERKN3WTF6StringERKNS_12TextEncodingEb
 __ZN7WebCore19TextResourceDecoderD1Ev
 __ZN7WebCore19applicationIsSafariEv
+__ZN7WebCore20NodeRenderingContextC1EPNS_4NodeE
+__ZN7WebCore20NodeRenderingContextD1Ev
 __ZN7WebCore20RenderEmbeddedObject30setShowsCrashedPluginIndicatorEv
 __ZN7WebCore20ResourceResponseBase24setExpectedContentLengthEx
 __ZN7WebCore20ResourceResponseBaseC2Ev
index 507399f..3a172d0 100644 (file)
@@ -41,7 +41,7 @@ NodeRenderingContext::NodeRenderingContext(Node* node)
     , m_node(node)
     , m_parentNodeForRenderingAndStyle(0)
     , m_visualParentShadowRoot(0)
-    , m_contentElement(0)
+    , m_includer(0)
     , m_style(0)
 {
     ContainerNode* parent = m_node->parentOrHostNode();
@@ -60,9 +60,9 @@ NodeRenderingContext::NodeRenderingContext(Node* node)
         m_visualParentShadowRoot = toElement(parent)->shadowRoot();
 
         if (m_visualParentShadowRoot) {
-            if ((m_contentElement = m_visualParentShadowRoot->activeContentElement())) {
+            if ((m_includer = m_visualParentShadowRoot->includerFor(m_node))) {
                 m_phase = AttachContentForwarded;
-                m_parentNodeForRenderingAndStyle = NodeRenderingContext(m_contentElement).parentNodeForRenderingAndStyle();
+                m_parentNodeForRenderingAndStyle = NodeRenderingContext(m_includer).parentNodeForRenderingAndStyle();
                 return;
             } 
                 
@@ -81,7 +81,7 @@ NodeRenderingContext::NodeRenderingContext(Node* node, RenderStyle* style)
     , m_node(node)
     , m_parentNodeForRenderingAndStyle(0)
     , m_visualParentShadowRoot(0)
-    , m_contentElement(0)
+    , m_includer(0)
     , m_style(style)
 {
 }
@@ -155,9 +155,9 @@ RenderObject* NodeRenderingContext::nextRenderer() const
         return renderer->nextSibling();
 
     if (m_phase == AttachContentForwarded) {
-        if (RenderObject* found = nextRendererOf(m_contentElement, m_node))
+        if (RenderObject* found = nextRendererOf(m_includer, m_node))
             return found;
-        return NodeRenderingContext(m_contentElement).nextRenderer();
+        return NodeRenderingContext(m_includer).nextRenderer();
     }
 
     // Avoid an O(n^2) problem with this function by not checking for
@@ -184,9 +184,9 @@ RenderObject* NodeRenderingContext::previousRenderer() const
         return renderer->previousSibling();
 
     if (m_phase == AttachContentForwarded) {
-        if (RenderObject* found = previousRendererOf(m_contentElement, m_node))
+        if (RenderObject* found = previousRendererOf(m_includer, m_node))
             return found;
-        return NodeRenderingContext(m_contentElement).previousRenderer();
+        return NodeRenderingContext(m_includer).previousRenderer();
     }
 
     // FIXME: We should have the same O(N^2) avoidance as nextRenderer does
index 95775f0..9a623e4 100644 (file)
@@ -50,6 +50,7 @@ public:
     RenderObject* parentRenderer() const;
     RenderObject* nextRenderer() const;
     RenderObject* previousRenderer() const;
+    ShadowContentElement* includer() const;
 
     RenderStyle* style() const;
     void setStyle(PassRefPtr<RenderStyle>);
@@ -79,7 +80,7 @@ private:
     Node* m_node;
     ContainerNode* m_parentNodeForRenderingAndStyle;
     ShadowRoot* m_visualParentShadowRoot;
-    ShadowContentElement* m_contentElement;
+    ShadowContentElement* m_includer;
     RefPtr<RenderStyle> m_style;
 };
 
@@ -99,6 +100,11 @@ inline RenderStyle* NodeRenderingContext::style() const
     return m_style.get();
 }
 
+inline ShadowContentElement* NodeRenderingContext::includer() const
+{
+    return m_includer;
+}
+
 class NodeRendererFactory {
     WTF_MAKE_NONCOPYABLE(NodeRendererFactory);
     WTF_MAKE_FAST_ALLOCATED;
index 6d7e747..c3c1918 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "HTMLNames.h"
 #include "ShadowContentSelector.h"
+#include "ShadowRoot.h"
 
 namespace WebCore {
 
@@ -97,7 +98,6 @@ void ShadowInclusionList::append(PassRefPtr<ShadowInclusion> child)
     m_last = m_last->next();
 }
 
-
 PassRefPtr<ShadowContentElement> ShadowContentElement::create(Document* document)
 {
     DEFINE_STATIC_LOCAL(QualifiedName, tagName, (nullAtom, "webkitShadowContent", HTMLNames::divTag.namespaceURI()));
@@ -113,24 +113,44 @@ ShadowContentElement::~ShadowContentElement()
 {
 }
 
+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()) {
-        selector->willAttachContentFor(this);
-        selector->selectInclusion(&m_inclusions);
+
+        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())
             inclusion->content()->detach();
         for (ShadowInclusion* inclusion = m_inclusions.first(); inclusion; inclusion = inclusion->next())
             inclusion->content()->attach();
-        selector->didAttachContent();
     }
 }
 
 void ShadowContentElement::detach()
 {
-    m_inclusions.clear();
+    if (ShadowRoot* root = toShadowRoot(shadowTreeRootNode())) {
+        removeFromSet(&m_inclusions, root->ensureInclusions());
+        m_inclusions.clear();
+    }
+
+    ASSERT(m_inclusions.isEmpty());
     StyledElement::detach();
 }
 
index 5d6b0c3..bda482b 100644 (file)
@@ -33,6 +33,7 @@
 
 #include "StyledElement.h"
 #include <wtf/Forward.h>
+#include <wtf/HashSet.h>
 
 namespace WebCore {
 
@@ -66,7 +67,6 @@ inline PassRefPtr<ShadowInclusion> ShadowInclusion::create(ShadowContentElement*
     return adoptRef(new ShadowInclusion(includer, content));
 }
 
-
 class ShadowInclusionList {
 public:
     ShadowInclusionList();
@@ -91,6 +91,36 @@ inline void ShadowInclusionList::append(ShadowContentElement* includer, Node* no
     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.
index 016a447..b08fc75 100644 (file)
@@ -38,7 +38,6 @@ ShadowContentSelector* ShadowContentSelector::s_currentInstance = 0;
 ShadowContentSelector::ShadowContentSelector(ShadowRoot* shadowRoot)
     : m_parent(s_currentInstance)
     , m_shadowRoot(shadowRoot)
-    , m_activeElement(0)
 {
     s_currentInstance = this;
     for (Node* node = shadowRoot->shadowHost()->firstChild(); node; node = node->nextSibling())
@@ -51,38 +50,20 @@ ShadowContentSelector::~ShadowContentSelector()
     s_currentInstance = m_parent;
 }
 
-void ShadowContentSelector::selectInclusion(ShadowInclusionList* inclusions)
+void ShadowContentSelector::selectInclusion(ShadowContentElement* contentElement, ShadowInclusionList* inclusions)
 {
-    inclusions->clear();
+    ASSERT(inclusions->isEmpty());
 
     for (size_t i = 0; i < m_children.size(); ++i) {
         Node* child = m_children[i].get();
         if (!child)
             continue;
-        if (!m_activeElement->shouldInclude(child))
+        if (!contentElement->shouldInclude(child))
             continue;
 
-        inclusions->append(m_activeElement, child);
+        inclusions->append(contentElement, child);
         m_children[i] = 0;
     }
-
-}
-
-void ShadowContentSelector::willAttachContentFor(ShadowContentElement* element)
-{
-    ASSERT(!m_activeElement);
-    m_activeElement = element;
-}
-
-void ShadowContentSelector::didAttachContent()
-{
-    ASSERT(m_activeElement);
-    m_activeElement = 0;
-}
-
-ShadowContentElement* ShadowContentSelector::activeElement() const
-{
-    return m_activeElement;
 }
 
 }
index b5f6714..b1960ef 100644 (file)
@@ -49,18 +49,14 @@ public:
     explicit ShadowContentSelector(ShadowRoot*);
     ~ShadowContentSelector();
 
-    void willAttachContentFor(ShadowContentElement*);
-    void didAttachContent();
-    void selectInclusion(ShadowInclusionList*);
+    void selectInclusion(ShadowContentElement*, ShadowInclusionList*);
 
     ShadowRoot* shadowRoot() const { return m_shadowRoot; }
-    ShadowContentElement* activeElement() const;
     static ShadowContentSelector* currentInstance() { return s_currentInstance; }
 
 private:
     ShadowContentSelector* m_parent;
     ShadowRoot* m_shadowRoot;
-    ShadowContentElement* m_activeElement;
     Vector<RefPtr<Node> > m_children;
 
     static ShadowContentSelector* s_currentInstance;
index 95e3770..1cb04a4 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "Document.h"
 #include "NodeRareData.h"
+#include "ShadowContentElement.h"
 #include "ShadowContentSelector.h"
 
 namespace WebCore {
@@ -49,6 +50,7 @@ ShadowRoot::ShadowRoot(Document* document)
 
 ShadowRoot::~ShadowRoot()
 {
+    ASSERT(!m_inclusions || m_inclusions->isEmpty());
 }
 
 String ShadowRoot::nodeName() const
@@ -95,12 +97,14 @@ void ShadowRoot::recalcStyle(StyleChange change)
     clearChildNeedsStyleRecalc();
 }
 
-ShadowContentElement* ShadowRoot::activeContentElement()
+ShadowContentElement* ShadowRoot::includerFor(Node* node) const
 {
-    ShadowContentSelector* selector = ShadowContentSelector::currentInstance();
-    if (!selector || selector->shadowRoot() != this)
+    if (!m_inclusions)
         return 0;
-    return selector->activeElement();
+    ShadowInclusion* found = m_inclusions->find(node);
+    if (!found)
+        return 0;
+    return found->includer();
 }
 
 void ShadowRoot::hostChildrenChanged()
@@ -137,4 +141,17 @@ void ShadowRoot::attach()
     TreeScope::attach();
 }
 
+ShadowInclusionSet* ShadowRoot::inclusions() const
+{
+    return m_inclusions.get();
+}
+
+ShadowInclusionSet* ShadowRoot::ensureInclusions()
+{
+    if (!m_inclusions)
+        m_inclusions = adoptPtr(new ShadowInclusionSet());
+    return m_inclusions.get();
+}
+
+
 }
index 62122de..ed0e787 100644 (file)
@@ -33,6 +33,7 @@ namespace WebCore {
 
 class Document;
 class ShadowContentElement;
+class ShadowInclusionSet;
 
 class ShadowRoot : public TreeScope {
 public:
@@ -40,7 +41,7 @@ public:
 
     virtual void recalcStyle(StyleChange = NoChange);
 
-    ShadowContentElement* activeContentElement();
+    ShadowContentElement* includerFor(Node*) const;
     void hostChildrenChanged();
 
     virtual void attach();
@@ -48,6 +49,9 @@ public:
     virtual bool applyAuthorSheets() const;
     void setApplyAuthorSheets(bool);
 
+    ShadowInclusionSet* inclusions() const;
+    ShadowInclusionSet* ensureInclusions();
+
 private:
     ShadowRoot(Document*);
     virtual ~ShadowRoot();
@@ -60,6 +64,7 @@ private:
     bool hasContentElement() const;
 
     bool m_applyAuthorSheets;
+    OwnPtr<ShadowInclusionSet> m_inclusions;
 };
 
 inline PassRefPtr<ShadowRoot> ShadowRoot::create(Document* document)
@@ -67,6 +72,12 @@ inline PassRefPtr<ShadowRoot> ShadowRoot::create(Document* document)
     return adoptRef(new ShadowRoot(document));
 }
 
+inline ShadowRoot* toShadowRoot(Node* node)
+{
+    ASSERT(!node || node->nodeType() == Node::SHADOW_ROOT_NODE);
+    return static_cast<ShadowRoot*>(node);
+}
+
 } // namespace
 
 #endif
index fb95e1b..4d7b6aa 100644 (file)
@@ -31,6 +31,7 @@
 #include "Element.h"
 #include "ExceptionCode.h"
 #include "InspectorController.h"
+#include "NodeRenderingContext.h"
 #include "Page.h"
 #include "RenderTreeAsText.h"
 #include "ShadowContentElement.h"
@@ -115,6 +116,16 @@ void Internals::removeShadowRoot(Element* host, ExceptionCode& ec)
     host->removeShadowRoot();
 }
 
+Element* Internals::includerFor(Node* node, ExceptionCode& ec)
+{
+    if (!node) {
+        ec = INVALID_ACCESS_ERR;
+        return 0;
+    }
+
+    return NodeRenderingContext(node).includer();
+}
+
 String Internals::shadowPseudoId(Element* element, ExceptionCode& ec)
 {
     if (!element) {
index b0c1d67..b626b59 100644 (file)
@@ -50,6 +50,7 @@ public:
     Node* ensureShadowRoot(Element* host, ExceptionCode&);
     Node* shadowRoot(Element* host, ExceptionCode&);
     void removeShadowRoot(Element* host, ExceptionCode&);
+    Element* includerFor(Node*, ExceptionCode&);
     String shadowPseudoId(Element*, ExceptionCode&);
     PassRefPtr<Element> createShadowContentElement(Document*, ExceptionCode&);
 
index 6aba803..d7b2183 100644 (file)
@@ -32,6 +32,7 @@ module window {
 
         Node ensureShadowRoot(in Element host) raises (DOMException);
         Node shadowRoot(in Element host) raises (DOMException);
+        Element includerFor(in Node node) raises (DOMException);
         void removeShadowRoot(in Element host) raises (DOMException);
         DOMString shadowPseudoId(in Element element) raises (DOMException);
         Element createShadowContentElement(in Document document) raises(DOMException);
index f3c23cd..e763bbd 100644 (file)
@@ -1,3 +1,15 @@
+2011-07-18  MORITA Hajime  <morrita@google.com>
+
+        [ShadowContentElement] forwarded node should be able to access its hosting content element.
+        https://bugs.webkit.org/show_bug.cgi?id=64251
+
+        Reviewed by Dimitri Glazkov.
+
+        Exported additional symbols for window.internals object.
+
+        * win/WebKit2.def:
+        * win/WebKit2CFLite.def:
+
 2011-07-18  Dean Jackson  <dino@apple.com>
 
         https://bugs.webkit.org/show_bug.cgi?id=64742
index 6181dde..711d02f 100644 (file)
@@ -135,6 +135,9 @@ EXPORTS
         ?createThread@WTF@@YAIP6APAXPAX@Z0@Z
 
         ; Re-exports from WebCore for test harnesses
+        ??0NodeRenderingContext@WebCore@@QAE@PAVNode@1@@Z
+        ??1NodeRenderingContext@WebCore@@QAE@XZ
+        ?toNode@WebCore@@YAPAVNode@1@VJSValue@JSC@@@Z
         ??0String@WTF@@QAE@PBD@Z
         ??0String@WTF@@QAE@PB_W@Z
         ?add@AtomicString@WTF@@CA?AV?$PassRefPtr@VStringImpl@WTF@@@2@PBD@Z
index 0a3559e..d5ba4ee 100644 (file)
@@ -128,8 +128,10 @@ EXPORTS
         ?createThread@WTF@@YAIP6APAXPAX@Z0@Z
 
         ; Re-exports from WebCore for test harnesses
+        ??0NodeRenderingContext@WebCore@@QAE@PAVNode@1@@Z
         ??0String@WTF@@QAE@PBD@Z
         ??0String@WTF@@QAE@PB_W@Z
+        ??1NodeRenderingContext@WebCore@@QAE@XZ
         ?add@AtomicString@WTF@@CA?AV?$PassRefPtr@VStringImpl@WTF@@@2@PBD@Z
         ?addSlowCase@AtomicString@WTF@@CA?AV?$PassRefPtr@VStringImpl@WTF@@@2@PAVStringImpl@2@@Z
         ?cacheDOMStructure@WebCore@@YAPAVStructure@JSC@@PAVJSDOMGlobalObject@1@PAV23@PBUClassInfo@3@@Z
@@ -148,4 +150,5 @@ EXPORTS
         ?toDocument@WebCore@@YAPAVDocument@1@VJSValue@JSC@@@Z
         ?toElement@WebCore@@YAPAVElement@1@VJSValue@JSC@@@Z
         ?toJS@WebCore@@YA?AVJSValue@JSC@@PAVExecState@3@PAVJSDOMGlobalObject@1@PAVNode@1@@Z
-        ?virtualFunctionToPreventWeakVtable@JSDOMWrapper@WebCore@@MAEXXZ
+        ?toNode@WebCore@@YAPAVNode@1@VJSValue@JSC@@@Z
+        ?virtualFunctionToPreventWeakVtable@JSDOMWrapper@WebCore@@MAEXXZ
\ No newline at end of file
index bc920a9..0430145 100644 (file)
@@ -37,12 +37,15 @@ _ZN7WebCore15setDOMExceptionEPN3JSC9ExecStateEi;
 _ZN7WebCore16jsStringSlowCaseEPN3JSC9ExecStateERN3WTF7HashMapIPNS3_10StringImplENS0_4WeakINS0_8JSStringEEENS3_10StringHashENS3_10HashTraitsIS6_EENSB_IS9_EEEES6_;
 _ZN7WebCore17cacheDOMStructureEPNS_17JSDOMGlobalObjectEPN3JSC9StructureEPKNS2_9ClassInfoE;
 _ZN7WebCore19InspectorController39setResourcesDataSizeLimitsFromInternalsEii;
+_ZN7WebCore20NodeRenderingContextC1EPNS_4NodeE;
+_ZN7WebCore20NodeRenderingContextD1Ev;
 _ZN7WebCore20ShadowContentElement6createEPNS_8DocumentE;
 _ZN7WebCore21getCachedDOMStructureEPNS_17JSDOMGlobalObjectEPKN3JSC9ClassInfoE;
 _ZN7WebCore22externalRepresentationEPNS_7ElementEj;
 _ZN7WebCore6JSNode13visitChildrenERN3JSC11SlotVisitorE;
 _ZN7WebCore6JSNode3putEPN3JSC9ExecStateERKNS1_10IdentifierENS1_7JSValueERNS1_15PutPropertySlotE;
 _ZN7WebCore6JSNode6s_infoE;
+_ZN7WebCore6toNodeEN3JSC7JSValueE;
 _ZN7WebCore7Element16ensureShadowRootEv;
 _ZN7WebCore7Element16removeShadowRootEv;
 _ZN7WebCore9JSElement3putEPN3JSC9ExecStateERKNS1_10IdentifierENS1_7JSValueERNS1_15PutPropertySlotE;