Commit c19324ed authored by commit-queue@webkit.org's avatar commit-queue@webkit.org
Browse files

[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@130177 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent b0122204
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.
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
<!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>
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.
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:
2012-10-02 Vsevolod Vlasov <vsevik@chromium.org>
 
Web Inspector: [Regression] DevToolsExtensionTest.TestContentScriptIsPresent fails
......@@ -55,6 +55,7 @@ ShadowRoot::ShadowRoot(Document* document)
, m_applyAuthorStyles(false)
, m_resetStyleInheritance(false)
, m_insertionPointAssignedTo(0)
, m_numberOfShadowElementChildren(0)
{
ASSERT(document);
......
......@@ -89,6 +89,10 @@ public:
InsertionPoint* assignedTo() const;
void setAssignedTo(InsertionPoint*);
void registerShadowElement() { ++m_numberOfShadowElementChildren; }
void unregisterShadowElement() { --m_numberOfShadowElementChildren; }
bool hasShadowInsertionPoint() const { return m_numberOfShadowElementChildren > 0; }
#ifndef NDEBUG
ShadowRootType type() const { return m_type; }
#endif
......@@ -108,6 +112,7 @@ private:
bool m_applyAuthorStyles : 1;
bool m_resetStyleInheritance : 1;
InsertionPoint* m_insertionPointAssignedTo;
size_t m_numberOfShadowElementChildren;
#ifndef NDEBUG
ShadowRootType m_type;
......
......@@ -41,6 +41,7 @@ class Document;
inline HTMLShadowElement::HTMLShadowElement(const QualifiedName& tagName, Document* document)
: InsertionPoint(tagName, document)
, m_registeredWithShadowRoot(false)
{
ASSERT(hasTagName(HTMLNames::shadowTag));
}
......@@ -68,4 +69,31 @@ bool HTMLShadowElement::doesSelectFromHostChildren() const
return false;
}
Node::InsertionNotificationRequest HTMLShadowElement::insertedInto(ContainerNode* insertionPoint)
{
InsertionPoint::insertedInto(insertionPoint);
if (insertionPoint->inDocument() && isActive()) {
if (ShadowRoot* root = shadowRoot()) {
root->registerShadowElement();
m_registeredWithShadowRoot = true;
}
}
return InsertionDone;
}
void HTMLShadowElement::removedFrom(ContainerNode* insertionPoint)
{
if (insertionPoint->inDocument() && m_registeredWithShadowRoot) {
ShadowRoot* root = shadowRoot();
if (!root)
root = insertionPoint->shadowRoot();
if (root)
root->unregisterShadowElement();
m_registeredWithShadowRoot = false;
}
InsertionPoint::removedFrom(insertionPoint);
}
} // namespace WebCore
......@@ -46,8 +46,14 @@ public:
bool isSelectValid() const OVERRIDE { return true; }
bool doesSelectFromHostChildren() const;
protected:
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
private:
HTMLShadowElement(const QualifiedName&, Document*);
bool m_registeredWithShadowRoot;
};
} // namespace WebCore
......
......@@ -297,6 +297,15 @@ Node* Internals::parentTreeScope(Node* node, ExceptionCode& ec)
return parentTreeScope ? parentTreeScope->rootNode() : 0;
}
bool Internals::hasShadowInsertionPoint(const Node* root, ExceptionCode& ec) const
{
if (root && root->isShadowRoot())
return toShadowRoot(root)->hasShadowInsertionPoint();
ec = INVALID_ACCESS_ERR;
return 0;
}
bool Internals::attached(Node* node, ExceptionCode& ec)
{
if (!node) {
......
......@@ -80,6 +80,7 @@ public:
ShadowRootIfShadowDOMEnabledOrNode* oldestShadowRoot(Element* host, ExceptionCode&);
ShadowRootIfShadowDOMEnabledOrNode* youngerShadowRoot(Node* shadow, ExceptionCode&);
ShadowRootIfShadowDOMEnabledOrNode* olderShadowRoot(Node* shadow, ExceptionCode&);
bool hasShadowInsertionPoint(const Node*, ExceptionCode&) const;
Element* includerFor(Node*, ExceptionCode&);
String shadowPseudoId(Element*, ExceptionCode&);
void setShadowPseudoId(Element*, const String&, ExceptionCode&);
......
......@@ -48,6 +48,7 @@ module window {
Node oldestShadowRoot(in Element host) raises (DOMException);
Node youngerShadowRoot(in Node root) raises (DOMException);
#endif
boolean hasShadowInsertionPoint(in Node root) raises (DOMException);
Element includerFor(in Node node) raises (DOMException);
DOMString shadowPseudoId(in Element element) raises (DOMException);
void setShadowPseudoId(in Element element, in DOMString id) raises (DOMException);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment