Title: [226520] trunk/Source/WebCore
Revision
226520
Author
[email protected]
Date
2018-01-08 10:38:31 -0800 (Mon, 08 Jan 2018)

Log Message

[RenderTreeBuilder] Move RenderInline addChild logic to RenderTreeBuilder
https://bugs.webkit.org/show_bug.cgi?id=181336
<rdar://problem/36324693>

Reviewed by Antti Koivisto.

This is about moving the code, no cleanup and/or normalization (unfortunately it also means
some temporary changes).

No change in functionality.

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* rendering/RenderInline.cpp:
(WebCore::RenderInline::addChild):
(WebCore::RenderInline::addChildIgnoringContinuation):
(WebCore::RenderInline::childBecameNonInline):
(WebCore::nextContinuation): Deleted.
(WebCore::RenderInline::continuationBefore): Deleted.
(WebCore::newChildIsInline): Deleted.
(WebCore::RenderInline::cloneAsContinuation const): Deleted.
(WebCore::RenderInline::splitInlines): Deleted.
(WebCore::RenderInline::splitFlow): Deleted.
(WebCore::canUseAsParentForContinuation): Deleted.
(WebCore::RenderInline::addChildToContinuation): Deleted.
* rendering/RenderInline.h:
* rendering/updating/RenderTreeBuilder.cpp:
(WebCore::RenderTreeBuilder::RenderTreeBuilder):
(WebCore::RenderTreeBuilder::insertChildToRenderInline):
(WebCore::RenderTreeBuilder::insertChildToRenderInlineIgnoringContinuation):
(WebCore::RenderTreeBuilder::splitFlow):
* rendering/updating/RenderTreeBuilder.h:
(WebCore::RenderTreeBuilder::inlineBuilder):
* rendering/updating/RenderTreeBuilderInline.cpp: Added.
(WebCore::canUseAsParentForContinuation):
(WebCore::nextContinuation):
(WebCore::continuationBefore):
(WebCore::cloneAsContinuation):
(WebCore::newChildIsInline):
(WebCore::inFlowPositionedInlineAncestor):
(WebCore::RenderTreeBuilder::Inline::Inline):
(WebCore::RenderTreeBuilder::Inline::insertChild):
(WebCore::RenderTreeBuilder::Inline::insertChildToContinuation):
(WebCore::RenderTreeBuilder::Inline::insertChildIgnoringContinuation):
(WebCore::RenderTreeBuilder::Inline::splitFlow):
(WebCore::RenderTreeBuilder::Inline::splitInlines):
* rendering/updating/RenderTreeBuilderInline.h: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (226519 => 226520)


--- trunk/Source/WebCore/ChangeLog	2018-01-08 18:37:37 UTC (rev 226519)
+++ trunk/Source/WebCore/ChangeLog	2018-01-08 18:38:31 UTC (rev 226520)
@@ -1,3 +1,53 @@
+2018-01-08  Zalan Bujtas <[email protected]>
+
+        [RenderTreeBuilder] Move RenderInline addChild logic to RenderTreeBuilder
+        https://bugs.webkit.org/show_bug.cgi?id=181336
+        <rdar://problem/36324693>
+
+        Reviewed by Antti Koivisto.
+
+        This is about moving the code, no cleanup and/or normalization (unfortunately it also means
+        some temporary changes).  
+
+        No change in functionality.
+
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * rendering/RenderInline.cpp:
+        (WebCore::RenderInline::addChild):
+        (WebCore::RenderInline::addChildIgnoringContinuation):
+        (WebCore::RenderInline::childBecameNonInline):
+        (WebCore::nextContinuation): Deleted.
+        (WebCore::RenderInline::continuationBefore): Deleted.
+        (WebCore::newChildIsInline): Deleted.
+        (WebCore::RenderInline::cloneAsContinuation const): Deleted.
+        (WebCore::RenderInline::splitInlines): Deleted.
+        (WebCore::RenderInline::splitFlow): Deleted.
+        (WebCore::canUseAsParentForContinuation): Deleted.
+        (WebCore::RenderInline::addChildToContinuation): Deleted.
+        * rendering/RenderInline.h:
+        * rendering/updating/RenderTreeBuilder.cpp:
+        (WebCore::RenderTreeBuilder::RenderTreeBuilder):
+        (WebCore::RenderTreeBuilder::insertChildToRenderInline):
+        (WebCore::RenderTreeBuilder::insertChildToRenderInlineIgnoringContinuation):
+        (WebCore::RenderTreeBuilder::splitFlow):
+        * rendering/updating/RenderTreeBuilder.h:
+        (WebCore::RenderTreeBuilder::inlineBuilder):
+        * rendering/updating/RenderTreeBuilderInline.cpp: Added.
+        (WebCore::canUseAsParentForContinuation):
+        (WebCore::nextContinuation):
+        (WebCore::continuationBefore):
+        (WebCore::cloneAsContinuation):
+        (WebCore::newChildIsInline):
+        (WebCore::inFlowPositionedInlineAncestor):
+        (WebCore::RenderTreeBuilder::Inline::Inline):
+        (WebCore::RenderTreeBuilder::Inline::insertChild):
+        (WebCore::RenderTreeBuilder::Inline::insertChildToContinuation):
+        (WebCore::RenderTreeBuilder::Inline::insertChildIgnoringContinuation):
+        (WebCore::RenderTreeBuilder::Inline::splitFlow):
+        (WebCore::RenderTreeBuilder::Inline::splitInlines):
+        * rendering/updating/RenderTreeBuilderInline.h: Added.
+
 2018-01-08  Zalan Bujtas  <[email protected]>
 
         [RenderTreeBuilder] Move RenderBlock addChild logic to RenderTreeBuilder

Modified: trunk/Source/WebCore/Sources.txt (226519 => 226520)


--- trunk/Source/WebCore/Sources.txt	2018-01-08 18:37:37 UTC (rev 226519)
+++ trunk/Source/WebCore/Sources.txt	2018-01-08 18:38:31 UTC (rev 226520)
@@ -1987,6 +1987,7 @@
 rendering/updating/RenderTreeBuilderBlock.cpp
 rendering/updating/RenderTreeBuilderFirstLetter.cpp
 rendering/updating/RenderTreeBuilderFormControls.cpp
+rendering/updating/RenderTreeBuilderInline.cpp
 rendering/updating/RenderTreeBuilderList.cpp
 rendering/updating/RenderTreeBuilderMultiColumn.cpp
 rendering/updating/RenderTreeBuilderRuby.cpp

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (226519 => 226520)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2018-01-08 18:37:37 UTC (rev 226519)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2018-01-08 18:38:31 UTC (rev 226520)
@@ -1025,9 +1025,7 @@
 		417DA6D913734E6E007C57FB /* Internals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 417DA4CF13734326007C57FB /* Internals.cpp */; };
 		417DA6DA13734E6E007C57FB /* Internals.h in Headers */ = {isa = PBXBuildFile; fileRef = 417DA4CE13734326007C57FB /* Internals.h */; };
 		417DA71D13735DFA007C57FB /* JSInternals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 417DA71B13735DFA007C57FB /* JSInternals.cpp */; };
-		427DA71D13735DFA007C57FB /* JSServiceWorkerInternals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 427DA71B13735DFA007C57FB /* JSServiceWorkerInternals.cpp */; };
 		417DA71E13735DFA007C57FB /* JSInternals.h in Headers */ = {isa = PBXBuildFile; fileRef = 417DA71C13735DFA007C57FB /* JSInternals.h */; };
-		427DA71E13735DFA007C57FB /* JSServiceWorkerInternals.h in Headers */ = {isa = PBXBuildFile; fileRef = 427DA71C13735DFA007C57FB /* JSServiceWorkerInternals.h */; };
 		417F0D821FFEE979008EF303 /* ServiceWorkerInternals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 417F0D801FFEE14F008EF303 /* ServiceWorkerInternals.cpp */; };
 		41815C1E138319830057AAA4 /* WebCoreTestSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41815C1C138319830057AAA4 /* WebCoreTestSupport.cpp */; };
 		41815C1F138319830057AAA4 /* WebCoreTestSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 41815C1D138319830057AAA4 /* WebCoreTestSupport.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -1064,6 +1062,8 @@
 		41F062140F5F192600A07EAC /* InspectorDatabaseResource.h in Headers */ = {isa = PBXBuildFile; fileRef = 41F062120F5F192600A07EAC /* InspectorDatabaseResource.h */; };
 		41F1D21F0EF35C2A00DA8753 /* ScriptCachedFrameData.h in Headers */ = {isa = PBXBuildFile; fileRef = 41F1D21D0EF35C2A00DA8753 /* ScriptCachedFrameData.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		41FABD2D1F4DFE4A006A6C97 /* DOMCacheEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 41FABD2B1F4DFE42006A6C97 /* DOMCacheEngine.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		427DA71D13735DFA007C57FB /* JSServiceWorkerInternals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 427DA71B13735DFA007C57FB /* JSServiceWorkerInternals.cpp */; };
+		427DA71E13735DFA007C57FB /* JSServiceWorkerInternals.h in Headers */ = {isa = PBXBuildFile; fileRef = 427DA71C13735DFA007C57FB /* JSServiceWorkerInternals.h */; };
 		43107BE218CC19DE00CC18E8 /* SelectorPseudoTypeMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 43107BE118CC19DE00CC18E8 /* SelectorPseudoTypeMap.h */; };
 		431A2F9C13B6F2B0007791E4 /* SVGAnimatedNumberOptionalNumber.h in Headers */ = {isa = PBXBuildFile; fileRef = 431A2F9A13B6F2B0007791E4 /* SVGAnimatedNumberOptionalNumber.h */; };
 		432D3FE818A8658400D7DC03 /* SelectorCheckerTestFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 432D3FE718A8658400D7DC03 /* SelectorCheckerTestFunctions.h */; };
@@ -5591,6 +5591,8 @@
 		119340951FED715500935F1E /* RenderTreeBuilderFormControls.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RenderTreeBuilderFormControls.h; sourceTree = "<group>"; };
 		119340A01FEE024000935F1E /* RenderTreeBuilderBlock.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = RenderTreeBuilderBlock.cpp; sourceTree = "<group>"; };
 		119340A11FEE024000935F1E /* RenderTreeBuilderBlock.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RenderTreeBuilderBlock.h; sourceTree = "<group>"; };
+		11C5F1162003E7750001AE60 /* RenderTreeBuilderInline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderTreeBuilderInline.cpp; sourceTree = "<group>"; };
+		11C5F1182003E7760001AE60 /* RenderTreeBuilderInline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderTreeBuilderInline.h; sourceTree = "<group>"; };
 		11E067EB1E62461300162D16 /* SimpleLineLayoutCoverage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SimpleLineLayoutCoverage.cpp; sourceTree = "<group>"; };
 		11E067ED1E6246E500162D16 /* SimpleLineLayoutCoverage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SimpleLineLayoutCoverage.h; sourceTree = "<group>"; };
 		1400D7A717136EA70077CE05 /* ScriptWrappableInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptWrappableInlines.h; sourceTree = "<group>"; };
@@ -7031,9 +7033,7 @@
 		417DA4CF13734326007C57FB /* Internals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Internals.cpp; sourceTree = "<group>"; };
 		417DA6D013734E02007C57FB /* libWebCoreTestSupport.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libWebCoreTestSupport.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
 		417DA71B13735DFA007C57FB /* JSInternals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSInternals.cpp; sourceTree = "<group>"; };
-		427DA71B13735DFA007C57FB /* JSServiceWorkerInternals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSServiceWorkerInternals.cpp; sourceTree = "<group>"; };
 		417DA71C13735DFA007C57FB /* JSInternals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSInternals.h; sourceTree = "<group>"; };
-		427DA71C13735DFA007C57FB /* JSServiceWorkerInternals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSServiceWorkerInternals.h; sourceTree = "<group>"; };
 		417F0D7E1FFEE14E008EF303 /* ServiceWorkerInternals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ServiceWorkerInternals.h; sourceTree = "<group>"; };
 		417F0D801FFEE14F008EF303 /* ServiceWorkerInternals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ServiceWorkerInternals.cpp; sourceTree = "<group>"; };
 		417F0D811FFEE150008EF303 /* ServiceWorkerInternals.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ServiceWorkerInternals.idl; sourceTree = "<group>"; };
@@ -7145,6 +7145,8 @@
 		41FB278F1F34C28200795487 /* WorkerGlobalScopeCaches.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WorkerGlobalScopeCaches.cpp; sourceTree = "<group>"; };
 		41FB27991F34CE9C00795487 /* CacheQueryOptions.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = CacheQueryOptions.idl; sourceTree = "<group>"; };
 		41FB279B1F34CEF000795487 /* CacheQueryOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CacheQueryOptions.h; sourceTree = "<group>"; };
+		427DA71B13735DFA007C57FB /* JSServiceWorkerInternals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSServiceWorkerInternals.cpp; sourceTree = "<group>"; };
+		427DA71C13735DFA007C57FB /* JSServiceWorkerInternals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSServiceWorkerInternals.h; sourceTree = "<group>"; };
 		43107BE118CC19DE00CC18E8 /* SelectorPseudoTypeMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SelectorPseudoTypeMap.h; sourceTree = "<group>"; };
 		43142E7913B1E97700F1C871 /* SVGAnimatedRect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGAnimatedRect.cpp; sourceTree = "<group>"; };
 		431A2F9A13B6F2B0007791E4 /* SVGAnimatedNumberOptionalNumber.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGAnimatedNumberOptionalNumber.h; sourceTree = "<group>"; };
@@ -24635,6 +24637,8 @@
 				E47C39261FE6E0DC00BBBC6B /* RenderTreeBuilderFirstLetter.h */,
 				119340941FED715500935F1E /* RenderTreeBuilderFormControls.cpp */,
 				119340951FED715500935F1E /* RenderTreeBuilderFormControls.h */,
+				11C5F1162003E7750001AE60 /* RenderTreeBuilderInline.cpp */,
+				11C5F1182003E7760001AE60 /* RenderTreeBuilderInline.h */,
 				E47C392B1FE6E0DF00BBBC6B /* RenderTreeBuilderList.cpp */,
 				E47C39281FE6E0DD00BBBC6B /* RenderTreeBuilderList.h */,
 				E47C39231FE6E0DA00BBBC6B /* RenderTreeBuilderMultiColumn.cpp */,

Modified: trunk/Source/WebCore/rendering/RenderInline.cpp (226519 => 226520)


--- trunk/Source/WebCore/rendering/RenderInline.cpp	2018-01-08 18:37:37 UTC (rev 226519)
+++ trunk/Source/WebCore/rendering/RenderInline.cpp	2018-01-08 18:38:31 UTC (rev 226520)
@@ -257,336 +257,14 @@
 
 void RenderInline::addChild(RenderTreeBuilder& builder, RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
 {
-    auto* beforeChildOrPlaceholder = beforeChild;
-    if (auto* fragmentedFlow = enclosingFragmentedFlow())
-        beforeChildOrPlaceholder = fragmentedFlow->resolveMovedChild(beforeChild);
-    if (continuation()) {
-        addChildToContinuation(builder, WTFMove(newChild), beforeChildOrPlaceholder);
-        return;
-    }
-    addChildIgnoringContinuation(builder, WTFMove(newChild), beforeChildOrPlaceholder);
+    builder.insertChildToRenderInline(*this, WTFMove(newChild), beforeChild);
 }
 
-static RenderBoxModelObject* nextContinuation(RenderObject* renderer)
-{
-    if (is<RenderInline>(*renderer) && !renderer->isReplaced())
-        return downcast<RenderInline>(*renderer).continuation();
-    return downcast<RenderBlock>(*renderer).inlineContinuation();
-}
-
-RenderBoxModelObject* RenderInline::continuationBefore(RenderObject* beforeChild)
-{
-    if (beforeChild && beforeChild->parent() == this)
-        return this;
-
-    RenderBoxModelObject* curr = nextContinuation(this);
-    RenderBoxModelObject* nextToLast = this;
-    RenderBoxModelObject* last = this;
-    while (curr) {
-        if (beforeChild && beforeChild->parent() == curr) {
-            if (curr->firstChild() == beforeChild)
-                return last;
-            return curr;
-        }
-
-        nextToLast = last;
-        last = curr;
-        curr = nextContinuation(curr);
-    }
-
-    if (!beforeChild && !last->firstChild())
-        return nextToLast;
-    return last;
-}
-
-static bool newChildIsInline(const RenderObject& newChild, const RenderInline& parent)
-{
-    // inline parent generates inline-table.
-    return newChild.isInline() | (parent.childRequiresTable(newChild) && parent.style().display() == INLINE);
-}
-
 void RenderInline::addChildIgnoringContinuation(RenderTreeBuilder& builder, RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
 {
-    // Make sure we don't append things after :after-generated content if we have it.
-    if (!beforeChild && isAfterContent(lastChild()))
-        beforeChild = lastChild();
-    
-    bool childInline = newChildIsInline(*newChild, *this);
-    // This code is for the old block-inside-inline model that uses continuations.
-    if (!childInline && !newChild->isFloatingOrOutOfFlowPositioned()) {
-        // We are placing a block inside an inline. We have to perform a split of this
-        // inline into continuations.  This involves creating an anonymous block box to hold
-        // |newChild|.  We then make that block box a continuation of this inline.  We take all of
-        // the children after |beforeChild| and put them in a clone of this object.
-        auto newStyle = RenderStyle::createAnonymousStyleWithDisplay(style(), BLOCK);
-        
-        // If inside an inline affected by in-flow positioning the block needs to be affected by it too.
-        // Giving the block a layer like this allows it to collect the x/y offsets from inline parents later.
-        if (auto positionedAncestor = inFlowPositionedInlineAncestor(this))
-            newStyle.setPosition(positionedAncestor->style().position());
-
-        auto newBox = createRenderer<RenderBlockFlow>(document(), WTFMove(newStyle));
-        newBox->initializeStyle();
-        newBox->setIsContinuation();
-        RenderBoxModelObject* oldContinuation = continuation();
-        if (oldContinuation)
-            oldContinuation->removeFromContinuationChain();
-        newBox->insertIntoContinuationChainAfter(*this);
-
-        splitFlow(builder, beforeChild, WTFMove(newBox), WTFMove(newChild), oldContinuation);
-        return;
-    }
-
-    auto& child = *newChild;
-    RenderBoxModelObject::addChild(builder, WTFMove(newChild), beforeChild);
-    child.setNeedsLayoutAndPrefWidthsRecalc();
+    builder.insertChildToRenderInlineIgnoringContinuation(*this, WTFMove(newChild), beforeChild);
 }
 
-RenderPtr<RenderInline> RenderInline::cloneAsContinuation() const
-{
-    RenderPtr<RenderInline> cloneInline = createRenderer<RenderInline>(*element(), RenderStyle::clone(style()));
-    cloneInline->initializeStyle();
-    cloneInline->setFragmentedFlowState(fragmentedFlowState());
-    cloneInline->setHasOutlineAutoAncestor(hasOutlineAutoAncestor());
-    cloneInline->setIsContinuation();
-    return cloneInline;
-}
-
-void RenderInline::splitInlines(RenderTreeBuilder& builder, RenderBlock* fromBlock, RenderBlock* toBlock,
-                                RenderBlock* middleBlock,
-                                RenderObject* beforeChild, RenderBoxModelObject* oldCont)
-{
-    // Create a clone of this inline.
-    RenderPtr<RenderInline> cloneInline = cloneAsContinuation();
-#if ENABLE(FULLSCREEN_API)
-    // If we're splitting the inline containing the fullscreened element,
-    // |beforeChild| may be the renderer for the fullscreened element. However,
-    // that renderer is wrapped in a RenderFullScreen, so |this| is not its
-    // parent. Since the splitting logic expects |this| to be the parent, set
-    // |beforeChild| to be the RenderFullScreen.
-    const Element* fullScreenElement = document().webkitCurrentFullScreenElement();
-    if (fullScreenElement && beforeChild && beforeChild->node() == fullScreenElement)
-        beforeChild = document().fullScreenRenderer();
-#endif
-    // Now take all of the children from beforeChild to the end and remove
-    // them from |this| and place them in the clone.
-    for (RenderObject* rendererToMove = beforeChild; rendererToMove;) {
-        RenderObject* nextSibling = rendererToMove->nextSibling();
-        // When anonymous wrapper is present, we might need to move the whole subtree instead.
-        if (rendererToMove->parent() != this) {
-            auto* anonymousParent = rendererToMove->parent();
-            while (anonymousParent && anonymousParent->parent() != this) {
-                ASSERT(anonymousParent->isAnonymous());
-                anonymousParent = anonymousParent->parent();
-            }
-            if (!anonymousParent) {
-                ASSERT_NOT_REACHED();
-                break;
-            }
-            // If beforeChild is the first child in the subtree, we could just move the whole subtree.
-            if (!rendererToMove->previousSibling()) {
-                // Reparent the whole anonymous wrapper tree.
-                rendererToMove = anonymousParent;
-                // Skip to the next sibling that is not in this subtree.
-                nextSibling = anonymousParent->nextSibling();
-            } else if (!rendererToMove->nextSibling()) {
-                // This is the last renderer in the subtree. We need to jump out of the wrapper subtree, so that
-                // the siblings are getting reparented too.
-                nextSibling = anonymousParent->nextSibling();
-            }
-            // Otherwise just move the renderer to the inline clone. Should the renderer need an anon
-            // wrapper, the addChild() will generate one for it.
-            // FIXME: When the anonymous wrapper has multiple children, we end up traversing up to the topmost wrapper
-            // every time, which is a bit wasteful.
-        }
-        auto childToMove = rendererToMove->parent()->takeChildInternal(*rendererToMove);
-        cloneInline->addChildIgnoringContinuation(builder, WTFMove(childToMove));
-        rendererToMove->setNeedsLayoutAndPrefWidthsRecalc();
-        rendererToMove = nextSibling;
-    }
-    // Hook |clone| up as the continuation of the middle block.
-    cloneInline->insertIntoContinuationChainAfter(*middleBlock);
-    if (oldCont)
-        oldCont->insertIntoContinuationChainAfter(*cloneInline);
-
-    // We have been reparented and are now under the fromBlock.  We need
-    // to walk up our inline parent chain until we hit the containing block.
-    // Once we hit the containing block we're done.
-    RenderBoxModelObject* current = downcast<RenderBoxModelObject>(parent());
-    RenderBoxModelObject* currentChild = this;
-    
-    // FIXME: Because splitting is O(n^2) as tags nest pathologically, we cap the depth at which we're willing to clone.
-    // There will eventually be a better approach to this problem that will let us nest to a much
-    // greater depth (see bugzilla bug 13430) but for now we have a limit.  This *will* result in
-    // incorrect rendering, but the alternative is to hang forever.
-    unsigned splitDepth = 1;
-    const unsigned cMaxSplitDepth = 200; 
-    while (current && current != fromBlock) {
-        if (splitDepth < cMaxSplitDepth) {
-            // Create a new clone.
-            RenderPtr<RenderInline> cloneChild = WTFMove(cloneInline);
-            cloneInline = downcast<RenderInline>(*current).cloneAsContinuation();
-
-            // Insert our child clone as the first child.
-            cloneInline->addChildIgnoringContinuation(builder, WTFMove(cloneChild));
-
-            // Hook the clone up as a continuation of |curr|.
-            cloneInline->insertIntoContinuationChainAfter(*current);
-
-            // Now we need to take all of the children starting from the first child
-            // *after* currentChild and append them all to the clone.
-            for (auto* sibling = currentChild->nextSibling(); sibling;) {
-                auto* next = sibling->nextSibling();
-                auto childToMove = current->takeChildInternal(*sibling);
-                cloneInline->addChildIgnoringContinuation(builder, WTFMove(childToMove));
-                sibling->setNeedsLayoutAndPrefWidthsRecalc();
-                sibling = next;
-            }
-        }
-        
-        // Keep walking up the chain.
-        currentChild = current;
-        current = downcast<RenderBoxModelObject>(current->parent());
-        ++splitDepth;
-    }
-
-    // Clear the flow thread containing blocks cached during the detached state insertions.
-    for (auto& cloneBlockChild : childrenOfType<RenderBlock>(*cloneInline))
-        cloneBlockChild.resetEnclosingFragmentedFlowAndChildInfoIncludingDescendants();
-
-    // Now we are at the block level. We need to put the clone into the toBlock.
-    toBlock->insertChildInternal(WTFMove(cloneInline), nullptr);
-
-    // Now take all the children after currentChild and remove them from the fromBlock
-    // and put them in the toBlock.
-    for (auto* current = currentChild->nextSibling(); current;) {
-        auto* next = current->nextSibling();
-        auto childToMove = fromBlock->takeChildInternal(*current);
-        toBlock->insertChildInternal(WTFMove(childToMove), nullptr);
-        current = next;
-    }
-}
-
-void RenderInline::splitFlow(RenderTreeBuilder& builder, RenderObject* beforeChild, RenderPtr<RenderBlock> newBlockBox, RenderPtr<RenderObject> newChild, RenderBoxModelObject* oldCont)
-{
-    auto& addedBlockBox = *newBlockBox;
-    RenderBlock* pre = nullptr;
-    RenderBlock* block = containingBlock();
-
-    // Delete our line boxes before we do the inline split into continuations.
-    block->deleteLines();
-
-    RenderPtr<RenderBlock> createdPre;
-    bool madeNewBeforeBlock = false;
-    if (block->isAnonymousBlock() && (!block->parent() || !block->parent()->createsAnonymousWrapper())) {
-        // We can reuse this block and make it the preBlock of the next continuation.
-        pre = block;
-        pre->removePositionedObjects(nullptr);
-        // FIXME-BLOCKFLOW: The enclosing method should likely be switched over
-        // to only work on RenderBlockFlow, in which case this conversion can be
-        // removed.
-        if (is<RenderBlockFlow>(*pre))
-            downcast<RenderBlockFlow>(*pre).removeFloatingObjects();
-        block = block->containingBlock();
-    } else {
-        // No anonymous block available for use.  Make one.
-        createdPre = block->createAnonymousBlock();
-        pre = createdPre.get();
-        madeNewBeforeBlock = true;
-    }
-
-    auto createdPost = pre->createAnonymousBoxWithSameTypeAs(*block);
-    auto& post = downcast<RenderBlock>(*createdPost);
-
-    RenderObject* boxFirst = madeNewBeforeBlock ? block->firstChild() : pre->nextSibling();
-    if (createdPre)
-        block->insertChildInternal(WTFMove(createdPre), boxFirst);
-    block->insertChildInternal(WTFMove(newBlockBox), boxFirst);
-    block->insertChildInternal(WTFMove(createdPost), boxFirst);
-    block->setChildrenInline(false);
-    
-    if (madeNewBeforeBlock) {
-        RenderObject* o = boxFirst;
-        while (o) {
-            RenderObject* no = o;
-            o = no->nextSibling();
-            auto childToMove = block->takeChildInternal(*no);
-            pre->insertChildInternal(WTFMove(childToMove), nullptr);
-            no->setNeedsLayoutAndPrefWidthsRecalc();
-        }
-    }
-
-    splitInlines(builder, pre, &post, &addedBlockBox, beforeChild, oldCont);
-
-    // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting
-    // time in makeChildrenNonInline by just setting this explicitly up front.
-    addedBlockBox.setChildrenInline(false);
-
-    // We delayed adding the newChild until now so that the |newBlockBox| would be fully
-    // connected, thus allowing newChild access to a renderArena should it need
-    // to wrap itself in additional boxes (e.g., table construction).
-    builder.insertChild(addedBlockBox, WTFMove(newChild));
-
-    // Always just do a full layout in order to ensure that line boxes (especially wrappers for images)
-    // get deleted properly.  Because objects moves from the pre block into the post block, we want to
-    // make new line boxes instead of leaving the old line boxes around.
-    pre->setNeedsLayoutAndPrefWidthsRecalc();
-    block->setNeedsLayoutAndPrefWidthsRecalc();
-    post.setNeedsLayoutAndPrefWidthsRecalc();
-}
-
-static bool canUseAsParentForContinuation(const RenderObject* renderer)
-{
-    if (!renderer)
-        return false;
-    if (!is<RenderBlock>(renderer) && renderer->isAnonymous())
-        return false;
-    if (is<RenderTable>(renderer))
-        return false;
-    return true;
-}
-
-void RenderInline::addChildToContinuation(RenderTreeBuilder& builder, RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
-{
-    auto* flow = continuationBefore(beforeChild);
-    // It may or may not be the direct parent of the beforeChild.
-    RenderBoxModelObject* beforeChildAncestor = nullptr;
-    if (!beforeChild) {
-        auto* continuation = nextContinuation(flow);
-        beforeChildAncestor = continuation ? continuation : flow;
-    } else if (canUseAsParentForContinuation(beforeChild->parent()))
-        beforeChildAncestor = downcast<RenderBoxModelObject>(beforeChild->parent());
-    else if (beforeChild->parent()) {
-        // In case of anonymous wrappers, the parent of the beforeChild is mostly irrelevant. What we need is the topmost wrapper.
-        auto* parent = beforeChild->parent();
-        while (parent && parent->parent() && parent->parent()->isAnonymous()) {
-            // The ancestor candidate needs to be inside the continuation.
-            if (parent->isContinuation())
-                break;
-            parent = parent->parent();
-        }
-        ASSERT(parent && parent->parent());
-        beforeChildAncestor = downcast<RenderBoxModelObject>(parent->parent());
-    } else
-        ASSERT_NOT_REACHED();
-
-    if (newChild->isFloatingOrOutOfFlowPositioned())
-        return beforeChildAncestor->addChildIgnoringContinuation(builder, WTFMove(newChild), beforeChild);
-
-    if (flow == beforeChildAncestor)
-        return flow->addChildIgnoringContinuation(builder, WTFMove(newChild), beforeChild);
-    // A continuation always consists of two potential candidates: an inline or an anonymous
-    // block box holding block children.
-    bool childInline = newChildIsInline(*newChild, *this);
-    // The goal here is to match up if we can, so that we can coalesce and create the
-    // minimal # of continuations needed for the inline.
-    if (childInline == beforeChildAncestor->isInline())
-        return beforeChildAncestor->addChildIgnoringContinuation(builder, WTFMove(newChild), beforeChild);
-    if (flow->isInline() == childInline)
-        return flow->addChildIgnoringContinuation(builder, WTFMove(newChild)); // Just treat like an append.
-    return beforeChildAncestor->addChildIgnoringContinuation(builder, WTFMove(newChild), beforeChild);
-}
-
 void RenderInline::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
 {
     m_lineBoxes.paint(this, paintInfo, paintOffset);
@@ -1369,7 +1047,7 @@
     newBox->insertIntoContinuationChainAfter(*this);
     RenderObject* beforeChild = child.nextSibling();
     auto removedChild = takeChildInternal(child);
-    splitFlow(*RenderTreeBuilder::current(), beforeChild, WTFMove(newBox), WTFMove(removedChild), oldContinuation);
+    RenderTreeBuilder::current()->splitFlow(*this, beforeChild, WTFMove(newBox), WTFMove(removedChild), oldContinuation);
 }
 
 void RenderInline::updateHitTestResult(HitTestResult& result, const LayoutPoint& point)

Modified: trunk/Source/WebCore/rendering/RenderInline.h (226519 => 226520)


--- trunk/Source/WebCore/rendering/RenderInline.h	2018-01-08 18:37:37 UTC (rev 226519)
+++ trunk/Source/WebCore/rendering/RenderInline.h	2018-01-08 18:38:31 UTC (rev 226520)
@@ -94,6 +94,8 @@
 
     bool hitTestCulledInline(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset);
 
+    void addChildIgnoringContinuation(RenderTreeBuilder&, RenderPtr<RenderObject> newChild, RenderObject* beforeChild = nullptr) final;
+
 protected:
     void willBeDestroyed() override;
 
@@ -116,12 +118,6 @@
     template<typename GeneratorContext>
     void generateCulledLineBoxRects(GeneratorContext& yield, const RenderInline* container) const;
 
-    void addChildToContinuation(RenderTreeBuilder&, RenderPtr<RenderObject> newChild, RenderObject* beforeChild);
-    void addChildIgnoringContinuation(RenderTreeBuilder&, RenderPtr<RenderObject> newChild, RenderObject* beforeChild = nullptr) final;
-
-    void splitInlines(RenderTreeBuilder&, RenderBlock* fromBlock, RenderBlock* toBlock, RenderBlock* middleBlock, RenderObject* beforeChild, RenderBoxModelObject* oldCont);
-    void splitFlow(RenderTreeBuilder&, RenderObject* beforeChild, RenderPtr<RenderBlock> newBlockBox, RenderPtr<RenderObject> newChild, RenderBoxModelObject* oldCont);
-
     void layout() final { ASSERT_NOT_REACHED(); } // Do nothing for layout()
 
     void paint(PaintInfo&, const LayoutPoint&) final;
@@ -162,11 +158,8 @@
 #if ENABLE(DASHBOARD_SUPPORT)
     void addAnnotatedRegions(Vector<AnnotatedRegionValue>&) final;
 #endif
-    
-    RenderPtr<RenderInline> cloneAsContinuation() const;
 
     void paintOutlineForLine(GraphicsContext&, const LayoutPoint&, const LayoutRect& prevLine, const LayoutRect& thisLine, const LayoutRect& nextLine, const Color&);
-    RenderBoxModelObject* continuationBefore(RenderObject* beforeChild);
 
     bool willChangeCreatesStackingContext() const
     {

Modified: trunk/Source/WebCore/rendering/updating/RenderTreeBuilder.cpp (226519 => 226520)


--- trunk/Source/WebCore/rendering/updating/RenderTreeBuilder.cpp	2018-01-08 18:37:37 UTC (rev 226519)
+++ trunk/Source/WebCore/rendering/updating/RenderTreeBuilder.cpp	2018-01-08 18:38:31 UTC (rev 226520)
@@ -36,6 +36,7 @@
 #include "RenderTreeBuilderBlock.h"
 #include "RenderTreeBuilderFirstLetter.h"
 #include "RenderTreeBuilderFormControls.h"
+#include "RenderTreeBuilderInline.h"
 #include "RenderTreeBuilderList.h"
 #include "RenderTreeBuilderMultiColumn.h"
 #include "RenderTreeBuilderRuby.h"
@@ -107,6 +108,7 @@
     , m_rubyBuilder(std::make_unique<Ruby>(*this))
     , m_formControlsBuilder(std::make_unique<FormControls>(*this))
     , m_blockBuilder(std::make_unique<Block>(*this))
+    , m_inlineBuilder(std::make_unique<Inline>(*this))
 {
     RELEASE_ASSERT(!s_current || &m_view != &s_current->m_view);
     m_previous = s_current;
@@ -272,6 +274,21 @@
     return beforeChild;
 }
 
+void RenderTreeBuilder::insertChildToRenderInline(RenderInline& parent, RenderPtr<RenderObject> child, RenderObject* beforeChild)
+{
+    inlineBuilder().insertChild(parent, WTFMove(child), beforeChild);
+}
+
+void RenderTreeBuilder::insertChildToRenderInlineIgnoringContinuation(RenderInline& parent, RenderPtr<RenderObject> child, RenderObject* beforeChild)
+{
+    inlineBuilder().insertChildIgnoringContinuation(parent, WTFMove(child), beforeChild);
+}
+
+void RenderTreeBuilder::splitFlow(RenderInline& parent, RenderObject* beforeChild, RenderPtr<RenderBlock> newBlockBox, RenderPtr<RenderObject> child, RenderBoxModelObject* oldCont)
+{
+    inlineBuilder().splitFlow(parent, beforeChild, WTFMove(newBlockBox), WTFMove(child), oldCont);
+}
+
 void RenderTreeBuilder::updateAfterDescendants(RenderElement& renderer)
 {
     if (is<RenderBlock>(renderer))

Modified: trunk/Source/WebCore/rendering/updating/RenderTreeBuilder.h (226519 => 226520)


--- trunk/Source/WebCore/rendering/updating/RenderTreeBuilder.h	2018-01-08 18:37:37 UTC (rev 226519)
+++ trunk/Source/WebCore/rendering/updating/RenderTreeBuilder.h	2018-01-08 18:38:31 UTC (rev 226520)
@@ -52,6 +52,11 @@
     void makeChildrenNonInline(RenderBlock& parent, RenderObject* insertionPoint = nullptr);
     RenderObject* splitAnonymousBoxesAroundChild(RenderBox& parent, RenderObject* beforeChild);
 
+    // These functions are temporary until after all block/inline/continuation code is moved over.
+    void insertChildToRenderInline(RenderInline& parent, RenderPtr<RenderObject>, RenderObject* beforeChild = nullptr);
+    void insertChildToRenderInlineIgnoringContinuation(RenderInline& parent, RenderPtr<RenderObject>, RenderObject* beforeChild = nullptr);
+    void splitFlow(RenderInline& parent, RenderObject* beforeChild, RenderPtr<RenderBlock> newBlockBox, RenderPtr<RenderObject> child, RenderBoxModelObject* oldCont);
+
 private:
     class FirstLetter;
     class List;
@@ -60,6 +65,7 @@
     class Ruby;
     class FormControls;
     class Block;
+    class Inline;
 
     FirstLetter& firstLetterBuilder() { return *m_firstLetterBuilder; }
     List& listBuilder() { return *m_listBuilder; }
@@ -68,6 +74,7 @@
     Ruby& rubyBuilder() { return *m_rubyBuilder; }
     FormControls& formControlsBuilder() { return *m_formControlsBuilder; }
     Block& blockBuilder() { return *m_blockBuilder; }
+    Inline& inlineBuilder() { return *m_inlineBuilder; }
 
     RenderView& m_view;
 
@@ -81,6 +88,7 @@
     std::unique_ptr<Ruby> m_rubyBuilder;
     std::unique_ptr<FormControls> m_formControlsBuilder;
     std::unique_ptr<Block> m_blockBuilder;
+    std::unique_ptr<Inline> m_inlineBuilder;
 };
 
 }

Added: trunk/Source/WebCore/rendering/updating/RenderTreeBuilderInline.cpp (0 => 226520)


--- trunk/Source/WebCore/rendering/updating/RenderTreeBuilderInline.cpp	                        (rev 0)
+++ trunk/Source/WebCore/rendering/updating/RenderTreeBuilderInline.cpp	2018-01-08 18:38:31 UTC (rev 226520)
@@ -0,0 +1,383 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "RenderTreeBuilderInline.h"
+
+#include "RenderChildIterator.h"
+#include "RenderFullScreen.h"
+#include "RenderInline.h"
+#include "RenderTable.h"
+
+namespace WebCore {
+
+static bool canUseAsParentForContinuation(const RenderObject* renderer)
+{
+    if (!renderer)
+        return false;
+    if (!is<RenderBlock>(renderer) && renderer->isAnonymous())
+        return false;
+    if (is<RenderTable>(renderer))
+        return false;
+    return true;
+}
+
+static RenderBoxModelObject* nextContinuation(RenderObject* renderer)
+{
+    if (is<RenderInline>(*renderer) && !renderer->isReplaced())
+        return downcast<RenderInline>(*renderer).continuation();
+    return downcast<RenderBlock>(*renderer).inlineContinuation();
+}
+
+static RenderBoxModelObject* continuationBefore(RenderInline& parent, RenderObject* beforeChild)
+{
+    if (beforeChild && beforeChild->parent() == &parent)
+        return &parent;
+
+    RenderBoxModelObject* curr = nextContinuation(&parent);
+    RenderBoxModelObject* nextToLast = &parent;
+    RenderBoxModelObject* last = &parent;
+    while (curr) {
+        if (beforeChild && beforeChild->parent() == curr) {
+            if (curr->firstChild() == beforeChild)
+                return last;
+            return curr;
+        }
+
+        nextToLast = last;
+        last = curr;
+        curr = nextContinuation(curr);
+    }
+
+    if (!beforeChild && !last->firstChild())
+        return nextToLast;
+    return last;
+}
+
+static RenderPtr<RenderInline> cloneAsContinuation(RenderInline& renderer)
+{
+    RenderPtr<RenderInline> cloneInline = createRenderer<RenderInline>(*renderer.element(), RenderStyle::clone(renderer.style()));
+    cloneInline->initializeStyle();
+    cloneInline->setFragmentedFlowState(renderer.fragmentedFlowState());
+    cloneInline->setHasOutlineAutoAncestor(renderer.hasOutlineAutoAncestor());
+    cloneInline->setIsContinuation();
+    return cloneInline;
+}
+
+static bool newChildIsInline(const RenderObject& child, const RenderInline& parent)
+{
+    // inline parent generates inline-table.
+    return child.isInline() | (parent.childRequiresTable(child) && parent.style().display() == INLINE);
+}
+
+static RenderElement* inFlowPositionedInlineAncestor(RenderElement& renderer)
+{
+    auto* ancestor = &renderer;
+    while (ancestor && ancestor->isRenderInline()) {
+        if (ancestor->isInFlowPositioned())
+            return ancestor;
+        ancestor = ancestor->parent();
+    }
+    return nullptr;
+}
+
+RenderTreeBuilder::Inline::Inline(RenderTreeBuilder& builder)
+    : m_builder(builder)
+{
+}
+
+void RenderTreeBuilder::Inline::insertChild(RenderInline& parent, RenderPtr<RenderObject> child, RenderObject* beforeChild)
+{
+    auto* beforeChildOrPlaceholder = beforeChild;
+    if (auto* fragmentedFlow = parent.enclosingFragmentedFlow())
+        beforeChildOrPlaceholder = fragmentedFlow->resolveMovedChild(beforeChild);
+    if (parent.continuation()) {
+        insertChildToContinuation(parent, WTFMove(child), beforeChildOrPlaceholder);
+        return;
+    }
+    insertChildIgnoringContinuation(parent, WTFMove(child), beforeChildOrPlaceholder);
+}
+
+void RenderTreeBuilder::Inline::insertChildToContinuation(RenderInline& parent, RenderPtr<RenderObject> child, RenderObject* beforeChild)
+{
+    auto* flow = continuationBefore(parent, beforeChild);
+    // It may or may not be the direct parent of the beforeChild.
+    RenderBoxModelObject* beforeChildAncestor = nullptr;
+    if (!beforeChild) {
+        auto* continuation = nextContinuation(flow);
+        beforeChildAncestor = continuation ? continuation : flow;
+    } else if (canUseAsParentForContinuation(beforeChild->parent()))
+        beforeChildAncestor = downcast<RenderBoxModelObject>(beforeChild->parent());
+    else if (beforeChild->parent()) {
+        // In case of anonymous wrappers, the parent of the beforeChild is mostly irrelevant. What we need is the topmost wrapper.
+        auto* parent = beforeChild->parent();
+        while (parent && parent->parent() && parent->parent()->isAnonymous()) {
+            // The ancestor candidate needs to be inside the continuation.
+            if (parent->isContinuation())
+                break;
+            parent = parent->parent();
+        }
+        ASSERT(parent && parent->parent());
+        beforeChildAncestor = downcast<RenderBoxModelObject>(parent->parent());
+    } else
+        ASSERT_NOT_REACHED();
+
+    if (child->isFloatingOrOutOfFlowPositioned())
+        return beforeChildAncestor->addChildIgnoringContinuation(m_builder, WTFMove(child), beforeChild);
+
+    if (flow == beforeChildAncestor)
+        return flow->addChildIgnoringContinuation(m_builder, WTFMove(child), beforeChild);
+    // A continuation always consists of two potential candidates: an inline or an anonymous
+    // block box holding block children.
+    bool childInline = newChildIsInline(*child, parent);
+    // The goal here is to match up if we can, so that we can coalesce and create the
+    // minimal # of continuations needed for the inline.
+    if (childInline == beforeChildAncestor->isInline())
+        return beforeChildAncestor->addChildIgnoringContinuation(m_builder, WTFMove(child), beforeChild);
+    if (flow->isInline() == childInline)
+        return flow->addChildIgnoringContinuation(m_builder, WTFMove(child)); // Just treat like an append.
+    return beforeChildAncestor->addChildIgnoringContinuation(m_builder, WTFMove(child), beforeChild);
+}
+
+void RenderTreeBuilder::Inline::insertChildIgnoringContinuation(RenderInline& parent, RenderPtr<RenderObject> child, RenderObject* beforeChild)
+{
+    // Make sure we don't append things after :after-generated content if we have it.
+    if (!beforeChild && parent.isAfterContent(parent.lastChild()))
+        beforeChild = parent.lastChild();
+
+    bool childInline = newChildIsInline(*child, parent);
+    // This code is for the old block-inside-inline model that uses continuations.
+    if (!childInline && !child->isFloatingOrOutOfFlowPositioned()) {
+        // We are placing a block inside an inline. We have to perform a split of this
+        // inline into continuations. This involves creating an anonymous block box to hold
+        // |newChild|. We then make that block box a continuation of this inline. We take all of
+        // the children after |beforeChild| and put them in a clone of this object.
+        auto newStyle = RenderStyle::createAnonymousStyleWithDisplay(parent.style(), BLOCK);
+
+        // If inside an inline affected by in-flow positioning the block needs to be affected by it too.
+        // Giving the block a layer like this allows it to collect the x/y offsets from inline parents later.
+        if (auto positionedAncestor = inFlowPositionedInlineAncestor(parent))
+            newStyle.setPosition(positionedAncestor->style().position());
+
+        auto newBox = createRenderer<RenderBlockFlow>(parent.document(), WTFMove(newStyle));
+        newBox->initializeStyle();
+        newBox->setIsContinuation();
+        RenderBoxModelObject* oldContinuation = parent.continuation();
+        if (oldContinuation)
+            oldContinuation->removeFromContinuationChain();
+        newBox->insertIntoContinuationChainAfter(parent);
+
+        splitFlow(parent, beforeChild, WTFMove(newBox), WTFMove(child), oldContinuation);
+        return;
+    }
+
+    auto& childToAdd = *child;
+    parent.RenderBoxModelObject::addChild(m_builder, WTFMove(child), beforeChild);
+    childToAdd.setNeedsLayoutAndPrefWidthsRecalc();
+}
+
+void RenderTreeBuilder::Inline::splitFlow(RenderInline& parent, RenderObject* beforeChild, RenderPtr<RenderBlock> newBlockBox, RenderPtr<RenderObject> child, RenderBoxModelObject* oldCont)
+{
+    auto& addedBlockBox = *newBlockBox;
+    RenderBlock* pre = nullptr;
+    RenderBlock* block = parent.containingBlock();
+
+    // Delete our line boxes before we do the inline split into continuations.
+    block->deleteLines();
+
+    RenderPtr<RenderBlock> createdPre;
+    bool madeNewBeforeBlock = false;
+    if (block->isAnonymousBlock() && (!block->parent() || !block->parent()->createsAnonymousWrapper())) {
+        // We can reuse this block and make it the preBlock of the next continuation.
+        pre = block;
+        pre->removePositionedObjects(nullptr);
+        // FIXME-BLOCKFLOW: The enclosing method should likely be switched over
+        // to only work on RenderBlockFlow, in which case this conversion can be
+        // removed.
+        if (is<RenderBlockFlow>(*pre))
+            downcast<RenderBlockFlow>(*pre).removeFloatingObjects();
+        block = block->containingBlock();
+    } else {
+        // No anonymous block available for use. Make one.
+        createdPre = block->createAnonymousBlock();
+        pre = createdPre.get();
+        madeNewBeforeBlock = true;
+    }
+
+    auto createdPost = pre->createAnonymousBoxWithSameTypeAs(*block);
+    auto& post = downcast<RenderBlock>(*createdPost);
+
+    RenderObject* boxFirst = madeNewBeforeBlock ? block->firstChild() : pre->nextSibling();
+    if (createdPre)
+        block->insertChildInternal(WTFMove(createdPre), boxFirst);
+    block->insertChildInternal(WTFMove(newBlockBox), boxFirst);
+    block->insertChildInternal(WTFMove(createdPost), boxFirst);
+    block->setChildrenInline(false);
+
+    if (madeNewBeforeBlock) {
+        RenderObject* o = boxFirst;
+        while (o) {
+            RenderObject* no = o;
+            o = no->nextSibling();
+            auto childToMove = block->takeChildInternal(*no);
+            pre->insertChildInternal(WTFMove(childToMove), nullptr);
+            no->setNeedsLayoutAndPrefWidthsRecalc();
+        }
+    }
+
+    splitInlines(parent, pre, &post, &addedBlockBox, beforeChild, oldCont);
+
+    // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting
+    // time in makeChildrenNonInline by just setting this explicitly up front.
+    addedBlockBox.setChildrenInline(false);
+
+    // We delayed adding the newChild until now so that the |newBlockBox| would be fully
+    // connected, thus allowing newChild access to a renderArena should it need
+    // to wrap itself in additional boxes (e.g., table construction).
+    m_builder.insertChild(addedBlockBox, WTFMove(child));
+
+    // Always just do a full layout in order to ensure that line boxes (especially wrappers for images)
+    // get deleted properly. Because objects moves from the pre block into the post block, we want to
+    // make new line boxes instead of leaving the old line boxes around.
+    pre->setNeedsLayoutAndPrefWidthsRecalc();
+    block->setNeedsLayoutAndPrefWidthsRecalc();
+    post.setNeedsLayoutAndPrefWidthsRecalc();
+}
+
+void RenderTreeBuilder::Inline::splitInlines(RenderInline& parent, RenderBlock* fromBlock, RenderBlock* toBlock, RenderBlock* middleBlock, RenderObject* beforeChild, RenderBoxModelObject* oldCont)
+{
+    // Create a clone of this inline.
+    RenderPtr<RenderInline> cloneInline = cloneAsContinuation(parent);
+#if ENABLE(FULLSCREEN_API)
+    // If we're splitting the inline containing the fullscreened element,
+    // |beforeChild| may be the renderer for the fullscreened element. However,
+    // that renderer is wrapped in a RenderFullScreen, so |this| is not its
+    // parent. Since the splitting logic expects |this| to be the parent, set
+    // |beforeChild| to be the RenderFullScreen.
+    const Element* fullScreenElement = parent.document().webkitCurrentFullScreenElement();
+    if (fullScreenElement && beforeChild && beforeChild->node() == fullScreenElement)
+        beforeChild = parent.document().fullScreenRenderer();
+#endif
+    // Now take all of the children from beforeChild to the end and remove
+    // them from |this| and place them in the clone.
+    for (RenderObject* rendererToMove = beforeChild; rendererToMove;) {
+        RenderObject* nextSibling = rendererToMove->nextSibling();
+        // When anonymous wrapper is present, we might need to move the whole subtree instead.
+        if (rendererToMove->parent() != &parent) {
+            auto* anonymousParent = rendererToMove->parent();
+            while (anonymousParent && anonymousParent->parent() != &parent) {
+                ASSERT(anonymousParent->isAnonymous());
+                anonymousParent = anonymousParent->parent();
+            }
+            if (!anonymousParent) {
+                ASSERT_NOT_REACHED();
+                break;
+            }
+            // If beforeChild is the first child in the subtree, we could just move the whole subtree.
+            if (!rendererToMove->previousSibling()) {
+                // Reparent the whole anonymous wrapper tree.
+                rendererToMove = anonymousParent;
+                // Skip to the next sibling that is not in this subtree.
+                nextSibling = anonymousParent->nextSibling();
+            } else if (!rendererToMove->nextSibling()) {
+                // This is the last renderer in the subtree. We need to jump out of the wrapper subtree, so that
+                // the siblings are getting reparented too.
+                nextSibling = anonymousParent->nextSibling();
+            }
+            // Otherwise just move the renderer to the inline clone. Should the renderer need an anon
+            // wrapper, the addChild() will generate one for it.
+            // FIXME: When the anonymous wrapper has multiple children, we end up traversing up to the topmost wrapper
+            // every time, which is a bit wasteful.
+        }
+        auto childToMove = rendererToMove->parent()->takeChildInternal(*rendererToMove);
+        cloneInline->addChildIgnoringContinuation(m_builder, WTFMove(childToMove));
+        rendererToMove->setNeedsLayoutAndPrefWidthsRecalc();
+        rendererToMove = nextSibling;
+    }
+    // Hook |clone| up as the continuation of the middle block.
+    cloneInline->insertIntoContinuationChainAfter(*middleBlock);
+    if (oldCont)
+        oldCont->insertIntoContinuationChainAfter(*cloneInline);
+
+    // We have been reparented and are now under the fromBlock. We need
+    // to walk up our inline parent chain until we hit the containing block.
+    // Once we hit the containing block we're done.
+    RenderBoxModelObject* current = downcast<RenderBoxModelObject>(parent.parent());
+    RenderBoxModelObject* currentChild = &parent;
+
+    // FIXME: Because splitting is O(n^2) as tags nest pathologically, we cap the depth at which we're willing to clone.
+    // There will eventually be a better approach to this problem that will let us nest to a much
+    // greater depth (see bugzilla bug 13430) but for now we have a limit. This *will* result in
+    // incorrect rendering, but the alternative is to hang forever.
+    unsigned splitDepth = 1;
+    const unsigned cMaxSplitDepth = 200;
+    while (current && current != fromBlock) {
+        if (splitDepth < cMaxSplitDepth) {
+            // Create a new clone.
+            RenderPtr<RenderInline> cloneChild = WTFMove(cloneInline);
+            cloneInline = cloneAsContinuation(downcast<RenderInline>(*current));
+
+            // Insert our child clone as the first child.
+            cloneInline->addChildIgnoringContinuation(m_builder, WTFMove(cloneChild));
+
+            // Hook the clone up as a continuation of |curr|.
+            cloneInline->insertIntoContinuationChainAfter(*current);
+
+            // Now we need to take all of the children starting from the first child
+            // *after* currentChild and append them all to the clone.
+            for (auto* sibling = currentChild->nextSibling(); sibling;) {
+                auto* next = sibling->nextSibling();
+                auto childToMove = current->takeChildInternal(*sibling);
+                cloneInline->addChildIgnoringContinuation(m_builder, WTFMove(childToMove));
+                sibling->setNeedsLayoutAndPrefWidthsRecalc();
+                sibling = next;
+            }
+        }
+
+        // Keep walking up the chain.
+        currentChild = current;
+        current = downcast<RenderBoxModelObject>(current->parent());
+        ++splitDepth;
+    }
+
+    // Clear the flow thread containing blocks cached during the detached state insertions.
+    for (auto& cloneBlockChild : childrenOfType<RenderBlock>(*cloneInline))
+        cloneBlockChild.resetEnclosingFragmentedFlowAndChildInfoIncludingDescendants();
+
+    // Now we are at the block level. We need to put the clone into the toBlock.
+    toBlock->insertChildInternal(WTFMove(cloneInline), nullptr);
+
+    // Now take all the children after currentChild and remove them from the fromBlock
+    // and put them in the toBlock.
+    for (auto* current = currentChild->nextSibling(); current;) {
+        auto* next = current->nextSibling();
+        auto childToMove = fromBlock->takeChildInternal(*current);
+        toBlock->insertChildInternal(WTFMove(childToMove), nullptr);
+        current = next;
+    }
+}
+
+}
+

Copied: trunk/Source/WebCore/rendering/updating/RenderTreeBuilderInline.h (from rev 226519, trunk/Source/WebCore/rendering/updating/RenderTreeBuilderTable.h) (0 => 226520)


--- trunk/Source/WebCore/rendering/updating/RenderTreeBuilderInline.h	                        (rev 0)
+++ trunk/Source/WebCore/rendering/updating/RenderTreeBuilderInline.h	2018-01-08 18:38:31 UTC (rev 226520)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "RenderTreeBuilder.h"
+
+namespace WebCore {
+
+class RenderTreeBuilder::Inline {
+public:
+    Inline(RenderTreeBuilder&);
+
+    void insertChild(RenderInline& parent, RenderPtr<RenderObject> child, RenderObject* beforeChild);
+    void insertChildIgnoringContinuation(RenderInline& parent, RenderPtr<RenderObject> child, RenderObject* beforeChild);
+
+    // Make this private once all the mutation code is in RenderTreeBuilder.
+    void splitFlow(RenderInline& parent, RenderObject* beforeChild, RenderPtr<RenderBlock> newBlockBox, RenderPtr<RenderObject> child, RenderBoxModelObject* oldCont);
+
+private:
+    void insertChildToContinuation(RenderInline& parent, RenderPtr<RenderObject> child, RenderObject* beforeChild);
+    void splitInlines(RenderInline& parent, RenderBlock* fromBlock, RenderBlock* toBlock, RenderBlock* middleBlock, RenderObject* beforeChild, RenderBoxModelObject* oldCont);
+
+    RenderTreeBuilder& m_builder;
+};
+
+}

Modified: trunk/Source/WebCore/rendering/updating/RenderTreeBuilderTable.h (226519 => 226520)


--- trunk/Source/WebCore/rendering/updating/RenderTreeBuilderTable.h	2018-01-08 18:37:37 UTC (rev 226519)
+++ trunk/Source/WebCore/rendering/updating/RenderTreeBuilderTable.h	2018-01-08 18:38:31 UTC (rev 226520)
@@ -31,6 +31,8 @@
 
 class RenderElement;
 class RenderObject;
+class RenderTable;
+class RenderTableSection;
 class RenderTableRow;
 class RenderTreeBuilder;
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to