[Shadow] ShadowRoot should know whether <shadow> in its treescope
https://bugs.webkit.org/show_bug.cgi?id=97184

Patch by Takashi Sakamoto <tasak@google.com> on 2012-10-02
Reviewed by Dimitri Glazkov.

Source/WebCore:

To quickly know whether some shadow dom subtree has any shadow element
or not, added hasShadowRootInsertionPoint, registerShadowElement and
unregisterShadowElement to class ShadowRoot. The register method or
unregister method is used when a shadow element is inserted into
document or removed from document. hasShadowInsertionPoint returns true
if any shadow element is still registered with the given shadow root.
Otherwise returns false. To test hasShadowInsertionPoint, added
hasShadowInsertionPoint to Internals.

Test: fast/dom/shadow/has-shadow-insertion-point.html

* dom/ShadowRoot.cpp:
(WebCore::ShadowRoot::ShadowRoot):
Initializes number of shadow elements.
* dom/ShadowRoot.h:
(WebCore::ShadowRoot::registerShadowElement):
Increases number of shadow elements in shadow dom subtree by 1.
(WebCore::ShadowRoot::unregisterShadowElement):
Decreases number of shadow elements in shadow dom subtree by 1.
(WebCore::ShadowRoot::hasShadowInsertionPoint):
If number of shadow elements in shadow dom subtree is not equal to 0,
returns true. Otherwise, returns false.
* html/shadow/HTMLShadowElement.cpp:
(WebCore::HTMLShadowElement::HTMLShadowElement):
(WebCore::HTMLShadowElement::insertedInto):
If a shadow element is inserted into document, register the shadow
element with its shadow root.
(WebCore::HTMLShadowElement::removedFrom):
 If a shadow element is removed from document, unregister the shadow
element with its shadow root.
* html/shadow/HTMLShadowElement.h:
Added a new member variable which has information about whether
this shadow element has been already registered with its shadow root
or not.
* testing/Internals.cpp:
(WebCore::Internals::hasShadowInsertionPoint):
Added a new testing method which returns whether the given shadow
root has any shadow element or not.
* testing/Internals.h:
(Internals):
* testing/Internals.idl:

LayoutTests:

* fast/dom/shadow/has-shadow-insertion-point-expected.txt: Added.
* fast/dom/shadow/has-shadow-insertion-point.html: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk/LayoutTests@130177 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/ChangeLog b/ChangeLog
index 0dc6ae7..cbbd88a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2012-10-02  Takashi Sakamoto  <tasak@google.com>
+
+        [Shadow] ShadowRoot should know whether <shadow> in its treescope
+        https://bugs.webkit.org/show_bug.cgi?id=97184
+
+        Reviewed by Dimitri Glazkov.
+
+        * fast/dom/shadow/has-shadow-insertion-point-expected.txt: Added.
+        * fast/dom/shadow/has-shadow-insertion-point.html: Added.
+
 2012-10-02  Sheriff Bot  <webkit.review.bot@gmail.com>
 
         Unreviewed, rolling out r130167 and r130171.
diff --git a/fast/dom/shadow/has-shadow-insertion-point-expected.txt b/fast/dom/shadow/has-shadow-insertion-point-expected.txt
new file mode 100644
index 0000000..dc4a16b
--- /dev/null
+++ b/fast/dom/shadow/has-shadow-insertion-point-expected.txt
@@ -0,0 +1,18 @@
+PASS internals.hasShadowInsertionPoint(shadowRoot) is false
+PASS internals.hasShadowInsertionPoint(shadowRoot) is true
+PASS internals.hasShadowInsertionPoint(shadowRoot) is false
+PASS internals.hasShadowInsertionPoint(shadowRoot) is false
+PASS internals.hasShadowInsertionPoint(shadowRoot) is false
+PASS internals.hasShadowInsertionPoint(shadowRoot) is true
+PASS internals.hasShadowInsertionPoint(shadowRoot) is true
+PASS internals.hasShadowInsertionPoint(shadowRoot) is true
+PASS internals.hasShadowInsertionPoint(youngerShadowRoot) is false
+PASS internals.hasShadowInsertionPoint(shadowRoot) is false
+PASS internals.hasShadowInsertionPoint(youngerShadowRoot) is false
+PASS internals.hasShadowInsertionPoint(shadowRoot) is false
+PASS internals.hasShadowInsertionPoint(youngerShadowRoot) is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+Test for Bug 97184: https://bugs.webkit.org/show_bug.cgi?id=97184 - [Shadow] ShadowRoot should know whether <shadow> in its treescope
+
diff --git a/fast/dom/shadow/has-shadow-insertion-point.html b/fast/dom/shadow/has-shadow-insertion-point.html
new file mode 100644
index 0000000..986702b
--- /dev/null
+++ b/fast/dom/shadow/has-shadow-insertion-point.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../js/resources/js-test-pre.js"></script>
+<script src="resources/polyfill.js"></script>
+<script>
+if (!window.internals)
+    debug("windows.internals not found!");
+else if (!window.internals.hasShadowInsertionPoint)
+    debug("windows.internals.hasShadowInsertionPoint not found!");
+</script>
+</head>
+<body>
+  <span>Test for Bug 97184: <a href="https://bugs.webkit.org/show_bug.cgi?id=97184">https://bugs.webkit.org/show_bug.cgi?id=97184</a> -
+    [Shadow] ShadowRoot should know whether &lt;shadow&gt; in its treescope
+  </span>
+  <div id="host"></div>
+
+<script>
+var host = document.getElementById("host");
+var shadowRoot = new WebKitShadowRoot(host);
+
+shouldBeFalse("internals.hasShadowInsertionPoint(shadowRoot)");
+
+var div = document.createElement("div");
+div.appendChild(document.createElement("shadow"));
+shadowRoot.appendChild(div);
+shouldBeTrue("internals.hasShadowInsertionPoint(shadowRoot)");
+
+shadowRoot.removeChild(div);
+shouldBeFalse("internals.hasShadowInsertionPoint(shadowRoot)");
+
+shadowRoot.innerHTML = "<div>No Insertion Points</div>";
+shouldBeFalse("internals.hasShadowInsertionPoint(shadowRoot)");
+
+shadowRoot.innerHTML = "<content></content>";
+shouldBeFalse("internals.hasShadowInsertionPoint(shadowRoot)");
+
+shadowRoot.innerHTML = "<shadow></shadow>";
+shouldBeTrue("internals.hasShadowInsertionPoint(shadowRoot)");
+
+shadowRoot.innerHTML = "<div><div><div><shadow></shadow></div></div></div>";
+shouldBeTrue("internals.hasShadowInsertionPoint(shadowRoot)");
+
+var youngerShadowRoot = new WebKitShadowRoot(host);
+// Modifying older shadow root or younger shadow root doesn't affect the other.
+shouldBeTrue("internals.hasShadowInsertionPoint(shadowRoot)");
+shouldBeFalse("internals.hasShadowInsertionPoint(youngerShadowRoot)");
+
+shadowRoot.innerHTML = "<content></content>";
+shouldBeFalse("internals.hasShadowInsertionPoint(shadowRoot)");
+shouldBeFalse("internals.hasShadowInsertionPoint(youngerShadowRoot)");
+
+youngerShadowRoot.innerHTML = "<shadow></shadow>";
+shouldBeFalse("internals.hasShadowInsertionPoint(shadowRoot)");
+shouldBeTrue("internals.hasShadowInsertionPoint(youngerShadowRoot)");
+</script>
+<script src="../../js/resources/js-test-post.js"></script>
+</body>
+</html>
+