Commit f269b27a authored by antti@apple.com's avatar antti@apple.com

<https://webkit.org/b/119865> Parent pointer and shadow root host pointer should not be shared

Reviewed by Andreas Kling.

Node::m_parentOrShadowHostNode is currently used both as the parent pointer for regular nodes and as the host
pointer for ShadowRoots. This is confusing. It is also slow as it introduces a branch to all code paths that 
want to traverse ancestors normally, without leaving the shadow trees. This is much more popular than
traversing through.
        
This patch makes the Node have a pure parent pointer only and adds the host element pointer as a separate
member in ShadowRoot. This eliminates the ShadowRoot test branch from Node::parentNode() as the pointer is
now always null in the root node.
        
ShadowRoot grows by a pointer. This is not significant as there are few ShadowRoots compared to Nodes.

* css/StyleResolver.cpp:
(WebCore::StyleResolver::pushParentShadowRoot):
(WebCore::StyleResolver::popParentShadowRoot):
* dom/Attr.cpp:
(WebCore::Attr::createTextChild):
* dom/ComposedShadowTreeWalker.cpp:
(WebCore::ComposedShadowTreeWalker::traverseParentBackToShadowRootOrHost):
* dom/ContainerNode.cpp:
(WebCore::ContainerNode::insertBeforeCommon):
(WebCore::ContainerNode::removeBetween):
* dom/ContainerNodeAlgorithms.cpp:
(WebCore::ChildNodeInsertionNotifier::notifyDescendantInsertedIntoDocument):
(WebCore::ChildNodeRemovalNotifier::notifyDescendantRemovedFromDocument):
* dom/ContainerNodeAlgorithms.h:
(WebCore::appendChildToContainer):
(WebCore::Private::addChildNodesToDeletionQueue):
* dom/Document.h:
(WebCore::Node::Node):
* dom/Element.cpp:
(WebCore::Element::addShadowRoot):
(WebCore::Element::removeShadowRoot):
* dom/ElementRareData.h:
(WebCore::ElementRareData::releasePseudoElement):
* dom/EventPathWalker.cpp:
(WebCore::EventPathWalker::moveToParent):
* dom/EventRetargeter.cpp:
(WebCore::determineDispatchBehavior):
* dom/EventRetargeter.h:
(WebCore::EventRetargeter::eventTargetRespectingTargetRules):
* dom/Node.cpp:
(WebCore::Node::shadowHost):
(WebCore::Node::deprecatedShadowAncestorNode):
(WebCore::Node::parentOrShadowHostElement):
* dom/Node.h:
(WebCore::Node::hasTreeSharedParent):
        
    Shadow host elements refs the ShadowRoot. There is no reason to use TreeShared to keep it alive.

(WebCore::Node::setParentNode):
(WebCore::Node::parentNode):
(WebCore::Node::parentNodeGuaranteedHostFree):
* dom/PseudoElement.cpp:
(WebCore::PseudoElement::PseudoElement):
* dom/ShadowRoot.cpp:
(WebCore::ShadowRoot::ShadowRoot):
(WebCore::ShadowRoot::setInnerHTML):
(WebCore::ShadowRoot::setApplyAuthorStyles):
(WebCore::ShadowRoot::setResetStyleInheritance):
* dom/ShadowRoot.h:
        
    Rename host() -> hostElement() for clarity.

(WebCore::Node::parentOrShadowHostNode):
* dom/Text.cpp:
(WebCore::isSVGShadowText):
* dom/TreeScope.cpp:
(WebCore::TreeScope::focusedElement):
* html/shadow/ContentDistributor.cpp:
(WebCore::ContentDistributor::ensureDistribution):
* html/shadow/InsertionPoint.cpp:
(WebCore::InsertionPoint::insertedInto):
(WebCore::InsertionPoint::removedFrom):
(WebCore::InsertionPoint::parseAttribute):
* page/DragController.cpp:
(WebCore::asFileInput):
* page/EventHandler.cpp:
(WebCore::EventHandler::handleMousePressEvent):
(WebCore::instanceAssociatedWithShadowTreeElement):
* page/FocusController.cpp:
(WebCore::FocusNavigationScope::owner):
* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::hasLineIfEmpty):
* rendering/RenderLayer.cpp:
(WebCore::rendererForScrollbar):
* svg/SVGElementInstance.h:
(WebCore::SVGElementInstance::setParentNode):
            
    Renamed so it works with appendChildToContainer template.

* svg/SVGStyledElement.cpp:
(WebCore::SVGStyledElement::title):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@154165 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 3b296395
2013-08-15 Antti Koivisto <antti@apple.com>
<https://webkit.org/b/119865> Parent pointer and shadow root host pointer should not be shared
Reviewed by Andreas Kling.
Node::m_parentOrShadowHostNode is currently used both as the parent pointer for regular nodes and as the host
pointer for ShadowRoots. This is confusing. It is also slow as it introduces a branch to all code paths that
want to traverse ancestors normally, without leaving the shadow trees. This is much more popular than
traversing through.
This patch makes the Node have a pure parent pointer only and adds the host element pointer as a separate
member in ShadowRoot. This eliminates the ShadowRoot test branch from Node::parentNode() as the pointer is
now always null in the root node.
ShadowRoot grows by a pointer. This is not significant as there are few ShadowRoots compared to Nodes.
* css/StyleResolver.cpp:
(WebCore::StyleResolver::pushParentShadowRoot):
(WebCore::StyleResolver::popParentShadowRoot):
* dom/Attr.cpp:
(WebCore::Attr::createTextChild):
* dom/ComposedShadowTreeWalker.cpp:
(WebCore::ComposedShadowTreeWalker::traverseParentBackToShadowRootOrHost):
* dom/ContainerNode.cpp:
(WebCore::ContainerNode::insertBeforeCommon):
(WebCore::ContainerNode::removeBetween):
* dom/ContainerNodeAlgorithms.cpp:
(WebCore::ChildNodeInsertionNotifier::notifyDescendantInsertedIntoDocument):
(WebCore::ChildNodeRemovalNotifier::notifyDescendantRemovedFromDocument):
* dom/ContainerNodeAlgorithms.h:
(WebCore::appendChildToContainer):
(WebCore::Private::addChildNodesToDeletionQueue):
* dom/Document.h:
(WebCore::Node::Node):
* dom/Element.cpp:
(WebCore::Element::addShadowRoot):
(WebCore::Element::removeShadowRoot):
* dom/ElementRareData.h:
(WebCore::ElementRareData::releasePseudoElement):
* dom/EventPathWalker.cpp:
(WebCore::EventPathWalker::moveToParent):
* dom/EventRetargeter.cpp:
(WebCore::determineDispatchBehavior):
* dom/EventRetargeter.h:
(WebCore::EventRetargeter::eventTargetRespectingTargetRules):
* dom/Node.cpp:
(WebCore::Node::shadowHost):
(WebCore::Node::deprecatedShadowAncestorNode):
(WebCore::Node::parentOrShadowHostElement):
* dom/Node.h:
(WebCore::Node::hasTreeSharedParent):
Shadow host elements refs the ShadowRoot. There is no reason to use TreeShared to keep it alive.
(WebCore::Node::setParentNode):
(WebCore::Node::parentNode):
(WebCore::Node::parentNodeGuaranteedHostFree):
* dom/PseudoElement.cpp:
(WebCore::PseudoElement::PseudoElement):
* dom/ShadowRoot.cpp:
(WebCore::ShadowRoot::ShadowRoot):
(WebCore::ShadowRoot::setInnerHTML):
(WebCore::ShadowRoot::setApplyAuthorStyles):
(WebCore::ShadowRoot::setResetStyleInheritance):
* dom/ShadowRoot.h:
Rename host() -> hostElement() for clarity.
(WebCore::Node::parentOrShadowHostNode):
* dom/Text.cpp:
(WebCore::isSVGShadowText):
* dom/TreeScope.cpp:
(WebCore::TreeScope::focusedElement):
* html/shadow/ContentDistributor.cpp:
(WebCore::ContentDistributor::ensureDistribution):
* html/shadow/InsertionPoint.cpp:
(WebCore::InsertionPoint::insertedInto):
(WebCore::InsertionPoint::removedFrom):
(WebCore::InsertionPoint::parseAttribute):
* page/DragController.cpp:
(WebCore::asFileInput):
* page/EventHandler.cpp:
(WebCore::EventHandler::handleMousePressEvent):
(WebCore::instanceAssociatedWithShadowTreeElement):
* page/FocusController.cpp:
(WebCore::FocusNavigationScope::owner):
* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::hasLineIfEmpty):
* rendering/RenderLayer.cpp:
(WebCore::rendererForScrollbar):
* svg/SVGElementInstance.h:
(WebCore::SVGElementInstance::setParentNode):
Renamed so it works with appendChildToContainer template.
* svg/SVGStyledElement.cpp:
(WebCore::SVGStyledElement::title):
2013-08-13 Darin Adler <darin@apple.com>
[iOS] Get iOS port off legacy clipboard
......@@ -29,6 +29,7 @@
#include "JSDOMBinding.h"
#include "JSNode.h"
#include "ScriptState.h"
#include "ShadowRoot.h"
namespace WebCore {
......
......@@ -88,7 +88,7 @@ void SelectorFilter::setupParentStack(Element* parent)
m_parentStack.shrink(0);
m_ancestorIdentifierFilter = adoptPtr(new BloomFilter<bloomFilterKeyBits>);
// Fast version if parent is a root element:
if (!parent->parentOrShadowHostNode()) {
if (!parent->parentNode() && !parent->isShadowRoot()) {
pushParentStackFrame(parent);
return;
}
......
......@@ -336,14 +336,14 @@ void StyleResolver::popParentElement(Element* parent)
void StyleResolver::pushParentShadowRoot(const ShadowRoot* shadowRoot)
{
ASSERT(shadowRoot->host());
ASSERT(shadowRoot->hostElement());
if (m_scopeResolver)
m_scopeResolver->push(shadowRoot, shadowRoot->host());
m_scopeResolver->push(shadowRoot, shadowRoot->hostElement());
}
void StyleResolver::popParentShadowRoot(const ShadowRoot* shadowRoot)
{
ASSERT(shadowRoot->host());
ASSERT(shadowRoot->hostElement());
if (m_scopeResolver)
m_scopeResolver->pop(shadowRoot);
}
......
......@@ -82,7 +82,7 @@ void Attr::createTextChild()
// This does everything appendChild() would do in this situation (assuming m_ignoreChildrenChanged was set),
// but much more efficiently.
textNode->setParentOrShadowHostNode(this);
textNode->setParentNode(this);
setFirstChild(textNode.get());
setLastChild(textNode.get());
}
......
......@@ -233,7 +233,7 @@ Node* ComposedShadowTreeWalker::traverseParentBackToShadowRootOrHost(const Shado
if (canCrossUpperBoundary()) {
if (details)
details->didTraverseShadowRoot(shadowRoot);
return shadowRoot->host();
return shadowRoot->hostElement();
}
return const_cast<ShadowRoot*>(shadowRoot);
......
......@@ -345,7 +345,7 @@ void ContainerNode::insertBeforeCommon(Node* nextChild, Node* newChild)
ASSERT(m_firstChild == nextChild);
m_firstChild = newChild;
}
newChild->setParentOrShadowHostNode(this);
newChild->setParentNode(this);
newChild->setPreviousSibling(prev);
newChild->setNextSibling(nextChild);
}
......@@ -579,7 +579,7 @@ void ContainerNode::removeBetween(Node* previousChild, Node* nextChild, Node* ol
oldChild->setPreviousSibling(0);
oldChild->setNextSibling(0);
oldChild->setParentOrShadowHostNode(0);
oldChild->setParentNode(0);
document()->adoptIfNeeded(oldChild);
}
......
......@@ -46,7 +46,7 @@ void ChildNodeInsertionNotifier::notifyDescendantInsertedIntoDocument(ContainerN
return;
if (RefPtr<ShadowRoot> root = toElement(node)->shadowRoot()) {
if (node->inDocument() && root->host() == node)
if (node->inDocument() && root->hostElement() == node)
notifyNodeInsertedIntoDocument(root.get());
}
}
......@@ -80,7 +80,7 @@ void ChildNodeRemovalNotifier::notifyDescendantRemovedFromDocument(ContainerNode
node->document()->setCSSTarget(0);
if (RefPtr<ShadowRoot> root = toElement(node)->shadowRoot()) {
if (!node->inDocument() && root->host() == node)
if (!node->inDocument() && root->hostElement() == node)
notifyNodeRemovedFromDocument(root.get());
}
}
......
......@@ -109,7 +109,7 @@ inline void removeDetachedChildrenInContainer(GenericNodeContainer* container)
template<class GenericNode, class GenericNodeContainer>
inline void appendChildToContainer(GenericNode* child, GenericNodeContainer* container)
{
child->setParentOrShadowHostNode(container);
child->setParentNode(container);
GenericNode* lastChild = container->lastChild();
if (lastChild) {
......@@ -164,7 +164,7 @@ namespace Private {
next = n->nextSibling();
n->setNextSibling(0);
n->setParentOrShadowHostNode(0);
n->setParentNode(0);
container->setFirstChild(next);
if (next)
next->setPreviousSibling(0);
......
......@@ -1615,7 +1615,7 @@ inline bool Node::isDocumentNode() const
inline Node::Node(Document* document, ConstructionType type)
: m_nodeFlags(type)
, m_parentOrShadowHostNode(0)
, m_parentNode(0)
, m_treeScope(document)
, m_previous(0)
, m_next(0)
......
......@@ -1588,7 +1588,7 @@ void Element::addShadowRoot(PassRefPtr<ShadowRoot> newShadowRoot)
ShadowRoot* shadowRoot = newShadowRoot.get();
ensureElementRareData().setShadowRoot(newShadowRoot);
shadowRoot->setParentOrShadowHostNode(this);
shadowRoot->setHostElement(this);
shadowRoot->setParentTreeScope(treeScope());
shadowRoot->distributor().didShadowBoundaryChange(this);
......@@ -1619,7 +1619,7 @@ void Element::removeShadowRoot()
elementRareData()->clearShadowRoot();
oldRoot->setParentOrShadowHostNode(0);
oldRoot->setHostElement(0);
oldRoot->setParentTreeScope(document());
ChildNodeRemovalNotifier(this).notify(oldRoot.get());
......
......@@ -942,25 +942,6 @@ inline UniqueElementData& Element::ensureUniqueElementData()
return static_cast<UniqueElementData&>(*m_elementData);
}
inline Node::InsertionNotificationRequest Node::insertedInto(ContainerNode* insertionPoint)
{
ASSERT(insertionPoint->inDocument() || isContainerNode());
if (insertionPoint->inDocument())
setFlag(InDocumentFlag);
if (parentOrShadowHostNode()->isInShadowTree())
setFlag(IsInShadowTreeFlag);
return InsertionDone;
}
inline void Node::removedFrom(ContainerNode* insertionPoint)
{
ASSERT(insertionPoint->inDocument() || isContainerNode());
if (insertionPoint->inDocument())
clearFlag(InDocumentFlag);
if (isInShadowTree() && !treeScope()->rootNode()->isShadowRoot())
clearFlag(IsInShadowTreeFlag);
}
inline bool isShadowHost(const Node* node)
{
return node && node->isElementNode() && toElement(node)->shadowRoot();
......
......@@ -258,7 +258,7 @@ inline void ElementRareData::releasePseudoElement(PseudoElement* element)
ASSERT(!element->nextSibling());
ASSERT(!element->previousSibling());
element->setParentOrShadowHostNode(0);
element->setParentNode(0);
}
inline void ElementRareData::resetComputedStyle()
......
......@@ -64,7 +64,7 @@ void EventPathWalker::moveToParent()
m_isVisitingInsertionPointInReprojection = false;
return;
}
m_node = toShadowRoot(m_node)->host();
m_node = toShadowRoot(m_node)->hostElement();
m_distributedNode = m_node;
m_isVisitingInsertionPointInReprojection = false;
}
......
......@@ -49,7 +49,7 @@ static inline EventDispatchBehavior determineDispatchBehavior(Event* event, Shad
if (Element* element = target->toNode()->document()->webkitCurrentFullScreenElement()) {
// FIXME: We assume that if the full screen element is a media element that it's
// the video-only full screen. Both here and elsewhere. But that is probably wrong.
if (element->isMediaElement() && shadowRoot && shadowRoot->host() == element)
if (element->isMediaElement() && shadowRoot && shadowRoot->hostElement() == element)
return StayInsideShadowDOM;
}
#else
......
......@@ -89,7 +89,7 @@ inline EventTarget* EventRetargeter::eventTargetRespectingTargetRules(Node* refe
// Spec: The event handling for the non-exposed tree works as if the referenced element had been textually included
// as a deeply cloned child of the 'use' element, except that events are dispatched to the SVGElementInstance objects
Element* shadowHostElement = toShadowRoot(referenceNode->treeScope()->rootNode())->host();
Element* shadowHostElement = toShadowRoot(referenceNode->treeScope()->rootNode())->hostElement();
// At this time, SVG nodes are not supported in non-<use> shadow trees.
if (!shadowHostElement || !shadowHostElement->hasTagName(SVGNames::useTag))
return referenceNode;
......
......@@ -986,14 +986,14 @@ bool Node::isRegisteredWithNamedFlow() const
Element* Node::shadowHost() const
{
if (ShadowRoot* root = containingShadowRoot())
return root->host();
return root->hostElement();
return 0;
}
Node* Node::deprecatedShadowAncestorNode() const
{
if (ShadowRoot* root = containingShadowRoot())
return root->host();
return root->hostElement();
return const_cast<Node*>(this);
}
......@@ -1032,7 +1032,7 @@ Element* Node::parentOrShadowHostElement() const
return 0;
if (parent->isShadowRoot())
return toShadowRoot(parent)->host();
return toShadowRoot(parent)->hostElement();
if (!parent->isElementNode())
return 0;
......@@ -1045,6 +1045,25 @@ Node* Node::insertionParentForBinding() const
return resolveReprojection(this);
}
Node::InsertionNotificationRequest Node::insertedInto(ContainerNode* insertionPoint)
{
ASSERT(insertionPoint->inDocument() || isContainerNode());
if (insertionPoint->inDocument())
setFlag(InDocumentFlag);
if (parentOrShadowHostNode()->isInShadowTree())
setFlag(IsInShadowTreeFlag);
return InsertionDone;
}
void Node::removedFrom(ContainerNode* insertionPoint)
{
ASSERT(insertionPoint->inDocument() || isContainerNode());
if (insertionPoint->inDocument())
clearFlag(InDocumentFlag);
if (isInShadowTree() && !treeScope()->rootNode()->isShadowRoot())
clearFlag(IsInShadowTreeFlag);
}
bool Node::needsShadowTreeWalkerSlow() const
{
return (isShadowRoot() || (isElementNode() && (isInsertionPoint() || isPseudoElement() || toElement(this)->hasPseudoElements() || toElement(this)->shadowRoot())));
......
......@@ -284,10 +284,10 @@ public:
// Returns 0, a child of ShadowRoot, or a legacy shadow root.
Node* nonBoundaryShadowTreeRootNode();
// Node's parent, shadow tree host.
// Node's parent or shadow tree host.
ContainerNode* parentOrShadowHostNode() const;
Element* parentOrShadowHostElement() const;
void setParentOrShadowHostNode(ContainerNode*);
void setParentNode(ContainerNode*);
Node* highestAncestor() const;
// Use when it's guaranteed to that shadowHost is 0.
......@@ -698,7 +698,7 @@ private:
}
void removedLastRef();
bool hasTreeSharedParent() const { return !!parentOrShadowHostNode(); }
bool hasTreeSharedParent() const { return !!parentNode(); }
enum EditableLevel { Editable, RichlyEditable };
bool rendererIsEditable(EditableLevel, UserSelectAllTreatment = UserSelectAllIsAlwaysNonEditable) const;
......@@ -718,7 +718,7 @@ private:
HashSet<MutationObserverRegistration*>* transientMutationObserverRegistry();
mutable uint32_t m_nodeFlags;
ContainerNode* m_parentOrShadowHostNode;
ContainerNode* m_parentNode;
TreeScope* m_treeScope;
Node* m_previous;
Node* m_next;
......@@ -748,27 +748,22 @@ inline void addSubresourceURL(ListHashSet<KURL>& urls, const KURL& url)
urls.add(url);
}
inline void Node::setParentOrShadowHostNode(ContainerNode* parent)
inline void Node::setParentNode(ContainerNode* parent)
{
ASSERT(isMainThread());
m_parentOrShadowHostNode = parent;
}
inline ContainerNode* Node::parentOrShadowHostNode() const
{
ASSERT(isMainThreadOrGCThread());
return m_parentOrShadowHostNode;
m_parentNode = parent;
}
inline ContainerNode* Node::parentNode() const
{
return isShadowRoot() ? 0 : parentOrShadowHostNode();
ASSERT(isMainThreadOrGCThread());
return m_parentNode;
}
inline ContainerNode* Node::parentNodeGuaranteedHostFree() const
{
ASSERT(!isShadowRoot());
return parentOrShadowHostNode();
return parentNode();
}
} //namespace
......
......@@ -60,7 +60,8 @@ PseudoElement::PseudoElement(Element* parent, PseudoId pseudoId)
, m_pseudoId(pseudoId)
{
ASSERT(pseudoId != NOPSEUDO);
setParentOrShadowHostNode(parent);
// FIXME: This is wrong in terms of tree consistency. Pseudo element is now not a child of its parent.
setParentNode(parent);
setHasCustomStyleCallbacks();
}
......
......@@ -41,6 +41,7 @@ namespace WebCore {
struct SameSizeAsShadowRoot : public DocumentFragment, public TreeScope {
unsigned countersAndFlags[1];
ContentDistributor distributor;
void* host;
};
COMPILE_ASSERT(sizeof(ShadowRoot) == sizeof(SameSizeAsShadowRoot), shadowroot_should_stay_small);
......@@ -58,6 +59,7 @@ ShadowRoot::ShadowRoot(Document* document, ShadowRootType type)
, m_applyAuthorStyles(false)
, m_resetStyleInheritance(false)
, m_type(type)
, m_hostElement(0)
{
ASSERT(document);
}
......@@ -104,7 +106,7 @@ void ShadowRoot::setInnerHTML(const String& markup, ExceptionCode& ec)
return;
}
if (RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(markup, host(), AllowScriptingContent, ec))
if (RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(markup, hostElement(), AllowScriptingContent, ec))
replaceChildrenWithFragment(this, fragment.release(), ec);
}
......@@ -130,7 +132,7 @@ void ShadowRoot::setApplyAuthorStyles(bool value)
if (m_applyAuthorStyles != value) {
m_applyAuthorStyles = value;
host()->setNeedsStyleRecalc();
hostElement()->setNeedsStyleRecalc();
}
}
......@@ -141,8 +143,8 @@ void ShadowRoot::setResetStyleInheritance(bool value)
if (value != m_resetStyleInheritance) {
m_resetStyleInheritance = value;
if (attached() && host())
Style::resolveTree(host(), Style::Force);
if (attached() && hostElement())
Style::resolveTree(hostElement(), Style::Force);
}
}
......
......@@ -60,7 +60,8 @@ public:
virtual bool resetStyleInheritance() const OVERRIDE { return m_resetStyleInheritance; }
void setResetStyleInheritance(bool);
Element* host() const { return toElement(parentOrShadowHostNode()); }
Element* hostElement() const { return m_hostElement; }
void setHostElement(Element* hostElement) { m_hostElement = hostElement; }
String innerHTML() const;
void setInnerHTML(const String&, ExceptionCode&);
......@@ -78,7 +79,7 @@ public:
PassRefPtr<Node> cloneNode(bool, ExceptionCode&);
ContentDistributor& distributor() { return m_distributor; }
void invalidateDistribution() { m_distributor.invalidateDistribution(host()); }
void invalidateDistribution() { m_distributor.invalidateDistribution(hostElement()); }
void removeAllEventListeners();
......@@ -93,13 +94,15 @@ private:
virtual PassRefPtr<Node> cloneNode(bool) OVERRIDE { return 0; }
// FIXME: This shouldn't happen. https://bugs.webkit.org/show_bug.cgi?id=88834
bool isOrphan() const { return !host(); }
bool isOrphan() const { return !hostElement(); }
unsigned m_numberOfStyles : 28;
unsigned m_applyAuthorStyles : 1;
unsigned m_resetStyleInheritance : 1;
unsigned m_type : 1;
Element* m_hostElement;
ContentDistributor m_distributor;
};
......@@ -126,6 +129,14 @@ inline ShadowRoot* Node::shadowRoot() const
return toElement(this)->shadowRoot();
}
inline ContainerNode* Node::parentOrShadowHostNode() const
{
ASSERT(isMainThreadOrGCThread());
if (isShadowRoot())
return toShadowRoot(this)->hostElement();
return parentNode();
}
} // namespace
#endif
......@@ -255,7 +255,7 @@ bool Text::textRendererIsNeeded(const NodeRenderingContext& context)
static bool isSVGShadowText(Text* text)
{
Node* parentNode = text->parentNode();
return parentNode->isShadowRoot() && toShadowRoot(parentNode)->host()->hasTagName(SVGNames::trefTag);
return parentNode->isShadowRoot() && toShadowRoot(parentNode)->hostElement()->hasTagName(SVGNames::trefTag);
}
static bool isSVGText(Text* text)
......
......@@ -400,7 +400,7 @@ Element* TreeScope::focusedElement()
return 0;
TreeScope* treeScope = element->treeScope();
while (treeScope != this && treeScope != document) {
element = toShadowRoot(treeScope->rootNode())->host();
element = toShadowRoot(treeScope->rootNode())->hostElement();
treeScope = element->treeScope();
}
if (this != treeScope)
......
......@@ -25,6 +25,7 @@
#include "Frame.h"
#include "FrameLoader.h"
#include "RenderPart.h"
#include "ShadowRoot.h"
#if ENABLE(SVG)
#include "ExceptionCode.h"
......@@ -124,4 +125,13 @@ SVGDocument* HTMLFrameOwnerElement::getSVGDocument(ExceptionCode& ec) const
}
#endif
bool SubframeLoadingDisabler::canLoadFrame(HTMLFrameOwnerElement* owner)
{
for (Node* node = owner; node; node = node->parentOrShadowHostNode()) {
if (disabledSubtreeRoots().contains(node))
return false;
}
return true;
}
} // namespace WebCore
......@@ -90,14 +90,7 @@ public:
disabledSubtreeRoots().remove(m_root);
}
static bool canLoadFrame(HTMLFrameOwnerElement* owner)
{
for (Node* node = owner; node; node = node->parentOrShadowHostNode()) {
if (disabledSubtreeRoots().contains(node))
return false;
}
return true;
}
static bool canLoadFrame(HTMLFrameOwnerElement*);
private:
static HashSet<Node*>& disabledSubtreeRoots()
......
......@@ -43,6 +43,7 @@
#include "NodeList.h"
#include "RawDataDocumentParser.h"
#include "ScriptController.h"
#include "ShadowRoot.h"
namespace WebCore {
......
......@@ -130,7 +130,7 @@ void ContentDistributor::ensureDistribution(ShadowRoot* shadowRoot)
ASSERT(shadowRoot);
Vector<ShadowRoot*, 8> shadowRoots;
for (Element* current = shadowRoot->host(); current; current = current->shadowHost()) {
for (Element* current = shadowRoot->hostElement(); current; current = current->shadowHost()) {
ShadowRoot* currentRoot = current->shadowRoot();
if (!currentRoot->distributor().needsDistribution())
break;
......@@ -138,7 +138,7 @@ void ContentDistributor::ensureDistribution(ShadowRoot* shadowRoot)
}
for (size_t i = shadowRoots.size(); i > 0; --i)
shadowRoots[i - 1]->distributor().distribute(shadowRoots[i - 1]->host());
shadowRoots[i - 1]->distributor().distribute(shadowRoots[i - 1]->hostElement());
}
void ContentDistributor::invalidateDistribution(Element* host)
......
......@@ -125,7 +125,7 @@ Node::InsertionNotificationRequest InsertionPoint::insertedInto(ContainerNode* i
HTMLElement::insertedInto(insertionPoint);
if (ShadowRoot* root = containingShadowRoot()) {
root->distributor().didShadowBoundaryChange(root->host());
root->distributor().didShadowBoundaryChange(root->hostElement());
root->distributor().invalidateInsertionPointList();
}
......@@ -138,7 +138,7 @@ void InsertionPoint::removedFrom(ContainerNode* insertionPoint)
if (!root)
root = insertionPoint->containingShadowRoot();
if (root && root->host()) {
if (root && root->hostElement()) {
root->invalidateDistribution();
root->distributor().invalidateInsertionPointList();
}
......@@ -154,7 +154,7 @@ void InsertionPoint::parseAttribute(const QualifiedName& name, const AtomicStrin
if (name == reset_style_inheritanceAttr) {
if (!inDocument() || !attached() || !isActive())
return;
containingShadowRoot()->host()->setNeedsStyleRecalc();
containingShadowRoot()->hostElement()->setNeedsStyleRecalc();
} else
HTMLElement::parseAttribute(name, value);
}
......
......@@ -285,7 +285,7 @@ static HTMLInputElement* asFileInput(Node* node)
// If this is a button inside of the a file input, move up to the file input.
if (inputElement && inputElement->isTextButton() && inputElement->treeScope()->rootNode()->isShadowRoot())
inputElement = toShadowRoot(inputElement->treeScope()->rootNode())->host()->toInputElement();
inputElement = toShadowRoot(inputElement->treeScope()->rootNode())->hostElement()->toInputElement();
return inputElement && inputElement->isFileUpload() ? inputElement : 0;
}
......
......@@ -1619,7 +1619,7 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
// If a mouse event handler changes the input element type to one that has a widget associated,
// we'd like to EventHandler::handleMousePressEvent to pass the event to the widget and thus the
// event target node can't still be the shadow node.
if (mev.targetNode()->isShadowRoot() && isHTMLInputElement(toShadowRoot(mev.targetNode())->host())) {
if (mev.targetNode()->isShadowRoot() && isHTMLInputElement(toShadowRoot(mev.targetNode())->hostElement())) {
HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowShadowContent);
mev = m_frame->document()->prepareMouseEvent(request, documentPoint, mouseEvent);
}
......@@ -2179,7 +2179,7 @@ static inline SVGElementInstance* instanceAssociatedWithShadowTreeElement(Node*
if (!shadowRoot)
return 0;
Element* shadowTreeParentElement = shadowRoot->host();
Element* shadowTreeParentElement = shadowRoot->hostElement();
if (!shadowTreeParentElement || !shadowTreeParentElement->hasTagName(useTag))
return 0;