Index: Source/core/dom/RenderTreeBuilder.cpp |
diff --git a/Source/core/dom/RenderTreeBuilder.cpp b/Source/core/dom/RenderTreeBuilder.cpp |
index 4acfcf80c0ade657854c10c15f10caddb5628153..0e5392b5b7f2d824fe548415b54b885d62b877b9 100644 |
--- a/Source/core/dom/RenderTreeBuilder.cpp |
+++ b/Source/core/dom/RenderTreeBuilder.cpp |
@@ -26,6 +26,7 @@ |
#include "config.h" |
#include "core/dom/RenderTreeBuilder.h" |
+#include "HTMLNames.h" |
#include "RuntimeEnabledFeatures.h" |
#include "SVGNames.h" |
#include "core/css/resolver/StyleResolver.h" |
@@ -43,32 +44,24 @@ namespace WebCore { |
RenderObject* RenderTreeBuilder::nextRenderer() const |
{ |
+ ASSERT(m_renderingParent); |
+ |
Element* element = m_node->isElementNode() ? toElement(m_node) : 0; |
- if (element && element->shouldBeReparentedUnderRenderView(m_style.get())) { |
- // FIXME: Reparented renderers not in the top layer should probably be |
- // ordered in DOM tree order. We don't have a good way to do that yet, |
- // since NodeRenderingTraversal isn't aware of reparenting. It's safe to |
- // just append for now; it doesn't disrupt the top layer rendering as |
- // the layer collection in RenderLayer only requires that top layer |
- // renderers are orderered correctly relative to each other. |
- if (!element->isInTopLayer()) |
- return 0; |
- const Vector<RefPtr<Element> >& topLayerElements = element->document().topLayerElements(); |
- size_t position = topLayerElements.find(element); |
- ASSERT(position != kNotFound); |
- for (size_t i = position + 1; i < topLayerElements.size(); ++i) { |
- if (RenderObject* renderer = topLayerElements[i]->renderer()) |
- return renderer; |
- } |
- return 0; |
+ if (element) { |
+ if (element->isInTopLayer()) |
+ return NodeRenderingTraversal::nextInTopLayer(element); |
+ // FIXME: Reparented dialogs not in the top layer need to be in DOM tree order. |
+ // FIXME: The spec should not require magical behavior for <dialog>. |
+ if (element->hasTagName(HTMLNames::dialogTag) && m_style->position() == AbsolutePosition) |
+ return 0; |
} |
if (m_parentFlowRenderer) |
return m_parentFlowRenderer->nextRendererForNode(m_node); |
// Avoid an O(N^2) walk over the children when reattaching all children of a node. |
- if (m_renderingParent && m_renderingParent->needsAttach()) |
+ if (m_renderingParent->needsAttach()) |
return 0; |
return NodeRenderingTraversal::nextSiblingRenderer(m_node); |
@@ -76,22 +69,33 @@ RenderObject* RenderTreeBuilder::nextRenderer() const |
RenderObject* RenderTreeBuilder::parentRenderer() const |
{ |
- if (m_node->isElementNode() && toElement(m_node)->shouldBeReparentedUnderRenderView(m_style.get())) { |
- // The parent renderer of reparented elements is the RenderView, but only |
- // if the normal parent would have had a renderer. |
- // FIXME: This behavior 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 (!m_renderingParent || !m_renderingParent->renderer()) |
- return 0; |
- return m_node->document().renderView(); |
+ ASSERT(m_renderingParent); |
+ |
+ Element* element = m_node->isElementNode() ? toElement(m_node) : 0; |
+ |
+ if (element && m_renderingParent->renderer()) { |
+ // FIXME: The spec should not require magical behavior for <dialog>. Note that the first |
+ // time we enter here the m_style might be null because of a call in shouldCreateRenderer() |
+ // which means we return the wrong wrong renderer for that check and then return a totally |
+ // different renderer (the RenderView) later when this method is called after setting m_style. |
+ if (element->hasTagName(HTMLNames::dialogTag) && m_style && m_style->position() == AbsolutePosition) |
+ return m_node->document().renderView(); |
+ |
+ // FIXME: Guarding this by m_renderingParent->renderer() 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()) |
+ return m_node->document().renderView(); |
} |
+ // Even if the normal parent has no renderer we still can be flowed into a named flow. |
+ // FIXME: This is bad, it breaks the assumption that if you have a renderer then |
+ // NodeRenderingTraversal::parent(this) also has one which likely means lots of bugs |
+ // with regions. |
if (m_parentFlowRenderer) |
return m_parentFlowRenderer; |
- return m_renderingParent ? m_renderingParent->renderer() : 0; |
+ return m_renderingParent->renderer(); |
} |
bool RenderTreeBuilder::shouldCreateRenderer() const |
@@ -114,8 +118,9 @@ bool RenderTreeBuilder::shouldCreateRenderer() const |
// Check the specific case of elements that are children of regions but are flowed into a flow thread themselves. |
bool RenderTreeBuilder::elementInsideRegionNeedsRenderer() |
{ |
+ if (!RuntimeEnabledFeatures::cssRegionsEnabled()) |
+ return false; |
Element* element = toElement(m_node); |
- bool elementInsideRegionNeedsRenderer = false; |
RenderObject* parentRenderer = this->parentRenderer(); |
if ((parentRenderer && !parentRenderer->canHaveChildren() && parentRenderer->isRenderNamedFlowFragmentContainer()) |
|| (!parentRenderer && element->parentElement() && element->parentElement()->isInsideRegion())) { |
@@ -123,14 +128,14 @@ bool RenderTreeBuilder::elementInsideRegionNeedsRenderer() |
if (!m_style) |
m_style = element->styleForRenderer(); |
- elementInsideRegionNeedsRenderer = element->shouldMoveToFlowThread(m_style.get()); |
- |
// Children of this element will only be allowed to be flowed into other flow-threads if display is NOT none. |
if (element->rendererIsNeeded(*m_style)) |
element->setIsInsideRegion(true); |
+ |
+ return element->shouldMoveToFlowThread(m_style.get()); |
} |
- return elementInsideRegionNeedsRenderer; |
+ return false; |
} |
void RenderTreeBuilder::moveToFlowThreadIfNeeded() |
@@ -153,9 +158,11 @@ void RenderTreeBuilder::createRendererForElementIfNeeded() |
{ |
ASSERT(!m_node->renderer()); |
- Element* element = toElement(m_node); |
+ // If we're out of composition then we can't render since there's no parent to inherit from. |
+ if (!m_renderingParent) |
+ return; |
- element->setIsInsideRegion(false); |
+ Element* element = toElement(m_node); |
if (!shouldCreateRenderer() && !elementInsideRegionNeedsRenderer()) |
return; |
@@ -201,11 +208,14 @@ void RenderTreeBuilder::createRendererForTextIfNeeded() |
{ |
ASSERT(!m_node->renderer()); |
- Text* textNode = toText(m_node); |
+ // If we're out of composition then we can't render since there's no parent to inherit from. |
+ if (!m_renderingParent) |
+ return; |
if (!shouldCreateRenderer()) |
return; |
+ Text* textNode = toText(m_node); |
RenderObject* parentRenderer = this->parentRenderer(); |
if (m_parentDetails.resetStyleInheritance()) |