Title: [154738] trunk/Source/WebCore
Revision
154738
Author
[email protected]
Date
2013-08-28 06:12:52 -0700 (Wed, 28 Aug 2013)

Log Message

Don't use NodeRenderingContext when attaching text renderers
https://bugs.webkit.org/show_bug.cgi?id=120402

Reviewed by Andreas Kling.

This patch moves various functions for creating text renderers from NodeRenderingContext and Text to StyleResolveTree.
It also tightens the logic and combines some functions.

* dom/CharacterData.cpp:
(WebCore::CharacterData::parserAppendData):
(WebCore::CharacterData::setDataAndUpdate):
* dom/ContainerNode.cpp:
(WebCore::attachChild):
(WebCore::detachChild):
* dom/NodeRenderingContext.cpp:
* dom/NodeRenderingContext.h:
* dom/Text.cpp:
(WebCore::Text::~Text):
* dom/Text.h:
* html/HTMLViewSourceDocument.cpp:
(WebCore::HTMLViewSourceDocument::addText):
* html/parser/HTMLConstructionSite.cpp:
(WebCore::executeTask):
* html/shadow/InsertionPoint.cpp:
(WebCore::InsertionPoint::willAttachRenderers):
(WebCore::InsertionPoint::willDetachRenderers):
* style/StyleResolveTree.cpp:
(WebCore::Style::isRendererReparented):
(WebCore::Style::previousSiblingRenderer):
(WebCore::Style::nextSiblingRenderer):
        
    From NodeRenderingContext::next/previousRenderer

(WebCore::Style::createTextRenderersForSiblingsAfterAttachIfNeeded):
        
    From Text::createTextRenderersForSiblingsAfterAttachIfNeeded()

(WebCore::Style::textRendererIsNeeded):
        
    From Text::textRendererIsNeeded

(WebCore::Style::createTextRendererIfNeeded):
        
    Combines code from Text::createTextRendererIfNeeded, NodeRenderingContext::createRendererForTextIfNeeded,
    NodeRenderingContext constructor and text node relevant code NodeRenderingContext::shouldCreateRenderer.

(WebCore::Style::attachTextRenderer):
(WebCore::Style::detachTextRenderer):
        
    New functions of attaching text renderers. From Text::attach/detachText()

(WebCore::Style::updateTextRendererAfterContentChange):
        
    From Text::updateTextRenderer.

(WebCore::Style::attachShadowRoot):
(WebCore::Style::attachChildren):
(WebCore::Style::attachRenderTree):
(WebCore::Style::detachShadowRoot):
(WebCore::Style::detachChildren):
(WebCore::Style::updateTextStyle):
* style/StyleResolveTree.h:
* xml/parser/XMLDocumentParser.cpp:
(WebCore::XMLDocumentParser::exitText):
* xml/parser/XMLDocumentParserLibxml2.cpp:
(WebCore::XMLDocumentParser::cdataBlock):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (154737 => 154738)


--- trunk/Source/WebCore/ChangeLog	2013-08-28 12:52:18 UTC (rev 154737)
+++ trunk/Source/WebCore/ChangeLog	2013-08-28 13:12:52 UTC (rev 154738)
@@ -1,5 +1,74 @@
 2013-08-28  Antti Koivisto  <[email protected]>
 
+        Don't use NodeRenderingContext when attaching text renderers
+        https://bugs.webkit.org/show_bug.cgi?id=120402
+
+        Reviewed by Andreas Kling.
+
+        This patch moves various functions for creating text renderers from NodeRenderingContext and Text to StyleResolveTree.
+        It also tightens the logic and combines some functions.
+
+        * dom/CharacterData.cpp:
+        (WebCore::CharacterData::parserAppendData):
+        (WebCore::CharacterData::setDataAndUpdate):
+        * dom/ContainerNode.cpp:
+        (WebCore::attachChild):
+        (WebCore::detachChild):
+        * dom/NodeRenderingContext.cpp:
+        * dom/NodeRenderingContext.h:
+        * dom/Text.cpp:
+        (WebCore::Text::~Text):
+        * dom/Text.h:
+        * html/HTMLViewSourceDocument.cpp:
+        (WebCore::HTMLViewSourceDocument::addText):
+        * html/parser/HTMLConstructionSite.cpp:
+        (WebCore::executeTask):
+        * html/shadow/InsertionPoint.cpp:
+        (WebCore::InsertionPoint::willAttachRenderers):
+        (WebCore::InsertionPoint::willDetachRenderers):
+        * style/StyleResolveTree.cpp:
+        (WebCore::Style::isRendererReparented):
+        (WebCore::Style::previousSiblingRenderer):
+        (WebCore::Style::nextSiblingRenderer):
+        
+            From NodeRenderingContext::next/previousRenderer
+
+        (WebCore::Style::createTextRenderersForSiblingsAfterAttachIfNeeded):
+        
+            From Text::createTextRenderersForSiblingsAfterAttachIfNeeded()
+
+        (WebCore::Style::textRendererIsNeeded):
+        
+            From Text::textRendererIsNeeded
+
+        (WebCore::Style::createTextRendererIfNeeded):
+        
+            Combines code from Text::createTextRendererIfNeeded, NodeRenderingContext::createRendererForTextIfNeeded,
+            NodeRenderingContext constructor and text node relevant code NodeRenderingContext::shouldCreateRenderer.
+
+        (WebCore::Style::attachTextRenderer):
+        (WebCore::Style::detachTextRenderer):
+        
+            New functions of attaching text renderers. From Text::attach/detachText()
+
+        (WebCore::Style::updateTextRendererAfterContentChange):
+        
+            From Text::updateTextRenderer.
+
+        (WebCore::Style::attachShadowRoot):
+        (WebCore::Style::attachChildren):
+        (WebCore::Style::attachRenderTree):
+        (WebCore::Style::detachShadowRoot):
+        (WebCore::Style::detachChildren):
+        (WebCore::Style::updateTextStyle):
+        * style/StyleResolveTree.h:
+        * xml/parser/XMLDocumentParser.cpp:
+        (WebCore::XMLDocumentParser::exitText):
+        * xml/parser/XMLDocumentParserLibxml2.cpp:
+        (WebCore::XMLDocumentParser::cdataBlock):
+
+2013-08-28  Antti Koivisto  <[email protected]>
+
         Make descendant iterators always require ContainerNode root
         https://bugs.webkit.org/show_bug.cgi?id=120393
 

Modified: trunk/Source/WebCore/dom/CharacterData.cpp (154737 => 154738)


--- trunk/Source/WebCore/dom/CharacterData.cpp	2013-08-28 12:52:18 UTC (rev 154737)
+++ trunk/Source/WebCore/dom/CharacterData.cpp	2013-08-28 13:12:52 UTC (rev 154738)
@@ -91,7 +91,7 @@
 
     ASSERT(!renderer() || isTextNode());
     if (isTextNode())
-        toText(this)->updateTextRenderer(oldLength, 0);
+        Style::updateTextRendererAfterContentChange(*toText(this), oldLength, 0);
 
     document()->incDOMTreeVersion();
     // We don't call dispatchModifiedEvent here because we don't want the
@@ -191,7 +191,7 @@
 
     ASSERT(!renderer() || isTextNode());
     if (isTextNode())
-        toText(this)->updateTextRenderer(offsetOfReplacedData, oldLength);
+        Style::updateTextRendererAfterContentChange(*toText(this), offsetOfReplacedData, oldLength);
 
     if (document()->frame())
         document()->frame()->selection().textWasReplaced(this, offsetOfReplacedData, oldLength, newLength);

Modified: trunk/Source/WebCore/dom/ContainerNode.cpp (154737 => 154738)


--- trunk/Source/WebCore/dom/ContainerNode.cpp	2013-08-28 12:52:18 UTC (rev 154737)
+++ trunk/Source/WebCore/dom/ContainerNode.cpp	2013-08-28 13:12:52 UTC (rev 154738)
@@ -110,7 +110,7 @@
     if (child->isElementNode())
         Style::attachRenderTree(toElement(child));
     else if (child->isTextNode())
-        toText(child)->attachText();
+        Style::attachTextRenderer(*toText(child));
 }
 
 static inline void detachChild(Node* child)
@@ -118,7 +118,7 @@
     if (child->isElementNode())
         Style::detachRenderTree(toElement(child));
     else if (child->isTextNode())
-        toText(child)->detachText();
+        Style::detachTextRenderer(*toText(child));
 }
 
 void ContainerNode::takeAllChildrenFrom(ContainerNode* oldParent)

Modified: trunk/Source/WebCore/dom/NodeRenderingContext.cpp (154737 => 154738)


--- trunk/Source/WebCore/dom/NodeRenderingContext.cpp	2013-08-28 12:52:18 UTC (rev 154737)
+++ trunk/Source/WebCore/dom/NodeRenderingContext.cpp	2013-08-28 13:12:52 UTC (rev 154738)
@@ -285,45 +285,6 @@
     parentRenderer->addChild(newRenderer, nextRenderer);
 }
 
-void NodeRenderingContext::createRendererForTextIfNeeded()
-{
-    ASSERT(!m_node->renderer());
-
-    Text* textNode = toText(m_node);
-
-    if (!shouldCreateRenderer())
-        return;
-
-    RenderObject* parentRenderer = this->parentRenderer();
-    ASSERT(parentRenderer);
-    Document* document = textNode->document();
-
-    if (resetStyleInheritance())
-        m_style = document->ensureStyleResolver().defaultStyleForElement();
-    else
-        m_style = parentRenderer->style();
-
-    if (!textNode->textRendererIsNeeded(*this))
-        return;
-    RenderText* newRenderer = textNode->createTextRenderer(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());
-
-    RenderObject* nextRenderer = this->nextRenderer();
-    textNode->setRenderer(newRenderer);
-    // Parent takes care of the animations, no need to call setAnimatableStyle.
-    newRenderer->setStyle(m_style.release());
-    parentRenderer->addChild(newRenderer, nextRenderer);
-}
-
 bool NodeRenderingContext::resetStyleInheritance() const
 {
     ContainerNode* parent = m_node->parentNode();

Modified: trunk/Source/WebCore/dom/NodeRenderingContext.h (154737 => 154738)


--- trunk/Source/WebCore/dom/NodeRenderingContext.h	2013-08-28 12:52:18 UTC (rev 154737)
+++ trunk/Source/WebCore/dom/NodeRenderingContext.h	2013-08-28 13:12:52 UTC (rev 154738)
@@ -50,7 +50,6 @@
     NodeRenderingContext(Node*, const Style::AttachContext&);
     ~NodeRenderingContext();
 
-    void createRendererForTextIfNeeded();
     void createRendererForElementIfNeeded();
 
     Node* node() const;

Modified: trunk/Source/WebCore/dom/Text.cpp (154737 => 154738)


--- trunk/Source/WebCore/dom/Text.cpp	2013-08-28 12:52:18 UTC (rev 154737)
+++ trunk/Source/WebCore/dom/Text.cpp	2013-08-28 13:12:52 UTC (rev 154738)
@@ -58,8 +58,7 @@
 
 Text::~Text()
 {
-    if (renderer())
-        detachText();
+    ASSERT(!renderer());
 }
 
 PassRefPtr<Text> Text::splitText(unsigned offset, ExceptionCode& ec)
@@ -178,53 +177,7 @@
     return create(document(), data());
 }
 
-bool Text::textRendererIsNeeded(const NodeRenderingContext& context)
-{
-    if (isEditingText())
-        return true;
 
-    if (!length())
-        return false;
-
-    if (context.style()->display() == NONE)
-        return false;
-
-    bool _onlyWS_ = containsOnlyWhitespace();
-    if (!onlyWS)
-        return true;
-
-    RenderObject* parent = context.parentRenderer();
-    if (parent->isTable() || parent->isTableRow() || parent->isTableSection() || parent->isRenderTableCol() || parent->isFrameSet())
-        return false;
-    
-    if (context.style()->preserveNewline()) // pre/pre-wrap/pre-line always make renderers.
-        return true;
-    
-    RenderObject* prev = context.previousRenderer();
-    if (prev && prev->isBR()) // <span><br/> <br/></span>
-        return false;
-        
-    if (parent->isRenderInline()) {
-        // <span><div/> <div/></span>
-        if (prev && !prev->isInline())
-            return false;
-    } else {
-        if (parent->isRenderBlock() && !parent->childrenInline() && (!prev || !prev->isInline()))
-            return false;
-        
-        RenderObject* first = parent->firstChild();
-        while (first && first->isFloatingOrOutOfFlowPositioned())
-            first = first->nextSibling();
-        if (!first || context.nextRenderer() == first) {
-            // Whitespace at the start of a block just goes away.  Don't even
-            // make a render object for this text.
-            return false;
-        }
-    }
-    
-    return true;
-}
-
 #if ENABLE(SVG)
 static bool isSVGShadowText(Text* text)
 {
@@ -239,11 +192,6 @@
 }
 #endif
 
-void Text::createTextRendererIfNeeded()
-{
-    NodeRenderingContext(this).createRendererForTextIfNeeded();
-}
-
 RenderText* Text::createTextRenderer(RenderArena* arena, RenderStyle* style)
 {
 #if ENABLE(SVG)
@@ -256,70 +204,6 @@
     return new (arena) RenderText(this, dataImpl());
 }
 
-void Text::createTextRenderersForSiblingsAfterAttachIfNeeded(Node* sibling)
-{
-    ASSERT(sibling->previousSibling());
-    ASSERT(sibling->previousSibling()->renderer());
-    ASSERT(!sibling->renderer());
-    ASSERT(sibling->attached());
-    // If this node got a renderer it may be the previousRenderer() of sibling text nodes and thus affect the
-    // result of Text::textRendererIsNeeded() for those nodes.
-    for (; sibling; sibling = sibling->nextSibling()) {
-        if (sibling->renderer())
-            break;
-        if (!sibling->attached())
-            break; // Assume this means none of the following siblings are attached.
-        if (!sibling->isTextNode())
-            continue;
-        ASSERT(!sibling->renderer());
-        toText(sibling)->createTextRendererIfNeeded();
-        // If we again decided not to create a renderer for next, we can bail out the loop,
-        // because it won't affect the result of Text::textRendererIsNeeded() for the rest
-        // of sibling nodes.
-        if (!sibling->renderer())
-            break;
-    }
-}
-
-void Text::attachText()
-{
-    createTextRendererIfNeeded();
-
-    Node* sibling = nextSibling();
-    if (renderer() && sibling && !sibling->renderer() && sibling->attached())
-        createTextRenderersForSiblingsAfterAttachIfNeeded(sibling);
-
-    setAttached(true);
-    clearNeedsStyleRecalc();
-}
-
-void Text::detachText()
-{
-    if (renderer())
-        renderer()->destroyAndCleanupAnonymousWrappers();
-    setRenderer(0);
-    setAttached(false);
-}
-
-void Text::updateTextRenderer(unsigned offsetOfReplacedData, unsigned lengthOfReplacedData)
-{
-    if (!attached())
-        return;
-    RenderText* textRenderer = toRenderText(renderer());
-    if (!textRenderer) {
-        attachText();
-        return;
-    }
-    NodeRenderingContext renderingContext(this, textRenderer->style());
-    if (!textRendererIsNeeded(renderingContext)) {
-        if (attached())
-            detachText();
-        attachText();
-        return;
-    }
-    textRenderer->setTextWithOffset(dataImpl(), offsetOfReplacedData, lengthOfReplacedData);
-}
-
 bool Text::childTypeAllowed(NodeType) const
 {
     return false;

Modified: trunk/Source/WebCore/dom/Text.h (154737 => 154738)


--- trunk/Source/WebCore/dom/Text.h	2013-08-28 12:52:18 UTC (rev 154737)
+++ trunk/Source/WebCore/dom/Text.h	2013-08-28 13:12:52 UTC (rev 154738)
@@ -48,15 +48,7 @@
     String wholeText() const;
     PassRefPtr<Text> replaceWholeText(const String&, ExceptionCode&);
     
-    void createTextRendererIfNeeded();
-    bool textRendererIsNeeded(const NodeRenderingContext&);
     RenderText* createTextRenderer(RenderArena*, RenderStyle*);
-    void updateTextRenderer(unsigned offsetOfReplacedData, unsigned lengthOfReplacedData);
-
-    void attachText();
-    void detachText();
-
-    static void createTextRenderersForSiblingsAfterAttachIfNeeded(Node*);
     
     virtual bool canContainRangeEndPoint() const OVERRIDE FINAL { return true; }
 

Modified: trunk/Source/WebCore/html/HTMLViewSourceDocument.cpp (154737 => 154738)


--- trunk/Source/WebCore/html/HTMLViewSourceDocument.cpp	2013-08-28 12:52:18 UTC (rev 154737)
+++ trunk/Source/WebCore/html/HTMLViewSourceDocument.cpp	2013-08-28 13:12:52 UTC (rev 154738)
@@ -253,7 +253,7 @@
         }
         RefPtr<Text> text = Text::create(this, substring);
         m_current->parserAppendChild(text);
-        text->attachText();
+        Style::attachTextRenderer(*text);
         if (i < size - 1)
             finishLine();
     }

Modified: trunk/Source/WebCore/html/parser/HTMLConstructionSite.cpp (154737 => 154738)


--- trunk/Source/WebCore/html/parser/HTMLConstructionSite.cpp	2013-08-28 12:52:18 UTC (rev 154737)
+++ trunk/Source/WebCore/html/parser/HTMLConstructionSite.cpp	2013-08-28 13:12:52 UTC (rev 154738)
@@ -103,7 +103,7 @@
         if (task.child->isElementNode())
             Style::attachRenderTree(toElement(task.child.get()));
         else if (task.child->isTextNode())
-            toText(task.child.get())->attachText();
+            Style::attachTextRenderer(*toText(task.child.get()));
     }
 
     task.child->beginParsingChildren();

Modified: trunk/Source/WebCore/html/shadow/InsertionPoint.cpp (154737 => 154738)


--- trunk/Source/WebCore/html/shadow/InsertionPoint.cpp	2013-08-28 12:52:18 UTC (rev 154737)
+++ trunk/Source/WebCore/html/shadow/InsertionPoint.cpp	2013-08-28 13:12:52 UTC (rev 154738)
@@ -60,7 +60,7 @@
         if (current->attached())
             continue;
         if (current->isTextNode()) {
-            toText(current)->attachText();
+            Style::attachTextRenderer(*toText(current));
             continue;
         }
         if (current->isElementNode())
@@ -75,7 +75,7 @@
 
     for (Node* current = firstDistributed(); current; current = nextDistributedTo(current)) {
         if (current->isTextNode()) {
-            toText(current)->detachText();
+            Style::detachTextRenderer(*toText(current));
             continue;
         }
         if (current->isElementNode())

Modified: trunk/Source/WebCore/style/StyleResolveTree.cpp (154737 => 154738)


--- trunk/Source/WebCore/style/StyleResolveTree.cpp	2013-08-28 12:52:18 UTC (rev 154737)
+++ trunk/Source/WebCore/style/StyleResolveTree.cpp	2013-08-28 13:12:52 UTC (rev 154738)
@@ -109,6 +109,185 @@
     NodeRenderingContext(element, context).createRendererForElementIfNeeded();
 }
 
+static bool isRendererReparented(const RenderObject* renderer)
+{
+    if (!renderer->node()->isElementNode())
+        return false;
+    if (renderer->style() && !renderer->style()->flowThread().isEmpty())
+        return true;
+    return false;
+}
+
+static RenderObject* previousSiblingRenderer(const Text& textNode)
+{
+    if (textNode.renderer())
+        return textNode.renderer()->previousSibling();
+    for (Node* sibling = NodeRenderingTraversal::previousSibling(&textNode); sibling; sibling = NodeRenderingTraversal::previousSibling(sibling)) {
+        RenderObject* renderer = sibling->renderer();
+        if (renderer && !isRendererReparented(renderer))
+            return renderer;
+    }
+    return 0;
+}
+
+static RenderObject* nextSiblingRenderer(const Text& textNode)
+{
+    if (textNode.renderer())
+        return textNode.renderer()->nextSibling();
+    for (Node* sibling = NodeRenderingTraversal::nextSibling(&textNode); sibling; sibling = NodeRenderingTraversal::nextSibling(sibling)) {
+        RenderObject* renderer = sibling->renderer();
+        if (renderer && !isRendererReparented(renderer))
+            return renderer;
+    }
+    return 0;
+}
+
+static void createTextRenderersForSiblingsAfterAttachIfNeeded(Node* sibling)
+{
+    ASSERT(sibling->previousSibling());
+    ASSERT(sibling->previousSibling()->renderer());
+    ASSERT(!sibling->renderer());
+    ASSERT(sibling->attached());
+    // If this node got a renderer it may be the previousRenderer() of sibling text nodes and thus affect the
+    // result of Text::textRendererIsNeeded() for those nodes.
+    for (; sibling; sibling = sibling->nextSibling()) {
+        if (sibling->renderer())
+            break;
+        if (!sibling->attached())
+            break; // Assume this means none of the following siblings are attached.
+        if (!sibling->isTextNode())
+            continue;
+        ASSERT(!sibling->renderer());
+        attachTextRenderer(*toText(sibling));
+        // If we again decided not to create a renderer for next, we can bail out the loop,
+        // because it won't affect the result of Text::textRendererIsNeeded() for the rest
+        // of sibling nodes.
+        if (!sibling->renderer())
+            break;
+    }
+}
+
+static bool textRendererIsNeeded(const Text& textNode, const RenderObject& parentRenderer, const RenderStyle& style)
+{
+    if (textNode.isEditingText())
+        return true;
+    if (!textNode.length())
+        return false;
+    if (style.display() == NONE)
+        return false;
+    if (!textNode.containsOnlyWhitespace())
+        return true;
+    // This text node has nothing but white space. We may still need a renderer in some cases.
+    if (parentRenderer.isTable() || parentRenderer.isTableRow() || parentRenderer.isTableSection() || parentRenderer.isRenderTableCol() || parentRenderer.isFrameSet())
+        return false;
+    if (style.preserveNewline()) // pre/pre-wrap/pre-line always make renderers.
+        return true;
+
+    RenderObject* previousRenderer = previousSiblingRenderer(textNode);
+    if (previousRenderer && previousRenderer->isBR()) // <span><br/> <br/></span>
+        return false;
+        
+    if (parentRenderer.isRenderInline()) {
+        // <span><div/> <div/></span>
+        if (previousRenderer && !previousRenderer->isInline())
+            return false;
+    } else {
+        if (parentRenderer.isRenderBlock() && !parentRenderer.childrenInline() && (!previousRenderer || !previousRenderer->isInline()))
+            return false;
+        
+        RenderObject* first = parentRenderer.firstChild();
+        while (first && first->isFloatingOrOutOfFlowPositioned())
+            first = first->nextSibling();
+        RenderObject* nextRenderer = nextSiblingRenderer(textNode);
+        if (!first || nextRenderer == first) {
+            // Whitespace at the start of a block just goes away. Don't even make a render object for this text.
+            return false;
+        }
+    }
+    return true;
+}
+
+static void createTextRendererIfNeeded(Text& textNode)
+{
+    ASSERT(!textNode.renderer());
+
+    ContainerNode* renderingParentNode = NodeRenderingTraversal::parent(&textNode);
+    if (!renderingParentNode)
+        return;
+    RenderObject* parentRenderer = renderingParentNode->renderer();
+    if (!parentRenderer || !parentRenderer->canHaveChildren())
+        return;
+    if (!renderingParentNode->childShouldCreateRenderer(&textNode))
+        return;
+
+    Document* document = textNode.document();
+    RefPtr<RenderStyle> style;
+    bool resetStyleInheritance = renderingParentNode->isShadowRoot() && toShadowRoot(renderingParentNode)->resetStyleInheritance();
+    if (resetStyleInheritance)
+        style = document->ensureStyleResolver().defaultStyleForElement();
+    else
+        style = parentRenderer->style();
+
+    if (!textRendererIsNeeded(textNode, *parentRenderer, *style))
+        return;
+    RenderText* newRenderer = textNode.createTextRenderer(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());
+
+    RenderObject* nextRenderer = nextSiblingRenderer(textNode);
+    textNode.setRenderer(newRenderer);
+    // Parent takes care of the animations, no need to call setAnimatableStyle.
+    newRenderer->setStyle(style.release());
+    parentRenderer->addChild(newRenderer, nextRenderer);
+
+    Node* sibling = textNode.nextSibling();
+    if (sibling && !sibling->renderer() && sibling->attached())
+        createTextRenderersForSiblingsAfterAttachIfNeeded(sibling);
+}
+
+void attachTextRenderer(Text& textNode)
+{
+    createTextRendererIfNeeded(textNode);
+
+    textNode.setAttached(true);
+    textNode.clearNeedsStyleRecalc();
+}
+
+void detachTextRenderer(Text& textNode)
+{
+    if (textNode.renderer())
+        textNode.renderer()->destroyAndCleanupAnonymousWrappers();
+    textNode.setRenderer(0);
+    textNode.setAttached(false);
+}
+
+void updateTextRendererAfterContentChange(Text& textNode, unsigned offsetOfReplacedData, unsigned lengthOfReplacedData)
+{
+    if (!textNode.attached())
+        return;
+    RenderText* textRenderer = toRenderText(textNode.renderer());
+    if (!textRenderer) {
+        attachTextRenderer(textNode);
+        return;
+    }
+    RenderObject* parentRenderer = NodeRenderingTraversal::parent(&textNode)->renderer();
+    if (!textRendererIsNeeded(textNode, *parentRenderer, *textRenderer->style())) {
+        detachTextRenderer(textNode);
+        attachTextRenderer(textNode);
+        return;
+    }
+    textRenderer->setTextWithOffset(textNode.dataImpl(), offsetOfReplacedData, lengthOfReplacedData);
+}
+
+
 static void attachShadowRoot(ShadowRoot* shadowRoot, const AttachContext& context)
 {
     if (shadowRoot->attached())
@@ -120,7 +299,7 @@
     childrenContext.resolvedStyle = 0;
     for (Node* child = shadowRoot->firstChild(); child; child = child->nextSibling()) {
         if (child->isTextNode()) {
-            toText(child)->attachText();
+            attachTextRenderer(*toText(child));
             continue;
         }
         if (child->isElementNode())
@@ -155,7 +334,7 @@
         if (child->attached())
             continue;
         if (child->isTextNode()) {
-            toText(child)->attachText();
+            attachTextRenderer(*toText(child));
             continue;
         }
         if (child->isElementNode())
@@ -191,7 +370,7 @@
 
     Node* sibling = current->nextSibling();
     if (current->renderer() && sibling && !sibling->renderer() && sibling->attached())
-        Text::createTextRenderersForSiblingsAfterAttachIfNeeded(sibling);
+        createTextRenderersForSiblingsAfterAttachIfNeeded(sibling);
 
     current->setAttached(true);
     current->clearNeedsStyleRecalc();
@@ -217,7 +396,7 @@
     childrenContext.resolvedStyle = 0;
     for (Node* child = shadowRoot->firstChild(); child; child = child->nextSibling()) {
         if (child->isTextNode()) {
-            toText(child)->detachText();
+            Style::detachTextRenderer(*toText(child));
             continue;
         }
         if (child->isElementNode())
@@ -234,7 +413,7 @@
 
     for (Node* child = current->firstChild(); child; child = child->nextSibling()) {
         if (child->isTextNode()) {
-            toText(child)->detachText();
+            Style::detachTextRenderer(*toText(child));
             continue;
         }
         if (child->isElementNode())
@@ -373,7 +552,7 @@
     if (renderer)
         renderer->setText(text->dataImpl());
     else
-        text->attachText();
+        attachTextRenderer(*text);
     text->clearNeedsStyleRecalc();
 }
 

Modified: trunk/Source/WebCore/style/StyleResolveTree.h (154737 => 154738)


--- trunk/Source/WebCore/style/StyleResolveTree.h	2013-08-28 12:52:18 UTC (rev 154737)
+++ trunk/Source/WebCore/style/StyleResolveTree.h	2013-08-28 13:12:52 UTC (rev 154738)
@@ -32,6 +32,7 @@
 class Element;
 class RenderStyle;
 class Settings;
+class Text;
 
 namespace Style {
 
@@ -50,6 +51,10 @@
 void detachRenderTree(Element*, const AttachContext& = AttachContext());
 void reattachRenderTree(Element*, const AttachContext& = AttachContext());
 
+void attachTextRenderer(Text&);
+void detachTextRenderer(Text&);
+void updateTextRendererAfterContentChange(Text&, unsigned offsetOfReplacedData, unsigned lengthOfReplacedData);
+
 Change determineChange(const RenderStyle*, const RenderStyle*, Settings*);
 
 }

Modified: trunk/Source/WebCore/xml/parser/XMLDocumentParser.cpp (154737 => 154738)


--- trunk/Source/WebCore/xml/parser/XMLDocumentParser.cpp	2013-08-28 12:52:18 UTC (rev 154737)
+++ trunk/Source/WebCore/xml/parser/XMLDocumentParser.cpp	2013-08-28 13:12:52 UTC (rev 154738)
@@ -172,9 +172,8 @@
     m_bufferedText.swap(empty);
 #endif
 
-    if (m_view && m_leafTextNode->parentNode() && m_leafTextNode->parentNode()->attached()
-        && !m_leafTextNode->attached())
-        m_leafTextNode->attachText();
+    if (m_view && m_leafTextNode->parentNode() && m_leafTextNode->parentNode()->attached() && !m_leafTextNode->attached())
+        Style::attachTextRenderer(*m_leafTextNode);
 
     m_leafTextNode = 0;
 }

Modified: trunk/Source/WebCore/xml/parser/XMLDocumentParserLibxml2.cpp (154737 => 154738)


--- trunk/Source/WebCore/xml/parser/XMLDocumentParserLibxml2.cpp	2013-08-28 12:52:18 UTC (rev 154737)
+++ trunk/Source/WebCore/xml/parser/XMLDocumentParserLibxml2.cpp	2013-08-28 13:12:52 UTC (rev 154738)
@@ -1037,7 +1037,7 @@
     RefPtr<CDATASection> newNode = CDATASection::create(m_currentNode->document(), toString(s, len));
     m_currentNode->parserAppendChild(newNode.get());
     if (m_view && !newNode->attached())
-        newNode->attachText();
+        Style::attachTextRenderer(*newNode);
 }
 
 void XMLDocumentParser::comment(const xmlChar* s)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to