[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-10851-g50815da
dglazkov at chromium.org
dglazkov at chromium.org
Wed Dec 22 18:17:50 UTC 2010
The following commit has been merged in the debian/experimental branch:
commit e5cbec63042ea149426949f09ed10b9202a1f3ce
Author: dglazkov at chromium.org <dglazkov at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Thu Dec 9 17:23:00 2010 +0000
2010-12-08 Dimitri Glazkov <dglazkov at chromium.org>
Reviewed by Darin Adler.
Provide a generic way to store shadowParent on a Node.
https://bugs.webkit.org/show_bug.cgi?id=50184
This patch makes TreeShared::m_parent act as either parentNode() or
shadowHost() for Node. The distinction is controlled by IsShadowRootFlag.
Refactoring, so no new tests. See performance result testing in bug.
* dom/Element.cpp:
(WebCore::Element::recalcStyle): Changed to use parentOrHostNode().
* dom/Node.cpp:
(WebCore::Node::shadowHost): Added.
(WebCore::Node::setShadowHost): Added.
(WebCore::Node::isContentEditable): Changed to use parentOrHostNode().
(WebCore::Node::isContentRichlyEditable): Ditto.
(WebCore::Node::nextRenderer): Ditto.
(WebCore::Node::virtualComputedStyle): Ditto.
(WebCore::Node::canStartSelection): Ditto.
(WebCore::Node::shadowTreeRootNode): Changed to use parentNodeGuaranteedHostFree().
(WebCore::Node::getEventAncestors): Ditto.
(WebCore::Node::defaultEventHandler): Changed to use parentOrHostNode().
* dom/Node.h: Added an extra flag and adjusted bit counts.
(WebCore::Node::isShadowNode): Made non-virtual, switched to use flag.
(WebCore::Node::parentNode): Made to recognize flag.
(WebCore::Node::parentOrHostNode): Changed to use straight parent() and made const.
(WebCore::Node::parentNodeGuaranteedHostFree): Added.
(WebCore::Node::shadowParentNode): Made non-virtual and const.
* editing/TextIterator.cpp:
(WebCore::depthCrossingShadowBoundaries): Changed to use parentOrHostNode();
(WebCore::nextInPreOrderCrossingShadowBoundaries): Ditto.
(WebCore::previousInPostOrderCrossingShadowBoundaries): Ditto.
(WebCore::setUpFullyClippedStack): Ditto.
(WebCore::TextIterator::advance): Ditto.
(WebCore::SimplifiedBackwardsTextIterator::advance): Ditto.
* page/DOMSelection.cpp:
(WebCore::DOMSelection::anchorNode): Changed to use parentNodeGuaranteedHostFree().
(WebCore::DOMSelection::focusNode): Ditto.
(WebCore::DOMSelection::baseNode): Ditto.
(WebCore::DOMSelection::extentNode): Ditto.
(WebCore::DOMSelection::getRangeAt): Ditto.
* rendering/MediaControlElements.cpp:
(WebCore::MediaControlShadowRootElement::MediaControlShadowRootElement):
Changed to setShadowHost().
(WebCore::MediaControlShadowRootElement::updateStyle): Changed to use shadowHost().
(WebCore::MediaControlShadowRootElement::detach): Added an override to
explicitly set shadowHost to 0. Otherwise, the element will leak.
* rendering/MediaControlElements.h: Added detach def, removed members that are
no longer needed.
* rendering/RenderSVGShadowTreeRootContainer.cpp:
(WebCore::RenderSVGShadowTreeRootContainer::~RenderSVGShadowTreeRootContainer):
Added explicit clearing of shadowHost to avoid leaking and crashes,
because SVG shadow DOM can be dynamically attached/detached, producing
stale nodes in over/out event handling.
* rendering/RenderSlider.cpp:
(WebCore::SliderThumbElement::defaultEventHandler): Changed to use shadowHost().
* rendering/RenderTextControlSingleLine.cpp:
(WebCore::RenderTextControlSingleLine::~RenderTextControlSingleLine):
Added explicit clearing of shadowHost and explicit destruction to
avoid out-of-order removal of children.
* rendering/RenderTreeAsText.cpp:
(WebCore::nodePosition): Simplified code.
* rendering/SVGShadowTreeElements.cpp:
(WebCore::SVGShadowTreeRootElement::SVGShadowTreeRootElement): Added
setting of shadowHost.
(WebCore::SVGShadowTreeRootElement::attachElement): Changed to use shadowHost().
(WebCore::SVGShadowTreeRootElement::clearShadowHost): Added.
* rendering/SVGShadowTreeElements.h: Added def, removed members that are
no longer needed.
* rendering/ShadowElement.cpp:
(WebCore::ShadowBlockElement::initAsPart): Changed to use shadowHost().
* rendering/ShadowElement.h: Removed members that are no longer needed.
(WebCore::ShadowElement::ShadowElement): Added setting of shadowHost.
(WebCore::ShadowElement::detach): Added.
* rendering/TextControlInnerElements.cpp:
(WebCore::TextControlInnerElement::TextControlInnerElement): Added setting
of shadowHost.
(WebCore::TextControlInnerElement::attachInnerElement): Changed to use
isShadowNode().
(WebCore::TextControlInnerElement::detach): Added.
* rendering/TextControlInnerElements.h: Removed members that are no
longer needed.
* svg/SVGElement.cpp:
(WebCore::SVGElement::ownerSVGElement): Simplified code.
(WebCore::SVGElement::viewportElement): Ditto.
* svg/SVGLocatable.cpp:
(WebCore::SVGLocatable::computeCTM): Ditto.
* svg/SVGStyledElement.cpp:
(WebCore::SVGStyledElement::title): Ditto.
* svg/SVGUseElement.cpp:
(WebCore::ShadowTreeUpdateBlocker::while): Ditto.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@73618 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 28edc4a..c5aae5e 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,98 @@
+2010-12-08 Dimitri Glazkov <dglazkov at chromium.org>
+
+ Reviewed by Darin Adler.
+
+ Provide a generic way to store shadowParent on a Node.
+ https://bugs.webkit.org/show_bug.cgi?id=50184
+
+ This patch makes TreeShared::m_parent act as either parentNode() or
+ shadowHost() for Node. The distinction is controlled by IsShadowRootFlag.
+
+ Refactoring, so no new tests. See performance result testing in bug.
+
+ * dom/Element.cpp:
+ (WebCore::Element::recalcStyle): Changed to use parentOrHostNode().
+ * dom/Node.cpp:
+ (WebCore::Node::shadowHost): Added.
+ (WebCore::Node::setShadowHost): Added.
+ (WebCore::Node::isContentEditable): Changed to use parentOrHostNode().
+ (WebCore::Node::isContentRichlyEditable): Ditto.
+ (WebCore::Node::nextRenderer): Ditto.
+ (WebCore::Node::virtualComputedStyle): Ditto.
+ (WebCore::Node::canStartSelection): Ditto.
+ (WebCore::Node::shadowTreeRootNode): Changed to use parentNodeGuaranteedHostFree().
+ (WebCore::Node::getEventAncestors): Ditto.
+ (WebCore::Node::defaultEventHandler): Changed to use parentOrHostNode().
+ * dom/Node.h: Added an extra flag and adjusted bit counts.
+ (WebCore::Node::isShadowNode): Made non-virtual, switched to use flag.
+ (WebCore::Node::parentNode): Made to recognize flag.
+ (WebCore::Node::parentOrHostNode): Changed to use straight parent() and made const.
+ (WebCore::Node::parentNodeGuaranteedHostFree): Added.
+ (WebCore::Node::shadowParentNode): Made non-virtual and const.
+ * editing/TextIterator.cpp:
+ (WebCore::depthCrossingShadowBoundaries): Changed to use parentOrHostNode();
+ (WebCore::nextInPreOrderCrossingShadowBoundaries): Ditto.
+ (WebCore::previousInPostOrderCrossingShadowBoundaries): Ditto.
+ (WebCore::setUpFullyClippedStack): Ditto.
+ (WebCore::TextIterator::advance): Ditto.
+ (WebCore::SimplifiedBackwardsTextIterator::advance): Ditto.
+ * page/DOMSelection.cpp:
+ (WebCore::DOMSelection::anchorNode): Changed to use parentNodeGuaranteedHostFree().
+ (WebCore::DOMSelection::focusNode): Ditto.
+ (WebCore::DOMSelection::baseNode): Ditto.
+ (WebCore::DOMSelection::extentNode): Ditto.
+ (WebCore::DOMSelection::getRangeAt): Ditto.
+ * rendering/MediaControlElements.cpp:
+ (WebCore::MediaControlShadowRootElement::MediaControlShadowRootElement):
+ Changed to setShadowHost().
+ (WebCore::MediaControlShadowRootElement::updateStyle): Changed to use shadowHost().
+ (WebCore::MediaControlShadowRootElement::detach): Added an override to
+ explicitly set shadowHost to 0. Otherwise, the element will leak.
+ * rendering/MediaControlElements.h: Added detach def, removed members that are
+ no longer needed.
+ * rendering/RenderSVGShadowTreeRootContainer.cpp:
+ (WebCore::RenderSVGShadowTreeRootContainer::~RenderSVGShadowTreeRootContainer):
+ Added explicit clearing of shadowHost to avoid leaking and crashes,
+ because SVG shadow DOM can be dynamically attached/detached, producing
+ stale nodes in over/out event handling.
+ * rendering/RenderSlider.cpp:
+ (WebCore::SliderThumbElement::defaultEventHandler): Changed to use shadowHost().
+ * rendering/RenderTextControlSingleLine.cpp:
+ (WebCore::RenderTextControlSingleLine::~RenderTextControlSingleLine):
+ Added explicit clearing of shadowHost and explicit destruction to
+ avoid out-of-order removal of children.
+ * rendering/RenderTreeAsText.cpp:
+ (WebCore::nodePosition): Simplified code.
+ * rendering/SVGShadowTreeElements.cpp:
+ (WebCore::SVGShadowTreeRootElement::SVGShadowTreeRootElement): Added
+ setting of shadowHost.
+ (WebCore::SVGShadowTreeRootElement::attachElement): Changed to use shadowHost().
+ (WebCore::SVGShadowTreeRootElement::clearShadowHost): Added.
+ * rendering/SVGShadowTreeElements.h: Added def, removed members that are
+ no longer needed.
+ * rendering/ShadowElement.cpp:
+ (WebCore::ShadowBlockElement::initAsPart): Changed to use shadowHost().
+ * rendering/ShadowElement.h: Removed members that are no longer needed.
+ (WebCore::ShadowElement::ShadowElement): Added setting of shadowHost.
+ (WebCore::ShadowElement::detach): Added.
+ * rendering/TextControlInnerElements.cpp:
+ (WebCore::TextControlInnerElement::TextControlInnerElement): Added setting
+ of shadowHost.
+ (WebCore::TextControlInnerElement::attachInnerElement): Changed to use
+ isShadowNode().
+ (WebCore::TextControlInnerElement::detach): Added.
+ * rendering/TextControlInnerElements.h: Removed members that are no
+ longer needed.
+ * svg/SVGElement.cpp:
+ (WebCore::SVGElement::ownerSVGElement): Simplified code.
+ (WebCore::SVGElement::viewportElement): Ditto.
+ * svg/SVGLocatable.cpp:
+ (WebCore::SVGLocatable::computeCTM): Ditto.
+ * svg/SVGStyledElement.cpp:
+ (WebCore::SVGStyledElement::title): Ditto.
+ * svg/SVGUseElement.cpp:
+ (WebCore::ShadowTreeUpdateBlocker::while): Ditto.
+
2010-12-09 Hans Wennborg <hans at chromium.org>
Reviewed by Jeremy Orlow.
diff --git a/WebCore/dom/Element.cpp b/WebCore/dom/Element.cpp
index be400b8..30d239b 100644
--- a/WebCore/dom/Element.cpp
+++ b/WebCore/dom/Element.cpp
@@ -982,13 +982,10 @@ void Element::recalcStyle(StyleChange change)
{
// Ref currentStyle in case it would otherwise be deleted when setRenderStyle() is called.
RefPtr<RenderStyle> currentStyle(renderStyle());
- bool hasParentStyle = parentNode() ? parentNode()->renderStyle() : false;
+ bool hasParentStyle = parentOrHostNode() ? parentOrHostNode()->renderStyle() : false;
bool hasPositionalRules = needsStyleRecalc() && currentStyle && currentStyle->childrenAffectedByPositionalRules();
bool hasDirectAdjacentRules = currentStyle && currentStyle->childrenAffectedByDirectAdjacentRules();
- if (!hasParentStyle && isShadowNode())
- hasParentStyle = true;
-
if ((change > NoChange || needsStyleRecalc())) {
if (hasRareData())
rareData()->resetComputedStyle();
diff --git a/WebCore/dom/Node.cpp b/WebCore/dom/Node.cpp
index 216d119..564be32 100644
--- a/WebCore/dom/Node.cpp
+++ b/WebCore/dom/Node.cpp
@@ -480,7 +480,22 @@ NodeRareData* Node::createRareData()
{
return new NodeRareData;
}
-
+
+Element* Node::shadowHost() const
+{
+ return toElement(shadowParentNode());
+}
+
+void Node::setShadowHost(Element* host)
+{
+ if (host)
+ setFlag(IsShadowRootFlag);
+ else
+ clearFlag(IsShadowRootFlag);
+
+ setParent(host);
+}
+
short Node::tabIndex() const
{
return hasRareData() ? rareData()->tabIndex() : 0;
@@ -666,12 +681,12 @@ void Node::deprecatedParserAddChild(PassRefPtr<Node>)
bool Node::isContentEditable() const
{
- return parent() && parent()->isContentEditable();
+ return parentOrHostNode() && parentOrHostNode()->isContentEditable();
}
bool Node::isContentRichlyEditable() const
{
- return parent() && parent()->isContentRichlyEditable();
+ return parentOrHostNode() && parentOrHostNode()->isContentRichlyEditable();
}
bool Node::shouldUseInputMethod() const
@@ -1267,7 +1282,7 @@ RenderObject * Node::nextRenderer()
{
// Avoid an O(n^2) problem with this function by not checking for nextRenderer() when the parent element hasn't even
// been attached yet.
- if (parent() && !parent()->attached())
+ if (parentOrHostNode() && !parentOrHostNode()->attached())
return 0;
for (Node *n = nextSibling(); n; n = n->nextSibling()) {
@@ -1394,7 +1409,7 @@ void Node::setRenderStyle(PassRefPtr<RenderStyle> s)
RenderStyle* Node::virtualComputedStyle(PseudoId pseudoElementSpecifier)
{
- return parent() ? parent()->computedStyle(pseudoElementSpecifier) : 0;
+ return parentOrHostNode() ? parentOrHostNode()->computedStyle(pseudoElementSpecifier) : 0;
}
int Node::maxCharacterOffset() const
@@ -1417,7 +1432,7 @@ bool Node::canStartSelection() const
if (style->userDrag() == DRAG_ELEMENT && style->userSelect() == SELECT_NONE)
return false;
}
- return parent() ? parent()->canStartSelection() : true;
+ return parentOrHostNode() ? parentOrHostNode()->canStartSelection() : true;
}
Node* Node::shadowAncestorNode()
@@ -1443,7 +1458,7 @@ Node* Node::shadowTreeRootNode()
while (root) {
if (root->isShadowNode())
return root;
- root = root->parentNode();
+ root = root->parentNodeGuaranteedHostFree();
}
return 0;
}
@@ -2536,7 +2551,7 @@ void Node::getEventAncestors(Vector<EventContext>& ancestors, EventTarget* origi
if (!shouldSkipNextAncestor)
target = ancestor;
} else
- ancestor = ancestor->parentNode();
+ ancestor = ancestor->parentNodeGuaranteedHostFree();
if (!ancestor)
return;
@@ -2948,7 +2963,7 @@ void Node::defaultEventHandler(Event* event)
// This is needed for <option> and <optgroup> elements so that <select>s get a wheel scroll.
Node* startNode = this;
while (startNode && !startNode->renderer())
- startNode = startNode->parent();
+ startNode = startNode->parentOrHostNode();
if (startNode && startNode->renderer())
if (Frame* frame = document()->frame())
diff --git a/WebCore/dom/Node.h b/WebCore/dom/Node.h
index 9921795..1c5c5c4 100644
--- a/WebCore/dom/Node.h
+++ b/WebCore/dom/Node.h
@@ -74,7 +74,7 @@ class TagNodeList;
typedef int ExceptionCode;
-const int nodeStyleChangeShift = 24;
+const int nodeStyleChangeShift = 25;
// SyntheticStyleChange means that we need to go through the entire style change logic even though
// no style property has actually changed. It is used to restructure the tree when, for instance,
@@ -138,7 +138,7 @@ public:
virtual String nodeValue() const;
virtual void setNodeValue(const String&, ExceptionCode&);
virtual NodeType nodeType() const = 0;
- ContainerNode* parentNode() const { return parent(); }
+ ContainerNode* parentNode() const;
Element* parentElement() const;
Node* previousSibling() const { return m_previous; }
Node* nextSibling() const { return m_next; }
@@ -205,13 +205,16 @@ public:
bool isCommentNode() const { return getFlag(IsCommentFlag); }
virtual bool isCharacterDataNode() const { return false; }
bool isDocumentNode() const;
- virtual bool isShadowNode() const { return false; }
- virtual ContainerNode* shadowParentNode() { return 0; }
+ bool isShadowNode() const { return getFlag(IsShadowRootFlag); }
+ // FIXME: Eliminate all uses, fold into shadowHost.
+ ContainerNode* shadowParentNode() const;
Node* shadowAncestorNode();
Node* shadowTreeRootNode();
bool isInShadowTree();
// Node's parent or shadow tree host.
- ContainerNode* parentOrHostNode();
+ ContainerNode* parentOrHostNode() const;
+ // Use when it's guaranteed to that shadowParentNode is 0.
+ ContainerNode* parentNodeGuaranteedHostFree() const;
// Returns the enclosing event parent node (or self) that, when clicked, would trigger a navigation.
Node* enclosingLinkEventParentOrSelf();
@@ -581,17 +584,19 @@ private:
InActiveChainFlag = 1 << 15,
InDetachFlag = 1 << 16,
HasRareDataFlag = 1 << 17,
+ IsShadowRootFlag = 1 << 18,
// These bits are used by derived classes, pulled up here so they can
// be stored in the same memory word as the Node bits above.
- IsParsingChildrenFinishedFlag = 1 << 18, // Element
- IsStyleAttributeValidFlag = 1 << 19, // StyledElement
- IsSynchronizingStyleAttributeFlag = 1 << 20, // StyledElement
+ IsParsingChildrenFinishedFlag = 1 << 19, // Element
+ IsStyleAttributeValidFlag = 1 << 20, // StyledElement
+ IsSynchronizingStyleAttributeFlag = 1 << 21, // StyledElement
#if ENABLE(SVG)
- AreSVGAttributesValidFlag = 1 << 21, // Element
- IsSynchronizingSVGAttributesFlag = 1 << 22, // SVGElement
- HasSVGRareDataFlag = 1 << 23, // SVGElement
+ AreSVGAttributesValidFlag = 1 << 22, // Element
+ IsSynchronizingSVGAttributesFlag = 1 << 23, // SVGElement
+ HasSVGRareDataFlag = 1 << 24, // SVGElement
#endif
+
StyleChangeMask = 1 << nodeStyleChangeShift | 1 << (nodeStyleChangeShift + 1),
#if ENABLE(SVG)
@@ -601,7 +606,7 @@ private:
#endif
};
- // 5 bits remaining
+ // 4 bits remaining
bool getFlag(NodeFlags mask) const { return m_nodeFlags & mask; }
void setFlag(bool f, NodeFlags mask) const { m_nodeFlags = (m_nodeFlags & ~mask) | (-(int32_t)f & mask); }
@@ -632,6 +637,9 @@ protected:
NodeRareData* rareData() const;
NodeRareData* ensureRareData();
+ Element* shadowHost() const;
+ void setShadowHost(Element*);
+
private:
#if USE(JSC)
void markCachedNodeListsSlow(JSC::MarkStack&, JSC::JSGlobalData&);
@@ -703,11 +711,25 @@ inline void addSubresourceURL(ListHashSet<KURL>& urls, const KURL& url)
urls.add(url);
}
-inline ContainerNode* Node::parentOrHostNode()
+inline ContainerNode* Node::parentNode() const
+{
+ return getFlag(IsShadowRootFlag) ? 0 : parent();
+}
+
+inline ContainerNode* Node::parentOrHostNode() const
+{
+ return parent();
+}
+
+inline ContainerNode* Node::parentNodeGuaranteedHostFree() const
+{
+ ASSERT(!getFlag(IsShadowRootFlag));
+ return parentOrHostNode();
+}
+
+inline ContainerNode* Node::shadowParentNode() const
{
- if (ContainerNode* parent = parentNode())
- return parent;
- return shadowParentNode();
+ return getFlag(IsShadowRootFlag) ? parent() : 0;
}
} //namespace
diff --git a/WebCore/editing/TextIterator.cpp b/WebCore/editing/TextIterator.cpp
index a3edd38..7e41420 100644
--- a/WebCore/editing/TextIterator.cpp
+++ b/WebCore/editing/TextIterator.cpp
@@ -165,19 +165,12 @@ unsigned BitStack::size() const
// --------
-static inline ContainerNode* parentCrossingShadowBoundaries(Node* node)
-{
- if (ContainerNode* parent = node->parentNode())
- return parent;
- return node->shadowParentNode();
-}
-
#if !ASSERT_DISABLED
static unsigned depthCrossingShadowBoundaries(Node* node)
{
unsigned depth = 0;
- for (Node* parent = parentCrossingShadowBoundaries(node); parent; parent = parentCrossingShadowBoundaries(parent))
+ for (Node* parent = node->parentOrHostNode(); parent; parent = parent->parentOrHostNode())
++depth;
return depth;
}
@@ -193,7 +186,7 @@ static Node* nextInPreOrderCrossingShadowBoundaries(Node* rangeEndContainer, int
if (Node* next = rangeEndContainer->childNode(rangeEndOffset))
return next;
}
- for (Node* node = rangeEndContainer; node; node = parentCrossingShadowBoundaries(node)) {
+ for (Node* node = rangeEndContainer; node; node = node->parentOrHostNode()) {
if (Node* next = node->nextSibling())
return next;
}
@@ -208,7 +201,7 @@ static Node* previousInPostOrderCrossingShadowBoundaries(Node* rangeStartContain
if (Node* previous = rangeStartContainer->childNode(rangeStartOffset - 1))
return previous;
}
- for (Node* node = rangeStartContainer; node; node = parentCrossingShadowBoundaries(node)) {
+ for (Node* node = rangeStartContainer; node; node = node->parentOrHostNode()) {
if (Node* previous = node->previousSibling())
return previous;
}
@@ -247,7 +240,7 @@ static void setUpFullyClippedStack(BitStack& stack, Node* node)
{
// Put the nodes in a vector so we can iterate in reverse order.
Vector<Node*, 100> ancestry;
- for (Node* parent = parentCrossingShadowBoundaries(node); parent; parent = parentCrossingShadowBoundaries(parent))
+ for (Node* parent = node->parentOrHostNode(); parent; parent = parent->parentOrHostNode())
ancestry.append(parent);
// Call pushFullyClippedState on each node starting with the earliest ancestor.
@@ -427,14 +420,14 @@ void TextIterator::advance()
next = m_node->nextSibling();
if (!next) {
bool pastEnd = m_node->traverseNextNode() == m_pastEndNode;
- Node* parentNode = parentCrossingShadowBoundaries(m_node);
+ Node* parentNode = m_node->parentOrHostNode();
while (!next && parentNode) {
if ((pastEnd && parentNode == m_endContainer) || m_endContainer->isDescendantOf(parentNode))
return;
bool haveRenderer = m_node->renderer();
m_node = parentNode;
m_fullyClippedStack.pop();
- parentNode = parentCrossingShadowBoundaries(m_node);
+ parentNode = m_node->parentOrHostNode();
if (haveRenderer)
exitNode();
if (m_positionNode) {
@@ -1148,7 +1141,7 @@ void SimplifiedBackwardsTextIterator::advance()
}
// Exit all other containers.
while (!m_node->previousSibling()) {
- if (!setCurrentNode(parentCrossingShadowBoundaries(m_node)))
+ if (!setCurrentNode(m_node->parentOrHostNode()))
break;
m_fullyClippedStack.pop();
exitNode();
diff --git a/WebCore/page/DOMSelection.cpp b/WebCore/page/DOMSelection.cpp
index 03172b5..944f13d 100644
--- a/WebCore/page/DOMSelection.cpp
+++ b/WebCore/page/DOMSelection.cpp
@@ -100,7 +100,7 @@ Node* DOMSelection::anchorNode() const
if (!m_frame)
return 0;
if (Node* shadowAncestor = selectionShadowAncestor(m_frame))
- return shadowAncestor->parentNode();
+ return shadowAncestor->parentNodeGuaranteedHostFree();
return anchorPosition(visibleSelection()).node();
}
@@ -118,7 +118,7 @@ Node* DOMSelection::focusNode() const
if (!m_frame)
return 0;
if (Node* shadowAncestor = selectionShadowAncestor(m_frame))
- return shadowAncestor->parentNode();
+ return shadowAncestor->parentNodeGuaranteedHostFree();
return focusPosition(visibleSelection()).node();
}
@@ -136,7 +136,7 @@ Node* DOMSelection::baseNode() const
if (!m_frame)
return 0;
if (Node* shadowAncestor = selectionShadowAncestor(m_frame))
- return shadowAncestor->parentNode();
+ return shadowAncestor->parentNodeGuaranteedHostFree();
return basePosition(visibleSelection()).node();
}
@@ -154,7 +154,7 @@ Node* DOMSelection::extentNode() const
if (!m_frame)
return 0;
if (Node* shadowAncestor = selectionShadowAncestor(m_frame))
- return shadowAncestor->parentNode();
+ return shadowAncestor->parentNodeGuaranteedHostFree();
return extentPosition(visibleSelection()).node();
}
@@ -370,7 +370,7 @@ PassRefPtr<Range> DOMSelection::getRangeAt(int index, ExceptionCode& ec)
ASSERT(rangeCount() == 1);
if (Node* shadowAncestor = selectionShadowAncestor(m_frame)) {
- ContainerNode* container = shadowAncestor->parentNode();
+ ContainerNode* container = shadowAncestor->parentNodeGuaranteedHostFree();
int offset = shadowAncestor->nodeIndex();
return Range::create(shadowAncestor->document(), container, offset, container, offset);
}
diff --git a/WebCore/rendering/MediaControlElements.cpp b/WebCore/rendering/MediaControlElements.cpp
index 1af1b80..8dfdc81 100644
--- a/WebCore/rendering/MediaControlElements.cpp
+++ b/WebCore/rendering/MediaControlElements.cpp
@@ -65,8 +65,8 @@ static const float cSeekTime = 0.2f;
inline MediaControlShadowRootElement::MediaControlShadowRootElement(HTMLMediaElement* mediaElement)
: HTMLDivElement(divTag, mediaElement->document())
- , m_mediaElement(mediaElement)
{
+ setShadowHost(mediaElement);
}
PassRefPtr<MediaControlShadowRootElement> MediaControlShadowRootElement::create(HTMLMediaElement* mediaElement)
@@ -91,11 +91,18 @@ PassRefPtr<MediaControlShadowRootElement> MediaControlShadowRootElement::create(
void MediaControlShadowRootElement::updateStyle()
{
if (renderer()) {
- RenderStyle* timelineContainerStyle = m_mediaElement->renderer()->getCachedPseudoStyle(MEDIA_CONTROLS_TIMELINE_CONTAINER);
+ RenderStyle* timelineContainerStyle = shadowHost()->renderer()->getCachedPseudoStyle(MEDIA_CONTROLS_TIMELINE_CONTAINER);
renderer()->setStyle(timelineContainerStyle);
}
}
+void MediaControlShadowRootElement::detach()
+{
+ HTMLDivElement::detach();
+ // FIXME: Remove once shadow DOM uses Element::setShadowRoot().
+ setShadowHost(0);
+}
+
// ----------------------------
MediaControlElement::MediaControlElement(HTMLMediaElement* mediaElement, PseudoId pseudo)
diff --git a/WebCore/rendering/MediaControlElements.h b/WebCore/rendering/MediaControlElements.h
index a9ffb0b..b2d063d 100644
--- a/WebCore/rendering/MediaControlElements.h
+++ b/WebCore/rendering/MediaControlElements.h
@@ -76,14 +76,10 @@ public:
static PassRefPtr<MediaControlShadowRootElement> create(HTMLMediaElement*);
void updateStyle();
+ virtual void detach();
private:
MediaControlShadowRootElement(HTMLMediaElement*);
-
- virtual bool isShadowNode() const { return true; }
- virtual ContainerNode* shadowParentNode() { return m_mediaElement; }
-
- HTMLMediaElement* m_mediaElement;
};
// ----------------------------
diff --git a/WebCore/rendering/RenderSVGShadowTreeRootContainer.cpp b/WebCore/rendering/RenderSVGShadowTreeRootContainer.cpp
index d3064c6..c5430ed 100644
--- a/WebCore/rendering/RenderSVGShadowTreeRootContainer.cpp
+++ b/WebCore/rendering/RenderSVGShadowTreeRootContainer.cpp
@@ -36,8 +36,10 @@ RenderSVGShadowTreeRootContainer::RenderSVGShadowTreeRootContainer(SVGUseElement
RenderSVGShadowTreeRootContainer::~RenderSVGShadowTreeRootContainer()
{
- if (m_shadowRoot && m_shadowRoot->attached())
+ if (m_shadowRoot && m_shadowRoot->attached()) {
m_shadowRoot->detach();
+ m_shadowRoot->clearShadowHost();
+ }
}
void RenderSVGShadowTreeRootContainer::updateStyle(Node::StyleChange change)
diff --git a/WebCore/rendering/RenderSlider.cpp b/WebCore/rendering/RenderSlider.cpp
index 304219e..1619d94 100644
--- a/WebCore/rendering/RenderSlider.cpp
+++ b/WebCore/rendering/RenderSlider.cpp
@@ -106,7 +106,7 @@ void SliderThumbElement::defaultEventHandler(Event* event)
}
m_inDragMode = true;
- document()->frame()->eventHandler()->setCapturingMouseEventsNode(shadowParent());
+ document()->frame()->eventHandler()->setCapturingMouseEventsNode(shadowHost());
event->setDefaultHandled();
return;
}
diff --git a/WebCore/rendering/RenderTextControlSingleLine.cpp b/WebCore/rendering/RenderTextControlSingleLine.cpp
index 01b9f28..93d34ee 100644
--- a/WebCore/rendering/RenderTextControlSingleLine.cpp
+++ b/WebCore/rendering/RenderTextControlSingleLine.cpp
@@ -67,8 +67,10 @@ RenderTextControlSingleLine::~RenderTextControlSingleLine()
m_searchPopup = 0;
}
- if (m_innerBlock)
+ if (m_innerBlock) {
m_innerBlock->detach();
+ m_innerBlock = 0;
+ }
if (m_innerSpinButton)
m_innerSpinButton->detach();
diff --git a/WebCore/rendering/RenderTreeAsText.cpp b/WebCore/rendering/RenderTreeAsText.cpp
index 22ee620..2e64999 100644
--- a/WebCore/rendering/RenderTreeAsText.cpp
+++ b/WebCore/rendering/RenderTreeAsText.cpp
@@ -685,9 +685,7 @@ static String nodePosition(Node* node)
Element* body = node->document()->body();
Node* parent;
for (Node* n = node; n; n = parent) {
- parent = n->parentNode();
- if (!parent)
- parent = n->shadowParentNode();
+ parent = n->parentOrHostNode();
if (n != node)
result += " of ";
if (parent) {
diff --git a/WebCore/rendering/SVGShadowTreeElements.cpp b/WebCore/rendering/SVGShadowTreeElements.cpp
index 8a66991..7c5e1a9 100644
--- a/WebCore/rendering/SVGShadowTreeElements.cpp
+++ b/WebCore/rendering/SVGShadowTreeElements.cpp
@@ -51,8 +51,8 @@ FloatSize SVGShadowTreeContainerElement::containerTranslation() const
inline SVGShadowTreeRootElement::SVGShadowTreeRootElement(Document* document, SVGUseElement* shadowParent)
: SVGShadowTreeContainerElement(document)
- , m_shadowParent(shadowParent)
{
+ setShadowHost(shadowParent);
setInDocument();
}
@@ -63,7 +63,7 @@ PassRefPtr<SVGShadowTreeRootElement> SVGShadowTreeRootElement::create(Document*
void SVGShadowTreeRootElement::attachElement(PassRefPtr<RenderStyle> style, RenderArena* arena)
{
- ASSERT(m_shadowParent);
+ ASSERT(shadowHost());
// Create the renderer with the specified style
RenderObject* renderer = createRenderer(arena, style.get());
@@ -77,7 +77,12 @@ void SVGShadowTreeRootElement::attachElement(PassRefPtr<RenderStyle> style, Rend
// Add the renderer to the render tree
if (renderer)
- m_shadowParent->renderer()->addChild(renderer);
+ shadowHost()->renderer()->addChild(renderer);
+}
+
+void SVGShadowTreeRootElement::clearShadowHost()
+{
+ setShadowHost(0);
}
}
diff --git a/WebCore/rendering/SVGShadowTreeElements.h b/WebCore/rendering/SVGShadowTreeElements.h
index d49fbaa..fe25678 100644
--- a/WebCore/rendering/SVGShadowTreeElements.h
+++ b/WebCore/rendering/SVGShadowTreeElements.h
@@ -55,15 +55,10 @@ public:
static PassRefPtr<SVGShadowTreeRootElement> create(Document*, SVGUseElement* shadowParent);
void attachElement(PassRefPtr<RenderStyle>, RenderArena*);
-
- virtual ContainerNode* shadowParentNode() { return m_shadowParent; }
+ void clearShadowHost();
private:
SVGShadowTreeRootElement(Document*, SVGUseElement* shadowParent);
-
- virtual bool isShadowNode() const { return m_shadowParent; }
-
- ContainerNode* m_shadowParent;
};
}
diff --git a/WebCore/rendering/ShadowElement.cpp b/WebCore/rendering/ShadowElement.cpp
index 72f48e2..e1b247c 100644
--- a/WebCore/rendering/ShadowElement.cpp
+++ b/WebCore/rendering/ShadowElement.cpp
@@ -75,7 +75,7 @@ PassRefPtr<ShadowBlockElement> ShadowBlockElement::createForPart(HTMLElement* sh
void ShadowBlockElement::initAsPart(PseudoId pseudoId)
{
- RenderObject* parentRenderer = shadowParent()->renderer();
+ RenderObject* parentRenderer = shadowHost()->renderer();
RefPtr<RenderStyle> styleForPart = createStyleForPart(parentRenderer, pseudoId);
setRenderer(createRenderer(parentRenderer->renderArena(), styleForPart.get()));
renderer()->setStyle(styleForPart.release());
diff --git a/WebCore/rendering/ShadowElement.h b/WebCore/rendering/ShadowElement.h
index 72bc207..2c1a69e 100644
--- a/WebCore/rendering/ShadowElement.h
+++ b/WebCore/rendering/ShadowElement.h
@@ -41,17 +41,24 @@ protected:
: BaseElement(name, shadowParent->document())
, m_shadowParent(shadowParent)
{
+ BaseElement::setShadowHost(shadowParent);
}
- HTMLElement* shadowParent() const { return m_shadowParent.get(); }
+public:
+ virtual void detach();
private:
- virtual bool isShadowNode() const { return true; }
- virtual ContainerNode* shadowParentNode() { return m_shadowParent.get(); }
-
RefPtr<HTMLElement> m_shadowParent;
};
+template<class BaseElement>
+void ShadowElement<BaseElement>::detach()
+{
+ BaseElement::detach();
+ // FIXME: Remove once shadow DOM uses Element::setShadowRoot().
+ BaseElement::setShadowHost(0);
+}
+
class ShadowBlockElement : public ShadowElement<HTMLDivElement> {
public:
static PassRefPtr<ShadowBlockElement> create(HTMLElement*);
diff --git a/WebCore/rendering/TextControlInnerElements.cpp b/WebCore/rendering/TextControlInnerElements.cpp
index 92c51ee..9c21542 100644
--- a/WebCore/rendering/TextControlInnerElements.cpp
+++ b/WebCore/rendering/TextControlInnerElements.cpp
@@ -79,6 +79,7 @@ TextControlInnerElement::TextControlInnerElement(Document* document, HTMLElement
: HTMLDivElement(divTag, document)
, m_shadowParent(shadowParent)
{
+ setShadowHost(shadowParent);
}
PassRefPtr<TextControlInnerElement> TextControlInnerElement::create(HTMLElement* shadowParent)
@@ -102,8 +103,8 @@ void TextControlInnerElement::attachInnerElement(Node* parent, PassRefPtr<Render
setAttached();
setInDocument();
- // For elements without a shadow parent, add the node to the DOM normally.
- if (!m_shadowParent) {
+ // For elements not yet in shadow DOM, add the node to the DOM normally.
+ if (!isShadowNode()) {
// FIXME: This code seems very wrong. Why are we magically adding |this| to the DOM here?
// We shouldn't be calling parser API methods outside of the parser!
parent->deprecatedParserAddChild(this);
@@ -114,6 +115,13 @@ void TextControlInnerElement::attachInnerElement(Node* parent, PassRefPtr<Render
parent->renderer()->addChild(renderer);
}
+void TextControlInnerElement::detach()
+{
+ HTMLDivElement::detach();
+ // FIXME: Remove once shadow DOM uses Element::setShadowRoot().
+ setShadowHost(0);
+}
+
// ----------------------------
inline TextControlInnerTextElement::TextControlInnerTextElement(Document* document, HTMLElement* shadowParent)
diff --git a/WebCore/rendering/TextControlInnerElements.h b/WebCore/rendering/TextControlInnerElements.h
index 5af98ed..bb77dcd 100644
--- a/WebCore/rendering/TextControlInnerElements.h
+++ b/WebCore/rendering/TextControlInnerElements.h
@@ -39,6 +39,7 @@ class SpeechInput;
class TextControlInnerElement : public HTMLDivElement {
public:
static PassRefPtr<TextControlInnerElement> create(HTMLElement* shadowParent);
+ virtual void detach();
void attachInnerElement(Node*, PassRefPtr<RenderStyle>, RenderArena*);
@@ -46,10 +47,7 @@ protected:
TextControlInnerElement(Document*, HTMLElement* shadowParent = 0);
private:
- virtual bool isMouseFocusable() const { return false; }
- virtual bool isShadowNode() const { return m_shadowParent.get(); }
- virtual ContainerNode* shadowParentNode() { return m_shadowParent.get(); }
- void setShadowParentNode(HTMLElement* shadowParent) { m_shadowParent = shadowParent; }
+ virtual bool isMouseFocusable() const { return false; }
RefPtr<HTMLElement> m_shadowParent;
};
diff --git a/WebCore/svg/SVGElement.cpp b/WebCore/svg/SVGElement.cpp
index 615aaab..3889dfd 100644
--- a/WebCore/svg/SVGElement.cpp
+++ b/WebCore/svg/SVGElement.cpp
@@ -118,12 +118,12 @@ void SVGElement::setXmlbase(const String& value, ExceptionCode&)
SVGSVGElement* SVGElement::ownerSVGElement() const
{
- ContainerNode* n = isShadowNode() ? const_cast<SVGElement*>(this)->shadowParentNode() : parentNode();
+ ContainerNode* n = parentOrHostNode();
while (n) {
if (n->hasTagName(SVGNames::svgTag))
return static_cast<SVGSVGElement*>(n);
- n = n->isShadowNode() ? n->shadowParentNode() : n->parentNode();
+ n = n->parentOrHostNode();
}
return 0;
@@ -133,12 +133,12 @@ SVGElement* SVGElement::viewportElement() const
{
// This function needs shadow tree support - as RenderSVGContainer uses this function
// to determine the "overflow" property. <use> on <symbol> wouldn't work otherwhise.
- ContainerNode* n = isShadowNode() ? const_cast<SVGElement*>(this)->shadowParentNode() : parentNode();
+ ContainerNode* n = parentOrHostNode();
while (n) {
if (n->hasTagName(SVGNames::svgTag) || n->hasTagName(SVGNames::imageTag) || n->hasTagName(SVGNames::symbolTag))
return static_cast<SVGElement*>(n);
- n = n->isShadowNode() ? n->shadowParentNode() : n->parentNode();
+ n = n->parentOrHostNode();
}
return 0;
diff --git a/WebCore/svg/SVGLocatable.cpp b/WebCore/svg/SVGLocatable.cpp
index b3dce01..43961d9 100644
--- a/WebCore/svg/SVGLocatable.cpp
+++ b/WebCore/svg/SVGLocatable.cpp
@@ -97,7 +97,7 @@ AffineTransform SVGLocatable::computeCTM(const SVGElement* element, CTMScope mod
if (currentElement == stopAtElement)
break;
- current = current->isShadowNode() ? current->shadowParentNode() : current->parentNode();
+ current = current->parentOrHostNode();
}
return ctm;
diff --git a/WebCore/svg/SVGStyledElement.cpp b/WebCore/svg/SVGStyledElement.cpp
index 895c1e0..bed2b65 100644
--- a/WebCore/svg/SVGStyledElement.cpp
+++ b/WebCore/svg/SVGStyledElement.cpp
@@ -81,7 +81,7 @@ String SVGStyledElement::title() const
Node* parent = const_cast<SVGStyledElement*>(this);
while (parent) {
if (!parent->isShadowNode()) {
- parent = parent->parentNode();
+ parent = parent->parentNodeGuaranteedHostFree();
continue;
}
diff --git a/WebCore/svg/SVGUseElement.cpp b/WebCore/svg/SVGUseElement.cpp
index c8228ca..ec3d542 100644
--- a/WebCore/svg/SVGUseElement.cpp
+++ b/WebCore/svg/SVGUseElement.cpp
@@ -496,7 +496,7 @@ void SVGUseElement::buildShadowAndInstanceTree(SVGShadowTreeRootElement* shadowR
if (parent->isShadowNode())
return;
- parent = parent->parentNode();
+ parent = parent->parentNodeGuaranteedHostFree();
}
SVGElement* target = 0;
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list