Title: [154806] trunk/Source/WebCore
Revision
154806
Author
[email protected]
Date
2013-08-29 05:25:23 -0700 (Thu, 29 Aug 2013)

Log Message

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:

Modified Paths

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:
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to