[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