[RenderTreeBuilder] Move RenderRubyAsInline::addChild mutation to a RenderTreeBuilder
authorzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 Dec 2017 23:03:28 +0000 (23:03 +0000)
committerzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 Dec 2017 23:03:28 +0000 (23:03 +0000)
https://bugs.webkit.org/show_bug.cgi?id=181101
<rdar://problem/36184788>

Reviewed by Antti Koivisto.

* rendering/RenderRuby.cpp:
(WebCore::isRubyBeforeBlock): Deleted.
(WebCore::isRubyAfterBlock): Deleted.
(WebCore::rubyBeforeBlock): Deleted.
(WebCore::rubyAfterBlock): Deleted.
(WebCore::createAnonymousRubyInlineBlock): Deleted.
(WebCore::lastRubyRun): Deleted.
(WebCore::RenderRubyAsInline::addChild): Deleted.
* rendering/RenderRuby.h:
* rendering/updating/RenderTreeBuilder.cpp:
(WebCore::RenderTreeBuilder::insertChild):
* rendering/updating/RenderTreeBuilderRuby.cpp:
(WebCore::RenderTreeBuilder::Ruby::findOrCreateParentForChild):
* rendering/updating/RenderTreeBuilderRuby.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@226246 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderRuby.cpp
Source/WebCore/rendering/RenderRuby.h
Source/WebCore/rendering/updating/RenderTreeBuilder.cpp
Source/WebCore/rendering/updating/RenderTreeBuilderRuby.cpp
Source/WebCore/rendering/updating/RenderTreeBuilderRuby.h

index 583d2e5..0eaf71c 100644 (file)
@@ -1,3 +1,26 @@
+2017-12-21  Zalan Bujtas  <zalan@apple.com>
+
+        [RenderTreeBuilder] Move RenderRubyAsInline::addChild mutation to a RenderTreeBuilder
+        https://bugs.webkit.org/show_bug.cgi?id=181101
+        <rdar://problem/36184788>
+
+        Reviewed by Antti Koivisto.
+
+        * rendering/RenderRuby.cpp:
+        (WebCore::isRubyBeforeBlock): Deleted.
+        (WebCore::isRubyAfterBlock): Deleted.
+        (WebCore::rubyBeforeBlock): Deleted.
+        (WebCore::rubyAfterBlock): Deleted.
+        (WebCore::createAnonymousRubyInlineBlock): Deleted.
+        (WebCore::lastRubyRun): Deleted.
+        (WebCore::RenderRubyAsInline::addChild): Deleted.
+        * rendering/RenderRuby.h:
+        * rendering/updating/RenderTreeBuilder.cpp:
+        (WebCore::RenderTreeBuilder::insertChild):
+        * rendering/updating/RenderTreeBuilderRuby.cpp:
+        (WebCore::RenderTreeBuilder::Ruby::findOrCreateParentForChild):
+        * rendering/updating/RenderTreeBuilderRuby.h:
+
 2017-12-21  Jiewen Tan  <jiewen_tan@apple.com>
 
         Update Credential Management API for WebAuthentication
index 2e29bc7..7f57d97 100644 (file)
@@ -61,22 +61,6 @@ static inline bool isAnonymousRubyInlineBlock(const RenderObject* object)
         && !is<RenderRubyRun>(*object);
 }
 
-static inline bool isRubyBeforeBlock(const RenderObject* object)
-{
-    return isAnonymousRubyInlineBlock(object)
-        && !object->previousSibling()
-        && downcast<RenderBlock>(*object).firstChild()
-        && downcast<RenderBlock>(*object).firstChild()->style().styleType() == BEFORE;
-}
-
-static inline bool isRubyAfterBlock(const RenderObject* object)
-{
-    return isAnonymousRubyInlineBlock(object)
-        && !object->nextSibling()
-        && downcast<RenderBlock>(*object).firstChild()
-        && downcast<RenderBlock>(*object).firstChild()->style().styleType() == AFTER;
-}
-
 #ifndef ASSERT_DISABLED
 static inline bool isRubyChildForNormalRemoval(const RenderObject& object)
 {
@@ -89,37 +73,6 @@ static inline bool isRubyChildForNormalRemoval(const RenderObject& object)
 }
 #endif
 
-static inline RenderBlock* rubyBeforeBlock(const RenderElement* ruby)
-{
-    RenderObject* child = ruby->firstChild();
-    return isRubyBeforeBlock(child) ? downcast<RenderBlock>(child) : nullptr;
-}
-
-static inline RenderBlock* rubyAfterBlock(const RenderElement* ruby)
-{
-    RenderObject* child = ruby->lastChild();
-    return isRubyAfterBlock(child) ? downcast<RenderBlock>(child) : nullptr;
-}
-
-static auto createAnonymousRubyInlineBlock(RenderObject& ruby)
-{
-    auto newBlock = createRenderer<RenderBlockFlow>(ruby.document(), RenderStyle::createAnonymousStyleWithDisplay(ruby.style(), INLINE_BLOCK));
-    newBlock->initializeStyle();
-    return newBlock;
-}
-
-static RenderRubyRun* lastRubyRun(const RenderElement* ruby)
-{
-    RenderObject* child = ruby->lastChild();
-    if (child && !is<RenderRubyRun>(*child))
-        child = child->previousSibling();
-    if (!is<RenderRubyRun>(child)) {
-        ASSERT(!child || child->isBeforeContent() || child == rubyBeforeBlock(ruby));
-        return nullptr;
-    }
-    return downcast<RenderRubyRun>(child);
-}
-
 static inline RenderRubyRun& findRubyRunParent(RenderObject& child)
 {
     return *lineageOfType<RenderRubyRun>(child).first();
@@ -140,74 +93,6 @@ void RenderRubyAsInline::styleDidChange(StyleDifference diff, const RenderStyle*
     propagateStyleToAnonymousChildren(PropagateToAllChildren);
 }
 
-void RenderRubyAsInline::addChild(RenderTreeBuilder& builder, RenderPtr<RenderObject> child, RenderObject* beforeChild)
-{
-    // Insert :before and :after content before/after the RenderRubyRun(s)
-    if (child->isBeforeContent()) {
-        if (child->isInline()) {
-            // Add generated inline content normally
-            RenderInline::addChild(builder, WTFMove(child), firstChild());
-        } else {
-            // Wrap non-inline content with an anonymous inline-block.
-            RenderBlock* beforeBlock = rubyBeforeBlock(this);
-            if (!beforeBlock) {
-                auto newBlock = createAnonymousRubyInlineBlock(*this);
-                beforeBlock = newBlock.get();
-                RenderInline::addChild(builder, WTFMove(newBlock), firstChild());
-            }
-            builder.insertChild(*beforeBlock, WTFMove(child));
-        }
-        return;
-    }
-    if (child->isAfterContent()) {
-        if (child->isInline()) {
-            // Add generated inline content normally
-            RenderInline::addChild(builder, WTFMove(child));
-        } else {
-            // Wrap non-inline content with an anonymous inline-block.
-            RenderBlock* afterBlock = rubyAfterBlock(this);
-            if (!afterBlock) {
-                auto newBlock = createAnonymousRubyInlineBlock(*this);
-                afterBlock = newBlock.get();
-                RenderInline::addChild(builder, WTFMove(newBlock));
-            }
-            builder.insertChild(*afterBlock, WTFMove(child));
-        }
-        return;
-    }
-
-    // If the child is a ruby run, just add it normally.
-    if (child->isRubyRun()) {
-        RenderInline::addChild(builder, WTFMove(child), beforeChild);
-        return;
-    }
-
-    if (beforeChild && !isAfterContent(beforeChild)) {
-        // insert child into run
-        ASSERT(!beforeChild->isRubyRun());
-        RenderElement* run = beforeChild->parent();
-        while (run && !run->isRubyRun())
-            run = run->parent();
-        if (run) {
-            builder.insertChild(*run, WTFMove(child), beforeChild);
-            return;
-        }
-        ASSERT_NOT_REACHED(); // beforeChild should always have a run as parent!
-        // Emergency fallback: fall through and just append.
-    }
-
-    // If the new child would be appended, try to add the child to the previous run
-    // if possible, or create a new run otherwise.
-    // (The RenderRubyRun object will handle the details)
-    RenderRubyRun* lastRun = lastRubyRun(this);
-    if (!lastRun || lastRun->hasRubyText()) {
-        auto newRun = RenderRubyRun::staticCreateRubyRun(this);
-        lastRun = newRun.get();
-        RenderInline::addChild(builder, WTFMove(newRun), beforeChild);
-    }
-    builder.insertChild(*lastRun, WTFMove(child));
-}
-
 RenderPtr<RenderObject> RenderRubyAsInline::takeChild(RenderObject& child)
 {
     // If the child's parent is *this (must be a ruby run or generated content or anonymous block),
index 6acf7fe..cbfc23b 100644 (file)
@@ -56,7 +56,6 @@ public:
     RenderRubyAsInline(Element&, RenderStyle&&);
     virtual ~RenderRubyAsInline();
 
-    void addChild(RenderTreeBuilder&, RenderPtr<RenderObject> child, RenderObject* beforeChild = 0) override;
     RenderPtr<RenderObject> takeChild(RenderObject& child) override;
 
 protected:
index efe070a..a2f941c 100644 (file)
@@ -97,6 +97,11 @@ void RenderTreeBuilder::insertChild(RenderElement& parent, RenderPtr<RenderObjec
         return;
     }
 
+    if (is<RenderRubyAsInline>(parent)) {
+        insertRecursiveIfNeeded(rubyBuilder().findOrCreateParentForChild(downcast<RenderRubyAsInline>(parent), *child, beforeChild));
+        return;
+    }
+
     if (is<RenderRubyRun>(parent)) {
         rubyBuilder().insertChild(downcast<RenderRubyRun>(parent), WTFMove(child), beforeChild);
         return;
index f9866cd..05bcd97 100644 (file)
@@ -218,6 +218,66 @@ RenderElement& RenderTreeBuilder::Ruby::findOrCreateParentForChild(RenderRubyAsB
     return *lastRun;
 }
 
+RenderElement& RenderTreeBuilder::Ruby::findOrCreateParentForChild(RenderRubyAsInline& parent, const RenderObject& child, RenderObject*& beforeChild)
+{
+    // Insert :before and :after content before/after the RenderRubyRun(s)
+    if (child.isBeforeContent()) {
+        // Add generated inline content normally
+        if (child.isInline())
+            return parent;
+        // Wrap non-inline content with an anonymous inline-block.
+        auto* beforeBlock = rubyBeforeBlock(&parent);
+        if (!beforeBlock) {
+            auto newBlock = createAnonymousRubyInlineBlock(parent);
+            beforeBlock = newBlock.get();
+            parent.RenderInline::addChild(m_builder, WTFMove(newBlock), parent.firstChild());
+        }
+        beforeChild = nullptr;
+        return *beforeBlock;
+    }
+
+    if (child.isAfterContent()) {
+        // Add generated inline content normally
+        if (child.isInline())
+            return parent;
+        // Wrap non-inline content with an anonymous inline-block.
+        auto* afterBlock = rubyAfterBlock(&parent);
+        if (!afterBlock) {
+            auto newBlock = createAnonymousRubyInlineBlock(parent);
+            afterBlock = newBlock.get();
+            parent.RenderInline::addChild(m_builder, WTFMove(newBlock));
+        }
+        beforeChild = nullptr;
+        return *afterBlock;
+    }
+
+    // If the child is a ruby run, just add it normally.
+    if (child.isRubyRun())
+        return parent;
+
+    if (beforeChild && !parent.isAfterContent(beforeChild)) {
+        // insert child into run
+        ASSERT(!beforeChild->isRubyRun());
+        auto* run = beforeChild->parent();
+        while (run && !run->isRubyRun())
+            run = run->parent();
+        if (run)
+            return *run;
+        ASSERT_NOT_REACHED(); // beforeChild should always have a run as parent!
+        // Emergency fallback: fall through and just append.
+    }
 
+    // If the new child would be appended, try to add the child to the previous run
+    // if possible, or create a new run otherwise.
+    // (The RenderRubyRun object will handle the details)
+    auto* lastRun = lastRubyRun(&parent);
+    if (!lastRun || lastRun->hasRubyText()) {
+        auto newRun = RenderRubyRun::staticCreateRubyRun(&parent);
+        lastRun = newRun.get();
+        parent.RenderInline::addChild(m_builder, WTFMove(newRun), beforeChild);
+    }
+    beforeChild = nullptr;
+    return *lastRun;
 }
 
+}
index d9eed9b..aaa6887 100644 (file)
@@ -32,6 +32,7 @@ namespace WebCore {
 class RenderElement;
 class RenderObject;
 class RenderRubyAsBlock;
+class RenderRubyAsInline;
 class RenderRubyRun;
 class RenderTreeBuilder;
 
@@ -41,6 +42,7 @@ public:
 
     void insertChild(RenderRubyRun& parent, RenderPtr<RenderObject> child, RenderObject* beforeChild);
     RenderElement& findOrCreateParentForChild(RenderRubyAsBlock& parent, const RenderObject& child, RenderObject*& beforeChild);
+    RenderElement& findOrCreateParentForChild(RenderRubyAsInline& parent, const RenderObject& child, RenderObject*& beforeChild);
 
 private:
     RenderTreeBuilder& m_builder;