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