Diff
Modified: trunk/Source/WebCore/ChangeLog (154805 => 154806)
--- trunk/Source/WebCore/ChangeLog 2013-08-29 06:11:10 UTC (rev 154805)
+++ trunk/Source/WebCore/ChangeLog 2013-08-29 12:25:23 UTC (rev 154806)
@@ -1,3 +1,35 @@
+2013-08-29 Antti Koivisto <[email protected]>
+
+ Move element renderer creation out of NodeRenderingContext
+ https://bugs.webkit.org/show_bug.cgi?id=120461
+
+ Reviewed by Andreas Kling.
+
+ Move NodeRenderingContext::createRendererIfNeeded() and the related utility functions to StyleResolveTree.
+
+ Tighten typing and constness. Refactor sligthly to be more understandable.
+
+ * dom/Element.cpp:
+ (WebCore::Element::shouldMoveToFlowThread):
+ * dom/Element.h:
+ * dom/NodeRenderingContext.cpp:
+ (WebCore::NodeRenderingContext::NodeRenderingContext):
+ (WebCore::NodeRenderingContext::nextRenderer):
+ (WebCore::NodeRenderingContext::previousRenderer):
+ (WebCore::NodeRenderingContext::parentRenderer):
+ * dom/NodeRenderingContext.h:
+ * dom/PseudoElement.h:
+ * style/StyleResolveTree.cpp:
+ (WebCore::Style::nextSiblingRenderer):
+ (WebCore::Style::shouldCreateRenderer):
+ (WebCore::Style::elementInsideRegionNeedsRenderer):
+ (WebCore::Style::moveToFlowThreadIfNeeded):
+ (WebCore::Style::createRendererIfNeeded):
+ (WebCore::Style::attachRenderTree):
+ * svg/SVGElement.cpp:
+ (WebCore::SVGElement::shouldMoveToFlowThread):
+ * svg/SVGElement.h:
+
2013-08-28 Chris Fleizach <[email protected]>
AX: WebProcess at com.apple.WebCore: WebCore::AXObjectCache::rootObject + 27
Modified: trunk/Source/WebCore/dom/Element.cpp (154805 => 154806)
--- trunk/Source/WebCore/dom/Element.cpp 2013-08-29 06:11:10 UTC (rev 154805)
+++ trunk/Source/WebCore/dom/Element.cpp 2013-08-29 12:25:23 UTC (rev 154806)
@@ -2677,10 +2677,8 @@
#if ENABLE(CSS_REGIONS)
-bool Element::shouldMoveToFlowThread(RenderStyle* styleToUse) const
+bool Element::shouldMoveToFlowThread(const RenderStyle& styleToUse) const
{
- ASSERT(styleToUse);
-
#if ENABLE(FULLSCREEN_API)
if (document()->webkitIsFullScreen() && document()->webkitCurrentFullScreenElement() == this)
return false;
@@ -2689,7 +2687,7 @@
if (isInShadowTree())
return false;
- if (styleToUse->flowThread().isEmpty())
+ if (styleToUse.flowThread().isEmpty())
return false;
return !isRegisteredWithNamedFlow();
Modified: trunk/Source/WebCore/dom/Element.h (154805 => 154806)
--- trunk/Source/WebCore/dom/Element.h 2013-08-29 06:11:10 UTC (rev 154805)
+++ trunk/Source/WebCore/dom/Element.h 2013-08-29 12:25:23 UTC (rev 154806)
@@ -525,7 +525,7 @@
RenderRegion* renderRegion() const;
#if ENABLE(CSS_REGIONS)
- virtual bool shouldMoveToFlowThread(RenderStyle*) const;
+ virtual bool shouldMoveToFlowThread(const RenderStyle&) const;
const AtomicString& webkitRegionOverset() const;
Vector<RefPtr<Range> > webkitGetRegionFlowRanges() const;
Modified: trunk/Source/WebCore/dom/NodeRenderingContext.cpp (154805 => 154806)
--- trunk/Source/WebCore/dom/NodeRenderingContext.cpp 2013-08-29 06:11:10 UTC (rev 154805)
+++ trunk/Source/WebCore/dom/NodeRenderingContext.cpp 2013-08-29 12:25:23 UTC (rev 154806)
@@ -54,27 +54,10 @@
NodeRenderingContext::NodeRenderingContext(Node* node)
: m_node(node)
- , m_parentFlowRenderer(0)
{
m_renderingParent = NodeRenderingTraversal::parent(node);
}
-NodeRenderingContext::NodeRenderingContext(Node* node, RenderStyle* style)
- : m_node(node)
- , m_renderingParent(0)
- , m_style(style)
- , m_parentFlowRenderer(0)
-{
-}
-
-NodeRenderingContext::NodeRenderingContext(Node* node, const Style::AttachContext& context)
- : m_node(node)
- , m_style(context.resolvedStyle)
- , m_parentFlowRenderer(0)
-{
- m_renderingParent = NodeRenderingTraversal::parent(node);
-}
-
NodeRenderingContext::~NodeRenderingContext()
{
}
@@ -111,9 +94,6 @@
}
#endif
- if (m_parentFlowRenderer)
- return m_parentFlowRenderer->nextRendererForNode(m_node);
-
// Avoid an O(N^2) problem with this function by not checking for
// nextRenderer() when the parent element hasn't attached yet.
if (m_renderingParent && !m_renderingParent->attached())
@@ -140,9 +120,6 @@
ASSERT(!m_node->isElementNode() || !toElement(m_node)->isInTopLayer());
#endif
- if (m_parentFlowRenderer)
- return m_parentFlowRenderer->previousRendererForNode(m_node);
-
// FIXME: We should have the same O(N^2) avoidance as nextRenderer does
// however, when I tried adding it, several tests failed.
for (Node* sibling = NodeRenderingTraversal::previousSibling(m_node); sibling; sibling = NodeRenderingTraversal::previousSibling(sibling)) {
@@ -173,118 +150,9 @@
}
#endif
- if (m_parentFlowRenderer)
- return m_parentFlowRenderer;
-
return m_renderingParent ? m_renderingParent->renderer() : 0;
}
-bool NodeRenderingContext::shouldCreateRenderer() const
-{
- if (!m_node->document()->shouldCreateRenderers())
- return false;
- if (!m_renderingParent)
- return false;
- RenderObject* parentRenderer = this->parentRenderer();
- if (!parentRenderer)
- return false;
- if (!parentRenderer->canHaveChildren() && !(m_node->isPseudoElement() && parentRenderer->canHaveGeneratedChildren()))
- return false;
- if (!m_renderingParent->childShouldCreateRenderer(m_node))
- return false;
- return true;
-}
-
-// Check the specific case of elements that are children of regions but are flowed into a flow thread themselves.
-bool NodeRenderingContext::elementInsideRegionNeedsRenderer()
-{
- bool elementInsideRegionNeedsRenderer = false;
-
-#if ENABLE(CSS_REGIONS)
- Element* element = toElement(m_node);
- RenderObject* parentRenderer = this->parentRenderer();
- if ((parentRenderer && !parentRenderer->canHaveChildren() && parentRenderer->isRenderRegion())
- || (!parentRenderer && element->parentElement() && element->parentElement()->isInsideRegion())) {
-
- 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);
- }
-#endif
-
- return elementInsideRegionNeedsRenderer;
-}
-
-void NodeRenderingContext::moveToFlowThreadIfNeeded()
-{
-#if ENABLE(CSS_REGIONS)
- Element* element = toElement(m_node);
-
- if (!element->shouldMoveToFlowThread(m_style.get()))
- return;
-
- ASSERT(m_node->document()->renderView());
- FlowThreadController& flowThreadController = m_node->document()->renderView()->flowThreadController();
- m_parentFlowRenderer = &flowThreadController.ensureRenderFlowThreadWithName(m_style->flowThread());
- flowThreadController.registerNamedFlowContentNode(m_node, m_parentFlowRenderer);
-#endif
-}
-
-void NodeRenderingContext::createRendererForElementIfNeeded()
-{
- ASSERT(!m_node->renderer());
-
- Element* element = toElement(m_node);
-
- element->setIsInsideRegion(false);
-
- if (!shouldCreateRenderer() && !elementInsideRegionNeedsRenderer())
- return;
-
- if (!m_style)
- m_style = element->styleForRenderer();
- ASSERT(m_style);
-
- moveToFlowThreadIfNeeded();
-
- if (!element->rendererIsNeeded(*m_style))
- return;
-
- RenderObject* parentRenderer = this->parentRenderer();
- RenderObject* nextRenderer = this->nextRenderer();
-
- Document* document = element->document();
- RenderObject* newRenderer = element->createRenderer(document->renderArena(), m_style.get());
- if (!newRenderer)
- return;
- if (!parentRenderer->isChildAllowed(newRenderer, m_style.get())) {
- newRenderer->destroy();
- return;
- }
-
- // Make sure the RenderObject already knows it is going to be added to a RenderFlowThread before we set the style
- // for the first time. Otherwise code using inRenderFlowThread() in the styleWillChange and styleDidChange will fail.
- newRenderer->setFlowThreadState(parentRenderer->flowThreadState());
-
- element->setRenderer(newRenderer);
- newRenderer->setAnimatableStyle(m_style.release()); // setAnimatableStyle() can depend on renderer() already being set.
-
-#if ENABLE(FULLSCREEN_API)
- if (document->webkitIsFullScreen() && document->webkitCurrentFullScreenElement() == element) {
- newRenderer = RenderFullScreen::wrapRenderer(newRenderer, parentRenderer, document);
- if (!newRenderer)
- return;
- }
-#endif
- // Note: Adding newRenderer instead of renderer(). renderer() may be a child of newRenderer.
- parentRenderer->addChild(newRenderer, nextRenderer);
-}
-
bool NodeRenderingContext::resetStyleInheritance() const
{
ContainerNode* parent = m_node->parentNode();
Modified: trunk/Source/WebCore/dom/NodeRenderingContext.h (154805 => 154806)
--- trunk/Source/WebCore/dom/NodeRenderingContext.h 2013-08-29 06:11:10 UTC (rev 154805)
+++ trunk/Source/WebCore/dom/NodeRenderingContext.h 2013-08-29 12:25:23 UTC (rev 154806)
@@ -27,7 +27,6 @@
#define NodeRenderingContext_h
#include "NodeRenderingTraversal.h"
-#include "StyleResolveTree.h"
#include <wtf/Noncopyable.h>
#include <wtf/RefPtr.h>
@@ -36,22 +35,14 @@
namespace WebCore {
class ContainerNode;
-class Document;
-class InsertionPoint;
class Node;
-class RenderNamedFlowThread;
class RenderObject;
-class RenderStyle;
class NodeRenderingContext {
public:
explicit NodeRenderingContext(Node*);
- NodeRenderingContext(Node*, RenderStyle*);
- NodeRenderingContext(Node*, const Style::AttachContext&);
~NodeRenderingContext();
- void createRendererForElementIfNeeded();
-
Node* node() const;
ContainerNode* parentNodeForRenderingAndStyle() const;
bool resetStyleInheritance() const;
@@ -59,17 +50,9 @@
RenderObject* nextRenderer() const;
RenderObject* previousRenderer() const;
- const RenderStyle* style() const;
-
private:
- bool shouldCreateRenderer() const;
- void moveToFlowThreadIfNeeded();
- bool elementInsideRegionNeedsRenderer();
-
Node* m_node;
ContainerNode* m_renderingParent;
- RefPtr<RenderStyle> m_style;
- RenderNamedFlowThread* m_parentFlowRenderer;
};
inline Node* NodeRenderingContext::node() const
@@ -82,11 +65,6 @@
return m_renderingParent;
}
-inline const RenderStyle* NodeRenderingContext::style() const
-{
- return m_style.get();
-}
-
} // namespace WebCore
#endif
Modified: trunk/Source/WebCore/dom/PseudoElement.h (154805 => 154806)
--- trunk/Source/WebCore/dom/PseudoElement.h 2013-08-29 06:11:10 UTC (rev 154805)
+++ trunk/Source/WebCore/dom/PseudoElement.h 2013-08-29 12:25:23 UTC (rev 154806)
@@ -52,7 +52,7 @@
// As per http://dev.w3.org/csswg/css3-regions/#flow-into, pseudo-elements such as ::first-line, ::first-letter, ::before or ::after
// cannot be directly collected into a named flow.
#if ENABLE(CSS_REGIONS)
- virtual bool shouldMoveToFlowThread(RenderStyle*) const OVERRIDE { return false; }
+ virtual bool shouldMoveToFlowThread(const RenderStyle&) const OVERRIDE { return false; }
#endif
virtual bool canStartSelection() const OVERRIDE { return false; }
Modified: trunk/Source/WebCore/style/StyleResolveTree.cpp (154805 => 154806)
--- trunk/Source/WebCore/style/StyleResolveTree.cpp 2013-08-29 06:11:10 UTC (rev 154805)
+++ trunk/Source/WebCore/style/StyleResolveTree.cpp 2013-08-29 12:25:23 UTC (rev 154806)
@@ -30,9 +30,12 @@
#include "Element.h"
#include "ElementRareData.h"
#include "ElementTraversal.h"
+#include "FlowThreadController.h"
#include "NodeRenderStyle.h"
#include "NodeRenderingContext.h"
#include "NodeTraversal.h"
+#include "RenderFullScreen.h"
+#include "RenderNamedFlowThread.h"
#include "RenderObject.h"
#include "RenderText.h"
#include "RenderWidget.h"
@@ -104,11 +107,6 @@
return NoChange;
}
-static void createRendererIfNeeded(Element* element, const AttachContext& context)
-{
- NodeRenderingContext(element, context).createRendererForElementIfNeeded();
-}
-
static bool isRendererReparented(const RenderObject* renderer)
{
if (!renderer->node()->isElementNode())
@@ -118,6 +116,132 @@
return false;
}
+static RenderObject* nextSiblingRenderer(const Element& element, const ContainerNode* renderingParentNode)
+{
+ // Avoid an O(N^2) problem with this function by not checking for
+ // nextRenderer() when the parent element hasn't attached yet.
+ // FIXME: Why would we get here anyway if parent is not attached?
+ if (renderingParentNode && !renderingParentNode->attached())
+ return 0;
+ for (Node* sibling = NodeRenderingTraversal::nextSibling(&element); sibling; sibling = NodeRenderingTraversal::nextSibling(sibling)) {
+ RenderObject* renderer = sibling->renderer();
+ if (renderer && !isRendererReparented(renderer))
+ return renderer;
+ }
+ return 0;
+}
+
+static bool shouldCreateRenderer(const Element& element, const ContainerNode* renderingParent)
+{
+ if (!element.document()->shouldCreateRenderers())
+ return false;
+ if (!renderingParent)
+ return false;
+ RenderObject* parentRenderer = renderingParent->renderer();
+ if (!parentRenderer)
+ return false;
+ if (!parentRenderer->canHaveChildren() && !(element.isPseudoElement() && parentRenderer->canHaveGeneratedChildren()))
+ return false;
+ if (!renderingParent->childShouldCreateRenderer(&element))
+ return false;
+ return true;
+}
+
+// Check the specific case of elements that are children of regions but are flowed into a flow thread themselves.
+static bool elementInsideRegionNeedsRenderer(Element& element, const ContainerNode* renderingParentNode, RefPtr<RenderStyle>& style)
+{
+#if ENABLE(CSS_REGIONS)
+ const RenderObject* parentRenderer = renderingParentNode ? renderingParentNode->renderer() : 0;
+
+ bool parentIsRegion = parentRenderer && !parentRenderer->canHaveChildren() && parentRenderer->isRenderRegion();
+ bool parentIsNonRenderedInsideRegion = !parentRenderer && element.parentElement() && element.parentElement()->isInsideRegion();
+ if (!parentIsRegion && !parentIsNonRenderedInsideRegion)
+ return false;
+
+ if (!style)
+ style = element.styleForRenderer();
+
+ // Children of this element will only be allowed to be flowed into other flow-threads if display is NOT none.
+ if (element.rendererIsNeeded(*style))
+ element.setIsInsideRegion(true);
+
+ if (element.shouldMoveToFlowThread(*style))
+ return true;
+#endif
+ return false;
+}
+
+static RenderNamedFlowThread* moveToFlowThreadIfNeeded(Element& element, const RenderStyle& style)
+{
+ if (!element.shouldMoveToFlowThread(style))
+ return 0;
+ FlowThreadController& flowThreadController = element.document()->renderView()->flowThreadController();
+ RenderNamedFlowThread& parentFlowRenderer = flowThreadController.ensureRenderFlowThreadWithName(style.flowThread());
+ flowThreadController.registerNamedFlowContentNode(&element, &parentFlowRenderer);
+ return &parentFlowRenderer;
+}
+
+static void createRendererIfNeeded(Element& element, const AttachContext& context)
+{
+ ASSERT(!element.renderer());
+
+ Document& document = *element.document();
+ ContainerNode* renderingParentNode = NodeRenderingTraversal::parent(&element);
+
+ RefPtr<RenderStyle> style = context.resolvedStyle;
+
+ element.setIsInsideRegion(false);
+
+ if (!shouldCreateRenderer(element, renderingParentNode) && !elementInsideRegionNeedsRenderer(element, renderingParentNode, style))
+ return;
+
+ if (!style)
+ style = element.styleForRenderer();
+
+ RenderNamedFlowThread* parentFlowRenderer = 0;
+#if ENABLE(CSS_REGIONS)
+ parentFlowRenderer = moveToFlowThreadIfNeeded(element, *style);
+#endif
+
+ if (!element.rendererIsNeeded(*style))
+ return;
+
+ RenderObject* parentRenderer;
+ RenderObject* nextRenderer;
+ if (parentFlowRenderer) {
+ parentRenderer = parentFlowRenderer;
+ nextRenderer = parentFlowRenderer->nextRendererForNode(&element);
+ } else {
+ parentRenderer = renderingParentNode->renderer();
+ nextRenderer = nextSiblingRenderer(element, renderingParentNode);
+ }
+
+ RenderObject* newRenderer = element.createRenderer(document.renderArena(), style.get());
+ if (!newRenderer)
+ return;
+ if (!parentRenderer->isChildAllowed(newRenderer, style.get())) {
+ newRenderer->destroy();
+ return;
+ }
+
+ // Make sure the RenderObject already knows it is going to be added to a RenderFlowThread before we set the style
+ // for the first time. Otherwise code using inRenderFlowThread() in the styleWillChange and styleDidChange will fail.
+ newRenderer->setFlowThreadState(parentRenderer->flowThreadState());
+
+ element.setRenderer(newRenderer);
+ newRenderer->setAnimatableStyle(style.release()); // setAnimatableStyle() can depend on renderer() already being set.
+
+#if ENABLE(FULLSCREEN_API)
+ if (document.webkitIsFullScreen() && document.webkitCurrentFullScreenElement() == &element) {
+ newRenderer = RenderFullScreen::wrapRenderer(newRenderer, parentRenderer, &document);
+ if (!newRenderer)
+ return;
+ }
+#endif
+ // Note: Adding newRenderer instead of renderer(). renderer() may be a child of newRenderer.
+ parentRenderer->addChild(newRenderer, nextRenderer);
+}
+
static RenderObject* previousSiblingRenderer(const Text& textNode)
{
if (textNode.renderer())
@@ -341,7 +465,7 @@
if (current->hasCustomStyleResolveCallbacks())
current->willAttachRenderers();
- createRendererIfNeeded(current, context);
+ createRendererIfNeeded(*current, context);
if (current->parentElement() && current->parentElement()->isInCanvasSubtree())
current->setIsInCanvasSubtree(true);
Modified: trunk/Source/WebCore/svg/SVGElement.cpp (154805 => 154806)
--- trunk/Source/WebCore/svg/SVGElement.cpp 2013-08-29 06:11:10 UTC (rev 154805)
+++ trunk/Source/WebCore/svg/SVGElement.cpp 2013-08-29 12:25:23 UTC (rev 154806)
@@ -569,7 +569,7 @@
}
#if ENABLE(CSS_REGIONS)
-bool SVGElement::shouldMoveToFlowThread(RenderStyle* styleToUse) const
+bool SVGElement::shouldMoveToFlowThread(const RenderStyle& styleToUse) const
{
// Allow only svg root elements to be directly collected by a render flow thread.
return parentNode() && !parentNode()->isSVGElement() && hasTagName(SVGNames::svgTag) && Element::shouldMoveToFlowThread(styleToUse);
Modified: trunk/Source/WebCore/svg/SVGElement.h (154805 => 154806)
--- trunk/Source/WebCore/svg/SVGElement.h 2013-08-29 06:11:10 UTC (rev 154805)
+++ trunk/Source/WebCore/svg/SVGElement.h 2013-08-29 12:25:23 UTC (rev 154806)
@@ -135,7 +135,7 @@
virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture) OVERRIDE;
#if ENABLE(CSS_REGIONS)
- virtual bool shouldMoveToFlowThread(RenderStyle*) const OVERRIDE;
+ virtual bool shouldMoveToFlowThread(const RenderStyle&) const OVERRIDE;
#endif
protected: