| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
| 4 * (C) 2007 David Smith (catfish.man@gmail.com) | 4 * (C) 2007 David Smith (catfish.man@gmail.com) |
| 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc.
All rights reserved. | 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc.
All rights reserved. |
| 6 * Copyright (C) Research In Motion Limited 2010. All rights reserved. | 6 * Copyright (C) Research In Motion Limited 2010. All rights reserved. |
| 7 * | 7 * |
| 8 * This library is free software; you can redistribute it and/or | 8 * This library is free software; you can redistribute it and/or |
| 9 * modify it under the terms of the GNU Library General Public | 9 * modify it under the terms of the GNU Library General Public |
| 10 * License as published by the Free Software Foundation; either | 10 * License as published by the Free Software Foundation; either |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 }; | 67 }; |
| 68 | 68 |
| 69 COMPILE_ASSERT(sizeof(RenderBlock) == sizeof(SameSizeAsRenderBlock), RenderBlock
_should_stay_small); | 69 COMPILE_ASSERT(sizeof(RenderBlock) == sizeof(SameSizeAsRenderBlock), RenderBlock
_should_stay_small); |
| 70 | 70 |
| 71 static TrackedDescendantsMap* gPositionedDescendantsMap = 0; | 71 static TrackedDescendantsMap* gPositionedDescendantsMap = 0; |
| 72 static TrackedDescendantsMap* gPercentHeightDescendantsMap = 0; | 72 static TrackedDescendantsMap* gPercentHeightDescendantsMap = 0; |
| 73 | 73 |
| 74 static TrackedContainerMap* gPositionedContainerMap = 0; | 74 static TrackedContainerMap* gPositionedContainerMap = 0; |
| 75 static TrackedContainerMap* gPercentHeightContainerMap = 0; | 75 static TrackedContainerMap* gPercentHeightContainerMap = 0; |
| 76 | 76 |
| 77 typedef WTF::HashMap<RenderBlock*, OwnPtr<ListHashSet<RenderInline*> > > Continu
ationOutlineTableMap; | |
| 78 | |
| 79 typedef WTF::HashSet<RenderBlock*> DelayedUpdateScrollInfoSet; | 77 typedef WTF::HashSet<RenderBlock*> DelayedUpdateScrollInfoSet; |
| 80 static int gDelayUpdateScrollInfo = 0; | 78 static int gDelayUpdateScrollInfo = 0; |
| 81 static DelayedUpdateScrollInfoSet* gDelayedUpdateScrollInfoSet = 0; | 79 static DelayedUpdateScrollInfoSet* gDelayedUpdateScrollInfoSet = 0; |
| 82 | 80 |
| 83 RenderBlock::RenderBlock(ContainerNode* node) | 81 RenderBlock::RenderBlock(ContainerNode* node) |
| 84 : RenderBox(node) | 82 : RenderBox(node) |
| 85 , m_hasMarginBeforeQuirk(false) | 83 , m_hasMarginBeforeQuirk(false) |
| 86 , m_hasMarginAfterQuirk(false) | 84 , m_hasMarginAfterQuirk(false) |
| 87 , m_beingDestroyed(false) | 85 , m_beingDestroyed(false) |
| 88 , m_hasMarkupTruncation(false) | 86 , m_hasMarkupTruncation(false) |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 | 131 |
| 134 void RenderBlock::willBeDestroyed() | 132 void RenderBlock::willBeDestroyed() |
| 135 { | 133 { |
| 136 // Mark as being destroyed to avoid trouble with merges in removeChild(). | 134 // Mark as being destroyed to avoid trouble with merges in removeChild(). |
| 137 m_beingDestroyed = true; | 135 m_beingDestroyed = true; |
| 138 | 136 |
| 139 // Make sure to destroy anonymous children first while they are still connec
ted to the rest of the tree, so that they will | 137 // Make sure to destroy anonymous children first while they are still connec
ted to the rest of the tree, so that they will |
| 140 // properly dirty line boxes that they are removed from. Effects that do :be
fore/:after only on hover could crash otherwise. | 138 // properly dirty line boxes that they are removed from. Effects that do :be
fore/:after only on hover could crash otherwise. |
| 141 children()->destroyLeftoverChildren(); | 139 children()->destroyLeftoverChildren(); |
| 142 | 140 |
| 143 // Destroy our continuation before anything other than anonymous children. | |
| 144 // The reason we don't destroy it before anonymous children is that they may | |
| 145 // have continuations of their own that are anonymous children of our contin
uation. | |
| 146 RenderBoxModelObject* continuation = this->continuation(); | |
| 147 if (continuation) { | |
| 148 continuation->destroy(); | |
| 149 setContinuation(0); | |
| 150 } | |
| 151 | |
| 152 if (!documentBeingDestroyed()) { | 141 if (!documentBeingDestroyed()) { |
| 153 if (firstLineBox()) { | 142 if (firstLineBox()) { |
| 154 // We can't wait for RenderBox::destroy to clear the selection, | 143 // We can't wait for RenderBox::destroy to clear the selection, |
| 155 // because by then we will have nuked the line boxes. | 144 // because by then we will have nuked the line boxes. |
| 156 // FIXME: The FrameSelection should be responsible for this when it | 145 // FIXME: The FrameSelection should be responsible for this when it |
| 157 // is notified of DOM mutations. | 146 // is notified of DOM mutations. |
| 158 if (isSelectionBorder()) | 147 if (isSelectionBorder()) |
| 159 view()->clearSelection(); | 148 view()->clearSelection(); |
| 160 | 149 |
| 161 // If we are an anonymous block, then our line boxes might have chil
dren | 150 // If we are an anonymous block, then our line boxes might have chil
dren |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 219 || oldStyle->borderRightWidth() != newStyle->borderRightWidth() | 208 || oldStyle->borderRightWidth() != newStyle->borderRightWidth() |
| 220 || oldStyle->paddingLeft() != newStyle->paddingLeft() | 209 || oldStyle->paddingLeft() != newStyle->paddingLeft() |
| 221 || oldStyle->paddingRight() != newStyle->paddingRight(); | 210 || oldStyle->paddingRight() != newStyle->paddingRight(); |
| 222 } | 211 } |
| 223 | 212 |
| 224 void RenderBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldSty
le) | 213 void RenderBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldSty
le) |
| 225 { | 214 { |
| 226 RenderBox::styleDidChange(diff, oldStyle); | 215 RenderBox::styleDidChange(diff, oldStyle); |
| 227 | 216 |
| 228 RenderStyle* newStyle = style(); | 217 RenderStyle* newStyle = style(); |
| 229 | |
| 230 if (!isAnonymousBlock()) { | |
| 231 // Ensure that all of our continuation blocks pick up the new style. | |
| 232 for (RenderBlock* currCont = blockElementContinuation(); currCont; currC
ont = currCont->blockElementContinuation()) { | |
| 233 RenderBoxModelObject* nextCont = currCont->continuation(); | |
| 234 currCont->setContinuation(0); | |
| 235 currCont->setStyle(newStyle); | |
| 236 currCont->setContinuation(nextCont); | |
| 237 } | |
| 238 } | |
| 239 | |
| 240 propagateStyleToAnonymousChildren(true); | 218 propagateStyleToAnonymousChildren(true); |
| 241 | 219 |
| 242 // It's possible for our border/padding to change, but for the overall logic
al width of the block to | 220 // It's possible for our border/padding to change, but for the overall logic
al width of the block to |
| 243 // end up being the same. We keep track of this change so in layoutBlock, we
can know to set relayoutChildren=true. | 221 // end up being the same. We keep track of this change so in layoutBlock, we
can know to set relayoutChildren=true. |
| 244 m_hasBorderOrPaddingLogicalWidthChanged = oldStyle && diff.needsFullLayout()
&& needsLayout() && borderOrPaddingLogicalWidthChanged(oldStyle, newStyle); | 222 m_hasBorderOrPaddingLogicalWidthChanged = oldStyle && diff.needsFullLayout()
&& needsLayout() && borderOrPaddingLogicalWidthChanged(oldStyle, newStyle); |
| 245 } | 223 } |
| 246 | 224 |
| 247 void RenderBlock::invalidateTreeIfNeeded(const PaintInvalidationState& paintInva
lidationState) | 225 void RenderBlock::invalidateTreeIfNeeded(const PaintInvalidationState& paintInva
lidationState) |
| 248 { | 226 { |
| 249 // Note, we don't want to early out here using shouldCheckForInvalidationAft
erLayout as | 227 // Note, we don't want to early out here using shouldCheckForInvalidationAft
erLayout as |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 box->invalidateTreeIfNeeded(disabledPaintInvalidationState); | 267 box->invalidateTreeIfNeeded(disabledPaintInvalidationState); |
| 290 continue; | 268 continue; |
| 291 } | 269 } |
| 292 } | 270 } |
| 293 | 271 |
| 294 box->invalidateTreeIfNeeded(childPaintInvalidationState); | 272 box->invalidateTreeIfNeeded(childPaintInvalidationState); |
| 295 } | 273 } |
| 296 } | 274 } |
| 297 } | 275 } |
| 298 | 276 |
| 299 RenderBlock* RenderBlock::continuationBefore(RenderObject* beforeChild) | |
| 300 { | |
| 301 if (beforeChild && beforeChild->parent() == this) | |
| 302 return this; | |
| 303 | |
| 304 RenderBlock* curr = toRenderBlock(continuation()); | |
| 305 RenderBlock* nextToLast = this; | |
| 306 RenderBlock* last = this; | |
| 307 while (curr) { | |
| 308 if (beforeChild && beforeChild->parent() == curr) { | |
| 309 if (curr->firstChild() == beforeChild) | |
| 310 return last; | |
| 311 return curr; | |
| 312 } | |
| 313 | |
| 314 nextToLast = last; | |
| 315 last = curr; | |
| 316 curr = toRenderBlock(curr->continuation()); | |
| 317 } | |
| 318 | |
| 319 if (!beforeChild && !last->firstChild()) | |
| 320 return nextToLast; | |
| 321 return last; | |
| 322 } | |
| 323 | |
| 324 void RenderBlock::addChildToContinuation(RenderObject* newChild, RenderObject* b
eforeChild) | |
| 325 { | |
| 326 RenderBlock* flow = continuationBefore(beforeChild); | |
| 327 ASSERT(!beforeChild || beforeChild->parent()->isRenderBlock()); | |
| 328 RenderBoxModelObject* beforeChildParent = 0; | |
| 329 if (beforeChild) | |
| 330 beforeChildParent = toRenderBoxModelObject(beforeChild->parent()); | |
| 331 else { | |
| 332 RenderBoxModelObject* cont = flow->continuation(); | |
| 333 if (cont) | |
| 334 beforeChildParent = cont; | |
| 335 else | |
| 336 beforeChildParent = flow; | |
| 337 } | |
| 338 | |
| 339 if (newChild->isFloatingOrOutOfFlowPositioned()) { | |
| 340 beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild); | |
| 341 return; | |
| 342 } | |
| 343 | |
| 344 if (flow == beforeChildParent) { | |
| 345 flow->addChildIgnoringContinuation(newChild, beforeChild); | |
| 346 return; | |
| 347 } | |
| 348 | |
| 349 beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild); | |
| 350 } | |
| 351 | |
| 352 RenderBlock* RenderBlock::clone() const | |
| 353 { | |
| 354 RenderBlock* cloneBlock; | |
| 355 if (isAnonymousBlock()) { | |
| 356 cloneBlock = createAnonymousBlock(); | |
| 357 cloneBlock->setChildrenInline(childrenInline()); | |
| 358 } else { | |
| 359 RenderObject* cloneRenderer = toElement(node())->createRenderer(style())
; | |
| 360 cloneBlock = toRenderBlock(cloneRenderer); | |
| 361 cloneBlock->setStyle(style()); | |
| 362 | |
| 363 // This takes care of setting the right value of childrenInline in case | |
| 364 // generated content is added to cloneBlock and 'this' does not have | |
| 365 // generated content added yet. | |
| 366 cloneBlock->setChildrenInline(cloneBlock->firstChild() ? cloneBlock->fir
stChild()->isInline() : childrenInline()); | |
| 367 } | |
| 368 return cloneBlock; | |
| 369 } | |
| 370 | |
| 371 void RenderBlock::splitBlocks(RenderBlock* fromBlock, RenderBlock* toBlock, | |
| 372 RenderBlock* middleBlock, | |
| 373 RenderObject* beforeChild, RenderBoxModelObject* o
ldCont) | |
| 374 { | |
| 375 // Create a clone of this inline. | |
| 376 RenderBlock* cloneBlock = clone(); | |
| 377 if (!isAnonymousBlock()) | |
| 378 cloneBlock->setContinuation(oldCont); | |
| 379 | |
| 380 // If we are moving inline children from |this| to cloneBlock, then we need | |
| 381 // to clear our line box tree. | |
| 382 if (beforeChild && childrenInline()) | |
| 383 deleteLineBoxTree(); | |
| 384 | |
| 385 // Now take all of the children from beforeChild to the end and remove | |
| 386 // them from |this| and place them in the clone. | |
| 387 moveChildrenTo(cloneBlock, beforeChild, 0, true); | |
| 388 | |
| 389 // Hook |clone| up as the continuation of the middle block. | |
| 390 if (!cloneBlock->isAnonymousBlock()) | |
| 391 middleBlock->setContinuation(cloneBlock); | |
| 392 | |
| 393 // We have been reparented and are now under the fromBlock. We need | |
| 394 // to walk up our block parent chain until we hit the containing anonymous c
olumns block. | |
| 395 // Once we hit the anonymous columns block we're done. | |
| 396 RenderBoxModelObject* curr = toRenderBoxModelObject(parent()); | |
| 397 RenderBoxModelObject* currChild = this; | |
| 398 RenderObject* currChildNextSibling = currChild->nextSibling(); | |
| 399 | |
| 400 while (curr && curr->isDescendantOf(fromBlock) && curr != fromBlock) { | |
| 401 ASSERT_WITH_SECURITY_IMPLICATION(curr->isRenderBlock()); | |
| 402 | |
| 403 RenderBlock* blockCurr = toRenderBlock(curr); | |
| 404 | |
| 405 // Create a new clone. | |
| 406 RenderBlock* cloneChild = cloneBlock; | |
| 407 cloneBlock = blockCurr->clone(); | |
| 408 | |
| 409 // Insert our child clone as the first child. | |
| 410 cloneBlock->addChildIgnoringContinuation(cloneChild, 0); | |
| 411 | |
| 412 // Hook the clone up as a continuation of |curr|. Note we do encounter | |
| 413 // anonymous blocks possibly as we walk up the block chain. When we spl
it an | |
| 414 // anonymous block, there's no need to do any continuation hookup, since
we haven't | |
| 415 // actually split a real element. | |
| 416 if (!blockCurr->isAnonymousBlock()) { | |
| 417 oldCont = blockCurr->continuation(); | |
| 418 blockCurr->setContinuation(cloneBlock); | |
| 419 cloneBlock->setContinuation(oldCont); | |
| 420 } | |
| 421 | |
| 422 // Now we need to take all of the children starting from the first child | |
| 423 // *after* currChild and append them all to the clone. | |
| 424 blockCurr->moveChildrenTo(cloneBlock, currChildNextSibling, 0, true); | |
| 425 | |
| 426 // Keep walking up the chain. | |
| 427 currChild = curr; | |
| 428 currChildNextSibling = currChild->nextSibling(); | |
| 429 curr = toRenderBoxModelObject(curr->parent()); | |
| 430 } | |
| 431 | |
| 432 // Now we are at the columns block level. We need to put the clone into the
toBlock. | |
| 433 toBlock->children()->appendChildNode(toBlock, cloneBlock); | |
| 434 | |
| 435 // Now take all the children after currChild and remove them from the fromBl
ock | |
| 436 // and put them in the toBlock. | |
| 437 fromBlock->moveChildrenTo(toBlock, currChildNextSibling, 0, true); | |
| 438 } | |
| 439 | |
| 440 void RenderBlock::addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild,
RenderObject* beforeChild) | 277 void RenderBlock::addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild,
RenderObject* beforeChild) |
| 441 { | 278 { |
| 442 if (beforeChild && beforeChild->parent() != this) { | 279 if (beforeChild && beforeChild->parent() != this) { |
| 443 RenderObject* beforeChildContainer = beforeChild->parent(); | 280 RenderObject* beforeChildContainer = beforeChild->parent(); |
| 444 ASSERT(beforeChildContainer->parent() == this); | 281 ASSERT(beforeChildContainer->parent() == this); |
| 445 ASSERT(beforeChildContainer->isAnonymousBlock()); | 282 ASSERT(beforeChildContainer->isAnonymousBlock()); |
| 446 addChild(newChild, beforeChildContainer); | 283 addChild(newChild, beforeChildContainer); |
| 447 return; | 284 return; |
| 448 } | 285 } |
| 449 | 286 |
| 450 // TODO(ojan): What should we do in this case? For now we insert an anonymou
s paragraph. | 287 // TODO(ojan): What should we do in this case? For now we insert an anonymou
s paragraph. |
| 451 // This only happens if we have a text node directly inside a non-paragraph. | 288 // This only happens if we have a text node directly inside a non-paragraph. |
| 452 if (!childrenInline() && newChild->isInline()) { | 289 if (!childrenInline() && newChild->isInline()) { |
| 453 RenderBlock* newBox = createAnonymousBlock(); | 290 RenderBlock* newBox = createAnonymousBlock(); |
| 454 ASSERT(newBox->childrenInline()); | 291 ASSERT(newBox->childrenInline()); |
| 455 RenderBox::addChild(newBox, beforeChild); | 292 RenderBox::addChild(newBox, beforeChild); |
| 456 newBox->addChild(newChild); | 293 newBox->addChild(newChild); |
| 457 return; | 294 return; |
| 458 } | 295 } |
| 459 | 296 |
| 460 RenderBox::addChild(newChild, beforeChild); | 297 RenderBox::addChild(newChild, beforeChild); |
| 461 } | 298 } |
| 462 | 299 |
| 463 void RenderBlock::addChild(RenderObject* newChild, RenderObject* beforeChild) | 300 void RenderBlock::addChild(RenderObject* newChild, RenderObject* beforeChild) |
| 464 { | 301 { |
| 465 if (continuation() && !isAnonymousBlock()) | |
| 466 addChildToContinuation(newChild, beforeChild); | |
| 467 else | |
| 468 addChildIgnoringContinuation(newChild, beforeChild); | |
| 469 } | |
| 470 | |
| 471 void RenderBlock::addChildIgnoringContinuation(RenderObject* newChild, RenderObj
ect* beforeChild) | |
| 472 { | |
| 473 addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild); | 302 addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild); |
| 474 } | 303 } |
| 475 | 304 |
| 476 void RenderBlock::deleteLineBoxTree() | 305 void RenderBlock::deleteLineBoxTree() |
| 477 { | 306 { |
| 478 ASSERT(!m_lineBoxes.firstLineBox()); | 307 ASSERT(!m_lineBoxes.firstLineBox()); |
| 479 } | 308 } |
| 480 | 309 |
| 481 void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint) | 310 void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint) |
| 482 { | 311 { |
| 483 ASSERT_NOT_REACHED(); | 312 ASSERT_NOT_REACHED(); |
| 484 // FIXME(sky): Remove | 313 // FIXME(sky): Remove |
| 485 } | 314 } |
| 486 | 315 |
| 487 static bool canMergeContiguousAnonymousBlocks(RenderObject* oldChild, RenderObje
ct* prev, RenderObject* next) | |
| 488 { | |
| 489 if (oldChild->documentBeingDestroyed() || oldChild->isInline() || oldChild->
virtualContinuation()) | |
| 490 return false; | |
| 491 | |
| 492 if ((prev && (!prev->isAnonymousBlock() || toRenderBlock(prev)->continuation
() || toRenderBlock(prev)->beingDestroyed())) | |
| 493 || (next && (!next->isAnonymousBlock() || toRenderBlock(next)->continuat
ion() || toRenderBlock(next)->beingDestroyed()))) | |
| 494 return false; | |
| 495 | |
| 496 if (!prev || !next) | |
| 497 return true; | |
| 498 | |
| 499 return true; | |
| 500 } | |
| 501 | |
| 502 void RenderBlock::collapseAnonymousBlockChild(RenderBlock* parent, RenderBlock*
child) | 316 void RenderBlock::collapseAnonymousBlockChild(RenderBlock* parent, RenderBlock*
child) |
| 503 { | 317 { |
| 504 // It's possible that this block's destruction may have been triggered by th
e | 318 // It's possible that this block's destruction may have been triggered by th
e |
| 505 // child's removal. Just bail if the anonymous child block is already being | 319 // child's removal. Just bail if the anonymous child block is already being |
| 506 // destroyed. See crbug.com/282088 | 320 // destroyed. See crbug.com/282088 |
| 507 if (child->beingDestroyed()) | 321 if (child->beingDestroyed()) |
| 508 return; | 322 return; |
| 509 parent->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(); | 323 parent->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(); |
| 510 parent->setChildrenInline(child->childrenInline()); | 324 parent->setChildrenInline(child->childrenInline()); |
| 511 RenderObject* nextSibling = child->nextSibling(); | 325 RenderObject* nextSibling = child->nextSibling(); |
| 512 | 326 |
| 513 parent->children()->removeChildNode(parent, child, child->hasLayer()); | 327 parent->children()->removeChildNode(parent, child, child->hasLayer()); |
| 514 child->moveAllChildrenTo(parent, nextSibling, child->hasLayer()); | 328 child->moveAllChildrenTo(parent, nextSibling, child->hasLayer()); |
| 515 // Explicitly delete the child's line box tree, or the special anonymous | 329 // Explicitly delete the child's line box tree, or the special anonymous |
| 516 // block handling in willBeDestroyed will cause problems. | 330 // block handling in willBeDestroyed will cause problems. |
| 517 child->deleteLineBoxTree(); | 331 child->deleteLineBoxTree(); |
| 518 child->destroy(); | 332 child->destroy(); |
| 519 } | 333 } |
| 520 | 334 |
| 521 void RenderBlock::removeChild(RenderObject* oldChild) | 335 void RenderBlock::removeChild(RenderObject* oldChild) |
| 522 { | 336 { |
| 523 // No need to waste time in merging or removing empty anonymous blocks. | |
| 524 // We can just bail out if our document is getting destroyed. | |
| 525 if (documentBeingDestroyed()) { | |
| 526 RenderBox::removeChild(oldChild); | |
| 527 return; | |
| 528 } | |
| 529 | |
| 530 // If this child is a block, and if our previous and next siblings are | |
| 531 // both anonymous blocks with inline content, then we can go ahead and | |
| 532 // fold the inline content back together. | |
| 533 RenderObject* prev = oldChild->previousSibling(); | |
| 534 RenderObject* next = oldChild->nextSibling(); | |
| 535 bool canMergeAnonymousBlocks = canMergeContiguousAnonymousBlocks(oldChild, p
rev, next); | |
| 536 if (canMergeAnonymousBlocks && prev && next) { | |
| 537 prev->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(); | |
| 538 RenderBlockFlow* nextBlock = toRenderBlockFlow(next); | |
| 539 RenderBlockFlow* prevBlock = toRenderBlockFlow(prev); | |
| 540 | |
| 541 if (prev->childrenInline() != next->childrenInline()) { | |
| 542 RenderBlock* inlineChildrenBlock = prev->childrenInline() ? prevBloc
k : nextBlock; | |
| 543 RenderBlock* blockChildrenBlock = prev->childrenInline() ? nextBlock
: prevBlock; | |
| 544 | |
| 545 // Place the inline children block inside of the block children bloc
k instead of deleting it. | |
| 546 // In order to reuse it, we have to reset it to just be a generic an
onymous block. Make sure | |
| 547 // to clear out inherited column properties by just making a new sty
le, and to also clear the | |
| 548 // column span flag if it is set. | |
| 549 ASSERT(!inlineChildrenBlock->continuation()); | |
| 550 RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWith
Display(style(), BLOCK); | |
| 551 // Cache this value as it might get changed in setStyle() call. | |
| 552 bool inlineChildrenBlockHasLayer = inlineChildrenBlock->hasLayer(); | |
| 553 inlineChildrenBlock->setStyle(newStyle); | |
| 554 children()->removeChildNode(this, inlineChildrenBlock, inlineChildre
nBlockHasLayer); | |
| 555 | |
| 556 // Now just put the inlineChildrenBlock inside the blockChildrenBloc
k. | |
| 557 blockChildrenBlock->children()->insertChildNode(blockChildrenBlock,
inlineChildrenBlock, prev == inlineChildrenBlock ? blockChildrenBlock->firstChil
d() : 0, | |
| 558 inlineChildrenBlockH
asLayer || blockChildrenBlock->hasLayer()); | |
| 559 next->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(); | |
| 560 | |
| 561 // inlineChildrenBlock got reparented to blockChildrenBlock, so it i
s no longer a child | |
| 562 // of "this". we null out prev or next so that is not used later in
the function. | |
| 563 if (inlineChildrenBlock == prevBlock) | |
| 564 prev = 0; | |
| 565 else | |
| 566 next = 0; | |
| 567 } else { | |
| 568 // Take all the children out of the |next| block and put them in | |
| 569 // the |prev| block. | |
| 570 nextBlock->moveAllChildrenTo(prevBlock, nextBlock->hasLayer() || pre
vBlock->hasLayer()); | |
| 571 | |
| 572 // Delete the now-empty block's lines and nuke it. | |
| 573 nextBlock->deleteLineBoxTree(); | |
| 574 nextBlock->destroy(); | |
| 575 next = 0; | |
| 576 } | |
| 577 } | |
| 578 | |
| 579 RenderBox::removeChild(oldChild); | 337 RenderBox::removeChild(oldChild); |
| 580 | 338 |
| 581 RenderObject* child = prev ? prev : next; | 339 // No need to waste time deleting the line box tree if we're getting destroy
ed. |
| 582 if (canMergeAnonymousBlocks && child && !child->previousSibling() && !child-
>nextSibling() && canCollapseAnonymousBlockChild()) { | 340 if (documentBeingDestroyed()) |
| 583 // The removal has knocked us down to containing only a single anonymous | 341 return; |
| 584 // box. We can go ahead and pull the content right back up into our | |
| 585 // box. | |
| 586 collapseAnonymousBlockChild(this, toRenderBlock(child)); | |
| 587 } | |
| 588 | 342 |
| 589 if (!firstChild()) { | 343 // If this was our last child be sure to clear out our line boxes. |
| 590 // If this was our last child be sure to clear out our line boxes. | 344 if (!firstChild() && childrenInline()) |
| 591 if (childrenInline()) | 345 deleteLineBoxTree(); |
| 592 deleteLineBoxTree(); | |
| 593 | |
| 594 // If we are an empty anonymous block in the continuation chain, | |
| 595 // we need to remove ourself and fix the continuation chain. | |
| 596 if (!beingDestroyed() && isAnonymousBlockContinuation()) { | |
| 597 RenderObject* containingBlockIgnoringAnonymous = containingBlock(); | |
| 598 while (containingBlockIgnoringAnonymous && containingBlockIgnoringAn
onymous->isAnonymous()) | |
| 599 containingBlockIgnoringAnonymous = containingBlockIgnoringAnonym
ous->containingBlock(); | |
| 600 for (RenderObject* curr = this; curr; curr = curr->previousInPreOrde
r(containingBlockIgnoringAnonymous)) { | |
| 601 if (curr->virtualContinuation() != this) | |
| 602 continue; | |
| 603 | |
| 604 // Found our previous continuation. We just need to point it to | |
| 605 // |this|'s next continuation. | |
| 606 RenderBoxModelObject* nextContinuation = continuation(); | |
| 607 if (curr->isRenderInline()) | |
| 608 toRenderInline(curr)->setContinuation(nextContinuation); | |
| 609 else if (curr->isRenderBlock()) | |
| 610 toRenderBlock(curr)->setContinuation(nextContinuation); | |
| 611 else | |
| 612 ASSERT_NOT_REACHED(); | |
| 613 | |
| 614 break; | |
| 615 } | |
| 616 setContinuation(0); | |
| 617 destroy(); | |
| 618 } | |
| 619 } | |
| 620 } | 346 } |
| 621 | 347 |
| 622 void RenderBlock::startDelayUpdateScrollInfo() | 348 void RenderBlock::startDelayUpdateScrollInfo() |
| 623 { | 349 { |
| 624 if (gDelayUpdateScrollInfo == 0) { | 350 if (gDelayUpdateScrollInfo == 0) { |
| 625 ASSERT(!gDelayedUpdateScrollInfoSet); | 351 ASSERT(!gDelayedUpdateScrollInfoSet); |
| 626 gDelayedUpdateScrollInfoSet = new DelayedUpdateScrollInfoSet; | 352 gDelayedUpdateScrollInfoSet = new DelayedUpdateScrollInfoSet; |
| 627 } | 353 } |
| 628 ASSERT(gDelayedUpdateScrollInfoSet); | 354 ASSERT(gDelayedUpdateScrollInfoSet); |
| 629 ++gDelayUpdateScrollInfo; | 355 ++gDelayUpdateScrollInfo; |
| (...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1071 | 797 |
| 1072 // 2. paint contents | 798 // 2. paint contents |
| 1073 if (paintPhase != PaintPhaseSelfOutline) | 799 if (paintPhase != PaintPhaseSelfOutline) |
| 1074 paintContents(paintInfo, scrolledOffset); | 800 paintContents(paintInfo, scrolledOffset); |
| 1075 | 801 |
| 1076 // 3. paint selection | 802 // 3. paint selection |
| 1077 // FIXME: Make this work with multi column layouts. For now don't fill gaps
. | 803 // FIXME: Make this work with multi column layouts. For now don't fill gaps
. |
| 1078 paintSelection(paintInfo, scrolledOffset); // Fill in gaps in selection on l
ines and between blocks. | 804 paintSelection(paintInfo, scrolledOffset); // Fill in gaps in selection on l
ines and between blocks. |
| 1079 | 805 |
| 1080 // 5. paint outline. | 806 // 5. paint outline. |
| 1081 if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline)
&& style()->hasOutline()) { | 807 if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) |
| 1082 // Don't paint focus ring for anonymous block continuation because the | 808 && style()->hasOutline() && !style()->outlineStyleIsAuto()) { |
| 1083 // inline element having outline-style:auto paints the whole focus ring. | 809 paintOutline(paintInfo, LayoutRect(paintOffset, size())); |
| 1084 if (!style()->outlineStyleIsAuto() || !isAnonymousBlockContinuation()) | |
| 1085 paintOutline(paintInfo, LayoutRect(paintOffset, size())); | |
| 1086 } | 810 } |
| 1087 | 811 |
| 1088 // 6. paint continuation outlines. | |
| 1089 if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseChildOutline
s)) | |
| 1090 paintContinuationOutlines(paintInfo, paintOffset); | |
| 1091 | |
| 1092 // 7. paint caret. | 812 // 7. paint caret. |
| 1093 // If the caret's node's render object's containing block is this block, and
the paint action is PaintPhaseForeground, | 813 // If the caret's node's render object's containing block is this block, and
the paint action is PaintPhaseForeground, |
| 1094 // then paint the caret. | 814 // then paint the caret. |
| 1095 if (paintPhase == PaintPhaseForeground) | 815 if (paintPhase == PaintPhaseForeground) |
| 1096 paintCarets(paintInfo, paintOffset); | 816 paintCarets(paintInfo, paintOffset); |
| 1097 } | 817 } |
| 1098 | 818 |
| 1099 RenderInline* RenderBlock::inlineElementContinuation() const | |
| 1100 { | |
| 1101 RenderBoxModelObject* continuation = this->continuation(); | |
| 1102 return continuation && continuation->isInline() ? toRenderInline(continuatio
n) : 0; | |
| 1103 } | |
| 1104 | |
| 1105 RenderBlock* RenderBlock::blockElementContinuation() const | |
| 1106 { | |
| 1107 RenderBoxModelObject* currentContinuation = continuation(); | |
| 1108 if (!currentContinuation || currentContinuation->isInline()) | |
| 1109 return 0; | |
| 1110 RenderBlock* nextContinuation = toRenderBlock(currentContinuation); | |
| 1111 if (nextContinuation->isAnonymousBlock()) | |
| 1112 return nextContinuation->blockElementContinuation(); | |
| 1113 return nextContinuation; | |
| 1114 } | |
| 1115 | |
| 1116 static ContinuationOutlineTableMap* continuationOutlineTable() | |
| 1117 { | |
| 1118 DEFINE_STATIC_LOCAL(ContinuationOutlineTableMap, table, ()); | |
| 1119 return &table; | |
| 1120 } | |
| 1121 | |
| 1122 void RenderBlock::addContinuationWithOutline(RenderInline* flow) | |
| 1123 { | |
| 1124 // We can't make this work if the inline is in a layer. We'll just rely on
the broken | |
| 1125 // way of painting. | |
| 1126 ASSERT(!flow->layer() && !flow->isInlineElementContinuation()); | |
| 1127 | |
| 1128 ContinuationOutlineTableMap* table = continuationOutlineTable(); | |
| 1129 ListHashSet<RenderInline*>* continuations = table->get(this); | |
| 1130 if (!continuations) { | |
| 1131 continuations = new ListHashSet<RenderInline*>; | |
| 1132 table->set(this, adoptPtr(continuations)); | |
| 1133 } | |
| 1134 | |
| 1135 continuations->add(flow); | |
| 1136 } | |
| 1137 | |
| 1138 bool RenderBlock::paintsContinuationOutline(RenderInline* flow) | |
| 1139 { | |
| 1140 ContinuationOutlineTableMap* table = continuationOutlineTable(); | |
| 1141 if (table->isEmpty()) | |
| 1142 return false; | |
| 1143 | |
| 1144 ListHashSet<RenderInline*>* continuations = table->get(this); | |
| 1145 if (!continuations) | |
| 1146 return false; | |
| 1147 | |
| 1148 return continuations->contains(flow); | |
| 1149 } | |
| 1150 | |
| 1151 void RenderBlock::paintContinuationOutlines(PaintInfo& info, const LayoutPoint&
paintOffset) | |
| 1152 { | |
| 1153 RenderInline* inlineCont = inlineElementContinuation(); | |
| 1154 if (inlineCont && inlineCont->style()->hasOutline()) { | |
| 1155 RenderInline* inlineRenderer = toRenderInline(inlineCont->node()->render
er()); | |
| 1156 RenderBlock* cb = containingBlock(); | |
| 1157 | |
| 1158 bool inlineEnclosedInSelfPaintingLayer = false; | |
| 1159 for (RenderBoxModelObject* box = inlineRenderer; box != cb; box = box->p
arent()->enclosingBoxModelObject()) { | |
| 1160 if (box->hasSelfPaintingLayer()) { | |
| 1161 inlineEnclosedInSelfPaintingLayer = true; | |
| 1162 break; | |
| 1163 } | |
| 1164 } | |
| 1165 | |
| 1166 // Do not add continuations for outline painting by our containing block
if we are a relative positioned | |
| 1167 // anonymous block (i.e. have our own layer), paint them straightaway in
stead. This is because a block depends on renderers in its continuation table be
ing | |
| 1168 // in the same layer. | |
| 1169 if (!inlineEnclosedInSelfPaintingLayer && !hasLayer()) | |
| 1170 cb->addContinuationWithOutline(inlineRenderer); | |
| 1171 else if (!inlineRenderer->firstLineBox() || (!inlineEnclosedInSelfPainti
ngLayer && hasLayer())) | |
| 1172 inlineRenderer->paintOutline(info, paintOffset - locationOffset() +
inlineRenderer->containingBlock()->location()); | |
| 1173 } | |
| 1174 | |
| 1175 ContinuationOutlineTableMap* table = continuationOutlineTable(); | |
| 1176 if (table->isEmpty()) | |
| 1177 return; | |
| 1178 | |
| 1179 OwnPtr<ListHashSet<RenderInline*> > continuations = table->take(this); | |
| 1180 if (!continuations) | |
| 1181 return; | |
| 1182 | |
| 1183 LayoutPoint accumulatedPaintOffset = paintOffset; | |
| 1184 // Paint each continuation outline. | |
| 1185 ListHashSet<RenderInline*>::iterator end = continuations->end(); | |
| 1186 for (ListHashSet<RenderInline*>::iterator it = continuations->begin(); it !=
end; ++it) { | |
| 1187 // Need to add in the coordinates of the intervening blocks. | |
| 1188 RenderInline* flow = *it; | |
| 1189 RenderBlock* block = flow->containingBlock(); | |
| 1190 for ( ; block && block != this; block = block->containingBlock()) | |
| 1191 accumulatedPaintOffset.moveBy(block->location()); | |
| 1192 ASSERT(block); | |
| 1193 flow->paintOutline(info, accumulatedPaintOffset); | |
| 1194 } | |
| 1195 } | |
| 1196 | |
| 1197 bool RenderBlock::shouldPaintSelectionGaps() const | 819 bool RenderBlock::shouldPaintSelectionGaps() const |
| 1198 { | 820 { |
| 1199 return selectionState() != SelectionNone && isSelectionRoot(); | 821 return selectionState() != SelectionNone && isSelectionRoot(); |
| 1200 } | 822 } |
| 1201 | 823 |
| 1202 bool RenderBlock::isSelectionRoot() const | 824 bool RenderBlock::isSelectionRoot() const |
| 1203 { | 825 { |
| 1204 ASSERT(node() || isAnonymous()); | 826 ASSERT(node() || isAnonymous()); |
| 1205 | 827 |
| 1206 if (isDocumentElement() || hasOverflowClip() | 828 if (isDocumentElement() || hasOverflowClip() |
| (...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1736 afterLowest = lowestDirtyLine; | 1358 afterLowest = lowestDirtyLine; |
| 1737 lowestDirtyLine = lowestDirtyLine->prevRootBox(); | 1359 lowestDirtyLine = lowestDirtyLine->prevRootBox(); |
| 1738 } | 1360 } |
| 1739 | 1361 |
| 1740 while (afterLowest && afterLowest != highest && (afterLowest->lineBottomWith
Leading() >= logicalTop || afterLowest->lineBottomWithLeading() < 0)) { | 1362 while (afterLowest && afterLowest != highest && (afterLowest->lineBottomWith
Leading() >= logicalTop || afterLowest->lineBottomWithLeading() < 0)) { |
| 1741 afterLowest->markDirty(); | 1363 afterLowest->markDirty(); |
| 1742 afterLowest = afterLowest->prevRootBox(); | 1364 afterLowest = afterLowest->prevRootBox(); |
| 1743 } | 1365 } |
| 1744 } | 1366 } |
| 1745 | 1367 |
| 1746 Node* RenderBlock::nodeForHitTest() const | |
| 1747 { | |
| 1748 // If we are in the margins of block elements that are part of a | |
| 1749 // continuation we're actually still inside the enclosing element | |
| 1750 // that was split. Use the appropriate inner node. | |
| 1751 return isAnonymousBlockContinuation() ? continuation()->node() : node(); | |
| 1752 } | |
| 1753 | |
| 1754 bool RenderBlock::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
lt, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOf
fset, HitTestAction hitTestAction) | 1368 bool RenderBlock::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
lt, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOf
fset, HitTestAction hitTestAction) |
| 1755 { | 1369 { |
| 1756 LayoutPoint adjustedLocation(accumulatedOffset + location()); | 1370 LayoutPoint adjustedLocation(accumulatedOffset + location()); |
| 1757 LayoutSize localOffset = toLayoutSize(adjustedLocation); | 1371 LayoutSize localOffset = toLayoutSize(adjustedLocation); |
| 1758 | 1372 |
| 1759 if (!isRenderView()) { | 1373 if (!isRenderView()) { |
| 1760 // Check if we need to do anything at all. | 1374 // Check if we need to do anything at all. |
| 1761 // If we have clipping, then we can't have any spillout. | 1375 // If we have clipping, then we can't have any spillout. |
| 1762 LayoutRect overflowBox = hasOverflowClip() ? borderBoxRect() : visualOve
rflowRect(); | 1376 LayoutRect overflowBox = hasOverflowClip() ? borderBoxRect() : visualOve
rflowRect(); |
| 1763 overflowBox.moveBy(adjustedLocation); | 1377 overflowBox.moveBy(adjustedLocation); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1813 RoundedRect border = style()->getRoundedBorderFor(borderRect); | 1427 RoundedRect border = style()->getRoundedBorderFor(borderRect); |
| 1814 if (!locationInContainer.intersects(border)) | 1428 if (!locationInContainer.intersects(border)) |
| 1815 return false; | 1429 return false; |
| 1816 } | 1430 } |
| 1817 | 1431 |
| 1818 // Now hit test our background | 1432 // Now hit test our background |
| 1819 if (hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChild
BlockBackground) { | 1433 if (hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChild
BlockBackground) { |
| 1820 LayoutRect boundsRect(adjustedLocation, size()); | 1434 LayoutRect boundsRect(adjustedLocation, size()); |
| 1821 if (visibleToHitTestRequest(request) && locationInContainer.intersects(b
oundsRect)) { | 1435 if (visibleToHitTestRequest(request) && locationInContainer.intersects(b
oundsRect)) { |
| 1822 updateHitTestResult(result, locationInContainer.point() - localOffse
t); | 1436 updateHitTestResult(result, locationInContainer.point() - localOffse
t); |
| 1823 if (!result.addNodeToRectBasedTestResult(nodeForHitTest(), request,
locationInContainer, boundsRect)) | 1437 if (!result.addNodeToRectBasedTestResult(node(), request, locationIn
Container, boundsRect)) |
| 1824 return true; | 1438 return true; |
| 1825 } | 1439 } |
| 1826 } | 1440 } |
| 1827 | 1441 |
| 1828 return false; | 1442 return false; |
| 1829 } | 1443 } |
| 1830 | 1444 |
| 1831 bool RenderBlock::hitTestContents(const HitTestRequest& request, HitTestResult&
result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulat
edOffset, HitTestAction hitTestAction) | 1445 bool RenderBlock::hitTestContents(const HitTestRequest& request, HitTestResult&
result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulat
edOffset, HitTestAction hitTestAction) |
| 1832 { | 1446 { |
| 1833 if (childrenInline()) { | 1447 if (childrenInline()) { |
| (...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2383 } else { | 1997 } else { |
| 2384 for (RenderObject* obj = firstChild(); obj; obj = obj->nextSibling()) { | 1998 for (RenderObject* obj = firstChild(); obj; obj = obj->nextSibling()) { |
| 2385 if (shouldCheckLines(obj)) | 1999 if (shouldCheckLines(obj)) |
| 2386 toRenderBlock(obj)->clearTruncation(); | 2000 toRenderBlock(obj)->clearTruncation(); |
| 2387 } | 2001 } |
| 2388 } | 2002 } |
| 2389 } | 2003 } |
| 2390 | 2004 |
| 2391 void RenderBlock::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accum
ulatedOffset) const | 2005 void RenderBlock::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accum
ulatedOffset) const |
| 2392 { | 2006 { |
| 2393 // For blocks inside inlines, we go ahead and include margins so that we run
right up to the | 2007 rects.append(pixelSnappedIntRect(accumulatedOffset, size())); |
| 2394 // inline boxes above and below us (thus getting merged with them to form a
single irregular | |
| 2395 // shape). | |
| 2396 if (isAnonymousBlockContinuation()) { | |
| 2397 // FIXME: This is wrong for block-flows that are horizontal. | |
| 2398 // https://bugs.webkit.org/show_bug.cgi?id=46781 | |
| 2399 rects.append(pixelSnappedIntRect(accumulatedOffset.x(), accumulatedOffse
t.y() - marginBefore(), | |
| 2400 width(), height() + marginBefore() + marginAfter
())); | |
| 2401 continuation()->absoluteRects(rects, accumulatedOffset - toLayoutSize(lo
cation() + | |
| 2402 inlineElementContinuation()->containingBlock()->location())); | |
| 2403 } else | |
| 2404 rects.append(pixelSnappedIntRect(accumulatedOffset, size())); | |
| 2405 } | 2008 } |
| 2406 | 2009 |
| 2407 void RenderBlock::absoluteQuads(Vector<FloatQuad>& quads) const | 2010 void RenderBlock::absoluteQuads(Vector<FloatQuad>& quads) const |
| 2408 { | 2011 { |
| 2409 // For blocks inside inlines, we go ahead and include margins so that we run
right up to the | 2012 quads.append(RenderBox::localToAbsoluteQuad(FloatRect(0, 0, width().toFloat(
), height().toFloat()), 0 /* mode */)); |
| 2410 // inline boxes above and below us (thus getting merged with them to form a
single irregular | |
| 2411 // shape). | |
| 2412 if (isAnonymousBlockContinuation()) { | |
| 2413 // FIXME: This is wrong for block-flows that are horizontal. | |
| 2414 // https://bugs.webkit.org/show_bug.cgi?id=46781 | |
| 2415 FloatRect localRect(0, -marginBefore().toFloat(), | |
| 2416 width().toFloat(), (height() + marginBefore() + marginAfter()).toFlo
at()); | |
| 2417 quads.append(localToAbsoluteQuad(localRect, 0 /* mode */)); | |
| 2418 continuation()->absoluteQuads(quads); | |
| 2419 } else { | |
| 2420 quads.append(RenderBox::localToAbsoluteQuad(FloatRect(0, 0, width().toFl
oat(), height().toFloat()), 0 /* mode */)); | |
| 2421 } | |
| 2422 } | |
| 2423 | |
| 2424 LayoutRect RenderBlock::rectWithOutlineForPaintInvalidation(const RenderLayerMod
elObject* paintInvalidationContainer, LayoutUnit outlineWidth, const PaintInvali
dationState* paintInvalidationState) const | |
| 2425 { | |
| 2426 LayoutRect r(RenderBox::rectWithOutlineForPaintInvalidation(paintInvalidatio
nContainer, outlineWidth, paintInvalidationState)); | |
| 2427 if (isAnonymousBlockContinuation()) | |
| 2428 r.inflateY(marginBefore()); // FIXME: This is wrong for block-flows that
are horizontal. | |
| 2429 return r; | |
| 2430 } | |
| 2431 | |
| 2432 RenderObject* RenderBlock::hoverAncestor() const | |
| 2433 { | |
| 2434 return isAnonymousBlockContinuation() ? continuation() : RenderBox::hoverAnc
estor(); | |
| 2435 } | |
| 2436 | |
| 2437 void RenderBlock::childBecameNonInline(RenderObject*) | |
| 2438 { | |
| 2439 ASSERT_NOT_REACHED(); | |
| 2440 // FIXME(sky): Remove | |
| 2441 } | 2013 } |
| 2442 | 2014 |
| 2443 void RenderBlock::updateHitTestResult(HitTestResult& result, const LayoutPoint&
point) | 2015 void RenderBlock::updateHitTestResult(HitTestResult& result, const LayoutPoint&
point) |
| 2444 { | 2016 { |
| 2445 if (result.innerNode()) | 2017 if (result.innerNode()) |
| 2446 return; | 2018 return; |
| 2447 | 2019 |
| 2448 if (Node* n = nodeForHitTest()) { | 2020 if (Node* n = node()) { |
| 2449 result.setInnerNode(n); | 2021 result.setInnerNode(n); |
| 2450 if (!result.innerNonSharedNode()) | 2022 if (!result.innerNonSharedNode()) |
| 2451 result.setInnerNonSharedNode(n); | 2023 result.setInnerNonSharedNode(n); |
| 2452 result.setLocalPoint(point); | 2024 result.setLocalPoint(point); |
| 2453 } | 2025 } |
| 2454 } | 2026 } |
| 2455 | 2027 |
| 2456 LayoutRect RenderBlock::localCaretRect(InlineBox* inlineBox, int caretOffset, La
youtUnit* extraWidthToEndOfLine) | 2028 LayoutRect RenderBlock::localCaretRect(InlineBox* inlineBox, int caretOffset, La
youtUnit* extraWidthToEndOfLine) |
| 2457 { | 2029 { |
| 2458 // Do the normal calculation in most cases. | 2030 // Do the normal calculation in most cases. |
| 2459 if (firstChild()) | 2031 if (firstChild()) |
| 2460 return RenderBox::localCaretRect(inlineBox, caretOffset, extraWidthToEnd
OfLine); | 2032 return RenderBox::localCaretRect(inlineBox, caretOffset, extraWidthToEnd
OfLine); |
| 2461 | 2033 |
| 2462 LayoutRect caretRect = localCaretRectForEmptyElement(width(), textIndentOffs
et()); | 2034 LayoutRect caretRect = localCaretRectForEmptyElement(width(), textIndentOffs
et()); |
| 2463 | 2035 |
| 2464 if (extraWidthToEndOfLine) | 2036 if (extraWidthToEndOfLine) |
| 2465 *extraWidthToEndOfLine = width() - caretRect.maxX(); | 2037 *extraWidthToEndOfLine = width() - caretRect.maxX(); |
| 2466 | 2038 |
| 2467 return caretRect; | 2039 return caretRect; |
| 2468 } | 2040 } |
| 2469 | 2041 |
| 2470 void RenderBlock::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint& a
dditionalOffset, const RenderLayerModelObject* paintContainer) const | 2042 void RenderBlock::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint& a
dditionalOffset, const RenderLayerModelObject* paintContainer) const |
| 2471 { | 2043 { |
| 2472 // For blocks inside inlines, we go ahead and include margins so that we run
right up to the | 2044 if (width() && height()) |
| 2473 // inline boxes above and below us (thus getting merged with them to form a
single irregular | |
| 2474 // shape). | |
| 2475 if (inlineElementContinuation()) { | |
| 2476 // FIXME: This check really isn't accurate. | |
| 2477 bool nextInlineHasLineBox = inlineElementContinuation()->firstLineBox(); | |
| 2478 // FIXME: This is wrong. The principal renderer may not be the continuat
ion preceding this block. | |
| 2479 // FIXME: This is wrong for block-flows that are horizontal. | |
| 2480 // https://bugs.webkit.org/show_bug.cgi?id=46781 | |
| 2481 bool prevInlineHasLineBox = toRenderInline(inlineElementContinuation()->
node()->renderer())->firstLineBox(); | |
| 2482 LayoutUnit topMargin = prevInlineHasLineBox ? marginBefore() : LayoutUni
t(); | |
| 2483 LayoutUnit bottomMargin = nextInlineHasLineBox ? marginAfter() : LayoutU
nit(); | |
| 2484 LayoutRect rect(additionalOffset.x(), additionalOffset.y() - topMargin,
width(), height() + topMargin + bottomMargin); | |
| 2485 if (!rect.isEmpty()) | |
| 2486 rects.append(pixelSnappedIntRect(rect)); | |
| 2487 } else if (width() && height()) { | |
| 2488 rects.append(pixelSnappedIntRect(additionalOffset, size())); | 2045 rects.append(pixelSnappedIntRect(additionalOffset, size())); |
| 2489 } | |
| 2490 | 2046 |
| 2491 if (!hasOverflowClip() && !hasControlClip()) { | 2047 if (!hasOverflowClip() && !hasControlClip()) { |
| 2492 for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBo
x()) { | 2048 for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBo
x()) { |
| 2493 LayoutUnit top = std::max<LayoutUnit>(curr->lineTop(), curr->top()); | 2049 LayoutUnit top = std::max<LayoutUnit>(curr->lineTop(), curr->top()); |
| 2494 LayoutUnit bottom = std::min<LayoutUnit>(curr->lineBottom(), curr->t
op() + curr->height()); | 2050 LayoutUnit bottom = std::min<LayoutUnit>(curr->lineBottom(), curr->t
op() + curr->height()); |
| 2495 LayoutRect rect(additionalOffset.x() + curr->x(), additionalOffset.y
() + top, curr->width(), bottom - top); | 2051 LayoutRect rect(additionalOffset.x() + curr->x(), additionalOffset.y
() + top, curr->width(), bottom - top); |
| 2496 if (!rect.isEmpty()) | 2052 if (!rect.isEmpty()) |
| 2497 rects.append(pixelSnappedIntRect(rect)); | 2053 rects.append(pixelSnappedIntRect(rect)); |
| 2498 } | 2054 } |
| 2499 | 2055 |
| 2500 addChildFocusRingRects(rects, additionalOffset, paintContainer); | 2056 addChildFocusRingRects(rects, additionalOffset, paintContainer); |
| 2501 } | 2057 } |
| 2502 | |
| 2503 if (inlineElementContinuation()) | |
| 2504 inlineElementContinuation()->addFocusRingRects(rects, flooredLayoutPoint
(additionalOffset + inlineElementContinuation()->containingBlock()->location() -
location()), paintContainer); | |
| 2505 } | |
| 2506 | |
| 2507 RenderBox* RenderBlock::createAnonymousBoxWithSameTypeAs(const RenderObject* par
ent) const | |
| 2508 { | |
| 2509 return createAnonymousWithParentRendererAndDisplay(parent, style()->display(
)); | |
| 2510 } | 2058 } |
| 2511 | 2059 |
| 2512 LayoutUnit RenderBlock::marginBeforeForChild(const RenderBox* child) const | 2060 LayoutUnit RenderBlock::marginBeforeForChild(const RenderBox* child) const |
| 2513 { | 2061 { |
| 2514 // FIXME(sky): Remove | 2062 // FIXME(sky): Remove |
| 2515 return child->marginBefore(); | 2063 return child->marginBefore(); |
| 2516 } | 2064 } |
| 2517 | 2065 |
| 2518 LayoutUnit RenderBlock::marginAfterForChild(const RenderBox* child) const | 2066 LayoutUnit RenderBlock::marginAfterForChild(const RenderBox* child) const |
| 2519 { | 2067 { |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2661 void RenderBlock::showLineTreeAndMark(const InlineBox* markedBox1, const char* m
arkedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const Render
Object* obj) const | 2209 void RenderBlock::showLineTreeAndMark(const InlineBox* markedBox1, const char* m
arkedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const Render
Object* obj) const |
| 2662 { | 2210 { |
| 2663 showRenderObject(); | 2211 showRenderObject(); |
| 2664 for (const RootInlineBox* root = firstRootBox(); root; root = root->nextRoot
Box()) | 2212 for (const RootInlineBox* root = firstRootBox(); root; root = root->nextRoot
Box()) |
| 2665 root->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedLa
bel2, obj, 1); | 2213 root->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedLa
bel2, obj, 1); |
| 2666 } | 2214 } |
| 2667 | 2215 |
| 2668 #endif | 2216 #endif |
| 2669 | 2217 |
| 2670 } // namespace blink | 2218 } // namespace blink |
| OLD | NEW |