Changeset 125737 in webkit


Ignore:
Timestamp:
Aug 15, 2012 7:35:29 PM (12 years ago)
Author:
jchaffraix@webkit.org
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.

Location:
trunk/Source/WebCore
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r125736 r125737  
     12012-08-15  Julien Chaffraix  <jchaffraix@webkit.org>
     2
     3        Add a was-inserted-into-tree notification to RenderObject
     4        https://bugs.webkit.org/show_bug.cgi?id=93874
     5
     6        Reviewed by Eric Seidel.
     7
     8        This change adds insertedIntoTree to RenderObject so that renderers
     9        can now do their post-insertion task inside this function.
     10
     11        Our current architecture has 2 ways of doing post-insertion tasks:
     12        - overriding RenderObject::addChild
     13        - RenderObjectChildList::insertChildNode / appendChildNode
     14
     15        Because the former is not guaranteed to be called for each insertion
     16        (on top of being called on the parent and not the inserted child), the
     17        2 latter functions are the one that have been mostly used recently. This
     18        led to code duplication between the functions but also doesn't scale as
     19        other renderers need to hop on this notification and currently don't (for
     20        example, table parts). The other renderer's migration will be done in
     21        follow-up patches.
     22
     23        Refactoring covered by existing tests.
     24
     25        * rendering/RenderObjectChildList.cpp:
     26        (WebCore::RenderObjectChildList::removeChildNode):
     27        * rendering/RenderObject.cpp:
     28        (WebCore::RenderObject::enclosingRenderNamedFlowThread):
     29        Moved the code from renderNamedFlowThreadContainer to RenderObject::enclosingRenderNamedFlowThread.
     30        This is needed as now 2 classes need to access the function.
     31
     32        * rendering/RenderObjectChildList.cpp:
     33        (WebCore::RenderObjectChildList::appendChildNode):
     34        (WebCore::RenderObjectChildList::insertChildNode):
     35        Moved the code duplicated from those 2 functions into
     36        the instances of insertedIntoTree below.
     37
     38        * rendering/RenderObject.cpp:
     39        (WebCore::RenderObject::insertedIntoTree):
     40        Base function that needs to be called from all the other
     41        specialized functions below.
     42
     43        * rendering/RenderListItem.cpp:
     44        (WebCore::RenderListItem::insertedIntoTree):
     45        * rendering/RenderListItem.h:
     46        * rendering/RenderObject.h:
     47        * rendering/RenderObjectChildList.h:
     48        * rendering/RenderRegion.cpp:
     49        (WebCore::RenderRegion::insertedIntoTree):
     50        * rendering/RenderRegion.h:
     51        Added the overriden insertedIntoTree function.
     52
     53        * rendering/RenderQuote.h:
     54        Moved the comment from RenderObjectChildList about RenderQuote here.
     55
    1562012-08-14  Jeffrey Pfau  <jpfau@apple.com>
    257
  • trunk/Source/WebCore/rendering/RenderListItem.cpp

    r121123 r125737  
    7575    }
    7676    RenderBlock::willBeDestroyed();
     77}
     78
     79void RenderListItem::insertedIntoTree()
     80{
     81    RenderBlock::insertedIntoTree();
     82
     83    updateListMarkerNumbers();
    7784}
    7885
  • trunk/Source/WebCore/rendering/RenderListItem.h

    r103074 r125737  
    5959    virtual void willBeDestroyed();
    6060
     61    virtual void insertedIntoTree() OVERRIDE;
     62
    6163    virtual bool isEmpty() const;
    6264    virtual void paint(PaintInfo&, const LayoutPoint&);
  • trunk/Source/WebCore/rendering/RenderObject.cpp

    r125192 r125737  
    585585    }
    586586    return 0;
     587}
     588
     589RenderNamedFlowThread* RenderObject::enclosingRenderNamedFlowThread() const
     590{
     591    RenderObject* object = const_cast<RenderObject*>(this);
     592    while (object && object->isAnonymousBlock() && !object->isRenderNamedFlowThread())
     593        object = object->parent();
     594
     595    return object && object->isRenderNamedFlowThread() ? toRenderNamedFlowThread(object) : 0;
    587596}
    588597
     
    23552364}
    23562365
     2366void RenderObject::insertedIntoTree()
     2367{
     2368    // FIXME: We should ASSERT(isRooted()) here but generated content makes some out-of-order insertion.
     2369
     2370    // Keep our layer hierarchy updated. Optimize for the common case where we don't have any children
     2371    // and don't have a layer attached to ourselves.
     2372    RenderLayer* layer = 0;
     2373    if (firstChild() || hasLayer()) {
     2374        layer = parent()->enclosingLayer();
     2375        addLayers(layer);
     2376    }
     2377
     2378    // If |this| is visible but this object was not, tell the layer it has some visible content
     2379    // that needs to be drawn and layer visibility optimization can't be used
     2380    if (parent()->style()->visibility() != VISIBLE && style()->visibility() == VISIBLE && !hasLayer()) {
     2381        if (!layer)
     2382            layer = parent()->enclosingLayer();
     2383        if (layer)
     2384            layer->setHasVisibleContent();
     2385    }
     2386
     2387    if (!isFloating() && parent()->childrenInline())
     2388        parent()->dirtyLinesFromChangedChild(this);
     2389
     2390    if (RenderNamedFlowThread* containerFlowThread = parent()->enclosingRenderNamedFlowThread())
     2391        containerFlowThread->addFlowChild(this);
     2392}
     2393
    23572394void RenderObject::destroyAndCleanupAnonymousWrappers()
    23582395{
  • trunk/Source/WebCore/rendering/RenderObject.h

    r125256 r125737  
    6060class RenderGeometryMap;
    6161class RenderLayer;
     62class RenderNamedFlowThread;
    6263class RenderTable;
    6364class RenderTheme;
     
    226227    // Function to return our enclosing flow thread if we are contained inside one.
    227228    RenderFlowThread* enclosingRenderFlowThread() const;
     229
     230    RenderNamedFlowThread* enclosingRenderNamedFlowThread() const;
    228231
    229232    virtual bool isEmpty() const { return firstChild() == 0; }
     
    934937
    935938    virtual bool canBeReplacedWithInlineRunIn() const;
     939
     940    virtual void insertedIntoTree();
    936941
    937942private:
  • trunk/Source/WebCore/rendering/RenderObjectChildList.cpp

    r125220 r125737  
    6464}
    6565
    66 static RenderNamedFlowThread* renderNamedFlowThreadContainer(RenderObject* object)
    67 {
    68     while (object && object->isAnonymousBlock() && !object->isRenderNamedFlowThread())
    69         object = object->parent();
    70 
    71     return object && object->isRenderNamedFlowThread() ? toRenderNamedFlowThread(object) : 0;
    72 }
    73 
    7466RenderObject* RenderObjectChildList::removeChildNode(RenderObject* owner, RenderObject* oldChild, bool fullRemove)
    7567{
     
    127119        }
    128120
    129         if (RenderNamedFlowThread* containerFlowThread = renderNamedFlowThreadContainer(owner))
     121        if (RenderNamedFlowThread* containerFlowThread = owner->enclosingRenderNamedFlowThread())
    130122            containerFlowThread->removeFlowChild(oldChild);
    131123
     
    170162}
    171163
    172 void RenderObjectChildList::appendChildNode(RenderObject* owner, RenderObject* newChild, bool fullAppend)
     164void RenderObjectChildList::appendChildNode(RenderObject* owner, RenderObject* newChild, bool notifyRenderer)
    173165{
    174166    ASSERT(newChild->parent() == 0);
     
    186178    setLastChild(newChild);
    187179   
    188     if (fullAppend) {
    189         // Keep our layer hierarchy updated.  Optimize for the common case where we don't have any children
    190         // and don't have a layer attached to ourselves.
    191         RenderLayer* layer = 0;
    192         if (newChild->firstChild() || newChild->hasLayer()) {
    193             layer = owner->enclosingLayer();
    194             newChild->addLayers(layer);
    195         }
    196 
    197         // if the new child is visible but this object was not, tell the layer it has some visible content
    198         // that needs to be drawn and layer visibility optimization can't be used
    199         if (owner->style()->visibility() != VISIBLE && newChild->style()->visibility() == VISIBLE && !newChild->hasLayer()) {
    200             if (!layer)
    201                 layer = owner->enclosingLayer();
    202             if (layer)
    203                 layer->setHasVisibleContent();
    204         }
    205 
    206         if (newChild->isListItem())
    207             toRenderListItem(newChild)->updateListMarkerNumbers();
    208 
    209         if (!newChild->isFloating() && owner->childrenInline())
    210             owner->dirtyLinesFromChangedChild(newChild);
    211 
    212         if (newChild->isRenderRegion())
    213             toRenderRegion(newChild)->attachRegion();
    214 
    215         // You can't attachQuote() otherwise the quote would be attached too early
    216         // and get the wrong depth since generated content is inserted into anonymous
    217         // renderers before going into the main render tree.
    218 
    219         if (RenderNamedFlowThread* containerFlowThread = renderNamedFlowThreadContainer(owner))
    220             containerFlowThread->addFlowChild(newChild);
    221     }
     180    if (notifyRenderer)
     181        newChild->insertedIntoTree();
    222182
    223183    if (!owner->documentBeingDestroyed()) {
     
    232192}
    233193
    234 void RenderObjectChildList::insertChildNode(RenderObject* owner, RenderObject* child, RenderObject* beforeChild, bool fullInsert)
     194void RenderObjectChildList::insertChildNode(RenderObject* owner, RenderObject* child, RenderObject* beforeChild, bool notifyRenderer)
    235195{
    236196    if (!beforeChild) {
    237         appendChildNode(owner, child, fullInsert);
     197        appendChildNode(owner, child, notifyRenderer);
    238198        return;
    239199    }
     
    258218    child->setParent(owner);
    259219   
    260     if (fullInsert) {
    261         // Keep our layer hierarchy updated.  Optimize for the common case where we don't have any children
    262         // and don't have a layer attached to ourselves.
    263         RenderLayer* layer = 0;
    264         if (child->firstChild() || child->hasLayer()) {
    265             layer = owner->enclosingLayer();
    266             child->addLayers(layer);
    267         }
    268 
    269         // if the new child is visible but this object was not, tell the layer it has some visible content
    270         // that needs to be drawn and layer visibility optimization can't be used
    271         if (owner->style()->visibility() != VISIBLE && child->style()->visibility() == VISIBLE && !child->hasLayer()) {
    272             if (!layer)
    273                 layer = owner->enclosingLayer();
    274             if (layer)
    275                 layer->setHasVisibleContent();
    276         }
    277 
    278         if (child->isListItem())
    279             toRenderListItem(child)->updateListMarkerNumbers();
    280 
    281         if (!child->isFloating() && owner->childrenInline())
    282             owner->dirtyLinesFromChangedChild(child);
    283 
    284         if (child->isRenderRegion())
    285             toRenderRegion(child)->attachRegion();
    286 
    287         // Calling attachQuote() here would be too early (before anonymous renderers are inserted)
    288         // see appendChild() for more explanation.
    289 
    290         if (RenderNamedFlowThread* containerFlowThread = renderNamedFlowThreadContainer(owner))
    291             containerFlowThread->addFlowChild(child, beforeChild);
    292     }
     220    if (notifyRenderer)
     221        child->insertedIntoTree();
    293222
    294223    if (!owner->documentBeingDestroyed()) {
  • trunk/Source/WebCore/rendering/RenderObjectChildList.h

    r110656 r125737  
    5454
    5555    RenderObject* removeChildNode(RenderObject* owner, RenderObject*, bool fullRemove = true);
    56     void appendChildNode(RenderObject* owner, RenderObject*, bool fullAppend = true);
    57     void insertChildNode(RenderObject* owner, RenderObject* child, RenderObject* before, bool fullInsert = true);
     56    void appendChildNode(RenderObject* owner, RenderObject*, bool notifyRenderer = true);
     57    void insertChildNode(RenderObject* owner, RenderObject* child, RenderObject* before, bool notifyRenderer = true);
    5858
    5959    void updateBeforeAfterContent(RenderObject* owner, PseudoId type, const RenderObject* styledObject = 0);
  • trunk/Source/WebCore/rendering/RenderQuote.h

    r125476 r125737  
    4545    virtual void computePreferredLogicalWidths(float leadWidth) OVERRIDE;
    4646
     47    // We don't override insertedIntoTree to call attachQuote() as it would be attached
     48    // too early and get the wrong depth since generated content is inserted into anonymous
     49    // renderers before going into the main render tree. Once we can ensure that insertIntoTree,
     50    // is called on an attached tree, we should override it here.
     51
    4752    const QuotesData* quotesData() const;
    4853    void updateDepth();
  • trunk/Source/WebCore/rendering/RenderRegion.cpp

    r125376 r125737  
    358358}
    359359
     360void RenderRegion::insertedIntoTree()
     361{
     362    RenderReplaced::insertedIntoTree();
     363
     364    attachRegion();
     365}
     366
    360367PassRefPtr<RenderStyle> RenderRegion::computeStyleInRegion(const RenderObject* object)
    361368{
  • trunk/Source/WebCore/rendering/RenderRegion.h

    r125192 r125737  
    101101    virtual const char* renderName() const { return "RenderRegion"; }
    102102
     103    virtual void insertedIntoTree() OVERRIDE;
     104
    103105    PassRefPtr<RenderStyle> computeStyleInRegion(const RenderObject*);
    104106    void computeChildrenStyleInRegion(const RenderObject*);
Note: See TracChangeset for help on using the changeset viewer.