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