Changeset 226520 in webkit
- Timestamp:
- Jan 8, 2018 10:38:31 AM (6 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 1 added
- 8 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r226516 r226520 1 2018-01-08 Zalan Bujtas <zalan@apple.com> 2 3 [RenderTreeBuilder] Move RenderInline addChild logic to RenderTreeBuilder 4 https://bugs.webkit.org/show_bug.cgi?id=181336 5 <rdar://problem/36324693> 6 7 Reviewed by Antti Koivisto. 8 9 This is about moving the code, no cleanup and/or normalization (unfortunately it also means 10 some temporary changes). 11 12 No change in functionality. 13 14 * Sources.txt: 15 * WebCore.xcodeproj/project.pbxproj: 16 * rendering/RenderInline.cpp: 17 (WebCore::RenderInline::addChild): 18 (WebCore::RenderInline::addChildIgnoringContinuation): 19 (WebCore::RenderInline::childBecameNonInline): 20 (WebCore::nextContinuation): Deleted. 21 (WebCore::RenderInline::continuationBefore): Deleted. 22 (WebCore::newChildIsInline): Deleted. 23 (WebCore::RenderInline::cloneAsContinuation const): Deleted. 24 (WebCore::RenderInline::splitInlines): Deleted. 25 (WebCore::RenderInline::splitFlow): Deleted. 26 (WebCore::canUseAsParentForContinuation): Deleted. 27 (WebCore::RenderInline::addChildToContinuation): Deleted. 28 * rendering/RenderInline.h: 29 * rendering/updating/RenderTreeBuilder.cpp: 30 (WebCore::RenderTreeBuilder::RenderTreeBuilder): 31 (WebCore::RenderTreeBuilder::insertChildToRenderInline): 32 (WebCore::RenderTreeBuilder::insertChildToRenderInlineIgnoringContinuation): 33 (WebCore::RenderTreeBuilder::splitFlow): 34 * rendering/updating/RenderTreeBuilder.h: 35 (WebCore::RenderTreeBuilder::inlineBuilder): 36 * rendering/updating/RenderTreeBuilderInline.cpp: Added. 37 (WebCore::canUseAsParentForContinuation): 38 (WebCore::nextContinuation): 39 (WebCore::continuationBefore): 40 (WebCore::cloneAsContinuation): 41 (WebCore::newChildIsInline): 42 (WebCore::inFlowPositionedInlineAncestor): 43 (WebCore::RenderTreeBuilder::Inline::Inline): 44 (WebCore::RenderTreeBuilder::Inline::insertChild): 45 (WebCore::RenderTreeBuilder::Inline::insertChildToContinuation): 46 (WebCore::RenderTreeBuilder::Inline::insertChildIgnoringContinuation): 47 (WebCore::RenderTreeBuilder::Inline::splitFlow): 48 (WebCore::RenderTreeBuilder::Inline::splitInlines): 49 * rendering/updating/RenderTreeBuilderInline.h: Added. 50 1 51 2018-01-08 Zalan Bujtas <zalan@apple.com> 2 52 -
trunk/Source/WebCore/Sources.txt
r226516 r226520 1988 1988 rendering/updating/RenderTreeBuilderFirstLetter.cpp 1989 1989 rendering/updating/RenderTreeBuilderFormControls.cpp 1990 rendering/updating/RenderTreeBuilderInline.cpp 1990 1991 rendering/updating/RenderTreeBuilderList.cpp 1991 1992 rendering/updating/RenderTreeBuilderMultiColumn.cpp -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r226516 r226520 1026 1026 417DA6DA13734E6E007C57FB /* Internals.h in Headers */ = {isa = PBXBuildFile; fileRef = 417DA4CE13734326007C57FB /* Internals.h */; }; 1027 1027 417DA71D13735DFA007C57FB /* JSInternals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 417DA71B13735DFA007C57FB /* JSInternals.cpp */; }; 1028 427DA71D13735DFA007C57FB /* JSServiceWorkerInternals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 427DA71B13735DFA007C57FB /* JSServiceWorkerInternals.cpp */; };1029 1028 417DA71E13735DFA007C57FB /* JSInternals.h in Headers */ = {isa = PBXBuildFile; fileRef = 417DA71C13735DFA007C57FB /* JSInternals.h */; }; 1030 427DA71E13735DFA007C57FB /* JSServiceWorkerInternals.h in Headers */ = {isa = PBXBuildFile; fileRef = 427DA71C13735DFA007C57FB /* JSServiceWorkerInternals.h */; };1031 1029 417F0D821FFEE979008EF303 /* ServiceWorkerInternals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 417F0D801FFEE14F008EF303 /* ServiceWorkerInternals.cpp */; }; 1032 1030 41815C1E138319830057AAA4 /* WebCoreTestSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41815C1C138319830057AAA4 /* WebCoreTestSupport.cpp */; }; … … 1065 1063 41F1D21F0EF35C2A00DA8753 /* ScriptCachedFrameData.h in Headers */ = {isa = PBXBuildFile; fileRef = 41F1D21D0EF35C2A00DA8753 /* ScriptCachedFrameData.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1066 1064 41FABD2D1F4DFE4A006A6C97 /* DOMCacheEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 41FABD2B1F4DFE42006A6C97 /* DOMCacheEngine.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1065 427DA71D13735DFA007C57FB /* JSServiceWorkerInternals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 427DA71B13735DFA007C57FB /* JSServiceWorkerInternals.cpp */; }; 1066 427DA71E13735DFA007C57FB /* JSServiceWorkerInternals.h in Headers */ = {isa = PBXBuildFile; fileRef = 427DA71C13735DFA007C57FB /* JSServiceWorkerInternals.h */; }; 1067 1067 43107BE218CC19DE00CC18E8 /* SelectorPseudoTypeMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 43107BE118CC19DE00CC18E8 /* SelectorPseudoTypeMap.h */; }; 1068 1068 431A2F9C13B6F2B0007791E4 /* SVGAnimatedNumberOptionalNumber.h in Headers */ = {isa = PBXBuildFile; fileRef = 431A2F9A13B6F2B0007791E4 /* SVGAnimatedNumberOptionalNumber.h */; }; … … 5592 5592 119340A01FEE024000935F1E /* RenderTreeBuilderBlock.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = RenderTreeBuilderBlock.cpp; sourceTree = "<group>"; }; 5593 5593 119340A11FEE024000935F1E /* RenderTreeBuilderBlock.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RenderTreeBuilderBlock.h; sourceTree = "<group>"; }; 5594 11C5F1162003E7750001AE60 /* RenderTreeBuilderInline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderTreeBuilderInline.cpp; sourceTree = "<group>"; }; 5595 11C5F1182003E7760001AE60 /* RenderTreeBuilderInline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderTreeBuilderInline.h; sourceTree = "<group>"; }; 5594 5596 11E067EB1E62461300162D16 /* SimpleLineLayoutCoverage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SimpleLineLayoutCoverage.cpp; sourceTree = "<group>"; }; 5595 5597 11E067ED1E6246E500162D16 /* SimpleLineLayoutCoverage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SimpleLineLayoutCoverage.h; sourceTree = "<group>"; }; … … 7032 7034 417DA6D013734E02007C57FB /* libWebCoreTestSupport.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libWebCoreTestSupport.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; 7033 7035 417DA71B13735DFA007C57FB /* JSInternals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSInternals.cpp; sourceTree = "<group>"; }; 7034 427DA71B13735DFA007C57FB /* JSServiceWorkerInternals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSServiceWorkerInternals.cpp; sourceTree = "<group>"; };7035 7036 417DA71C13735DFA007C57FB /* JSInternals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSInternals.h; sourceTree = "<group>"; }; 7036 427DA71C13735DFA007C57FB /* JSServiceWorkerInternals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSServiceWorkerInternals.h; sourceTree = "<group>"; };7037 7037 417F0D7E1FFEE14E008EF303 /* ServiceWorkerInternals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ServiceWorkerInternals.h; sourceTree = "<group>"; }; 7038 7038 417F0D801FFEE14F008EF303 /* ServiceWorkerInternals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ServiceWorkerInternals.cpp; sourceTree = "<group>"; }; … … 7146 7146 41FB27991F34CE9C00795487 /* CacheQueryOptions.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = CacheQueryOptions.idl; sourceTree = "<group>"; }; 7147 7147 41FB279B1F34CEF000795487 /* CacheQueryOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CacheQueryOptions.h; sourceTree = "<group>"; }; 7148 427DA71B13735DFA007C57FB /* JSServiceWorkerInternals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSServiceWorkerInternals.cpp; sourceTree = "<group>"; }; 7149 427DA71C13735DFA007C57FB /* JSServiceWorkerInternals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSServiceWorkerInternals.h; sourceTree = "<group>"; }; 7148 7150 43107BE118CC19DE00CC18E8 /* SelectorPseudoTypeMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SelectorPseudoTypeMap.h; sourceTree = "<group>"; }; 7149 7151 43142E7913B1E97700F1C871 /* SVGAnimatedRect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGAnimatedRect.cpp; sourceTree = "<group>"; }; … … 24636 24638 119340941FED715500935F1E /* RenderTreeBuilderFormControls.cpp */, 24637 24639 119340951FED715500935F1E /* RenderTreeBuilderFormControls.h */, 24640 11C5F1162003E7750001AE60 /* RenderTreeBuilderInline.cpp */, 24641 11C5F1182003E7760001AE60 /* RenderTreeBuilderInline.h */, 24638 24642 E47C392B1FE6E0DF00BBBC6B /* RenderTreeBuilderList.cpp */, 24639 24643 E47C39281FE6E0DD00BBBC6B /* RenderTreeBuilderList.h */, -
trunk/Source/WebCore/rendering/RenderInline.cpp
r226007 r226520 258 258 void RenderInline::addChild(RenderTreeBuilder& builder, RenderPtr<RenderObject> newChild, RenderObject* beforeChild) 259 259 { 260 auto* beforeChildOrPlaceholder = beforeChild; 261 if (auto* fragmentedFlow = enclosingFragmentedFlow()) 262 beforeChildOrPlaceholder = fragmentedFlow->resolveMovedChild(beforeChild); 263 if (continuation()) { 264 addChildToContinuation(builder, WTFMove(newChild), beforeChildOrPlaceholder); 265 return; 266 } 267 addChildIgnoringContinuation(builder, WTFMove(newChild), beforeChildOrPlaceholder); 268 } 269 270 static RenderBoxModelObject* nextContinuation(RenderObject* renderer) 271 { 272 if (is<RenderInline>(*renderer) && !renderer->isReplaced()) 273 return downcast<RenderInline>(*renderer).continuation(); 274 return downcast<RenderBlock>(*renderer).inlineContinuation(); 275 } 276 277 RenderBoxModelObject* RenderInline::continuationBefore(RenderObject* beforeChild) 278 { 279 if (beforeChild && beforeChild->parent() == this) 280 return this; 281 282 RenderBoxModelObject* curr = nextContinuation(this); 283 RenderBoxModelObject* nextToLast = this; 284 RenderBoxModelObject* last = this; 285 while (curr) { 286 if (beforeChild && beforeChild->parent() == curr) { 287 if (curr->firstChild() == beforeChild) 288 return last; 289 return curr; 290 } 291 292 nextToLast = last; 293 last = curr; 294 curr = nextContinuation(curr); 295 } 296 297 if (!beforeChild && !last->firstChild()) 298 return nextToLast; 299 return last; 300 } 301 302 static bool newChildIsInline(const RenderObject& newChild, const RenderInline& parent) 303 { 304 // inline parent generates inline-table. 305 return newChild.isInline() | (parent.childRequiresTable(newChild) && parent.style().display() == INLINE); 260 builder.insertChildToRenderInline(*this, WTFMove(newChild), beforeChild); 306 261 } 307 262 308 263 void RenderInline::addChildIgnoringContinuation(RenderTreeBuilder& builder, RenderPtr<RenderObject> newChild, RenderObject* beforeChild) 309 264 { 310 // Make sure we don't append things after :after-generated content if we have it. 311 if (!beforeChild && isAfterContent(lastChild())) 312 beforeChild = lastChild(); 313 314 bool childInline = newChildIsInline(*newChild, *this); 315 // This code is for the old block-inside-inline model that uses continuations. 316 if (!childInline && !newChild->isFloatingOrOutOfFlowPositioned()) { 317 // We are placing a block inside an inline. We have to perform a split of this 318 // inline into continuations. This involves creating an anonymous block box to hold 319 // |newChild|. We then make that block box a continuation of this inline. We take all of 320 // the children after |beforeChild| and put them in a clone of this object. 321 auto newStyle = RenderStyle::createAnonymousStyleWithDisplay(style(), BLOCK); 322 323 // If inside an inline affected by in-flow positioning the block needs to be affected by it too. 324 // Giving the block a layer like this allows it to collect the x/y offsets from inline parents later. 325 if (auto positionedAncestor = inFlowPositionedInlineAncestor(this)) 326 newStyle.setPosition(positionedAncestor->style().position()); 327 328 auto newBox = createRenderer<RenderBlockFlow>(document(), WTFMove(newStyle)); 329 newBox->initializeStyle(); 330 newBox->setIsContinuation(); 331 RenderBoxModelObject* oldContinuation = continuation(); 332 if (oldContinuation) 333 oldContinuation->removeFromContinuationChain(); 334 newBox->insertIntoContinuationChainAfter(*this); 335 336 splitFlow(builder, beforeChild, WTFMove(newBox), WTFMove(newChild), oldContinuation); 337 return; 338 } 339 340 auto& child = *newChild; 341 RenderBoxModelObject::addChild(builder, WTFMove(newChild), beforeChild); 342 child.setNeedsLayoutAndPrefWidthsRecalc(); 343 } 344 345 RenderPtr<RenderInline> RenderInline::cloneAsContinuation() const 346 { 347 RenderPtr<RenderInline> cloneInline = createRenderer<RenderInline>(*element(), RenderStyle::clone(style())); 348 cloneInline->initializeStyle(); 349 cloneInline->setFragmentedFlowState(fragmentedFlowState()); 350 cloneInline->setHasOutlineAutoAncestor(hasOutlineAutoAncestor()); 351 cloneInline->setIsContinuation(); 352 return cloneInline; 353 } 354 355 void RenderInline::splitInlines(RenderTreeBuilder& builder, RenderBlock* fromBlock, RenderBlock* toBlock, 356 RenderBlock* middleBlock, 357 RenderObject* beforeChild, RenderBoxModelObject* oldCont) 358 { 359 // Create a clone of this inline. 360 RenderPtr<RenderInline> cloneInline = cloneAsContinuation(); 361 #if ENABLE(FULLSCREEN_API) 362 // If we're splitting the inline containing the fullscreened element, 363 // |beforeChild| may be the renderer for the fullscreened element. However, 364 // that renderer is wrapped in a RenderFullScreen, so |this| is not its 365 // parent. Since the splitting logic expects |this| to be the parent, set 366 // |beforeChild| to be the RenderFullScreen. 367 const Element* fullScreenElement = document().webkitCurrentFullScreenElement(); 368 if (fullScreenElement && beforeChild && beforeChild->node() == fullScreenElement) 369 beforeChild = document().fullScreenRenderer(); 370 #endif 371 // Now take all of the children from beforeChild to the end and remove 372 // them from |this| and place them in the clone. 373 for (RenderObject* rendererToMove = beforeChild; rendererToMove;) { 374 RenderObject* nextSibling = rendererToMove->nextSibling(); 375 // When anonymous wrapper is present, we might need to move the whole subtree instead. 376 if (rendererToMove->parent() != this) { 377 auto* anonymousParent = rendererToMove->parent(); 378 while (anonymousParent && anonymousParent->parent() != this) { 379 ASSERT(anonymousParent->isAnonymous()); 380 anonymousParent = anonymousParent->parent(); 381 } 382 if (!anonymousParent) { 383 ASSERT_NOT_REACHED(); 384 break; 385 } 386 // If beforeChild is the first child in the subtree, we could just move the whole subtree. 387 if (!rendererToMove->previousSibling()) { 388 // Reparent the whole anonymous wrapper tree. 389 rendererToMove = anonymousParent; 390 // Skip to the next sibling that is not in this subtree. 391 nextSibling = anonymousParent->nextSibling(); 392 } else if (!rendererToMove->nextSibling()) { 393 // This is the last renderer in the subtree. We need to jump out of the wrapper subtree, so that 394 // the siblings are getting reparented too. 395 nextSibling = anonymousParent->nextSibling(); 396 } 397 // Otherwise just move the renderer to the inline clone. Should the renderer need an anon 398 // wrapper, the addChild() will generate one for it. 399 // FIXME: When the anonymous wrapper has multiple children, we end up traversing up to the topmost wrapper 400 // every time, which is a bit wasteful. 401 } 402 auto childToMove = rendererToMove->parent()->takeChildInternal(*rendererToMove); 403 cloneInline->addChildIgnoringContinuation(builder, WTFMove(childToMove)); 404 rendererToMove->setNeedsLayoutAndPrefWidthsRecalc(); 405 rendererToMove = nextSibling; 406 } 407 // Hook |clone| up as the continuation of the middle block. 408 cloneInline->insertIntoContinuationChainAfter(*middleBlock); 409 if (oldCont) 410 oldCont->insertIntoContinuationChainAfter(*cloneInline); 411 412 // We have been reparented and are now under the fromBlock. We need 413 // to walk up our inline parent chain until we hit the containing block. 414 // Once we hit the containing block we're done. 415 RenderBoxModelObject* current = downcast<RenderBoxModelObject>(parent()); 416 RenderBoxModelObject* currentChild = this; 417 418 // FIXME: Because splitting is O(n^2) as tags nest pathologically, we cap the depth at which we're willing to clone. 419 // There will eventually be a better approach to this problem that will let us nest to a much 420 // greater depth (see bugzilla bug 13430) but for now we have a limit. This *will* result in 421 // incorrect rendering, but the alternative is to hang forever. 422 unsigned splitDepth = 1; 423 const unsigned cMaxSplitDepth = 200; 424 while (current && current != fromBlock) { 425 if (splitDepth < cMaxSplitDepth) { 426 // Create a new clone. 427 RenderPtr<RenderInline> cloneChild = WTFMove(cloneInline); 428 cloneInline = downcast<RenderInline>(*current).cloneAsContinuation(); 429 430 // Insert our child clone as the first child. 431 cloneInline->addChildIgnoringContinuation(builder, WTFMove(cloneChild)); 432 433 // Hook the clone up as a continuation of |curr|. 434 cloneInline->insertIntoContinuationChainAfter(*current); 435 436 // Now we need to take all of the children starting from the first child 437 // *after* currentChild and append them all to the clone. 438 for (auto* sibling = currentChild->nextSibling(); sibling;) { 439 auto* next = sibling->nextSibling(); 440 auto childToMove = current->takeChildInternal(*sibling); 441 cloneInline->addChildIgnoringContinuation(builder, WTFMove(childToMove)); 442 sibling->setNeedsLayoutAndPrefWidthsRecalc(); 443 sibling = next; 444 } 445 } 446 447 // Keep walking up the chain. 448 currentChild = current; 449 current = downcast<RenderBoxModelObject>(current->parent()); 450 ++splitDepth; 451 } 452 453 // Clear the flow thread containing blocks cached during the detached state insertions. 454 for (auto& cloneBlockChild : childrenOfType<RenderBlock>(*cloneInline)) 455 cloneBlockChild.resetEnclosingFragmentedFlowAndChildInfoIncludingDescendants(); 456 457 // Now we are at the block level. We need to put the clone into the toBlock. 458 toBlock->insertChildInternal(WTFMove(cloneInline), nullptr); 459 460 // Now take all the children after currentChild and remove them from the fromBlock 461 // and put them in the toBlock. 462 for (auto* current = currentChild->nextSibling(); current;) { 463 auto* next = current->nextSibling(); 464 auto childToMove = fromBlock->takeChildInternal(*current); 465 toBlock->insertChildInternal(WTFMove(childToMove), nullptr); 466 current = next; 467 } 468 } 469 470 void RenderInline::splitFlow(RenderTreeBuilder& builder, RenderObject* beforeChild, RenderPtr<RenderBlock> newBlockBox, RenderPtr<RenderObject> newChild, RenderBoxModelObject* oldCont) 471 { 472 auto& addedBlockBox = *newBlockBox; 473 RenderBlock* pre = nullptr; 474 RenderBlock* block = containingBlock(); 475 476 // Delete our line boxes before we do the inline split into continuations. 477 block->deleteLines(); 478 479 RenderPtr<RenderBlock> createdPre; 480 bool madeNewBeforeBlock = false; 481 if (block->isAnonymousBlock() && (!block->parent() || !block->parent()->createsAnonymousWrapper())) { 482 // We can reuse this block and make it the preBlock of the next continuation. 483 pre = block; 484 pre->removePositionedObjects(nullptr); 485 // FIXME-BLOCKFLOW: The enclosing method should likely be switched over 486 // to only work on RenderBlockFlow, in which case this conversion can be 487 // removed. 488 if (is<RenderBlockFlow>(*pre)) 489 downcast<RenderBlockFlow>(*pre).removeFloatingObjects(); 490 block = block->containingBlock(); 491 } else { 492 // No anonymous block available for use. Make one. 493 createdPre = block->createAnonymousBlock(); 494 pre = createdPre.get(); 495 madeNewBeforeBlock = true; 496 } 497 498 auto createdPost = pre->createAnonymousBoxWithSameTypeAs(*block); 499 auto& post = downcast<RenderBlock>(*createdPost); 500 501 RenderObject* boxFirst = madeNewBeforeBlock ? block->firstChild() : pre->nextSibling(); 502 if (createdPre) 503 block->insertChildInternal(WTFMove(createdPre), boxFirst); 504 block->insertChildInternal(WTFMove(newBlockBox), boxFirst); 505 block->insertChildInternal(WTFMove(createdPost), boxFirst); 506 block->setChildrenInline(false); 507 508 if (madeNewBeforeBlock) { 509 RenderObject* o = boxFirst; 510 while (o) { 511 RenderObject* no = o; 512 o = no->nextSibling(); 513 auto childToMove = block->takeChildInternal(*no); 514 pre->insertChildInternal(WTFMove(childToMove), nullptr); 515 no->setNeedsLayoutAndPrefWidthsRecalc(); 516 } 517 } 518 519 splitInlines(builder, pre, &post, &addedBlockBox, beforeChild, oldCont); 520 521 // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting 522 // time in makeChildrenNonInline by just setting this explicitly up front. 523 addedBlockBox.setChildrenInline(false); 524 525 // We delayed adding the newChild until now so that the |newBlockBox| would be fully 526 // connected, thus allowing newChild access to a renderArena should it need 527 // to wrap itself in additional boxes (e.g., table construction). 528 builder.insertChild(addedBlockBox, WTFMove(newChild)); 529 530 // Always just do a full layout in order to ensure that line boxes (especially wrappers for images) 531 // get deleted properly. Because objects moves from the pre block into the post block, we want to 532 // make new line boxes instead of leaving the old line boxes around. 533 pre->setNeedsLayoutAndPrefWidthsRecalc(); 534 block->setNeedsLayoutAndPrefWidthsRecalc(); 535 post.setNeedsLayoutAndPrefWidthsRecalc(); 536 } 537 538 static bool canUseAsParentForContinuation(const RenderObject* renderer) 539 { 540 if (!renderer) 541 return false; 542 if (!is<RenderBlock>(renderer) && renderer->isAnonymous()) 543 return false; 544 if (is<RenderTable>(renderer)) 545 return false; 546 return true; 547 } 548 549 void RenderInline::addChildToContinuation(RenderTreeBuilder& builder, RenderPtr<RenderObject> newChild, RenderObject* beforeChild) 550 { 551 auto* flow = continuationBefore(beforeChild); 552 // It may or may not be the direct parent of the beforeChild. 553 RenderBoxModelObject* beforeChildAncestor = nullptr; 554 if (!beforeChild) { 555 auto* continuation = nextContinuation(flow); 556 beforeChildAncestor = continuation ? continuation : flow; 557 } else if (canUseAsParentForContinuation(beforeChild->parent())) 558 beforeChildAncestor = downcast<RenderBoxModelObject>(beforeChild->parent()); 559 else if (beforeChild->parent()) { 560 // In case of anonymous wrappers, the parent of the beforeChild is mostly irrelevant. What we need is the topmost wrapper. 561 auto* parent = beforeChild->parent(); 562 while (parent && parent->parent() && parent->parent()->isAnonymous()) { 563 // The ancestor candidate needs to be inside the continuation. 564 if (parent->isContinuation()) 565 break; 566 parent = parent->parent(); 567 } 568 ASSERT(parent && parent->parent()); 569 beforeChildAncestor = downcast<RenderBoxModelObject>(parent->parent()); 570 } else 571 ASSERT_NOT_REACHED(); 572 573 if (newChild->isFloatingOrOutOfFlowPositioned()) 574 return beforeChildAncestor->addChildIgnoringContinuation(builder, WTFMove(newChild), beforeChild); 575 576 if (flow == beforeChildAncestor) 577 return flow->addChildIgnoringContinuation(builder, WTFMove(newChild), beforeChild); 578 // A continuation always consists of two potential candidates: an inline or an anonymous 579 // block box holding block children. 580 bool childInline = newChildIsInline(*newChild, *this); 581 // The goal here is to match up if we can, so that we can coalesce and create the 582 // minimal # of continuations needed for the inline. 583 if (childInline == beforeChildAncestor->isInline()) 584 return beforeChildAncestor->addChildIgnoringContinuation(builder, WTFMove(newChild), beforeChild); 585 if (flow->isInline() == childInline) 586 return flow->addChildIgnoringContinuation(builder, WTFMove(newChild)); // Just treat like an append. 587 return beforeChildAncestor->addChildIgnoringContinuation(builder, WTFMove(newChild), beforeChild); 265 builder.insertChildToRenderInlineIgnoringContinuation(*this, WTFMove(newChild), beforeChild); 588 266 } 589 267 … … 1370 1048 RenderObject* beforeChild = child.nextSibling(); 1371 1049 auto removedChild = takeChildInternal(child); 1372 splitFlow(*RenderTreeBuilder::current(), beforeChild, WTFMove(newBox), WTFMove(removedChild), oldContinuation);1050 RenderTreeBuilder::current()->splitFlow(*this, beforeChild, WTFMove(newBox), WTFMove(removedChild), oldContinuation); 1373 1051 } 1374 1052 -
trunk/Source/WebCore/rendering/RenderInline.h
r226007 r226520 95 95 bool hitTestCulledInline(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset); 96 96 97 void addChildIgnoringContinuation(RenderTreeBuilder&, RenderPtr<RenderObject> newChild, RenderObject* beforeChild = nullptr) final; 98 97 99 protected: 98 100 void willBeDestroyed() override; … … 116 118 template<typename GeneratorContext> 117 119 void generateCulledLineBoxRects(GeneratorContext& yield, const RenderInline* container) const; 118 119 void addChildToContinuation(RenderTreeBuilder&, RenderPtr<RenderObject> newChild, RenderObject* beforeChild);120 void addChildIgnoringContinuation(RenderTreeBuilder&, RenderPtr<RenderObject> newChild, RenderObject* beforeChild = nullptr) final;121 122 void splitInlines(RenderTreeBuilder&, RenderBlock* fromBlock, RenderBlock* toBlock, RenderBlock* middleBlock, RenderObject* beforeChild, RenderBoxModelObject* oldCont);123 void splitFlow(RenderTreeBuilder&, RenderObject* beforeChild, RenderPtr<RenderBlock> newBlockBox, RenderPtr<RenderObject> newChild, RenderBoxModelObject* oldCont);124 120 125 121 void layout() final { ASSERT_NOT_REACHED(); } // Do nothing for layout() … … 163 159 void addAnnotatedRegions(Vector<AnnotatedRegionValue>&) final; 164 160 #endif 165 166 RenderPtr<RenderInline> cloneAsContinuation() const;167 161 168 162 void paintOutlineForLine(GraphicsContext&, const LayoutPoint&, const LayoutRect& prevLine, const LayoutRect& thisLine, const LayoutRect& nextLine, const Color&); 169 RenderBoxModelObject* continuationBefore(RenderObject* beforeChild);170 163 171 164 bool willChangeCreatesStackingContext() const -
trunk/Source/WebCore/rendering/updating/RenderTreeBuilder.cpp
r226516 r226520 37 37 #include "RenderTreeBuilderFirstLetter.h" 38 38 #include "RenderTreeBuilderFormControls.h" 39 #include "RenderTreeBuilderInline.h" 39 40 #include "RenderTreeBuilderList.h" 40 41 #include "RenderTreeBuilderMultiColumn.h" … … 108 109 , m_formControlsBuilder(std::make_unique<FormControls>(*this)) 109 110 , m_blockBuilder(std::make_unique<Block>(*this)) 111 , m_inlineBuilder(std::make_unique<Inline>(*this)) 110 112 { 111 113 RELEASE_ASSERT(!s_current || &m_view != &s_current->m_view); … … 273 275 } 274 276 277 void RenderTreeBuilder::insertChildToRenderInline(RenderInline& parent, RenderPtr<RenderObject> child, RenderObject* beforeChild) 278 { 279 inlineBuilder().insertChild(parent, WTFMove(child), beforeChild); 280 } 281 282 void RenderTreeBuilder::insertChildToRenderInlineIgnoringContinuation(RenderInline& parent, RenderPtr<RenderObject> child, RenderObject* beforeChild) 283 { 284 inlineBuilder().insertChildIgnoringContinuation(parent, WTFMove(child), beforeChild); 285 } 286 287 void RenderTreeBuilder::splitFlow(RenderInline& parent, RenderObject* beforeChild, RenderPtr<RenderBlock> newBlockBox, RenderPtr<RenderObject> child, RenderBoxModelObject* oldCont) 288 { 289 inlineBuilder().splitFlow(parent, beforeChild, WTFMove(newBlockBox), WTFMove(child), oldCont); 290 } 291 275 292 void RenderTreeBuilder::updateAfterDescendants(RenderElement& renderer) 276 293 { -
trunk/Source/WebCore/rendering/updating/RenderTreeBuilder.h
r226516 r226520 53 53 RenderObject* splitAnonymousBoxesAroundChild(RenderBox& parent, RenderObject* beforeChild); 54 54 55 // These functions are temporary until after all block/inline/continuation code is moved over. 56 void insertChildToRenderInline(RenderInline& parent, RenderPtr<RenderObject>, RenderObject* beforeChild = nullptr); 57 void insertChildToRenderInlineIgnoringContinuation(RenderInline& parent, RenderPtr<RenderObject>, RenderObject* beforeChild = nullptr); 58 void splitFlow(RenderInline& parent, RenderObject* beforeChild, RenderPtr<RenderBlock> newBlockBox, RenderPtr<RenderObject> child, RenderBoxModelObject* oldCont); 59 55 60 private: 56 61 class FirstLetter; … … 61 66 class FormControls; 62 67 class Block; 68 class Inline; 63 69 64 70 FirstLetter& firstLetterBuilder() { return *m_firstLetterBuilder; } … … 69 75 FormControls& formControlsBuilder() { return *m_formControlsBuilder; } 70 76 Block& blockBuilder() { return *m_blockBuilder; } 77 Inline& inlineBuilder() { return *m_inlineBuilder; } 71 78 72 79 RenderView& m_view; … … 82 89 std::unique_ptr<FormControls> m_formControlsBuilder; 83 90 std::unique_ptr<Block> m_blockBuilder; 91 std::unique_ptr<Inline> m_inlineBuilder; 84 92 }; 85 93 -
trunk/Source/WebCore/rendering/updating/RenderTreeBuilderInline.h
r226519 r226520 1 1 /* 2 * Copyright (C) 201 7Apple Inc. All rights reserved.2 * Copyright (C) 2018 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 26 26 #pragma once 27 27 28 #include "RenderTree Updater.h"28 #include "RenderTreeBuilder.h" 29 29 30 30 namespace WebCore { 31 31 32 class RenderElement; 33 class RenderObject; 34 class RenderTableRow; 35 class RenderTreeBuilder; 32 class RenderTreeBuilder::Inline { 33 public: 34 Inline(RenderTreeBuilder&); 36 35 37 class RenderTreeBuilder::Table { 38 public: 39 Table(RenderTreeBuilder&); 36 void insertChild(RenderInline& parent, RenderPtr<RenderObject> child, RenderObject* beforeChild); 37 void insertChildIgnoringContinuation(RenderInline& parent, RenderPtr<RenderObject> child, RenderObject* beforeChild); 40 38 41 RenderElement& findOrCreateParentForChild(RenderTableRow& parent, const RenderObject& child, RenderObject*& beforeChild); 42 RenderElement& findOrCreateParentForChild(RenderTableSection& parent, const RenderObject& child, RenderObject*& beforeChild); 43 RenderElement& findOrCreateParentForChild(RenderTable& parent, const RenderObject& child, RenderObject*& beforeChild); 39 // Make this private once all the mutation code is in RenderTreeBuilder. 40 void splitFlow(RenderInline& parent, RenderObject* beforeChild, RenderPtr<RenderBlock> newBlockBox, RenderPtr<RenderObject> child, RenderBoxModelObject* oldCont); 44 41 45 42 private: 43 void insertChildToContinuation(RenderInline& parent, RenderPtr<RenderObject> child, RenderObject* beforeChild); 44 void splitInlines(RenderInline& parent, RenderBlock* fromBlock, RenderBlock* toBlock, RenderBlock* middleBlock, RenderObject* beforeChild, RenderBoxModelObject* oldCont); 45 46 46 RenderTreeBuilder& m_builder; 47 47 }; -
trunk/Source/WebCore/rendering/updating/RenderTreeBuilderTable.h
r226181 r226520 32 32 class RenderElement; 33 33 class RenderObject; 34 class RenderTable; 35 class RenderTableSection; 34 36 class RenderTableRow; 35 37 class RenderTreeBuilder;
Note: See TracChangeset
for help on using the changeset viewer.