Index: Source/core/dom/RenderTreeBuilder.cpp |
diff --git a/Source/core/dom/RenderTreeBuilder.cpp b/Source/core/dom/RenderTreeBuilder.cpp |
index faa45502740da114ee05cbef3e76139de3e905c1..ca6f6ca27e356893318b1a752f80def45464e77b 100644 |
--- a/Source/core/dom/RenderTreeBuilder.cpp |
+++ b/Source/core/dom/RenderTreeBuilder.cpp |
@@ -43,70 +43,52 @@ |
namespace blink { |
-RenderTreeBuilder::RenderTreeBuilder(Node* node, RenderStyle* style) |
- : m_node(node) |
- , m_renderingParent(nullptr) |
+RenderTreeBuilderForElement::RenderTreeBuilderForElement(Element* element, RenderStyle* style) |
+ : RenderTreeBuilder(element, nullptr) |
, m_style(style) |
{ |
- ASSERT(!node->renderer()); |
- ASSERT(node->needsAttach()); |
- ASSERT(node->document().inStyleRecalc()); |
- |
- // FIXME: We should be able to ASSERT(node->inActiveDocument()) but childrenChanged is called |
- // before ChildNodeInsertionNotifier in ContainerNode's methods and some implementations |
- // will trigger a layout inside childrenChanged. |
- // Mainly HTMLTextAreaElement::childrenChanged calls HTMLTextFormControlElement::setSelectionRange |
- // which does an updateLayoutIgnorePendingStylesheets. |
- |
- Element* element = node->isElementNode() ? toElement(node) : 0; |
- if (element && element->isFirstLetterPseudoElement()) { |
+ if (element->isFirstLetterPseudoElement()) { |
if (RenderObject* nextRenderer = FirstLetterPseudoElement::firstLetterTextRenderer(*element)) |
m_renderingParent = nextRenderer->parent(); |
- } else if (ContainerNode* containerNode = NodeRenderingTraversal::parent(node, &m_parentDetails)) { |
+ } else if (ContainerNode* containerNode = NodeRenderingTraversal::parent(element)) { |
m_renderingParent = containerNode->renderer(); |
} |
} |
-RenderObject* RenderTreeBuilder::nextRenderer() const |
+RenderObject* RenderTreeBuilderForElement::nextRenderer() const |
{ |
ASSERT(m_renderingParent); |
- Element* element = m_node->isElementNode() ? toElement(m_node) : 0; |
+ if (m_node->isInTopLayer()) |
+ return NodeRenderingTraversal::nextInTopLayer(m_node); |
- if (element && element->isInTopLayer()) |
- return NodeRenderingTraversal::nextInTopLayer(element); |
+ if (m_node->isFirstLetterPseudoElement()) |
+ return FirstLetterPseudoElement::firstLetterTextRenderer(*m_node); |
- if (element && element->isFirstLetterPseudoElement()) |
- return FirstLetterPseudoElement::firstLetterTextRenderer(*element); |
- |
- // Avoid an O(N^2) walk over the children when reattaching all children of a node. |
- if (m_renderingParent->node() && m_renderingParent->node()->needsAttach()) |
- return 0; |
- |
- return NodeRenderingTraversal::nextSiblingRenderer(m_node); |
+ return RenderTreeBuilder::nextRenderer(); |
} |
-RenderObject* RenderTreeBuilder::parentRenderer() const |
+RenderObject* RenderTreeBuilderForElement::parentRenderer() const |
{ |
- ASSERT(m_renderingParent); |
- |
- Element* element = m_node->isElementNode() ? toElement(m_node) : 0; |
+ RenderObject* parentRenderer = RenderTreeBuilder::parentRenderer(); |
- if (element && m_renderingParent) { |
- // FIXME: Guarding this by m_renderingParent isn't quite right as the spec for |
+ if (parentRenderer) { |
+ // FIXME: Guarding this by parentRenderer isn't quite right as the spec for |
// top layer only talks about display: none ancestors so putting a <dialog> inside an |
// <optgroup> seems like it should still work even though this check will prevent it. |
- if (element->isInTopLayer()) |
+ if (m_node->isInTopLayer()) |
return m_node->document().renderView(); |
} |
- return m_renderingParent; |
+ return parentRenderer; |
} |
-bool RenderTreeBuilder::shouldCreateRenderer() const |
+bool RenderTreeBuilderForElement::shouldCreateRenderer() const |
{ |
if (!m_renderingParent) |
return false; |
+ |
+ // FIXME: Should the following be in SVGElement::rendererIsNeeded()? |
if (m_node->isSVGElement()) { |
// SVG elements only render when inside <svg>, or if the element is an <svg> itself. |
if (!isSVGSVGElement(*m_node) && (!m_renderingParent->node() || !m_renderingParent->node()->isSVGElement())) |
@@ -120,30 +102,22 @@ bool RenderTreeBuilder::shouldCreateRenderer() const |
return false; |
if (!parentRenderer->canHaveChildren()) |
return false; |
- return true; |
+ |
+ return m_node->rendererIsNeeded(style()); |
} |
-RenderStyle& RenderTreeBuilder::style() const |
+RenderStyle& RenderTreeBuilderForElement::style() const |
{ |
if (!m_style) |
- m_style = toElement(m_node)->styleForRenderer(); |
+ m_style = m_node->styleForRenderer(); |
return *m_style; |
} |
-void RenderTreeBuilder::createRendererForElementIfNeeded() |
+void RenderTreeBuilderForElement::createRenderer() |
{ |
- ASSERT(!m_node->renderer()); |
- |
- if (!shouldCreateRenderer()) |
- return; |
- |
- Element* element = toElement(m_node); |
RenderStyle& style = this->style(); |
- if (!element->rendererIsNeeded(style)) |
- return; |
- |
- RenderObject* newRenderer = element->createRenderer(&style); |
+ RenderObject* newRenderer = m_node->createRenderer(&style); |
if (!newRenderer) |
return; |
@@ -159,11 +133,11 @@ void RenderTreeBuilder::createRendererForElementIfNeeded() |
newRenderer->setFlowThreadState(parentRenderer->flowThreadState()); |
RenderObject* nextRenderer = this->nextRenderer(); |
- element->setRenderer(newRenderer); |
+ m_node->setRenderer(newRenderer); |
newRenderer->setStyle(&style); // setStyle() can depend on renderer() already being set. |
- if (Fullscreen::isActiveFullScreenElement(*element)) { |
- newRenderer = RenderFullScreen::wrapRenderer(newRenderer, parentRenderer, &element->document()); |
+ if (Fullscreen::isActiveFullScreenElement(*m_node)) { |
+ newRenderer = RenderFullScreen::wrapRenderer(newRenderer, parentRenderer, &m_node->document()); |
if (!newRenderer) |
return; |
} |
@@ -172,23 +146,15 @@ void RenderTreeBuilder::createRendererForElementIfNeeded() |
parentRenderer->addChild(newRenderer, nextRenderer); |
} |
-void RenderTreeBuilder::createRendererForTextIfNeeded() |
+void RenderTreeBuilderForText::createRenderer() |
{ |
- ASSERT(!m_node->renderer()); |
- |
- if (!shouldCreateRenderer()) |
- return; |
- |
- Text* textNode = toText(m_node); |
RenderObject* parentRenderer = this->parentRenderer(); |
+ RenderStyle* style = parentRenderer->style(); |
- m_style = parentRenderer->style(); |
- |
- if (!textNode->textRendererIsNeeded(*m_style, *parentRenderer)) |
- return; |
+ ASSERT(m_node->textRendererIsNeeded(*style, *parentRenderer)); |
- RenderText* newRenderer = textNode->createTextRenderer(m_style.get()); |
- if (!parentRenderer->isChildAllowed(newRenderer, m_style.get())) { |
+ RenderText* newRenderer = m_node->createTextRenderer(style); |
+ if (!parentRenderer->isChildAllowed(newRenderer, style)) { |
newRenderer->destroy(); |
return; |
} |
@@ -198,9 +164,9 @@ void RenderTreeBuilder::createRendererForTextIfNeeded() |
newRenderer->setFlowThreadState(parentRenderer->flowThreadState()); |
RenderObject* nextRenderer = this->nextRenderer(); |
- textNode->setRenderer(newRenderer); |
+ m_node->setRenderer(newRenderer); |
// Parent takes care of the animations, no need to call setAnimatableStyle. |
- newRenderer->setStyle(m_style.release()); |
+ newRenderer->setStyle(style); |
parentRenderer->addChild(newRenderer, nextRenderer); |
} |