Only allow one shadowRoot.

R=ojan@chromium.org

Review URL: https://codereview.chromium.org/759663003
This commit is contained in:
Elliott Sprehn 2014-11-26 13:54:14 -05:00
parent ead67ecbbf
commit 253b5bed74
29 changed files with 92 additions and 205 deletions

View File

@ -14,7 +14,7 @@ WidgetPrototype.createdCallback = function() {
this.wasAttached = false;
this.wasDetached = false;
this.attrsChanged = [];
this.createShadowRoot();
this.ensureShadowRoot();
};
WidgetPrototype.attachedCallback = function() {

View File

@ -171,14 +171,9 @@ private:
node->clearV8CollectableDuringMinorGC();
partiallyDependentNodes->append(node);
}
if (ShadowRoot* shadowRoot = node->youngestShadowRoot()) {
if (ShadowRoot* shadowRoot = node->shadowRoot()) {
if (!traverseTree(shadowRoot, partiallyDependentNodes))
return false;
} else if (node->isShadowRoot()) {
if (ShadowRoot* shadowRoot = toShadowRoot(node)->olderShadowRoot()) {
if (!traverseTree(shadowRoot, partiallyDependentNodes))
return false;
}
}
// <template> has a |content| property holding a DOM fragment which we must traverse,
// just like we do for the shadow trees above.

View File

@ -682,7 +682,7 @@ void StyleResolver::collectScopedResolversForHostedShadowTrees(const Element* el
return;
// Adding scoped resolver for active shadow roots for shadow host styling.
for (ShadowRoot* shadowRoot = shadow->youngestShadowRoot(); shadowRoot; shadowRoot = shadowRoot->olderShadowRoot()) {
if (ShadowRoot* shadowRoot = shadow->shadowRoot()) {
if (shadowRoot->numberOfStyles() > 0) {
if (ScopedStyleResolver* resolver = shadowRoot->scopedStyleResolver())
resolvers.append(resolver);

View File

@ -617,7 +617,7 @@ void ContainerNode::notifyNodeInsertedInternal(Node& root)
if (!inDocument() && !node->isContainerNode())
continue;
node->insertedInto(this);
for (ShadowRoot* shadowRoot = node->youngestShadowRoot(); shadowRoot; shadowRoot = shadowRoot->olderShadowRoot())
if (ShadowRoot* shadowRoot = node->shadowRoot())
notifyNodeInsertedInternal(*shadowRoot);
}
}
@ -634,7 +634,7 @@ void ContainerNode::notifyNodeRemoved(Node& root)
if (!node->inDocument() && !node->isContainerNode())
continue;
node->removedFrom(this);
for (ShadowRoot* shadowRoot = node->youngestShadowRoot(); shadowRoot; shadowRoot = shadowRoot->olderShadowRoot())
if (ShadowRoot* shadowRoot = node->shadowRoot())
notifyNodeRemoved(*shadowRoot);
}
}

View File

@ -967,7 +967,7 @@ void Element::recalcChildStyle(StyleRecalcChange change)
ASSERT(!needsStyleRecalc());
if (change > Inherit || childNeedsStyleRecalc()) {
for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) {
if (ShadowRoot* root = shadowRoot()) {
if (root->shouldCallRecalcStyle(change))
root->recalcStyle(change);
}
@ -1049,8 +1049,12 @@ CustomElementDefinition* Element::customElementDefinition() const
return 0;
}
PassRefPtr<ShadowRoot> Element::createShadowRoot(ExceptionState& exceptionState)
// TODO(esprehn): Implement the sky spec where shadow roots are a custom
// element registration feature.
PassRefPtr<ShadowRoot> Element::ensureShadowRoot(ExceptionState& exceptionState)
{
if (ShadowRoot* root = shadowRoot())
return root;
return PassRefPtr<ShadowRoot>(ensureShadow().addShadowRoot(*this));
}
@ -1059,7 +1063,7 @@ ShadowRoot* Element::shadowRoot() const
ElementShadow* elementShadow = shadow();
if (!elementShadow)
return 0;
return elementShadow->youngestShadowRoot();
return elementShadow->shadowRoot();
}
void Element::childrenChanged(const ChildrenChange& change)

View File

@ -209,9 +209,8 @@ public:
ElementShadow* shadow() const;
ElementShadow& ensureShadow();
PassRefPtr<ShadowRoot> createShadowRoot(ExceptionState&);
PassRefPtr<ShadowRoot> ensureShadowRoot(ExceptionState&);
ShadowRoot* shadowRoot() const;
ShadowRoot* youngestShadowRoot() const;
bool hasAuthorShadowRoot() const { return shadowRoot(); }
@ -547,6 +546,13 @@ inline void Node::removedFrom(ContainerNode* insertionPoint)
clearFlag(IsInShadowTreeFlag);
}
inline ShadowRoot* Node::shadowRoot() const
{
if (!isElementNode())
return 0;
return toElement(this)->shadowRoot();
}
inline void Element::invalidateStyleAttribute()
{
ASSERT(elementData());

View File

@ -64,7 +64,7 @@
[PerWorldBindings] readonly attribute DOMTokenList classList;
[RaisesException, MeasureAs=ElementCreateShadowRoot] ShadowRoot createShadowRoot();
[RaisesException] ShadowRoot ensureShadowRoot();
[PerWorldBindings] readonly attribute ShadowRoot shadowRoot;
NodeList getDestinationInsertionPoints();

View File

@ -459,17 +459,6 @@ bool Node::hasNonEmptyBoundingBox() const
return false;
}
#ifndef NDEBUG
inline static ShadowRoot* oldestShadowRootFor(const Node* node)
{
if (!node->isElementNode())
return 0;
if (ElementShadow* shadow = toElement(node)->shadow())
return shadow->oldestShadowRoot();
return 0;
}
#endif
void Node::recalcDistribution()
{
if (isElementNode()) {
@ -482,7 +471,7 @@ void Node::recalcDistribution()
child->recalcDistribution();
}
for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) {
if (ShadowRoot* root = shadowRoot()) {
if (root->childNeedsDistributionRecalc())
root->recalcDistribution();
}
@ -533,7 +522,7 @@ unsigned Node::styledSubtreeSize() const
for (const Node* node = this; node; node = NodeTraversal::next(*node, this)) {
if (node->isTextNode() || node->isElementNode())
nodeCount++;
for (ShadowRoot* root = node->youngestShadowRoot(); root; root = root->olderShadowRoot())
if (ShadowRoot* root = node->shadowRoot())
nodeCount += root->styledSubtreeSize();
}
@ -1094,10 +1083,6 @@ unsigned short Node::compareDocumentPosition(const Node* otherNode, ShadowTreesT
if (!child1->isShadowRoot())
return Node::DOCUMENT_POSITION_PRECEDING | connection;
for (ShadowRoot* child = toShadowRoot(child2)->olderShadowRoot(); child; child = child->olderShadowRoot())
if (child == child1)
return Node::DOCUMENT_POSITION_FOLLOWING | connection;
return Node::DOCUMENT_POSITION_PRECEDING | connection;
}
@ -1200,10 +1185,7 @@ void Node::showNodePathForThis() const
for (unsigned index = chain.size(); index > 0; --index) {
const Node* node = chain[index - 1];
if (node->isShadowRoot()) {
int count = 0;
for (ShadowRoot* shadowRoot = toShadowRoot(node)->olderShadowRoot(); shadowRoot; shadowRoot = shadowRoot->olderShadowRoot())
++count;
fprintf(stderr, "/#shadow-root[%d]", count);
fprintf(stderr, "/#shadow-root");
continue;
}
@ -1253,11 +1235,8 @@ static void traverseTreeAndMark(const String& baseIndent, const Node* rootNode,
fprintf(stderr, "%s", indent.toString().utf8().data());
node->showNode();
indent.append('\t');
if (node->isShadowRoot()) {
if (ShadowRoot* youngerShadowRoot = toShadowRoot(node)->youngerShadowRoot())
traverseTreeAndMark(indent.toString(), youngerShadowRoot, markedNode1, markedLabel1, markedNode2, markedLabel2);
} else if (ShadowRoot* oldestShadowRoot = oldestShadowRootFor(node))
traverseTreeAndMark(indent.toString(), oldestShadowRoot, markedNode1, markedLabel1, markedNode2, markedLabel2);
if (ShadowRoot* shadowRoot = node->shadowRoot())
traverseTreeAndMark(indent.toString(), shadowRoot, markedNode1, markedLabel1, markedNode2, markedLabel2);
}
}
@ -1293,13 +1272,8 @@ static void showSubTreeAcrossFrame(const Node* node, const Node* markedNode, con
fputs("*", stderr);
fputs(indent.utf8().data(), stderr);
node->showNode();
if (node->isShadowRoot()) {
if (ShadowRoot* youngerShadowRoot = toShadowRoot(node)->youngerShadowRoot())
showSubTreeAcrossFrame(youngerShadowRoot, markedNode, indent + "\t");
} else {
if (ShadowRoot* oldestShadowRoot = oldestShadowRootFor(node))
showSubTreeAcrossFrame(oldestShadowRoot, markedNode, indent + "\t");
}
if (ShadowRoot* shadowRoot = node->shadowRoot())
showSubTreeAcrossFrame(shadowRoot, markedNode, indent + "\t");
for (Node* child = node->firstChild(); child; child = child->nextSibling())
showSubTreeAcrossFrame(child, markedNode, indent + "\t");
}
@ -1398,7 +1372,7 @@ void Node::removeAllEventListenersRecursively()
{
for (Node* node = this; node; node = NodeTraversal::next(*node)) {
node->removeAllEventListeners();
for (ShadowRoot* root = node->youngestShadowRoot(); root; root = root->olderShadowRoot())
if (ShadowRoot* root = node->shadowRoot())
root->removeAllEventListenersRecursively();
}
}

View File

@ -212,7 +212,7 @@ public:
// If this node is in a shadow tree, returns its shadow host. Otherwise, returns 0.
Element* shadowHost() const;
ShadowRoot* containingShadowRoot() const;
ShadowRoot* youngestShadowRoot() const;
ShadowRoot* shadowRoot() const;
// Returns 0, a child of ShadowRoot, or a legacy shadow root.
Node* nonBoundaryShadowTreeRootNode();

View File

@ -92,18 +92,9 @@ TreeScope::~TreeScope()
#endif
}
TreeScope* TreeScope::olderShadowRootOrParentTreeScope() const
{
if (rootNode().isShadowRoot()) {
if (ShadowRoot* olderShadowRoot = toShadowRoot(rootNode()).olderShadowRoot())
return olderShadowRoot;
}
return parentTreeScope();
}
bool TreeScope::isInclusiveOlderSiblingShadowRootOrAncestorTreeScopeOf(const TreeScope& scope) const
{
for (const TreeScope* current = &scope; current; current = current->olderShadowRootOrParentTreeScope()) {
for (const TreeScope* current = &scope; current; current = current->parentTreeScope()) {
if (current == this)
return true;
}
@ -303,10 +294,6 @@ unsigned short TreeScope::comparePosition(const TreeScope& otherScope) const
if (shadowHost1 != shadowHost2)
return shadowHost1->compareDocumentPosition(shadowHost2, Node::TreatShadowTreesAsDisconnected);
for (const ShadowRoot* child = toShadowRoot(child2->rootNode()).olderShadowRoot(); child; child = child->olderShadowRoot())
if (child == child1)
return Node::DOCUMENT_POSITION_FOLLOWING;
return Node::DOCUMENT_POSITION_PRECEDING;
}
}
@ -414,7 +401,7 @@ Element* TreeScope::getElementByAccessKey(const String& key) const
for (Element* element = ElementTraversal::firstWithin(root); element; element = ElementTraversal::next(*element, &root)) {
if (equalIgnoringCase(element->getAttribute(HTMLNames::accesskeyAttr), key))
result = element;
for (ShadowRoot* shadowRoot = element->youngestShadowRoot(); shadowRoot; shadowRoot = shadowRoot->olderShadowRoot()) {
if (ShadowRoot* shadowRoot = element->shadowRoot()) {
if (Element* shadowResult = shadowRoot->getElementByAccessKey(key))
result = shadowResult;
}
@ -425,7 +412,7 @@ Element* TreeScope::getElementByAccessKey(const String& key) const
void TreeScope::setNeedsStyleRecalcForViewportUnits()
{
for (Element* element = ElementTraversal::firstWithin(rootNode()); element; element = ElementTraversal::next(*element)) {
for (ShadowRoot* root = element->youngestShadowRoot(); root; root = root->olderShadowRoot())
if (ShadowRoot* root = element->shadowRoot())
root->setNeedsStyleRecalcForViewportUnits();
RenderStyle* style = element->renderStyle();
if (style && style->hasViewportUnits())

View File

@ -48,7 +48,6 @@ class TreeScope {
public:
TreeScope* parentTreeScope() const { return m_parentTreeScope; }
TreeScope* olderShadowRootOrParentTreeScope() const;
bool isInclusiveOlderSiblingShadowRootOrAncestorTreeScopeOf(const TreeScope&) const;
Element* adjustedFocusedElement() const;

View File

@ -37,9 +37,7 @@ void TreeScopeAdopter::moveTreeToNewScope(Node& root) const
{
ASSERT(needsScopeChange());
#if !ENABLE(OILPAN)
oldScope().guardRef();
#endif
Document& oldDocument = oldScope().document();
Document& newDocument = newScope().document();
@ -54,16 +52,14 @@ void TreeScopeAdopter::moveTreeToNewScope(Node& root) const
if (!node->isElementNode())
continue;
for (ShadowRoot* shadow = node->youngestShadowRoot(); shadow; shadow = shadow->olderShadowRoot()) {
if (ShadowRoot* shadow = node->shadowRoot()) {
shadow->setParentTreeScope(newScope());
if (willMoveToNewDocument)
moveTreeToNewDocument(*shadow, oldDocument, newDocument);
}
}
#if !ENABLE(OILPAN)
oldScope().guardDeref();
#endif
}
void TreeScopeAdopter::moveTreeToNewDocument(Node& root, Document& oldDocument, Document& newDocument) const
@ -72,7 +68,7 @@ void TreeScopeAdopter::moveTreeToNewDocument(Node& root, Document& oldDocument,
for (Node* node = &root; node; node = NodeTraversal::next(*node, &root)) {
moveNodeToNewDocument(*node, oldDocument, newDocument);
for (ShadowRoot* shadow = node->youngestShadowRoot(); shadow; shadow = shadow->olderShadowRoot())
if (ShadowRoot* shadow = node->shadowRoot())
moveTreeToNewDocument(*shadow, oldDocument, newDocument);
}
}

View File

@ -21,7 +21,7 @@ TEST(TreeScopeTest, CommonAncestorOfSameTrees)
RefPtr<Element> html = document->createElement("html", nullAtom, ASSERT_NO_EXCEPTION);
document->appendChild(html, ASSERT_NO_EXCEPTION);
RefPtr<ShadowRoot> shadowRoot = html->createShadowRoot(ASSERT_NO_EXCEPTION);
RefPtr<ShadowRoot> shadowRoot = html->ensureShadowRoot(ASSERT_NO_EXCEPTION);
EXPECT_EQ(shadowRoot.get(), shadowRoot->commonAncestorTreeScope(*shadowRoot));
}
@ -34,7 +34,7 @@ TEST(TreeScopeTest, CommonAncestorOfInclusiveTrees)
RefPtr<Document> document = Document::create();
RefPtr<Element> html = document->createElement("html", nullAtom, ASSERT_NO_EXCEPTION);
document->appendChild(html, ASSERT_NO_EXCEPTION);
RefPtr<ShadowRoot> shadowRoot = html->createShadowRoot(ASSERT_NO_EXCEPTION);
RefPtr<ShadowRoot> shadowRoot = html->ensureShadowRoot(ASSERT_NO_EXCEPTION);
EXPECT_EQ(document.get(), document->commonAncestorTreeScope(*shadowRoot));
EXPECT_EQ(document.get(), shadowRoot->commonAncestorTreeScope(*document));
@ -54,8 +54,8 @@ TEST(TreeScopeTest, CommonAncestorOfSiblingTrees)
RefPtr<Element> body = document->createElement("body", nullAtom, ASSERT_NO_EXCEPTION);
html->appendChild(body);
RefPtr<ShadowRoot> shadowRootA = head->createShadowRoot(ASSERT_NO_EXCEPTION);
RefPtr<ShadowRoot> shadowRootB = body->createShadowRoot(ASSERT_NO_EXCEPTION);
RefPtr<ShadowRoot> shadowRootA = head->ensureShadowRoot(ASSERT_NO_EXCEPTION);
RefPtr<ShadowRoot> shadowRootB = body->ensureShadowRoot(ASSERT_NO_EXCEPTION);
EXPECT_EQ(document.get(), shadowRootA->commonAncestorTreeScope(*shadowRootB));
EXPECT_EQ(document.get(), shadowRootB->commonAncestorTreeScope(*shadowRootA));
@ -77,12 +77,12 @@ TEST(TreeScopeTest, CommonAncestorOfTreesAtDifferentDepths)
RefPtr<Element> body = document->createElement("body", nullAtom, ASSERT_NO_EXCEPTION);
html->appendChild(body);
RefPtr<ShadowRoot> shadowRootY = head->createShadowRoot(ASSERT_NO_EXCEPTION);
RefPtr<ShadowRoot> shadowRootB = body->createShadowRoot(ASSERT_NO_EXCEPTION);
RefPtr<ShadowRoot> shadowRootY = head->ensureShadowRoot(ASSERT_NO_EXCEPTION);
RefPtr<ShadowRoot> shadowRootB = body->ensureShadowRoot(ASSERT_NO_EXCEPTION);
RefPtr<Element> divInY = document->createElement("div", nullAtom, ASSERT_NO_EXCEPTION);
shadowRootY->appendChild(divInY);
RefPtr<ShadowRoot> shadowRootA = divInY->createShadowRoot(ASSERT_NO_EXCEPTION);
RefPtr<ShadowRoot> shadowRootA = divInY->ensureShadowRoot(ASSERT_NO_EXCEPTION);
EXPECT_EQ(document.get(), shadowRootA->commonAncestorTreeScope(*shadowRootB));
EXPECT_EQ(document.get(), shadowRootB->commonAncestorTreeScope(*shadowRootA));

View File

@ -44,7 +44,7 @@ Node* ComposedTreeWalker::traverseChild(const Node* node, TraversalDirection dir
{
ASSERT(node);
ElementShadow* shadow = shadowFor(node);
return shadow ? traverseLightChildren(shadow->youngestShadowRoot(), direction)
return shadow ? traverseLightChildren(shadow->shadowRoot(), direction)
: traverseLightChildren(node, direction);
}
@ -105,14 +105,6 @@ Node* ComposedTreeWalker::traverseSiblingInCurrentTree(const Node* node, Travers
ASSERT(node);
if (Node* found = traverseSiblings(direction == TraversalDirectionForward ? node->nextSibling() : node->previousSibling(), direction))
return found;
if (Node* next = traverseBackToYoungerShadowRoot(node, direction))
return next;
return 0;
}
Node* ComposedTreeWalker::traverseBackToYoungerShadowRoot(const Node* node, TraversalDirection direction)
{
// FIXME(sky): Remove this.
return 0;
}
@ -142,8 +134,6 @@ inline Node* ComposedTreeWalker::traverseParentOrHost(const Node* node) const
if (!parent->isShadowRoot())
return parent;
ShadowRoot* shadowRoot = toShadowRoot(parent);
if (!shadowRoot->isYoungest())
return 0;
return shadowRoot->host();
}

View File

@ -105,8 +105,6 @@ private:
static Node* traverseSiblings(const Node*, TraversalDirection);
static Node* traverseDistributedNodes(const Node*, const InsertionPoint*, TraversalDirection);
static Node* traverseBackToYoungerShadowRoot(const Node*, TraversalDirection);
Node* traverseParentOrHost(const Node*) const;
RawPtr<const Node> m_node;

View File

@ -129,16 +129,15 @@ PassOwnPtr<ElementShadow> ElementShadow::create()
}
ElementShadow::ElementShadow()
: m_needsDistributionRecalc(false)
: m_shadowRoot(0)
, m_needsDistributionRecalc(false)
, m_needsSelectFeatureSet(false)
{
}
ElementShadow::~ElementShadow()
{
#if !ENABLE(OILPAN)
removeDetachedShadowRoots();
#endif
removeDetachedShadowRoot();
}
ShadowRoot& ElementShadow::addShadowRoot(Element& shadowHost)
@ -146,13 +145,13 @@ ShadowRoot& ElementShadow::addShadowRoot(Element& shadowHost)
EventDispatchForbiddenScope assertNoEventDispatch;
ScriptForbiddenScope forbidScript;
for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot())
root->lazyReattachIfAttached();
ASSERT(!m_shadowRoot);
RefPtr<ShadowRoot> shadowRoot = ShadowRoot::create(shadowHost.document());
shadowRoot->setParentOrShadowHostNode(&shadowHost);
shadowRoot->setParentTreeScope(shadowHost.treeScope());
m_shadowRoots.push(shadowRoot.get());
m_shadowRoot = shadowRoot.get();
setNeedsDistributionRecalc();
shadowRoot->insertedInto(&shadowHost);
@ -160,42 +159,40 @@ ShadowRoot& ElementShadow::addShadowRoot(Element& shadowHost)
return *shadowRoot;
}
#if !ENABLE(OILPAN)
void ElementShadow::removeDetachedShadowRoots()
void ElementShadow::removeDetachedShadowRoot()
{
// Dont protect this ref count.
Element* shadowHost = host();
ASSERT(shadowHost);
while (RefPtr<ShadowRoot> oldRoot = m_shadowRoots.head()) {
if (RefPtr<ShadowRoot> oldRoot = m_shadowRoot) {
shadowHost->document().removeFocusedElementOfSubtree(oldRoot.get());
m_shadowRoots.removeHead();
m_shadowRoot = 0;
oldRoot->setParentOrShadowHostNode(0);
oldRoot->setParentTreeScope(shadowHost->document());
oldRoot->setPrev(0);
oldRoot->setNext(0);
}
}
#endif
void ElementShadow::attach(const Node::AttachContext& context)
{
if (!m_shadowRoot)
return;
ASSERT(m_shadowRoot->needsAttach());
Node::AttachContext childrenContext(context);
childrenContext.resolvedStyle = 0;
for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) {
if (root->needsAttach())
root->attach(childrenContext);
}
m_shadowRoot->attach(childrenContext);
}
void ElementShadow::detach(const Node::AttachContext& context)
{
if (!m_shadowRoot)
return;
Node::AttachContext childrenContext(context);
childrenContext.resolvedStyle = 0;
for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot())
root->detach(childrenContext);
m_shadowRoot->detach(childrenContext);
}
void ElementShadow::setNeedsDistributionRecalc()
@ -209,9 +206,9 @@ void ElementShadow::setNeedsDistributionRecalc()
bool ElementShadow::hasSameStyles(const ElementShadow* other) const
{
ShadowRoot* root = youngestShadowRoot();
ShadowRoot* otherRoot = other->youngestShadowRoot();
while (root || otherRoot) {
ShadowRoot* root = m_shadowRoot;
ShadowRoot* otherRoot = other->shadowRoot();
if (root || otherRoot) {
if (!root || !otherRoot)
return false;
@ -225,8 +222,6 @@ bool ElementShadow::hasSameStyles(const ElementShadow* other) const
if (toCSSStyleSheet(list->item(i))->contents() != toCSSStyleSheet(otherList->item(i))->contents())
return false;
}
root = root->olderShadowRoot();
otherRoot = otherRoot->olderShadowRoot();
}
return true;
@ -251,7 +246,7 @@ void ElementShadow::distribute()
host()->setNeedsStyleRecalc(SubtreeStyleChange);
DistributionPool pool(*host());
for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) {
if (ShadowRoot* root = shadowRoot()) {
const Vector<RefPtr<InsertionPoint> >& insertionPoints = root->descendantInsertionPoints();
for (size_t i = 0; i < insertionPoints.size(); ++i) {
InsertionPoint* point = insertionPoints[i].get();
@ -276,7 +271,7 @@ const SelectRuleFeatureSet& ElementShadow::ensureSelectFeatureSet()
return m_selectFeatures;
m_selectFeatures.clear();
for (ShadowRoot* root = oldestShadowRoot(); root; root = root->youngerShadowRoot())
if (ShadowRoot* root = shadowRoot())
collectSelectFeatureSetFrom(*root);
m_needsSelectFeatureSet = false;
return m_selectFeatures;

View File

@ -31,7 +31,6 @@
#include "sky/engine/core/dom/shadow/SelectRuleFeatureSet.h"
#include "sky/engine/core/dom/shadow/ShadowRoot.h"
#include "sky/engine/platform/heap/Handle.h"
#include "sky/engine/wtf/DoublyLinkedList.h"
#include "sky/engine/wtf/HashMap.h"
#include "sky/engine/wtf/Noncopyable.h"
#include "sky/engine/wtf/PassOwnPtr.h"
@ -46,8 +45,7 @@ public:
~ElementShadow();
Element* host() const;
ShadowRoot* youngestShadowRoot() const { return m_shadowRoots.head(); }
ShadowRoot* oldestShadowRoot() const { return m_shadowRoots.tail(); }
ShadowRoot* shadowRoot() const { return m_shadowRoot; }
ElementShadow* containingShadow() const;
ShadowRoot& addShadowRoot(Element& shadowHost);
@ -71,9 +69,7 @@ public:
private:
ElementShadow();
#if !ENABLE(OILPAN)
void removeDetachedShadowRoots();
#endif
void removeDetachedShadowRoot();
void distribute();
void clearDistribution();
@ -88,30 +84,15 @@ private:
NodeToDestinationInsertionPoints m_nodeToInsertionPoints;
SelectRuleFeatureSet m_selectFeatures;
// FIXME: Oilpan: add a heap-based version of DoublyLinkedList<>.
DoublyLinkedList<ShadowRoot> m_shadowRoots;
ShadowRoot* m_shadowRoot;
bool m_needsDistributionRecalc;
bool m_needsSelectFeatureSet;
};
inline Element* ElementShadow::host() const
{
ASSERT(!m_shadowRoots.isEmpty());
return youngestShadowRoot()->host();
}
inline ShadowRoot* Node::youngestShadowRoot() const
{
if (!isElementNode())
return 0;
return toElement(this)->youngestShadowRoot();
}
inline ShadowRoot* Element::youngestShadowRoot() const
{
if (ElementShadow* shadow = this->shadow())
return shadow->youngestShadowRoot();
return 0;
ASSERT(m_shadowRoot);
return m_shadowRoot->host();
}
inline ElementShadow* ElementShadow::containingShadow() const

View File

@ -95,8 +95,6 @@ inline ElementShadow* shadowWhereNodeCanBeDistributed(const Node& node)
Node* parent = node.parentNode();
if (!parent)
return 0;
if (parent->isShadowRoot() && !toShadowRoot(parent)->isYoungest())
return node.shadowHost()->shadow();
if (isActiveInsertionPoint(*parent))
return node.shadowHost()->shadow();
if (parent->isElementNode())

View File

@ -41,8 +41,8 @@
namespace blink {
struct SameSizeAsShadowRoot : public DocumentFragment, public TreeScope, public DoublyLinkedListNode<ShadowRoot> {
void* pointers[3];
struct SameSizeAsShadowRoot : public DocumentFragment, public TreeScope {
void* pointers[1];
unsigned countersAndFlags[1];
};
@ -51,8 +51,6 @@ COMPILE_ASSERT(sizeof(ShadowRoot) == sizeof(SameSizeAsShadowRoot), shadowroot_sh
ShadowRoot::ShadowRoot(Document& document)
: DocumentFragment(0, CreateShadowRoot)
, TreeScope(*this, document)
, m_prev(nullptr)
, m_next(nullptr)
, m_numberOfStyles(0)
, m_registeredWithParentShadowRoot(false)
, m_descendantInsertionPointsIsValid(false)
@ -61,10 +59,6 @@ ShadowRoot::ShadowRoot(Document& document)
ShadowRoot::~ShadowRoot()
{
#if !ENABLE(OILPAN)
ASSERT(!m_prev);
ASSERT(!m_next);
if (m_shadowRootRareData && m_shadowRootRareData->styleSheets())
m_shadowRootRareData->styleSheets()->detachFromDocument();
@ -85,15 +79,12 @@ ShadowRoot::~ShadowRoot()
// as well as Node. See a comment on TreeScope.h for the reason.
if (hasRareData())
clearRareData();
#endif
}
#if !ENABLE(OILPAN)
void ShadowRoot::dispose()
{
removeDetachedChildren();
}
#endif
PassRefPtr<Node> ShadowRoot::cloneNode(bool, ExceptionState& exceptionState)
{
@ -130,7 +121,7 @@ void ShadowRoot::insertedInto(ContainerNode* insertionPoint)
{
DocumentFragment::insertedInto(insertionPoint);
if (!insertionPoint->inDocument() || !isOldest())
if (!insertionPoint->inDocument())
return;
// FIXME: When parsing <video controls>, insertedInto() is called many times without invoking removedFrom.

View File

@ -31,7 +31,6 @@
#include "sky/engine/core/dom/DocumentFragment.h"
#include "sky/engine/core/dom/Element.h"
#include "sky/engine/core/dom/TreeScope.h"
#include "sky/engine/wtf/DoublyLinkedList.h"
namespace blink {
@ -42,9 +41,8 @@ class InsertionPoint;
class ShadowRootRareData;
class StyleSheetList;
class ShadowRoot final : public DocumentFragment, public TreeScope, public DoublyLinkedListNode<ShadowRoot> {
class ShadowRoot final : public DocumentFragment, public TreeScope {
DEFINE_WRAPPERTYPEINFO();
friend class WTF::DoublyLinkedListNode<ShadowRoot>;
public:
static PassRefPtr<ShadowRoot> create(Document& document)
@ -61,12 +59,6 @@ public:
Element* host() const { return toElement(parentOrShadowHostNode()); }
ElementShadow* owner() const { return host() ? host()->shadow() : 0; }
ShadowRoot* youngerShadowRoot() const { return prev(); }
bool isYoungest() const { return !youngerShadowRoot(); }
bool isOldest() const { return !olderShadowRoot(); }
bool isOldestAuthorShadowRoot() const;
virtual void insertedInto(ContainerNode*) override;
virtual void removedFrom(ContainerNode*) override;
@ -92,8 +84,6 @@ public:
public:
Element* activeElement() const;
ShadowRoot* olderShadowRoot() const { return next(); }
PassRefPtr<Node> cloneNode(bool, ExceptionState&);
PassRefPtr<Node> cloneNode(ExceptionState& exceptionState) { return cloneNode(true, exceptionState); }
@ -116,11 +106,6 @@ private:
// ShadowRoots should never be cloned.
virtual PassRefPtr<Node> cloneNode(bool) override { return nullptr; }
// FIXME: This shouldn't happen. https://bugs.webkit.org/show_bug.cgi?id=88834
bool isOrphan() const { return !host(); }
RawPtr<ShadowRoot> m_prev;
RawPtr<ShadowRoot> m_next;
OwnPtr<ShadowRootRareData> m_shadowRootRareData;
unsigned m_numberOfStyles : 27;
unsigned m_registeredWithParentShadowRoot : 1;

View File

@ -26,7 +26,6 @@
interface ShadowRoot : DocumentFragment {
readonly attribute Element activeElement;
readonly attribute ShadowRoot olderShadowRoot;
[RaisesException] Node cloneNode([Default=Undefined] optional boolean deep);
Selection getSelection();

View File

@ -461,23 +461,12 @@ void TextIterator::advance()
}
if (!next && !parentNode && m_shadowDepth > 0) {
// 4. Reached the top of a shadow root. If it's created by author, then try to visit the next
// sibling shadow root, if any.
// 4. Reached the top of a shadow root.
ShadowRoot* shadowRoot = toShadowRoot(m_node);
ShadowRoot* nextShadowRoot = shadowRoot->olderShadowRoot();
if (nextShadowRoot) {
m_fullyClippedStack.pop();
m_node = nextShadowRoot;
m_iterationProgress = HandledNone;
// m_shadowDepth is unchanged since we exit from a shadow root and enter another.
pushFullyClippedState(m_fullyClippedStack, m_node);
} else {
// We are the last shadow root; exit from here and go back to where we were.
m_node = shadowRoot->host();
m_iterationProgress = HandledAuthorShadowRoots;
--m_shadowDepth;
m_fullyClippedStack.pop();
}
m_node = shadowRoot->host();
m_iterationProgress = HandledAuthorShadowRoots;
--m_shadowDepth;
m_fullyClippedStack.pop();
continue;
}
}

View File

@ -138,9 +138,9 @@ void EventPath::calculateTreeScopePrePostOrderNumbers()
TreeScopeEventContext* rootTree = 0;
for (size_t i = 0; i < m_treeScopeEventContexts.size(); ++i) {
TreeScopeEventContext* treeScopeEventContext = m_treeScopeEventContexts[i].get();
// Use olderShadowRootOrParentTreeScope here for parent-child relationships.
// Use parentTreeScope here for parent-child relationships.
// See the definition of trees of trees in the Shado DOM spec: http://w3c.github.io/webcomponents/spec/shadow/
TreeScope* parent = treeScopeEventContext->treeScope().olderShadowRootOrParentTreeScope();
TreeScope* parent = treeScopeEventContext->treeScope().parentTreeScope();
if (!parent) {
ASSERT(!rootTree);
rootTree = treeScopeEventContext;
@ -167,7 +167,7 @@ TreeScopeEventContext* EventPath::ensureTreeScopeEventContext(Node* currentTarge
treeScopeEventContext = addResult.storedValue->value.get();
}
if (isNewEntry) {
TreeScopeEventContext* parentTreeScopeEventContext = ensureTreeScopeEventContext(0, treeScope->olderShadowRootOrParentTreeScope(), treeScopeEventContextMap);
TreeScopeEventContext* parentTreeScopeEventContext = ensureTreeScopeEventContext(0, treeScope->parentTreeScope(), treeScopeEventContextMap);
if (parentTreeScopeEventContext && parentTreeScopeEventContext->target()) {
treeScopeEventContext->setTarget(parentTreeScopeEventContext->target());
} else if (currentTarget) {
@ -219,7 +219,7 @@ EventTarget* EventPath::findRelatedNode(TreeScope* scope, RelatedTargetMap& rela
relatedNode = iter->value;
break;
}
scope = scope->olderShadowRootOrParentTreeScope();
scope = scope->parentTreeScope();
}
ASSERT(relatedNode);
for (Vector<RawPtr<TreeScope>, 32>::iterator iter = parentTreeScopes.begin(); iter < parentTreeScopes.end(); ++iter)

View File

@ -96,7 +96,7 @@ FocusNavigationScope FocusNavigationScope::ownedByNonFocusableFocusScopeOwner(No
FocusNavigationScope FocusNavigationScope::ownedByShadowHost(Node* node)
{
ASSERT(isShadowHost(node));
return FocusNavigationScope(toElement(node)->shadow()->youngestShadowRoot());
return FocusNavigationScope(toElement(node)->shadow()->shadowRoot());
}
static inline void dispatchEventsOnWindowAndFocusedNode(Document* document, bool focused)

View File

@ -4,7 +4,7 @@ document.addEventListener('touchstart', function() {});
window.addEventListener('load', function() {
// Create any shadow DOM nodes requested by the test.
var shadowTrees = document.querySelectorAll('[make-shadow-dom]');
if (shadowTrees.length > 0 && !HTMLElement.prototype.createShadowRoot) {
if (shadowTrees.length > 0 && !HTMLElement.prototype.ensureShadowRoot) {
document.body.innerHTML = 'ERROR: Shadow DOM not supported!';
return;
}
@ -16,7 +16,7 @@ window.addEventListener('load', function() {
return;
}
tree.parentElement.removeChild(tree);
var shadowRoot = host.createShadowRoot();
var shadowRoot = host.ensureShadowRoot();
shadowRoot.appendChild(tree);
}
});

View File

@ -31,7 +31,7 @@ var BasePrototype = createPrototype(HTMLElement.prototype, {
if (!this.shadowRoot) {
var template = templates.get(this.localName);
if (template) {
var shadow = this.createShadowRoot();
var shadow = this.ensureShadowRoot();
shadow.appendChild(template.createInstance(this));
}
}

View File

@ -53,7 +53,7 @@ describe("appendChild", function() {
it("should throw when inserting a tree scope", function() {
var parent = document.createElement("div");
var doc = new Document();
var shadowRoot = document.createElement("span").createShadowRoot();
var shadowRoot = document.createElement("span").ensureShadowRoot();
assert.throws(function() {
parent.appendChild(doc);
});

View File

@ -67,7 +67,7 @@ describe("replaceChild", function() {
it("should throw when inserting a tree scope", function() {
var parent = document.createElement("div");
var doc = new Document();
var shadowRoot = document.createElement("span").createShadowRoot();
var shadowRoot = document.createElement("span").ensureShadowRoot();
assert.throws(function() {
parent.replaceChild(doc);
});

View File

@ -13,7 +13,7 @@ describe('MutationObservers', function() {
}
var range = document.getElementById('range');
var shadowRoot = range.createShadowRoot();
var shadowRoot = range.ensureShadowRoot();
shadowRoot.appendChild(document.createElement('div'));
var observer = new MutationObserver(function() { });