Title: [125737] trunk/Source/WebCore
Revision
125737
Author
[email protected]
Date
2012-08-15 19:35:29 -0700 (Wed, 15 Aug 2012)

Log Message

Add a was-inserted-into-tree notification to RenderObject
https://bugs.webkit.org/show_bug.cgi?id=93874

Reviewed by Eric Seidel.

This change adds insertedIntoTree to RenderObject so that renderers
can now do their post-insertion task inside this function.

Our current architecture has 2 ways of doing post-insertion tasks:
- overriding RenderObject::addChild
- RenderObjectChildList::insertChildNode / appendChildNode

Because the former is not guaranteed to be called for each insertion
(on top of being called on the parent and not the inserted child), the
2 latter functions are the one that have been mostly used recently. This
led to code duplication between the functions but also doesn't scale as
other renderers need to hop on this notification and currently don't (for
example, table parts). The other renderer's migration will be done in
follow-up patches.

Refactoring covered by existing tests.

* rendering/RenderObjectChildList.cpp:
(WebCore::RenderObjectChildList::removeChildNode):
* rendering/RenderObject.cpp:
(WebCore::RenderObject::enclosingRenderNamedFlowThread):
Moved the code from renderNamedFlowThreadContainer to RenderObject::enclosingRenderNamedFlowThread.
This is needed as now 2 classes need to access the function.

* rendering/RenderObjectChildList.cpp:
(WebCore::RenderObjectChildList::appendChildNode):
(WebCore::RenderObjectChildList::insertChildNode):
Moved the code duplicated from those 2 functions into
the instances of insertedIntoTree below.

* rendering/RenderObject.cpp:
(WebCore::RenderObject::insertedIntoTree):
Base function that needs to be called from all the other
specialized functions below.

* rendering/RenderListItem.cpp:
(WebCore::RenderListItem::insertedIntoTree):
* rendering/RenderListItem.h:
* rendering/RenderObject.h:
* rendering/RenderObjectChildList.h:
* rendering/RenderRegion.cpp:
(WebCore::RenderRegion::insertedIntoTree):
* rendering/RenderRegion.h:
Added the overriden insertedIntoTree function.

* rendering/RenderQuote.h:
Moved the comment from RenderObjectChildList about RenderQuote here.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (125736 => 125737)


--- trunk/Source/WebCore/ChangeLog	2012-08-16 02:14:16 UTC (rev 125736)
+++ trunk/Source/WebCore/ChangeLog	2012-08-16 02:35:29 UTC (rev 125737)
@@ -1,3 +1,58 @@
+2012-08-15  Julien Chaffraix  <[email protected]>
+
+        Add a was-inserted-into-tree notification to RenderObject
+        https://bugs.webkit.org/show_bug.cgi?id=93874
+
+        Reviewed by Eric Seidel.
+
+        This change adds insertedIntoTree to RenderObject so that renderers
+        can now do their post-insertion task inside this function.
+
+        Our current architecture has 2 ways of doing post-insertion tasks:
+        - overriding RenderObject::addChild
+        - RenderObjectChildList::insertChildNode / appendChildNode
+
+        Because the former is not guaranteed to be called for each insertion
+        (on top of being called on the parent and not the inserted child), the
+        2 latter functions are the one that have been mostly used recently. This
+        led to code duplication between the functions but also doesn't scale as
+        other renderers need to hop on this notification and currently don't (for
+        example, table parts). The other renderer's migration will be done in
+        follow-up patches.
+
+        Refactoring covered by existing tests.
+
+        * rendering/RenderObjectChildList.cpp:
+        (WebCore::RenderObjectChildList::removeChildNode):
+        * rendering/RenderObject.cpp:
+        (WebCore::RenderObject::enclosingRenderNamedFlowThread):
+        Moved the code from renderNamedFlowThreadContainer to RenderObject::enclosingRenderNamedFlowThread.
+        This is needed as now 2 classes need to access the function.
+
+        * rendering/RenderObjectChildList.cpp:
+        (WebCore::RenderObjectChildList::appendChildNode):
+        (WebCore::RenderObjectChildList::insertChildNode):
+        Moved the code duplicated from those 2 functions into
+        the instances of insertedIntoTree below.
+
+        * rendering/RenderObject.cpp:
+        (WebCore::RenderObject::insertedIntoTree):
+        Base function that needs to be called from all the other
+        specialized functions below.
+
+        * rendering/RenderListItem.cpp:
+        (WebCore::RenderListItem::insertedIntoTree):
+        * rendering/RenderListItem.h:
+        * rendering/RenderObject.h:
+        * rendering/RenderObjectChildList.h:
+        * rendering/RenderRegion.cpp:
+        (WebCore::RenderRegion::insertedIntoTree):
+        * rendering/RenderRegion.h:
+        Added the overriden insertedIntoTree function.
+
+        * rendering/RenderQuote.h:
+        Moved the comment from RenderObjectChildList about RenderQuote here.
+
 2012-08-14  Jeffrey Pfau  <[email protected]>
 
         Allow blocking of Web SQL databases in third-party documents

Modified: trunk/Source/WebCore/rendering/RenderListItem.cpp (125736 => 125737)


--- trunk/Source/WebCore/rendering/RenderListItem.cpp	2012-08-16 02:14:16 UTC (rev 125736)
+++ trunk/Source/WebCore/rendering/RenderListItem.cpp	2012-08-16 02:35:29 UTC (rev 125737)
@@ -76,6 +76,13 @@
     RenderBlock::willBeDestroyed();
 }
 
+void RenderListItem::insertedIntoTree()
+{
+    RenderBlock::insertedIntoTree();
+
+    updateListMarkerNumbers();
+}
+
 static bool isList(Node* node)
 {
     return (node->hasTagName(ulTag) || node->hasTagName(olTag));

Modified: trunk/Source/WebCore/rendering/RenderListItem.h (125736 => 125737)


--- trunk/Source/WebCore/rendering/RenderListItem.h	2012-08-16 02:14:16 UTC (rev 125736)
+++ trunk/Source/WebCore/rendering/RenderListItem.h	2012-08-16 02:35:29 UTC (rev 125737)
@@ -58,6 +58,8 @@
     
     virtual void willBeDestroyed();
 
+    virtual void insertedIntoTree() OVERRIDE;
+
     virtual bool isEmpty() const;
     virtual void paint(PaintInfo&, const LayoutPoint&);
 

Modified: trunk/Source/WebCore/rendering/RenderObject.cpp (125736 => 125737)


--- trunk/Source/WebCore/rendering/RenderObject.cpp	2012-08-16 02:14:16 UTC (rev 125736)
+++ trunk/Source/WebCore/rendering/RenderObject.cpp	2012-08-16 02:35:29 UTC (rev 125737)
@@ -586,6 +586,15 @@
     return 0;
 }
 
+RenderNamedFlowThread* RenderObject::enclosingRenderNamedFlowThread() const
+{
+    RenderObject* object = const_cast<RenderObject*>(this);
+    while (object && object->isAnonymousBlock() && !object->isRenderNamedFlowThread())
+        object = object->parent();
+
+    return object && object->isRenderNamedFlowThread() ? toRenderNamedFlowThread(object) : 0;
+}
+
 RenderBlock* RenderObject::firstLineBlock() const
 {
     return 0;
@@ -2354,6 +2363,34 @@
     clearLayoutRootIfNeeded();
 }
 
+void RenderObject::insertedIntoTree()
+{
+    // FIXME: We should ASSERT(isRooted()) here but generated content makes some out-of-order insertion.
+
+    // Keep our layer hierarchy updated. Optimize for the common case where we don't have any children
+    // and don't have a layer attached to ourselves.
+    RenderLayer* layer = 0;
+    if (firstChild() || hasLayer()) {
+        layer = parent()->enclosingLayer();
+        addLayers(layer);
+    }
+
+    // If |this| is visible but this object was not, tell the layer it has some visible content
+    // that needs to be drawn and layer visibility optimization can't be used
+    if (parent()->style()->visibility() != VISIBLE && style()->visibility() == VISIBLE && !hasLayer()) {
+        if (!layer)
+            layer = parent()->enclosingLayer();
+        if (layer)
+            layer->setHasVisibleContent();
+    }
+
+    if (!isFloating() && parent()->childrenInline())
+        parent()->dirtyLinesFromChangedChild(this);
+
+    if (RenderNamedFlowThread* containerFlowThread = parent()->enclosingRenderNamedFlowThread())
+        containerFlowThread->addFlowChild(this);
+}
+
 void RenderObject::destroyAndCleanupAnonymousWrappers()
 {
     RenderObject* parent = this->parent();

Modified: trunk/Source/WebCore/rendering/RenderObject.h (125736 => 125737)


--- trunk/Source/WebCore/rendering/RenderObject.h	2012-08-16 02:14:16 UTC (rev 125736)
+++ trunk/Source/WebCore/rendering/RenderObject.h	2012-08-16 02:35:29 UTC (rev 125737)
@@ -59,6 +59,7 @@
 class RenderFlowThread;
 class RenderGeometryMap;
 class RenderLayer;
+class RenderNamedFlowThread;
 class RenderTable;
 class RenderTheme;
 class TransformState;
@@ -226,6 +227,8 @@
     // Function to return our enclosing flow thread if we are contained inside one.
     RenderFlowThread* enclosingRenderFlowThread() const;
 
+    RenderNamedFlowThread* enclosingRenderNamedFlowThread() const;
+
     virtual bool isEmpty() const { return firstChild() == 0; }
 
 #ifndef NDEBUG
@@ -934,6 +937,8 @@
 
     virtual bool canBeReplacedWithInlineRunIn() const;
 
+    virtual void insertedIntoTree();
+
 private:
     RenderStyle* firstLineStyleSlowCase() const;
     StyleDifference adjustStyleDifference(StyleDifference, unsigned contextSensitiveProperties) const;

Modified: trunk/Source/WebCore/rendering/RenderObjectChildList.cpp (125736 => 125737)


--- trunk/Source/WebCore/rendering/RenderObjectChildList.cpp	2012-08-16 02:14:16 UTC (rev 125736)
+++ trunk/Source/WebCore/rendering/RenderObjectChildList.cpp	2012-08-16 02:35:29 UTC (rev 125737)
@@ -63,14 +63,6 @@
     }
 }
 
-static RenderNamedFlowThread* renderNamedFlowThreadContainer(RenderObject* object)
-{
-    while (object && object->isAnonymousBlock() && !object->isRenderNamedFlowThread())
-        object = object->parent();
-
-    return object && object->isRenderNamedFlowThread() ? toRenderNamedFlowThread(object) : 0;
-}
-
 RenderObject* RenderObjectChildList::removeChildNode(RenderObject* owner, RenderObject* oldChild, bool fullRemove)
 {
     ASSERT(oldChild->parent() == owner);
@@ -126,7 +118,7 @@
             oldChild->enclosingRenderFlowThread()->clearRenderObjectCustomStyle(oldChild);
         }
 
-        if (RenderNamedFlowThread* containerFlowThread = renderNamedFlowThreadContainer(owner))
+        if (RenderNamedFlowThread* containerFlowThread = owner->enclosingRenderNamedFlowThread())
             containerFlowThread->removeFlowChild(oldChild);
 
 #if ENABLE(SVG)
@@ -169,7 +161,7 @@
     return oldChild;
 }
 
-void RenderObjectChildList::appendChildNode(RenderObject* owner, RenderObject* newChild, bool fullAppend)
+void RenderObjectChildList::appendChildNode(RenderObject* owner, RenderObject* newChild, bool notifyRenderer)
 {
     ASSERT(newChild->parent() == 0);
     ASSERT(!owner->isBlockFlow() || (!newChild->isTableSection() && !newChild->isTableRow() && !newChild->isTableCell()));
@@ -185,41 +177,9 @@
 
     setLastChild(newChild);
     
-    if (fullAppend) {
-        // Keep our layer hierarchy updated.  Optimize for the common case where we don't have any children
-        // and don't have a layer attached to ourselves.
-        RenderLayer* layer = 0;
-        if (newChild->firstChild() || newChild->hasLayer()) {
-            layer = owner->enclosingLayer();
-            newChild->addLayers(layer);
-        }
+    if (notifyRenderer)
+        newChild->insertedIntoTree();
 
-        // if the new child is visible but this object was not, tell the layer it has some visible content
-        // that needs to be drawn and layer visibility optimization can't be used
-        if (owner->style()->visibility() != VISIBLE && newChild->style()->visibility() == VISIBLE && !newChild->hasLayer()) {
-            if (!layer)
-                layer = owner->enclosingLayer();
-            if (layer)
-                layer->setHasVisibleContent();
-        }
-
-        if (newChild->isListItem())
-            toRenderListItem(newChild)->updateListMarkerNumbers();
-
-        if (!newChild->isFloating() && owner->childrenInline())
-            owner->dirtyLinesFromChangedChild(newChild);
-
-        if (newChild->isRenderRegion())
-            toRenderRegion(newChild)->attachRegion();
-
-        // You can't attachQuote() otherwise the quote would be attached too early
-        // and get the wrong depth since generated content is inserted into anonymous
-        // renderers before going into the main render tree.
-
-        if (RenderNamedFlowThread* containerFlowThread = renderNamedFlowThreadContainer(owner))
-            containerFlowThread->addFlowChild(newChild);
-    }
-
     if (!owner->documentBeingDestroyed()) {
         RenderCounter::rendererSubtreeAttached(newChild);
     }
@@ -231,10 +191,10 @@
         owner->document()->axObjectCache()->childrenChanged(owner);
 }
 
-void RenderObjectChildList::insertChildNode(RenderObject* owner, RenderObject* child, RenderObject* beforeChild, bool fullInsert)
+void RenderObjectChildList::insertChildNode(RenderObject* owner, RenderObject* child, RenderObject* beforeChild, bool notifyRenderer)
 {
     if (!beforeChild) {
-        appendChildNode(owner, child, fullInsert);
+        appendChildNode(owner, child, notifyRenderer);
         return;
     }
 
@@ -257,40 +217,9 @@
 
     child->setParent(owner);
     
-    if (fullInsert) {
-        // Keep our layer hierarchy updated.  Optimize for the common case where we don't have any children
-        // and don't have a layer attached to ourselves.
-        RenderLayer* layer = 0;
-        if (child->firstChild() || child->hasLayer()) {
-            layer = owner->enclosingLayer();
-            child->addLayers(layer);
-        }
+    if (notifyRenderer)
+        child->insertedIntoTree();
 
-        // if the new child is visible but this object was not, tell the layer it has some visible content
-        // that needs to be drawn and layer visibility optimization can't be used
-        if (owner->style()->visibility() != VISIBLE && child->style()->visibility() == VISIBLE && !child->hasLayer()) {
-            if (!layer)
-                layer = owner->enclosingLayer();
-            if (layer)
-                layer->setHasVisibleContent();
-        }
-
-        if (child->isListItem())
-            toRenderListItem(child)->updateListMarkerNumbers();
-
-        if (!child->isFloating() && owner->childrenInline())
-            owner->dirtyLinesFromChangedChild(child);
-
-        if (child->isRenderRegion())
-            toRenderRegion(child)->attachRegion();
-
-        // Calling attachQuote() here would be too early (before anonymous renderers are inserted)
-        // see appendChild() for more explanation.
-
-        if (RenderNamedFlowThread* containerFlowThread = renderNamedFlowThreadContainer(owner))
-            containerFlowThread->addFlowChild(child, beforeChild);
-    }
-
     if (!owner->documentBeingDestroyed()) {
         RenderCounter::rendererSubtreeAttached(child);
     }

Modified: trunk/Source/WebCore/rendering/RenderObjectChildList.h (125736 => 125737)


--- trunk/Source/WebCore/rendering/RenderObjectChildList.h	2012-08-16 02:14:16 UTC (rev 125736)
+++ trunk/Source/WebCore/rendering/RenderObjectChildList.h	2012-08-16 02:35:29 UTC (rev 125737)
@@ -53,8 +53,8 @@
     void destroyLeftoverChildren();
 
     RenderObject* removeChildNode(RenderObject* owner, RenderObject*, bool fullRemove = true);
-    void appendChildNode(RenderObject* owner, RenderObject*, bool fullAppend = true);
-    void insertChildNode(RenderObject* owner, RenderObject* child, RenderObject* before, bool fullInsert = true);
+    void appendChildNode(RenderObject* owner, RenderObject*, bool notifyRenderer = true);
+    void insertChildNode(RenderObject* owner, RenderObject* child, RenderObject* before, bool notifyRenderer = true);
 
     void updateBeforeAfterContent(RenderObject* owner, PseudoId type, const RenderObject* styledObject = 0);
     RenderObject* beforePseudoElementRenderer(const RenderObject* owner) const;

Modified: trunk/Source/WebCore/rendering/RenderQuote.h (125736 => 125737)


--- trunk/Source/WebCore/rendering/RenderQuote.h	2012-08-16 02:14:16 UTC (rev 125736)
+++ trunk/Source/WebCore/rendering/RenderQuote.h	2012-08-16 02:35:29 UTC (rev 125737)
@@ -44,6 +44,11 @@
     virtual PassRefPtr<StringImpl> originalText() const OVERRIDE;
     virtual void computePreferredLogicalWidths(float leadWidth) OVERRIDE;
 
+    // We don't override insertedIntoTree to call attachQuote() as it would be attached
+    // too early and get the wrong depth since generated content is inserted into anonymous
+    // renderers before going into the main render tree. Once we can ensure that insertIntoTree,
+    // is called on an attached tree, we should override it here.
+
     const QuotesData* quotesData() const;
     void updateDepth();
     bool isAttached() { return m_attached; }

Modified: trunk/Source/WebCore/rendering/RenderRegion.cpp (125736 => 125737)


--- trunk/Source/WebCore/rendering/RenderRegion.cpp	2012-08-16 02:14:16 UTC (rev 125736)
+++ trunk/Source/WebCore/rendering/RenderRegion.cpp	2012-08-16 02:35:29 UTC (rev 125737)
@@ -357,6 +357,13 @@
     m_renderObjectRegionStyle.swap(temp);
 }
 
+void RenderRegion::insertedIntoTree()
+{
+    RenderReplaced::insertedIntoTree();
+
+    attachRegion();
+}
+
 PassRefPtr<RenderStyle> RenderRegion::computeStyleInRegion(const RenderObject* object)
 {
     ASSERT(object);

Modified: trunk/Source/WebCore/rendering/RenderRegion.h (125736 => 125737)


--- trunk/Source/WebCore/rendering/RenderRegion.h	2012-08-16 02:14:16 UTC (rev 125736)
+++ trunk/Source/WebCore/rendering/RenderRegion.h	2012-08-16 02:35:29 UTC (rev 125737)
@@ -100,6 +100,8 @@
 private:
     virtual const char* renderName() const { return "RenderRegion"; }
 
+    virtual void insertedIntoTree() OVERRIDE;
+
     PassRefPtr<RenderStyle> computeStyleInRegion(const RenderObject*);
     void computeChildrenStyleInRegion(const RenderObject*);
     void setRegionObjectsRegionStyle();
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to