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