OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 void clearMargin() { | 126 void clearMargin() { |
127 m_positiveMargin = LayoutUnit(); | 127 m_positiveMargin = LayoutUnit(); |
128 m_negativeMargin = LayoutUnit(); | 128 m_negativeMargin = LayoutUnit(); |
129 } | 129 } |
130 void setHasMarginBeforeQuirk(bool b) { m_hasMarginBeforeQuirk = b; } | 130 void setHasMarginBeforeQuirk(bool b) { m_hasMarginBeforeQuirk = b; } |
131 void setHasMarginAfterQuirk(bool b) { m_hasMarginAfterQuirk = b; } | 131 void setHasMarginAfterQuirk(bool b) { m_hasMarginAfterQuirk = b; } |
132 void setDeterminedMarginBeforeQuirk(bool b) { | 132 void setDeterminedMarginBeforeQuirk(bool b) { |
133 m_determinedMarginBeforeQuirk = b; | 133 m_determinedMarginBeforeQuirk = b; |
134 } | 134 } |
135 void setPositiveMargin(LayoutUnit p) { | 135 void setPositiveMargin(LayoutUnit p) { |
136 ASSERT(!m_discardMargin); | 136 DCHECK(!m_discardMargin); |
137 m_positiveMargin = p; | 137 m_positiveMargin = p; |
138 } | 138 } |
139 void setNegativeMargin(LayoutUnit n) { | 139 void setNegativeMargin(LayoutUnit n) { |
140 ASSERT(!m_discardMargin); | 140 DCHECK(!m_discardMargin); |
141 m_negativeMargin = n; | 141 m_negativeMargin = n; |
142 } | 142 } |
143 void setPositiveMarginIfLarger(LayoutUnit p) { | 143 void setPositiveMarginIfLarger(LayoutUnit p) { |
144 ASSERT(!m_discardMargin); | 144 DCHECK(!m_discardMargin); |
145 if (p > m_positiveMargin) | 145 if (p > m_positiveMargin) |
146 m_positiveMargin = p; | 146 m_positiveMargin = p; |
147 } | 147 } |
148 void setNegativeMarginIfLarger(LayoutUnit n) { | 148 void setNegativeMarginIfLarger(LayoutUnit n) { |
149 ASSERT(!m_discardMargin); | 149 DCHECK(!m_discardMargin); |
150 if (n > m_negativeMargin) | 150 if (n > m_negativeMargin) |
151 m_negativeMargin = n; | 151 m_negativeMargin = n; |
152 } | 152 } |
153 | 153 |
154 void setMargin(LayoutUnit p, LayoutUnit n) { | 154 void setMargin(LayoutUnit p, LayoutUnit n) { |
155 ASSERT(!m_discardMargin); | 155 DCHECK(!m_discardMargin); |
156 m_positiveMargin = p; | 156 m_positiveMargin = p; |
157 m_negativeMargin = n; | 157 m_negativeMargin = n; |
158 } | 158 } |
159 void setCanCollapseMarginAfterWithChildren(bool collapse) { | 159 void setCanCollapseMarginAfterWithChildren(bool collapse) { |
160 m_canCollapseMarginAfterWithChildren = collapse; | 160 m_canCollapseMarginAfterWithChildren = collapse; |
161 } | 161 } |
162 void setCanCollapseMarginAfterWithLastChild(bool collapse) { | 162 void setCanCollapseMarginAfterWithLastChild(bool collapse) { |
163 m_canCollapseMarginAfterWithLastChild = collapse; | 163 m_canCollapseMarginAfterWithLastChild = collapse; |
164 } | 164 } |
165 void setDiscardMargin(bool value) { m_discardMargin = value; } | 165 void setDiscardMargin(bool value) { m_discardMargin = value; } |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 bool LayoutBlockFlow::updateLogicalWidthAndColumnWidth() { | 275 bool LayoutBlockFlow::updateLogicalWidthAndColumnWidth() { |
276 bool relayoutChildren = LayoutBlock::updateLogicalWidthAndColumnWidth(); | 276 bool relayoutChildren = LayoutBlock::updateLogicalWidthAndColumnWidth(); |
277 if (LayoutMultiColumnFlowThread* flowThread = multiColumnFlowThread()) { | 277 if (LayoutMultiColumnFlowThread* flowThread = multiColumnFlowThread()) { |
278 if (flowThread->needsNewWidth()) | 278 if (flowThread->needsNewWidth()) |
279 return true; | 279 return true; |
280 } | 280 } |
281 return relayoutChildren; | 281 return relayoutChildren; |
282 } | 282 } |
283 | 283 |
284 void LayoutBlockFlow::setBreakAtLineToAvoidWidow(int lineToBreak) { | 284 void LayoutBlockFlow::setBreakAtLineToAvoidWidow(int lineToBreak) { |
285 ASSERT(lineToBreak >= 0); | 285 DCHECK_GE(lineToBreak, 0); |
286 ensureRareData(); | 286 ensureRareData(); |
287 ASSERT(!m_rareData->m_didBreakAtLineToAvoidWidow); | 287 DCHECK(!m_rareData->m_didBreakAtLineToAvoidWidow); |
288 m_rareData->m_lineBreakToAvoidWidow = lineToBreak; | 288 m_rareData->m_lineBreakToAvoidWidow = lineToBreak; |
289 } | 289 } |
290 | 290 |
291 void LayoutBlockFlow::setDidBreakAtLineToAvoidWidow() { | 291 void LayoutBlockFlow::setDidBreakAtLineToAvoidWidow() { |
292 ASSERT(!shouldBreakAtLineToAvoidWidow()); | 292 DCHECK(!shouldBreakAtLineToAvoidWidow()); |
293 | 293 |
294 // This function should be called only after a break was applied to avoid | 294 // This function should be called only after a break was applied to avoid |
295 // widows so assert |m_rareData| exists. | 295 // widows so assert |m_rareData| exists. |
296 ASSERT(m_rareData); | 296 DCHECK(m_rareData); |
297 | 297 |
298 m_rareData->m_didBreakAtLineToAvoidWidow = true; | 298 m_rareData->m_didBreakAtLineToAvoidWidow = true; |
299 } | 299 } |
300 | 300 |
301 void LayoutBlockFlow::clearDidBreakAtLineToAvoidWidow() { | 301 void LayoutBlockFlow::clearDidBreakAtLineToAvoidWidow() { |
302 if (!m_rareData) | 302 if (!m_rareData) |
303 return; | 303 return; |
304 | 304 |
305 m_rareData->m_didBreakAtLineToAvoidWidow = false; | 305 m_rareData->m_didBreakAtLineToAvoidWidow = false; |
306 } | 306 } |
307 | 307 |
308 void LayoutBlockFlow::clearShouldBreakAtLineToAvoidWidow() const { | 308 void LayoutBlockFlow::clearShouldBreakAtLineToAvoidWidow() const { |
309 ASSERT(shouldBreakAtLineToAvoidWidow()); | 309 DCHECK(shouldBreakAtLineToAvoidWidow()); |
310 if (!m_rareData) | 310 if (!m_rareData) |
311 return; | 311 return; |
312 | 312 |
313 m_rareData->m_lineBreakToAvoidWidow = -1; | 313 m_rareData->m_lineBreakToAvoidWidow = -1; |
314 } | 314 } |
315 | 315 |
316 bool LayoutBlockFlow::isSelfCollapsingBlock() const { | 316 bool LayoutBlockFlow::isSelfCollapsingBlock() const { |
317 if (needsLayout()) { | 317 if (needsLayout()) { |
318 // Sometimes we don't lay out objects in DOM order (column spanners being | 318 // Sometimes we don't lay out objects in DOM order (column spanners being |
319 // one such relevant type of object right here). As long as the object in | 319 // one such relevant type of object right here). As long as the object in |
320 // question establishes a new formatting context, that's nothing to worry | 320 // question establishes a new formatting context, that's nothing to worry |
321 // about, though. | 321 // about, though. |
322 ASSERT(createsNewFormattingContext()); | 322 DCHECK(createsNewFormattingContext()); |
323 return false; | 323 return false; |
324 } | 324 } |
325 ASSERT(!m_isSelfCollapsing == !checkIfIsSelfCollapsingBlock()); | 325 DCHECK_EQ(!m_isSelfCollapsing, !checkIfIsSelfCollapsingBlock()); |
326 return m_isSelfCollapsing; | 326 return m_isSelfCollapsing; |
327 } | 327 } |
328 | 328 |
329 bool LayoutBlockFlow::checkIfIsSelfCollapsingBlock() const { | 329 bool LayoutBlockFlow::checkIfIsSelfCollapsingBlock() const { |
330 // We are not self-collapsing if we | 330 // We are not self-collapsing if we |
331 // (a) have a non-zero height according to layout (an optimization to avoid | 331 // (a) have a non-zero height according to layout (an optimization to avoid |
332 // wasting time) | 332 // wasting time) |
333 // (b) have border/padding, | 333 // (b) have border/padding, |
334 // (c) have a min-height | 334 // (c) have a min-height |
335 // (d) have specified that one of our margins can't collapse using a CSS | 335 // (d) have specified that one of our margins can't collapse using a CSS |
336 // extension | 336 // extension |
337 // (e) establish a new block formatting context. | 337 // (e) establish a new block formatting context. |
338 | 338 |
339 // The early exit must be done before we check for clean layout. | 339 // The early exit must be done before we check for clean layout. |
340 // We should be able to give a quick answer if the box is a relayout boundary. | 340 // We should be able to give a quick answer if the box is a relayout boundary. |
341 // Being a relayout boundary implies a block formatting context, and also | 341 // Being a relayout boundary implies a block formatting context, and also |
342 // our internal layout shouldn't affect our container in any way. | 342 // our internal layout shouldn't affect our container in any way. |
343 if (createsNewFormattingContext()) | 343 if (createsNewFormattingContext()) |
344 return false; | 344 return false; |
345 | 345 |
346 // Placeholder elements are not laid out until the dimensions of their parent | 346 // Placeholder elements are not laid out until the dimensions of their parent |
347 // text control are known, so they don't get layout until their parent has had | 347 // text control are known, so they don't get layout until their parent has had |
348 // layout - this is unique in the layout tree and means when we call | 348 // layout - this is unique in the layout tree and means when we call |
349 // isSelfCollapsingBlock on them we find that they still need layout. | 349 // isSelfCollapsingBlock on them we find that they still need layout. |
350 ASSERT(!needsLayout() || | 350 DCHECK(!needsLayout() || |
351 (node() && node()->isElementNode() && | 351 (node() && node()->isElementNode() && |
352 toElement(node())->shadowPseudoId() == "-webkit-input-placeholder")); | 352 toElement(node())->shadowPseudoId() == "-webkit-input-placeholder")); |
353 | 353 |
354 if (logicalHeight() > LayoutUnit() || borderAndPaddingLogicalHeight() || | 354 if (logicalHeight() > LayoutUnit() || borderAndPaddingLogicalHeight() || |
355 style()->logicalMinHeight().isPositive() || | 355 style()->logicalMinHeight().isPositive() || |
356 style()->marginBeforeCollapse() == MarginCollapseSeparate || | 356 style()->marginBeforeCollapse() == MarginCollapseSeparate || |
357 style()->marginAfterCollapse() == MarginCollapseSeparate) | 357 style()->marginAfterCollapse() == MarginCollapseSeparate) |
358 return false; | 358 return false; |
359 | 359 |
360 Length logicalHeightLength = style()->logicalHeight(); | 360 Length logicalHeightLength = style()->logicalHeight(); |
(...skipping 28 matching lines...) Expand all Loading... |
389 if (!child->isSelfCollapsingBlock()) | 389 if (!child->isSelfCollapsingBlock()) |
390 return false; | 390 return false; |
391 } | 391 } |
392 return true; | 392 return true; |
393 } | 393 } |
394 return false; | 394 return false; |
395 } | 395 } |
396 | 396 |
397 DISABLE_CFI_PERF | 397 DISABLE_CFI_PERF |
398 void LayoutBlockFlow::layoutBlock(bool relayoutChildren) { | 398 void LayoutBlockFlow::layoutBlock(bool relayoutChildren) { |
399 ASSERT(needsLayout()); | 399 DCHECK(needsLayout()); |
400 ASSERT(isInlineBlockOrInlineTable() || !isInline()); | 400 DCHECK(isInlineBlockOrInlineTable() || !isInline()); |
401 | 401 |
402 if (!relayoutChildren && simplifiedLayout()) | 402 if (!relayoutChildren && simplifiedLayout()) |
403 return; | 403 return; |
404 | 404 |
405 LayoutAnalyzer::BlockScope analyzer(*this); | 405 LayoutAnalyzer::BlockScope analyzer(*this); |
406 SubtreeLayoutScope layoutScope(*this); | 406 SubtreeLayoutScope layoutScope(*this); |
407 | 407 |
408 LayoutUnit previousHeight = logicalHeight(); | 408 LayoutUnit previousHeight = logicalHeight(); |
409 LayoutUnit oldLeft = logicalLeft(); | 409 LayoutUnit oldLeft = logicalLeft(); |
410 bool logicalWidthChanged = updateLogicalWidthAndColumnWidth(); | 410 bool logicalWidthChanged = updateLogicalWidthAndColumnWidth(); |
(...skipping 552 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
963 LayoutUnit logicalTopAfterPagination = | 963 LayoutUnit logicalTopAfterPagination = |
964 std::max(logicalTopWithContentStrut, logicalTopAfterUnsplittable); | 964 std::max(logicalTopWithContentStrut, logicalTopAfterUnsplittable); |
965 LayoutUnit newLogicalTop = logicalTop; | 965 LayoutUnit newLogicalTop = logicalTop; |
966 | 966 |
967 // Forced breaks may already have caused a strut, and this needs to be added | 967 // Forced breaks may already have caused a strut, and this needs to be added |
968 // together with any strut detected here in this method. | 968 // together with any strut detected here in this method. |
969 LayoutUnit previousStrut = child.paginationStrut(); | 969 LayoutUnit previousStrut = child.paginationStrut(); |
970 | 970 |
971 if (LayoutUnit paginationStrut = | 971 if (LayoutUnit paginationStrut = |
972 logicalTopAfterPagination - logicalTop + previousStrut) { | 972 logicalTopAfterPagination - logicalTop + previousStrut) { |
973 ASSERT(paginationStrut > 0); | 973 DCHECK_GT(paginationStrut, 0); |
974 // If we're not at the first in-flow child, there's a class A break point | 974 // If we're not at the first in-flow child, there's a class A break point |
975 // before the child. If we *are* at the first in-flow child, but the child | 975 // before the child. If we *are* at the first in-flow child, but the child |
976 // isn't flush with the content edge of its container, due to e.g. | 976 // isn't flush with the content edge of its container, due to e.g. |
977 // clearance, there's a class C break point before the child. Otherwise we | 977 // clearance, there's a class C break point before the child. Otherwise we |
978 // should propagate the strut to our parent block, and attempt to break | 978 // should propagate the strut to our parent block, and attempt to break |
979 // there instead. See https://drafts.csswg.org/css-break/#possible-breaks | 979 // there instead. See https://drafts.csswg.org/css-break/#possible-breaks |
980 bool canBreak = !layoutInfo.isAtFirstInFlowChild() || !atBeforeSideOfBlock; | 980 bool canBreak = !layoutInfo.isAtFirstInFlowChild() || !atBeforeSideOfBlock; |
981 if (!canBreak && child.getPaginationBreakability() == ForbidBreaks && | 981 if (!canBreak && child.getPaginationBreakability() == ForbidBreaks && |
982 !allowsPaginationStrut()) { | 982 !allowsPaginationStrut()) { |
983 // The child is monolithic content, e.g. an image. It is truly | 983 // The child is monolithic content, e.g. an image. It is truly |
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1373 LayoutUnit oldLogicalTop = logicalTopForFloat(*oldFloatingObject); | 1373 LayoutUnit oldLogicalTop = logicalTopForFloat(*oldFloatingObject); |
1374 if (logicalTop != oldLogicalTop) { | 1374 if (logicalTop != oldLogicalTop) { |
1375 changeLogicalTop = std::min(changeLogicalTop, | 1375 changeLogicalTop = std::min(changeLogicalTop, |
1376 std::min(logicalTop, oldLogicalTop)); | 1376 std::min(logicalTop, oldLogicalTop)); |
1377 changeLogicalBottom = std::max( | 1377 changeLogicalBottom = std::max( |
1378 changeLogicalBottom, std::max(logicalTop, oldLogicalTop)); | 1378 changeLogicalBottom, std::max(logicalTop, oldLogicalTop)); |
1379 } | 1379 } |
1380 } | 1380 } |
1381 | 1381 |
1382 if (oldFloatingObject->originatingLine() && !selfNeedsLayout()) { | 1382 if (oldFloatingObject->originatingLine() && !selfNeedsLayout()) { |
1383 ASSERT(oldFloatingObject->originatingLine() | 1383 DCHECK(oldFloatingObject->originatingLine() |
1384 ->getLineLayoutItem() | 1384 ->getLineLayoutItem() |
1385 .isEqual(this)); | 1385 .isEqual(this)); |
1386 oldFloatingObject->originatingLine()->markDirty(); | 1386 oldFloatingObject->originatingLine()->markDirty(); |
1387 } | 1387 } |
1388 | 1388 |
1389 floatMap.erase(floatingObject.layoutObject()); | 1389 floatMap.erase(floatingObject.layoutObject()); |
1390 } else { | 1390 } else { |
1391 changeLogicalTop = LayoutUnit(); | 1391 changeLogicalTop = LayoutUnit(); |
1392 changeLogicalBottom = std::max(changeLogicalBottom, logicalBottom); | 1392 changeLogicalBottom = std::max(changeLogicalBottom, logicalBottom); |
1393 } | 1393 } |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1507 LayoutUnit afterBorderPadding) | 1507 LayoutUnit afterBorderPadding) |
1508 : m_canCollapseMarginAfterWithLastChild(true), | 1508 : m_canCollapseMarginAfterWithLastChild(true), |
1509 m_atBeforeSideOfBlock(true), | 1509 m_atBeforeSideOfBlock(true), |
1510 m_atAfterSideOfBlock(false), | 1510 m_atAfterSideOfBlock(false), |
1511 m_hasMarginBeforeQuirk(false), | 1511 m_hasMarginBeforeQuirk(false), |
1512 m_hasMarginAfterQuirk(false), | 1512 m_hasMarginAfterQuirk(false), |
1513 m_determinedMarginBeforeQuirk(false), | 1513 m_determinedMarginBeforeQuirk(false), |
1514 m_discardMargin(false), | 1514 m_discardMargin(false), |
1515 m_lastChildIsSelfCollapsingBlockWithClearance(false) { | 1515 m_lastChildIsSelfCollapsingBlockWithClearance(false) { |
1516 const ComputedStyle& blockStyle = blockFlow->styleRef(); | 1516 const ComputedStyle& blockStyle = blockFlow->styleRef(); |
1517 ASSERT(blockFlow->isLayoutView() || blockFlow->parent()); | 1517 DCHECK(blockFlow->isLayoutView() || blockFlow->parent()); |
1518 m_canCollapseWithChildren = !blockFlow->createsNewFormattingContext() && | 1518 m_canCollapseWithChildren = !blockFlow->createsNewFormattingContext() && |
1519 !blockFlow->isLayoutFlowThread() && | 1519 !blockFlow->isLayoutFlowThread() && |
1520 !blockFlow->isLayoutView(); | 1520 !blockFlow->isLayoutView(); |
1521 | 1521 |
1522 m_canCollapseMarginBeforeWithChildren = | 1522 m_canCollapseMarginBeforeWithChildren = |
1523 m_canCollapseWithChildren && !beforeBorderPadding && | 1523 m_canCollapseWithChildren && !beforeBorderPadding && |
1524 blockStyle.marginBeforeCollapse() != MarginCollapseSeparate; | 1524 blockStyle.marginBeforeCollapse() != MarginCollapseSeparate; |
1525 | 1525 |
1526 // If any height other than auto is specified in CSS, then we don't collapse | 1526 // If any height other than auto is specified in CSS, then we don't collapse |
1527 // our bottom margins with our children's margins. To do otherwise would be to | 1527 // our bottom margins with our children's margins. To do otherwise would be to |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1762 if (!marginInfo.canCollapseWithMarginBefore()) { | 1762 if (!marginInfo.canCollapseWithMarginBefore()) { |
1763 // We need to make sure that the position of the self-collapsing block | 1763 // We need to make sure that the position of the self-collapsing block |
1764 // is correct, since it could have overflowing content | 1764 // is correct, since it could have overflowing content |
1765 // that needs to be positioned correctly (e.g., a block that | 1765 // that needs to be positioned correctly (e.g., a block that |
1766 // had a specified height of 0 but that actually had subcontent). | 1766 // had a specified height of 0 but that actually had subcontent). |
1767 logicalTop = logicalHeight() + collapsedBeforePos - collapsedBeforeNeg; | 1767 logicalTop = logicalHeight() + collapsedBeforePos - collapsedBeforeNeg; |
1768 } | 1768 } |
1769 } | 1769 } |
1770 } else { | 1770 } else { |
1771 if (mustSeparateMarginBeforeForChild(child)) { | 1771 if (mustSeparateMarginBeforeForChild(child)) { |
1772 ASSERT(!marginInfo.discardMargin() || | 1772 DCHECK(!marginInfo.discardMargin() || |
1773 (marginInfo.discardMargin() && !marginInfo.margin())); | 1773 (marginInfo.discardMargin() && !marginInfo.margin())); |
1774 // If we are at the before side of the block and we collapse, ignore the | 1774 // If we are at the before side of the block and we collapse, ignore the |
1775 // computed margin and just add the child margin to the container height. | 1775 // computed margin and just add the child margin to the container height. |
1776 // This will correctly position the child inside the container. | 1776 // This will correctly position the child inside the container. |
1777 LayoutUnit separateMargin = !marginInfo.canCollapseWithMarginBefore() | 1777 LayoutUnit separateMargin = !marginInfo.canCollapseWithMarginBefore() |
1778 ? marginInfo.margin() | 1778 ? marginInfo.margin() |
1779 : LayoutUnit(); | 1779 : LayoutUnit(); |
1780 setLogicalHeight(logicalHeight() + separateMargin + | 1780 setLogicalHeight(logicalHeight() + separateMargin + |
1781 marginBeforeForChild(child)); | 1781 marginBeforeForChild(child)); |
1782 logicalTop = logicalHeight(); | 1782 logicalTop = logicalHeight(); |
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2171 LayoutUnit afterSide, | 2171 LayoutUnit afterSide, |
2172 MarginInfo& marginInfo) { | 2172 MarginInfo& marginInfo) { |
2173 marginInfo.setAtAfterSideOfBlock(true); | 2173 marginInfo.setAtAfterSideOfBlock(true); |
2174 | 2174 |
2175 // If our last child was a self-collapsing block with clearance then our | 2175 // If our last child was a self-collapsing block with clearance then our |
2176 // logical height is flush with the bottom edge of the float that the child | 2176 // logical height is flush with the bottom edge of the float that the child |
2177 // clears. The correct vertical position for the margin-collapsing we want to | 2177 // clears. The correct vertical position for the margin-collapsing we want to |
2178 // perform now is at the child's margin-top - so adjust our height to that | 2178 // perform now is at the child's margin-top - so adjust our height to that |
2179 // position. | 2179 // position. |
2180 if (marginInfo.lastChildIsSelfCollapsingBlockWithClearance()) { | 2180 if (marginInfo.lastChildIsSelfCollapsingBlockWithClearance()) { |
2181 ASSERT(lastChild); | 2181 DCHECK(lastChild); |
2182 setLogicalHeight(logicalHeight() - | 2182 setLogicalHeight(logicalHeight() - |
2183 marginValuesForChild(*lastChild).positiveMarginBefore()); | 2183 marginValuesForChild(*lastChild).positiveMarginBefore()); |
2184 } | 2184 } |
2185 | 2185 |
2186 if (marginInfo.canCollapseMarginAfterWithChildren() && | 2186 if (marginInfo.canCollapseMarginAfterWithChildren() && |
2187 !marginInfo.canCollapseMarginAfterWithLastChild()) | 2187 !marginInfo.canCollapseMarginAfterWithLastChild()) |
2188 marginInfo.setCanCollapseMarginAfterWithChildren(false); | 2188 marginInfo.setCanCollapseMarginAfterWithChildren(false); |
2189 | 2189 |
2190 // If we can't collapse with children then go ahead and add in the bottom | 2190 // If we can't collapse with children then go ahead and add in the bottom |
2191 // margin. | 2191 // margin. |
(...skipping 19 matching lines...) Expand all Loading... |
2211 // siblings. So propagate the break-after value, and keep looking for a class | 2211 // siblings. So propagate the break-after value, and keep looking for a class |
2212 // A break point (at the next in-flow block-level object), where we'll join | 2212 // A break point (at the next in-flow block-level object), where we'll join |
2213 // this break-after value with the break-before value there. | 2213 // this break-after value with the break-before value there. |
2214 if (view()->layoutState()->isPaginated() && lastChild) | 2214 if (view()->layoutState()->isPaginated() && lastChild) |
2215 setBreakAfter( | 2215 setBreakAfter( |
2216 joinFragmentainerBreakValues(breakAfter(), lastChild->breakAfter())); | 2216 joinFragmentainerBreakValues(breakAfter(), lastChild->breakAfter())); |
2217 } | 2217 } |
2218 | 2218 |
2219 void LayoutBlockFlow::setMustDiscardMarginBefore(bool value) { | 2219 void LayoutBlockFlow::setMustDiscardMarginBefore(bool value) { |
2220 if (style()->marginBeforeCollapse() == MarginCollapseDiscard) { | 2220 if (style()->marginBeforeCollapse() == MarginCollapseDiscard) { |
2221 ASSERT(value); | 2221 DCHECK(value); |
2222 return; | 2222 return; |
2223 } | 2223 } |
2224 | 2224 |
2225 if (!m_rareData && !value) | 2225 if (!m_rareData && !value) |
2226 return; | 2226 return; |
2227 | 2227 |
2228 if (!m_rareData) | 2228 if (!m_rareData) |
2229 m_rareData = WTF::makeUnique<LayoutBlockFlowRareData>(this); | 2229 m_rareData = WTF::makeUnique<LayoutBlockFlowRareData>(this); |
2230 | 2230 |
2231 m_rareData->m_discardMarginBefore = value; | 2231 m_rareData->m_discardMarginBefore = value; |
2232 } | 2232 } |
2233 | 2233 |
2234 void LayoutBlockFlow::setMustDiscardMarginAfter(bool value) { | 2234 void LayoutBlockFlow::setMustDiscardMarginAfter(bool value) { |
2235 if (style()->marginAfterCollapse() == MarginCollapseDiscard) { | 2235 if (style()->marginAfterCollapse() == MarginCollapseDiscard) { |
2236 ASSERT(value); | 2236 DCHECK(value); |
2237 return; | 2237 return; |
2238 } | 2238 } |
2239 | 2239 |
2240 if (!m_rareData && !value) | 2240 if (!m_rareData && !value) |
2241 return; | 2241 return; |
2242 | 2242 |
2243 if (!m_rareData) | 2243 if (!m_rareData) |
2244 m_rareData = WTF::makeUnique<LayoutBlockFlowRareData>(this); | 2244 m_rareData = WTF::makeUnique<LayoutBlockFlowRareData>(this); |
2245 | 2245 |
2246 m_rareData->m_discardMarginAfter = value; | 2246 m_rareData->m_discardMarginAfter = value; |
2247 } | 2247 } |
2248 | 2248 |
2249 bool LayoutBlockFlow::mustDiscardMarginBefore() const { | 2249 bool LayoutBlockFlow::mustDiscardMarginBefore() const { |
2250 return style()->marginBeforeCollapse() == MarginCollapseDiscard || | 2250 return style()->marginBeforeCollapse() == MarginCollapseDiscard || |
2251 (m_rareData && m_rareData->m_discardMarginBefore); | 2251 (m_rareData && m_rareData->m_discardMarginBefore); |
2252 } | 2252 } |
2253 | 2253 |
2254 bool LayoutBlockFlow::mustDiscardMarginAfter() const { | 2254 bool LayoutBlockFlow::mustDiscardMarginAfter() const { |
2255 return style()->marginAfterCollapse() == MarginCollapseDiscard || | 2255 return style()->marginAfterCollapse() == MarginCollapseDiscard || |
2256 (m_rareData && m_rareData->m_discardMarginAfter); | 2256 (m_rareData && m_rareData->m_discardMarginAfter); |
2257 } | 2257 } |
2258 | 2258 |
2259 bool LayoutBlockFlow::mustDiscardMarginBeforeForChild( | 2259 bool LayoutBlockFlow::mustDiscardMarginBeforeForChild( |
2260 const LayoutBox& child) const { | 2260 const LayoutBox& child) const { |
2261 ASSERT(!child.selfNeedsLayout()); | 2261 DCHECK(!child.selfNeedsLayout()); |
2262 if (!child.isWritingModeRoot()) | 2262 if (!child.isWritingModeRoot()) |
2263 return child.isLayoutBlockFlow() | 2263 return child.isLayoutBlockFlow() |
2264 ? toLayoutBlockFlow(&child)->mustDiscardMarginBefore() | 2264 ? toLayoutBlockFlow(&child)->mustDiscardMarginBefore() |
2265 : (child.style()->marginBeforeCollapse() == | 2265 : (child.style()->marginBeforeCollapse() == |
2266 MarginCollapseDiscard); | 2266 MarginCollapseDiscard); |
2267 if (child.isHorizontalWritingMode() == isHorizontalWritingMode()) | 2267 if (child.isHorizontalWritingMode() == isHorizontalWritingMode()) |
2268 return child.isLayoutBlockFlow() | 2268 return child.isLayoutBlockFlow() |
2269 ? toLayoutBlockFlow(&child)->mustDiscardMarginAfter() | 2269 ? toLayoutBlockFlow(&child)->mustDiscardMarginAfter() |
2270 : (child.style()->marginAfterCollapse() == | 2270 : (child.style()->marginAfterCollapse() == |
2271 MarginCollapseDiscard); | 2271 MarginCollapseDiscard); |
2272 | 2272 |
2273 // FIXME: We return false here because the implementation is not geometrically | 2273 // FIXME: We return false here because the implementation is not geometrically |
2274 // complete. We have values only for before/after, not start/end. | 2274 // complete. We have values only for before/after, not start/end. |
2275 // In case the boxes are perpendicular we assume the property is not | 2275 // In case the boxes are perpendicular we assume the property is not |
2276 // specified. | 2276 // specified. |
2277 return false; | 2277 return false; |
2278 } | 2278 } |
2279 | 2279 |
2280 bool LayoutBlockFlow::mustDiscardMarginAfterForChild( | 2280 bool LayoutBlockFlow::mustDiscardMarginAfterForChild( |
2281 const LayoutBox& child) const { | 2281 const LayoutBox& child) const { |
2282 ASSERT(!child.selfNeedsLayout()); | 2282 DCHECK(!child.selfNeedsLayout()); |
2283 if (!child.isWritingModeRoot()) | 2283 if (!child.isWritingModeRoot()) |
2284 return child.isLayoutBlockFlow() | 2284 return child.isLayoutBlockFlow() |
2285 ? toLayoutBlockFlow(&child)->mustDiscardMarginAfter() | 2285 ? toLayoutBlockFlow(&child)->mustDiscardMarginAfter() |
2286 : (child.style()->marginAfterCollapse() == | 2286 : (child.style()->marginAfterCollapse() == |
2287 MarginCollapseDiscard); | 2287 MarginCollapseDiscard); |
2288 if (child.isHorizontalWritingMode() == isHorizontalWritingMode()) | 2288 if (child.isHorizontalWritingMode() == isHorizontalWritingMode()) |
2289 return child.isLayoutBlockFlow() | 2289 return child.isLayoutBlockFlow() |
2290 ? toLayoutBlockFlow(&child)->mustDiscardMarginBefore() | 2290 ? toLayoutBlockFlow(&child)->mustDiscardMarginBefore() |
2291 : (child.style()->marginBeforeCollapse() == | 2291 : (child.style()->marginBeforeCollapse() == |
2292 MarginCollapseDiscard); | 2292 MarginCollapseDiscard); |
(...skipping 19 matching lines...) Expand all Loading... |
2312 neg == LayoutBlockFlowRareData::negativeMarginAfterDefault(this)) | 2312 neg == LayoutBlockFlowRareData::negativeMarginAfterDefault(this)) |
2313 return; | 2313 return; |
2314 m_rareData = WTF::makeUnique<LayoutBlockFlowRareData>(this); | 2314 m_rareData = WTF::makeUnique<LayoutBlockFlowRareData>(this); |
2315 } | 2315 } |
2316 m_rareData->m_margins.setPositiveMarginAfter(pos); | 2316 m_rareData->m_margins.setPositiveMarginAfter(pos); |
2317 m_rareData->m_margins.setNegativeMarginAfter(neg); | 2317 m_rareData->m_margins.setNegativeMarginAfter(neg); |
2318 } | 2318 } |
2319 | 2319 |
2320 bool LayoutBlockFlow::mustSeparateMarginBeforeForChild( | 2320 bool LayoutBlockFlow::mustSeparateMarginBeforeForChild( |
2321 const LayoutBox& child) const { | 2321 const LayoutBox& child) const { |
2322 ASSERT(!child.selfNeedsLayout()); | 2322 DCHECK(!child.selfNeedsLayout()); |
2323 const ComputedStyle& childStyle = child.styleRef(); | 2323 const ComputedStyle& childStyle = child.styleRef(); |
2324 if (!child.isWritingModeRoot()) | 2324 if (!child.isWritingModeRoot()) |
2325 return childStyle.marginBeforeCollapse() == MarginCollapseSeparate; | 2325 return childStyle.marginBeforeCollapse() == MarginCollapseSeparate; |
2326 if (child.isHorizontalWritingMode() == isHorizontalWritingMode()) | 2326 if (child.isHorizontalWritingMode() == isHorizontalWritingMode()) |
2327 return childStyle.marginAfterCollapse() == MarginCollapseSeparate; | 2327 return childStyle.marginAfterCollapse() == MarginCollapseSeparate; |
2328 | 2328 |
2329 // FIXME: See |mustDiscardMarginBeforeForChild| above. | 2329 // FIXME: See |mustDiscardMarginBeforeForChild| above. |
2330 return false; | 2330 return false; |
2331 } | 2331 } |
2332 | 2332 |
2333 bool LayoutBlockFlow::mustSeparateMarginAfterForChild( | 2333 bool LayoutBlockFlow::mustSeparateMarginAfterForChild( |
2334 const LayoutBox& child) const { | 2334 const LayoutBox& child) const { |
2335 ASSERT(!child.selfNeedsLayout()); | 2335 DCHECK(!child.selfNeedsLayout()); |
2336 const ComputedStyle& childStyle = child.styleRef(); | 2336 const ComputedStyle& childStyle = child.styleRef(); |
2337 if (!child.isWritingModeRoot()) | 2337 if (!child.isWritingModeRoot()) |
2338 return childStyle.marginAfterCollapse() == MarginCollapseSeparate; | 2338 return childStyle.marginAfterCollapse() == MarginCollapseSeparate; |
2339 if (child.isHorizontalWritingMode() == isHorizontalWritingMode()) | 2339 if (child.isHorizontalWritingMode() == isHorizontalWritingMode()) |
2340 return childStyle.marginBeforeCollapse() == MarginCollapseSeparate; | 2340 return childStyle.marginBeforeCollapse() == MarginCollapseSeparate; |
2341 | 2341 |
2342 // FIXME: See |mustDiscardMarginBeforeForChild| above. | 2342 // FIXME: See |mustDiscardMarginBeforeForChild| above. |
2343 return false; | 2343 return false; |
2344 } | 2344 } |
2345 | 2345 |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2505 | 2505 |
2506 void LayoutBlockFlow::deleteLineBoxTree() { | 2506 void LayoutBlockFlow::deleteLineBoxTree() { |
2507 if (containsFloats()) | 2507 if (containsFloats()) |
2508 m_floatingObjects->clearLineBoxTreePointers(); | 2508 m_floatingObjects->clearLineBoxTreePointers(); |
2509 | 2509 |
2510 m_lineBoxes.deleteLineBoxTree(); | 2510 m_lineBoxes.deleteLineBoxTree(); |
2511 } | 2511 } |
2512 | 2512 |
2513 int LayoutBlockFlow::lineCount(const RootInlineBox* stopRootInlineBox) const { | 2513 int LayoutBlockFlow::lineCount(const RootInlineBox* stopRootInlineBox) const { |
2514 #ifndef NDEBUG | 2514 #ifndef NDEBUG |
2515 ASSERT(!stopRootInlineBox || | 2515 DCHECK(!stopRootInlineBox || |
2516 stopRootInlineBox->block().debugPointer() == this); | 2516 stopRootInlineBox->block().debugPointer() == this); |
2517 #endif | 2517 #endif |
2518 if (!childrenInline()) | 2518 if (!childrenInline()) |
2519 return 0; | 2519 return 0; |
2520 | 2520 |
2521 int count = 0; | 2521 int count = 0; |
2522 for (const RootInlineBox* box = firstRootBox(); box; | 2522 for (const RootInlineBox* box = firstRootBox(); box; |
2523 box = box->nextRootBox()) { | 2523 box = box->nextRootBox()) { |
2524 count++; | 2524 count++; |
2525 if (box == stopRootInlineBox) | 2525 if (box == stopRootInlineBox) |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2738 // addition of overhanging floats from previous siblings when negative | 2738 // addition of overhanging floats from previous siblings when negative |
2739 // margins exist on a child (see the addOverhangingFloats call at the | 2739 // margins exist on a child (see the addOverhangingFloats call at the |
2740 // end of collapseMargins). | 2740 // end of collapseMargins). |
2741 if (childLogicalWidthAtOldLogicalTopOffset != | 2741 if (childLogicalWidthAtOldLogicalTopOffset != |
2742 childLogicalWidthAtNewLogicalTopOffset) | 2742 childLogicalWidthAtNewLogicalTopOffset) |
2743 child->setChildNeedsLayout(MarkOnlyThis); | 2743 child->setChildNeedsLayout(MarkOnlyThis); |
2744 return newLogicalTop - logicalTop; | 2744 return newLogicalTop - logicalTop; |
2745 } | 2745 } |
2746 | 2746 |
2747 newLogicalTop = nextFloatLogicalBottomBelowForBlock(newLogicalTop); | 2747 newLogicalTop = nextFloatLogicalBottomBelowForBlock(newLogicalTop); |
2748 ASSERT(newLogicalTop >= logicalTop); | 2748 DCHECK_GE(newLogicalTop, logicalTop); |
2749 if (newLogicalTop < logicalTop) | 2749 if (newLogicalTop < logicalTop) |
2750 break; | 2750 break; |
2751 } | 2751 } |
2752 NOTREACHED(); | 2752 NOTREACHED(); |
2753 } | 2753 } |
2754 return result; | 2754 return result; |
2755 } | 2755 } |
2756 | 2756 |
2757 void LayoutBlockFlow::createFloatingObjects() { | 2757 void LayoutBlockFlow::createFloatingObjects() { |
2758 m_floatingObjects = | 2758 m_floatingObjects = |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2924 LayoutBoxModelObject* continuation = this->continuation(); | 2924 LayoutBoxModelObject* continuation = this->continuation(); |
2925 return continuation && continuation->isInline() ? toLayoutInline(continuation) | 2925 return continuation && continuation->isInline() ? toLayoutInline(continuation) |
2926 : nullptr; | 2926 : nullptr; |
2927 } | 2927 } |
2928 | 2928 |
2929 void LayoutBlockFlow::addChild(LayoutObject* newChild, | 2929 void LayoutBlockFlow::addChild(LayoutObject* newChild, |
2930 LayoutObject* beforeChild) { | 2930 LayoutObject* beforeChild) { |
2931 if (LayoutMultiColumnFlowThread* flowThread = multiColumnFlowThread()) { | 2931 if (LayoutMultiColumnFlowThread* flowThread = multiColumnFlowThread()) { |
2932 if (beforeChild == flowThread) | 2932 if (beforeChild == flowThread) |
2933 beforeChild = flowThread->firstChild(); | 2933 beforeChild = flowThread->firstChild(); |
2934 ASSERT(!beforeChild || beforeChild->isDescendantOf(flowThread)); | 2934 DCHECK(!beforeChild || beforeChild->isDescendantOf(flowThread)); |
2935 flowThread->addChild(newChild, beforeChild); | 2935 flowThread->addChild(newChild, beforeChild); |
2936 return; | 2936 return; |
2937 } | 2937 } |
2938 | 2938 |
2939 if (beforeChild && beforeChild->parent() != this) { | 2939 if (beforeChild && beforeChild->parent() != this) { |
2940 addChildBeforeDescendant(newChild, beforeChild); | 2940 addChildBeforeDescendant(newChild, beforeChild); |
2941 return; | 2941 return; |
2942 } | 2942 } |
2943 | 2943 |
2944 bool madeBoxesNonInline = false; | 2944 bool madeBoxesNonInline = false; |
2945 | 2945 |
2946 // A block has to either have all of its children inline, or all of its | 2946 // A block has to either have all of its children inline, or all of its |
2947 // children as blocks. | 2947 // children as blocks. |
2948 // So, if our children are currently inline and a block child has to be | 2948 // So, if our children are currently inline and a block child has to be |
2949 // inserted, we move all our inline children into anonymous block boxes. | 2949 // inserted, we move all our inline children into anonymous block boxes. |
2950 bool childIsBlockLevel = | 2950 bool childIsBlockLevel = |
2951 !newChild->isInline() && !newChild->isFloatingOrOutOfFlowPositioned(); | 2951 !newChild->isInline() && !newChild->isFloatingOrOutOfFlowPositioned(); |
2952 if (childrenInline()) { | 2952 if (childrenInline()) { |
2953 if (childIsBlockLevel) { | 2953 if (childIsBlockLevel) { |
2954 // Wrap the inline content in anonymous blocks, to allow for the new block | 2954 // Wrap the inline content in anonymous blocks, to allow for the new block |
2955 // child to be inserted. | 2955 // child to be inserted. |
2956 makeChildrenNonInline(beforeChild); | 2956 makeChildrenNonInline(beforeChild); |
2957 madeBoxesNonInline = true; | 2957 madeBoxesNonInline = true; |
2958 | 2958 |
2959 if (beforeChild && beforeChild->parent() != this) { | 2959 if (beforeChild && beforeChild->parent() != this) { |
2960 beforeChild = beforeChild->parent(); | 2960 beforeChild = beforeChild->parent(); |
2961 ASSERT(beforeChild->isAnonymousBlock()); | 2961 DCHECK(beforeChild->isAnonymousBlock()); |
2962 ASSERT(beforeChild->parent() == this); | 2962 DCHECK_EQ(beforeChild->parent(), this); |
2963 } | 2963 } |
2964 } | 2964 } |
2965 } else if (!childIsBlockLevel) { | 2965 } else if (!childIsBlockLevel) { |
2966 // This block has block children. We may want to put the new child into an | 2966 // This block has block children. We may want to put the new child into an |
2967 // anomyous block. Floats and out-of-flow children may live among either | 2967 // anomyous block. Floats and out-of-flow children may live among either |
2968 // block or inline children, so for such children, only put them inside an | 2968 // block or inline children, so for such children, only put them inside an |
2969 // anonymous block if one already exists. If the child is inline, on the | 2969 // anonymous block if one already exists. If the child is inline, on the |
2970 // other hand, we *have to* put it inside an anonymous block, so create a | 2970 // other hand, we *have to* put it inside an anonymous block, so create a |
2971 // new one if there is none for us there already. | 2971 // new one if there is none for us there already. |
2972 LayoutObject* afterChild = | 2972 LayoutObject* afterChild = |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3185 | 3185 |
3186 if (!isMergeableAnonymousBlock(this) || | 3186 if (!isMergeableAnonymousBlock(this) || |
3187 !isMergeableAnonymousBlock(siblingThatMayBeDeleted)) | 3187 !isMergeableAnonymousBlock(siblingThatMayBeDeleted)) |
3188 return false; | 3188 return false; |
3189 | 3189 |
3190 setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation( | 3190 setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation( |
3191 LayoutInvalidationReason::AnonymousBlockChange); | 3191 LayoutInvalidationReason::AnonymousBlockChange); |
3192 | 3192 |
3193 // If the inlineness of children of the two block don't match, we'd need | 3193 // If the inlineness of children of the two block don't match, we'd need |
3194 // special code here (but there should be no need for it). | 3194 // special code here (but there should be no need for it). |
3195 ASSERT(siblingThatMayBeDeleted->childrenInline() == childrenInline()); | 3195 DCHECK_EQ(siblingThatMayBeDeleted->childrenInline(), childrenInline()); |
3196 // Take all the children out of the |next| block and put them in | 3196 // Take all the children out of the |next| block and put them in |
3197 // the |prev| block. | 3197 // the |prev| block. |
3198 siblingThatMayBeDeleted->moveAllChildrenIncludingFloatsTo( | 3198 siblingThatMayBeDeleted->moveAllChildrenIncludingFloatsTo( |
3199 this, siblingThatMayBeDeleted->hasLayer() || hasLayer()); | 3199 this, siblingThatMayBeDeleted->hasLayer() || hasLayer()); |
3200 // Delete the now-empty block's lines and nuke it. | 3200 // Delete the now-empty block's lines and nuke it. |
3201 siblingThatMayBeDeleted->deleteLineBoxTree(); | 3201 siblingThatMayBeDeleted->deleteLineBoxTree(); |
3202 siblingThatMayBeDeleted->destroy(); | 3202 siblingThatMayBeDeleted->destroy(); |
3203 return true; | 3203 return true; |
3204 } | 3204 } |
3205 | 3205 |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3330 } | 3330 } |
3331 | 3331 |
3332 void LayoutBlockFlow::makeChildrenNonInline(LayoutObject* insertionPoint) { | 3332 void LayoutBlockFlow::makeChildrenNonInline(LayoutObject* insertionPoint) { |
3333 // makeChildrenNonInline takes a block whose children are *all* inline and it | 3333 // makeChildrenNonInline takes a block whose children are *all* inline and it |
3334 // makes sure that inline children are coalesced under anonymous blocks. | 3334 // makes sure that inline children are coalesced under anonymous blocks. |
3335 // If |insertionPoint| is defined, then it represents the insertion point for | 3335 // If |insertionPoint| is defined, then it represents the insertion point for |
3336 // the new block child that is causing us to have to wrap all the inlines. | 3336 // the new block child that is causing us to have to wrap all the inlines. |
3337 // This means that we cannot coalesce inlines before |insertionPoint| with | 3337 // This means that we cannot coalesce inlines before |insertionPoint| with |
3338 // inlines following |insertionPoint|, because the new child is going to be | 3338 // inlines following |insertionPoint|, because the new child is going to be |
3339 // inserted in between the inlines, splitting them. | 3339 // inserted in between the inlines, splitting them. |
3340 ASSERT(!isInline() || isAtomicInlineLevel()); | 3340 DCHECK(!isInline() || isAtomicInlineLevel()); |
3341 ASSERT(!insertionPoint || insertionPoint->parent() == this); | 3341 DCHECK(!insertionPoint || insertionPoint->parent() == this); |
3342 | 3342 |
3343 setChildrenInline(false); | 3343 setChildrenInline(false); |
3344 | 3344 |
3345 LayoutObject* child = firstChild(); | 3345 LayoutObject* child = firstChild(); |
3346 if (!child) | 3346 if (!child) |
3347 return; | 3347 return; |
3348 | 3348 |
3349 deleteLineBoxTree(); | 3349 deleteLineBoxTree(); |
3350 | 3350 |
3351 while (child) { | 3351 while (child) { |
3352 LayoutObject* inlineRunStart; | 3352 LayoutObject* inlineRunStart; |
3353 LayoutObject* inlineRunEnd; | 3353 LayoutObject* inlineRunEnd; |
3354 getInlineRun(child, insertionPoint, inlineRunStart, inlineRunEnd); | 3354 getInlineRun(child, insertionPoint, inlineRunStart, inlineRunEnd); |
3355 | 3355 |
3356 if (!inlineRunStart) | 3356 if (!inlineRunStart) |
3357 break; | 3357 break; |
3358 | 3358 |
3359 child = inlineRunEnd->nextSibling(); | 3359 child = inlineRunEnd->nextSibling(); |
3360 | 3360 |
3361 LayoutBlock* block = createAnonymousBlock(); | 3361 LayoutBlock* block = createAnonymousBlock(); |
3362 children()->insertChildNode(this, block, inlineRunStart); | 3362 children()->insertChildNode(this, block, inlineRunStart); |
3363 moveChildrenTo(block, inlineRunStart, child); | 3363 moveChildrenTo(block, inlineRunStart, child); |
3364 } | 3364 } |
3365 | 3365 |
3366 #if DCHECK_IS_ON() | 3366 #if DCHECK_IS_ON() |
3367 for (LayoutObject* c = firstChild(); c; c = c->nextSibling()) | 3367 for (LayoutObject* c = firstChild(); c; c = c->nextSibling()) |
3368 ASSERT(!c->isInline()); | 3368 DCHECK(!c->isInline()); |
3369 #endif | 3369 #endif |
3370 | 3370 |
3371 setShouldDoFullPaintInvalidation(); | 3371 setShouldDoFullPaintInvalidation(); |
3372 } | 3372 } |
3373 | 3373 |
3374 void LayoutBlockFlow::childBecameNonInline(LayoutObject*) { | 3374 void LayoutBlockFlow::childBecameNonInline(LayoutObject*) { |
3375 makeChildrenNonInline(); | 3375 makeChildrenNonInline(); |
3376 if (isAnonymousBlock() && parent() && parent()->isLayoutBlock()) | 3376 if (isAnonymousBlock() && parent() && parent()->isLayoutBlock()) |
3377 toLayoutBlock(parent())->removeLeftoverAnonymousBlock(this); | 3377 toLayoutBlock(parent())->removeLeftoverAnonymousBlock(this); |
3378 // |this| may be dead here | 3378 // |this| may be dead here |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3508 // Use the original width of the float here, since the local variable | 3508 // Use the original width of the float here, since the local variable |
3509 // |floatLogicalWidth| was capped to the available line width. See | 3509 // |floatLogicalWidth| was capped to the available line width. See |
3510 // fast/block/float/clamped-right-float.html. | 3510 // fast/block/float/clamped-right-float.html. |
3511 floatLogicalLeft -= logicalWidthForFloat(floatingObject); | 3511 floatLogicalLeft -= logicalWidthForFloat(floatingObject); |
3512 } | 3512 } |
3513 | 3513 |
3514 return LayoutPoint(floatLogicalLeft, logicalTopOffset); | 3514 return LayoutPoint(floatLogicalLeft, logicalTopOffset); |
3515 } | 3515 } |
3516 | 3516 |
3517 FloatingObject* LayoutBlockFlow::insertFloatingObject(LayoutBox& floatBox) { | 3517 FloatingObject* LayoutBlockFlow::insertFloatingObject(LayoutBox& floatBox) { |
3518 ASSERT(floatBox.isFloating()); | 3518 DCHECK(floatBox.isFloating()); |
3519 | 3519 |
3520 // Create the list of special objects if we don't aleady have one | 3520 // Create the list of special objects if we don't aleady have one |
3521 if (!m_floatingObjects) { | 3521 if (!m_floatingObjects) { |
3522 createFloatingObjects(); | 3522 createFloatingObjects(); |
3523 } else { | 3523 } else { |
3524 // Don't insert the object again if it's already in the list | 3524 // Don't insert the object again if it's already in the list |
3525 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); | 3525 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); |
3526 FloatingObjectSetIterator it = | 3526 FloatingObjectSetIterator it = |
3527 floatingObjectSet.find<FloatingObjectHashTranslator>(&floatBox); | 3527 floatingObjectSet.find<FloatingObjectHashTranslator>(&floatBox); |
3528 if (it != floatingObjectSet.end()) | 3528 if (it != floatingObjectSet.end()) |
(...skipping 22 matching lines...) Expand all Loading... |
3551 logicalTop == LayoutUnit::max()) { | 3551 logicalTop == LayoutUnit::max()) { |
3552 logicalBottom = LayoutUnit::max(); | 3552 logicalBottom = LayoutUnit::max(); |
3553 } else { | 3553 } else { |
3554 // Special-case zero- and less-than-zero-height floats: those don't | 3554 // Special-case zero- and less-than-zero-height floats: those don't |
3555 // touch the line that they're on, but it still needs to be dirtied. | 3555 // touch the line that they're on, but it still needs to be dirtied. |
3556 // This is accomplished by pretending they have a height of 1. | 3556 // This is accomplished by pretending they have a height of 1. |
3557 logicalBottom = std::max(logicalBottom, logicalTop + 1); | 3557 logicalBottom = std::max(logicalBottom, logicalTop + 1); |
3558 } | 3558 } |
3559 if (floatingObject.originatingLine()) { | 3559 if (floatingObject.originatingLine()) { |
3560 if (!selfNeedsLayout()) { | 3560 if (!selfNeedsLayout()) { |
3561 ASSERT( | 3561 DCHECK( |
3562 floatingObject.originatingLine()->getLineLayoutItem().isEqual( | 3562 floatingObject.originatingLine()->getLineLayoutItem().isEqual( |
3563 this)); | 3563 this)); |
3564 floatingObject.originatingLine()->markDirty(); | 3564 floatingObject.originatingLine()->markDirty(); |
3565 } | 3565 } |
3566 #if DCHECK_IS_ON() | 3566 #if DCHECK_IS_ON() |
3567 floatingObject.setOriginatingLine(nullptr); | 3567 floatingObject.setOriginatingLine(nullptr); |
3568 #endif | 3568 #endif |
3569 } | 3569 } |
3570 markLinesDirtyInBlockRange(LayoutUnit(), logicalBottom); | 3570 markLinesDirtyInBlockRange(LayoutUnit(), logicalBottom); |
3571 } | 3571 } |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3770 floatingObjectSet.find<FloatingObjectHashTranslator>(layoutBox); | 3770 floatingObjectSet.find<FloatingObjectHashTranslator>(layoutBox); |
3771 if (it == floatingObjectSet.end()) | 3771 if (it == floatingObjectSet.end()) |
3772 return false; | 3772 return false; |
3773 | 3773 |
3774 return isOverhangingFloat(**it); | 3774 return isOverhangingFloat(**it); |
3775 } | 3775 } |
3776 | 3776 |
3777 void LayoutBlockFlow::addIntrudingFloats(LayoutBlockFlow* prev, | 3777 void LayoutBlockFlow::addIntrudingFloats(LayoutBlockFlow* prev, |
3778 LayoutUnit logicalLeftOffset, | 3778 LayoutUnit logicalLeftOffset, |
3779 LayoutUnit logicalTopOffset) { | 3779 LayoutUnit logicalTopOffset) { |
3780 ASSERT(!avoidsFloats()); | 3780 DCHECK(!avoidsFloats()); |
3781 | 3781 |
3782 // If we create our own block formatting context then our contents don't | 3782 // If we create our own block formatting context then our contents don't |
3783 // interact with floats outside it, even those from our parent. | 3783 // interact with floats outside it, even those from our parent. |
3784 if (createsNewFormattingContext()) | 3784 if (createsNewFormattingContext()) |
3785 return; | 3785 return; |
3786 | 3786 |
3787 // If the parent or previous sibling doesn't have any floats to add, don't | 3787 // If the parent or previous sibling doesn't have any floats to add, don't |
3788 // bother. | 3788 // bother. |
3789 if (!prev->m_floatingObjects) | 3789 if (!prev->m_floatingObjects) |
3790 return; | 3790 return; |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4039 LayoutUnit logicalHeight) const { | 4039 LayoutUnit logicalHeight) const { |
4040 if (m_floatingObjects && m_floatingObjects->hasRightObjects()) | 4040 if (m_floatingObjects && m_floatingObjects->hasRightObjects()) |
4041 return m_floatingObjects->logicalRightOffset(fixedOffset, logicalTop, | 4041 return m_floatingObjects->logicalRightOffset(fixedOffset, logicalTop, |
4042 logicalHeight); | 4042 logicalHeight); |
4043 | 4043 |
4044 return fixedOffset; | 4044 return fixedOffset; |
4045 } | 4045 } |
4046 | 4046 |
4047 void LayoutBlockFlow::updateAncestorShouldPaintFloatingObject( | 4047 void LayoutBlockFlow::updateAncestorShouldPaintFloatingObject( |
4048 const LayoutBox& floatBox) { | 4048 const LayoutBox& floatBox) { |
4049 ASSERT(floatBox.isFloating()); | 4049 DCHECK(floatBox.isFloating()); |
4050 bool floatBoxIsSelfPaintingLayer = | 4050 bool floatBoxIsSelfPaintingLayer = |
4051 floatBox.hasLayer() && floatBox.layer()->isSelfPaintingLayer(); | 4051 floatBox.hasLayer() && floatBox.layer()->isSelfPaintingLayer(); |
4052 for (LayoutObject* ancestor = floatBox.parent(); | 4052 for (LayoutObject* ancestor = floatBox.parent(); |
4053 ancestor && ancestor->isLayoutBlockFlow(); | 4053 ancestor && ancestor->isLayoutBlockFlow(); |
4054 ancestor = ancestor->parent()) { | 4054 ancestor = ancestor->parent()) { |
4055 LayoutBlockFlow* ancestorBlock = toLayoutBlockFlow(ancestor); | 4055 LayoutBlockFlow* ancestorBlock = toLayoutBlockFlow(ancestor); |
4056 FloatingObjects* ancestorFloatingObjects = | 4056 FloatingObjects* ancestorFloatingObjects = |
4057 ancestorBlock->m_floatingObjects.get(); | 4057 ancestorBlock->m_floatingObjects.get(); |
4058 if (!ancestorFloatingObjects) | 4058 if (!ancestorFloatingObjects) |
4059 break; | 4059 break; |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4245 void LayoutBlockFlow::createOrDestroyMultiColumnFlowThreadIfNeeded( | 4245 void LayoutBlockFlow::createOrDestroyMultiColumnFlowThreadIfNeeded( |
4246 const ComputedStyle* oldStyle) { | 4246 const ComputedStyle* oldStyle) { |
4247 // Paged overflow trumps multicol in this implementation. Ideally, it should | 4247 // Paged overflow trumps multicol in this implementation. Ideally, it should |
4248 // be possible to have both paged overflow and multicol on the same element, | 4248 // be possible to have both paged overflow and multicol on the same element, |
4249 // but then we need two flow threads. Anyway, this is nothing to worry about | 4249 // but then we need two flow threads. Anyway, this is nothing to worry about |
4250 // until we can actually nest multicol properly inside other fragmentation | 4250 // until we can actually nest multicol properly inside other fragmentation |
4251 // contexts. | 4251 // contexts. |
4252 FlowThreadType type = getFlowThreadType(styleRef()); | 4252 FlowThreadType type = getFlowThreadType(styleRef()); |
4253 | 4253 |
4254 if (multiColumnFlowThread()) { | 4254 if (multiColumnFlowThread()) { |
4255 ASSERT(oldStyle); | 4255 DCHECK(oldStyle); |
4256 if (type != getFlowThreadType(*oldStyle)) { | 4256 if (type != getFlowThreadType(*oldStyle)) { |
4257 // If we're no longer to be multicol/paged, destroy the flow thread. Also | 4257 // If we're no longer to be multicol/paged, destroy the flow thread. Also |
4258 // destroy it when switching between multicol and paged, since that | 4258 // destroy it when switching between multicol and paged, since that |
4259 // affects the column set structure (multicol containers may have | 4259 // affects the column set structure (multicol containers may have |
4260 // spanners, paged containers may not). | 4260 // spanners, paged containers may not). |
4261 multiColumnFlowThread()->evacuateAndDestroy(); | 4261 multiColumnFlowThread()->evacuateAndDestroy(); |
4262 ASSERT(!multiColumnFlowThread()); | 4262 DCHECK(!multiColumnFlowThread()); |
4263 m_paginationStateChanged = true; | 4263 m_paginationStateChanged = true; |
4264 } | 4264 } |
4265 } | 4265 } |
4266 | 4266 |
4267 if (type == NoFlowThread || multiColumnFlowThread()) | 4267 if (type == NoFlowThread || multiColumnFlowThread()) |
4268 return; | 4268 return; |
4269 | 4269 |
4270 // Ruby elements manage child insertion in a special way, and would mess up | 4270 // Ruby elements manage child insertion in a special way, and would mess up |
4271 // insertion of the flow thread. The flow thread needs to be a direct child of | 4271 // insertion of the flow thread. The flow thread needs to be a direct child of |
4272 // the multicol block (|this|). | 4272 // the multicol block (|this|). |
(...skipping 10 matching lines...) Expand all Loading... |
4283 // support multicol. | 4283 // support multicol. |
4284 if (isFileUploadControl() || isTextControl() || isListBox()) | 4284 if (isFileUploadControl() || isTextControl() || isListBox()) |
4285 return; | 4285 return; |
4286 | 4286 |
4287 LayoutMultiColumnFlowThread* flowThread = createMultiColumnFlowThread(type); | 4287 LayoutMultiColumnFlowThread* flowThread = createMultiColumnFlowThread(type); |
4288 addChild(flowThread); | 4288 addChild(flowThread); |
4289 m_paginationStateChanged = true; | 4289 m_paginationStateChanged = true; |
4290 | 4290 |
4291 // Check that addChild() put the flow thread as a direct child, and didn't do | 4291 // Check that addChild() put the flow thread as a direct child, and didn't do |
4292 // fancy things. | 4292 // fancy things. |
4293 ASSERT(flowThread->parent() == this); | 4293 DCHECK_EQ(flowThread->parent(), this); |
4294 | 4294 |
4295 flowThread->populate(); | 4295 flowThread->populate(); |
4296 LayoutBlockFlowRareData& rareData = ensureRareData(); | 4296 LayoutBlockFlowRareData& rareData = ensureRareData(); |
4297 ASSERT(!rareData.m_multiColumnFlowThread); | 4297 DCHECK(!rareData.m_multiColumnFlowThread); |
4298 rareData.m_multiColumnFlowThread = flowThread; | 4298 rareData.m_multiColumnFlowThread = flowThread; |
4299 } | 4299 } |
4300 | 4300 |
4301 LayoutBlockFlow::LayoutBlockFlowRareData& LayoutBlockFlow::ensureRareData() { | 4301 LayoutBlockFlow::LayoutBlockFlowRareData& LayoutBlockFlow::ensureRareData() { |
4302 if (m_rareData) | 4302 if (m_rareData) |
4303 return *m_rareData; | 4303 return *m_rareData; |
4304 | 4304 |
4305 m_rareData = WTF::makeUnique<LayoutBlockFlowRareData>(this); | 4305 m_rareData = WTF::makeUnique<LayoutBlockFlowRareData>(this); |
4306 return *m_rareData; | 4306 return *m_rareData; |
4307 } | 4307 } |
4308 | 4308 |
4309 void LayoutBlockFlow::positionDialog() { | 4309 void LayoutBlockFlow::positionDialog() { |
4310 HTMLDialogElement* dialog = toHTMLDialogElement(node()); | 4310 HTMLDialogElement* dialog = toHTMLDialogElement(node()); |
4311 if (dialog->getCenteringMode() == HTMLDialogElement::NotCentered) | 4311 if (dialog->getCenteringMode() == HTMLDialogElement::NotCentered) |
4312 return; | 4312 return; |
4313 | 4313 |
4314 bool canCenterDialog = (style()->position() == EPosition::kAbsolute || | 4314 bool canCenterDialog = (style()->position() == EPosition::kAbsolute || |
4315 style()->position() == EPosition::kFixed) && | 4315 style()->position() == EPosition::kFixed) && |
4316 style()->hasAutoTopAndBottom(); | 4316 style()->hasAutoTopAndBottom(); |
4317 | 4317 |
4318 if (dialog->getCenteringMode() == HTMLDialogElement::Centered) { | 4318 if (dialog->getCenteringMode() == HTMLDialogElement::Centered) { |
4319 if (canCenterDialog) | 4319 if (canCenterDialog) |
4320 setY(dialog->centeredPosition()); | 4320 setY(dialog->centeredPosition()); |
4321 return; | 4321 return; |
4322 } | 4322 } |
4323 | 4323 |
4324 ASSERT(dialog->getCenteringMode() == HTMLDialogElement::NeedsCentering); | 4324 DCHECK_EQ(dialog->getCenteringMode(), HTMLDialogElement::NeedsCentering); |
4325 if (!canCenterDialog) { | 4325 if (!canCenterDialog) { |
4326 dialog->setNotCentered(); | 4326 dialog->setNotCentered(); |
4327 return; | 4327 return; |
4328 } | 4328 } |
4329 | 4329 |
4330 FrameView* frameView = document().view(); | 4330 FrameView* frameView = document().view(); |
4331 LayoutUnit top = LayoutUnit((style()->position() == EPosition::kFixed) | 4331 LayoutUnit top = LayoutUnit((style()->position() == EPosition::kFixed) |
4332 ? 0 | 4332 ? 0 |
4333 : frameView->scrollOffsetInt().height()); | 4333 : frameView->scrollOffsetInt().height()); |
4334 int visibleHeight = frameView->visibleContentRect(IncludeScrollbars).height(); | 4334 int visibleHeight = frameView->visibleContentRect(IncludeScrollbars).height(); |
4335 if (size().height() < visibleHeight) | 4335 if (size().height() < visibleHeight) |
4336 top += (visibleHeight - size().height()) / 2; | 4336 top += (visibleHeight - size().height()) / 2; |
4337 setY(top); | 4337 setY(top); |
4338 dialog->setCentered(top); | 4338 dialog->setCentered(top); |
4339 } | 4339 } |
4340 | 4340 |
4341 void LayoutBlockFlow::simplifiedNormalFlowInlineLayout() { | 4341 void LayoutBlockFlow::simplifiedNormalFlowInlineLayout() { |
4342 ASSERT(childrenInline()); | 4342 DCHECK(childrenInline()); |
4343 ListHashSet<RootInlineBox*> lineBoxes; | 4343 ListHashSet<RootInlineBox*> lineBoxes; |
4344 for (InlineWalker walker(LineLayoutBlockFlow(this)); !walker.atEnd(); | 4344 for (InlineWalker walker(LineLayoutBlockFlow(this)); !walker.atEnd(); |
4345 walker.advance()) { | 4345 walker.advance()) { |
4346 LayoutObject* o = walker.current().layoutObject(); | 4346 LayoutObject* o = walker.current().layoutObject(); |
4347 if (!o->isOutOfFlowPositioned() && | 4347 if (!o->isOutOfFlowPositioned() && |
4348 (o->isAtomicInlineLevel() || o->isFloating())) { | 4348 (o->isAtomicInlineLevel() || o->isFloating())) { |
4349 o->layoutIfNeeded(); | 4349 o->layoutIfNeeded(); |
4350 if (toLayoutBox(o)->inlineBoxWrapper()) { | 4350 if (toLayoutBox(o)->inlineBoxWrapper()) { |
4351 RootInlineBox& box = toLayoutBox(o)->inlineBoxWrapper()->root(); | 4351 RootInlineBox& box = toLayoutBox(o)->inlineBoxWrapper()->root(); |
4352 lineBoxes.insert(&box); | 4352 lineBoxes.insert(&box); |
4353 } | 4353 } |
4354 } else if (o->isText() || | 4354 } else if (o->isText() || |
4355 (o->isLayoutInline() && !walker.atEndOfInline())) { | 4355 (o->isLayoutInline() && !walker.atEndOfInline())) { |
4356 o->clearNeedsLayout(); | 4356 o->clearNeedsLayout(); |
4357 } | 4357 } |
4358 } | 4358 } |
4359 | 4359 |
4360 // FIXME: Glyph overflow will get lost in this case, but not really a big | 4360 // FIXME: Glyph overflow will get lost in this case, but not really a big |
4361 // deal. | 4361 // deal. |
4362 GlyphOverflowAndFallbackFontsMap textBoxDataMap; | 4362 GlyphOverflowAndFallbackFontsMap textBoxDataMap; |
4363 for (ListHashSet<RootInlineBox*>::const_iterator it = lineBoxes.begin(); | 4363 for (ListHashSet<RootInlineBox*>::const_iterator it = lineBoxes.begin(); |
4364 it != lineBoxes.end(); ++it) { | 4364 it != lineBoxes.end(); ++it) { |
4365 RootInlineBox* box = *it; | 4365 RootInlineBox* box = *it; |
4366 box->computeOverflow(box->lineTop(), box->lineBottom(), textBoxDataMap); | 4366 box->computeOverflow(box->lineTop(), box->lineBottom(), textBoxDataMap); |
4367 } | 4367 } |
4368 } | 4368 } |
4369 | 4369 |
4370 bool LayoutBlockFlow::recalcInlineChildrenOverflowAfterStyleChange() { | 4370 bool LayoutBlockFlow::recalcInlineChildrenOverflowAfterStyleChange() { |
4371 ASSERT(childrenInline()); | 4371 DCHECK(childrenInline()); |
4372 bool childrenOverflowChanged = false; | 4372 bool childrenOverflowChanged = false; |
4373 ListHashSet<RootInlineBox*> lineBoxes; | 4373 ListHashSet<RootInlineBox*> lineBoxes; |
4374 for (InlineWalker walker(LineLayoutBlockFlow(this)); !walker.atEnd(); | 4374 for (InlineWalker walker(LineLayoutBlockFlow(this)); !walker.atEnd(); |
4375 walker.advance()) { | 4375 walker.advance()) { |
4376 LayoutObject* layoutObject = walker.current().layoutObject(); | 4376 LayoutObject* layoutObject = walker.current().layoutObject(); |
4377 if (recalcNormalFlowChildOverflowIfNeeded(layoutObject)) { | 4377 if (recalcNormalFlowChildOverflowIfNeeded(layoutObject)) { |
4378 childrenOverflowChanged = true; | 4378 childrenOverflowChanged = true; |
4379 if (InlineBox* inlineBoxWrapper = | 4379 if (InlineBox* inlineBoxWrapper = |
4380 toLayoutBlock(layoutObject)->inlineBoxWrapper()) | 4380 toLayoutBlock(layoutObject)->inlineBoxWrapper()) |
4381 lineBoxes.insert(&inlineBoxWrapper->root()); | 4381 lineBoxes.insert(&inlineBoxWrapper->root()); |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4502 point = point.transposedPoint(); | 4502 point = point.transposedPoint(); |
4503 if (closestBox->getLineLayoutItem().isAtomicInlineLevel()) | 4503 if (closestBox->getLineLayoutItem().isAtomicInlineLevel()) |
4504 return positionForPointRespectingEditingBoundaries( | 4504 return positionForPointRespectingEditingBoundaries( |
4505 LineLayoutBox(closestBox->getLineLayoutItem()), point); | 4505 LineLayoutBox(closestBox->getLineLayoutItem()), point); |
4506 return closestBox->getLineLayoutItem().positionForPoint(point); | 4506 return closestBox->getLineLayoutItem().positionForPoint(point); |
4507 } | 4507 } |
4508 | 4508 |
4509 if (lastRootBoxWithChildren) { | 4509 if (lastRootBoxWithChildren) { |
4510 // We hit this case for Mac behavior when the Y coordinate is below the last | 4510 // We hit this case for Mac behavior when the Y coordinate is below the last |
4511 // box. | 4511 // box. |
4512 ASSERT(moveCaretToBoundary); | 4512 DCHECK(moveCaretToBoundary); |
4513 InlineBox* logicallyLastBox; | 4513 InlineBox* logicallyLastBox; |
4514 if (lastRootBoxWithChildren->getLogicalEndBoxWithNode(logicallyLastBox)) | 4514 if (lastRootBoxWithChildren->getLogicalEndBoxWithNode(logicallyLastBox)) |
4515 return PositionWithAffinity(positionForBox(logicallyLastBox, false)); | 4515 return PositionWithAffinity(positionForBox(logicallyLastBox, false)); |
4516 } | 4516 } |
4517 | 4517 |
4518 // Can't reach this. We have a root line box, but it has no kids. | 4518 // Can't reach this. We have a root line box, but it has no kids. |
4519 // FIXME: This should NOTREACHED(), but clicking on placeholder text | 4519 // FIXME: This should NOTREACHED(), but clicking on placeholder text |
4520 // seems to hit this code path. | 4520 // seems to hit this code path. |
4521 return createPositionWithAffinity(0); | 4521 return createPositionWithAffinity(0); |
4522 } | 4522 } |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4599 return LayoutBlock::invalidatePaintIfNeeded(paintInvalidationState); | 4599 return LayoutBlock::invalidatePaintIfNeeded(paintInvalidationState); |
4600 } | 4600 } |
4601 | 4601 |
4602 void LayoutBlockFlow::invalidateDisplayItemClients( | 4602 void LayoutBlockFlow::invalidateDisplayItemClients( |
4603 PaintInvalidationReason invalidationReason) const { | 4603 PaintInvalidationReason invalidationReason) const { |
4604 BlockFlowPaintInvalidator(*this).invalidateDisplayItemClients( | 4604 BlockFlowPaintInvalidator(*this).invalidateDisplayItemClients( |
4605 invalidationReason); | 4605 invalidationReason); |
4606 } | 4606 } |
4607 | 4607 |
4608 } // namespace blink | 4608 } // namespace blink |
OLD | NEW |