| 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. | 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc.
All rights reserved. |
| 6 * All rights reserved. | |
| 7 * Copyright (C) Research In Motion Limited 2010. All rights reserved. | 6 * Copyright (C) Research In Motion Limited 2010. All rights reserved. |
| 8 * | 7 * |
| 9 * This library is free software; you can redistribute it and/or | 8 * This library is free software; you can redistribute it and/or |
| 10 * modify it under the terms of the GNU Library General Public | 9 * modify it under the terms of the GNU Library General Public |
| 11 * License as published by the Free Software Foundation; either | 10 * License as published by the Free Software Foundation; either |
| 12 * version 2 of the License, or (at your option) any later version. | 11 * version 2 of the License, or (at your option) any later version. |
| 13 * | 12 * |
| 14 * This library is distributed in the hope that it will be useful, | 13 * This library is distributed in the hope that it will be useful, |
| 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 // This map is populated during layout. It is kept across layouts to handle | 75 // This map is populated during layout. It is kept across layouts to handle |
| 77 // that we skip unchanged sub-trees during layout, in such a way that we are | 76 // that we skip unchanged sub-trees during layout, in such a way that we are |
| 78 // able to lay out deeply nested out-of-flow descendants if their containing | 77 // able to lay out deeply nested out-of-flow descendants if their containing |
| 79 // block got laid out. The map could be invalidated during style change but | 78 // block got laid out. The map could be invalidated during style change but |
| 80 // keeping track of containing blocks at that time is complicated (we are in | 79 // keeping track of containing blocks at that time is complicated (we are in |
| 81 // the middle of recomputing the style so we can't rely on any of its | 80 // the middle of recomputing the style so we can't rely on any of its |
| 82 // information), which is why it's easier to just update it for every layout. | 81 // information), which is why it's easier to just update it for every layout. |
| 83 static TrackedDescendantsMap* gPositionedDescendantsMap = nullptr; | 82 static TrackedDescendantsMap* gPositionedDescendantsMap = nullptr; |
| 84 static TrackedContainerMap* gPositionedContainerMap = nullptr; | 83 static TrackedContainerMap* gPositionedContainerMap = nullptr; |
| 85 | 84 |
| 86 // This map keeps track of the descendants whose 'height' is percentage | 85 // This map keeps track of the descendants whose 'height' is percentage associat
ed |
| 87 // associated with a containing block. Like |gPositionedDescendantsMap|, it is | 86 // with a containing block. Like |gPositionedDescendantsMap|, it is also recompu
ted |
| 88 // also recomputed for every layout (see the comment above about why). | 87 // for every layout (see the comment above about why). |
| 89 static TrackedDescendantsMap* gPercentHeightDescendantsMap = nullptr; | 88 static TrackedDescendantsMap* gPercentHeightDescendantsMap = nullptr; |
| 90 | 89 |
| 91 LayoutBlock::LayoutBlock(ContainerNode* node) | 90 LayoutBlock::LayoutBlock(ContainerNode* node) |
| 92 : LayoutBox(node), | 91 : LayoutBox(node), |
| 93 m_hasMarginBeforeQuirk(false), | 92 m_hasMarginBeforeQuirk(false), |
| 94 m_hasMarginAfterQuirk(false), | 93 m_hasMarginAfterQuirk(false), |
| 95 m_beingDestroyed(false), | 94 m_beingDestroyed(false), |
| 96 m_hasMarkupTruncation(false), | 95 m_hasMarkupTruncation(false), |
| 97 m_widthAvailableToChildrenChanged(false), | 96 m_widthAvailableToChildrenChanged(false), |
| 98 m_heightAvailableToChildrenChanged(false), | 97 m_heightAvailableToChildrenChanged(false), |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 153 oldStyle->canContainAbsolutePositionObjects(); | 152 oldStyle->canContainAbsolutePositionObjects(); |
| 154 bool newStyleContainsFixedPosition = | 153 bool newStyleContainsFixedPosition = |
| 155 newStyle.canContainFixedPositionObjects(); | 154 newStyle.canContainFixedPositionObjects(); |
| 156 bool newStyleContainsAbsolutePosition = | 155 bool newStyleContainsAbsolutePosition = |
| 157 newStyleContainsFixedPosition || | 156 newStyleContainsFixedPosition || |
| 158 newStyle.canContainAbsolutePositionObjects(); | 157 newStyle.canContainAbsolutePositionObjects(); |
| 159 | 158 |
| 160 if ((oldStyleContainsFixedPosition && !newStyleContainsFixedPosition) || | 159 if ((oldStyleContainsFixedPosition && !newStyleContainsFixedPosition) || |
| 161 (oldStyleContainsAbsolutePosition && | 160 (oldStyleContainsAbsolutePosition && |
| 162 !newStyleContainsAbsolutePosition)) { | 161 !newStyleContainsAbsolutePosition)) { |
| 163 // Clear our positioned objects list. Our absolute and fixed positioned | 162 // Clear our positioned objects list. Our absolute and fixed positioned de
scendants will be |
| 164 // descendants will be inserted into our containing block's positioned | 163 // inserted into our containing block's positioned objects list during lay
out. |
| 165 // objects list during layout. | |
| 166 removePositionedObjects(nullptr, NewContainingBlock); | 164 removePositionedObjects(nullptr, NewContainingBlock); |
| 167 } | 165 } |
| 168 if (!oldStyleContainsAbsolutePosition && newStyleContainsAbsolutePosition) { | 166 if (!oldStyleContainsAbsolutePosition && newStyleContainsAbsolutePosition) { |
| 169 // Remove our absolutely positioned descendants from their current | 167 // Remove our absolutely positioned descendants from their current contain
ing block. |
| 170 // containing block. | |
| 171 // They will be inserted into our positioned objects list during layout. | 168 // They will be inserted into our positioned objects list during layout. |
| 172 if (LayoutBlock* cb = containingBlockForAbsolutePosition()) | 169 if (LayoutBlock* cb = containingBlockForAbsolutePosition()) |
| 173 cb->removePositionedObjects(this, NewContainingBlock); | 170 cb->removePositionedObjects(this, NewContainingBlock); |
| 174 } | 171 } |
| 175 if (!oldStyleContainsFixedPosition && newStyleContainsFixedPosition) { | 172 if (!oldStyleContainsFixedPosition && newStyleContainsFixedPosition) { |
| 176 // Remove our fixed positioned descendants from their current containing | 173 // Remove our fixed positioned descendants from their current containing b
lock. |
| 177 // block. | |
| 178 // They will be inserted into our positioned objects list during layout. | 174 // They will be inserted into our positioned objects list during layout. |
| 179 if (LayoutBlock* cb = containerForFixedPosition()) | 175 if (LayoutBlock* cb = containerForFixedPosition()) |
| 180 cb->removePositionedObjects(this, NewContainingBlock); | 176 cb->removePositionedObjects(this, NewContainingBlock); |
| 181 } | 177 } |
| 182 } | 178 } |
| 183 | 179 |
| 184 LayoutBox::styleWillChange(diff, newStyle); | 180 LayoutBox::styleWillChange(diff, newStyle); |
| 185 } | 181 } |
| 186 | 182 |
| 187 enum LogicalExtent { LogicalWidth, LogicalHeight }; | 183 enum LogicalExtent { LogicalWidth, LogicalHeight }; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 204 | 200 |
| 205 void LayoutBlock::styleDidChange(StyleDifference diff, | 201 void LayoutBlock::styleDidChange(StyleDifference diff, |
| 206 const ComputedStyle* oldStyle) { | 202 const ComputedStyle* oldStyle) { |
| 207 LayoutBox::styleDidChange(diff, oldStyle); | 203 LayoutBox::styleDidChange(diff, oldStyle); |
| 208 | 204 |
| 209 const ComputedStyle& newStyle = styleRef(); | 205 const ComputedStyle& newStyle = styleRef(); |
| 210 | 206 |
| 211 if (oldStyle && parent()) { | 207 if (oldStyle && parent()) { |
| 212 if (oldStyle->position() != newStyle.position() && | 208 if (oldStyle->position() != newStyle.position() && |
| 213 newStyle.position() != StaticPosition) { | 209 newStyle.position() != StaticPosition) { |
| 214 // In LayoutObject::styleWillChange() we already removed ourself from our | 210 // In LayoutObject::styleWillChange() we already removed ourself from our
old containing |
| 215 // old containing block's positioned descendant list, and we will be | 211 // block's positioned descendant list, and we will be inserted to the new
containing |
| 216 // inserted to the new containing block's list during layout. However the | 212 // block's list during layout. However the positioned descendant layout lo
gic assumes |
| 217 // positioned descendant layout logic assumes layout objects to obey | 213 // layout objects to obey parent-child order in the list. Remove our desce
ndants here |
| 218 // parent-child order in the list. Remove our descendants here so they | 214 // so they will be re-inserted after us. |
| 219 // will be re-inserted after us. | |
| 220 if (LayoutBlock* cb = containingBlock()) { | 215 if (LayoutBlock* cb = containingBlock()) { |
| 221 cb->removePositionedObjects(this, NewContainingBlock); | 216 cb->removePositionedObjects(this, NewContainingBlock); |
| 222 if (isOutOfFlowPositioned()) { | 217 if (isOutOfFlowPositioned()) { |
| 223 // Insert this object into containing block's positioned descendants | 218 // Insert this object into containing block's positioned descendants l
ist |
| 224 // list in case the parent won't layout. This is needed especially | 219 // in case the parent won't layout. This is needed especially there ar
e |
| 225 // there are descendants scheduled for overflow recalc. | 220 // descendants scheduled for overflow recalc. |
| 226 cb->insertPositionedObject(this); | 221 cb->insertPositionedObject(this); |
| 227 } | 222 } |
| 228 } | 223 } |
| 229 } | 224 } |
| 230 } | 225 } |
| 231 | 226 |
| 232 if (TextAutosizer* textAutosizer = document().textAutosizer()) | 227 if (TextAutosizer* textAutosizer = document().textAutosizer()) |
| 233 textAutosizer->record(this); | 228 textAutosizer->record(this); |
| 234 | 229 |
| 235 propagateStyleToAnonymousChildren(); | 230 propagateStyleToAnonymousChildren(); |
| 236 | 231 |
| 237 // It's possible for our border/padding to change, but for the overall logical | 232 // It's possible for our border/padding to change, but for the overall logical
width or height of the block to |
| 238 // width or height of the block to end up being the same. We keep track of | 233 // end up being the same. We keep track of this change so in layoutBlock, we c
an know to set relayoutChildren=true. |
| 239 // this change so in layoutBlock, we can know to set relayoutChildren=true. | |
| 240 m_widthAvailableToChildrenChanged |= | 234 m_widthAvailableToChildrenChanged |= |
| 241 oldStyle && diff.needsFullLayout() && needsLayout() && | 235 oldStyle && diff.needsFullLayout() && needsLayout() && |
| 242 borderOrPaddingLogicalDimensionChanged(*oldStyle, newStyle, LogicalWidth); | 236 borderOrPaddingLogicalDimensionChanged(*oldStyle, newStyle, LogicalWidth); |
| 243 m_heightAvailableToChildrenChanged |= oldStyle && diff.needsFullLayout() && | 237 m_heightAvailableToChildrenChanged |= oldStyle && diff.needsFullLayout() && |
| 244 needsLayout() && | 238 needsLayout() && |
| 245 borderOrPaddingLogicalDimensionChanged( | 239 borderOrPaddingLogicalDimensionChanged( |
| 246 *oldStyle, newStyle, LogicalHeight); | 240 *oldStyle, newStyle, LogicalHeight); |
| 247 } | 241 } |
| 248 | 242 |
| 249 void LayoutBlock::updateFromStyle() { | 243 void LayoutBlock::updateFromStyle() { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 265 } | 259 } |
| 266 | 260 |
| 267 void LayoutBlock::addChildBeforeDescendant(LayoutObject* newChild, | 261 void LayoutBlock::addChildBeforeDescendant(LayoutObject* newChild, |
| 268 LayoutObject* beforeDescendant) { | 262 LayoutObject* beforeDescendant) { |
| 269 ASSERT(beforeDescendant->parent() != this); | 263 ASSERT(beforeDescendant->parent() != this); |
| 270 LayoutObject* beforeDescendantContainer = beforeDescendant->parent(); | 264 LayoutObject* beforeDescendantContainer = beforeDescendant->parent(); |
| 271 while (beforeDescendantContainer->parent() != this) | 265 while (beforeDescendantContainer->parent() != this) |
| 272 beforeDescendantContainer = beforeDescendantContainer->parent(); | 266 beforeDescendantContainer = beforeDescendantContainer->parent(); |
| 273 ASSERT(beforeDescendantContainer); | 267 ASSERT(beforeDescendantContainer); |
| 274 | 268 |
| 275 // We really can't go on if what we have found isn't anonymous. We're not | 269 // We really can't go on if what we have found isn't anonymous. We're not supp
osed to use some |
| 276 // supposed to use some random non-anonymous object and put the child there. | 270 // random non-anonymous object and put the child there. That's a recipe for se
curity issues. |
| 277 // That's a recipe for security issues. | |
| 278 RELEASE_ASSERT(beforeDescendantContainer->isAnonymous()); | 271 RELEASE_ASSERT(beforeDescendantContainer->isAnonymous()); |
| 279 | 272 |
| 280 // If the requested insertion point is not one of our children, then this is | 273 // If the requested insertion point is not one of our children, then this is b
ecause |
| 281 // because there is an anonymous container within this object that contains | 274 // there is an anonymous container within this object that contains the before
Descendant. |
| 282 // the beforeDescendant. | |
| 283 if (beforeDescendantContainer->isAnonymousBlock() | 275 if (beforeDescendantContainer->isAnonymousBlock() |
| 284 // Full screen layoutObjects and full screen placeholders act as anonymous | 276 // Full screen layoutObjects and full screen placeholders act as anonymous
blocks, not tables: |
| 285 // blocks, not tables: | |
| 286 || beforeDescendantContainer->isLayoutFullScreen() || | 277 || beforeDescendantContainer->isLayoutFullScreen() || |
| 287 beforeDescendantContainer->isLayoutFullScreenPlaceholder()) { | 278 beforeDescendantContainer->isLayoutFullScreenPlaceholder()) { |
| 288 // Insert the child into the anonymous block box instead of here. | 279 // Insert the child into the anonymous block box instead of here. |
| 289 if (newChild->isInline() || newChild->isFloatingOrOutOfFlowPositioned() || | 280 if (newChild->isInline() || newChild->isFloatingOrOutOfFlowPositioned() || |
| 290 beforeDescendant->parent()->slowFirstChild() != beforeDescendant) | 281 beforeDescendant->parent()->slowFirstChild() != beforeDescendant) |
| 291 beforeDescendant->parent()->addChild(newChild, beforeDescendant); | 282 beforeDescendant->parent()->addChild(newChild, beforeDescendant); |
| 292 else | 283 else |
| 293 addChild(newChild, beforeDescendant->parent()); | 284 addChild(newChild, beforeDescendant->parent()); |
| 294 return; | 285 return; |
| 295 } | 286 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 312 | 303 |
| 313 addChild(newChild, beforeChild); | 304 addChild(newChild, beforeChild); |
| 314 } | 305 } |
| 315 | 306 |
| 316 void LayoutBlock::addChild(LayoutObject* newChild, LayoutObject* beforeChild) { | 307 void LayoutBlock::addChild(LayoutObject* newChild, LayoutObject* beforeChild) { |
| 317 if (beforeChild && beforeChild->parent() != this) { | 308 if (beforeChild && beforeChild->parent() != this) { |
| 318 addChildBeforeDescendant(newChild, beforeChild); | 309 addChildBeforeDescendant(newChild, beforeChild); |
| 319 return; | 310 return; |
| 320 } | 311 } |
| 321 | 312 |
| 322 // Only LayoutBlockFlow should have inline children, and then we shouldn't be | 313 // Only LayoutBlockFlow should have inline children, and then we shouldn't be
here. |
| 323 // here. | |
| 324 ASSERT(!childrenInline()); | 314 ASSERT(!childrenInline()); |
| 325 | 315 |
| 326 if (newChild->isInline() || newChild->isFloatingOrOutOfFlowPositioned()) { | 316 if (newChild->isInline() || newChild->isFloatingOrOutOfFlowPositioned()) { |
| 327 // If we're inserting an inline child but all of our children are blocks, | 317 // If we're inserting an inline child but all of our children are blocks, th
en we have to make sure |
| 328 // then we have to make sure it is put into an anomyous block box. We try to | 318 // it is put into an anomyous block box. We try to use an existing anonymous
box if possible, otherwise |
| 329 // use an existing anonymous box if possible, otherwise a new one is created | 319 // a new one is created and inserted into our list of children in the approp
riate position. |
| 330 // and inserted into our list of children in the appropriate position. | |
| 331 LayoutObject* afterChild = | 320 LayoutObject* afterChild = |
| 332 beforeChild ? beforeChild->previousSibling() : lastChild(); | 321 beforeChild ? beforeChild->previousSibling() : lastChild(); |
| 333 | 322 |
| 334 if (afterChild && afterChild->isAnonymousBlock()) { | 323 if (afterChild && afterChild->isAnonymousBlock()) { |
| 335 afterChild->addChild(newChild); | 324 afterChild->addChild(newChild); |
| 336 return; | 325 return; |
| 337 } | 326 } |
| 338 | 327 |
| 339 if (newChild->isInline()) { | 328 if (newChild->isInline()) { |
| 340 // No suitable existing anonymous box - create a new one. | 329 // No suitable existing anonymous box - create a new one. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 352 ASSERT(child->isAnonymousBlock()); | 341 ASSERT(child->isAnonymousBlock()); |
| 353 ASSERT(!child->childrenInline()); | 342 ASSERT(!child->childrenInline()); |
| 354 ASSERT(child->parent() == this); | 343 ASSERT(child->parent() == this); |
| 355 | 344 |
| 356 if (child->continuation()) | 345 if (child->continuation()) |
| 357 return; | 346 return; |
| 358 | 347 |
| 359 if (isFieldset()) | 348 if (isFieldset()) |
| 360 return; | 349 return; |
| 361 | 350 |
| 362 // Promote all the leftover anonymous block's children (to become children of | 351 // Promote all the leftover anonymous block's children (to become children of
this block |
| 363 // this block instead). We still want to keep the leftover block in the tree | 352 // instead). We still want to keep the leftover block in the tree for a moment
, for notification |
| 364 // for a moment, for notification purposes done further below (flow threads | 353 // purposes done further below (flow threads and grids). |
| 365 // and grids). | |
| 366 child->moveAllChildrenTo(this, child->nextSibling()); | 354 child->moveAllChildrenTo(this, child->nextSibling()); |
| 367 | 355 |
| 368 // Remove all the information in the flow thread associated with the leftover | 356 // Remove all the information in the flow thread associated with the leftover
anonymous block. |
| 369 // anonymous block. | |
| 370 child->removeFromLayoutFlowThread(); | 357 child->removeFromLayoutFlowThread(); |
| 371 | 358 |
| 372 // LayoutGrid keeps track of its children, we must notify it about changes in | 359 // LayoutGrid keeps track of its children, we must notify it about changes in
the tree. |
| 373 // the tree. | |
| 374 if (child->parent()->isLayoutGrid()) | 360 if (child->parent()->isLayoutGrid()) |
| 375 toLayoutGrid(child->parent())->dirtyGrid(); | 361 toLayoutGrid(child->parent())->dirtyGrid(); |
| 376 | 362 |
| 377 // Now remove the leftover anonymous block from the tree, and destroy it. | 363 // Now remove the leftover anonymous block from the tree, and destroy it. We'l
l rip it out |
| 378 // We'll rip it out manually from the tree before destroying it, because we | 364 // manually from the tree before destroying it, because we don't want to trigg
er any tree |
| 379 // don't want to trigger any tree adjustments with regards to anonymous blocks | 365 // adjustments with regards to anonymous blocks (or any other kind of undesire
d chain-reaction). |
| 380 // (or any other kind of undesired chain-reaction). | |
| 381 children()->removeChildNode(this, child, false); | 366 children()->removeChildNode(this, child, false); |
| 382 child->destroy(); | 367 child->destroy(); |
| 383 } | 368 } |
| 384 | 369 |
| 385 void LayoutBlock::updateAfterLayout() { | 370 void LayoutBlock::updateAfterLayout() { |
| 386 invalidateStickyConstraints(); | 371 invalidateStickyConstraints(); |
| 387 | 372 |
| 388 // Update our scroll information if we're overflow:auto/scroll/hidden now that | 373 // Update our scroll information if we're overflow:auto/scroll/hidden now that
we know if |
| 389 // we know if we overflow or not. | 374 // we overflow or not. |
| 390 if (hasOverflowClip()) | 375 if (hasOverflowClip()) |
| 391 layer()->getScrollableArea()->updateAfterLayout(); | 376 layer()->getScrollableArea()->updateAfterLayout(); |
| 392 } | 377 } |
| 393 | 378 |
| 394 void LayoutBlock::layout() { | 379 void LayoutBlock::layout() { |
| 395 DCHECK(!getScrollableArea() || getScrollableArea()->scrollAnchor()); | 380 DCHECK(!getScrollableArea() || getScrollableArea()->scrollAnchor()); |
| 396 | 381 |
| 397 LayoutAnalyzer::Scope analyzer(*this); | 382 LayoutAnalyzer::Scope analyzer(*this); |
| 398 | 383 |
| 399 bool needsScrollAnchoring = | 384 bool needsScrollAnchoring = |
| 400 hasOverflowClip() && getScrollableArea()->shouldPerformScrollAnchoring(); | 385 hasOverflowClip() && getScrollableArea()->shouldPerformScrollAnchoring(); |
| 401 if (needsScrollAnchoring) | 386 if (needsScrollAnchoring) |
| 402 getScrollableArea()->scrollAnchor()->save(); | 387 getScrollableArea()->scrollAnchor()->save(); |
| 403 | 388 |
| 404 // Table cells call layoutBlock directly, so don't add any logic here. Put | 389 // Table cells call layoutBlock directly, so don't add any logic here. Put co
de into |
| 405 // code into layoutBlock(). | 390 // layoutBlock(). |
| 406 layoutBlock(false); | 391 layoutBlock(false); |
| 407 | 392 |
| 408 // It's safe to check for control clip here, since controls can never be table | 393 // It's safe to check for control clip here, since controls can never be table
cells. |
| 409 // cells. If we have a lightweight clip, there can never be any overflow from | 394 // If we have a lightweight clip, there can never be any overflow from childre
n. |
| 410 // children. | |
| 411 if (hasControlClip() && m_overflow) | 395 if (hasControlClip() && m_overflow) |
| 412 clearLayoutOverflow(); | 396 clearLayoutOverflow(); |
| 413 | 397 |
| 414 invalidateBackgroundObscurationStatus(); | 398 invalidateBackgroundObscurationStatus(); |
| 415 | 399 |
| 416 // If clamping is delayed, we will restore in | 400 // If clamping is delayed, we will restore in PaintLayerScrollableArea::clampS
crollPositionsAfterLayout. |
| 417 // PaintLayerScrollableArea::clampScrollPositionsAfterLayout. | 401 // Restoring during the intermediate layout may clamp the scroller to the wron
g bounds. |
| 418 // Restoring during the intermediate layout may clamp the scroller to the | |
| 419 // wrong bounds. | |
| 420 bool clampingDelayed = PaintLayerScrollableArea:: | 402 bool clampingDelayed = PaintLayerScrollableArea:: |
| 421 DelayScrollPositionClampScope::clampingIsDelayed(); | 403 DelayScrollPositionClampScope::clampingIsDelayed(); |
| 422 if (needsScrollAnchoring && !clampingDelayed) | 404 if (needsScrollAnchoring && !clampingDelayed) |
| 423 getScrollableArea()->scrollAnchor()->restore(); | 405 getScrollableArea()->scrollAnchor()->restore(); |
| 424 | 406 |
| 425 m_heightAvailableToChildrenChanged = false; | 407 m_heightAvailableToChildrenChanged = false; |
| 426 } | 408 } |
| 427 | 409 |
| 428 bool LayoutBlock::widthAvailableToChildrenHasChanged() { | 410 bool LayoutBlock::widthAvailableToChildrenHasChanged() { |
| 429 // TODO(robhogan): Does m_widthAvailableToChildrenChanged always get reset | 411 // TODO(robhogan): Does m_widthAvailableToChildrenChanged always get reset whe
n it needs to? |
| 430 // when it needs to? | |
| 431 bool widthAvailableToChildrenHasChanged = m_widthAvailableToChildrenChanged; | 412 bool widthAvailableToChildrenHasChanged = m_widthAvailableToChildrenChanged; |
| 432 m_widthAvailableToChildrenChanged = false; | 413 m_widthAvailableToChildrenChanged = false; |
| 433 | 414 |
| 434 // If we use border-box sizing, have percentage padding, and our parent has | 415 // If we use border-box sizing, have percentage padding, and our parent has ch
anged width then the width available to our children has changed even |
| 435 // changed width then the width available to our children has changed even | |
| 436 // though our own width has remained the same. | 416 // though our own width has remained the same. |
| 437 widthAvailableToChildrenHasChanged |= | 417 widthAvailableToChildrenHasChanged |= |
| 438 style()->boxSizing() == BoxSizingBorderBox && | 418 style()->boxSizing() == BoxSizingBorderBox && |
| 439 needsPreferredWidthsRecalculation() && | 419 needsPreferredWidthsRecalculation() && |
| 440 view()->layoutState()->containingBlockLogicalWidthChanged(); | 420 view()->layoutState()->containingBlockLogicalWidthChanged(); |
| 441 | 421 |
| 442 return widthAvailableToChildrenHasChanged; | 422 return widthAvailableToChildrenHasChanged; |
| 443 } | 423 } |
| 444 | 424 |
| 445 DISABLE_CFI_PERF | 425 DISABLE_CFI_PERF |
| (...skipping 19 matching lines...) Expand all Loading... |
| 465 void LayoutBlock::computeOverflow(LayoutUnit oldClientAfterEdge, bool) { | 445 void LayoutBlock::computeOverflow(LayoutUnit oldClientAfterEdge, bool) { |
| 466 m_overflow.reset(); | 446 m_overflow.reset(); |
| 467 | 447 |
| 468 // Add overflow from children. | 448 // Add overflow from children. |
| 469 addOverflowFromChildren(); | 449 addOverflowFromChildren(); |
| 470 | 450 |
| 471 // Add in the overflow from positioned objects. | 451 // Add in the overflow from positioned objects. |
| 472 addOverflowFromPositionedObjects(); | 452 addOverflowFromPositionedObjects(); |
| 473 | 453 |
| 474 if (hasOverflowClip()) { | 454 if (hasOverflowClip()) { |
| 475 // When we have overflow clip, propagate the original spillout since it will | 455 // When we have overflow clip, propagate the original spillout since it will
include collapsed bottom margins |
| 476 // include collapsed bottom margins and bottom padding. Set the axis we | 456 // and bottom padding. Set the axis we don't care about to be 1, since we w
ant this overflow to always |
| 477 // don't care about to be 1, since we want this overflow to always be | 457 // be considered reachable. |
| 478 // considered reachable. | |
| 479 LayoutRect clientRect(noOverflowRect()); | 458 LayoutRect clientRect(noOverflowRect()); |
| 480 LayoutRect rectToApply; | 459 LayoutRect rectToApply; |
| 481 if (isHorizontalWritingMode()) | 460 if (isHorizontalWritingMode()) |
| 482 rectToApply = LayoutRect( | 461 rectToApply = LayoutRect( |
| 483 clientRect.x(), clientRect.y(), LayoutUnit(1), | 462 clientRect.x(), clientRect.y(), LayoutUnit(1), |
| 484 (oldClientAfterEdge - clientRect.y()).clampNegativeToZero()); | 463 (oldClientAfterEdge - clientRect.y()).clampNegativeToZero()); |
| 485 else | 464 else |
| 486 rectToApply = LayoutRect( | 465 rectToApply = LayoutRect( |
| 487 clientRect.x(), clientRect.y(), | 466 clientRect.x(), clientRect.y(), |
| 488 (oldClientAfterEdge - clientRect.x()).clampNegativeToZero(), | 467 (oldClientAfterEdge - clientRect.x()).clampNegativeToZero(), |
| 489 LayoutUnit(1)); | 468 LayoutUnit(1)); |
| 490 addLayoutOverflow(rectToApply); | 469 addLayoutOverflow(rectToApply); |
| 491 if (hasOverflowModel()) | 470 if (hasOverflowModel()) |
| 492 m_overflow->setLayoutClientAfterEdge(oldClientAfterEdge); | 471 m_overflow->setLayoutClientAfterEdge(oldClientAfterEdge); |
| 493 } | 472 } |
| 494 | 473 |
| 495 addVisualEffectOverflow(); | 474 addVisualEffectOverflow(); |
| 496 addVisualOverflowFromTheme(); | 475 addVisualOverflowFromTheme(); |
| 497 | 476 |
| 498 // An enclosing composited layer will need to update its bounds if we now | 477 // An enclosing composited layer will need to update its bounds if we now over
flow it. |
| 499 // overflow it. | |
| 500 PaintLayer* layer = enclosingLayer(); | 478 PaintLayer* layer = enclosingLayer(); |
| 501 if (!needsLayout() && layer->hasCompositedLayerMapping() && | 479 if (!needsLayout() && layer->hasCompositedLayerMapping() && |
| 502 !layer->visualRect().contains(visualOverflowRect())) | 480 !layer->visualRect().contains(visualOverflowRect())) |
| 503 layer->setNeedsCompositingInputsUpdate(); | 481 layer->setNeedsCompositingInputsUpdate(); |
| 504 } | 482 } |
| 505 | 483 |
| 506 void LayoutBlock::addOverflowFromBlockChildren() { | 484 void LayoutBlock::addOverflowFromBlockChildren() { |
| 507 for (LayoutBox* child = firstChildBox(); child; | 485 for (LayoutBox* child = firstChildBox(); child; |
| 508 child = child->nextSiblingBox()) { | 486 child = child->nextSiblingBox()) { |
| 509 if (!child->isFloatingOrOutOfFlowPositioned() && !child->isColumnSpanAll()) | 487 if (!child->isFloatingOrOutOfFlowPositioned() && !child->isColumnSpanAll()) |
| 510 addOverflowFromChild(child); | 488 addOverflowFromChild(child); |
| 511 } | 489 } |
| 512 } | 490 } |
| 513 | 491 |
| 514 void LayoutBlock::addOverflowFromPositionedObjects() { | 492 void LayoutBlock::addOverflowFromPositionedObjects() { |
| 515 TrackedLayoutBoxListHashSet* positionedDescendants = positionedObjects(); | 493 TrackedLayoutBoxListHashSet* positionedDescendants = positionedObjects(); |
| 516 if (!positionedDescendants) | 494 if (!positionedDescendants) |
| 517 return; | 495 return; |
| 518 | 496 |
| 519 for (auto* positionedObject : *positionedDescendants) { | 497 for (auto* positionedObject : *positionedDescendants) { |
| 520 // Fixed positioned elements don't contribute to layout overflow, since they | 498 // Fixed positioned elements don't contribute to layout overflow, since they
don't scroll with the content. |
| 521 // don't scroll with the content. | |
| 522 if (positionedObject->style()->position() != FixedPosition) | 499 if (positionedObject->style()->position() != FixedPosition) |
| 523 addOverflowFromChild(positionedObject, | 500 addOverflowFromChild(positionedObject, |
| 524 toLayoutSize(positionedObject->location())); | 501 toLayoutSize(positionedObject->location())); |
| 525 } | 502 } |
| 526 } | 503 } |
| 527 | 504 |
| 528 void LayoutBlock::addVisualOverflowFromTheme() { | 505 void LayoutBlock::addVisualOverflowFromTheme() { |
| 529 if (!style()->hasAppearance()) | 506 if (!style()->hasAppearance()) |
| 530 return; | 507 return; |
| 531 | 508 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 549 LayoutBox& child) { | 526 LayoutBox& child) { |
| 550 if (parent->style()->boxSizing() != BoxSizingBorderBox) | 527 if (parent->style()->boxSizing() != BoxSizingBorderBox) |
| 551 return false; | 528 return false; |
| 552 return parent->style()->isHorizontalWritingMode() && | 529 return parent->style()->isHorizontalWritingMode() && |
| 553 !child.style()->isHorizontalWritingMode(); | 530 !child.style()->isHorizontalWritingMode(); |
| 554 } | 531 } |
| 555 | 532 |
| 556 void LayoutBlock::updateBlockChildDirtyBitsBeforeLayout(bool relayoutChildren, | 533 void LayoutBlock::updateBlockChildDirtyBitsBeforeLayout(bool relayoutChildren, |
| 557 LayoutBox& child) { | 534 LayoutBox& child) { |
| 558 if (child.isOutOfFlowPositioned()) { | 535 if (child.isOutOfFlowPositioned()) { |
| 559 // It's rather useless to mark out-of-flow children at this point. We may | 536 // It's rather useless to mark out-of-flow children at this point. We may no
t be their |
| 560 // not be their containing block (and if we are, it's just pure luck), so | 537 // containing block (and if we are, it's just pure luck), so this would be t
he wrong place |
| 561 // this would be the wrong place for it. Furthermore, it would cause trouble | 538 // for it. Furthermore, it would cause trouble for out-of-flow descendants o
f column |
| 562 // for out-of-flow descendants of column spanners, if the containing block | 539 // spanners, if the containing block is outside the spanner but inside the m
ulticol container. |
| 563 // is outside the spanner but inside the multicol container. | |
| 564 return; | 540 return; |
| 565 } | 541 } |
| 566 // FIXME: Technically percentage height objects only need a relayout if their | 542 // FIXME: Technically percentage height objects only need a relayout if their
percentage isn't going to be turned into |
| 567 // percentage isn't going to be turned into an auto value. Add a method to | 543 // an auto value. Add a method to determine this, so that we can avoid the rel
ayout. |
| 568 // determine this, so that we can avoid the relayout. | |
| 569 bool hasRelativeLogicalHeight = | 544 bool hasRelativeLogicalHeight = |
| 570 child.hasRelativeLogicalHeight() || | 545 child.hasRelativeLogicalHeight() || |
| 571 (child.isAnonymous() && this->hasRelativeLogicalHeight()) || | 546 (child.isAnonymous() && this->hasRelativeLogicalHeight()) || |
| 572 child.stretchesToViewport(); | 547 child.stretchesToViewport(); |
| 573 if (relayoutChildren || (hasRelativeLogicalHeight && !isLayoutView()) || | 548 if (relayoutChildren || (hasRelativeLogicalHeight && !isLayoutView()) || |
| 574 (m_heightAvailableToChildrenChanged && | 549 (m_heightAvailableToChildrenChanged && |
| 575 changeInAvailableLogicalHeightAffectsChild(this, child))) { | 550 changeInAvailableLogicalHeightAffectsChild(this, child))) { |
| 576 child.setChildNeedsLayout(MarkOnlyThis); | 551 child.setChildNeedsLayout(MarkOnlyThis); |
| 577 | 552 |
| 578 // If the child has percentage padding or an embedded content box, we also | 553 // If the child has percentage padding or an embedded content box, we also n
eed to invalidate the childs pref widths. |
| 579 // need to invalidate the childs pref widths. | |
| 580 if (child.needsPreferredWidthsRecalculation()) | 554 if (child.needsPreferredWidthsRecalculation()) |
| 581 child.setPreferredLogicalWidthsDirty(MarkOnlyThis); | 555 child.setPreferredLogicalWidthsDirty(MarkOnlyThis); |
| 582 } | 556 } |
| 583 } | 557 } |
| 584 | 558 |
| 585 void LayoutBlock::simplifiedNormalFlowLayout() { | 559 void LayoutBlock::simplifiedNormalFlowLayout() { |
| 586 if (childrenInline()) { | 560 if (childrenInline()) { |
| 587 ASSERT_WITH_SECURITY_IMPLICATION(isLayoutBlockFlow()); | 561 ASSERT_WITH_SECURITY_IMPLICATION(isLayoutBlockFlow()); |
| 588 LayoutBlockFlow* blockFlow = toLayoutBlockFlow(this); | 562 LayoutBlockFlow* blockFlow = toLayoutBlockFlow(this); |
| 589 blockFlow->simplifiedNormalFlowInlineLayout(); | 563 blockFlow->simplifiedNormalFlowInlineLayout(); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 617 !tryLayoutDoingPositionedMovementOnly()) | 591 !tryLayoutDoingPositionedMovementOnly()) |
| 618 return false; | 592 return false; |
| 619 | 593 |
| 620 if (LayoutFlowThread* flowThread = flowThreadContainingBlock()) { | 594 if (LayoutFlowThread* flowThread = flowThreadContainingBlock()) { |
| 621 if (!flowThread->canSkipLayout(*this)) | 595 if (!flowThread->canSkipLayout(*this)) |
| 622 return false; | 596 return false; |
| 623 } | 597 } |
| 624 | 598 |
| 625 TextAutosizer::LayoutScope textAutosizerLayoutScope(this); | 599 TextAutosizer::LayoutScope textAutosizerLayoutScope(this); |
| 626 | 600 |
| 627 // Lay out positioned descendants or objects that just need to recompute | 601 // Lay out positioned descendants or objects that just need to recompute ove
rflow. |
| 628 // overflow. | |
| 629 if (needsSimplifiedNormalFlowLayout()) | 602 if (needsSimplifiedNormalFlowLayout()) |
| 630 simplifiedNormalFlowLayout(); | 603 simplifiedNormalFlowLayout(); |
| 631 | 604 |
| 632 // Lay out our positioned objects if our positioned child bit is set. | 605 // Lay out our positioned objects if our positioned child bit is set. |
| 633 // Also, if an absolute position element inside a relative positioned | 606 // Also, if an absolute position element inside a relative positioned contai
ner moves, and the absolute element has a fixed position |
| 634 // container moves, and the absolute element has a fixed position child | 607 // child, neither the fixed element nor its container learn of the movement
since posChildNeedsLayout() is only marked as far as the |
| 635 // neither the fixed element nor its container learn of the movement since | 608 // relative positioned container. So if we can have fixed pos objects in our
positioned objects list check if any of them |
| 636 // posChildNeedsLayout() is only marked as far as the relative positioned | 609 // are statically positioned and thus need to move with their absolute ances
tors. |
| 637 // container. So if we can have fixed pos objects in our positioned objects | |
| 638 // list check if any of them are statically positioned and thus need to move | |
| 639 // with their absolute ancestors. | |
| 640 bool canContainFixedPosObjects = canContainFixedPositionObjects(); | 610 bool canContainFixedPosObjects = canContainFixedPositionObjects(); |
| 641 if (posChildNeedsLayout() || needsPositionedMovementLayout() || | 611 if (posChildNeedsLayout() || needsPositionedMovementLayout() || |
| 642 canContainFixedPosObjects) | 612 canContainFixedPosObjects) |
| 643 layoutPositionedObjects( | 613 layoutPositionedObjects( |
| 644 false, needsPositionedMovementLayout() | 614 false, needsPositionedMovementLayout() |
| 645 ? ForcedLayoutAfterContainingBlockMoved | 615 ? ForcedLayoutAfterContainingBlockMoved |
| 646 : (!posChildNeedsLayout() && canContainFixedPosObjects | 616 : (!posChildNeedsLayout() && canContainFixedPosObjects |
| 647 ? LayoutOnlyFixedPositionedObjects | 617 ? LayoutOnlyFixedPositionedObjects |
| 648 : DefaultLayout)); | 618 : DefaultLayout)); |
| 649 | 619 |
| 650 // Recompute our overflow information. | 620 // Recompute our overflow information. |
| 651 // FIXME: We could do better here by computing a temporary overflow object | 621 // FIXME: We could do better here by computing a temporary overflow object f
rom layoutPositionedObjects and only |
| 652 // from layoutPositionedObjects and only updating our overflow if we either | 622 // updating our overflow if we either used to have overflow or if the new te
mporary object has overflow. |
| 653 // used to have overflow or if the new temporary object has overflow. | 623 // For now just always recompute overflow. This is no worse performance-wise
than the old code that called rightmostPosition and |
| 654 // For now just always recompute overflow. This is no worse performance-wise | 624 // lowestPosition on every relayout so it's not a regression. |
| 655 // than the old code that called rightmostPosition and lowestPosition on | 625 // computeOverflow expects the bottom edge before we clamp our height. Since
this information isn't available during |
| 656 // every relayout so it's not a regression. computeOverflow expects the | 626 // simplifiedLayout, we cache the value in m_overflow. |
| 657 // bottom edge before we clamp our height. Since this information isn't | |
| 658 // available during simplifiedLayout, we cache the value in m_overflow. | |
| 659 LayoutUnit oldClientAfterEdge = hasOverflowModel() | 627 LayoutUnit oldClientAfterEdge = hasOverflowModel() |
| 660 ? m_overflow->layoutClientAfterEdge() | 628 ? m_overflow->layoutClientAfterEdge() |
| 661 : clientLogicalBottom(); | 629 : clientLogicalBottom(); |
| 662 computeOverflow(oldClientAfterEdge, true); | 630 computeOverflow(oldClientAfterEdge, true); |
| 663 } | 631 } |
| 664 | 632 |
| 665 updateLayerTransformAfterLayout(); | 633 updateLayerTransformAfterLayout(); |
| 666 | 634 |
| 667 updateAfterLayout(); | 635 updateAfterLayout(); |
| 668 | 636 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 717 Length marginRight = child.style()->marginEndUsing(style()); | 685 Length marginRight = child.style()->marginEndUsing(style()); |
| 718 LayoutUnit margin; | 686 LayoutUnit margin; |
| 719 if (marginLeft.isFixed()) | 687 if (marginLeft.isFixed()) |
| 720 margin += marginLeft.value(); | 688 margin += marginLeft.value(); |
| 721 if (marginRight.isFixed()) | 689 if (marginRight.isFixed()) |
| 722 margin += marginRight.value(); | 690 margin += marginRight.value(); |
| 723 return margin; | 691 return margin; |
| 724 } | 692 } |
| 725 | 693 |
| 726 static bool needsLayoutDueToStaticPosition(LayoutBox* child) { | 694 static bool needsLayoutDueToStaticPosition(LayoutBox* child) { |
| 727 // When a non-positioned block element moves, it may have positioned children | 695 // When a non-positioned block element moves, it may have positioned children
that are |
| 728 // that are implicitly positioned relative to the non-positioned block. | 696 // implicitly positioned relative to the non-positioned block. |
| 729 const ComputedStyle* style = child->style(); | 697 const ComputedStyle* style = child->style(); |
| 730 bool isHorizontal = style->isHorizontalWritingMode(); | 698 bool isHorizontal = style->isHorizontalWritingMode(); |
| 731 if (style->hasStaticBlockPosition(isHorizontal)) { | 699 if (style->hasStaticBlockPosition(isHorizontal)) { |
| 732 LayoutBox::LogicalExtentComputedValues computedValues; | 700 LayoutBox::LogicalExtentComputedValues computedValues; |
| 733 LayoutUnit currentLogicalTop = child->logicalTop(); | 701 LayoutUnit currentLogicalTop = child->logicalTop(); |
| 734 LayoutUnit currentLogicalHeight = child->logicalHeight(); | 702 LayoutUnit currentLogicalHeight = child->logicalHeight(); |
| 735 child->computeLogicalHeight(currentLogicalHeight, currentLogicalTop, | 703 child->computeLogicalHeight(currentLogicalHeight, currentLogicalTop, |
| 736 computedValues); | 704 computedValues); |
| 737 if (computedValues.m_position != currentLogicalTop || | 705 if (computedValues.m_position != currentLogicalTop || |
| 738 computedValues.m_extent != currentLogicalHeight) | 706 computedValues.m_extent != currentLogicalHeight) |
| (...skipping 16 matching lines...) Expand all Loading... |
| 755 TrackedLayoutBoxListHashSet* positionedDescendants = positionedObjects(); | 723 TrackedLayoutBoxListHashSet* positionedDescendants = positionedObjects(); |
| 756 if (!positionedDescendants) | 724 if (!positionedDescendants) |
| 757 return; | 725 return; |
| 758 | 726 |
| 759 bool isPaginated = view()->layoutState()->isPaginated(); | 727 bool isPaginated = view()->layoutState()->isPaginated(); |
| 760 | 728 |
| 761 for (auto* positionedObject : *positionedDescendants) { | 729 for (auto* positionedObject : *positionedDescendants) { |
| 762 positionedObject->setMayNeedPaintInvalidation(); | 730 positionedObject->setMayNeedPaintInvalidation(); |
| 763 | 731 |
| 764 SubtreeLayoutScope layoutScope(*positionedObject); | 732 SubtreeLayoutScope layoutScope(*positionedObject); |
| 765 // A fixed position element with an absolute positioned ancestor has no way | 733 // A fixed position element with an absolute positioned ancestor has no way
of knowing if the latter has changed position. So |
| 766 // of knowing if the latter has changed position. So if this is a fixed | 734 // if this is a fixed position element, mark it for layout if it has an absp
os ancestor and needs to move with that ancestor, i.e. |
| 767 // position element, mark it for layout if it has an abspos ancestor and | 735 // it has static position. |
| 768 // needs to move with that ancestor, i.e. it has static position. | |
| 769 markFixedPositionObjectForLayoutIfNeeded(positionedObject, layoutScope); | 736 markFixedPositionObjectForLayoutIfNeeded(positionedObject, layoutScope); |
| 770 if (info == LayoutOnlyFixedPositionedObjects) { | 737 if (info == LayoutOnlyFixedPositionedObjects) { |
| 771 positionedObject->layoutIfNeeded(); | 738 positionedObject->layoutIfNeeded(); |
| 772 continue; | 739 continue; |
| 773 } | 740 } |
| 774 | 741 |
| 775 if (!positionedObject->normalChildNeedsLayout() && | 742 if (!positionedObject->normalChildNeedsLayout() && |
| 776 (relayoutChildren || m_heightAvailableToChildrenChanged || | 743 (relayoutChildren || m_heightAvailableToChildrenChanged || |
| 777 needsLayoutDueToStaticPosition(positionedObject))) | 744 needsLayoutDueToStaticPosition(positionedObject))) |
| 778 layoutScope.setChildNeedsLayout(positionedObject); | 745 layoutScope.setChildNeedsLayout(positionedObject); |
| 779 | 746 |
| 780 // If relayoutChildren is set and the child has percentage padding or an | 747 // If relayoutChildren is set and the child has percentage padding or an emb
edded content box, we also need to invalidate the childs pref widths. |
| 781 // embedded content box, we also need to invalidate the childs pref widths. | |
| 782 if (relayoutChildren && | 748 if (relayoutChildren && |
| 783 positionedObject->needsPreferredWidthsRecalculation()) | 749 positionedObject->needsPreferredWidthsRecalculation()) |
| 784 positionedObject->setPreferredLogicalWidthsDirty(MarkOnlyThis); | 750 positionedObject->setPreferredLogicalWidthsDirty(MarkOnlyThis); |
| 785 | 751 |
| 786 LayoutUnit logicalTopEstimate; | 752 LayoutUnit logicalTopEstimate; |
| 787 bool needsBlockDirectionLocationSetBeforeLayout = | 753 bool needsBlockDirectionLocationSetBeforeLayout = |
| 788 isPaginated && | 754 isPaginated && |
| 789 positionedObject->getPaginationBreakability() != ForbidBreaks; | 755 positionedObject->getPaginationBreakability() != ForbidBreaks; |
| 790 if (needsBlockDirectionLocationSetBeforeLayout) { | 756 if (needsBlockDirectionLocationSetBeforeLayout) { |
| 791 // Out-of-flow objects are normally positioned after layout (while in-flow | 757 // Out-of-flow objects are normally positioned after layout (while in-flow
objects are |
| 792 // objects are positioned before layout). If the child object is paginated | 758 // positioned before layout). If the child object is paginated in the same
context as |
| 793 // in the same context as we are, estimate its logical top now. We need to | 759 // we are, estimate its logical top now. We need to know this up-front, to
correctly |
| 794 // know this up-front, to correctly evaluate if we need to mark for | 760 // evaluate if we need to mark for relayout, and, if our estimate is corre
ct, we'll |
| 795 // relayout, and, if our estimate is correct, we'll even be able to insert | 761 // even be able to insert correct pagination struts on the first attempt. |
| 796 // correct pagination struts on the first attempt. | |
| 797 LogicalExtentComputedValues computedValues; | 762 LogicalExtentComputedValues computedValues; |
| 798 positionedObject->computeLogicalHeight(positionedObject->logicalHeight(), | 763 positionedObject->computeLogicalHeight(positionedObject->logicalHeight(), |
| 799 positionedObject->logicalTop(), | 764 positionedObject->logicalTop(), |
| 800 computedValues); | 765 computedValues); |
| 801 logicalTopEstimate = computedValues.m_position; | 766 logicalTopEstimate = computedValues.m_position; |
| 802 positionedObject->setLogicalTop(logicalTopEstimate); | 767 positionedObject->setLogicalTop(logicalTopEstimate); |
| 803 } | 768 } |
| 804 | 769 |
| 805 if (!positionedObject->needsLayout()) | 770 if (!positionedObject->needsLayout()) |
| 806 markChildForPaginationRelayoutIfNeeded(*positionedObject, layoutScope); | 771 markChildForPaginationRelayoutIfNeeded(*positionedObject, layoutScope); |
| 807 | 772 |
| 808 // FIXME: We should be able to do a r->setNeedsPositionedMovementLayout() | 773 // FIXME: We should be able to do a r->setNeedsPositionedMovementLayout() he
re instead of a full layout. Need |
| 809 // here instead of a full layout. Need to investigate why it does not | 774 // to investigate why it does not trigger the correct invalidations in that
case. crbug.com/350756 |
| 810 // trigger the correct invalidations in that case. crbug.com/350756 | |
| 811 if (info == ForcedLayoutAfterContainingBlockMoved) | 775 if (info == ForcedLayoutAfterContainingBlockMoved) |
| 812 positionedObject->setNeedsLayout(LayoutInvalidationReason::AncestorMoved, | 776 positionedObject->setNeedsLayout(LayoutInvalidationReason::AncestorMoved, |
| 813 MarkOnlyThis); | 777 MarkOnlyThis); |
| 814 | 778 |
| 815 positionedObject->layoutIfNeeded(); | 779 positionedObject->layoutIfNeeded(); |
| 816 | 780 |
| 817 LayoutObject* parent = positionedObject->parent(); | 781 LayoutObject* parent = positionedObject->parent(); |
| 818 bool layoutChanged = false; | 782 bool layoutChanged = false; |
| 819 if (parent->isFlexibleBox() && | 783 if (parent->isFlexibleBox() && |
| 820 toLayoutFlexibleBox(parent)->setStaticPositionForPositionedLayout( | 784 toLayoutFlexibleBox(parent)->setStaticPositionForPositionedLayout( |
| 821 *positionedObject)) { | 785 *positionedObject)) { |
| 822 // The static position of an abspos child of a flexbox depends on its size | 786 // The static position of an abspos child of a flexbox depends on its size
(for example, |
| 823 // (for example, they can be centered). So we may have to reposition the | 787 // they can be centered). So we may have to reposition the item after layo
ut. |
| 824 // item after layout. | 788 // TODO(cbiesinger): We could probably avoid a layout here and just reposi
tion? |
| 825 // TODO(cbiesinger): We could probably avoid a layout here and just | |
| 826 // reposition? | |
| 827 positionedObject->forceChildLayout(); | 789 positionedObject->forceChildLayout(); |
| 828 layoutChanged = true; | 790 layoutChanged = true; |
| 829 } | 791 } |
| 830 | 792 |
| 831 // Lay out again if our estimate was wrong. | 793 // Lay out again if our estimate was wrong. |
| 832 if (!layoutChanged && needsBlockDirectionLocationSetBeforeLayout && | 794 if (!layoutChanged && needsBlockDirectionLocationSetBeforeLayout && |
| 833 logicalTopEstimate != logicalTopForChild(*positionedObject)) | 795 logicalTopEstimate != logicalTopForChild(*positionedObject)) |
| 834 positionedObject->forceChildLayout(); | 796 positionedObject->forceChildLayout(); |
| 835 } | 797 } |
| 836 } | 798 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 856 void LayoutBlock::paintObject(const PaintInfo& paintInfo, | 818 void LayoutBlock::paintObject(const PaintInfo& paintInfo, |
| 857 const LayoutPoint& paintOffset) const { | 819 const LayoutPoint& paintOffset) const { |
| 858 BlockPainter(*this).paintObject(paintInfo, paintOffset); | 820 BlockPainter(*this).paintObject(paintInfo, paintOffset); |
| 859 } | 821 } |
| 860 | 822 |
| 861 bool LayoutBlock::isSelectionRoot() const { | 823 bool LayoutBlock::isSelectionRoot() const { |
| 862 if (isPseudoElement()) | 824 if (isPseudoElement()) |
| 863 return false; | 825 return false; |
| 864 ASSERT(node() || isAnonymous()); | 826 ASSERT(node() || isAnonymous()); |
| 865 | 827 |
| 866 // FIXME: Eventually tables should have to learn how to fill gaps between | 828 // FIXME: Eventually tables should have to learn how to fill gaps between cell
s, at least in simple non-spanning cases. |
| 867 // cells, at least in simple non-spanning cases. | |
| 868 if (isTable()) | 829 if (isTable()) |
| 869 return false; | 830 return false; |
| 870 | 831 |
| 871 if (isBody() || isDocumentElement() || hasOverflowClip() || isPositioned() || | 832 if (isBody() || isDocumentElement() || hasOverflowClip() || isPositioned() || |
| 872 isFloating() || isTableCell() || isInlineBlockOrInlineTable() || | 833 isFloating() || isTableCell() || isInlineBlockOrInlineTable() || |
| 873 hasTransformRelatedProperty() || hasReflection() || hasMask() || | 834 hasTransformRelatedProperty() || hasReflection() || hasMask() || |
| 874 isWritingModeRoot() || isLayoutFlowThread() || | 835 isWritingModeRoot() || isLayoutFlowThread() || |
| 875 isFlexItemIncludingDeprecated()) | 836 isFlexItemIncludingDeprecated()) |
| 876 return true; | 837 return true; |
| 877 | 838 |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1029 return; | 990 return; |
| 1030 | 991 |
| 1031 Vector<LayoutBox*, 16> deadObjects; | 992 Vector<LayoutBox*, 16> deadObjects; |
| 1032 for (auto* positionedObject : *positionedDescendants) { | 993 for (auto* positionedObject : *positionedDescendants) { |
| 1033 if (!o || (positionedObject->isDescendantOf(o) && o != positionedObject)) { | 994 if (!o || (positionedObject->isDescendantOf(o) && o != positionedObject)) { |
| 1034 if (containingBlockState == NewContainingBlock) { | 995 if (containingBlockState == NewContainingBlock) { |
| 1035 positionedObject->setChildNeedsLayout(MarkOnlyThis); | 996 positionedObject->setChildNeedsLayout(MarkOnlyThis); |
| 1036 if (positionedObject->needsPreferredWidthsRecalculation()) | 997 if (positionedObject->needsPreferredWidthsRecalculation()) |
| 1037 positionedObject->setPreferredLogicalWidthsDirty(MarkOnlyThis); | 998 positionedObject->setPreferredLogicalWidthsDirty(MarkOnlyThis); |
| 1038 | 999 |
| 1039 // The positioned object changing containing block may change paint | 1000 // The positioned object changing containing block may change paint inva
lidation container. |
| 1040 // invalidation container. | 1001 // Invalidate it (including non-compositing descendants) on its original
paint invalidation container. |
| 1041 // Invalidate it (including non-compositing descendants) on its original | |
| 1042 // paint invalidation container. | |
| 1043 if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { | 1002 if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { |
| 1044 // This valid because we need to invalidate based on the current | 1003 // This valid because we need to invalidate based on the current statu
s. |
| 1045 // status. | |
| 1046 DisableCompositingQueryAsserts compositingDisabler; | 1004 DisableCompositingQueryAsserts compositingDisabler; |
| 1047 if (!positionedObject->isPaintInvalidationContainer()) | 1005 if (!positionedObject->isPaintInvalidationContainer()) |
| 1048 ObjectPaintInvalidator(*positionedObject) | 1006 ObjectPaintInvalidator(*positionedObject) |
| 1049 .invalidatePaintIncludingNonCompositingDescendants(); | 1007 .invalidatePaintIncludingNonCompositingDescendants(); |
| 1050 } | 1008 } |
| 1051 } | 1009 } |
| 1052 | 1010 |
| 1053 // It is parent blocks job to add positioned child to positioned objects | 1011 // It is parent blocks job to add positioned child to positioned objects l
ist of its containing block |
| 1054 // list of its containing block | |
| 1055 // Parent layout needs to be invalidated to ensure this happens. | 1012 // Parent layout needs to be invalidated to ensure this happens. |
| 1056 LayoutObject* p = positionedObject->parent(); | 1013 LayoutObject* p = positionedObject->parent(); |
| 1057 while (p && !p->isLayoutBlock()) | 1014 while (p && !p->isLayoutBlock()) |
| 1058 p = p->parent(); | 1015 p = p->parent(); |
| 1059 if (p) | 1016 if (p) |
| 1060 p->setChildNeedsLayout(); | 1017 p->setChildNeedsLayout(); |
| 1061 | 1018 |
| 1062 deadObjects.append(positionedObject); | 1019 deadObjects.append(positionedObject); |
| 1063 } | 1020 } |
| 1064 } | 1021 } |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1231 // FIXME: This function should go on LayoutObject. | 1188 // FIXME: This function should go on LayoutObject. |
| 1232 // Then all cases in which positionForPoint recurs could call this instead to | 1189 // Then all cases in which positionForPoint recurs could call this instead to |
| 1233 // prevent crossing editable boundaries. This would require many tests. | 1190 // prevent crossing editable boundaries. This would require many tests. |
| 1234 PositionWithAffinity LayoutBlock::positionForPointRespectingEditingBoundaries( | 1191 PositionWithAffinity LayoutBlock::positionForPointRespectingEditingBoundaries( |
| 1235 LineLayoutBox child, | 1192 LineLayoutBox child, |
| 1236 const LayoutPoint& pointInParentCoordinates) { | 1193 const LayoutPoint& pointInParentCoordinates) { |
| 1237 LayoutPoint childLocation = child.location(); | 1194 LayoutPoint childLocation = child.location(); |
| 1238 if (child.isInFlowPositioned()) | 1195 if (child.isInFlowPositioned()) |
| 1239 childLocation += child.offsetForInFlowPosition(); | 1196 childLocation += child.offsetForInFlowPosition(); |
| 1240 | 1197 |
| 1241 // FIXME: This is wrong if the child's writing-mode is different from the | 1198 // FIXME: This is wrong if the child's writing-mode is different from the pare
nt's. |
| 1242 // parent's. | |
| 1243 LayoutPoint pointInChildCoordinates( | 1199 LayoutPoint pointInChildCoordinates( |
| 1244 toLayoutPoint(pointInParentCoordinates - childLocation)); | 1200 toLayoutPoint(pointInParentCoordinates - childLocation)); |
| 1245 | 1201 |
| 1246 // If this is an anonymous layoutObject, we just recur normally | 1202 // If this is an anonymous layoutObject, we just recur normally |
| 1247 Node* childNode = child.nonPseudoNode(); | 1203 Node* childNode = child.nonPseudoNode(); |
| 1248 if (!childNode) | 1204 if (!childNode) |
| 1249 return child.positionForPoint(pointInChildCoordinates); | 1205 return child.positionForPoint(pointInChildCoordinates); |
| 1250 | 1206 |
| 1251 // Otherwise, first make sure that the editability of the parent and child | 1207 // Otherwise, first make sure that the editability of the parent and child agr
ee. |
| 1252 // agree. If they don't agree, then we return a visible position just before | 1208 // If they don't agree, then we return a visible position just before or after
the child |
| 1253 // or after the child | |
| 1254 LayoutObject* ancestor = this; | 1209 LayoutObject* ancestor = this; |
| 1255 while (ancestor && !ancestor->nonPseudoNode()) | 1210 while (ancestor && !ancestor->nonPseudoNode()) |
| 1256 ancestor = ancestor->parent(); | 1211 ancestor = ancestor->parent(); |
| 1257 | 1212 |
| 1258 // If we can't find an ancestor to check editability on, or editability is | 1213 // If we can't find an ancestor to check editability on, or editability is unc
hanged, we recur like normal |
| 1259 // unchanged, we recur like normal | |
| 1260 if (isEditingBoundary(ancestor, child)) | 1214 if (isEditingBoundary(ancestor, child)) |
| 1261 return child.positionForPoint(pointInChildCoordinates); | 1215 return child.positionForPoint(pointInChildCoordinates); |
| 1262 | 1216 |
| 1263 // Otherwise return before or after the child, depending on if the click was | 1217 // Otherwise return before or after the child, depending on if the click was t
o the logical left or logical right of the child |
| 1264 // to the logical left or logical right of the child | |
| 1265 LayoutUnit childMiddle = logicalWidthForChildSize(child.size()) / 2; | 1218 LayoutUnit childMiddle = logicalWidthForChildSize(child.size()) / 2; |
| 1266 LayoutUnit logicalLeft = isHorizontalWritingMode() | 1219 LayoutUnit logicalLeft = isHorizontalWritingMode() |
| 1267 ? pointInChildCoordinates.x() | 1220 ? pointInChildCoordinates.x() |
| 1268 : pointInChildCoordinates.y(); | 1221 : pointInChildCoordinates.y(); |
| 1269 if (logicalLeft < childMiddle) | 1222 if (logicalLeft < childMiddle) |
| 1270 return ancestor->createPositionWithAffinity(childNode->nodeIndex()); | 1223 return ancestor->createPositionWithAffinity(childNode->nodeIndex()); |
| 1271 return ancestor->createPositionWithAffinity(childNode->nodeIndex() + 1, | 1224 return ancestor->createPositionWithAffinity(childNode->nodeIndex() + 1, |
| 1272 TextAffinity::Upstream); | 1225 TextAffinity::Upstream); |
| 1273 } | 1226 } |
| 1274 | 1227 |
| 1275 PositionWithAffinity LayoutBlock::positionForPointIfOutsideAtomicInlineLevel( | 1228 PositionWithAffinity LayoutBlock::positionForPointIfOutsideAtomicInlineLevel( |
| 1276 const LayoutPoint& point) { | 1229 const LayoutPoint& point) { |
| 1277 ASSERT(isAtomicInlineLevel()); | 1230 ASSERT(isAtomicInlineLevel()); |
| 1278 // FIXME: This seems wrong when the object's writing-mode doesn't match the | 1231 // FIXME: This seems wrong when the object's writing-mode doesn't match the li
ne's writing-mode. |
| 1279 // line's writing-mode. | |
| 1280 LayoutUnit pointLogicalLeft = | 1232 LayoutUnit pointLogicalLeft = |
| 1281 isHorizontalWritingMode() ? point.x() : point.y(); | 1233 isHorizontalWritingMode() ? point.x() : point.y(); |
| 1282 LayoutUnit pointLogicalTop = | 1234 LayoutUnit pointLogicalTop = |
| 1283 isHorizontalWritingMode() ? point.y() : point.x(); | 1235 isHorizontalWritingMode() ? point.y() : point.x(); |
| 1284 | 1236 |
| 1285 if (pointLogicalLeft < 0) | 1237 if (pointLogicalLeft < 0) |
| 1286 return createPositionWithAffinity(caretMinOffset()); | 1238 return createPositionWithAffinity(caretMinOffset()); |
| 1287 if (pointLogicalLeft >= logicalWidth()) | 1239 if (pointLogicalLeft >= logicalWidth()) |
| 1288 return createPositionWithAffinity(caretMaxOffset()); | 1240 return createPositionWithAffinity(caretMaxOffset()); |
| 1289 if (pointLogicalTop < 0) | 1241 if (pointLogicalTop < 0) |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1329 pointInLogicalContents.y() == logicalTopForChild(*lastCandidateBox))) | 1281 pointInLogicalContents.y() == logicalTopForChild(*lastCandidateBox))) |
| 1330 return positionForPointRespectingEditingBoundaries( | 1282 return positionForPointRespectingEditingBoundaries( |
| 1331 LineLayoutBox(lastCandidateBox), pointInContents); | 1283 LineLayoutBox(lastCandidateBox), pointInContents); |
| 1332 | 1284 |
| 1333 for (LayoutBox* childBox = firstChildBox(); childBox; | 1285 for (LayoutBox* childBox = firstChildBox(); childBox; |
| 1334 childBox = childBox->nextSiblingBox()) { | 1286 childBox = childBox->nextSiblingBox()) { |
| 1335 if (!isChildHitTestCandidate(childBox)) | 1287 if (!isChildHitTestCandidate(childBox)) |
| 1336 continue; | 1288 continue; |
| 1337 LayoutUnit childLogicalBottom = | 1289 LayoutUnit childLogicalBottom = |
| 1338 logicalTopForChild(*childBox) + logicalHeightForChild(*childBox); | 1290 logicalTopForChild(*childBox) + logicalHeightForChild(*childBox); |
| 1339 // We hit child if our click is above the bottom of its padding box (like | 1291 // We hit child if our click is above the bottom of its padding box (like
IE6/7 and FF3). |
| 1340 // IE6/7 and FF3). | |
| 1341 if (isChildHitTestCandidate(childBox) && | 1292 if (isChildHitTestCandidate(childBox) && |
| 1342 (pointInLogicalContents.y() < childLogicalBottom || | 1293 (pointInLogicalContents.y() < childLogicalBottom || |
| 1343 (blocksAreFlipped && | 1294 (blocksAreFlipped && |
| 1344 pointInLogicalContents.y() == childLogicalBottom))) | 1295 pointInLogicalContents.y() == childLogicalBottom))) |
| 1345 return positionForPointRespectingEditingBoundaries( | 1296 return positionForPointRespectingEditingBoundaries( |
| 1346 LineLayoutBox(childBox), pointInContents); | 1297 LineLayoutBox(childBox), pointInContents); |
| 1347 } | 1298 } |
| 1348 } | 1299 } |
| 1349 | 1300 |
| 1350 // We only get here if there are no hit test candidate children below the | 1301 // We only get here if there are no hit test candidate children below the clic
k. |
| 1351 // click. | |
| 1352 return LayoutBox::positionForPoint(point); | 1302 return LayoutBox::positionForPoint(point); |
| 1353 } | 1303 } |
| 1354 | 1304 |
| 1355 void LayoutBlock::offsetForContents(LayoutPoint& offset) const { | 1305 void LayoutBlock::offsetForContents(LayoutPoint& offset) const { |
| 1356 offset = flipForWritingMode(offset); | 1306 offset = flipForWritingMode(offset); |
| 1357 | 1307 |
| 1358 if (hasOverflowClip()) | 1308 if (hasOverflowClip()) |
| 1359 offset += LayoutSize(scrolledContentOffset()); | 1309 offset += LayoutSize(scrolledContentOffset()); |
| 1360 | 1310 |
| 1361 offset = flipForWritingMode(offset); | 1311 offset = flipForWritingMode(offset); |
| 1362 } | 1312 } |
| 1363 | 1313 |
| 1364 int LayoutBlock::columnGap() const { | 1314 int LayoutBlock::columnGap() const { |
| 1365 if (style()->hasNormalColumnGap()) { | 1315 if (style()->hasNormalColumnGap()) |
| 1366 // "1em" is recommended as the normal gap setting. Matches <p> margins. | 1316 return style() |
| 1367 return style()->getFontDescription().computedPixelSize(); | 1317 ->getFontDescription() |
| 1368 } | 1318 .computedPixelSize(); // "1em" is recommended as the normal gap setting
. Matches <p> margins. |
| 1369 return static_cast<int>(style()->columnGap()); | 1319 return static_cast<int>(style()->columnGap()); |
| 1370 } | 1320 } |
| 1371 | 1321 |
| 1372 void LayoutBlock::scrollbarsChanged(bool horizontalScrollbarChanged, | 1322 void LayoutBlock::scrollbarsChanged(bool horizontalScrollbarChanged, |
| 1373 bool verticalScrollbarChanged) { | 1323 bool verticalScrollbarChanged) { |
| 1374 m_widthAvailableToChildrenChanged |= verticalScrollbarChanged; | 1324 m_widthAvailableToChildrenChanged |= verticalScrollbarChanged; |
| 1375 m_heightAvailableToChildrenChanged |= horizontalScrollbarChanged; | 1325 m_heightAvailableToChildrenChanged |= horizontalScrollbarChanged; |
| 1376 } | 1326 } |
| 1377 | 1327 |
| 1378 void LayoutBlock::computeIntrinsicLogicalWidths( | 1328 void LayoutBlock::computeIntrinsicLogicalWidths( |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1409 minLogicalWidth += scrollbarWidth; | 1359 minLogicalWidth += scrollbarWidth; |
| 1410 } | 1360 } |
| 1411 | 1361 |
| 1412 DISABLE_CFI_PERF | 1362 DISABLE_CFI_PERF |
| 1413 void LayoutBlock::computePreferredLogicalWidths() { | 1363 void LayoutBlock::computePreferredLogicalWidths() { |
| 1414 ASSERT(preferredLogicalWidthsDirty()); | 1364 ASSERT(preferredLogicalWidthsDirty()); |
| 1415 | 1365 |
| 1416 m_minPreferredLogicalWidth = LayoutUnit(); | 1366 m_minPreferredLogicalWidth = LayoutUnit(); |
| 1417 m_maxPreferredLogicalWidth = LayoutUnit(); | 1367 m_maxPreferredLogicalWidth = LayoutUnit(); |
| 1418 | 1368 |
| 1419 // FIXME: The isFixed() calls here should probably be checking for isSpecified | 1369 // FIXME: The isFixed() calls here should probably be checking for isSpecified
since you |
| 1420 // since you should be able to use percentage, calc or viewport relative | 1370 // should be able to use percentage, calc or viewport relative values for widt
h. |
| 1421 // values for width. | |
| 1422 const ComputedStyle& styleToUse = styleRef(); | 1371 const ComputedStyle& styleToUse = styleRef(); |
| 1423 if (!isTableCell() && styleToUse.logicalWidth().isFixed() && | 1372 if (!isTableCell() && styleToUse.logicalWidth().isFixed() && |
| 1424 styleToUse.logicalWidth().value() >= 0 && | 1373 styleToUse.logicalWidth().value() >= 0 && |
| 1425 !(isDeprecatedFlexItem() && !styleToUse.logicalWidth().intValue())) | 1374 !(isDeprecatedFlexItem() && !styleToUse.logicalWidth().intValue())) |
| 1426 m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = | 1375 m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = |
| 1427 adjustContentBoxLogicalWidthForBoxSizing( | 1376 adjustContentBoxLogicalWidthForBoxSizing( |
| 1428 LayoutUnit(styleToUse.logicalWidth().value())); | 1377 LayoutUnit(styleToUse.logicalWidth().value())); |
| 1429 else | 1378 else |
| 1430 computeIntrinsicLogicalWidths(m_minPreferredLogicalWidth, | 1379 computeIntrinsicLogicalWidths(m_minPreferredLogicalWidth, |
| 1431 m_maxPreferredLogicalWidth); | 1380 m_maxPreferredLogicalWidth); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1446 m_maxPreferredLogicalWidth = | 1395 m_maxPreferredLogicalWidth = |
| 1447 std::min(m_maxPreferredLogicalWidth, | 1396 std::min(m_maxPreferredLogicalWidth, |
| 1448 adjustContentBoxLogicalWidthForBoxSizing( | 1397 adjustContentBoxLogicalWidthForBoxSizing( |
| 1449 LayoutUnit(styleToUse.logicalMaxWidth().value()))); | 1398 LayoutUnit(styleToUse.logicalMaxWidth().value()))); |
| 1450 m_minPreferredLogicalWidth = | 1399 m_minPreferredLogicalWidth = |
| 1451 std::min(m_minPreferredLogicalWidth, | 1400 std::min(m_minPreferredLogicalWidth, |
| 1452 adjustContentBoxLogicalWidthForBoxSizing( | 1401 adjustContentBoxLogicalWidthForBoxSizing( |
| 1453 LayoutUnit(styleToUse.logicalMaxWidth().value()))); | 1402 LayoutUnit(styleToUse.logicalMaxWidth().value()))); |
| 1454 } | 1403 } |
| 1455 | 1404 |
| 1456 // Table layout uses integers, ceil the preferred widths to ensure that they | 1405 // Table layout uses integers, ceil the preferred widths to ensure that they c
an contain the contents. |
| 1457 // can contain the contents. | |
| 1458 if (isTableCell()) { | 1406 if (isTableCell()) { |
| 1459 m_minPreferredLogicalWidth = LayoutUnit(m_minPreferredLogicalWidth.ceil()); | 1407 m_minPreferredLogicalWidth = LayoutUnit(m_minPreferredLogicalWidth.ceil()); |
| 1460 m_maxPreferredLogicalWidth = LayoutUnit(m_maxPreferredLogicalWidth.ceil()); | 1408 m_maxPreferredLogicalWidth = LayoutUnit(m_maxPreferredLogicalWidth.ceil()); |
| 1461 } | 1409 } |
| 1462 | 1410 |
| 1463 LayoutUnit borderAndPadding = borderAndPaddingLogicalWidth(); | 1411 LayoutUnit borderAndPadding = borderAndPaddingLogicalWidth(); |
| 1464 m_minPreferredLogicalWidth += borderAndPadding; | 1412 m_minPreferredLogicalWidth += borderAndPadding; |
| 1465 m_maxPreferredLogicalWidth += borderAndPadding; | 1413 m_maxPreferredLogicalWidth += borderAndPadding; |
| 1466 | 1414 |
| 1467 clearPreferredLogicalWidthsDirty(); | 1415 clearPreferredLogicalWidthsDirty(); |
| 1468 } | 1416 } |
| 1469 | 1417 |
| 1470 void LayoutBlock::computeBlockPreferredLogicalWidths( | 1418 void LayoutBlock::computeBlockPreferredLogicalWidths( |
| 1471 LayoutUnit& minLogicalWidth, | 1419 LayoutUnit& minLogicalWidth, |
| 1472 LayoutUnit& maxLogicalWidth) const { | 1420 LayoutUnit& maxLogicalWidth) const { |
| 1473 const ComputedStyle& styleToUse = styleRef(); | 1421 const ComputedStyle& styleToUse = styleRef(); |
| 1474 bool nowrap = styleToUse.whiteSpace() == NOWRAP; | 1422 bool nowrap = styleToUse.whiteSpace() == NOWRAP; |
| 1475 | 1423 |
| 1476 LayoutObject* child = firstChild(); | 1424 LayoutObject* child = firstChild(); |
| 1477 LayoutBlock* containingBlock = this->containingBlock(); | 1425 LayoutBlock* containingBlock = this->containingBlock(); |
| 1478 LayoutUnit floatLeftWidth, floatRightWidth; | 1426 LayoutUnit floatLeftWidth, floatRightWidth; |
| 1479 while (child) { | 1427 while (child) { |
| 1480 // Positioned children don't affect the min/max width. Spanners only affect | 1428 // Positioned children don't affect the min/max width. Spanners only affect
the min/max |
| 1481 // the min/max width of the multicol container, not the flow thread. | 1429 // width of the multicol container, not the flow thread. |
| 1482 if (child->isOutOfFlowPositioned() || child->isColumnSpanAll()) { | 1430 if (child->isOutOfFlowPositioned() || child->isColumnSpanAll()) { |
| 1483 child = child->nextSibling(); | 1431 child = child->nextSibling(); |
| 1484 continue; | 1432 continue; |
| 1485 } | 1433 } |
| 1486 | 1434 |
| 1487 RefPtr<ComputedStyle> childStyle = child->mutableStyle(); | 1435 RefPtr<ComputedStyle> childStyle = child->mutableStyle(); |
| 1488 if (child->isFloating() || | 1436 if (child->isFloating() || |
| 1489 (child->isBox() && toLayoutBox(child)->avoidsFloats())) { | 1437 (child->isBox() && toLayoutBox(child)->avoidsFloats())) { |
| 1490 LayoutUnit floatTotalWidth = floatLeftWidth + floatRightWidth; | 1438 LayoutUnit floatTotalWidth = floatLeftWidth + floatRightWidth; |
| 1491 if (childStyle->clear() & ClearLeft) { | 1439 if (childStyle->clear() & ClearLeft) { |
| 1492 maxLogicalWidth = std::max(floatTotalWidth, maxLogicalWidth); | 1440 maxLogicalWidth = std::max(floatTotalWidth, maxLogicalWidth); |
| 1493 floatLeftWidth = LayoutUnit(); | 1441 floatLeftWidth = LayoutUnit(); |
| 1494 } | 1442 } |
| 1495 if (childStyle->clear() & ClearRight) { | 1443 if (childStyle->clear() & ClearRight) { |
| 1496 maxLogicalWidth = std::max(floatTotalWidth, maxLogicalWidth); | 1444 maxLogicalWidth = std::max(floatTotalWidth, maxLogicalWidth); |
| 1497 floatRightWidth = LayoutUnit(); | 1445 floatRightWidth = LayoutUnit(); |
| 1498 } | 1446 } |
| 1499 } | 1447 } |
| 1500 | 1448 |
| 1501 // A margin basically has three types: fixed, percentage, and auto | 1449 // A margin basically has three types: fixed, percentage, and auto (variable
). |
| 1502 // (variable). | |
| 1503 // Auto and percentage margins simply become 0 when computing min/max width. | 1450 // Auto and percentage margins simply become 0 when computing min/max width. |
| 1504 // Fixed margins can be added in as is. | 1451 // Fixed margins can be added in as is. |
| 1505 Length startMarginLength = childStyle->marginStartUsing(&styleToUse); | 1452 Length startMarginLength = childStyle->marginStartUsing(&styleToUse); |
| 1506 Length endMarginLength = childStyle->marginEndUsing(&styleToUse); | 1453 Length endMarginLength = childStyle->marginEndUsing(&styleToUse); |
| 1507 LayoutUnit margin; | 1454 LayoutUnit margin; |
| 1508 LayoutUnit marginStart; | 1455 LayoutUnit marginStart; |
| 1509 LayoutUnit marginEnd; | 1456 LayoutUnit marginEnd; |
| 1510 if (startMarginLength.isFixed()) | 1457 if (startMarginLength.isFixed()) |
| 1511 marginStart += startMarginLength.value(); | 1458 marginStart += startMarginLength.value(); |
| 1512 if (endMarginLength.isFixed()) | 1459 if (endMarginLength.isFixed()) |
| 1513 marginEnd += endMarginLength.value(); | 1460 marginEnd += endMarginLength.value(); |
| 1514 margin = marginStart + marginEnd; | 1461 margin = marginStart + marginEnd; |
| 1515 | 1462 |
| 1516 LayoutUnit childMinPreferredLogicalWidth, childMaxPreferredLogicalWidth; | 1463 LayoutUnit childMinPreferredLogicalWidth, childMaxPreferredLogicalWidth; |
| 1517 computeChildPreferredLogicalWidths(*child, childMinPreferredLogicalWidth, | 1464 computeChildPreferredLogicalWidths(*child, childMinPreferredLogicalWidth, |
| 1518 childMaxPreferredLogicalWidth); | 1465 childMaxPreferredLogicalWidth); |
| 1519 | 1466 |
| 1520 LayoutUnit w = childMinPreferredLogicalWidth + margin; | 1467 LayoutUnit w = childMinPreferredLogicalWidth + margin; |
| 1521 minLogicalWidth = std::max(w, minLogicalWidth); | 1468 minLogicalWidth = std::max(w, minLogicalWidth); |
| 1522 | 1469 |
| 1523 // IE ignores tables for calculation of nowrap. Makes some sense. | 1470 // IE ignores tables for calculation of nowrap. Makes some sense. |
| 1524 if (nowrap && !child->isTable()) | 1471 if (nowrap && !child->isTable()) |
| 1525 maxLogicalWidth = std::max(w, maxLogicalWidth); | 1472 maxLogicalWidth = std::max(w, maxLogicalWidth); |
| 1526 | 1473 |
| 1527 w = childMaxPreferredLogicalWidth + margin; | 1474 w = childMaxPreferredLogicalWidth + margin; |
| 1528 | 1475 |
| 1529 if (!child->isFloating()) { | 1476 if (!child->isFloating()) { |
| 1530 if (child->isBox() && toLayoutBox(child)->avoidsFloats()) { | 1477 if (child->isBox() && toLayoutBox(child)->avoidsFloats()) { |
| 1531 // Determine a left and right max value based off whether or not the | 1478 // Determine a left and right max value based off whether or not the flo
ats can fit in the |
| 1532 // floats can fit in the margins of the object. For negative margins, we | 1479 // margins of the object. For negative margins, we will attempt to over
lap the float if the negative margin |
| 1533 // will attempt to overlap the float if the negative margin is smaller | 1480 // is smaller than the float width. |
| 1534 // than the float width. | |
| 1535 bool ltr = containingBlock | 1481 bool ltr = containingBlock |
| 1536 ? containingBlock->style()->isLeftToRightDirection() | 1482 ? containingBlock->style()->isLeftToRightDirection() |
| 1537 : styleToUse.isLeftToRightDirection(); | 1483 : styleToUse.isLeftToRightDirection(); |
| 1538 LayoutUnit marginLogicalLeft = ltr ? marginStart : marginEnd; | 1484 LayoutUnit marginLogicalLeft = ltr ? marginStart : marginEnd; |
| 1539 LayoutUnit marginLogicalRight = ltr ? marginEnd : marginStart; | 1485 LayoutUnit marginLogicalRight = ltr ? marginEnd : marginStart; |
| 1540 LayoutUnit maxLeft = marginLogicalLeft > 0 | 1486 LayoutUnit maxLeft = marginLogicalLeft > 0 |
| 1541 ? std::max(floatLeftWidth, marginLogicalLeft) | 1487 ? std::max(floatLeftWidth, marginLogicalLeft) |
| 1542 : floatLeftWidth + marginLogicalLeft; | 1488 : floatLeftWidth + marginLogicalLeft; |
| 1543 LayoutUnit maxRight = | 1489 LayoutUnit maxRight = |
| 1544 marginLogicalRight > 0 | 1490 marginLogicalRight > 0 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1572 maxLogicalWidth = std::max(floatLeftWidth + floatRightWidth, maxLogicalWidth); | 1518 maxLogicalWidth = std::max(floatLeftWidth + floatRightWidth, maxLogicalWidth); |
| 1573 } | 1519 } |
| 1574 | 1520 |
| 1575 DISABLE_CFI_PERF | 1521 DISABLE_CFI_PERF |
| 1576 void LayoutBlock::computeChildPreferredLogicalWidths( | 1522 void LayoutBlock::computeChildPreferredLogicalWidths( |
| 1577 LayoutObject& child, | 1523 LayoutObject& child, |
| 1578 LayoutUnit& minPreferredLogicalWidth, | 1524 LayoutUnit& minPreferredLogicalWidth, |
| 1579 LayoutUnit& maxPreferredLogicalWidth) const { | 1525 LayoutUnit& maxPreferredLogicalWidth) const { |
| 1580 if (child.isBox() && | 1526 if (child.isBox() && |
| 1581 child.isHorizontalWritingMode() != isHorizontalWritingMode()) { | 1527 child.isHorizontalWritingMode() != isHorizontalWritingMode()) { |
| 1582 // If the child is an orthogonal flow, child's height determines the width, | 1528 // If the child is an orthogonal flow, child's height determines the width,
but the height is not available until layout. |
| 1583 // but the height is not available until layout. | |
| 1584 // http://dev.w3.org/csswg/css-writing-modes-3/#orthogonal-shrink-to-fit | 1529 // http://dev.w3.org/csswg/css-writing-modes-3/#orthogonal-shrink-to-fit |
| 1585 if (!child.needsLayout()) { | 1530 if (!child.needsLayout()) { |
| 1586 minPreferredLogicalWidth = maxPreferredLogicalWidth = | 1531 minPreferredLogicalWidth = maxPreferredLogicalWidth = |
| 1587 toLayoutBox(child).logicalHeight(); | 1532 toLayoutBox(child).logicalHeight(); |
| 1588 return; | 1533 return; |
| 1589 } | 1534 } |
| 1590 minPreferredLogicalWidth = maxPreferredLogicalWidth = | 1535 minPreferredLogicalWidth = maxPreferredLogicalWidth = |
| 1591 toLayoutBox(child).computeLogicalHeightWithoutLayout(); | 1536 toLayoutBox(child).computeLogicalHeightWithoutLayout(); |
| 1592 return; | 1537 return; |
| 1593 } | 1538 } |
| 1594 minPreferredLogicalWidth = child.minPreferredLogicalWidth(); | 1539 minPreferredLogicalWidth = child.minPreferredLogicalWidth(); |
| 1595 maxPreferredLogicalWidth = child.maxPreferredLogicalWidth(); | 1540 maxPreferredLogicalWidth = child.maxPreferredLogicalWidth(); |
| 1596 | 1541 |
| 1597 // For non-replaced blocks if the inline size is min|max-content or a definite | 1542 // For non-replaced blocks if the inline size is min|max-content or a definite
size the min|max-content contribution |
| 1598 // size the min|max-content contribution is that size plus border, padding and | 1543 // is that size plus border, padding and margin https://drafts.csswg.org/css-s
izing/#block-intrinsic |
| 1599 // margin https://drafts.csswg.org/css-sizing/#block-intrinsic | |
| 1600 if (child.isLayoutBlock()) { | 1544 if (child.isLayoutBlock()) { |
| 1601 const Length& computedInlineSize = child.styleRef().logicalWidth(); | 1545 const Length& computedInlineSize = child.styleRef().logicalWidth(); |
| 1602 if (computedInlineSize.isMaxContent()) | 1546 if (computedInlineSize.isMaxContent()) |
| 1603 minPreferredLogicalWidth = maxPreferredLogicalWidth; | 1547 minPreferredLogicalWidth = maxPreferredLogicalWidth; |
| 1604 else if (computedInlineSize.isMinContent()) | 1548 else if (computedInlineSize.isMinContent()) |
| 1605 maxPreferredLogicalWidth = minPreferredLogicalWidth; | 1549 maxPreferredLogicalWidth = minPreferredLogicalWidth; |
| 1606 } | 1550 } |
| 1607 } | 1551 } |
| 1608 | 1552 |
| 1609 bool LayoutBlock::hasLineIfEmpty() const { | 1553 bool LayoutBlock::hasLineIfEmpty() const { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1642 | 1586 |
| 1643 int LayoutBlock::baselinePosition(FontBaseline baselineType, | 1587 int LayoutBlock::baselinePosition(FontBaseline baselineType, |
| 1644 bool firstLine, | 1588 bool firstLine, |
| 1645 LineDirectionMode direction, | 1589 LineDirectionMode direction, |
| 1646 LinePositionMode linePositionMode) const { | 1590 LinePositionMode linePositionMode) const { |
| 1647 // Inline blocks are replaced elements. Otherwise, just pass off to | 1591 // Inline blocks are replaced elements. Otherwise, just pass off to |
| 1648 // the base class. If we're being queried as though we're the root line | 1592 // the base class. If we're being queried as though we're the root line |
| 1649 // box, then the fact that we're an inline-block is irrelevant, and we behave | 1593 // box, then the fact that we're an inline-block is irrelevant, and we behave |
| 1650 // just like a block. | 1594 // just like a block. |
| 1651 if (isInline() && linePositionMode == PositionOnContainingLine) { | 1595 if (isInline() && linePositionMode == PositionOnContainingLine) { |
| 1652 // For "leaf" theme objects, let the theme decide what the baseline position | 1596 // For "leaf" theme objects, let the theme decide what the baseline position
is. |
| 1653 // is. | 1597 // FIXME: Might be better to have a custom CSS property instead, so that if
the theme |
| 1654 // FIXME: Might be better to have a custom CSS property instead, so that if | 1598 // is turned off, checkboxes/radios will still have decent baselines. |
| 1655 // the theme is turned off, checkboxes/radios will still have decent | |
| 1656 // baselines. | |
| 1657 // FIXME: Need to patch form controls to deal with vertical lines. | 1599 // FIXME: Need to patch form controls to deal with vertical lines. |
| 1658 if (style()->hasAppearance() && | 1600 if (style()->hasAppearance() && |
| 1659 !LayoutTheme::theme().isControlContainer(style()->appearance())) | 1601 !LayoutTheme::theme().isControlContainer(style()->appearance())) |
| 1660 return LayoutTheme::theme().baselinePosition(this); | 1602 return LayoutTheme::theme().baselinePosition(this); |
| 1661 | 1603 |
| 1662 int baselinePos = (isWritingModeRoot() && !isRubyRun()) | 1604 int baselinePos = (isWritingModeRoot() && !isRubyRun()) |
| 1663 ? -1 | 1605 ? -1 |
| 1664 : inlineBlockBaseline(direction); | 1606 : inlineBlockBaseline(direction); |
| 1665 | 1607 |
| 1666 if (isDeprecatedFlexibleBox()) { | 1608 if (isDeprecatedFlexibleBox()) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1678 if (baselinePos > bottomOfContent) | 1620 if (baselinePos > bottomOfContent) |
| 1679 baselinePos = -1; | 1621 baselinePos = -1; |
| 1680 } | 1622 } |
| 1681 if (baselinePos != -1) | 1623 if (baselinePos != -1) |
| 1682 return beforeMarginInLineDirection(direction) + baselinePos; | 1624 return beforeMarginInLineDirection(direction) + baselinePos; |
| 1683 | 1625 |
| 1684 return LayoutBox::baselinePosition(baselineType, firstLine, direction, | 1626 return LayoutBox::baselinePosition(baselineType, firstLine, direction, |
| 1685 linePositionMode); | 1627 linePositionMode); |
| 1686 } | 1628 } |
| 1687 | 1629 |
| 1688 // If we're not replaced, we'll only get called with | 1630 // If we're not replaced, we'll only get called with PositionOfInteriorLineBox
es. |
| 1689 // PositionOfInteriorLineBoxes. | |
| 1690 // Note that inline-block counts as replaced here. | 1631 // Note that inline-block counts as replaced here. |
| 1691 ASSERT(linePositionMode == PositionOfInteriorLineBoxes); | 1632 ASSERT(linePositionMode == PositionOfInteriorLineBoxes); |
| 1692 | 1633 |
| 1693 const FontMetrics& fontMetrics = style(firstLine)->getFontMetrics(); | 1634 const FontMetrics& fontMetrics = style(firstLine)->getFontMetrics(); |
| 1694 return (fontMetrics.ascent(baselineType) + | 1635 return (fontMetrics.ascent(baselineType) + |
| 1695 (lineHeight(firstLine, direction, linePositionMode) - | 1636 (lineHeight(firstLine, direction, linePositionMode) - |
| 1696 fontMetrics.height()) / | 1637 fontMetrics.height()) / |
| 1697 2) | 1638 2) |
| 1698 .toInt(); | 1639 .toInt(); |
| 1699 } | 1640 } |
| 1700 | 1641 |
| 1701 LayoutUnit LayoutBlock::minLineHeightForReplacedObject( | 1642 LayoutUnit LayoutBlock::minLineHeightForReplacedObject( |
| 1702 bool isFirstLine, | 1643 bool isFirstLine, |
| 1703 LayoutUnit replacedHeight) const { | 1644 LayoutUnit replacedHeight) const { |
| 1704 if (!document().inNoQuirksMode() && replacedHeight) | 1645 if (!document().inNoQuirksMode() && replacedHeight) |
| 1705 return replacedHeight; | 1646 return replacedHeight; |
| 1706 | 1647 |
| 1707 return std::max<LayoutUnit>( | 1648 return std::max<LayoutUnit>( |
| 1708 replacedHeight, | 1649 replacedHeight, |
| 1709 lineHeight(isFirstLine, | 1650 lineHeight(isFirstLine, |
| 1710 isHorizontalWritingMode() ? HorizontalLine : VerticalLine, | 1651 isHorizontalWritingMode() ? HorizontalLine : VerticalLine, |
| 1711 PositionOfInteriorLineBoxes)); | 1652 PositionOfInteriorLineBoxes)); |
| 1712 } | 1653 } |
| 1713 | 1654 |
| 1714 // TODO(mstensho): Figure out if all of this baseline code is needed here, or if | 1655 // TODO(mstensho): Figure out if all of this baseline code is needed here, or if
it should be moved |
| 1715 // it should be moved down to LayoutBlockFlow. LayoutDeprecatedFlexibleBox and | 1656 // down to LayoutBlockFlow. LayoutDeprecatedFlexibleBox and LayoutGrid lack base
line calculation |
| 1716 // LayoutGrid lack baseline calculation overrides, so the code is here just for | 1657 // overrides, so the code is here just for them. Just walking the block children
in logical order |
| 1717 // them. Just walking the block children in logical order seems rather wrong for | 1658 // seems rather wrong for those two layout modes, though. |
| 1718 // those two layout modes, though. | |
| 1719 | 1659 |
| 1720 int LayoutBlock::firstLineBoxBaseline() const { | 1660 int LayoutBlock::firstLineBoxBaseline() const { |
| 1721 ASSERT(!childrenInline()); | 1661 ASSERT(!childrenInline()); |
| 1722 if (isWritingModeRoot() && !isRubyRun()) | 1662 if (isWritingModeRoot() && !isRubyRun()) |
| 1723 return -1; | 1663 return -1; |
| 1724 | 1664 |
| 1725 for (LayoutBox* curr = firstChildBox(); curr; curr = curr->nextSiblingBox()) { | 1665 for (LayoutBox* curr = firstChildBox(); curr; curr = curr->nextSiblingBox()) { |
| 1726 if (!curr->isFloatingOrOutOfFlowPositioned()) { | 1666 if (!curr->isFloatingOrOutOfFlowPositioned()) { |
| 1727 int result = curr->firstLineBoxBaseline(); | 1667 int result = curr->firstLineBoxBaseline(); |
| 1728 if (result != -1) | 1668 if (result != -1) |
| 1729 return (curr->logicalTop() + result) | 1669 return (curr->logicalTop() + result) |
| 1730 .toInt(); // Translate to our coordinate space. | 1670 .toInt(); // Translate to our coordinate space. |
| 1731 } | 1671 } |
| 1732 } | 1672 } |
| 1733 return -1; | 1673 return -1; |
| 1734 } | 1674 } |
| 1735 | 1675 |
| 1736 int LayoutBlock::inlineBlockBaseline(LineDirectionMode lineDirection) const { | 1676 int LayoutBlock::inlineBlockBaseline(LineDirectionMode lineDirection) const { |
| 1737 ASSERT(!childrenInline()); | 1677 ASSERT(!childrenInline()); |
| 1738 if ((!style()->isOverflowVisible() && | 1678 if ((!style()->isOverflowVisible() && |
| 1739 !shouldIgnoreOverflowPropertyForInlineBlockBaseline()) || | 1679 !shouldIgnoreOverflowPropertyForInlineBlockBaseline()) || |
| 1740 style()->containsSize()) { | 1680 style()->containsSize()) { |
| 1741 // We are not calling LayoutBox::baselinePosition here because the caller | 1681 // We are not calling LayoutBox::baselinePosition here because the caller sh
ould add the margin-top/margin-right, not us. |
| 1742 // should add the margin-top/margin-right, not us. | |
| 1743 return (lineDirection == HorizontalLine ? size().height() + marginBottom() | 1682 return (lineDirection == HorizontalLine ? size().height() + marginBottom() |
| 1744 : size().width() + marginLeft()) | 1683 : size().width() + marginLeft()) |
| 1745 .toInt(); | 1684 .toInt(); |
| 1746 } | 1685 } |
| 1747 | 1686 |
| 1748 if (isWritingModeRoot() && !isRubyRun()) | 1687 if (isWritingModeRoot() && !isRubyRun()) |
| 1749 return -1; | 1688 return -1; |
| 1750 | 1689 |
| 1751 bool haveNormalFlowChild = false; | 1690 bool haveNormalFlowChild = false; |
| 1752 for (LayoutBox* curr = lastChildBox(); curr; | 1691 for (LayoutBox* curr = lastChildBox(); curr; |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1897 | 1836 |
| 1898 void LayoutBlock::paginatedContentWasLaidOut( | 1837 void LayoutBlock::paginatedContentWasLaidOut( |
| 1899 LayoutUnit logicalBottomOffsetAfterPagination) { | 1838 LayoutUnit logicalBottomOffsetAfterPagination) { |
| 1900 if (LayoutFlowThread* flowThread = flowThreadContainingBlock()) | 1839 if (LayoutFlowThread* flowThread = flowThreadContainingBlock()) |
| 1901 flowThread->contentWasLaidOut(offsetFromLogicalTopOfFirstPage() + | 1840 flowThread->contentWasLaidOut(offsetFromLogicalTopOfFirstPage() + |
| 1902 logicalBottomOffsetAfterPagination); | 1841 logicalBottomOffsetAfterPagination); |
| 1903 } | 1842 } |
| 1904 | 1843 |
| 1905 LayoutUnit LayoutBlock::collapsedMarginBeforeForChild( | 1844 LayoutUnit LayoutBlock::collapsedMarginBeforeForChild( |
| 1906 const LayoutBox& child) const { | 1845 const LayoutBox& child) const { |
| 1907 // If the child has the same directionality as we do, then we can just return | 1846 // If the child has the same directionality as we do, then we can just return
its |
| 1908 // its collapsed margin. | 1847 // collapsed margin. |
| 1909 if (!child.isWritingModeRoot()) | 1848 if (!child.isWritingModeRoot()) |
| 1910 return child.collapsedMarginBefore(); | 1849 return child.collapsedMarginBefore(); |
| 1911 | 1850 |
| 1912 // The child has a different directionality. If the child is parallel, then | 1851 // The child has a different directionality. If the child is parallel, then i
t's just |
| 1913 // it's just flipped relative to us. We can use the collapsed margin for the | 1852 // flipped relative to us. We can use the collapsed margin for the opposite e
dge. |
| 1914 // opposite edge. | |
| 1915 if (child.isHorizontalWritingMode() == isHorizontalWritingMode()) | 1853 if (child.isHorizontalWritingMode() == isHorizontalWritingMode()) |
| 1916 return child.collapsedMarginAfter(); | 1854 return child.collapsedMarginAfter(); |
| 1917 | 1855 |
| 1918 // The child is perpendicular to us, which means its margins don't collapse | 1856 // The child is perpendicular to us, which means its margins don't collapse bu
t are on the |
| 1919 // but are on the "logical left/right" sides of the child box. We can just | 1857 // "logical left/right" sides of the child box. We can just return the raw ma
rgin in this case. |
| 1920 // return the raw margin in this case. | |
| 1921 return marginBeforeForChild(child); | 1858 return marginBeforeForChild(child); |
| 1922 } | 1859 } |
| 1923 | 1860 |
| 1924 LayoutUnit LayoutBlock::collapsedMarginAfterForChild( | 1861 LayoutUnit LayoutBlock::collapsedMarginAfterForChild( |
| 1925 const LayoutBox& child) const { | 1862 const LayoutBox& child) const { |
| 1926 // If the child has the same directionality as we do, then we can just return | 1863 // If the child has the same directionality as we do, then we can just return
its |
| 1927 // its collapsed margin. | 1864 // collapsed margin. |
| 1928 if (!child.isWritingModeRoot()) | 1865 if (!child.isWritingModeRoot()) |
| 1929 return child.collapsedMarginAfter(); | 1866 return child.collapsedMarginAfter(); |
| 1930 | 1867 |
| 1931 // The child has a different directionality. If the child is parallel, then | 1868 // The child has a different directionality. If the child is parallel, then i
t's just |
| 1932 // it's just flipped relative to us. We can use the collapsed margin for the | 1869 // flipped relative to us. We can use the collapsed margin for the opposite e
dge. |
| 1933 // opposite edge. | |
| 1934 if (child.isHorizontalWritingMode() == isHorizontalWritingMode()) | 1870 if (child.isHorizontalWritingMode() == isHorizontalWritingMode()) |
| 1935 return child.collapsedMarginBefore(); | 1871 return child.collapsedMarginBefore(); |
| 1936 | 1872 |
| 1937 // The child is perpendicular to us, which means its margins don't collapse | 1873 // The child is perpendicular to us, which means its margins don't collapse bu
t are on the |
| 1938 // but are on the "logical left/right" side of the child box. We can just | 1874 // "logical left/right" side of the child box. We can just return the raw mar
gin in this case. |
| 1939 // return the raw margin in this case. | |
| 1940 return marginAfterForChild(child); | 1875 return marginAfterForChild(child); |
| 1941 } | 1876 } |
| 1942 | 1877 |
| 1943 bool LayoutBlock::hasMarginBeforeQuirk(const LayoutBox* child) const { | 1878 bool LayoutBlock::hasMarginBeforeQuirk(const LayoutBox* child) const { |
| 1944 // If the child has the same directionality as we do, then we can just return | 1879 // If the child has the same directionality as we do, then we can just return
its |
| 1945 // its margin quirk. | 1880 // margin quirk. |
| 1946 if (!child->isWritingModeRoot()) | 1881 if (!child->isWritingModeRoot()) |
| 1947 return child->isLayoutBlock() ? toLayoutBlock(child)->hasMarginBeforeQuirk() | 1882 return child->isLayoutBlock() ? toLayoutBlock(child)->hasMarginBeforeQuirk() |
| 1948 : child->style()->hasMarginBeforeQuirk(); | 1883 : child->style()->hasMarginBeforeQuirk(); |
| 1949 | 1884 |
| 1950 // The child has a different directionality. If the child is parallel, then | 1885 // The child has a different directionality. If the child is parallel, then it
's just |
| 1951 // it's just flipped relative to us. We can use the opposite edge. | 1886 // flipped relative to us. We can use the opposite edge. |
| 1952 if (child->isHorizontalWritingMode() == isHorizontalWritingMode()) | 1887 if (child->isHorizontalWritingMode() == isHorizontalWritingMode()) |
| 1953 return child->isLayoutBlock() ? toLayoutBlock(child)->hasMarginAfterQuirk() | 1888 return child->isLayoutBlock() ? toLayoutBlock(child)->hasMarginAfterQuirk() |
| 1954 : child->style()->hasMarginAfterQuirk(); | 1889 : child->style()->hasMarginAfterQuirk(); |
| 1955 | 1890 |
| 1956 // The child is perpendicular to us and box sides are never quirky in | 1891 // The child is perpendicular to us and box sides are never quirky in html.css
, and we don't really care about |
| 1957 // html.css, and we don't really care about whether or not authors specified | 1892 // whether or not authors specified quirky ems, since they're an implementatio
n detail. |
| 1958 // quirky ems, since they're an implementation detail. | |
| 1959 return false; | 1893 return false; |
| 1960 } | 1894 } |
| 1961 | 1895 |
| 1962 bool LayoutBlock::hasMarginAfterQuirk(const LayoutBox* child) const { | 1896 bool LayoutBlock::hasMarginAfterQuirk(const LayoutBox* child) const { |
| 1963 // If the child has the same directionality as we do, then we can just return | 1897 // If the child has the same directionality as we do, then we can just return
its |
| 1964 // its margin quirk. | 1898 // margin quirk. |
| 1965 if (!child->isWritingModeRoot()) | 1899 if (!child->isWritingModeRoot()) |
| 1966 return child->isLayoutBlock() ? toLayoutBlock(child)->hasMarginAfterQuirk() | 1900 return child->isLayoutBlock() ? toLayoutBlock(child)->hasMarginAfterQuirk() |
| 1967 : child->style()->hasMarginAfterQuirk(); | 1901 : child->style()->hasMarginAfterQuirk(); |
| 1968 | 1902 |
| 1969 // The child has a different directionality. If the child is parallel, then | 1903 // The child has a different directionality. If the child is parallel, then it
's just |
| 1970 // it's just flipped relative to us. We can use the opposite edge. | 1904 // flipped relative to us. We can use the opposite edge. |
| 1971 if (child->isHorizontalWritingMode() == isHorizontalWritingMode()) | 1905 if (child->isHorizontalWritingMode() == isHorizontalWritingMode()) |
| 1972 return child->isLayoutBlock() ? toLayoutBlock(child)->hasMarginBeforeQuirk() | 1906 return child->isLayoutBlock() ? toLayoutBlock(child)->hasMarginBeforeQuirk() |
| 1973 : child->style()->hasMarginBeforeQuirk(); | 1907 : child->style()->hasMarginBeforeQuirk(); |
| 1974 | 1908 |
| 1975 // The child is perpendicular to us and box sides are never quirky in | 1909 // The child is perpendicular to us and box sides are never quirky in html.css
, and we don't really care about |
| 1976 // html.css, and we don't really care about whether or not authors specified | 1910 // whether or not authors specified quirky ems, since they're an implementatio
n detail. |
| 1977 // quirky ems, since they're an implementation detail. | |
| 1978 return false; | 1911 return false; |
| 1979 } | 1912 } |
| 1980 | 1913 |
| 1981 const char* LayoutBlock::name() const { | 1914 const char* LayoutBlock::name() const { |
| 1982 ASSERT_NOT_REACHED(); | 1915 ASSERT_NOT_REACHED(); |
| 1983 return "LayoutBlock"; | 1916 return "LayoutBlock"; |
| 1984 } | 1917 } |
| 1985 | 1918 |
| 1986 LayoutBlock* LayoutBlock::createAnonymousWithParentAndDisplay( | 1919 LayoutBlock* LayoutBlock::createAnonymousWithParentAndDisplay( |
| 1987 const LayoutObject* parent, | 1920 const LayoutObject* parent, |
| 1988 EDisplay display) { | 1921 EDisplay display) { |
| 1989 // FIXME: Do we need to convert all our inline displays to block-type in the | 1922 // FIXME: Do we need to convert all our inline displays to block-type in the a
nonymous logic ? |
| 1990 // anonymous logic ? | |
| 1991 EDisplay newDisplay; | 1923 EDisplay newDisplay; |
| 1992 LayoutBlock* newBox = nullptr; | 1924 LayoutBlock* newBox = nullptr; |
| 1993 if (display == EDisplay::Flex || display == EDisplay::InlineFlex) { | 1925 if (display == EDisplay::Flex || display == EDisplay::InlineFlex) { |
| 1994 newBox = LayoutFlexibleBox::createAnonymous(&parent->document()); | 1926 newBox = LayoutFlexibleBox::createAnonymous(&parent->document()); |
| 1995 newDisplay = EDisplay::Flex; | 1927 newDisplay = EDisplay::Flex; |
| 1996 } else if (display == EDisplay::Grid || display == EDisplay::InlineGrid) { | 1928 } else if (display == EDisplay::Grid || display == EDisplay::InlineGrid) { |
| 1997 newBox = LayoutGrid::createAnonymous(&parent->document()); | 1929 newBox = LayoutGrid::createAnonymous(&parent->document()); |
| 1998 newDisplay = EDisplay::Grid; | 1930 newDisplay = EDisplay::Grid; |
| 1999 } else { | 1931 } else { |
| 2000 newBox = LayoutBlockFlow::createAnonymous(&parent->document()); | 1932 newBox = LayoutBlockFlow::createAnonymous(&parent->document()); |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2080 ? m_overflow->layoutClientAfterEdge() | 2012 ? m_overflow->layoutClientAfterEdge() |
| 2081 : clientLogicalBottom(); | 2013 : clientLogicalBottom(); |
| 2082 computeOverflow(oldClientAfterEdge, true); | 2014 computeOverflow(oldClientAfterEdge, true); |
| 2083 | 2015 |
| 2084 if (hasOverflowClip()) | 2016 if (hasOverflowClip()) |
| 2085 layer()->getScrollableArea()->updateAfterOverflowRecalc(); | 2017 layer()->getScrollableArea()->updateAfterOverflowRecalc(); |
| 2086 | 2018 |
| 2087 return !hasOverflowClip(); | 2019 return !hasOverflowClip(); |
| 2088 } | 2020 } |
| 2089 | 2021 |
| 2090 // Called when a positioned object moves but doesn't necessarily change size. | 2022 // Called when a positioned object moves but doesn't necessarily change size. A
simplified layout is attempted |
| 2091 // A simplified layout is attempted that just updates the object's position. | 2023 // that just updates the object's position. If the size does change, the object
remains dirty. |
| 2092 // If the size does change, the object remains dirty. | |
| 2093 bool LayoutBlock::tryLayoutDoingPositionedMovementOnly() { | 2024 bool LayoutBlock::tryLayoutDoingPositionedMovementOnly() { |
| 2094 LayoutUnit oldWidth = logicalWidth(); | 2025 LayoutUnit oldWidth = logicalWidth(); |
| 2095 LogicalExtentComputedValues computedValues; | 2026 LogicalExtentComputedValues computedValues; |
| 2096 logicalExtentAfterUpdatingLogicalWidth(logicalTop(), computedValues); | 2027 logicalExtentAfterUpdatingLogicalWidth(logicalTop(), computedValues); |
| 2097 // If we shrink to fit our width may have changed, so we still need full | 2028 // If we shrink to fit our width may have changed, so we still need full layou
t. |
| 2098 // layout. | |
| 2099 if (oldWidth != computedValues.m_extent) | 2029 if (oldWidth != computedValues.m_extent) |
| 2100 return false; | 2030 return false; |
| 2101 setLogicalWidth(computedValues.m_extent); | 2031 setLogicalWidth(computedValues.m_extent); |
| 2102 setLogicalLeft(computedValues.m_position); | 2032 setLogicalLeft(computedValues.m_position); |
| 2103 setMarginStart(computedValues.m_margins.m_start); | 2033 setMarginStart(computedValues.m_margins.m_start); |
| 2104 setMarginEnd(computedValues.m_margins.m_end); | 2034 setMarginEnd(computedValues.m_margins.m_end); |
| 2105 | 2035 |
| 2106 LayoutUnit oldHeight = logicalHeight(); | 2036 LayoutUnit oldHeight = logicalHeight(); |
| 2107 LayoutUnit oldIntrinsicContentLogicalHeight = intrinsicContentLogicalHeight(); | 2037 LayoutUnit oldIntrinsicContentLogicalHeight = intrinsicContentLogicalHeight(); |
| 2108 | 2038 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 2139 ASSERT(!currBox->needsLayout()); | 2069 ASSERT(!currBox->needsLayout()); |
| 2140 } | 2070 } |
| 2141 } | 2071 } |
| 2142 } | 2072 } |
| 2143 | 2073 |
| 2144 #endif | 2074 #endif |
| 2145 | 2075 |
| 2146 LayoutUnit LayoutBlock::availableLogicalHeightForPercentageComputation() const { | 2076 LayoutUnit LayoutBlock::availableLogicalHeightForPercentageComputation() const { |
| 2147 LayoutUnit availableHeight(-1); | 2077 LayoutUnit availableHeight(-1); |
| 2148 | 2078 |
| 2149 // For anonymous blocks that are skipped during percentage height calculation, | 2079 // For anonymous blocks that are skipped during percentage height calculation,
we consider them to have an indefinite height. |
| 2150 // we consider them to have an indefinite height. | |
| 2151 if (skipContainingBlockForPercentHeightCalculation(this)) | 2080 if (skipContainingBlockForPercentHeightCalculation(this)) |
| 2152 return availableHeight; | 2081 return availableHeight; |
| 2153 | 2082 |
| 2154 const ComputedStyle& style = styleRef(); | 2083 const ComputedStyle& style = styleRef(); |
| 2155 | 2084 |
| 2156 // A positioned element that specified both top/bottom or that specifies | 2085 // A positioned element that specified both top/bottom or that specifies heigh
t should be treated as though it has a height |
| 2157 // height should be treated as though it has a height explicitly specified | 2086 // explicitly specified that can be used for any percentage computations. |
| 2158 // that can be used for any percentage computations. | |
| 2159 bool isOutOfFlowPositionedWithSpecifiedHeight = | 2087 bool isOutOfFlowPositionedWithSpecifiedHeight = |
| 2160 isOutOfFlowPositioned() && | 2088 isOutOfFlowPositioned() && |
| 2161 (!style.logicalHeight().isAuto() || | 2089 (!style.logicalHeight().isAuto() || |
| 2162 (!style.logicalTop().isAuto() && !style.logicalBottom().isAuto())); | 2090 (!style.logicalTop().isAuto() && !style.logicalBottom().isAuto())); |
| 2163 | 2091 |
| 2164 LayoutUnit stretchedFlexHeight(-1); | 2092 LayoutUnit stretchedFlexHeight(-1); |
| 2165 if (isFlexItem()) | 2093 if (isFlexItem()) |
| 2166 stretchedFlexHeight = | 2094 stretchedFlexHeight = |
| 2167 toLayoutFlexibleBox(parent()) | 2095 toLayoutFlexibleBox(parent()) |
| 2168 ->childLogicalHeightForPercentageResolution(*this); | 2096 ->childLogicalHeightForPercentageResolution(*this); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2207 } | 2135 } |
| 2208 | 2136 |
| 2209 return availableHeight; | 2137 return availableHeight; |
| 2210 } | 2138 } |
| 2211 | 2139 |
| 2212 bool LayoutBlock::hasDefiniteLogicalHeight() const { | 2140 bool LayoutBlock::hasDefiniteLogicalHeight() const { |
| 2213 return availableLogicalHeightForPercentageComputation() != LayoutUnit(-1); | 2141 return availableLogicalHeightForPercentageComputation() != LayoutUnit(-1); |
| 2214 } | 2142 } |
| 2215 | 2143 |
| 2216 } // namespace blink | 2144 } // namespace blink |
| OLD | NEW |