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();