Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(762)

Side by Side Diff: third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp

Issue 2391893004: Reformat comments in core/layout up until LayoutBox (Closed)
Patch Set: Rebase w/HEAD (again) Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 struct SameSizeAsMarginInfo { 68 struct SameSizeAsMarginInfo {
69 uint16_t bitfields; 69 uint16_t bitfields;
70 LayoutUnit margins[2]; 70 LayoutUnit margins[2];
71 }; 71 };
72 72
73 static_assert(sizeof(LayoutBlockFlow::MarginValues) == sizeof(LayoutUnit[4]), 73 static_assert(sizeof(LayoutBlockFlow::MarginValues) == sizeof(LayoutUnit[4]),
74 "MarginValues should stay small"); 74 "MarginValues should stay small");
75 75
76 // Caches all our current margin collapsing state. 76 // Caches all our current margin collapsing state.
77 class MarginInfo { 77 class MarginInfo {
78 // Collapsing flags for whether we can collapse our margins with our children' s margins. 78 // Collapsing flags for whether we can collapse our margins with our
79 // children's margins.
79 bool m_canCollapseWithChildren : 1; 80 bool m_canCollapseWithChildren : 1;
80 bool m_canCollapseMarginBeforeWithChildren : 1; 81 bool m_canCollapseMarginBeforeWithChildren : 1;
81 bool m_canCollapseMarginAfterWithChildren : 1; 82 bool m_canCollapseMarginAfterWithChildren : 1;
82 bool m_canCollapseMarginAfterWithLastChild : 1; 83 bool m_canCollapseMarginAfterWithLastChild : 1;
83 84
84 // Whether or not we are a quirky container, i.e., do we collapse away top and bottom 85 // Whether or not we are a quirky container, i.e., do we collapse away top and
85 // margins in our container. Table cells and the body are the common examples. We 86 // bottom margins in our container. Table cells and the body are the common
86 // also have a custom style property for Safari RSS to deal with TypePad blog articles. 87 // examples. We also have a custom style property for Safari RSS to deal with
88 // TypePad blog articles.
87 bool m_quirkContainer : 1; 89 bool m_quirkContainer : 1;
88 90
89 // This flag tracks whether we are still looking at child margins that can all collapse together at the beginning of a block. 91 // This flag tracks whether we are still looking at child margins that can all
90 // They may or may not collapse with the top margin of the block (|m_canCollap seTopWithChildren| tells us that), but they will 92 // collapse together at the beginning of a block. They may or may not collapse
91 // always be collapsing with one another. This variable can remain set to true through multiple iterations 93 // with the top margin of the block (|m_canCollapseTopWithChildren| tells us
92 // as long as we keep encountering self-collapsing blocks. 94 // that), but they will always be collapsing with one another. This variable
95 // can remain set to true through multiple iterations as long as we keep
96 // encountering self-collapsing blocks.
93 bool m_atBeforeSideOfBlock : 1; 97 bool m_atBeforeSideOfBlock : 1;
94 98
95 // This flag is set when we know we're examining bottom margins and we know we 're at the bottom of the block. 99 // This flag is set when we know we're examining bottom margins and we know
100 // we're at the bottom of the block.
96 bool m_atAfterSideOfBlock : 1; 101 bool m_atAfterSideOfBlock : 1;
97 102
98 // These variables are used to detect quirky margins that we need to collapse away (in table cells 103 // These variables are used to detect quirky margins that we need to collapse
104 // away (in table cells
99 // and in the body element). 105 // and in the body element).
100 bool m_hasMarginBeforeQuirk : 1; 106 bool m_hasMarginBeforeQuirk : 1;
101 bool m_hasMarginAfterQuirk : 1; 107 bool m_hasMarginAfterQuirk : 1;
102 bool m_determinedMarginBeforeQuirk : 1; 108 bool m_determinedMarginBeforeQuirk : 1;
103 109
104 bool m_discardMargin : 1; 110 bool m_discardMargin : 1;
105 bool m_lastChildIsSelfCollapsingBlockWithClearance : 1; 111 bool m_lastChildIsSelfCollapsingBlockWithClearance : 1;
106 112
107 // These flags track the previous maximal positive and negative margins. 113 // These flags track the previous maximal positive and negative margins.
108 LayoutUnit m_positiveMargin; 114 LayoutUnit m_positiveMargin;
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 bool discardMargin() const { return m_discardMargin; } 189 bool discardMargin() const { return m_discardMargin; }
184 LayoutUnit margin() const { return m_positiveMargin - m_negativeMargin; } 190 LayoutUnit margin() const { return m_positiveMargin - m_negativeMargin; }
185 void setLastChildIsSelfCollapsingBlockWithClearance(bool value) { 191 void setLastChildIsSelfCollapsingBlockWithClearance(bool value) {
186 m_lastChildIsSelfCollapsingBlockWithClearance = value; 192 m_lastChildIsSelfCollapsingBlockWithClearance = value;
187 } 193 }
188 bool lastChildIsSelfCollapsingBlockWithClearance() const { 194 bool lastChildIsSelfCollapsingBlockWithClearance() const {
189 return m_lastChildIsSelfCollapsingBlockWithClearance; 195 return m_lastChildIsSelfCollapsingBlockWithClearance;
190 } 196 }
191 }; 197 };
192 198
193 // Some features, such as floats, margin collapsing and fragmentation, require s ome knowledge about 199 // Some features, such as floats, margin collapsing and fragmentation, require
194 // things that happened when laying out previous block child siblings. Only look ing at the object 200 // some knowledge about things that happened when laying out previous block
195 // currently being laid out isn't always enough. 201 // child siblings. Only looking at the object currently being laid out isn't
202 // always enough.
196 class BlockChildrenLayoutInfo { 203 class BlockChildrenLayoutInfo {
197 public: 204 public:
198 BlockChildrenLayoutInfo(LayoutBlockFlow* blockFlow, 205 BlockChildrenLayoutInfo(LayoutBlockFlow* blockFlow,
199 LayoutUnit beforeEdge, 206 LayoutUnit beforeEdge,
200 LayoutUnit afterEdge) 207 LayoutUnit afterEdge)
201 : m_marginInfo(blockFlow, beforeEdge, afterEdge), 208 : m_marginInfo(blockFlow, beforeEdge, afterEdge),
202 m_previousBreakAfterValue(BreakAuto), 209 m_previousBreakAfterValue(BreakAuto),
203 m_isAtFirstInFlowChild(true) {} 210 m_isAtFirstInFlowChild(true) {}
204 211
205 // Store multicol layout state before first layout of a block child. The child may contain a 212 // Store multicol layout state before first layout of a block child. The child
206 // column spanner. If we need to re-lay out the block child because our initia l logical top 213 // may contain a column spanner. If we need to re-lay out the block child
207 // estimate was wrong, we need to roll back to how things were before laying o ut the child. 214 // because our initial logical top estimate was wrong, we need to roll back to
215 // how things were before laying out the child.
208 void storeMultiColumnLayoutState(const LayoutFlowThread& flowThread) { 216 void storeMultiColumnLayoutState(const LayoutFlowThread& flowThread) {
209 m_multiColumnLayoutState = flowThread.multiColumnLayoutState(); 217 m_multiColumnLayoutState = flowThread.multiColumnLayoutState();
210 } 218 }
211 void rollBackToInitialMultiColumnLayoutState(LayoutFlowThread& flowThread) { 219 void rollBackToInitialMultiColumnLayoutState(LayoutFlowThread& flowThread) {
212 flowThread.restoreMultiColumnLayoutState(m_multiColumnLayoutState); 220 flowThread.restoreMultiColumnLayoutState(m_multiColumnLayoutState);
213 } 221 }
214 222
215 const MarginInfo& marginInfo() const { return m_marginInfo; } 223 const MarginInfo& marginInfo() const { return m_marginInfo; }
216 MarginInfo& marginInfo() { return m_marginInfo; } 224 MarginInfo& marginInfo() { return m_marginInfo; }
217 LayoutUnit& previousFloatLogicalBottom() { 225 LayoutUnit& previousFloatLogicalBottom() {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 return true; 275 return true;
268 } 276 }
269 return relayoutChildren; 277 return relayoutChildren;
270 } 278 }
271 279
272 void LayoutBlockFlow::checkForPaginationLogicalHeightChange( 280 void LayoutBlockFlow::checkForPaginationLogicalHeightChange(
273 LayoutUnit& pageLogicalHeight, 281 LayoutUnit& pageLogicalHeight,
274 bool& pageLogicalHeightChanged, 282 bool& pageLogicalHeightChanged,
275 bool& hasSpecifiedPageLogicalHeight) { 283 bool& hasSpecifiedPageLogicalHeight) {
276 if (LayoutMultiColumnFlowThread* flowThread = multiColumnFlowThread()) { 284 if (LayoutMultiColumnFlowThread* flowThread = multiColumnFlowThread()) {
277 // Calculate the non-auto content box height, or set it to 0 if it's auto. W e need to know 285 // Calculate the non-auto content box height, or set it to 0 if it's auto.
278 // this before layout, so that we can figure out where to insert column brea ks. We also 286 // We need to know this before layout, so that we can figure out where to
279 // treat LayoutView (which may be paginated, which uses the multicol implmen tation) as 287 // insert column breaks. We also treat LayoutView (which may be paginated,
280 // having non-auto height, since its height is deduced from the viewport hei ght. We use 288 // which uses the multicol implmentation) as having non-auto height, since
281 // computeLogicalHeight() to calculate the content box height. That method w ill clamp 289 // its height is deduced from the viewport height.
282 // against max-height and min-height. Since we're now at the beginning of la yout, and we 290 // We use computeLogicalHeight() to calculate the content box height. That
283 // don't know the actual height of the content yet, only call that method wh en height is 291 // method will clamp against max-height and min-height. Since we're now at
284 // definite, or we might fool ourselves into believing that columns have a d efinite height 292 // the beginning of layout, and we don't know the actual height of the
285 // when they in fact don't. 293 // content yet, only call that method when height is definite, or we might
294 // fool ourselves into believing that columns have a definite height when
295 // they in fact don't.
286 LayoutUnit columnHeight; 296 LayoutUnit columnHeight;
287 if (hasDefiniteLogicalHeight() || isLayoutView()) { 297 if (hasDefiniteLogicalHeight() || isLayoutView()) {
288 LogicalExtentComputedValues computedValues; 298 LogicalExtentComputedValues computedValues;
289 computeLogicalHeight(LayoutUnit(), logicalTop(), computedValues); 299 computeLogicalHeight(LayoutUnit(), logicalTop(), computedValues);
290 columnHeight = computedValues.m_extent - borderAndPaddingLogicalHeight() - 300 columnHeight = computedValues.m_extent - borderAndPaddingLogicalHeight() -
291 scrollbarLogicalHeight(); 301 scrollbarLogicalHeight();
292 } 302 }
293 pageLogicalHeightChanged = 303 pageLogicalHeightChanged =
294 columnHeight != flowThread->columnHeightAvailable(); 304 columnHeight != flowThread->columnHeightAvailable();
295 flowThread->setColumnHeightAvailable(std::max(columnHeight, LayoutUnit())); 305 flowThread->setColumnHeightAvailable(std::max(columnHeight, LayoutUnit()));
296 } else if (isLayoutFlowThread()) { 306 } else if (isLayoutFlowThread()) {
297 LayoutFlowThread* flowThread = toLayoutFlowThread(this); 307 LayoutFlowThread* flowThread = toLayoutFlowThread(this);
298 308
299 // FIXME: This is a hack to always make sure we have a page logical height, if said height 309 // FIXME: This is a hack to always make sure we have a page logical height,
300 // is known. The page logical height thing in LayoutState is meaningless for flow 310 // if said height is known. The page logical height thing in LayoutState is
301 // thread-based pagination (page height isn't necessarily uniform throughout the flow 311 // meaningless for flow thread-based pagination (page height isn't
302 // thread), but as long as it is used universally as a means to determine wh ether page 312 // necessarily uniform throughout the flow thread), but as long as it is
303 // height is known or not, we need this. Page height is unknown when column balancing is 313 // used universally as a means to determine whether page height is known or
304 // enabled and flow thread height is still unknown (i.e. during the first la yout pass). When 314 // not, we need this. Page height is unknown when column balancing is
305 // it's unknown, we need to prevent the pagination code from assuming page b reaks everywhere 315 // enabled and flow thread height is still unknown (i.e. during the first
306 // and thereby eating every top margin. It should be trivial to clean up and get rid of this 316 // layout pass). When it's unknown, we need to prevent the pagination code
307 // hack once the old multicol implementation is gone. 317 // from assuming page breaks everywhere and thereby eating every top margin.
318 // It should be trivial to clean up and get rid of this hack once the old
319 // multicol implementation is gone.
308 pageLogicalHeight = 320 pageLogicalHeight =
309 flowThread->isPageLogicalHeightKnown() ? LayoutUnit(1) : LayoutUnit(); 321 flowThread->isPageLogicalHeightKnown() ? LayoutUnit(1) : LayoutUnit();
310 322
311 pageLogicalHeightChanged = flowThread->pageLogicalSizeChanged(); 323 pageLogicalHeightChanged = flowThread->pageLogicalSizeChanged();
312 } 324 }
313 } 325 }
314 326
315 void LayoutBlockFlow::setBreakAtLineToAvoidWidow(int lineToBreak) { 327 void LayoutBlockFlow::setBreakAtLineToAvoidWidow(int lineToBreak) {
316 ASSERT(lineToBreak >= 0); 328 ASSERT(lineToBreak >= 0);
317 ensureRareData(); 329 ensureRareData();
318 ASSERT(!m_rareData->m_didBreakAtLineToAvoidWidow); 330 ASSERT(!m_rareData->m_didBreakAtLineToAvoidWidow);
319 m_rareData->m_lineBreakToAvoidWidow = lineToBreak; 331 m_rareData->m_lineBreakToAvoidWidow = lineToBreak;
320 } 332 }
321 333
322 void LayoutBlockFlow::setDidBreakAtLineToAvoidWidow() { 334 void LayoutBlockFlow::setDidBreakAtLineToAvoidWidow() {
323 ASSERT(!shouldBreakAtLineToAvoidWidow()); 335 ASSERT(!shouldBreakAtLineToAvoidWidow());
324 336
325 // This function should be called only after a break was applied to avoid wido ws 337 // This function should be called only after a break was applied to avoid
326 // so assert |m_rareData| exists. 338 // widows so assert |m_rareData| exists.
327 ASSERT(m_rareData); 339 ASSERT(m_rareData);
328 340
329 m_rareData->m_didBreakAtLineToAvoidWidow = true; 341 m_rareData->m_didBreakAtLineToAvoidWidow = true;
330 } 342 }
331 343
332 void LayoutBlockFlow::clearDidBreakAtLineToAvoidWidow() { 344 void LayoutBlockFlow::clearDidBreakAtLineToAvoidWidow() {
333 if (!m_rareData) 345 if (!m_rareData)
334 return; 346 return;
335 347
336 m_rareData->m_didBreakAtLineToAvoidWidow = false; 348 m_rareData->m_didBreakAtLineToAvoidWidow = false;
337 } 349 }
338 350
339 void LayoutBlockFlow::clearShouldBreakAtLineToAvoidWidow() const { 351 void LayoutBlockFlow::clearShouldBreakAtLineToAvoidWidow() const {
340 ASSERT(shouldBreakAtLineToAvoidWidow()); 352 ASSERT(shouldBreakAtLineToAvoidWidow());
341 if (!m_rareData) 353 if (!m_rareData)
342 return; 354 return;
343 355
344 m_rareData->m_lineBreakToAvoidWidow = -1; 356 m_rareData->m_lineBreakToAvoidWidow = -1;
345 } 357 }
346 358
347 bool LayoutBlockFlow::isSelfCollapsingBlock() const { 359 bool LayoutBlockFlow::isSelfCollapsingBlock() const {
348 if (needsLayout()) { 360 if (needsLayout()) {
349 // Sometimes we don't lay out objects in DOM order (column spanners being on e such relevant 361 // Sometimes we don't lay out objects in DOM order (column spanners being
350 // type of object right here). As long as the object in question establishes a new 362 // one such relevant type of object right here). As long as the object in
351 // formatting context, that's nothing to worry about, though. 363 // question establishes a new formatting context, that's nothing to worry
364 // about, though.
352 ASSERT(createsNewFormattingContext()); 365 ASSERT(createsNewFormattingContext());
353 return false; 366 return false;
354 } 367 }
355 ASSERT(!m_isSelfCollapsing == !checkIfIsSelfCollapsingBlock()); 368 ASSERT(!m_isSelfCollapsing == !checkIfIsSelfCollapsingBlock());
356 return m_isSelfCollapsing; 369 return m_isSelfCollapsing;
357 } 370 }
358 371
359 bool LayoutBlockFlow::checkIfIsSelfCollapsingBlock() const { 372 bool LayoutBlockFlow::checkIfIsSelfCollapsingBlock() const {
360 // We are not self-collapsing if we 373 // We are not self-collapsing if we
361 // (a) have a non-zero height according to layout (an optimization to avoid wa sting time) 374 // (a) have a non-zero height according to layout (an optimization to avoid
375 // wasting time)
362 // (b) have border/padding, 376 // (b) have border/padding,
363 // (c) have a min-height 377 // (c) have a min-height
364 // (d) have specified that one of our margins can't collapse using a CSS exten sion 378 // (d) have specified that one of our margins can't collapse using a CSS
379 // extension
365 // (e) establish a new block formatting context. 380 // (e) establish a new block formatting context.
366 381
367 // The early exit must be done before we check for clean layout. 382 // The early exit must be done before we check for clean layout.
368 // We should be able to give a quick answer if the box is a relayout boundary. 383 // We should be able to give a quick answer if the box is a relayout boundary.
369 // Being a relayout boundary implies a block formatting context, and also 384 // Being a relayout boundary implies a block formatting context, and also
370 // our internal layout shouldn't affect our container in any way. 385 // our internal layout shouldn't affect our container in any way.
371 if (createsNewFormattingContext()) 386 if (createsNewFormattingContext())
372 return false; 387 return false;
373 388
374 // Placeholder elements are not laid out until the dimensions of their parent text control are known, so they 389 // Placeholder elements are not laid out until the dimensions of their parent
375 // don't get layout until their parent has had layout - this is unique in the layout tree and means 390 // text control are known, so they don't get layout until their parent has had
376 // when we call isSelfCollapsingBlock on them we find that they still need lay out. 391 // layout - this is unique in the layout tree and means when we call
392 // isSelfCollapsingBlock on them we find that they still need layout.
377 ASSERT(!needsLayout() || 393 ASSERT(!needsLayout() ||
378 (node() && node()->isElementNode() && 394 (node() && node()->isElementNode() &&
379 toElement(node())->shadowPseudoId() == "-webkit-input-placeholder")); 395 toElement(node())->shadowPseudoId() == "-webkit-input-placeholder"));
380 396
381 if (logicalHeight() > LayoutUnit() || borderAndPaddingLogicalHeight() || 397 if (logicalHeight() > LayoutUnit() || borderAndPaddingLogicalHeight() ||
382 style()->logicalMinHeight().isPositive() || 398 style()->logicalMinHeight().isPositive() ||
383 style()->marginBeforeCollapse() == MarginCollapseSeparate || 399 style()->marginBeforeCollapse() == MarginCollapseSeparate ||
384 style()->marginAfterCollapse() == MarginCollapseSeparate) 400 style()->marginAfterCollapse() == MarginCollapseSeparate)
385 return false; 401 return false;
386 402
387 Length logicalHeightLength = style()->logicalHeight(); 403 Length logicalHeightLength = style()->logicalHeight();
388 bool hasAutoHeight = logicalHeightLength.isAuto(); 404 bool hasAutoHeight = logicalHeightLength.isAuto();
389 if (logicalHeightLength.isPercentOrCalc() && !document().inQuirksMode()) { 405 if (logicalHeightLength.isPercentOrCalc() && !document().inQuirksMode()) {
390 hasAutoHeight = true; 406 hasAutoHeight = true;
391 for (LayoutBlock* cb = containingBlock(); !cb->isLayoutView(); 407 for (LayoutBlock* cb = containingBlock(); !cb->isLayoutView();
392 cb = cb->containingBlock()) { 408 cb = cb->containingBlock()) {
393 if (cb->style()->logicalHeight().isFixed() || cb->isTableCell()) 409 if (cb->style()->logicalHeight().isFixed() || cb->isTableCell())
394 hasAutoHeight = false; 410 hasAutoHeight = false;
395 } 411 }
396 } 412 }
397 413
398 // If the height is 0 or auto, then whether or not we are a self-collapsing bl ock depends 414 // If the height is 0 or auto, then whether or not we are a self-collapsing
399 // on whether we have content that is all self-collapsing or not. 415 // block depends on whether we have content that is all self-collapsing.
400 // TODO(alancutter): Make this work correctly for calc lengths. 416 // TODO(alancutter): Make this work correctly for calc lengths.
401 if (hasAutoHeight || ((logicalHeightLength.isFixed() || 417 if (hasAutoHeight || ((logicalHeightLength.isFixed() ||
402 logicalHeightLength.isPercentOrCalc()) && 418 logicalHeightLength.isPercentOrCalc()) &&
403 logicalHeightLength.isZero())) { 419 logicalHeightLength.isZero())) {
404 // If the block has inline children, see if we generated any line boxes. If we have any 420 // If the block has inline children, see if we generated any line boxes.
405 // line boxes, then we can't be self-collapsing, since we have content. 421 // If we have any line boxes, then we can't be self-collapsing, since we
422 // have content.
406 if (childrenInline()) 423 if (childrenInline())
407 return !firstLineBox(); 424 return !firstLineBox();
408 425
409 // Whether or not we collapse is dependent on whether all our normal flow ch ildren 426 // Whether or not we collapse is dependent on whether all our normal flow
427 // children
410 // are also self-collapsing. 428 // are also self-collapsing.
411 for (LayoutBox* child = firstChildBox(); child; 429 for (LayoutBox* child = firstChildBox(); child;
412 child = child->nextSiblingBox()) { 430 child = child->nextSiblingBox()) {
413 if (child->isFloatingOrOutOfFlowPositioned()) 431 if (child->isFloatingOrOutOfFlowPositioned())
414 continue; 432 continue;
415 if (!child->isSelfCollapsingBlock()) 433 if (!child->isSelfCollapsingBlock())
416 return false; 434 return false;
417 } 435 }
418 return true; 436 return true;
419 } 437 }
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 bool hasSpecifiedPageLogicalHeight = false; 485 bool hasSpecifiedPageLogicalHeight = false;
468 checkForPaginationLogicalHeightChange(pageLogicalHeight, 486 checkForPaginationLogicalHeightChange(pageLogicalHeight,
469 pageLogicalHeightChanged, 487 pageLogicalHeightChanged,
470 hasSpecifiedPageLogicalHeight); 488 hasSpecifiedPageLogicalHeight);
471 if (pageLogicalHeightChanged) 489 if (pageLogicalHeightChanged)
472 relayoutChildren = true; 490 relayoutChildren = true;
473 491
474 LayoutState state(*this, locationOffset(), pageLogicalHeight, 492 LayoutState state(*this, locationOffset(), pageLogicalHeight,
475 pageLogicalHeightChanged, logicalWidthChanged); 493 pageLogicalHeightChanged, logicalWidthChanged);
476 494
477 // We use four values, maxTopPos, maxTopNeg, maxBottomPos, and maxBottomNeg, t o track 495 // We use four values, maxTopPos, maxTopNeg, maxBottomPos, and maxBottomNeg,
478 // our current maximal positive and negative margins. These values are used wh en we 496 // to track our current maximal positive and negative margins. These values
479 // are collapsed with adjacent blocks, so for example, if you have block A and B 497 // are used when we are collapsed with adjacent blocks, so for example, if you
480 // collapsing together, then you'd take the maximal positive margin from both A and B 498 // have block A and B collapsing together, then you'd take the maximal
481 // and subtract it from the maximal negative margin from both A and B to get t he 499 // positive margin from both A and B and subtract it from the maximal negative
482 // true collapsed margin. This algorithm is recursive, so when we finish layou t() 500 // margin from both A and B to get the true collapsed margin. This algorithm
483 // our block knows its current maximal positive/negative values. 501 // is recursive, so when we finish layout() our block knows its current
502 // maximal positive/negative values.
484 // 503 //
485 // Start out by setting our margin values to our current margins. Table cells have 504 // Start out by setting our margin values to our current margins. Table cells
486 // no margins, so we don't fill in the values for table cells. 505 // have no margins, so we don't fill in the values for table cells.
487 if (!isTableCell()) { 506 if (!isTableCell()) {
488 initMaxMarginValues(); 507 initMaxMarginValues();
489 setHasMarginBeforeQuirk(style()->hasMarginBeforeQuirk()); 508 setHasMarginBeforeQuirk(style()->hasMarginBeforeQuirk());
490 setHasMarginAfterQuirk(style()->hasMarginAfterQuirk()); 509 setHasMarginAfterQuirk(style()->hasMarginAfterQuirk());
491 } 510 }
492 511
493 if (state.isPaginated()) { 512 if (state.isPaginated()) {
494 setPaginationStrutPropagatedFromChild(LayoutUnit()); 513 setPaginationStrutPropagatedFromChild(LayoutUnit());
495 514
496 // Start with any applicable computed break-after and break-before values fo r this 515 // Start with any applicable computed break-after and break-before values
497 // object. During child layout, breakBefore will be joined with the breakBef ore value of 516 // for this object. During child layout, breakBefore will be joined with the
498 // the first in-flow child, and breakAfter will be joined with the breakAfte r value of the 517 // breakBefore value of the first in-flow child, and breakAfter will be
499 // last in-flow child. This is done in order to honor the requirement that a class A break 518 // joined with the breakAfter value of the last in-flow child. This is done
500 // point [1] may only exists *between* in-flow siblings (i.e. not before the first child 519 // in order to honor the requirement that a class A break point [1] may only
501 // and not after the last child). 520 // exists *between* in-flow siblings (i.e. not before the first child and
521 // not after the last child).
502 // 522 //
503 // [1] https://drafts.csswg.org/css-break/#possible-breaks 523 // [1] https://drafts.csswg.org/css-break/#possible-breaks
504 setBreakBefore(LayoutBlock::breakBefore()); 524 setBreakBefore(LayoutBlock::breakBefore());
505 setBreakAfter(LayoutBlock::breakAfter()); 525 setBreakAfter(LayoutBlock::breakAfter());
506 } 526 }
507 527
508 LayoutUnit beforeEdge = borderBefore() + paddingBefore(); 528 LayoutUnit beforeEdge = borderBefore() + paddingBefore();
509 LayoutUnit afterEdge = 529 LayoutUnit afterEdge =
510 borderAfter() + paddingAfter() + scrollbarLogicalHeight(); 530 borderAfter() + paddingAfter() + scrollbarLogicalHeight();
511 LayoutUnit previousHeight = logicalHeight(); 531 LayoutUnit previousHeight = logicalHeight();
(...skipping 10 matching lines...) Expand all
522 // all inline children are removed from this block. 542 // all inline children are removed from this block.
523 setContainsInlineWithOutlineAndContinuation(false); 543 setContainsInlineWithOutlineAndContinuation(false);
524 if (childrenInline()) 544 if (childrenInline())
525 layoutInlineChildren(relayoutChildren, afterEdge); 545 layoutInlineChildren(relayoutChildren, afterEdge);
526 else 546 else
527 layoutBlockChildren(relayoutChildren, layoutScope, beforeEdge, afterEdge); 547 layoutBlockChildren(relayoutChildren, layoutScope, beforeEdge, afterEdge);
528 548
529 bool preferredLogicalWidthsBecameDirty = 549 bool preferredLogicalWidthsBecameDirty =
530 !preferredLogicalWidthsWereDirty && preferredLogicalWidthsDirty(); 550 !preferredLogicalWidthsWereDirty && preferredLogicalWidthsDirty();
531 if (preferredLogicalWidthsBecameDirty) { 551 if (preferredLogicalWidthsBecameDirty) {
532 // The only thing that should dirty preferred widths at this point is the ad dition of 552 // The only thing that should dirty preferred widths at this point is the
533 // overflow:auto scrollbars in a descendant. To avoid a potential infinite loop, 553 // addition of overflow:auto scrollbars in a descendant. To avoid a
534 // run layout again with auto scrollbars frozen in their current state. 554 // potential infinite loop, run layout again with auto scrollbars frozen in
555 // their current state.
535 PaintLayerScrollableArea::FreezeScrollbarsScope freezeScrollbars; 556 PaintLayerScrollableArea::FreezeScrollbarsScope freezeScrollbars;
536 return layoutBlockFlow(relayoutChildren, pageLogicalHeight, layoutScope); 557 return layoutBlockFlow(relayoutChildren, pageLogicalHeight, layoutScope);
537 } 558 }
538 559
539 // Expand our intrinsic height to encompass floats. 560 // Expand our intrinsic height to encompass floats.
540 if (lowestFloatLogicalBottom() > (logicalHeight() - afterEdge) && 561 if (lowestFloatLogicalBottom() > (logicalHeight() - afterEdge) &&
541 createsNewFormattingContext()) 562 createsNewFormattingContext())
542 setLogicalHeight(lowestFloatLogicalBottom() + afterEdge); 563 setLogicalHeight(lowestFloatLogicalBottom() + afterEdge);
543 564
544 if (LayoutMultiColumnFlowThread* flowThread = multiColumnFlowThread()) { 565 if (LayoutMultiColumnFlowThread* flowThread = multiColumnFlowThread()) {
(...skipping 13 matching lines...) Expand all
558 LayoutUnit oldClientAfterEdge = clientLogicalBottom(); 579 LayoutUnit oldClientAfterEdge = clientLogicalBottom();
559 580
560 updateLogicalHeight(); 581 updateLogicalHeight();
561 LayoutUnit newHeight = logicalHeight(); 582 LayoutUnit newHeight = logicalHeight();
562 if (!childrenInline()) { 583 if (!childrenInline()) {
563 LayoutBlockFlow* lowestBlock = nullptr; 584 LayoutBlockFlow* lowestBlock = nullptr;
564 bool addedOverhangingFloats = false; 585 bool addedOverhangingFloats = false;
565 // One of our children's floats may have become an overhanging float for us. 586 // One of our children's floats may have become an overhanging float for us.
566 for (LayoutObject* child = lastChild(); child; 587 for (LayoutObject* child = lastChild(); child;
567 child = child->previousSibling()) { 588 child = child->previousSibling()) {
568 // TODO(robhogan): We should exclude blocks that create formatting context s, not just out of flow or floating blocks. 589 // TODO(robhogan): We should exclude blocks that create formatting
590 // contexts, not just out of flow or floating blocks.
569 if (child->isLayoutBlockFlow() && 591 if (child->isLayoutBlockFlow() &&
570 !child->isFloatingOrOutOfFlowPositioned()) { 592 !child->isFloatingOrOutOfFlowPositioned()) {
571 LayoutBlockFlow* block = toLayoutBlockFlow(child); 593 LayoutBlockFlow* block = toLayoutBlockFlow(child);
572 if (!block->containsFloats()) 594 if (!block->containsFloats())
573 continue; 595 continue;
574 lowestBlock = block; 596 lowestBlock = block;
575 if (oldHeight <= newHeight || 597 if (oldHeight <= newHeight ||
576 block->lowestFloatLogicalBottom() + block->logicalTop() <= 598 block->lowestFloatLogicalBottom() + block->logicalTop() <=
577 newHeight) 599 newHeight)
578 break; 600 break;
579 addOverhangingFloats(block, false); 601 addOverhangingFloats(block, false);
580 addedOverhangingFloats = true; 602 addedOverhangingFloats = true;
581 } 603 }
582 } 604 }
583 // If we have no overhanging floats we still pass a record of the lowest non -overhanging float up the tree so we can enclose it if 605 // If we have no overhanging floats we still pass a record of the lowest
584 // we are a formatting context and allow siblings to avoid it if they have n egative margin and find themselves in its vicinity. 606 // non-overhanging float up the tree so we can enclose it if we are a
607 // formatting context and allow siblings to avoid it if they have negative
608 // margin and find themselves in its vicinity.
585 if (!addedOverhangingFloats) 609 if (!addedOverhangingFloats)
586 addLowestFloatFromChildren(lowestBlock); 610 addLowestFloatFromChildren(lowestBlock);
587 } 611 }
588 612
589 bool heightChanged = (previousHeight != newHeight); 613 bool heightChanged = (previousHeight != newHeight);
590 if (heightChanged) 614 if (heightChanged)
591 relayoutChildren = true; 615 relayoutChildren = true;
592 616
593 layoutPositionedObjects(relayoutChildren || isDocumentElement(), 617 layoutPositionedObjects(relayoutChildren || isDocumentElement(),
594 oldLeft != logicalLeft() 618 oldLeft != logicalLeft()
595 ? ForcedLayoutAfterContainingBlockMoved 619 ? ForcedLayoutAfterContainingBlockMoved
596 : DefaultLayout); 620 : DefaultLayout);
597 621
598 // Add overflow from children (unless we're multi-column, since in that case a ll our child overflow is clipped anyway). 622 // Add overflow from children (unless we're multi-column, since in that case
623 // all our child overflow is clipped anyway).
599 computeOverflow(oldClientAfterEdge); 624 computeOverflow(oldClientAfterEdge);
600 625
601 m_descendantsWithFloatsMarkedForLayout = false; 626 m_descendantsWithFloatsMarkedForLayout = false;
602 return true; 627 return true;
603 } 628 }
604 629
605 void LayoutBlockFlow::addLowestFloatFromChildren(LayoutBlockFlow* block) { 630 void LayoutBlockFlow::addLowestFloatFromChildren(LayoutBlockFlow* block) {
606 // TODO(robhogan): Make createsNewFormattingContext an ASSERT. 631 // TODO(robhogan): Make createsNewFormattingContext an ASSERT.
607 if (!block || !block->containsFloats() || 632 if (!block || !block->containsFloats() ||
608 block->createsNewFormattingContext()) 633 block->createsNewFormattingContext())
(...skipping 25 matching lines...) Expand all
634 borderAndPaddingLogicalWidth() + availableLogicalWidth(); 659 borderAndPaddingLogicalWidth() + availableLogicalWidth();
635 660
636 LayoutUnit childMarginStart = marginStartForChild(child); 661 LayoutUnit childMarginStart = marginStartForChild(child);
637 LayoutUnit newPosition = startPosition + childMarginStart; 662 LayoutUnit newPosition = startPosition + childMarginStart;
638 663
639 if (child.avoidsFloats() && containsFloats()) { 664 if (child.avoidsFloats() && containsFloats()) {
640 LayoutUnit positionToAvoidFloats = 665 LayoutUnit positionToAvoidFloats =
641 startOffsetForLine(logicalTopForChild(child), DoNotIndentText, 666 startOffsetForLine(logicalTopForChild(child), DoNotIndentText,
642 logicalHeightForChild(child)); 667 logicalHeightForChild(child));
643 668
644 // If the child has an offset from the content edge to avoid floats then use that, otherwise let any negative 669 // If the child has an offset from the content edge to avoid floats then use
645 // margin pull it back over the content edge or any positive margin push it out. 670 // that, otherwise let any negative margin pull it back over the content
646 // If the child is being centred then the margin calculated to do that has f actored in any offset required to 671 // edge or any positive margin push it out.
647 // avoid floats, so use it if necessary. 672 // If the child is being centred then the margin calculated to do that has
673 // factored in any offset required to avoid floats, so use it if necessary.
648 if (style()->textAlign() == WEBKIT_CENTER || 674 if (style()->textAlign() == WEBKIT_CENTER ||
649 child.style()->marginStartUsing(style()).isAuto()) 675 child.style()->marginStartUsing(style()).isAuto())
650 newPosition = 676 newPosition =
651 std::max(newPosition, positionToAvoidFloats + childMarginStart); 677 std::max(newPosition, positionToAvoidFloats + childMarginStart);
652 else if (positionToAvoidFloats > initialStartPosition) 678 else if (positionToAvoidFloats > initialStartPosition)
653 newPosition = std::max(newPosition, positionToAvoidFloats); 679 newPosition = std::max(newPosition, positionToAvoidFloats);
654 } 680 }
655 681
656 setLogicalLeftForChild(child, style()->isLeftToRightDirection() 682 setLogicalLeftForChild(child, style()->isLeftToRightDirection()
657 ? newPosition 683 ? newPosition
(...skipping 16 matching lines...) Expand all
674 child.setY(logicalTop); 700 child.setY(logicalTop);
675 } else { 701 } else {
676 child.setX(logicalTop); 702 child.setX(logicalTop);
677 } 703 }
678 } 704 }
679 705
680 void LayoutBlockFlow::markDescendantsWithFloatsForLayoutIfNeeded( 706 void LayoutBlockFlow::markDescendantsWithFloatsForLayoutIfNeeded(
681 LayoutBlockFlow& child, 707 LayoutBlockFlow& child,
682 LayoutUnit newLogicalTop, 708 LayoutUnit newLogicalTop,
683 LayoutUnit previousFloatLogicalBottom) { 709 LayoutUnit previousFloatLogicalBottom) {
684 // TODO(mstensho): rework the code to return early when there is no need for m arking, instead 710 // TODO(mstensho): rework the code to return early when there is no need for
685 // of this |markDescendantsWithFloats| flag. 711 // marking, instead of this |markDescendantsWithFloats| flag.
686 bool markDescendantsWithFloats = false; 712 bool markDescendantsWithFloats = false;
687 if (newLogicalTop != child.logicalTop() && !child.avoidsFloats() && 713 if (newLogicalTop != child.logicalTop() && !child.avoidsFloats() &&
688 child.containsFloats()) { 714 child.containsFloats()) {
689 markDescendantsWithFloats = true; 715 markDescendantsWithFloats = true;
690 } else if (UNLIKELY(newLogicalTop.mightBeSaturated())) { 716 } else if (UNLIKELY(newLogicalTop.mightBeSaturated())) {
691 // The logical top might be saturated for very large elements. Comparing wit h the old 717 // The logical top might be saturated for very large elements. Comparing
692 // logical top might then yield a false negative, as adding and removing mar gins, borders 718 // with the old logical top might then yield a false negative, as adding and
693 // etc. from a saturated number might yield incorrect results. If this is th e case, always 719 // removing margins, borders etc. from a saturated number might yield
694 // mark for layout. 720 // incorrect results. If this is the case, always mark for layout.
695 markDescendantsWithFloats = true; 721 markDescendantsWithFloats = true;
696 } else if (!child.avoidsFloats() || child.shrinkToAvoidFloats()) { 722 } else if (!child.avoidsFloats() || child.shrinkToAvoidFloats()) {
697 // If an element might be affected by the presence of floats, then always ma rk it for 723 // If an element might be affected by the presence of floats, then always
698 // layout. 724 // mark it for layout.
699 if (std::max(previousFloatLogicalBottom, lowestFloatLogicalBottom()) > 725 if (std::max(previousFloatLogicalBottom, lowestFloatLogicalBottom()) >
700 newLogicalTop) 726 newLogicalTop)
701 markDescendantsWithFloats = true; 727 markDescendantsWithFloats = true;
702 } 728 }
703 729
704 if (markDescendantsWithFloats) 730 if (markDescendantsWithFloats)
705 child.markAllDescendantsWithFloatsForLayout(); 731 child.markAllDescendantsWithFloatsForLayout();
706 } 732 }
707 733
708 bool LayoutBlockFlow::positionAndLayoutOnceIfNeeded( 734 bool LayoutBlockFlow::positionAndLayoutOnceIfNeeded(
709 LayoutBox& child, 735 LayoutBox& child,
710 LayoutUnit newLogicalTop, 736 LayoutUnit newLogicalTop,
711 BlockChildrenLayoutInfo& layoutInfo) { 737 BlockChildrenLayoutInfo& layoutInfo) {
712 if (LayoutFlowThread* flowThread = flowThreadContainingBlock()) 738 if (LayoutFlowThread* flowThread = flowThreadContainingBlock())
713 layoutInfo.rollBackToInitialMultiColumnLayoutState(*flowThread); 739 layoutInfo.rollBackToInitialMultiColumnLayoutState(*flowThread);
714 740
715 if (child.isLayoutBlockFlow()) { 741 if (child.isLayoutBlockFlow()) {
716 LayoutUnit& previousFloatLogicalBottom = 742 LayoutUnit& previousFloatLogicalBottom =
717 layoutInfo.previousFloatLogicalBottom(); 743 layoutInfo.previousFloatLogicalBottom();
718 LayoutBlockFlow& childBlockFlow = toLayoutBlockFlow(child); 744 LayoutBlockFlow& childBlockFlow = toLayoutBlockFlow(child);
719 if (childBlockFlow.containsFloats() || containsFloats()) 745 if (childBlockFlow.containsFloats() || containsFloats())
720 markDescendantsWithFloatsForLayoutIfNeeded(childBlockFlow, newLogicalTop, 746 markDescendantsWithFloatsForLayoutIfNeeded(childBlockFlow, newLogicalTop,
721 previousFloatLogicalBottom); 747 previousFloatLogicalBottom);
722 748
723 // TODO(mstensho): A writing mode root is one thing, but we should be able t o skip anything 749 // TODO(mstensho): A writing mode root is one thing, but we should be able
724 // that establishes a new block formatting context here. Their floats don't affect us. 750 // to skip anything that establishes a new block formatting context here.
751 // Their floats don't affect us.
725 if (!childBlockFlow.isWritingModeRoot()) 752 if (!childBlockFlow.isWritingModeRoot())
726 previousFloatLogicalBottom = 753 previousFloatLogicalBottom =
727 std::max(previousFloatLogicalBottom, 754 std::max(previousFloatLogicalBottom,
728 childBlockFlow.logicalTop() + 755 childBlockFlow.logicalTop() +
729 childBlockFlow.lowestFloatLogicalBottom()); 756 childBlockFlow.lowestFloatLogicalBottom());
730 } 757 }
731 758
732 LayoutUnit oldLogicalTop = logicalTopForChild(child); 759 LayoutUnit oldLogicalTop = logicalTopForChild(child);
733 setLogicalTopForChild(child, newLogicalTop); 760 setLogicalTopForChild(child, newLogicalTop);
734 761
735 SubtreeLayoutScope layoutScope(child); 762 SubtreeLayoutScope layoutScope(child);
736 if (!child.needsLayout()) { 763 if (!child.needsLayout()) {
737 if (newLogicalTop != oldLogicalTop && child.shrinkToAvoidFloats()) { 764 if (newLogicalTop != oldLogicalTop && child.shrinkToAvoidFloats()) {
738 // The child's width is affected by adjacent floats. When the child shifts to clear an 765 // The child's width is affected by adjacent floats. When the child shifts
739 // item, its width can change (because it has more available width). 766 // to clear an item, its width can change (because it has more available
767 // width).
740 layoutScope.setChildNeedsLayout(&child); 768 layoutScope.setChildNeedsLayout(&child);
741 } else { 769 } else {
742 markChildForPaginationRelayoutIfNeeded(child, layoutScope); 770 markChildForPaginationRelayoutIfNeeded(child, layoutScope);
743 } 771 }
744 } 772 }
745 773
746 if (!child.needsLayout()) 774 if (!child.needsLayout())
747 return false; 775 return false;
748 child.layout(); 776 child.layout();
749 return true; 777 return true;
750 } 778 }
751 779
752 void LayoutBlockFlow::insertForcedBreakBeforeChildIfNeeded( 780 void LayoutBlockFlow::insertForcedBreakBeforeChildIfNeeded(
753 LayoutBox& child, 781 LayoutBox& child,
754 BlockChildrenLayoutInfo& layoutInfo) { 782 BlockChildrenLayoutInfo& layoutInfo) {
755 if (layoutInfo.isAtFirstInFlowChild()) { 783 if (layoutInfo.isAtFirstInFlowChild()) {
756 // There's no class A break point before the first child (only *between* sib lings), so 784 // There's no class A break point before the first child (only *between*
757 // steal its break value and join it with what we already have here. 785 // siblings), so steal its break value and join it with what we already have
786 // here.
758 setBreakBefore( 787 setBreakBefore(
759 joinFragmentainerBreakValues(breakBefore(), child.breakBefore())); 788 joinFragmentainerBreakValues(breakBefore(), child.breakBefore()));
760 return; 789 return;
761 } 790 }
762 791
763 // Figure out if a forced break should be inserted in front of the child. If w e insert a forced 792 // Figure out if a forced break should be inserted in front of the child. If
764 // break, the margins on this child may not collapse with those preceding the break. 793 // we insert a forced break, the margins on this child may not collapse with
794 // those preceding the break.
765 EBreak classABreakPointValue = 795 EBreak classABreakPointValue =
766 child.classABreakPointValue(layoutInfo.previousBreakAfterValue()); 796 child.classABreakPointValue(layoutInfo.previousBreakAfterValue());
767 if (isForcedFragmentainerBreakValue(classABreakPointValue)) { 797 if (isForcedFragmentainerBreakValue(classABreakPointValue)) {
768 layoutInfo.marginInfo().clearMargin(); 798 layoutInfo.marginInfo().clearMargin();
769 LayoutUnit oldLogicalTop = logicalHeight(); 799 LayoutUnit oldLogicalTop = logicalHeight();
770 LayoutUnit newLogicalTop = 800 LayoutUnit newLogicalTop =
771 applyForcedBreak(oldLogicalTop, classABreakPointValue); 801 applyForcedBreak(oldLogicalTop, classABreakPointValue);
772 setLogicalHeight(newLogicalTop); 802 setLogicalHeight(newLogicalTop);
773 LayoutUnit paginationStrut = newLogicalTop - oldLogicalTop; 803 LayoutUnit paginationStrut = newLogicalTop - oldLogicalTop;
774 child.setPaginationStrut(paginationStrut); 804 child.setPaginationStrut(paginationStrut);
775 } 805 }
776 } 806 }
777 807
778 void LayoutBlockFlow::layoutBlockChild(LayoutBox& child, 808 void LayoutBlockFlow::layoutBlockChild(LayoutBox& child,
779 BlockChildrenLayoutInfo& layoutInfo) { 809 BlockChildrenLayoutInfo& layoutInfo) {
780 MarginInfo& marginInfo = layoutInfo.marginInfo(); 810 MarginInfo& marginInfo = layoutInfo.marginInfo();
781 LayoutBlockFlow* childLayoutBlockFlow = 811 LayoutBlockFlow* childLayoutBlockFlow =
782 child.isLayoutBlockFlow() ? toLayoutBlockFlow(&child) : nullptr; 812 child.isLayoutBlockFlow() ? toLayoutBlockFlow(&child) : nullptr;
783 LayoutUnit oldPosMarginBefore = maxPositiveMarginBefore(); 813 LayoutUnit oldPosMarginBefore = maxPositiveMarginBefore();
784 LayoutUnit oldNegMarginBefore = maxNegativeMarginBefore(); 814 LayoutUnit oldNegMarginBefore = maxNegativeMarginBefore();
785 815
786 // The child is a normal flow object. Compute the margins we will use for coll apsing now. 816 // The child is a normal flow object. Compute the margins we will use for
817 // collapsing now.
787 child.computeAndSetBlockDirectionMargins(this); 818 child.computeAndSetBlockDirectionMargins(this);
788 819
789 // Try to guess our correct logical top position. In most cases this guess wil l 820 // Try to guess our correct logical top position. In most cases this guess
790 // be correct. Only if we're wrong (when we compute the real logical top posit ion) 821 // will be correct. Only if we're wrong (when we compute the real logical top
791 // will we have to potentially relayout. 822 // position) will we have to potentially relayout.
792 LayoutUnit estimateWithoutPagination; 823 LayoutUnit estimateWithoutPagination;
793 LayoutUnit logicalTopEstimate = 824 LayoutUnit logicalTopEstimate =
794 estimateLogicalTopPosition(child, layoutInfo, estimateWithoutPagination); 825 estimateLogicalTopPosition(child, layoutInfo, estimateWithoutPagination);
795 826
796 // Cache our old rect so that we can dirty the proper paint invalidation rects if the child moves. 827 // Cache our old rect so that we can dirty the proper paint invalidation rects
828 // if the child moves.
797 LayoutRect oldRect = child.frameRect(); 829 LayoutRect oldRect = child.frameRect();
798 830
799 if (LayoutFlowThread* flowThread = flowThreadContainingBlock()) 831 if (LayoutFlowThread* flowThread = flowThreadContainingBlock())
800 layoutInfo.storeMultiColumnLayoutState(*flowThread); 832 layoutInfo.storeMultiColumnLayoutState(*flowThread);
801 833
802 // Use the estimated block position and lay out the child if needed. After chi ld layout, when 834 // Use the estimated block position and lay out the child if needed. After
803 // we have enough information to perform proper margin collapsing, float clear ing and 835 // child layout, when we have enough information to perform proper margin
804 // pagination, we may have to reposition and lay out again if the estimate was wrong. 836 // collapsing, float clearing and pagination, we may have to reposition and
837 // lay out again if the estimate was wrong.
805 bool childNeededLayout = 838 bool childNeededLayout =
806 positionAndLayoutOnceIfNeeded(child, logicalTopEstimate, layoutInfo); 839 positionAndLayoutOnceIfNeeded(child, logicalTopEstimate, layoutInfo);
807 840
808 // Cache if we are at the top of the block right now. 841 // Cache if we are at the top of the block right now.
809 bool atBeforeSideOfBlock = marginInfo.atBeforeSideOfBlock(); 842 bool atBeforeSideOfBlock = marginInfo.atBeforeSideOfBlock();
810 bool childIsSelfCollapsing = child.isSelfCollapsingBlock(); 843 bool childIsSelfCollapsing = child.isSelfCollapsingBlock();
811 bool childDiscardMarginBefore = mustDiscardMarginBeforeForChild(child); 844 bool childDiscardMarginBefore = mustDiscardMarginBeforeForChild(child);
812 bool childDiscardMarginAfter = mustDiscardMarginAfterForChild(child); 845 bool childDiscardMarginAfter = mustDiscardMarginAfterForChild(child);
813 bool paginated = view()->layoutState()->isPaginated(); 846 bool paginated = view()->layoutState()->isPaginated();
814 847
815 // If there should be a forced break before the child, we need to insert it be fore attempting 848 // If there should be a forced break before the child, we need to insert it
816 // to collapse margins or apply clearance. 849 // before attempting to collapse margins or apply clearance.
817 if (paginated) { 850 if (paginated) {
818 // We will now insert the strut needed by any forced break. After this opera tion, we will 851 // We will now insert the strut needed by any forced break. After this
819 // have calculated the offset where we can apply margin collapsing and clear ance. After 852 // operation, we will have calculated the offset where we can apply margin
820 // having applied those things, we'll be at the position where we can honor requirements of 853 // collapsing and clearance. After having applied those things, we'll be at
821 // unbreakable content, which may extend the strut further. 854 // the position where we can honor requirements of unbreakable content,
855 // which may extend the strut further.
822 child.resetPaginationStrut(); 856 child.resetPaginationStrut();
823 insertForcedBreakBeforeChildIfNeeded(child, layoutInfo); 857 insertForcedBreakBeforeChildIfNeeded(child, layoutInfo);
824 } 858 }
825 859
826 // Now determine the correct ypos based off examination of collapsing margin 860 // Now determine the correct ypos based off examination of collapsing margin
827 // values. 861 // values.
828 LayoutUnit logicalTopBeforeClear = 862 LayoutUnit logicalTopBeforeClear =
829 collapseMargins(child, marginInfo, childIsSelfCollapsing, 863 collapseMargins(child, marginInfo, childIsSelfCollapsing,
830 childDiscardMarginBefore, childDiscardMarginAfter); 864 childDiscardMarginBefore, childDiscardMarginAfter);
831 865
832 // Now check for clear. 866 // Now check for clear.
833 bool childDiscardMargin = childDiscardMarginBefore || childDiscardMarginAfter; 867 bool childDiscardMargin = childDiscardMarginBefore || childDiscardMarginAfter;
834 LayoutUnit newLogicalTop = clearFloatsIfNeeded( 868 LayoutUnit newLogicalTop = clearFloatsIfNeeded(
835 child, marginInfo, oldPosMarginBefore, oldNegMarginBefore, 869 child, marginInfo, oldPosMarginBefore, oldNegMarginBefore,
836 logicalTopBeforeClear, childIsSelfCollapsing, childDiscardMargin); 870 logicalTopBeforeClear, childIsSelfCollapsing, childDiscardMargin);
837 871
838 // If there's a forced break in front of this child, its final position has al ready been 872 // If there's a forced break in front of this child, its final position has
839 // determined. Otherwise, see if there are other reasons for breaking before i t 873 // already been determined. Otherwise, see if there are other reasons for
840 // (break-inside:avoid, or not enough space for the first piece of child conte nt to fit in the 874 // breaking before it (break-inside:avoid, or not enough space for the first
841 // current fragmentainer), and adjust the position accordingly. 875 // piece of child content to fit in the current fragmentainer), and adjust the
876 // position accordingly.
842 if (paginated) { 877 if (paginated) {
843 if (estimateWithoutPagination != newLogicalTop) { 878 if (estimateWithoutPagination != newLogicalTop) {
844 // We got a new position due to clearance or margin collapsing. Before we attempt to 879 // We got a new position due to clearance or margin collapsing. Before we
845 // paginate (which may result in the position changing again), let's try a gain at the 880 // attempt to paginate (which may result in the position changing again),
846 // new position (since a new position may result in a new logical height). 881 // let's try again at the new position (since a new position may result in
882 // a new logical height).
847 positionAndLayoutOnceIfNeeded(child, newLogicalTop, layoutInfo); 883 positionAndLayoutOnceIfNeeded(child, newLogicalTop, layoutInfo);
848 } 884 }
849 885
850 // We have now applied forced breaks, margin collapsing and clearance, and w e're at the 886 // We have now applied forced breaks, margin collapsing and clearance, and
851 // position where we can honor requirements of unbreakable content. 887 // we're at the position where we can honor requirements of unbreakable
888 // content.
852 newLogicalTop = adjustBlockChildForPagination( 889 newLogicalTop = adjustBlockChildForPagination(
853 newLogicalTop, child, layoutInfo, 890 newLogicalTop, child, layoutInfo,
854 atBeforeSideOfBlock && logicalTopBeforeClear == newLogicalTop); 891 atBeforeSideOfBlock && logicalTopBeforeClear == newLogicalTop);
855 } 892 }
856 893
857 // Clearance, margin collapsing or pagination may have given us a new logical top, in which 894 // Clearance, margin collapsing or pagination may have given us a new logical
858 // case we may have to reposition and possibly relayout as well. If we determi ned during child 895 // top, in which case we may have to reposition and possibly relayout as well.
859 // layout that we need to insert a break to honor widows, we also need to rela yout. 896 // If we determined during child layout that we need to insert a break to
897 // honor widows, we also need to relayout.
860 if (newLogicalTop != logicalTopEstimate || child.needsLayout() || 898 if (newLogicalTop != logicalTopEstimate || child.needsLayout() ||
861 (paginated && childLayoutBlockFlow && 899 (paginated && childLayoutBlockFlow &&
862 childLayoutBlockFlow->shouldBreakAtLineToAvoidWidow())) { 900 childLayoutBlockFlow->shouldBreakAtLineToAvoidWidow())) {
863 positionAndLayoutOnceIfNeeded(child, newLogicalTop, layoutInfo); 901 positionAndLayoutOnceIfNeeded(child, newLogicalTop, layoutInfo);
864 } 902 }
865 903
866 // If we previously encountered a self-collapsing sibling of this child that h ad clearance then 904 // If we previously encountered a self-collapsing sibling of this child that
867 // we set this bit to ensure we would not collapse the child's margins, and th ose of any subsequent 905 // had clearance then we set this bit to ensure we would not collapse the
868 // self-collapsing siblings, with our parent. If this child is not self-collap sing then it can 906 // child's margins, and those of any subsequent self-collapsing siblings, with
869 // collapse its margins with the parent so reset the bit. 907 // our parent. If this child is not self-collapsing then it can collapse its
908 // margins with the parent so reset the bit.
870 if (!marginInfo.canCollapseMarginAfterWithLastChild() && 909 if (!marginInfo.canCollapseMarginAfterWithLastChild() &&
871 !childIsSelfCollapsing) 910 !childIsSelfCollapsing)
872 marginInfo.setCanCollapseMarginAfterWithLastChild(true); 911 marginInfo.setCanCollapseMarginAfterWithLastChild(true);
873 912
874 // We are no longer at the top of the block if we encounter a non-empty child. 913 // We are no longer at the top of the block if we encounter a non-empty child.
875 // This has to be done after checking for clear, so that margins can be reset if a clear occurred. 914 // This has to be done after checking for clear, so that margins can be reset
915 // if a clear occurred.
876 if (marginInfo.atBeforeSideOfBlock() && !childIsSelfCollapsing) 916 if (marginInfo.atBeforeSideOfBlock() && !childIsSelfCollapsing)
877 marginInfo.setAtBeforeSideOfBlock(false); 917 marginInfo.setAtBeforeSideOfBlock(false);
878 918
879 // Now place the child in the correct left position 919 // Now place the child in the correct left position
880 determineLogicalLeftPositionForChild(child); 920 determineLogicalLeftPositionForChild(child);
881 921
882 LayoutSize childOffset = child.location() - oldRect.location(); 922 LayoutSize childOffset = child.location() - oldRect.location();
883 923
884 // Update our height now that the child has been placed in the correct positio n. 924 // Update our height now that the child has been placed in the correct
925 // position.
885 setLogicalHeight(logicalHeight() + logicalHeightForChild(child)); 926 setLogicalHeight(logicalHeight() + logicalHeightForChild(child));
886 if (mustSeparateMarginAfterForChild(child)) { 927 if (mustSeparateMarginAfterForChild(child)) {
887 setLogicalHeight(logicalHeight() + marginAfterForChild(child)); 928 setLogicalHeight(logicalHeight() + marginAfterForChild(child));
888 marginInfo.clearMargin(); 929 marginInfo.clearMargin();
889 } 930 }
890 // If the child has overhanging floats that intrude into following siblings (o r possibly out 931 // If the child has overhanging floats that intrude into following siblings
891 // of this block), then the parent gets notified of the floats now. 932 // (or possibly out of this block), then the parent gets notified of the
933 // floats now.
892 if (childLayoutBlockFlow) 934 if (childLayoutBlockFlow)
893 addOverhangingFloats(childLayoutBlockFlow, !childNeededLayout); 935 addOverhangingFloats(childLayoutBlockFlow, !childNeededLayout);
894 936
895 // If the child moved, we have to invalidate its paint as well as any floating /positioned 937 // If the child moved, we have to invalidate its paint as well as any
896 // descendants. An exception is if we need a layout. In this case, we know we' re going to 938 // floating/positioned descendants. An exception is if we need a layout.
897 // invalidate our paint (and the child) anyway. 939 // In this case, we know we're going to invalidate our paint (and the child)
940 // anyway.
898 if (!selfNeedsLayout() && (childOffset.width() || childOffset.height()) && 941 if (!selfNeedsLayout() && (childOffset.width() || childOffset.height()) &&
899 child.isLayoutBlockFlow()) 942 child.isLayoutBlockFlow())
900 BlockFlowPaintInvalidator(toLayoutBlockFlow(child)) 943 BlockFlowPaintInvalidator(toLayoutBlockFlow(child))
901 .invalidatePaintForOverhangingFloats(); 944 .invalidatePaintForOverhangingFloats();
902 945
903 if (paginated) { 946 if (paginated) {
904 // Keep track of the break-after value of the child, so that it can be joine d with the 947 // Keep track of the break-after value of the child, so that it can be
905 // break-before value of the next in-flow object at the next class A break p oint. 948 // joined with the break-before value of the next in-flow object at the next
949 // class A break point.
906 layoutInfo.setPreviousBreakAfterValue(child.breakAfter()); 950 layoutInfo.setPreviousBreakAfterValue(child.breakAfter());
907 951
908 paginatedContentWasLaidOut(child.logicalBottom()); 952 paginatedContentWasLaidOut(child.logicalBottom());
909 } 953 }
910 954
911 if (child.isLayoutMultiColumnSpannerPlaceholder()) { 955 if (child.isLayoutMultiColumnSpannerPlaceholder()) {
912 // The actual column-span:all element is positioned by this placeholder chil d. 956 // The actual column-span:all element is positioned by this placeholder
957 // child.
913 positionSpannerDescendant(toLayoutMultiColumnSpannerPlaceholder(child)); 958 positionSpannerDescendant(toLayoutMultiColumnSpannerPlaceholder(child));
914 } 959 }
915 } 960 }
916 961
917 LayoutUnit LayoutBlockFlow::adjustBlockChildForPagination( 962 LayoutUnit LayoutBlockFlow::adjustBlockChildForPagination(
918 LayoutUnit logicalTop, 963 LayoutUnit logicalTop,
919 LayoutBox& child, 964 LayoutBox& child,
920 BlockChildrenLayoutInfo& layoutInfo, 965 BlockChildrenLayoutInfo& layoutInfo,
921 bool atBeforeSideOfBlock) { 966 bool atBeforeSideOfBlock) {
922 LayoutBlockFlow* childBlockFlow = 967 LayoutBlockFlow* childBlockFlow =
923 child.isLayoutBlockFlow() ? toLayoutBlockFlow(&child) : 0; 968 child.isLayoutBlockFlow() ? toLayoutBlockFlow(&child) : 0;
924 969
925 // See if we need a soft (unforced) break in front of this child, and set the pagination strut 970 // See if we need a soft (unforced) break in front of this child, and set the
926 // in that case. An unforced break may come from two sources: 971 // pagination strut in that case. An unforced break may come from two sources:
927 // 1. The first piece of content inside the child doesn't fit in the current p age or column 972 // 1. The first piece of content inside the child doesn't fit in the current
928 // 2. The child itself has breaking restrictions (break-inside:avoid, replaced content, etc.) 973 // page or column
929 // and doesn't fully fit in the current page or column. 974 // 2. The child itself has breaking restrictions (break-inside:avoid, replaced
975 // content, etc.) and doesn't fully fit in the current page or column.
930 // 976 //
931 // No matter which source, if we need to insert a strut, it should always take us to the exact 977 // No matter which source, if we need to insert a strut, it should always take
932 // top of a page or column further ahead, or be zero. 978 // us to the exact top of a page or column further ahead, or be zero.
933 979
934 // The first piece of content inside the child may have set a strut during lay out. Currently, 980 // The first piece of content inside the child may have set a strut during
935 // only block flows support strut propagation, but this may (and should) chang e in the future. 981 // layout. Currently, only block flows support strut propagation, but this may
936 // See crbug.com/539873 982 // (and should) change in the future. See crbug.com/539873
937 LayoutUnit strutFromContent = 983 LayoutUnit strutFromContent =
938 childBlockFlow ? childBlockFlow->paginationStrutPropagatedFromChild() 984 childBlockFlow ? childBlockFlow->paginationStrutPropagatedFromChild()
939 : LayoutUnit(); 985 : LayoutUnit();
940 LayoutUnit logicalTopWithContentStrut = logicalTop + strutFromContent; 986 LayoutUnit logicalTopWithContentStrut = logicalTop + strutFromContent;
941 987
942 // For replaced elements and scrolled elements, we want to shift them to the n ext page if they don't fit on the current one. 988 // For replaced elements and scrolled elements, we want to shift them to the
989 // next page if they don't fit on the current one.
943 LayoutUnit logicalTopAfterUnsplittable = 990 LayoutUnit logicalTopAfterUnsplittable =
944 adjustForUnsplittableChild(child, logicalTop); 991 adjustForUnsplittableChild(child, logicalTop);
945 992
946 // Pick the largest offset. Tall unsplittable content may take us to a page or column further 993 // Pick the largest offset. Tall unsplittable content may take us to a page or
947 // ahead than the next one. 994 // column further ahead than the next one.
948 LayoutUnit logicalTopAfterPagination = 995 LayoutUnit logicalTopAfterPagination =
949 std::max(logicalTopWithContentStrut, logicalTopAfterUnsplittable); 996 std::max(logicalTopWithContentStrut, logicalTopAfterUnsplittable);
950 LayoutUnit newLogicalTop = logicalTop; 997 LayoutUnit newLogicalTop = logicalTop;
951 998
952 // Forced breaks may already have caused a strut, and this needs to be added t ogether with 999 // Forced breaks may already have caused a strut, and this needs to be added
953 // any strut detected here in this method. 1000 // together with any strut detected here in this method.
954 LayoutUnit previousStrut = child.paginationStrut(); 1001 LayoutUnit previousStrut = child.paginationStrut();
955 1002
956 if (LayoutUnit paginationStrut = 1003 if (LayoutUnit paginationStrut =
957 logicalTopAfterPagination - logicalTop + previousStrut) { 1004 logicalTopAfterPagination - logicalTop + previousStrut) {
958 ASSERT(paginationStrut > 0); 1005 ASSERT(paginationStrut > 0);
959 // If we're not at the first in-flow child, there's a class A break point be fore the child. If we *are* at the 1006 // If we're not at the first in-flow child, there's a class A break point
960 // first in-flow child, but the child isn't flush with the content edge of i ts container, due to e.g. clearance, 1007 // before the child. If we *are* at the first in-flow child, but the child
961 // there's a class C break point before the child. Otherwise we should propa gate the strut to our parent block, 1008 // isn't flush with the content edge of its container, due to e.g.
962 // and attempt to break there instead. See https://drafts.csswg.org/css-brea k/#possible-breaks 1009 // clearance, there's a class C break point before the child. Otherwise we
1010 // should propagate the strut to our parent block, and attempt to break
1011 // there instead. See https://drafts.csswg.org/css-break/#possible-breaks
963 if (layoutInfo.isAtFirstInFlowChild() && atBeforeSideOfBlock && 1012 if (layoutInfo.isAtFirstInFlowChild() && atBeforeSideOfBlock &&
964 allowsPaginationStrut()) { 1013 allowsPaginationStrut()) {
965 // FIXME: Should really check if we're exceeding the page height before pr opagating the strut, but we don't 1014 // FIXME: Should really check if we're exceeding the page height before
966 // have all the information to do so (the strut only has the remaining amo unt to push). Gecko gets this wrong too 1015 // propagating the strut, but we don't have all the information to do so
967 // and pushes to the next page anyway, so not too concerned about it. 1016 // (the strut only has the remaining amount to push). Gecko gets this
1017 // wrong too and pushes to the next page anyway, so not too concerned
1018 // about it.
968 paginationStrut += logicalTop + marginBeforeIfFloating(); 1019 paginationStrut += logicalTop + marginBeforeIfFloating();
969 setPaginationStrutPropagatedFromChild(paginationStrut); 1020 setPaginationStrutPropagatedFromChild(paginationStrut);
970 child.resetPaginationStrut(); 1021 child.resetPaginationStrut();
971 if (childBlockFlow) 1022 if (childBlockFlow)
972 childBlockFlow->setPaginationStrutPropagatedFromChild(LayoutUnit()); 1023 childBlockFlow->setPaginationStrutPropagatedFromChild(LayoutUnit());
973 } else { 1024 } else {
974 child.setPaginationStrut(paginationStrut); 1025 child.setPaginationStrut(paginationStrut);
975 // |previousStrut| was already baked into the logical top, so don't add it again. 1026 // |previousStrut| was already baked into the logical top, so don't add it
1027 // again.
976 newLogicalTop += paginationStrut - previousStrut; 1028 newLogicalTop += paginationStrut - previousStrut;
977 } 1029 }
978 } 1030 }
979 1031
980 // Similar to how we apply clearance. Go ahead and boost height() to be the pl ace where we're going to position the child. 1032 // Similar to how we apply clearance. Go ahead and boost height() to be the
1033 // place where we're going to position the child.
981 setLogicalHeight(logicalHeight() + (newLogicalTop - logicalTop)); 1034 setLogicalHeight(logicalHeight() + (newLogicalTop - logicalTop));
982 1035
983 // Return the final adjusted logical top. 1036 // Return the final adjusted logical top.
984 return newLogicalTop; 1037 return newLogicalTop;
985 } 1038 }
986 1039
987 static bool shouldSetStrutOnBlock(const LayoutBlockFlow& block, 1040 static bool shouldSetStrutOnBlock(const LayoutBlockFlow& block,
988 const RootInlineBox& lineBox, 1041 const RootInlineBox& lineBox,
989 LayoutUnit lineLogicalOffset, 1042 LayoutUnit lineLogicalOffset,
990 int lineIndex, 1043 int lineIndex,
991 LayoutUnit pageLogicalHeight) { 1044 LayoutUnit pageLogicalHeight) {
992 if (lineBox == block.firstRootBox()) { 1045 if (lineBox == block.firstRootBox()) {
993 // This is the first line in the block. We can take the whole block with us to the next page 1046 // This is the first line in the block. We can take the whole block with us
994 // or column, rather than keeping a content-less portion of it in the previo us one. Only do 1047 // to the next page or column, rather than keeping a content-less portion of
995 // this if the line is flush with the content edge of the block, though. If it isn't, it 1048 // it in the previous one. Only do this if the line is flush with the
996 // means that the line was pushed downwards by preceding floats that didn't fit beside the 1049 // content edge of the block, though. If it isn't, it means that the line
997 // line, and we don't want to move all that, since it has already been estab lished that it 1050 // was pushed downwards by preceding floats that didn't fit beside the line,
998 // fits nicely where it is. In this case we have a class "C" break point [1] in front of 1051 // and we don't want to move all that, since it has already been established
999 // this line. 1052 // that it fits nicely where it is. In this case we have a class "C" break
1053 // point [1] in front of this line.
1000 // 1054 //
1001 // [1] https://drafts.csswg.org/css-break/#possible-breaks 1055 // [1] https://drafts.csswg.org/css-break/#possible-breaks
1002 if (lineLogicalOffset > block.borderAndPaddingBefore()) 1056 if (lineLogicalOffset > block.borderAndPaddingBefore())
1003 return false; 1057 return false;
1004 1058
1005 LayoutUnit lineHeight = 1059 LayoutUnit lineHeight =
1006 lineBox.lineBottomWithLeading() - lineBox.lineTopWithLeading(); 1060 lineBox.lineBottomWithLeading() - lineBox.lineTopWithLeading();
1007 LayoutUnit totalLogicalHeight = 1061 LayoutUnit totalLogicalHeight =
1008 lineHeight + lineLogicalOffset.clampNegativeToZero(); 1062 lineHeight + lineLogicalOffset.clampNegativeToZero();
1009 // It's rather pointless to break before the block if the current line isn't going to 1063 // It's rather pointless to break before the block if the current line isn't
1064 // going to
1010 // fit in the same column or page, so check that as well. 1065 // fit in the same column or page, so check that as well.
1011 if (totalLogicalHeight > pageLogicalHeight) 1066 if (totalLogicalHeight > pageLogicalHeight)
1012 return false; 1067 return false;
1013 } else { 1068 } else {
1014 if (lineIndex > block.style()->orphans()) 1069 if (lineIndex > block.style()->orphans())
1015 return false; 1070 return false;
1016 1071
1017 // Not enough orphans here. Push the entire block to the next column / page as an attempt to 1072 // Not enough orphans here. Push the entire block to the next column / page
1018 // better satisfy the orphans requirement. 1073 // as an attempt to better satisfy the orphans requirement.
1019 // 1074 //
1020 // Note that we should ideally check if the first line in the block is flush with the 1075 // Note that we should ideally check if the first line in the block is flush
1021 // content edge of the block here, because if it isn't, we should break at t he class "C" 1076 // with the content edge of the block here, because if it isn't, we should
1022 // break point in front of the first line, rather than before the entire blo ck. 1077 // break at the class "C" break point in front of the first line, rather
1078 // than before the entire block.
1023 } 1079 }
1024 return block.allowsPaginationStrut(); 1080 return block.allowsPaginationStrut();
1025 } 1081 }
1026 1082
1027 void LayoutBlockFlow::adjustLinePositionForPagination(RootInlineBox& lineBox, 1083 void LayoutBlockFlow::adjustLinePositionForPagination(RootInlineBox& lineBox,
1028 LayoutUnit& delta) { 1084 LayoutUnit& delta) {
1029 // TODO(mstensho): Pay attention to line overflow. It should be painted in the same column as 1085 // TODO(mstensho): Pay attention to line overflow. It should be painted in the
1030 // the rest of the line, possibly overflowing the column. We currently only al low overflow above 1086 // same column as the rest of the line, possibly overflowing the column. We
1031 // the first column. We clip at all other column boundaries, and that's how it has to be for 1087 // currently only allow overflow above the first column. We clip at all other
1032 // now. The paint we have to do when a column has overflow has to be special. We need to exclude 1088 // column boundaries, and that's how it has to be for now. The paint we have
1033 // content that paints in a previous column (and content that paints in the fo llowing column). 1089 // to do when a column has overflow has to be special.
1090 // We need to exclude content that paints in a previous column (and content
1091 // that paints in the following column).
1034 // 1092 //
1035 // FIXME: Another problem with simply moving lines is that the available line width may change (because of floats). 1093 // FIXME: Another problem with simply moving lines is that the available line
1036 // Technically if the location we move the line to has a different line width than our old position, then we need to dirty the 1094 // width may change (because of floats). Technically if the location we move
1037 // line and all following lines. 1095 // the line to has a different line width than our old position, then we need
1096 // to dirty the line and all following lines.
1038 LayoutUnit logicalOffset = lineBox.lineTopWithLeading(); 1097 LayoutUnit logicalOffset = lineBox.lineTopWithLeading();
1039 LayoutUnit lineHeight = lineBox.lineBottomWithLeading() - logicalOffset; 1098 LayoutUnit lineHeight = lineBox.lineBottomWithLeading() - logicalOffset;
1040 logicalOffset += delta; 1099 logicalOffset += delta;
1041 lineBox.setPaginationStrut(LayoutUnit()); 1100 lineBox.setPaginationStrut(LayoutUnit());
1042 lineBox.setIsFirstAfterPageBreak(false); 1101 lineBox.setIsFirstAfterPageBreak(false);
1043 LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset); 1102 LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset);
1044 if (!pageLogicalHeight) 1103 if (!pageLogicalHeight)
1045 return; 1104 return;
1046 LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset( 1105 LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset(
1047 logicalOffset, AssociateWithLatterPage); 1106 logicalOffset, AssociateWithLatterPage);
1048 int lineIndex = lineCount(&lineBox); 1107 int lineIndex = lineCount(&lineBox);
1049 if (remainingLogicalHeight < lineHeight || 1108 if (remainingLogicalHeight < lineHeight ||
1050 (shouldBreakAtLineToAvoidWidow() && 1109 (shouldBreakAtLineToAvoidWidow() &&
1051 lineBreakToAvoidWidow() == lineIndex)) { 1110 lineBreakToAvoidWidow() == lineIndex)) {
1052 LayoutUnit paginationStrut = calculatePaginationStrutToFitContent( 1111 LayoutUnit paginationStrut = calculatePaginationStrutToFitContent(
1053 logicalOffset, remainingLogicalHeight, lineHeight); 1112 logicalOffset, remainingLogicalHeight, lineHeight);
1054 LayoutUnit newLogicalOffset = logicalOffset + paginationStrut; 1113 LayoutUnit newLogicalOffset = logicalOffset + paginationStrut;
1055 // Moving to a different page or column may mean that its height is differen t. 1114 // Moving to a different page or column may mean that its height is
1115 // different.
1056 pageLogicalHeight = pageLogicalHeightForOffset(newLogicalOffset); 1116 pageLogicalHeight = pageLogicalHeightForOffset(newLogicalOffset);
1057 if (lineHeight > pageLogicalHeight) { 1117 if (lineHeight > pageLogicalHeight) {
1058 // Too tall to fit in one page / column. Give up. Don't push to the next p age / column. 1118 // Too tall to fit in one page / column. Give up. Don't push to the next
1059 // TODO(mstensho): Get rid of this. This is just utter weirdness, but the other browsers 1119 // page / column.
1060 // also do something slightly similar, although in much more specific case s than we do here, 1120 // TODO(mstensho): Get rid of this. This is just utter weirdness, but the
1061 // and printing Google Docs depends on it. 1121 // other browsers also do something slightly similar, although in much
1122 // more specific cases than we do here, and printing Google Docs depends
1123 // on it.
1062 paginatedContentWasLaidOut(logicalOffset + lineHeight); 1124 paginatedContentWasLaidOut(logicalOffset + lineHeight);
1063 return; 1125 return;
1064 } 1126 }
1065 1127
1066 // We need to insert a break now, either because there's no room for the lin e in the 1128 // We need to insert a break now, either because there's no room for the
1067 // current column / page, or because we have determined that we need a break to satisfy 1129 // line in the current column / page, or because we have determined that we
1068 // widow requirements. 1130 // need a break to satisfy widow requirements.
1069 if (shouldBreakAtLineToAvoidWidow() && 1131 if (shouldBreakAtLineToAvoidWidow() &&
1070 lineBreakToAvoidWidow() == lineIndex) { 1132 lineBreakToAvoidWidow() == lineIndex) {
1071 clearShouldBreakAtLineToAvoidWidow(); 1133 clearShouldBreakAtLineToAvoidWidow();
1072 setDidBreakAtLineToAvoidWidow(); 1134 setDidBreakAtLineToAvoidWidow();
1073 } 1135 }
1074 if (shouldSetStrutOnBlock(*this, lineBox, logicalOffset, lineIndex, 1136 if (shouldSetStrutOnBlock(*this, lineBox, logicalOffset, lineIndex,
1075 pageLogicalHeight)) { 1137 pageLogicalHeight)) {
1076 // Note that when setting the strut on a block, it may be propagated to pa rent blocks 1138 // Note that when setting the strut on a block, it may be propagated to
1077 // later on, if a block's logical top is flush with that of its parent. We don't want 1139 // parent blocks later on, if a block's logical top is flush with that of
1078 // content-less portions (struts) at the beginning of a block before a bre ak, if it can 1140 // its parent. We don't want content-less portions (struts) at the
1079 // be avoided. After all, that's the reason for setting struts on blocks a nd not lines 1141 // beginning of a block before a break, if it can be avoided. After all,
1080 // in the first place. 1142 // that's the reason for setting struts on blocks and not lines in the
1143 // first place.
1081 LayoutUnit strut = 1144 LayoutUnit strut =
1082 paginationStrut + logicalOffset + marginBeforeIfFloating(); 1145 paginationStrut + logicalOffset + marginBeforeIfFloating();
1083 setPaginationStrutPropagatedFromChild(strut); 1146 setPaginationStrutPropagatedFromChild(strut);
1084 } else { 1147 } else {
1085 delta += paginationStrut; 1148 delta += paginationStrut;
1086 lineBox.setPaginationStrut(paginationStrut); 1149 lineBox.setPaginationStrut(paginationStrut);
1087 lineBox.setIsFirstAfterPageBreak(true); 1150 lineBox.setIsFirstAfterPageBreak(true);
1088 } 1151 }
1089 paginatedContentWasLaidOut(newLogicalOffset + lineHeight); 1152 paginatedContentWasLaidOut(newLogicalOffset + lineHeight);
1090 return; 1153 return;
1091 } 1154 }
1092 1155
1093 LayoutUnit strutToPropagate; 1156 LayoutUnit strutToPropagate;
1094 if (remainingLogicalHeight == pageLogicalHeight) { 1157 if (remainingLogicalHeight == pageLogicalHeight) {
1095 // We're at the very top of a page or column. 1158 // We're at the very top of a page or column.
1096 if (lineBox != firstRootBox()) 1159 if (lineBox != firstRootBox())
1097 lineBox.setIsFirstAfterPageBreak(true); 1160 lineBox.setIsFirstAfterPageBreak(true);
1098 // If this is the first line in the block, and the block has a top border, p adding, or (in 1161 // If this is the first line in the block, and the block has a top border,
1099 // case it's a float) margin, we may want to set a strut on the block, so th at everything 1162 // padding, or (in case it's a float) margin, we may want to set a strut on
1100 // ends up in the next column or page. Setting a strut on the block is also important when 1163 // the block, so that everything ends up in the next column or page. Setting
1101 // it comes to satisfying orphan requirements. 1164 // a strut on the block is also important when it comes to satisfying orphan
1165 // requirements.
1102 if (shouldSetStrutOnBlock(*this, lineBox, logicalOffset, lineIndex, 1166 if (shouldSetStrutOnBlock(*this, lineBox, logicalOffset, lineIndex,
1103 pageLogicalHeight)) 1167 pageLogicalHeight))
1104 strutToPropagate = logicalOffset + marginBeforeIfFloating(); 1168 strutToPropagate = logicalOffset + marginBeforeIfFloating();
1105 } else if (lineBox == firstRootBox() && allowsPaginationStrut()) { 1169 } else if (lineBox == firstRootBox() && allowsPaginationStrut()) {
1106 // This is the first line in the block. The block may still start in the pre vious column or 1170 // This is the first line in the block. The block may still start in the
1107 // page, and if that's the case, attempt to pull it over to where this line is, so that we 1171 // previous column or page, and if that's the case, attempt to pull it over
1108 // don't split the top border, padding, or (in case it's a float) margin. 1172 // to where this line is, so that we don't split the top border, padding, or
1173 // (in case it's a float) margin.
1109 LayoutUnit totalLogicalOffset = logicalOffset + marginBeforeIfFloating(); 1174 LayoutUnit totalLogicalOffset = logicalOffset + marginBeforeIfFloating();
1110 LayoutUnit strut = 1175 LayoutUnit strut =
1111 remainingLogicalHeight + totalLogicalOffset - pageLogicalHeight; 1176 remainingLogicalHeight + totalLogicalOffset - pageLogicalHeight;
1112 if (strut > 0) { 1177 if (strut > 0) {
1113 // The block starts in a previous column or page. Set a strut on the block if there's 1178 // The block starts in a previous column or page. Set a strut on the block
1114 // room for the top border, padding and (if it's a float) margin and the l ine in one 1179 // if there's room for the top border, padding and (if it's a float)
1115 // column or page. 1180 // margin and the line in one column or page.
1116 if (totalLogicalOffset + lineHeight <= pageLogicalHeight) 1181 if (totalLogicalOffset + lineHeight <= pageLogicalHeight)
1117 strutToPropagate = strut; 1182 strutToPropagate = strut;
1118 } 1183 }
1119 } 1184 }
1120 1185
1121 // If we found that some preceding content (lines, border and padding) belongs together with 1186 // If we found that some preceding content (lines, border and padding) belongs
1122 // this line, we should pull the entire block with us to the fragmentainer we' re currently 1187 // together with this line, we should pull the entire block with us to the
1123 // in. We need to avoid this when the block precedes the first fragmentainer, though. We 1188 // fragmentainer we're currently in. We need to avoid this when the block
1124 // shouldn't fragment content there, but rather let it appear in the overflow area before the 1189 // precedes the first fragmentainer, though. We shouldn't fragment content
1125 // first fragmentainer. 1190 // there, but rather let it appear in the overflow area before the first
1191 // fragmentainer.
1126 if (strutToPropagate && offsetFromLogicalTopOfFirstPage() > LayoutUnit()) 1192 if (strutToPropagate && offsetFromLogicalTopOfFirstPage() > LayoutUnit())
1127 setPaginationStrutPropagatedFromChild(strutToPropagate); 1193 setPaginationStrutPropagatedFromChild(strutToPropagate);
1128 1194
1129 paginatedContentWasLaidOut(logicalOffset + lineHeight); 1195 paginatedContentWasLaidOut(logicalOffset + lineHeight);
1130 } 1196 }
1131 1197
1132 LayoutUnit LayoutBlockFlow::adjustForUnsplittableChild( 1198 LayoutUnit LayoutBlockFlow::adjustForUnsplittableChild(
1133 LayoutBox& child, 1199 LayoutBox& child,
1134 LayoutUnit logicalOffset) const { 1200 LayoutUnit logicalOffset) const {
1135 if (child.getPaginationBreakability() == AllowAnyBreaks) 1201 if (child.getPaginationBreakability() == AllowAnyBreaks)
1136 return logicalOffset; 1202 return logicalOffset;
1137 LayoutUnit childLogicalHeight = logicalHeightForChild(child); 1203 LayoutUnit childLogicalHeight = logicalHeightForChild(child);
1138 // Floats' margins do not collapse with page or column boundaries. 1204 // Floats' margins do not collapse with page or column boundaries.
1139 if (child.isFloating()) 1205 if (child.isFloating())
1140 childLogicalHeight += 1206 childLogicalHeight +=
1141 marginBeforeForChild(child) + marginAfterForChild(child); 1207 marginBeforeForChild(child) + marginAfterForChild(child);
1142 LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset); 1208 LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset);
1143 if (!pageLogicalHeight) 1209 if (!pageLogicalHeight)
1144 return logicalOffset; 1210 return logicalOffset;
1145 LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset( 1211 LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset(
1146 logicalOffset, AssociateWithLatterPage); 1212 logicalOffset, AssociateWithLatterPage);
1147 if (remainingLogicalHeight >= childLogicalHeight) 1213 if (remainingLogicalHeight >= childLogicalHeight)
1148 return logicalOffset; // It fits fine where it is. No need to break. 1214 return logicalOffset; // It fits fine where it is. No need to break.
1149 LayoutUnit paginationStrut = calculatePaginationStrutToFitContent( 1215 LayoutUnit paginationStrut = calculatePaginationStrutToFitContent(
1150 logicalOffset, remainingLogicalHeight, childLogicalHeight); 1216 logicalOffset, remainingLogicalHeight, childLogicalHeight);
1151 if (paginationStrut == remainingLogicalHeight && 1217 if (paginationStrut == remainingLogicalHeight &&
1152 remainingLogicalHeight == pageLogicalHeight) { 1218 remainingLogicalHeight == pageLogicalHeight) {
1153 // Don't break if we were at the top of a page, and we failed to fit the con tent 1219 // Don't break if we were at the top of a page, and we failed to fit the
1154 // completely. No point in leaving a page completely blank. 1220 // content completely. No point in leaving a page completely blank.
1155 return logicalOffset; 1221 return logicalOffset;
1156 } 1222 }
1157 return logicalOffset + paginationStrut; 1223 return logicalOffset + paginationStrut;
1158 } 1224 }
1159 1225
1160 DISABLE_CFI_PERF 1226 DISABLE_CFI_PERF
1161 void LayoutBlockFlow::rebuildFloatsFromIntruding() { 1227 void LayoutBlockFlow::rebuildFloatsFromIntruding() {
1162 if (m_floatingObjects) 1228 if (m_floatingObjects)
1163 m_floatingObjects->setHorizontalWritingMode(isHorizontalWritingMode()); 1229 m_floatingObjects->setHorizontalWritingMode(isHorizontalWritingMode());
1164 1230
1165 HashSet<LayoutBox*> oldIntrudingFloatSet; 1231 HashSet<LayoutBox*> oldIntrudingFloatSet;
1166 if (!childrenInline() && m_floatingObjects) { 1232 if (!childrenInline() && m_floatingObjects) {
1167 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); 1233 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
1168 FloatingObjectSetIterator end = floatingObjectSet.end(); 1234 FloatingObjectSetIterator end = floatingObjectSet.end();
1169 for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; 1235 for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end;
1170 ++it) { 1236 ++it) {
1171 const FloatingObject& floatingObject = *it->get(); 1237 const FloatingObject& floatingObject = *it->get();
1172 if (!floatingObject.isDescendant()) 1238 if (!floatingObject.isDescendant())
1173 oldIntrudingFloatSet.add(floatingObject.layoutObject()); 1239 oldIntrudingFloatSet.add(floatingObject.layoutObject());
1174 } 1240 }
1175 } 1241 }
1176 1242
1177 // Inline blocks are covered by the isAtomicInlineLevel() check in the avoidFl oats method. 1243 // Inline blocks are covered by the isAtomicInlineLevel() check in the
1244 // avoidFloats method.
1178 if (avoidsFloats() || isDocumentElement() || isLayoutView() || 1245 if (avoidsFloats() || isDocumentElement() || isLayoutView() ||
1179 isFloatingOrOutOfFlowPositioned() || isTableCell()) { 1246 isFloatingOrOutOfFlowPositioned() || isTableCell()) {
1180 if (m_floatingObjects) { 1247 if (m_floatingObjects) {
1181 m_floatingObjects->clear(); 1248 m_floatingObjects->clear();
1182 } 1249 }
1183 if (!oldIntrudingFloatSet.isEmpty()) 1250 if (!oldIntrudingFloatSet.isEmpty())
1184 markAllDescendantsWithFloatsForLayout(); 1251 markAllDescendantsWithFloatsForLayout();
1185 return; 1252 return;
1186 } 1253 }
1187 1254
1188 LayoutBoxToFloatInfoMap floatMap; 1255 LayoutBoxToFloatInfoMap floatMap;
1189 1256
1190 if (m_floatingObjects) { 1257 if (m_floatingObjects) {
1191 if (childrenInline()) 1258 if (childrenInline())
1192 m_floatingObjects->moveAllToFloatInfoMap(floatMap); 1259 m_floatingObjects->moveAllToFloatInfoMap(floatMap);
1193 else 1260 else
1194 m_floatingObjects->clear(); 1261 m_floatingObjects->clear();
1195 } 1262 }
1196 1263
1197 // We should not process floats if the parent node is not a LayoutBlockFlow. O therwise, we will add 1264 // We should not process floats if the parent node is not a LayoutBlockFlow.
1198 // floats in an invalid context. This will cause a crash arising from a bad ca st on the parent. 1265 // Otherwise, we will add floats in an invalid context. This will cause a
1199 // See <rdar://problem/8049753>, where float property is applied on a text nod e in a SVG. 1266 // crash arising from a bad cast on the parent.
1267 // See <rdar://problem/8049753>, where float property is applied on a text
1268 // node in a SVG.
1200 if (!parent() || !parent()->isLayoutBlockFlow()) 1269 if (!parent() || !parent()->isLayoutBlockFlow())
1201 return; 1270 return;
1202 1271
1203 // Attempt to locate a previous sibling with overhanging floats. We skip any e lements that 1272 // Attempt to locate a previous sibling with overhanging floats. We skip any
1204 // may have shifted to avoid floats, and any objects whose floats cannot inter act with objects 1273 // elements that may have shifted to avoid floats, and any objects whose
1205 // outside it (i.e. objects that create a new block formatting context). 1274 // floats cannot interact with objects outside it (i.e. objects that create a
1275 // new block formatting context).
1206 LayoutBlockFlow* parentBlockFlow = toLayoutBlockFlow(parent()); 1276 LayoutBlockFlow* parentBlockFlow = toLayoutBlockFlow(parent());
1207 bool siblingFloatMayIntrude = false; 1277 bool siblingFloatMayIntrude = false;
1208 LayoutObject* prev = previousSibling(); 1278 LayoutObject* prev = previousSibling();
1209 while (prev && (!prev->isBox() || !prev->isLayoutBlock() || 1279 while (prev && (!prev->isBox() || !prev->isLayoutBlock() ||
1210 toLayoutBlock(prev)->avoidsFloats() || 1280 toLayoutBlock(prev)->avoidsFloats() ||
1211 toLayoutBlock(prev)->createsNewFormattingContext())) { 1281 toLayoutBlock(prev)->createsNewFormattingContext())) {
1212 if (prev->isFloating()) 1282 if (prev->isFloating())
1213 siblingFloatMayIntrude = true; 1283 siblingFloatMayIntrude = true;
1214 prev = prev->previousSibling(); 1284 prev = prev->previousSibling();
1215 } 1285 }
1216 1286
1217 // First add in floats from the parent. Self-collapsing blocks let their paren t track any floats that intrude into 1287 // First add in floats from the parent. Self-collapsing blocks let their
1218 // them (as opposed to floats they contain themselves) so check for those here too. If margin collapsing has moved 1288 // parent track any floats that intrude into them (as opposed to floats they
1219 // us up past the top a previous sibling then we need to check for floats from the parent too. 1289 // contain themselves) so check for those here too. If margin collapsing has
1290 // moved us up past the top a previous sibling then we need to check for
1291 // floats from the parent too.
1220 bool parentFloatsMayIntrude = 1292 bool parentFloatsMayIntrude =
1221 !siblingFloatMayIntrude && 1293 !siblingFloatMayIntrude &&
1222 (!prev || toLayoutBlockFlow(prev)->isSelfCollapsingBlock() || 1294 (!prev || toLayoutBlockFlow(prev)->isSelfCollapsingBlock() ||
1223 toLayoutBlock(prev)->logicalTop() > logicalTop()) && 1295 toLayoutBlock(prev)->logicalTop() > logicalTop()) &&
1224 parentBlockFlow->lowestFloatLogicalBottom() > logicalTop(); 1296 parentBlockFlow->lowestFloatLogicalBottom() > logicalTop();
1225 if (siblingFloatMayIntrude || parentFloatsMayIntrude) 1297 if (siblingFloatMayIntrude || parentFloatsMayIntrude)
1226 addIntrudingFloats(parentBlockFlow, 1298 addIntrudingFloats(parentBlockFlow,
1227 parentBlockFlow->logicalLeftOffsetForContent(), 1299 parentBlockFlow->logicalLeftOffsetForContent(),
1228 logicalTop()); 1300 logicalTop());
1229 1301
1230 // Add overhanging floats from the previous LayoutBlockFlow, but only if it ha s a float that intrudes into our space. 1302 // Add overhanging floats from the previous LayoutBlockFlow, but only if it
1303 // has a float that intrudes into our space.
1231 if (prev) { 1304 if (prev) {
1232 LayoutBlockFlow* previousBlockFlow = toLayoutBlockFlow(prev); 1305 LayoutBlockFlow* previousBlockFlow = toLayoutBlockFlow(prev);
1233 if (logicalTop() < previousBlockFlow->logicalTop() + 1306 if (logicalTop() < previousBlockFlow->logicalTop() +
1234 previousBlockFlow->lowestFloatLogicalBottom()) 1307 previousBlockFlow->lowestFloatLogicalBottom())
1235 addIntrudingFloats(previousBlockFlow, LayoutUnit(), 1308 addIntrudingFloats(previousBlockFlow, LayoutUnit(),
1236 logicalTop() - previousBlockFlow->logicalTop()); 1309 logicalTop() - previousBlockFlow->logicalTop());
1237 } 1310 }
1238 1311
1239 if (childrenInline()) { 1312 if (childrenInline()) {
1240 LayoutUnit changeLogicalTop = LayoutUnit::max(); 1313 LayoutUnit changeLogicalTop = LayoutUnit::max();
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1297 std::unique_ptr<FloatingObject>& floatingObject = it->value; 1370 std::unique_ptr<FloatingObject>& floatingObject = it->value;
1298 if (!floatingObject->isDescendant()) { 1371 if (!floatingObject->isDescendant()) {
1299 changeLogicalTop = LayoutUnit(); 1372 changeLogicalTop = LayoutUnit();
1300 changeLogicalBottom = std::max(changeLogicalBottom, 1373 changeLogicalBottom = std::max(changeLogicalBottom,
1301 logicalBottomForFloat(*floatingObject)); 1374 logicalBottomForFloat(*floatingObject));
1302 } 1375 }
1303 } 1376 }
1304 1377
1305 markLinesDirtyInBlockRange(changeLogicalTop, changeLogicalBottom); 1378 markLinesDirtyInBlockRange(changeLogicalTop, changeLogicalBottom);
1306 } else if (!oldIntrudingFloatSet.isEmpty()) { 1379 } else if (!oldIntrudingFloatSet.isEmpty()) {
1307 // If there are previously intruding floats that no longer intrude, then chi ldren with floats 1380 // If there are previously intruding floats that no longer intrude, then
1308 // should also get layout because they might need their floating object list s cleared. 1381 // children with floats should also get layout because they might need their
1382 // floating object lists cleared.
1309 if (m_floatingObjects->set().size() < oldIntrudingFloatSet.size()) { 1383 if (m_floatingObjects->set().size() < oldIntrudingFloatSet.size()) {
1310 markAllDescendantsWithFloatsForLayout(); 1384 markAllDescendantsWithFloatsForLayout();
1311 } else { 1385 } else {
1312 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); 1386 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
1313 FloatingObjectSetIterator end = floatingObjectSet.end(); 1387 FloatingObjectSetIterator end = floatingObjectSet.end();
1314 for (FloatingObjectSetIterator it = floatingObjectSet.begin(); 1388 for (FloatingObjectSetIterator it = floatingObjectSet.begin();
1315 it != end && !oldIntrudingFloatSet.isEmpty(); ++it) 1389 it != end && !oldIntrudingFloatSet.isEmpty(); ++it)
1316 oldIntrudingFloatSet.remove((*it)->layoutObject()); 1390 oldIntrudingFloatSet.remove((*it)->layoutObject());
1317 if (!oldIntrudingFloatSet.isEmpty()) 1391 if (!oldIntrudingFloatSet.isEmpty())
1318 markAllDescendantsWithFloatsForLayout(); 1392 markAllDescendantsWithFloatsForLayout();
(...skipping 23 matching lines...) Expand all
1342 1416
1343 while (next) { 1417 while (next) {
1344 LayoutBox* child = next; 1418 LayoutBox* child = next;
1345 LayoutObject* nextSibling = child->nextSibling(); 1419 LayoutObject* nextSibling = child->nextSibling();
1346 CHECK(!nextSibling || nextSibling->isBox()); 1420 CHECK(!nextSibling || nextSibling->isBox());
1347 next = toLayoutBox(nextSibling); 1421 next = toLayoutBox(nextSibling);
1348 1422
1349 child->setMayNeedPaintInvalidation(); 1423 child->setMayNeedPaintInvalidation();
1350 1424
1351 if (childToExclude == child) 1425 if (childToExclude == child)
1352 continue; // Skip this child, since it will be positioned by the speciali zed subclass (ruby runs). 1426 continue; // Skip this child, since it will be positioned by the
1427 // specialized subclass (ruby runs).
1353 1428
1354 updateBlockChildDirtyBitsBeforeLayout(relayoutChildren, *child); 1429 updateBlockChildDirtyBitsBeforeLayout(relayoutChildren, *child);
1355 1430
1356 if (child->isOutOfFlowPositioned()) { 1431 if (child->isOutOfFlowPositioned()) {
1357 child->containingBlock()->insertPositionedObject(child); 1432 child->containingBlock()->insertPositionedObject(child);
1358 adjustPositionedBlock(*child, layoutInfo); 1433 adjustPositionedBlock(*child, layoutInfo);
1359 continue; 1434 continue;
1360 } 1435 }
1361 if (child->isFloating()) { 1436 if (child->isFloating()) {
1362 insertFloatingObject(*child); 1437 insertFloatingObject(*child);
1363 adjustFloatingBlock(marginInfo); 1438 adjustFloatingBlock(marginInfo);
1364 continue; 1439 continue;
1365 } 1440 }
1366 if (child->isColumnSpanAll()) { 1441 if (child->isColumnSpanAll()) {
1367 // This is not the containing block of the spanner. The spanner's placehol der will lay 1442 // This is not the containing block of the spanner. The spanner's
1368 // it out in due course. For now we just need to consult our flow thread, so that the 1443 // placeholder will lay it out in due course. For now we just need to
1369 // columns (if any) preceding and following the spanner are laid out corre ctly. But 1444 // consult our flow thread, so that the columns (if any) preceding and
1370 // first we apply the pending margin, so that it's taken into consideratio n and doesn't 1445 // following the spanner are laid out correctly. But first we apply the
1371 // end up on the other side of the spanner. 1446 // pending margin, so that it's taken into consideration and doesn't end
1447 // up on the other side of the spanner.
1372 setLogicalHeight(logicalHeight() + marginInfo.margin()); 1448 setLogicalHeight(logicalHeight() + marginInfo.margin());
1373 marginInfo.clearMargin(); 1449 marginInfo.clearMargin();
1374 1450
1375 child->spannerPlaceholder()->flowThread()->skipColumnSpanner( 1451 child->spannerPlaceholder()->flowThread()->skipColumnSpanner(
1376 child, offsetFromLogicalTopOfFirstPage() + logicalHeight()); 1452 child, offsetFromLogicalTopOfFirstPage() + logicalHeight());
1377 continue; 1453 continue;
1378 } 1454 }
1379 1455
1380 // Lay out the child. 1456 // Lay out the child.
1381 layoutBlockChild(*child, layoutInfo); 1457 layoutBlockChild(*child, layoutInfo);
1382 layoutInfo.clearIsAtFirstInFlowChild(); 1458 layoutInfo.clearIsAtFirstInFlowChild();
1383 lastNormalFlowChild = child; 1459 lastNormalFlowChild = child;
1384 } 1460 }
1385 1461
1386 // Now do the handling of the bottom of the block, adding in our bottom border /padding and 1462 // Now do the handling of the bottom of the block, adding in our bottom
1387 // determining the correct collapsed bottom margin information. 1463 // border/padding and determining the correct collapsed bottom margin
1464 // information.
1388 handleAfterSideOfBlock(lastNormalFlowChild, beforeEdge, afterEdge, 1465 handleAfterSideOfBlock(lastNormalFlowChild, beforeEdge, afterEdge,
1389 marginInfo); 1466 marginInfo);
1390 } 1467 }
1391 1468
1392 // Our MarginInfo state used when laying out block children. 1469 // Our MarginInfo state used when laying out block children.
1393 MarginInfo::MarginInfo(LayoutBlockFlow* blockFlow, 1470 MarginInfo::MarginInfo(LayoutBlockFlow* blockFlow,
1394 LayoutUnit beforeBorderPadding, 1471 LayoutUnit beforeBorderPadding,
1395 LayoutUnit afterBorderPadding) 1472 LayoutUnit afterBorderPadding)
1396 : m_canCollapseMarginAfterWithLastChild(true), 1473 : m_canCollapseMarginAfterWithLastChild(true),
1397 m_atBeforeSideOfBlock(true), 1474 m_atBeforeSideOfBlock(true),
1398 m_atAfterSideOfBlock(false), 1475 m_atAfterSideOfBlock(false),
1399 m_hasMarginBeforeQuirk(false), 1476 m_hasMarginBeforeQuirk(false),
1400 m_hasMarginAfterQuirk(false), 1477 m_hasMarginAfterQuirk(false),
1401 m_determinedMarginBeforeQuirk(false), 1478 m_determinedMarginBeforeQuirk(false),
1402 m_discardMargin(false), 1479 m_discardMargin(false),
1403 m_lastChildIsSelfCollapsingBlockWithClearance(false) { 1480 m_lastChildIsSelfCollapsingBlockWithClearance(false) {
1404 const ComputedStyle& blockStyle = blockFlow->styleRef(); 1481 const ComputedStyle& blockStyle = blockFlow->styleRef();
1405 ASSERT(blockFlow->isLayoutView() || blockFlow->parent()); 1482 ASSERT(blockFlow->isLayoutView() || blockFlow->parent());
1406 m_canCollapseWithChildren = !blockFlow->createsNewFormattingContext() && 1483 m_canCollapseWithChildren = !blockFlow->createsNewFormattingContext() &&
1407 !blockFlow->isLayoutFlowThread() && 1484 !blockFlow->isLayoutFlowThread() &&
1408 !blockFlow->isLayoutView(); 1485 !blockFlow->isLayoutView();
1409 1486
1410 m_canCollapseMarginBeforeWithChildren = 1487 m_canCollapseMarginBeforeWithChildren =
1411 m_canCollapseWithChildren && !beforeBorderPadding && 1488 m_canCollapseWithChildren && !beforeBorderPadding &&
1412 blockStyle.marginBeforeCollapse() != MarginCollapseSeparate; 1489 blockStyle.marginBeforeCollapse() != MarginCollapseSeparate;
1413 1490
1414 // If any height other than auto is specified in CSS, then we don't collapse o ur bottom 1491 // If any height other than auto is specified in CSS, then we don't collapse
1415 // margins with our children's margins. To do otherwise would be to risk odd v isual 1492 // our bottom margins with our children's margins. To do otherwise would be to
1416 // effects when the children overflow out of the parent block and yet still co llapse 1493 // risk odd visual effects when the children overflow out of the parent block
1417 // with it. We also don't collapse if we have any bottom border/padding. 1494 // and yet still collapse with it. We also don't collapse if we have any
1495 // bottom border/padding.
1418 m_canCollapseMarginAfterWithChildren = 1496 m_canCollapseMarginAfterWithChildren =
1419 m_canCollapseWithChildren && !afterBorderPadding && 1497 m_canCollapseWithChildren && !afterBorderPadding &&
1420 (blockStyle.logicalHeight().isAuto() && 1498 (blockStyle.logicalHeight().isAuto() &&
1421 !blockStyle.logicalHeight().value()) && 1499 !blockStyle.logicalHeight().value()) &&
1422 blockStyle.marginAfterCollapse() != MarginCollapseSeparate; 1500 blockStyle.marginAfterCollapse() != MarginCollapseSeparate;
1423 1501
1424 m_quirkContainer = blockFlow->isTableCell() || blockFlow->isBody(); 1502 m_quirkContainer = blockFlow->isTableCell() || blockFlow->isBody();
1425 1503
1426 m_discardMargin = m_canCollapseMarginBeforeWithChildren && 1504 m_discardMargin = m_canCollapseMarginBeforeWithChildren &&
1427 blockFlow->mustDiscardMarginBefore(); 1505 blockFlow->mustDiscardMarginBefore();
(...skipping 14 matching lines...) Expand all
1442 LayoutUnit childBeforeNegative; 1520 LayoutUnit childBeforeNegative;
1443 LayoutUnit childAfterPositive; 1521 LayoutUnit childAfterPositive;
1444 LayoutUnit childAfterNegative; 1522 LayoutUnit childAfterNegative;
1445 1523
1446 LayoutUnit beforeMargin; 1524 LayoutUnit beforeMargin;
1447 LayoutUnit afterMargin; 1525 LayoutUnit afterMargin;
1448 1526
1449 LayoutBlockFlow* childLayoutBlockFlow = 1527 LayoutBlockFlow* childLayoutBlockFlow =
1450 child.isLayoutBlockFlow() ? toLayoutBlockFlow(&child) : 0; 1528 child.isLayoutBlockFlow() ? toLayoutBlockFlow(&child) : 0;
1451 1529
1452 // If the child has the same directionality as we do, then we can just return its 1530 // If the child has the same directionality as we do, then we can just return
1453 // margins in the same direction. 1531 // its margins in the same direction.
1454 if (!child.isWritingModeRoot()) { 1532 if (!child.isWritingModeRoot()) {
1455 if (childLayoutBlockFlow) { 1533 if (childLayoutBlockFlow) {
1456 childBeforePositive = childLayoutBlockFlow->maxPositiveMarginBefore(); 1534 childBeforePositive = childLayoutBlockFlow->maxPositiveMarginBefore();
1457 childBeforeNegative = childLayoutBlockFlow->maxNegativeMarginBefore(); 1535 childBeforeNegative = childLayoutBlockFlow->maxNegativeMarginBefore();
1458 childAfterPositive = childLayoutBlockFlow->maxPositiveMarginAfter(); 1536 childAfterPositive = childLayoutBlockFlow->maxPositiveMarginAfter();
1459 childAfterNegative = childLayoutBlockFlow->maxNegativeMarginAfter(); 1537 childAfterNegative = childLayoutBlockFlow->maxNegativeMarginAfter();
1460 } else { 1538 } else {
1461 beforeMargin = child.marginBefore(); 1539 beforeMargin = child.marginBefore();
1462 afterMargin = child.marginAfter(); 1540 afterMargin = child.marginAfter();
1463 } 1541 }
1464 } else if (child.isHorizontalWritingMode() == isHorizontalWritingMode()) { 1542 } else if (child.isHorizontalWritingMode() == isHorizontalWritingMode()) {
1465 // The child has a different directionality. If the child is parallel, then it's just 1543 // The child has a different directionality. If the child is parallel, then
1466 // flipped relative to us. We can use the margins for the opposite edges. 1544 // it's just flipped relative to us. We can use the margins for the opposite
1545 // edges.
1467 if (childLayoutBlockFlow) { 1546 if (childLayoutBlockFlow) {
1468 childBeforePositive = childLayoutBlockFlow->maxPositiveMarginAfter(); 1547 childBeforePositive = childLayoutBlockFlow->maxPositiveMarginAfter();
1469 childBeforeNegative = childLayoutBlockFlow->maxNegativeMarginAfter(); 1548 childBeforeNegative = childLayoutBlockFlow->maxNegativeMarginAfter();
1470 childAfterPositive = childLayoutBlockFlow->maxPositiveMarginBefore(); 1549 childAfterPositive = childLayoutBlockFlow->maxPositiveMarginBefore();
1471 childAfterNegative = childLayoutBlockFlow->maxNegativeMarginBefore(); 1550 childAfterNegative = childLayoutBlockFlow->maxNegativeMarginBefore();
1472 } else { 1551 } else {
1473 beforeMargin = child.marginAfter(); 1552 beforeMargin = child.marginAfter();
1474 afterMargin = child.marginBefore(); 1553 afterMargin = child.marginBefore();
1475 } 1554 }
1476 } else { 1555 } else {
1477 // The child is perpendicular to us, which means its margins don't collapse but are on the 1556 // The child is perpendicular to us, which means its margins don't collapse
1478 // "logical left/right" sides of the child box. We can just return the raw m argin in this case. 1557 // but are on the "logical left/right" sides of the child box. We can just
1558 // return the raw margin in this case.
1479 beforeMargin = marginBeforeForChild(child); 1559 beforeMargin = marginBeforeForChild(child);
1480 afterMargin = marginAfterForChild(child); 1560 afterMargin = marginAfterForChild(child);
1481 } 1561 }
1482 1562
1483 // Resolve uncollapsing margins into their positive/negative buckets. 1563 // Resolve uncollapsing margins into their positive/negative buckets.
1484 if (beforeMargin) { 1564 if (beforeMargin) {
1485 if (beforeMargin > 0) 1565 if (beforeMargin > 0)
1486 childBeforePositive = beforeMargin; 1566 childBeforePositive = beforeMargin;
1487 else 1567 else
1488 childBeforeNegative = -beforeMargin; 1568 childBeforeNegative = -beforeMargin;
1489 } 1569 }
1490 if (afterMargin) { 1570 if (afterMargin) {
1491 if (afterMargin > 0) 1571 if (afterMargin > 0)
1492 childAfterPositive = afterMargin; 1572 childAfterPositive = afterMargin;
1493 else 1573 else
1494 childAfterNegative = -afterMargin; 1574 childAfterNegative = -afterMargin;
1495 } 1575 }
1496 1576
1497 return LayoutBlockFlow::MarginValues(childBeforePositive, childBeforeNegative, 1577 return LayoutBlockFlow::MarginValues(childBeforePositive, childBeforeNegative,
1498 childAfterPositive, childAfterNegative); 1578 childAfterPositive, childAfterNegative);
1499 } 1579 }
1500 1580
1501 LayoutUnit LayoutBlockFlow::collapseMargins(LayoutBox& child, 1581 LayoutUnit LayoutBlockFlow::collapseMargins(LayoutBox& child,
1502 MarginInfo& marginInfo, 1582 MarginInfo& marginInfo,
1503 bool childIsSelfCollapsing, 1583 bool childIsSelfCollapsing,
1504 bool childDiscardMarginBefore, 1584 bool childDiscardMarginBefore,
1505 bool childDiscardMarginAfter) { 1585 bool childDiscardMarginAfter) {
1506 // The child discards the before margin when the the after margin has discard in the case of a self collapsing block. 1586 // The child discards the before margin when the the after margin has discard
1587 // in the case of a self collapsing block.
1507 childDiscardMarginBefore = childDiscardMarginBefore || 1588 childDiscardMarginBefore = childDiscardMarginBefore ||
1508 (childDiscardMarginAfter && childIsSelfCollapsing); 1589 (childDiscardMarginAfter && childIsSelfCollapsing);
1509 1590
1510 // Get the four margin values for the child and cache them. 1591 // Get the four margin values for the child and cache them.
1511 const LayoutBlockFlow::MarginValues childMargins = 1592 const LayoutBlockFlow::MarginValues childMargins =
1512 marginValuesForChild(child); 1593 marginValuesForChild(child);
1513 1594
1514 // Get our max pos and neg top margins. 1595 // Get our max pos and neg top margins.
1515 LayoutUnit posTop = childMargins.positiveMarginBefore(); 1596 LayoutUnit posTop = childMargins.positiveMarginBefore();
1516 LayoutUnit negTop = childMargins.negativeMarginBefore(); 1597 LayoutUnit negTop = childMargins.negativeMarginBefore();
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1549 if (!marginInfo.determinedMarginBeforeQuirk() && topQuirk && 1630 if (!marginInfo.determinedMarginBeforeQuirk() && topQuirk &&
1550 !marginBefore()) { 1631 !marginBefore()) {
1551 // We have no top margin and our top child has a quirky margin. 1632 // We have no top margin and our top child has a quirky margin.
1552 // We will pick up this quirky margin and pass it through. 1633 // We will pick up this quirky margin and pass it through.
1553 // This deals with the <td><div><p> case. 1634 // This deals with the <td><div><p> case.
1554 // Don't do this for a block that split two inlines though. You do 1635 // Don't do this for a block that split two inlines though. You do
1555 // still apply margins in this case. 1636 // still apply margins in this case.
1556 setHasMarginBeforeQuirk(true); 1637 setHasMarginBeforeQuirk(true);
1557 } 1638 }
1558 } else { 1639 } else {
1559 // The before margin of the container will also discard all the margins it is collapsing with. 1640 // The before margin of the container will also discard all the margins it
1641 // is collapsing with.
1560 setMustDiscardMarginBefore(); 1642 setMustDiscardMarginBefore();
1561 } 1643 }
1562 } 1644 }
1563 1645
1564 // Once we find a child with discardMarginBefore all the margins collapsing wi th us must also discard. 1646 // Once we find a child with discardMarginBefore all the margins collapsing
1647 // with us must also discard.
1565 if (childDiscardMarginBefore) { 1648 if (childDiscardMarginBefore) {
1566 marginInfo.setDiscardMargin(true); 1649 marginInfo.setDiscardMargin(true);
1567 marginInfo.clearMargin(); 1650 marginInfo.clearMargin();
1568 } 1651 }
1569 1652
1570 if (marginInfo.quirkContainer() && marginInfo.atBeforeSideOfBlock() && 1653 if (marginInfo.quirkContainer() && marginInfo.atBeforeSideOfBlock() &&
1571 (posTop - negTop)) 1654 (posTop - negTop))
1572 marginInfo.setHasMarginBeforeQuirk(topQuirk); 1655 marginInfo.setHasMarginBeforeQuirk(topQuirk);
1573 1656
1574 LayoutUnit beforeCollapseLogicalTop = logicalHeight(); 1657 LayoutUnit beforeCollapseLogicalTop = logicalHeight();
1575 LayoutUnit logicalTop = beforeCollapseLogicalTop; 1658 LayoutUnit logicalTop = beforeCollapseLogicalTop;
1576 1659
1577 LayoutObject* prev = child.previousSibling(); 1660 LayoutObject* prev = child.previousSibling();
1578 LayoutBlockFlow* previousBlockFlow = 1661 LayoutBlockFlow* previousBlockFlow =
1579 prev && prev->isLayoutBlockFlow() && 1662 prev && prev->isLayoutBlockFlow() &&
1580 !prev->isFloatingOrOutOfFlowPositioned() 1663 !prev->isFloatingOrOutOfFlowPositioned()
1581 ? toLayoutBlockFlow(prev) 1664 ? toLayoutBlockFlow(prev)
1582 : 0; 1665 : 0;
1583 // If the child's previous sibling is a self-collapsing block that cleared a f loat then its top border edge has been set at the bottom border edge 1666 // If the child's previous sibling is a self-collapsing block that cleared a
1584 // of the float. Since we want to collapse the child's top margin with the sel f-collapsing block's top and bottom margins we need to adjust our parent's heigh t to match the 1667 // float then its top border edge has been set at the bottom border edge of
1585 // margin top of the self-collapsing block. If the resulting collapsed margin leaves the child still intruding into the float then we will want to clear it. 1668 // the float. Since we want to collapse the child's top margin with the self-
1669 // collapsing block's top and bottom margins we need to adjust our parent's
1670 // height to match the margin top of the self-collapsing block. If the
1671 // resulting collapsed margin leaves the child still intruding into the float
1672 // then we will want to clear it.
1586 if (!marginInfo.canCollapseWithMarginBefore() && previousBlockFlow && 1673 if (!marginInfo.canCollapseWithMarginBefore() && previousBlockFlow &&
1587 marginInfo.lastChildIsSelfCollapsingBlockWithClearance()) 1674 marginInfo.lastChildIsSelfCollapsingBlockWithClearance())
1588 setLogicalHeight( 1675 setLogicalHeight(
1589 logicalHeight() - 1676 logicalHeight() -
1590 marginValuesForChild(*previousBlockFlow).positiveMarginBefore()); 1677 marginValuesForChild(*previousBlockFlow).positiveMarginBefore());
1591 1678
1592 if (childIsSelfCollapsing) { 1679 if (childIsSelfCollapsing) {
1593 // For a self collapsing block both the before and after margins get discard ed. The block doesn't contribute anything to the height of the block. 1680 // For a self collapsing block both the before and after margins get
1594 // Also, the child's top position equals the logical height of the container . 1681 // discarded. The block doesn't contribute anything to the height of the
1682 // block. Also, the child's top position equals the logical height of the
1683 // container.
1595 if (!childDiscardMarginBefore && !marginInfo.discardMargin()) { 1684 if (!childDiscardMarginBefore && !marginInfo.discardMargin()) {
1596 // This child has no height. We need to compute our 1685 // This child has no height. We need to compute our
1597 // position before we collapse the child's margins together, 1686 // position before we collapse the child's margins together,
1598 // so that we can get an accurate position for the zero-height block. 1687 // so that we can get an accurate position for the zero-height block.
1599 LayoutUnit collapsedBeforePos = std::max( 1688 LayoutUnit collapsedBeforePos = std::max(
1600 marginInfo.positiveMargin(), childMargins.positiveMarginBefore()); 1689 marginInfo.positiveMargin(), childMargins.positiveMarginBefore());
1601 LayoutUnit collapsedBeforeNeg = std::max( 1690 LayoutUnit collapsedBeforeNeg = std::max(
1602 marginInfo.negativeMargin(), childMargins.negativeMarginBefore()); 1691 marginInfo.negativeMargin(), childMargins.negativeMarginBefore());
1603 marginInfo.setMargin(collapsedBeforePos, collapsedBeforeNeg); 1692 marginInfo.setMargin(collapsedBeforePos, collapsedBeforeNeg);
1604 1693
1605 // Now collapse the child's margins together, which means examining our 1694 // Now collapse the child's margins together, which means examining our
1606 // bottom margin values as well. 1695 // bottom margin values as well.
1607 marginInfo.setPositiveMarginIfLarger(childMargins.positiveMarginAfter()); 1696 marginInfo.setPositiveMarginIfLarger(childMargins.positiveMarginAfter());
1608 marginInfo.setNegativeMarginIfLarger(childMargins.negativeMarginAfter()); 1697 marginInfo.setNegativeMarginIfLarger(childMargins.negativeMarginAfter());
1609 1698
1610 if (!marginInfo.canCollapseWithMarginBefore()) { 1699 if (!marginInfo.canCollapseWithMarginBefore()) {
1611 // We need to make sure that the position of the self-collapsing block 1700 // We need to make sure that the position of the self-collapsing block
1612 // is correct, since it could have overflowing content 1701 // is correct, since it could have overflowing content
1613 // that needs to be positioned correctly (e.g., a block that 1702 // that needs to be positioned correctly (e.g., a block that
1614 // had a specified height of 0 but that actually had subcontent). 1703 // had a specified height of 0 but that actually had subcontent).
1615 logicalTop = logicalHeight() + collapsedBeforePos - collapsedBeforeNeg; 1704 logicalTop = logicalHeight() + collapsedBeforePos - collapsedBeforeNeg;
1616 } 1705 }
1617 } 1706 }
1618 } else { 1707 } else {
1619 if (mustSeparateMarginBeforeForChild(child)) { 1708 if (mustSeparateMarginBeforeForChild(child)) {
1620 ASSERT(!marginInfo.discardMargin() || 1709 ASSERT(!marginInfo.discardMargin() ||
1621 (marginInfo.discardMargin() && !marginInfo.margin())); 1710 (marginInfo.discardMargin() && !marginInfo.margin()));
1622 // If we are at the before side of the block and we collapse, ignore the c omputed margin 1711 // If we are at the before side of the block and we collapse, ignore the
1623 // and just add the child margin to the container height. This will correc tly position 1712 // computed margin and just add the child margin to the container height.
1624 // the child inside the container. 1713 // This will correctly position the child inside the container.
1625 LayoutUnit separateMargin = !marginInfo.canCollapseWithMarginBefore() 1714 LayoutUnit separateMargin = !marginInfo.canCollapseWithMarginBefore()
1626 ? marginInfo.margin() 1715 ? marginInfo.margin()
1627 : LayoutUnit(); 1716 : LayoutUnit();
1628 setLogicalHeight(logicalHeight() + separateMargin + 1717 setLogicalHeight(logicalHeight() + separateMargin +
1629 marginBeforeForChild(child)); 1718 marginBeforeForChild(child));
1630 logicalTop = logicalHeight(); 1719 logicalTop = logicalHeight();
1631 } else if (!marginInfo.discardMargin() && 1720 } else if (!marginInfo.discardMargin() &&
1632 (!marginInfo.atBeforeSideOfBlock() || 1721 (!marginInfo.atBeforeSideOfBlock() ||
1633 (!marginInfo.canCollapseMarginBeforeWithChildren() && 1722 (!marginInfo.canCollapseMarginBeforeWithChildren() &&
1634 (!document().inQuirksMode() || !marginInfo.quirkContainer() || 1723 (!document().inQuirksMode() || !marginInfo.quirkContainer() ||
(...skipping 12 matching lines...) Expand all
1647 marginInfo.setPositiveMargin(childMargins.positiveMarginAfter()); 1736 marginInfo.setPositiveMargin(childMargins.positiveMarginAfter());
1648 marginInfo.setNegativeMargin(childMargins.negativeMarginAfter()); 1737 marginInfo.setNegativeMargin(childMargins.negativeMarginAfter());
1649 } else { 1738 } else {
1650 marginInfo.clearMargin(); 1739 marginInfo.clearMargin();
1651 } 1740 }
1652 1741
1653 if (marginInfo.margin()) 1742 if (marginInfo.margin())
1654 marginInfo.setHasMarginAfterQuirk(hasMarginAfterQuirk(&child)); 1743 marginInfo.setHasMarginAfterQuirk(hasMarginAfterQuirk(&child));
1655 } 1744 }
1656 1745
1657 // If margins would pull us past the top of the next page, then we need to pul l back and pretend like the margins 1746 // If margins would pull us past the top of the next page, then we need to
1658 // collapsed into the page edge. 1747 // pull back and pretend like the margins collapsed into the page edge.
1659 LayoutState* layoutState = view()->layoutState(); 1748 LayoutState* layoutState = view()->layoutState();
1660 if (layoutState->isPaginated() && 1749 if (layoutState->isPaginated() &&
1661 isPageLogicalHeightKnown(beforeCollapseLogicalTop) && 1750 isPageLogicalHeightKnown(beforeCollapseLogicalTop) &&
1662 logicalTop > beforeCollapseLogicalTop) { 1751 logicalTop > beforeCollapseLogicalTop) {
1663 LayoutUnit oldLogicalTop = logicalTop; 1752 LayoutUnit oldLogicalTop = logicalTop;
1664 logicalTop = 1753 logicalTop =
1665 std::min(logicalTop, nextPageLogicalTop(beforeCollapseLogicalTop)); 1754 std::min(logicalTop, nextPageLogicalTop(beforeCollapseLogicalTop));
1666 setLogicalHeight(logicalHeight() + (logicalTop - oldLogicalTop)); 1755 setLogicalHeight(logicalHeight() + (logicalTop - oldLogicalTop));
1667 } 1756 }
1668 1757
1669 if (previousBlockFlow) { 1758 if (previousBlockFlow) {
1670 // If |child| is a self-collapsing block it may have collapsed into a previo us sibling and although it hasn't reduced the height of the parent yet 1759 // If |child| is a self-collapsing block it may have collapsed into a
1671 // any floats from the parent will now overhang. 1760 // previous sibling and although it hasn't reduced the height of the parent
1761 // yet any floats from the parent will now overhang.
1672 LayoutUnit oldLogicalHeight = logicalHeight(); 1762 LayoutUnit oldLogicalHeight = logicalHeight();
1673 setLogicalHeight(logicalTop); 1763 setLogicalHeight(logicalTop);
1674 if (!previousBlockFlow->avoidsFloats() && 1764 if (!previousBlockFlow->avoidsFloats() &&
1675 (previousBlockFlow->logicalTop() + 1765 (previousBlockFlow->logicalTop() +
1676 previousBlockFlow->lowestFloatLogicalBottom()) > logicalTop) 1766 previousBlockFlow->lowestFloatLogicalBottom()) > logicalTop)
1677 addOverhangingFloats(previousBlockFlow, false); 1767 addOverhangingFloats(previousBlockFlow, false);
1678 setLogicalHeight(oldLogicalHeight); 1768 setLogicalHeight(oldLogicalHeight);
1679 1769
1680 // If |child|'s previous sibling is or contains a self-collapsing block that cleared a float and margin collapsing resulted in |child| moving up 1770 // If |child|'s previous sibling is or contains a self-collapsing block that
1681 // into the margin area of the self-collapsing block then the float it clear s is now intruding into |child|. Layout again so that we can look for 1771 // cleared a float and margin collapsing resulted in |child| moving up
1682 // floats in the parent that overhang |child|'s new logical top. 1772 // into the margin area of the self-collapsing block then the float it
1773 // clears is now intruding into |child|. Layout again so that we can look
1774 // for floats in the parent that overhang |child|'s new logical top.
1683 bool logicalTopIntrudesIntoFloat = logicalTop < beforeCollapseLogicalTop; 1775 bool logicalTopIntrudesIntoFloat = logicalTop < beforeCollapseLogicalTop;
1684 if (logicalTopIntrudesIntoFloat && containsFloats() && 1776 if (logicalTopIntrudesIntoFloat && containsFloats() &&
1685 !child.avoidsFloats() && lowestFloatLogicalBottom() > logicalTop) 1777 !child.avoidsFloats() && lowestFloatLogicalBottom() > logicalTop)
1686 child.setNeedsLayoutAndFullPaintInvalidation( 1778 child.setNeedsLayoutAndFullPaintInvalidation(
1687 LayoutInvalidationReason::AncestorMarginCollapsing); 1779 LayoutInvalidationReason::AncestorMarginCollapsing);
1688 } 1780 }
1689 1781
1690 return logicalTop; 1782 return logicalTop;
1691 } 1783 }
1692 1784
1693 void LayoutBlockFlow::adjustPositionedBlock( 1785 void LayoutBlockFlow::adjustPositionedBlock(
1694 LayoutBox& child, 1786 LayoutBox& child,
1695 const BlockChildrenLayoutInfo& layoutInfo) { 1787 const BlockChildrenLayoutInfo& layoutInfo) {
1696 LayoutUnit logicalTop = logicalHeight(); 1788 LayoutUnit logicalTop = logicalHeight();
1697 1789
1698 // Forced breaks are only specified on in-flow objects, but auto-positioned ou t-of-flow objects 1790 // Forced breaks are only specified on in-flow objects, but auto-positioned
1699 // may be affected by a break-after value of the previous in-flow object. 1791 // out-of-flow objects may be affected by a break-after value of the previous
1792 // in-flow object.
1700 if (view()->layoutState()->isPaginated()) 1793 if (view()->layoutState()->isPaginated())
1701 logicalTop = 1794 logicalTop =
1702 applyForcedBreak(logicalTop, layoutInfo.previousBreakAfterValue()); 1795 applyForcedBreak(logicalTop, layoutInfo.previousBreakAfterValue());
1703 1796
1704 updateStaticInlinePositionForChild(child, logicalTop); 1797 updateStaticInlinePositionForChild(child, logicalTop);
1705 1798
1706 const MarginInfo& marginInfo = layoutInfo.marginInfo(); 1799 const MarginInfo& marginInfo = layoutInfo.marginInfo();
1707 if (!marginInfo.canCollapseWithMarginBefore()) { 1800 if (!marginInfo.canCollapseWithMarginBefore()) {
1708 // Positioned blocks don't collapse margins, so add the margin provided by 1801 // Positioned blocks don't collapse margins, so add the margin provided by
1709 // the container now. The child's own margin is added later when calculating its logical top. 1802 // the container now. The child's own margin is added later when calculating
1803 // its logical top.
1710 LayoutUnit collapsedBeforePos = marginInfo.positiveMargin(); 1804 LayoutUnit collapsedBeforePos = marginInfo.positiveMargin();
1711 LayoutUnit collapsedBeforeNeg = marginInfo.negativeMargin(); 1805 LayoutUnit collapsedBeforeNeg = marginInfo.negativeMargin();
1712 logicalTop += collapsedBeforePos - collapsedBeforeNeg; 1806 logicalTop += collapsedBeforePos - collapsedBeforeNeg;
1713 } 1807 }
1714 1808
1715 PaintLayer* childLayer = child.layer(); 1809 PaintLayer* childLayer = child.layer();
1716 if (childLayer->staticBlockPosition() != logicalTop) 1810 if (childLayer->staticBlockPosition() != logicalTop)
1717 childLayer->setStaticBlockPosition(logicalTop); 1811 childLayer->setStaticBlockPosition(logicalTop);
1718 } 1812 }
1719 1813
(...skipping 10 matching lines...) Expand all
1730 if (!heightIncrease) 1824 if (!heightIncrease)
1731 return yPos; 1825 return yPos;
1732 1826
1733 if (childIsSelfCollapsing) { 1827 if (childIsSelfCollapsing) {
1734 marginInfo.setLastChildIsSelfCollapsingBlockWithClearance(true); 1828 marginInfo.setLastChildIsSelfCollapsingBlockWithClearance(true);
1735 marginInfo.setDiscardMargin(childDiscardMargin); 1829 marginInfo.setDiscardMargin(childDiscardMargin);
1736 1830
1737 // For self-collapsing blocks that clear, they can still collapse their 1831 // For self-collapsing blocks that clear, they can still collapse their
1738 // margins with following siblings. Reset the current margins to represent 1832 // margins with following siblings. Reset the current margins to represent
1739 // the self-collapsing block's margins only. 1833 // the self-collapsing block's margins only.
1740 // If DISCARD is specified for -webkit-margin-collapse, reset the margin val ues. 1834 // If DISCARD is specified for -webkit-margin-collapse, reset the margin
1835 // values.
1741 LayoutBlockFlow::MarginValues childMargins = marginValuesForChild(child); 1836 LayoutBlockFlow::MarginValues childMargins = marginValuesForChild(child);
1742 if (!childDiscardMargin) { 1837 if (!childDiscardMargin) {
1743 marginInfo.setPositiveMargin( 1838 marginInfo.setPositiveMargin(
1744 std::max(childMargins.positiveMarginBefore(), 1839 std::max(childMargins.positiveMarginBefore(),
1745 childMargins.positiveMarginAfter())); 1840 childMargins.positiveMarginAfter()));
1746 marginInfo.setNegativeMargin( 1841 marginInfo.setNegativeMargin(
1747 std::max(childMargins.negativeMarginBefore(), 1842 std::max(childMargins.negativeMarginBefore(),
1748 childMargins.negativeMarginAfter())); 1843 childMargins.negativeMarginAfter()));
1749 } else { 1844 } else {
1750 marginInfo.clearMargin(); 1845 marginInfo.clearMargin();
1751 } 1846 }
1752 1847
1753 // CSS2.1 states: 1848 // CSS2.1 states:
1754 // "If the top and bottom margins of an element with clearance are adjoining , its margins collapse with 1849 // "If the top and bottom margins of an element with clearance are
1755 // the adjoining margins of following siblings but that resulting margin doe s not collapse with the bottom margin of the parent block." 1850 // adjoining, its margins collapse with the adjoining margins of following
1756 // So the parent's bottom margin cannot collapse through this block or any s ubsequent self-collapsing blocks. Set a bit to ensure 1851 // siblings but that resulting margin does not collapse with the bottom
1757 // this happens; it will get reset if we encounter an in-flow sibling that i s not self-collapsing. 1852 // margin of the parent block."
1853 // So the parent's bottom margin cannot collapse through this block or any
1854 // subsequent self-collapsing blocks. Set a bit to ensure this happens; it
1855 // will get reset if we encounter an in-flow sibling that is not
1856 // self-collapsing.
1758 marginInfo.setCanCollapseMarginAfterWithLastChild(false); 1857 marginInfo.setCanCollapseMarginAfterWithLastChild(false);
1759 1858
1760 // For now set the border-top of |child| flush with the bottom border-edge o f the float so it can layout any floating or positioned children of 1859 // For now set the border-top of |child| flush with the bottom border-edge
1761 // its own at the correct vertical position. If subsequent siblings attempt to collapse with |child|'s margins in |collapseMargins| we will 1860 // of the float so it can layout any floating or positioned children of its
1762 // adjust the height of the parent to |child|'s margin top (which if it is p ositive sits up 'inside' the float it's clearing) so that all three 1861 // own at the correct vertical position. If subsequent siblings attempt to
1763 // margins can collapse at the correct vertical position. 1862 // collapse with |child|'s margins in |collapseMargins| we will adjust the
1764 // Per CSS2.1 we need to ensure that any negative margin-top clears |child| beyond the bottom border-edge of the float so that the top border edge of the ch ild 1863 // height of the parent to |child|'s margin top (which if it is positive
1765 // (i.e. its clearance) is at a position that satisfies the equation: "the amount of clearance is set so that clearance + margin-top = [height of float], 1864 // sits up 'inside' the float it's clearing) so that all three margins can
1865 // collapse at the correct vertical position.
1866 // Per CSS2.1 we need to ensure that any negative margin-top clears |child|
1867 // beyond the bottom border-edge of the float so that the top border edge of
1868 // the child (i.e. its clearance) is at a position that satisfies the
1869 // equation: "the amount of clearance is set so that:
1870 // clearance + margin-top = [height of float],
1766 // i.e., clearance = [height of float] - margin-top". 1871 // i.e., clearance = [height of float] - margin-top".
1767 setLogicalHeight(child.logicalTop() + childMargins.negativeMarginBefore()); 1872 setLogicalHeight(child.logicalTop() + childMargins.negativeMarginBefore());
1768 } else { 1873 } else {
1769 // Increase our height by the amount we had to clear. 1874 // Increase our height by the amount we had to clear.
1770 setLogicalHeight(logicalHeight() + heightIncrease); 1875 setLogicalHeight(logicalHeight() + heightIncrease);
1771 } 1876 }
1772 1877
1773 if (marginInfo.canCollapseWithMarginBefore()) { 1878 if (marginInfo.canCollapseWithMarginBefore()) {
1774 // We can no longer collapse with the top of the block since a clear 1879 // We can no longer collapse with the top of the block since a clear
1775 // occurred. The empty blocks collapse into the cleared block. 1880 // occurred. The empty blocks collapse into the cleared block.
1776 setMaxMarginBeforeValues(oldTopPosMargin, oldTopNegMargin); 1881 setMaxMarginBeforeValues(oldTopPosMargin, oldTopNegMargin);
1777 marginInfo.setAtBeforeSideOfBlock(false); 1882 marginInfo.setAtBeforeSideOfBlock(false);
1778 1883
1779 // In case the child discarded the before margin of the block we need to res et the mustDiscardMarginBefore flag to the initial value. 1884 // In case the child discarded the before margin of the block we need to
1885 // reset the mustDiscardMarginBefore flag to the initial value.
1780 setMustDiscardMarginBefore(style()->marginBeforeCollapse() == 1886 setMustDiscardMarginBefore(style()->marginBeforeCollapse() ==
1781 MarginCollapseDiscard); 1887 MarginCollapseDiscard);
1782 } 1888 }
1783 1889
1784 return yPos + heightIncrease; 1890 return yPos + heightIncrease;
1785 } 1891 }
1786 1892
1787 void LayoutBlockFlow::setCollapsedBottomMargin(const MarginInfo& marginInfo) { 1893 void LayoutBlockFlow::setCollapsedBottomMargin(const MarginInfo& marginInfo) {
1788 if (marginInfo.canCollapseWithMarginAfter() && 1894 if (marginInfo.canCollapseWithMarginAfter() &&
1789 !marginInfo.canCollapseWithMarginBefore()) { 1895 !marginInfo.canCollapseWithMarginBefore()) {
1790 // Update the after side margin of the container to discard if the after mar gin of the last child also discards and we collapse with it. 1896 // Update the after side margin of the container to discard if the after
1897 // margin of the last child also discards and we collapse with it.
1791 // Don't update the max margin values because we won't need them anyway. 1898 // Don't update the max margin values because we won't need them anyway.
1792 if (marginInfo.discardMargin()) { 1899 if (marginInfo.discardMargin()) {
1793 setMustDiscardMarginAfter(); 1900 setMustDiscardMarginAfter();
1794 return; 1901 return;
1795 } 1902 }
1796 1903
1797 // Update our max pos/neg bottom margins, since we collapsed our bottom marg ins 1904 // Update our max pos/neg bottom margins, since we collapsed our bottom
1798 // with our children. 1905 // margins with our children.
1799 setMaxMarginAfterValues( 1906 setMaxMarginAfterValues(
1800 std::max(maxPositiveMarginAfter(), marginInfo.positiveMargin()), 1907 std::max(maxPositiveMarginAfter(), marginInfo.positiveMargin()),
1801 std::max(maxNegativeMarginAfter(), marginInfo.negativeMargin())); 1908 std::max(maxNegativeMarginAfter(), marginInfo.negativeMargin()));
1802 1909
1803 if (!marginInfo.hasMarginAfterQuirk()) 1910 if (!marginInfo.hasMarginAfterQuirk())
1804 setHasMarginAfterQuirk(false); 1911 setHasMarginAfterQuirk(false);
1805 1912
1806 if (marginInfo.hasMarginAfterQuirk() && !marginAfter()) { 1913 if (marginInfo.hasMarginAfterQuirk() && !marginAfter()) {
1807 // We have no bottom margin and our last child has a quirky margin. 1914 // We have no bottom margin and our last child has a quirky margin.
1808 // We will pick up this quirky margin and pass it through. 1915 // We will pick up this quirky margin and pass it through.
1809 // This deals with the <td><div><p> case. 1916 // This deals with the <td><div><p> case.
1810 setHasMarginAfterQuirk(true); 1917 setHasMarginAfterQuirk(true);
1811 } 1918 }
1812 } 1919 }
1813 } 1920 }
1814 1921
1815 DISABLE_CFI_PERF 1922 DISABLE_CFI_PERF
1816 void LayoutBlockFlow::marginBeforeEstimateForChild( 1923 void LayoutBlockFlow::marginBeforeEstimateForChild(
1817 LayoutBox& child, 1924 LayoutBox& child,
1818 LayoutUnit& positiveMarginBefore, 1925 LayoutUnit& positiveMarginBefore,
1819 LayoutUnit& negativeMarginBefore, 1926 LayoutUnit& negativeMarginBefore,
1820 bool& discardMarginBefore) const { 1927 bool& discardMarginBefore) const {
1821 // Give up if in quirks mode and we're a body/table cell and the top margin of the child box is quirky. 1928 // Give up if in quirks mode and we're a body/table cell and the top margin of
1822 // Give up if the child specified -webkit-margin-collapse: separate that preve nts collapsing. 1929 // the child box is quirky.
1930 // Give up if the child specified -webkit-margin-collapse: separate that
1931 // prevents collapsing.
1823 // FIXME: Use writing mode independent accessor for marginBeforeCollapse. 1932 // FIXME: Use writing mode independent accessor for marginBeforeCollapse.
1824 if ((document().inQuirksMode() && hasMarginBeforeQuirk(&child) && 1933 if ((document().inQuirksMode() && hasMarginBeforeQuirk(&child) &&
1825 (isTableCell() || isBody())) || 1934 (isTableCell() || isBody())) ||
1826 child.style()->marginBeforeCollapse() == MarginCollapseSeparate) 1935 child.style()->marginBeforeCollapse() == MarginCollapseSeparate)
1827 return; 1936 return;
1828 1937
1829 // The margins are discarded by a child that specified -webkit-margin-collapse : discard. 1938 // The margins are discarded by a child that specified
1939 // -webkit-margin-collapse: discard.
1830 // FIXME: Use writing mode independent accessor for marginBeforeCollapse. 1940 // FIXME: Use writing mode independent accessor for marginBeforeCollapse.
1831 if (child.style()->marginBeforeCollapse() == MarginCollapseDiscard) { 1941 if (child.style()->marginBeforeCollapse() == MarginCollapseDiscard) {
1832 positiveMarginBefore = LayoutUnit(); 1942 positiveMarginBefore = LayoutUnit();
1833 negativeMarginBefore = LayoutUnit(); 1943 negativeMarginBefore = LayoutUnit();
1834 discardMarginBefore = true; 1944 discardMarginBefore = true;
1835 return; 1945 return;
1836 } 1946 }
1837 1947
1838 LayoutUnit beforeChildMargin = marginBeforeForChild(child); 1948 LayoutUnit beforeChildMargin = marginBeforeForChild(child);
1839 positiveMarginBefore = std::max(positiveMarginBefore, beforeChildMargin); 1949 positiveMarginBefore = std::max(positiveMarginBefore, beforeChildMargin);
(...skipping 16 matching lines...) Expand all
1856 LayoutBox* grandchildBox = childBlockFlow->firstChildBox(); 1966 LayoutBox* grandchildBox = childBlockFlow->firstChildBox();
1857 for (; grandchildBox; grandchildBox = grandchildBox->nextSiblingBox()) { 1967 for (; grandchildBox; grandchildBox = grandchildBox->nextSiblingBox()) {
1858 if (!grandchildBox->isFloatingOrOutOfFlowPositioned() && 1968 if (!grandchildBox->isFloatingOrOutOfFlowPositioned() &&
1859 !grandchildBox->isColumnSpanAll()) 1969 !grandchildBox->isColumnSpanAll())
1860 break; 1970 break;
1861 } 1971 }
1862 1972
1863 if (!grandchildBox) 1973 if (!grandchildBox)
1864 return; 1974 return;
1865 1975
1866 // Make sure to update the block margins now for the grandchild box so that we 're looking at current values. 1976 // Make sure to update the block margins now for the grandchild box so that
1977 // we're looking at current values.
1867 if (grandchildBox->needsLayout()) { 1978 if (grandchildBox->needsLayout()) {
1868 grandchildBox->computeAndSetBlockDirectionMargins(this); 1979 grandchildBox->computeAndSetBlockDirectionMargins(this);
1869 if (grandchildBox->isLayoutBlock()) { 1980 if (grandchildBox->isLayoutBlock()) {
1870 LayoutBlock* grandchildBlock = toLayoutBlock(grandchildBox); 1981 LayoutBlock* grandchildBlock = toLayoutBlock(grandchildBox);
1871 grandchildBlock->setHasMarginBeforeQuirk( 1982 grandchildBlock->setHasMarginBeforeQuirk(
1872 grandchildBox->style()->hasMarginBeforeQuirk()); 1983 grandchildBox->style()->hasMarginBeforeQuirk());
1873 grandchildBlock->setHasMarginAfterQuirk( 1984 grandchildBlock->setHasMarginAfterQuirk(
1874 grandchildBox->style()->hasMarginAfterQuirk()); 1985 grandchildBox->style()->hasMarginAfterQuirk());
1875 } 1986 }
1876 } 1987 }
1877 1988
1878 // If we have a 'clear' value but also have a margin we may not actually requi re clearance to move past any floats. 1989 // If we have a 'clear' value but also have a margin we may not actually
1879 // If that's the case we want to be sure we estimate the correct position incl uding margins after any floats rather 1990 // require clearance to move past any floats. If that's the case we want to be
1880 // than use 'clearance' later which could give us the wrong position. 1991 // sure we estimate the correct position including margins after any floats
1992 // rather than use 'clearance' later which could give us the wrong position.
1881 if (grandchildBox->style()->clear() != ClearNone && 1993 if (grandchildBox->style()->clear() != ClearNone &&
1882 childBlockFlow->marginBeforeForChild(*grandchildBox) == 0) 1994 childBlockFlow->marginBeforeForChild(*grandchildBox) == 0)
1883 return; 1995 return;
1884 1996
1885 // Collapse the margin of the grandchild box with our own to produce an estima te. 1997 // Collapse the margin of the grandchild box with our own to produce an
1998 // estimate.
1886 childBlockFlow->marginBeforeEstimateForChild( 1999 childBlockFlow->marginBeforeEstimateForChild(
1887 *grandchildBox, positiveMarginBefore, negativeMarginBefore, 2000 *grandchildBox, positiveMarginBefore, negativeMarginBefore,
1888 discardMarginBefore); 2001 discardMarginBefore);
1889 } 2002 }
1890 2003
1891 LayoutUnit LayoutBlockFlow::estimateLogicalTopPosition( 2004 LayoutUnit LayoutBlockFlow::estimateLogicalTopPosition(
1892 LayoutBox& child, 2005 LayoutBox& child,
1893 const BlockChildrenLayoutInfo& layoutInfo, 2006 const BlockChildrenLayoutInfo& layoutInfo,
1894 LayoutUnit& estimateWithoutPagination) { 2007 LayoutUnit& estimateWithoutPagination) {
1895 const MarginInfo& marginInfo = layoutInfo.marginInfo(); 2008 const MarginInfo& marginInfo = layoutInfo.marginInfo();
1896 // FIXME: We need to eliminate the estimation of vertical position, because wh en it's wrong we sometimes trigger a pathological 2009 // FIXME: We need to eliminate the estimation of vertical position, because
2010 // when it's wrong we sometimes trigger a pathological
1897 // relayout if there are intruding floats. 2011 // relayout if there are intruding floats.
1898 LayoutUnit logicalTopEstimate = logicalHeight(); 2012 LayoutUnit logicalTopEstimate = logicalHeight();
1899 LayoutUnit positiveMarginBefore; 2013 LayoutUnit positiveMarginBefore;
1900 LayoutUnit negativeMarginBefore; 2014 LayoutUnit negativeMarginBefore;
1901 bool discardMarginBefore = false; 2015 bool discardMarginBefore = false;
1902 if (!marginInfo.canCollapseWithMarginBefore()) { 2016 if (!marginInfo.canCollapseWithMarginBefore()) {
1903 if (child.selfNeedsLayout()) { 2017 if (child.selfNeedsLayout()) {
1904 // Try to do a basic estimation of how the collapse is going to go. 2018 // Try to do a basic estimation of how the collapse is going to go.
1905 marginBeforeEstimateForChild(child, positiveMarginBefore, 2019 marginBeforeEstimateForChild(child, positiveMarginBefore,
1906 negativeMarginBefore, discardMarginBefore); 2020 negativeMarginBefore, discardMarginBefore);
1907 } else { 2021 } else {
1908 // Use the cached collapsed margin values from a previous layout. Most of the time they 2022 // Use the cached collapsed margin values from a previous layout. Most of
1909 // will be right. 2023 // the time they will be right.
1910 LayoutBlockFlow::MarginValues marginValues = marginValuesForChild(child); 2024 LayoutBlockFlow::MarginValues marginValues = marginValuesForChild(child);
1911 positiveMarginBefore = 2025 positiveMarginBefore =
1912 std::max(positiveMarginBefore, marginValues.positiveMarginBefore()); 2026 std::max(positiveMarginBefore, marginValues.positiveMarginBefore());
1913 negativeMarginBefore = 2027 negativeMarginBefore =
1914 std::max(negativeMarginBefore, marginValues.negativeMarginBefore()); 2028 std::max(negativeMarginBefore, marginValues.negativeMarginBefore());
1915 discardMarginBefore = mustDiscardMarginBeforeForChild(child); 2029 discardMarginBefore = mustDiscardMarginBeforeForChild(child);
1916 } 2030 }
1917 2031
1918 // Collapse the result with our current margins. 2032 // Collapse the result with our current margins.
1919 if (!discardMarginBefore) 2033 if (!discardMarginBefore)
1920 logicalTopEstimate += 2034 logicalTopEstimate +=
1921 std::max(marginInfo.positiveMargin(), positiveMarginBefore) - 2035 std::max(marginInfo.positiveMargin(), positiveMarginBefore) -
1922 std::max(marginInfo.negativeMargin(), negativeMarginBefore); 2036 std::max(marginInfo.negativeMargin(), negativeMarginBefore);
1923 } 2037 }
1924 2038
1925 // Adjust logicalTopEstimate down to the next page if the margins are so large that we don't fit on the current 2039 // Adjust logicalTopEstimate down to the next page if the margins are so large
1926 // page. 2040 // that we don't fit on the current page.
1927 LayoutState* layoutState = view()->layoutState(); 2041 LayoutState* layoutState = view()->layoutState();
1928 if (layoutState->isPaginated() && isPageLogicalHeightKnown(logicalHeight()) && 2042 if (layoutState->isPaginated() && isPageLogicalHeightKnown(logicalHeight()) &&
1929 logicalTopEstimate > logicalHeight()) 2043 logicalTopEstimate > logicalHeight())
1930 logicalTopEstimate = 2044 logicalTopEstimate =
1931 std::min(logicalTopEstimate, nextPageLogicalTop(logicalHeight())); 2045 std::min(logicalTopEstimate, nextPageLogicalTop(logicalHeight()));
1932 2046
1933 logicalTopEstimate += getClearDelta(&child, logicalTopEstimate); 2047 logicalTopEstimate += getClearDelta(&child, logicalTopEstimate);
1934 2048
1935 estimateWithoutPagination = logicalTopEstimate; 2049 estimateWithoutPagination = logicalTopEstimate;
1936 2050
1937 if (layoutState->isPaginated()) { 2051 if (layoutState->isPaginated()) {
1938 if (!layoutInfo.isAtFirstInFlowChild()) { 2052 if (!layoutInfo.isAtFirstInFlowChild()) {
1939 // Estimate the need for a forced break in front of this child. The final break policy 2053 // Estimate the need for a forced break in front of this child. The final
1940 // at this class A break point isn't known until we have laid out the chil dren of 2054 // break policy at this class A break point isn't known until we have laid
1941 // |child|. There may be forced break-before values set on first-children inside that 2055 // out the children of |child|. There may be forced break-before values
1942 // get propagated up to the child. Just make an estimate with what we know so far. 2056 // set on first-children inside that get propagated up to the child.
2057 // Just make an estimate with what we know so far.
1943 EBreak breakValue = 2058 EBreak breakValue =
1944 child.classABreakPointValue(layoutInfo.previousBreakAfterValue()); 2059 child.classABreakPointValue(layoutInfo.previousBreakAfterValue());
1945 if (isForcedFragmentainerBreakValue(breakValue)) { 2060 if (isForcedFragmentainerBreakValue(breakValue)) {
1946 logicalTopEstimate = applyForcedBreak(logicalHeight(), breakValue); 2061 logicalTopEstimate = applyForcedBreak(logicalHeight(), breakValue);
1947 // Disregard previous margins, since they will collapse with the fragmen tainer 2062 // Disregard previous margins, since they will collapse with the
1948 // boundary, due to the forced break. Only apply margins that have been specified 2063 // fragmentainer boundary, due to the forced break. Only apply margins
1949 // on the child or its descendants. 2064 // that have been specified on the child or its descendants.
1950 if (!discardMarginBefore) 2065 if (!discardMarginBefore)
1951 logicalTopEstimate += positiveMarginBefore - negativeMarginBefore; 2066 logicalTopEstimate += positiveMarginBefore - negativeMarginBefore;
1952 2067
1953 // Clearance may already have taken us past the beginning of the next 2068 // Clearance may already have taken us past the beginning of the next
1954 // fragmentainer. 2069 // fragmentainer.
1955 return std::max(estimateWithoutPagination, logicalTopEstimate); 2070 return std::max(estimateWithoutPagination, logicalTopEstimate);
1956 } 2071 }
1957 } 2072 }
1958 2073
1959 // For replaced elements and scrolled elements, we want to shift them to the next page if they don't fit on the current one. 2074 // For replaced elements and scrolled elements, we want to shift them to the
2075 // next page if they don't fit on the current one.
1960 logicalTopEstimate = adjustForUnsplittableChild(child, logicalTopEstimate); 2076 logicalTopEstimate = adjustForUnsplittableChild(child, logicalTopEstimate);
1961 } 2077 }
1962 2078
1963 return logicalTopEstimate; 2079 return logicalTopEstimate;
1964 } 2080 }
1965 2081
1966 void LayoutBlockFlow::adjustFloatingBlock(const MarginInfo& marginInfo) { 2082 void LayoutBlockFlow::adjustFloatingBlock(const MarginInfo& marginInfo) {
1967 // The float should be positioned taking into account the bottom margin 2083 // The float should be positioned taking into account the bottom margin
1968 // of the previous flow. We add that margin into the height, get the 2084 // of the previous flow. We add that margin into the height, get the
1969 // float positioned properly, and then subtract the margin out of the 2085 // float positioned properly, and then subtract the margin out of the
1970 // height again. In the case of self-collapsing blocks, we always just 2086 // height again. In the case of self-collapsing blocks, we always just
1971 // use the top margins, since the self-collapsing block collapsed its 2087 // use the top margins, since the self-collapsing block collapsed its
1972 // own bottom margin into its top margin. 2088 // own bottom margin into its top margin.
1973 // 2089 //
1974 // Note also that the previous flow may collapse its margin into the top of 2090 // Note also that the previous flow may collapse its margin into the top of
1975 // our block. If this is the case, then we do not add the margin in to our 2091 // our block. If this is the case, then we do not add the margin in to our
1976 // height when computing the position of the float. This condition can be test ed 2092 // height when computing the position of the float. This condition can be
1977 // for by simply calling canCollapseWithMarginBefore. See 2093 // tested for by simply calling canCollapseWithMarginBefore. See
1978 // http://www.hixie.ch/tests/adhoc/css/box/block/margin-collapse/046.html for 2094 // http://www.hixie.ch/tests/adhoc/css/box/block/margin-collapse/046.html for
1979 // an example of this scenario. 2095 // an example of this scenario.
1980 LayoutUnit marginOffset = marginInfo.canCollapseWithMarginBefore() 2096 LayoutUnit marginOffset = marginInfo.canCollapseWithMarginBefore()
1981 ? LayoutUnit() 2097 ? LayoutUnit()
1982 : marginInfo.margin(); 2098 : marginInfo.margin();
1983 setLogicalHeight(logicalHeight() + marginOffset); 2099 setLogicalHeight(logicalHeight() + marginOffset);
1984 positionNewFloats(); 2100 positionNewFloats();
1985 setLogicalHeight(logicalHeight() - marginOffset); 2101 setLogicalHeight(logicalHeight() - marginOffset);
1986 } 2102 }
1987 2103
1988 void LayoutBlockFlow::handleAfterSideOfBlock(LayoutBox* lastChild, 2104 void LayoutBlockFlow::handleAfterSideOfBlock(LayoutBox* lastChild,
1989 LayoutUnit beforeSide, 2105 LayoutUnit beforeSide,
1990 LayoutUnit afterSide, 2106 LayoutUnit afterSide,
1991 MarginInfo& marginInfo) { 2107 MarginInfo& marginInfo) {
1992 marginInfo.setAtAfterSideOfBlock(true); 2108 marginInfo.setAtAfterSideOfBlock(true);
1993 2109
1994 // If our last child was a self-collapsing block with clearance then our logic al height is flush with the 2110 // If our last child was a self-collapsing block with clearance then our
1995 // bottom edge of the float that the child clears. The correct vertical positi on for the margin-collapsing we want 2111 // logical height is flush with the bottom edge of the float that the child
1996 // to perform now is at the child's margin-top - so adjust our height to that position. 2112 // clears. The correct vertical position for the margin-collapsing we want to
2113 // perform now is at the child's margin-top - so adjust our height to that
2114 // position.
1997 if (marginInfo.lastChildIsSelfCollapsingBlockWithClearance()) { 2115 if (marginInfo.lastChildIsSelfCollapsingBlockWithClearance()) {
1998 ASSERT(lastChild); 2116 ASSERT(lastChild);
1999 setLogicalHeight(logicalHeight() - 2117 setLogicalHeight(logicalHeight() -
2000 marginValuesForChild(*lastChild).positiveMarginBefore()); 2118 marginValuesForChild(*lastChild).positiveMarginBefore());
2001 } 2119 }
2002 2120
2003 if (marginInfo.canCollapseMarginAfterWithChildren() && 2121 if (marginInfo.canCollapseMarginAfterWithChildren() &&
2004 !marginInfo.canCollapseMarginAfterWithLastChild()) 2122 !marginInfo.canCollapseMarginAfterWithLastChild())
2005 marginInfo.setCanCollapseMarginAfterWithChildren(false); 2123 marginInfo.setCanCollapseMarginAfterWithChildren(false);
2006 2124
2007 // If we can't collapse with children then go ahead and add in the bottom marg in. 2125 // If we can't collapse with children then go ahead and add in the bottom
2126 // margin.
2008 if (!marginInfo.discardMargin() && 2127 if (!marginInfo.discardMargin() &&
2009 (!marginInfo.canCollapseWithMarginAfter() && 2128 (!marginInfo.canCollapseWithMarginAfter() &&
2010 !marginInfo.canCollapseWithMarginBefore() && 2129 !marginInfo.canCollapseWithMarginBefore() &&
2011 (!document().inQuirksMode() || !marginInfo.quirkContainer() || 2130 (!document().inQuirksMode() || !marginInfo.quirkContainer() ||
2012 !marginInfo.hasMarginAfterQuirk()))) 2131 !marginInfo.hasMarginAfterQuirk())))
2013 setLogicalHeight(logicalHeight() + marginInfo.margin()); 2132 setLogicalHeight(logicalHeight() + marginInfo.margin());
2014 2133
2015 // Now add in our bottom border/padding. 2134 // Now add in our bottom border/padding.
2016 setLogicalHeight(logicalHeight() + afterSide); 2135 setLogicalHeight(logicalHeight() + afterSide);
2017 2136
2018 // Negative margins can cause our height to shrink below our minimal height (b order/padding). 2137 // Negative margins can cause our height to shrink below our minimal height
2019 // If this happens, ensure that the computed height is increased to the minima l height. 2138 // (border/padding). If this happens, ensure that the computed height is
2139 // increased to the minimal height.
2020 setLogicalHeight(std::max(logicalHeight(), beforeSide + afterSide)); 2140 setLogicalHeight(std::max(logicalHeight(), beforeSide + afterSide));
2021 2141
2022 // Update our bottom collapsed margin info. 2142 // Update our bottom collapsed margin info.
2023 setCollapsedBottomMargin(marginInfo); 2143 setCollapsedBottomMargin(marginInfo);
2024 2144
2025 // There's no class A break point right after the last child, only *between* s iblings. So 2145 // There's no class A break point right after the last child, only *between*
2026 // propagate the break-after value, and keep looking for a class A break point (at the next 2146 // siblings. So propagate the break-after value, and keep looking for a class
2027 // in-flow block-level object), where we'll join this break-after value with t he break-before 2147 // A break point (at the next in-flow block-level object), where we'll join
2028 // value there. 2148 // this break-after value with the break-before value there.
2029 if (view()->layoutState()->isPaginated() && lastChild) 2149 if (view()->layoutState()->isPaginated() && lastChild)
2030 setBreakAfter( 2150 setBreakAfter(
2031 joinFragmentainerBreakValues(breakAfter(), lastChild->breakAfter())); 2151 joinFragmentainerBreakValues(breakAfter(), lastChild->breakAfter()));
2032 } 2152 }
2033 2153
2034 void LayoutBlockFlow::setMustDiscardMarginBefore(bool value) { 2154 void LayoutBlockFlow::setMustDiscardMarginBefore(bool value) {
2035 if (style()->marginBeforeCollapse() == MarginCollapseDiscard) { 2155 if (style()->marginBeforeCollapse() == MarginCollapseDiscard) {
2036 ASSERT(value); 2156 ASSERT(value);
2037 return; 2157 return;
2038 } 2158 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2078 return child.isLayoutBlockFlow() 2198 return child.isLayoutBlockFlow()
2079 ? toLayoutBlockFlow(&child)->mustDiscardMarginBefore() 2199 ? toLayoutBlockFlow(&child)->mustDiscardMarginBefore()
2080 : (child.style()->marginBeforeCollapse() == 2200 : (child.style()->marginBeforeCollapse() ==
2081 MarginCollapseDiscard); 2201 MarginCollapseDiscard);
2082 if (child.isHorizontalWritingMode() == isHorizontalWritingMode()) 2202 if (child.isHorizontalWritingMode() == isHorizontalWritingMode())
2083 return child.isLayoutBlockFlow() 2203 return child.isLayoutBlockFlow()
2084 ? toLayoutBlockFlow(&child)->mustDiscardMarginAfter() 2204 ? toLayoutBlockFlow(&child)->mustDiscardMarginAfter()
2085 : (child.style()->marginAfterCollapse() == 2205 : (child.style()->marginAfterCollapse() ==
2086 MarginCollapseDiscard); 2206 MarginCollapseDiscard);
2087 2207
2088 // FIXME: We return false here because the implementation is not geometrically complete. We have values only for before/after, not start/end. 2208 // FIXME: We return false here because the implementation is not geometrically
2089 // In case the boxes are perpendicular we assume the property is not specified . 2209 // complete. We have values only for before/after, not start/end.
2210 // In case the boxes are perpendicular we assume the property is not
2211 // specified.
2090 return false; 2212 return false;
2091 } 2213 }
2092 2214
2093 bool LayoutBlockFlow::mustDiscardMarginAfterForChild( 2215 bool LayoutBlockFlow::mustDiscardMarginAfterForChild(
2094 const LayoutBox& child) const { 2216 const LayoutBox& child) const {
2095 ASSERT(!child.selfNeedsLayout()); 2217 ASSERT(!child.selfNeedsLayout());
2096 if (!child.isWritingModeRoot()) 2218 if (!child.isWritingModeRoot())
2097 return child.isLayoutBlockFlow() 2219 return child.isLayoutBlockFlow()
2098 ? toLayoutBlockFlow(&child)->mustDiscardMarginAfter() 2220 ? toLayoutBlockFlow(&child)->mustDiscardMarginAfter()
2099 : (child.style()->marginAfterCollapse() == 2221 : (child.style()->marginAfterCollapse() ==
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2153 return childStyle.marginBeforeCollapse() == MarginCollapseSeparate; 2275 return childStyle.marginBeforeCollapse() == MarginCollapseSeparate;
2154 2276
2155 // FIXME: See |mustDiscardMarginBeforeForChild| above. 2277 // FIXME: See |mustDiscardMarginBeforeForChild| above.
2156 return false; 2278 return false;
2157 } 2279 }
2158 2280
2159 LayoutUnit LayoutBlockFlow::applyForcedBreak(LayoutUnit logicalOffset, 2281 LayoutUnit LayoutBlockFlow::applyForcedBreak(LayoutUnit logicalOffset,
2160 EBreak breakValue) { 2282 EBreak breakValue) {
2161 if (!isForcedFragmentainerBreakValue(breakValue)) 2283 if (!isForcedFragmentainerBreakValue(breakValue))
2162 return logicalOffset; 2284 return logicalOffset;
2163 // TODO(mstensho): honor breakValue. There are different types of forced break s. We currently 2285 // TODO(mstensho): honor breakValue. There are different types of forced
2164 // just assume that we want to break to the top of the next fragmentainer of t he fragmentation 2286 // breaks. We currently just assume that we want to break to the top of the
2165 // context we're in. However, we may want to find the next left or right page - even if we're 2287 // next fragmentainer of the fragmentation context we're in. However, we may
2166 // inside a multicol container when printing. 2288 // want to find the next left or right page - even if we're inside a multicol
2289 // container when printing.
2167 LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset); 2290 LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset);
2168 if (!pageLogicalHeight) 2291 if (!pageLogicalHeight)
2169 return logicalOffset; // Page height is still unknown, so we cannot insert forced breaks. 2292 return logicalOffset; // Page height is still unknown, so we cannot insert
2293 // forced breaks.
2170 LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset( 2294 LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset(
2171 logicalOffset, AssociateWithLatterPage); 2295 logicalOffset, AssociateWithLatterPage);
2172 if (remainingLogicalHeight == pageLogicalHeight) 2296 if (remainingLogicalHeight == pageLogicalHeight)
2173 return logicalOffset; // Don't break if we're already at the block start of a fragmentainer. 2297 return logicalOffset; // Don't break if we're already at the block start of
2298 // a fragmentainer.
2174 return logicalOffset + remainingLogicalHeight; 2299 return logicalOffset + remainingLogicalHeight;
2175 } 2300 }
2176 2301
2177 void LayoutBlockFlow::setBreakBefore(EBreak breakValue) { 2302 void LayoutBlockFlow::setBreakBefore(EBreak breakValue) {
2178 if (breakValue != BreakAuto && !isBreakBetweenControllable(breakValue)) 2303 if (breakValue != BreakAuto && !isBreakBetweenControllable(breakValue))
2179 breakValue = BreakAuto; 2304 breakValue = BreakAuto;
2180 if (breakValue == BreakAuto && !m_rareData) 2305 if (breakValue == BreakAuto && !m_rareData)
2181 return; 2306 return;
2182 ensureRareData().m_breakBefore = breakValue; 2307 ensureRareData().m_breakBefore = breakValue;
2183 } 2308 }
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2231 2356
2232 if (!hasHorizontalLayoutOverflow() && !hasVerticalLayoutOverflow()) 2357 if (!hasHorizontalLayoutOverflow() && !hasVerticalLayoutOverflow())
2233 return; 2358 return;
2234 2359
2235 for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) { 2360 for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
2236 LayoutUnit top = std::max<LayoutUnit>(curr->lineTop(), curr->top()); 2361 LayoutUnit top = std::max<LayoutUnit>(curr->lineTop(), curr->top());
2237 LayoutUnit bottom = 2362 LayoutUnit bottom =
2238 std::min<LayoutUnit>(curr->lineBottom(), curr->top() + curr->height()); 2363 std::min<LayoutUnit>(curr->lineBottom(), curr->top() + curr->height());
2239 LayoutRect rect(layerOffset.x() + curr->x(), layerOffset.y() + top, 2364 LayoutRect rect(layerOffset.x() + curr->x(), layerOffset.y() + top,
2240 curr->width(), bottom - top); 2365 curr->width(), bottom - top);
2241 // It's common for this rect to be entirely contained in our box, so exclude that simple case. 2366 // It's common for this rect to be entirely contained in our box, so exclude
2367 // that simple case.
2242 if (!rect.isEmpty() && (rects.isEmpty() || !rects[0].contains(rect))) 2368 if (!rect.isEmpty() && (rects.isEmpty() || !rects[0].contains(rect)))
2243 rects.append(rect); 2369 rects.append(rect);
2244 } 2370 }
2245 } 2371 }
2246 2372
2247 void LayoutBlockFlow::absoluteRects( 2373 void LayoutBlockFlow::absoluteRects(
2248 Vector<IntRect>& rects, 2374 Vector<IntRect>& rects,
2249 const LayoutPoint& accumulatedOffset) const { 2375 const LayoutPoint& accumulatedOffset) const {
2250 if (!isAnonymousBlockContinuation()) { 2376 if (!isAnonymousBlockContinuation()) {
2251 LayoutBlock::absoluteRects(rects, accumulatedOffset); 2377 LayoutBlock::absoluteRects(rects, accumulatedOffset);
2252 return; 2378 return;
2253 } 2379 }
2254 // For blocks inside inlines, we go ahead and include margins so that we run r ight up to the 2380 // For blocks inside inlines, we go ahead and include margins so that we run
2255 // inline boxes above and below us (thus getting merged with them to form a si ngle irregular 2381 // right up to the inline boxes above and below us (thus getting merged with
2256 // shape). 2382 // them to form a single irregular shape).
2257 // FIXME: This is wrong for vertical writing-modes. 2383 // FIXME: This is wrong for vertical writing-modes.
2258 // https://bugs.webkit.org/show_bug.cgi?id=46781 2384 // https://bugs.webkit.org/show_bug.cgi?id=46781
2259 LayoutRect rect(accumulatedOffset, size()); 2385 LayoutRect rect(accumulatedOffset, size());
2260 rect.expand(collapsedMarginBoxLogicalOutsets()); 2386 rect.expand(collapsedMarginBoxLogicalOutsets());
2261 rects.append(pixelSnappedIntRect(rect)); 2387 rects.append(pixelSnappedIntRect(rect));
2262 continuation()->absoluteRects( 2388 continuation()->absoluteRects(
2263 rects, 2389 rects,
2264 accumulatedOffset - 2390 accumulatedOffset -
2265 toLayoutSize( 2391 toLayoutSize(
2266 location() + 2392 location() +
2267 inlineElementContinuation()->containingBlock()->location())); 2393 inlineElementContinuation()->containingBlock()->location()));
2268 } 2394 }
2269 2395
2270 void LayoutBlockFlow::absoluteQuads(Vector<FloatQuad>& quads) const { 2396 void LayoutBlockFlow::absoluteQuads(Vector<FloatQuad>& quads) const {
2271 if (!isAnonymousBlockContinuation()) { 2397 if (!isAnonymousBlockContinuation()) {
2272 LayoutBlock::absoluteQuads(quads); 2398 LayoutBlock::absoluteQuads(quads);
2273 return; 2399 return;
2274 } 2400 }
2275 // For blocks inside inlines, we go ahead and include margins so that we run r ight up to the 2401 // For blocks inside inlines, we go ahead and include margins so that we run
2276 // inline boxes above and below us (thus getting merged with them to form a si ngle irregular 2402 // right up to the inline boxes above and below us (thus getting merged with
2277 // shape). 2403 // them to form a single irregular shape).
2278 // FIXME: This is wrong for vertical writing-modes. 2404 // FIXME: This is wrong for vertical writing-modes.
2279 // https://bugs.webkit.org/show_bug.cgi?id=46781 2405 // https://bugs.webkit.org/show_bug.cgi?id=46781
2280 LayoutRect localRect(LayoutPoint(), size()); 2406 LayoutRect localRect(LayoutPoint(), size());
2281 localRect.expand(collapsedMarginBoxLogicalOutsets()); 2407 localRect.expand(collapsedMarginBoxLogicalOutsets());
2282 quads.append(localToAbsoluteQuad(FloatRect(localRect))); 2408 quads.append(localToAbsoluteQuad(FloatRect(localRect)));
2283 continuation()->absoluteQuads(quads); 2409 continuation()->absoluteQuads(quads);
2284 } 2410 }
2285 2411
2286 LayoutObject* LayoutBlockFlow::hoverAncestor() const { 2412 LayoutObject* LayoutBlockFlow::hoverAncestor() const {
2287 return isAnonymousBlockContinuation() ? continuation() 2413 return isAnonymousBlockContinuation() ? continuation()
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
2340 // either no in-flow line boxes or if its 'overflow' property has a computed 2466 // either no in-flow line boxes or if its 'overflow' property has a computed
2341 // value other than 'visible', in which case the baseline is the bottom 2467 // value other than 'visible', in which case the baseline is the bottom
2342 // margin edge. 2468 // margin edge.
2343 // We likewise avoid using the last line box in the case of size containment, 2469 // We likewise avoid using the last line box in the case of size containment,
2344 // where the block's contents shouldn't be considered when laying out its 2470 // where the block's contents shouldn't be considered when laying out its
2345 // ancestors or siblings. 2471 // ancestors or siblings.
2346 2472
2347 if ((!style()->isOverflowVisible() && 2473 if ((!style()->isOverflowVisible() &&
2348 !shouldIgnoreOverflowPropertyForInlineBlockBaseline()) || 2474 !shouldIgnoreOverflowPropertyForInlineBlockBaseline()) ||
2349 style()->containsSize()) { 2475 style()->containsSize()) {
2350 // We are not calling baselinePosition here because the caller should add th e margin-top/margin-right, not us. 2476 // We are not calling baselinePosition here because the caller should add
2477 // the margin-top/margin-right, not us.
2351 return (lineDirection == HorizontalLine ? size().height() + marginBottom() 2478 return (lineDirection == HorizontalLine ? size().height() + marginBottom()
2352 : size().width() + marginLeft()) 2479 : size().width() + marginLeft())
2353 .toInt(); 2480 .toInt();
2354 } 2481 }
2355 if (isWritingModeRoot() && !isRubyRun()) 2482 if (isWritingModeRoot() && !isRubyRun())
2356 return -1; 2483 return -1;
2357 if (!childrenInline()) 2484 if (!childrenInline())
2358 return LayoutBlock::inlineBlockBaseline(lineDirection); 2485 return LayoutBlock::inlineBlockBaseline(lineDirection);
2359 if (lastLineBox()) 2486 if (lastLineBox())
2360 return (lastLineBox()->logicalTop() + 2487 return (lastLineBox()->logicalTop() +
(...skipping 12 matching lines...) Expand all
2373 : borderRight() + paddingRight())) 2500 : borderRight() + paddingRight()))
2374 .toInt(); 2501 .toInt();
2375 } 2502 }
2376 2503
2377 void LayoutBlockFlow::removeFloatingObjectsFromDescendants() { 2504 void LayoutBlockFlow::removeFloatingObjectsFromDescendants() {
2378 if (!containsFloats()) 2505 if (!containsFloats())
2379 return; 2506 return;
2380 removeFloatingObjects(); 2507 removeFloatingObjects();
2381 setChildNeedsLayout(MarkOnlyThis); 2508 setChildNeedsLayout(MarkOnlyThis);
2382 2509
2383 // If our children are inline, then the only boxes which could contain floats are atomic inlines (e.g. inline-block, float etc.) 2510 // If our children are inline, then the only boxes which could contain floats
2384 // and these create formatting contexts, so can't pick up intruding floats fro m ancestors/siblings - making them safe to skip. 2511 // are atomic inlines (e.g. inline-block, float etc.) and these create
2512 // formatting contexts, so can't pick up intruding floats from
2513 // ancestors/siblings - making them safe to skip.
2385 if (childrenInline()) 2514 if (childrenInline())
2386 return; 2515 return;
2387 for (LayoutObject* child = firstChild(); child; 2516 for (LayoutObject* child = firstChild(); child;
2388 child = child->nextSibling()) { 2517 child = child->nextSibling()) {
2389 // We don't skip blocks that create formatting contexts as they may have onl y recently 2518 // We don't skip blocks that create formatting contexts as they may have
2390 // changed style and their float lists may still contain floats from sibling s and ancestors. 2519 // only recently changed style and their float lists may still contain
2520 // floats from siblings and ancestors.
2391 if (child->isLayoutBlockFlow()) 2521 if (child->isLayoutBlockFlow())
2392 toLayoutBlockFlow(child)->removeFloatingObjectsFromDescendants(); 2522 toLayoutBlockFlow(child)->removeFloatingObjectsFromDescendants();
2393 } 2523 }
2394 } 2524 }
2395 2525
2396 void LayoutBlockFlow::markAllDescendantsWithFloatsForLayout( 2526 void LayoutBlockFlow::markAllDescendantsWithFloatsForLayout(
2397 LayoutBox* floatToRemove, 2527 LayoutBox* floatToRemove,
2398 bool inLayout) { 2528 bool inLayout) {
2399 if (!everHadLayout() && !containsFloats()) 2529 if (!everHadLayout() && !containsFloats())
2400 return; 2530 return;
2401 2531
2402 if (m_descendantsWithFloatsMarkedForLayout && !floatToRemove) 2532 if (m_descendantsWithFloatsMarkedForLayout && !floatToRemove)
2403 return; 2533 return;
2404 m_descendantsWithFloatsMarkedForLayout |= !floatToRemove; 2534 m_descendantsWithFloatsMarkedForLayout |= !floatToRemove;
2405 2535
2406 MarkingBehavior markParents = inLayout ? MarkOnlyThis : MarkContainerChain; 2536 MarkingBehavior markParents = inLayout ? MarkOnlyThis : MarkContainerChain;
2407 setChildNeedsLayout(markParents); 2537 setChildNeedsLayout(markParents);
2408 2538
2409 if (floatToRemove) 2539 if (floatToRemove)
2410 removeFloatingObject(floatToRemove); 2540 removeFloatingObject(floatToRemove);
2411 2541
2412 // Iterate over our children and mark them as needed. If our children are inli ne, then the 2542 // Iterate over our children and mark them as needed. If our children are
2413 // only boxes which could contain floats are atomic inlines (e.g. inline-block , float etc.) and these create formatting 2543 // inline, then the only boxes which could contain floats are atomic inlines
2414 // contexts, so can't pick up intruding floats from ancestors/siblings - makin g them safe to skip. 2544 // (e.g. inline-block, float etc.) and these create formatting contexts, so
2545 // can't pick up intruding floats from ancestors/siblings - making them safe
2546 // to skip.
2415 if (!childrenInline()) { 2547 if (!childrenInline()) {
2416 for (LayoutObject* child = firstChild(); child; 2548 for (LayoutObject* child = firstChild(); child;
2417 child = child->nextSibling()) { 2549 child = child->nextSibling()) {
2418 if ((!floatToRemove && child->isFloatingOrOutOfFlowPositioned()) || 2550 if ((!floatToRemove && child->isFloatingOrOutOfFlowPositioned()) ||
2419 !child->isLayoutBlock()) 2551 !child->isLayoutBlock())
2420 continue; 2552 continue;
2421 if (!child->isLayoutBlockFlow()) { 2553 if (!child->isLayoutBlockFlow()) {
2422 LayoutBlock* childBlock = toLayoutBlock(child); 2554 LayoutBlock* childBlock = toLayoutBlock(child);
2423 if (childBlock->shrinkToAvoidFloats() && childBlock->everHadLayout()) 2555 if (childBlock->shrinkToAvoidFloats() && childBlock->everHadLayout())
2424 childBlock->setChildNeedsLayout(markParents); 2556 childBlock->setChildNeedsLayout(markParents);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2459 } 2591 }
2460 } 2592 }
2461 } 2593 }
2462 2594
2463 LayoutUnit LayoutBlockFlow::getClearDelta(LayoutBox* child, 2595 LayoutUnit LayoutBlockFlow::getClearDelta(LayoutBox* child,
2464 LayoutUnit logicalTop) { 2596 LayoutUnit logicalTop) {
2465 // There is no need to compute clearance if we have no floats. 2597 // There is no need to compute clearance if we have no floats.
2466 if (!containsFloats()) 2598 if (!containsFloats())
2467 return LayoutUnit(); 2599 return LayoutUnit();
2468 2600
2469 // At least one float is present. We need to perform the clearance computation . 2601 // At least one float is present. We need to perform the clearance
2602 // computation.
2470 bool clearSet = child->style()->clear() != ClearNone; 2603 bool clearSet = child->style()->clear() != ClearNone;
2471 LayoutUnit logicalBottom; 2604 LayoutUnit logicalBottom;
2472 switch (child->style()->clear()) { 2605 switch (child->style()->clear()) {
2473 case ClearNone: 2606 case ClearNone:
2474 break; 2607 break;
2475 case ClearLeft: 2608 case ClearLeft:
2476 logicalBottom = lowestFloatLogicalBottom(FloatingObject::FloatLeft); 2609 logicalBottom = lowestFloatLogicalBottom(FloatingObject::FloatLeft);
2477 break; 2610 break;
2478 case ClearRight: 2611 case ClearRight:
2479 logicalBottom = lowestFloatLogicalBottom(FloatingObject::FloatRight); 2612 logicalBottom = lowestFloatLogicalBottom(FloatingObject::FloatRight);
2480 break; 2613 break;
2481 case ClearBoth: 2614 case ClearBoth:
2482 logicalBottom = lowestFloatLogicalBottom(); 2615 logicalBottom = lowestFloatLogicalBottom();
2483 break; 2616 break;
2484 } 2617 }
2485 2618
2486 // We also clear floats if we are too big to sit on the same line as a float ( and wish to avoid floats by default). 2619 // We also clear floats if we are too big to sit on the same line as a float
2620 // (and wish to avoid floats by default).
2487 LayoutUnit result = clearSet 2621 LayoutUnit result = clearSet
2488 ? (logicalBottom - logicalTop).clampNegativeToZero() 2622 ? (logicalBottom - logicalTop).clampNegativeToZero()
2489 : LayoutUnit(); 2623 : LayoutUnit();
2490 if (!result && child->avoidsFloats()) { 2624 if (!result && child->avoidsFloats()) {
2491 LayoutUnit newLogicalTop = logicalTop; 2625 LayoutUnit newLogicalTop = logicalTop;
2492 LayoutRect borderBox = child->borderBoxRect(); 2626 LayoutRect borderBox = child->borderBoxRect();
2493 LayoutUnit childLogicalWidthAtOldLogicalTopOffset = 2627 LayoutUnit childLogicalWidthAtOldLogicalTopOffset =
2494 isHorizontalWritingMode() ? borderBox.width() : borderBox.height(); 2628 isHorizontalWritingMode() ? borderBox.width() : borderBox.height();
2495 while (true) { 2629 while (true) {
2496 LayoutUnit availableLogicalWidthAtNewLogicalTopOffset = 2630 LayoutUnit availableLogicalWidthAtNewLogicalTopOffset =
2497 availableLogicalWidthForLine(newLogicalTop, DoNotIndentText, 2631 availableLogicalWidthForLine(newLogicalTop, DoNotIndentText,
2498 logicalHeightForChild(*child)); 2632 logicalHeightForChild(*child));
2499 if (availableLogicalWidthAtNewLogicalTopOffset == 2633 if (availableLogicalWidthAtNewLogicalTopOffset ==
2500 availableLogicalWidthForContent()) 2634 availableLogicalWidthForContent())
2501 return newLogicalTop - logicalTop; 2635 return newLogicalTop - logicalTop;
2502 2636
2503 LogicalExtentComputedValues computedValues; 2637 LogicalExtentComputedValues computedValues;
2504 child->logicalExtentAfterUpdatingLogicalWidth(newLogicalTop, 2638 child->logicalExtentAfterUpdatingLogicalWidth(newLogicalTop,
2505 computedValues); 2639 computedValues);
2506 LayoutUnit childLogicalWidthAtNewLogicalTopOffset = 2640 LayoutUnit childLogicalWidthAtNewLogicalTopOffset =
2507 computedValues.m_extent; 2641 computedValues.m_extent;
2508 2642
2509 if (childLogicalWidthAtNewLogicalTopOffset <= 2643 if (childLogicalWidthAtNewLogicalTopOffset <=
2510 availableLogicalWidthAtNewLogicalTopOffset) { 2644 availableLogicalWidthAtNewLogicalTopOffset) {
2511 // Even though we may not be moving, if the logical width did shrink bec ause of the presence of new floats, then 2645 // Even though we may not be moving, if the logical width did shrink
2512 // we need to force a relayout as though we shifted. This happens becaus e of the dynamic addition of overhanging floats 2646 // because of the presence of new floats, then we need to force a
2513 // from previous siblings when negative margins exist on a child (see th e addOverhangingFloats call at the end of collapseMargins). 2647 // relayout as though we shifted. This happens because of the dynamic
2648 // addition of overhanging floats from previous siblings when negative
2649 // margins exist on a child (see the addOverhangingFloats call at the
2650 // end of collapseMargins).
2514 if (childLogicalWidthAtOldLogicalTopOffset != 2651 if (childLogicalWidthAtOldLogicalTopOffset !=
2515 childLogicalWidthAtNewLogicalTopOffset) 2652 childLogicalWidthAtNewLogicalTopOffset)
2516 child->setChildNeedsLayout(MarkOnlyThis); 2653 child->setChildNeedsLayout(MarkOnlyThis);
2517 return newLogicalTop - logicalTop; 2654 return newLogicalTop - logicalTop;
2518 } 2655 }
2519 2656
2520 newLogicalTop = nextFloatLogicalBottomBelowForBlock(newLogicalTop); 2657 newLogicalTop = nextFloatLogicalBottomBelowForBlock(newLogicalTop);
2521 ASSERT(newLogicalTop >= logicalTop); 2658 ASSERT(newLogicalTop >= logicalTop);
2522 if (newLogicalTop < logicalTop) 2659 if (newLogicalTop < logicalTop)
2523 break; 2660 break;
2524 } 2661 }
2525 ASSERT_NOT_REACHED(); 2662 ASSERT_NOT_REACHED();
2526 } 2663 }
2527 return result; 2664 return result;
2528 } 2665 }
2529 2666
2530 void LayoutBlockFlow::createFloatingObjects() { 2667 void LayoutBlockFlow::createFloatingObjects() {
2531 m_floatingObjects = 2668 m_floatingObjects =
2532 wrapUnique(new FloatingObjects(this, isHorizontalWritingMode())); 2669 wrapUnique(new FloatingObjects(this, isHorizontalWritingMode()));
2533 } 2670 }
2534 2671
2535 void LayoutBlockFlow::willBeDestroyed() { 2672 void LayoutBlockFlow::willBeDestroyed() {
2536 // Mark as being destroyed to avoid trouble with merges in removeChild(). 2673 // Mark as being destroyed to avoid trouble with merges in removeChild().
2537 m_beingDestroyed = true; 2674 m_beingDestroyed = true;
2538 2675
2539 // Make sure to destroy anonymous children first while they are still connecte d to the rest of the tree, so that they will 2676 // Make sure to destroy anonymous children first while they are still
2540 // properly dirty line boxes that they are removed from. Effects that do :befo re/:after only on hover could crash otherwise. 2677 // connected to the rest of the tree, so that they will properly dirty line
2678 // boxes that they are removed from. Effects that do :before/:after only on
2679 // hover could crash otherwise.
2541 children()->destroyLeftoverChildren(); 2680 children()->destroyLeftoverChildren();
2542 2681
2543 // Destroy our continuation before anything other than anonymous children. 2682 // Destroy our continuation before anything other than anonymous children.
2544 // The reason we don't destroy it before anonymous children is that they may 2683 // The reason we don't destroy it before anonymous children is that they may
2545 // have continuations of their own that are anonymous children of our continua tion. 2684 // have continuations of their own that are anonymous children of our
2685 // continuation.
2546 LayoutBoxModelObject* continuation = this->continuation(); 2686 LayoutBoxModelObject* continuation = this->continuation();
2547 if (continuation) { 2687 if (continuation) {
2548 continuation->destroy(); 2688 continuation->destroy();
2549 setContinuation(nullptr); 2689 setContinuation(nullptr);
2550 } 2690 }
2551 2691
2552 if (!documentBeingDestroyed()) { 2692 if (!documentBeingDestroyed()) {
2553 // TODO(mstensho): figure out if we need this. We have no test coverage for it. It looks 2693 // TODO(mstensho): figure out if we need this. We have no test coverage for
2554 // like all line boxes have been removed at this point. 2694 // it. It looks like all line boxes have been removed at this point.
2555 if (firstLineBox()) { 2695 if (firstLineBox()) {
2556 // We can't wait for LayoutBox::destroy to clear the selection, 2696 // We can't wait for LayoutBox::destroy to clear the selection,
2557 // because by then we will have nuked the line boxes. 2697 // because by then we will have nuked the line boxes.
2558 // FIXME: The FrameSelection should be responsible for this when it 2698 // FIXME: The FrameSelection should be responsible for this when it
2559 // is notified of DOM mutations. 2699 // is notified of DOM mutations.
2560 if (isSelectionBorder()) 2700 if (isSelectionBorder())
2561 view()->clearSelection(); 2701 view()->clearSelection();
2562 2702
2563 // If we are an anonymous block, then our line boxes might have children 2703 // If we are an anonymous block, then our line boxes might have children
2564 // that will outlast this block. In the non-anonymous block case those 2704 // that will outlast this block. In the non-anonymous block case those
(...skipping 26 matching lines...) Expand all
2591 2731
2592 LayoutBlock::styleWillChange(diff, newStyle); 2732 LayoutBlock::styleWillChange(diff, newStyle);
2593 } 2733 }
2594 2734
2595 DISABLE_CFI_PERF 2735 DISABLE_CFI_PERF
2596 void LayoutBlockFlow::styleDidChange(StyleDifference diff, 2736 void LayoutBlockFlow::styleDidChange(StyleDifference diff,
2597 const ComputedStyle* oldStyle) { 2737 const ComputedStyle* oldStyle) {
2598 bool hadSelfPaintingLayer = hasSelfPaintingLayer(); 2738 bool hadSelfPaintingLayer = hasSelfPaintingLayer();
2599 LayoutBlock::styleDidChange(diff, oldStyle); 2739 LayoutBlock::styleDidChange(diff, oldStyle);
2600 2740
2601 // After our style changed, if we lose our ability to propagate floats into ne xt sibling 2741 // After our style changed, if we lose our ability to propagate floats into
2602 // blocks, then we need to find the top most parent containing that overhangin g float and 2742 // next sibling blocks, then we need to find the top most parent containing
2603 // then mark its descendants with floats for layout and clear all floats from its next 2743 // that overhanging float and then mark its descendants with floats for layout
2604 // sibling blocks that exist in our floating objects list. See bug 56299 and 6 2875. 2744 // and clear all floats from its next sibling blocks that exist in our
2745 // floating objects list. See crbug.com/56299 and crbug.com/62875.
2605 bool canPropagateFloatIntoSibling = 2746 bool canPropagateFloatIntoSibling =
2606 !isFloatingOrOutOfFlowPositioned() && !avoidsFloats(); 2747 !isFloatingOrOutOfFlowPositioned() && !avoidsFloats();
2607 bool siblingFloatPropagationChanged = 2748 bool siblingFloatPropagationChanged =
2608 diff.needsFullLayout() && s_canPropagateFloatIntoSibling && 2749 diff.needsFullLayout() && s_canPropagateFloatIntoSibling &&
2609 !canPropagateFloatIntoSibling && hasOverhangingFloats(); 2750 !canPropagateFloatIntoSibling && hasOverhangingFloats();
2610 2751
2611 // When this object's self-painting layer status changed, we should update Flo atingObjects::shouldPaint() flags for 2752 // When this object's self-painting layer status changed, we should update
2612 // descendant overhanging floats in ancestors. 2753 // FloatingObjects::shouldPaint() flags for descendant overhanging floats in
2754 // ancestors.
2613 bool needsUpdateAncestorFloatObjectShouldPaintFlags = false; 2755 bool needsUpdateAncestorFloatObjectShouldPaintFlags = false;
2614 if (hasSelfPaintingLayer() != hadSelfPaintingLayer && 2756 if (hasSelfPaintingLayer() != hadSelfPaintingLayer &&
2615 hasOverhangingFloats()) { 2757 hasOverhangingFloats()) {
2616 setNeedsLayout(LayoutInvalidationReason::StyleChange); 2758 setNeedsLayout(LayoutInvalidationReason::StyleChange);
2617 if (hadSelfPaintingLayer) 2759 if (hadSelfPaintingLayer)
2618 markAllDescendantsWithFloatsForLayout(); 2760 markAllDescendantsWithFloatsForLayout();
2619 else 2761 else
2620 needsUpdateAncestorFloatObjectShouldPaintFlags = true; 2762 needsUpdateAncestorFloatObjectShouldPaintFlags = true;
2621 } 2763 }
2622 2764
(...skipping 24 matching lines...) Expand all
2647 parentBlockFlow->markAllDescendantsWithFloatsForLayout(); 2789 parentBlockFlow->markAllDescendantsWithFloatsForLayout();
2648 if (siblingFloatPropagationChanged) 2790 if (siblingFloatPropagationChanged)
2649 parentBlockFlow->markSiblingsWithFloatsForLayout(); 2791 parentBlockFlow->markSiblingsWithFloatsForLayout();
2650 } 2792 }
2651 2793
2652 if (diff.needsFullLayout() || !oldStyle) 2794 if (diff.needsFullLayout() || !oldStyle)
2653 createOrDestroyMultiColumnFlowThreadIfNeeded(oldStyle); 2795 createOrDestroyMultiColumnFlowThreadIfNeeded(oldStyle);
2654 if (oldStyle) { 2796 if (oldStyle) {
2655 if (LayoutMultiColumnFlowThread* flowThread = multiColumnFlowThread()) { 2797 if (LayoutMultiColumnFlowThread* flowThread = multiColumnFlowThread()) {
2656 if (!style()->columnRuleEquivalent(oldStyle)) { 2798 if (!style()->columnRuleEquivalent(oldStyle)) {
2657 // Column rules are painted by anonymous column set children of the mult icol 2799 // Column rules are painted by anonymous column set children of the
2658 // container. We need to notify them. 2800 // multicol container. We need to notify them.
2659 flowThread->columnRuleStyleDidChange(); 2801 flowThread->columnRuleStyleDidChange();
2660 } 2802 }
2661 } 2803 }
2662 } 2804 }
2663 } 2805 }
2664 2806
2665 void LayoutBlockFlow::updateBlockChildDirtyBitsBeforeLayout( 2807 void LayoutBlockFlow::updateBlockChildDirtyBitsBeforeLayout(
2666 bool relayoutChildren, 2808 bool relayoutChildren,
2667 LayoutBox& child) { 2809 LayoutBox& child) {
2668 if (child.isLayoutMultiColumnSpannerPlaceholder()) 2810 if (child.isLayoutMultiColumnSpannerPlaceholder())
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
2704 return; 2846 return;
2705 } 2847 }
2706 2848
2707 if (beforeChild && beforeChild->parent() != this) { 2849 if (beforeChild && beforeChild->parent() != this) {
2708 addChildBeforeDescendant(newChild, beforeChild); 2850 addChildBeforeDescendant(newChild, beforeChild);
2709 return; 2851 return;
2710 } 2852 }
2711 2853
2712 bool madeBoxesNonInline = false; 2854 bool madeBoxesNonInline = false;
2713 2855
2714 // A block has to either have all of its children inline, or all of its childr en as blocks. 2856 // A block has to either have all of its children inline, or all of its
2715 // So, if our children are currently inline and a block child has to be insert ed, we move all our 2857 // children as blocks.
2716 // inline children into anonymous block boxes. 2858 // So, if our children are currently inline and a block child has to be
2859 // inserted, we move all our inline children into anonymous block boxes.
2717 bool childIsBlockLevel = 2860 bool childIsBlockLevel =
2718 !newChild->isInline() && !newChild->isFloatingOrOutOfFlowPositioned(); 2861 !newChild->isInline() && !newChild->isFloatingOrOutOfFlowPositioned();
2719 if (childrenInline()) { 2862 if (childrenInline()) {
2720 if (childIsBlockLevel) { 2863 if (childIsBlockLevel) {
2721 // Wrap the inline content in anonymous blocks, to allow for the new block child to be 2864 // Wrap the inline content in anonymous blocks, to allow for the new block
2722 // inserted. 2865 // child to be inserted.
2723 makeChildrenNonInline(beforeChild); 2866 makeChildrenNonInline(beforeChild);
2724 madeBoxesNonInline = true; 2867 madeBoxesNonInline = true;
2725 2868
2726 if (beforeChild && beforeChild->parent() != this) { 2869 if (beforeChild && beforeChild->parent() != this) {
2727 beforeChild = beforeChild->parent(); 2870 beforeChild = beforeChild->parent();
2728 ASSERT(beforeChild->isAnonymousBlock()); 2871 ASSERT(beforeChild->isAnonymousBlock());
2729 ASSERT(beforeChild->parent() == this); 2872 ASSERT(beforeChild->parent() == this);
2730 } 2873 }
2731 } 2874 }
2732 } else if (!childIsBlockLevel) { 2875 } else if (!childIsBlockLevel) {
2733 // This block has block children. We may want to put the new child into an a nomyous 2876 // This block has block children. We may want to put the new child into an
2734 // block. Floats and out-of-flow children may live among either block or inl ine children, 2877 // anomyous block. Floats and out-of-flow children may live among either
2735 // so for such children, only put them inside an anonymous block if one alre ady exists. If 2878 // block or inline children, so for such children, only put them inside an
2736 // the child is inline, on the other hand, we *have to* put it inside an ano nymous block, 2879 // anonymous block if one already exists. If the child is inline, on the
2737 // so create a new one if there is none for us there already. 2880 // other hand, we *have to* put it inside an anonymous block, so create a
2881 // new one if there is none for us there already.
2738 LayoutObject* afterChild = 2882 LayoutObject* afterChild =
2739 beforeChild ? beforeChild->previousSibling() : lastChild(); 2883 beforeChild ? beforeChild->previousSibling() : lastChild();
2740 2884
2741 if (afterChild && afterChild->isAnonymousBlock()) { 2885 if (afterChild && afterChild->isAnonymousBlock()) {
2742 afterChild->addChild(newChild); 2886 afterChild->addChild(newChild);
2743 return; 2887 return;
2744 } 2888 }
2745 2889
2746 if (newChild->isInline()) { 2890 if (newChild->isInline()) {
2747 // No suitable existing anonymous box - create a new one. 2891 // No suitable existing anonymous box - create a new one.
2748 LayoutBlockFlow* newBlock = toLayoutBlockFlow(createAnonymousBlock()); 2892 LayoutBlockFlow* newBlock = toLayoutBlockFlow(createAnonymousBlock());
2749 LayoutBox::addChild(newBlock, beforeChild); 2893 LayoutBox::addChild(newBlock, beforeChild);
2750 // Reparent adjacent floating or out-of-flow siblings to the new box. 2894 // Reparent adjacent floating or out-of-flow siblings to the new box.
2751 newBlock->reparentPrecedingFloatingOrOutOfFlowSiblings(); 2895 newBlock->reparentPrecedingFloatingOrOutOfFlowSiblings();
2752 newBlock->addChild(newChild); 2896 newBlock->addChild(newChild);
2753 newBlock->reparentSubsequentFloatingOrOutOfFlowSiblings(); 2897 newBlock->reparentSubsequentFloatingOrOutOfFlowSiblings();
2754 return; 2898 return;
2755 } 2899 }
2756 } 2900 }
2757 2901
2758 // Skip the LayoutBlock override, since that one deals with anonymous child in sertion in a way 2902 // Skip the LayoutBlock override, since that one deals with anonymous child
2759 // that isn't sufficient for us, and can only cause trouble at this point. 2903 // insertion in a way that isn't sufficient for us, and can only cause trouble
2904 // at this point.
2760 LayoutBox::addChild(newChild, beforeChild); 2905 LayoutBox::addChild(newChild, beforeChild);
2761 2906
2762 if (madeBoxesNonInline && parent() && isAnonymousBlock() && 2907 if (madeBoxesNonInline && parent() && isAnonymousBlock() &&
2763 parent()->isLayoutBlock() && !parent()->createsAnonymousWrapper()) { 2908 parent()->isLayoutBlock() && !parent()->createsAnonymousWrapper()) {
2764 toLayoutBlock(parent())->removeLeftoverAnonymousBlock(this); 2909 toLayoutBlock(parent())->removeLeftoverAnonymousBlock(this);
2765 // |this| may be dead now. 2910 // |this| may be dead now.
2766 } 2911 }
2767 } 2912 }
2768 2913
2769 static bool isMergeableAnonymousBlock(const LayoutBlockFlow* block) { 2914 static bool isMergeableAnonymousBlock(const LayoutBlockFlow* block) {
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
2839 ASSERT_NOT_REACHED(); 2984 ASSERT_NOT_REACHED();
2840 2985
2841 break; 2986 break;
2842 } 2987 }
2843 setContinuation(nullptr); 2988 setContinuation(nullptr);
2844 destroy(); 2989 destroy();
2845 } 2990 }
2846 } else if (!beingDestroyed() && 2991 } else if (!beingDestroyed() &&
2847 !oldChild->isFloatingOrOutOfFlowPositioned() && 2992 !oldChild->isFloatingOrOutOfFlowPositioned() &&
2848 !oldChild->isAnonymousBlock()) { 2993 !oldChild->isAnonymousBlock()) {
2849 // If the child we're removing means that we can now treat all children as i nline without the need for anonymous blocks, then do that. 2994 // If the child we're removing means that we can now treat all children as
2995 // inline without the need for anonymous blocks, then do that.
2850 makeChildrenInlineIfPossible(); 2996 makeChildrenInlineIfPossible();
2851 } 2997 }
2852 } 2998 }
2853 2999
2854 void LayoutBlockFlow::moveAllChildrenIncludingFloatsTo(LayoutBlock* toBlock, 3000 void LayoutBlockFlow::moveAllChildrenIncludingFloatsTo(LayoutBlock* toBlock,
2855 bool fullRemoveInsert) { 3001 bool fullRemoveInsert) {
2856 LayoutBlockFlow* toBlockFlow = toLayoutBlockFlow(toBlock); 3002 LayoutBlockFlow* toBlockFlow = toLayoutBlockFlow(toBlock);
2857 moveAllChildrenTo(toBlockFlow, fullRemoveInsert); 3003 moveAllChildrenTo(toBlockFlow, fullRemoveInsert);
2858 3004
2859 // When a portion of the layout tree is being detached, anonymous blocks 3005 // When a portion of the layout tree is being detached, anonymous blocks
2860 // will be combined as their children are deleted. In this process, the 3006 // will be combined as their children are deleted. In this process, the
2861 // anonymous block later in the tree is merged into the one preceding it. 3007 // anonymous block later in the tree is merged into the one preceding it.
2862 // It can happen that the later block (this) contains floats that the 3008 // It can happen that the later block (this) contains floats that the
2863 // previous block (toBlockFlow) did not contain, and thus are not in the 3009 // previous block (toBlockFlow) did not contain, and thus are not in the
2864 // floating objects list for toBlockFlow. This can result in toBlockFlow conta ining 3010 // floating objects list for toBlockFlow. This can result in toBlockFlow
2865 // floats that are not in it's floating objects list, but are in the 3011 // containing floats that are not in it's floating objects list, but are in
2866 // floating objects lists of siblings and parents. This can cause problems 3012 // the floating objects lists of siblings and parents. This can cause problems
2867 // when the float itself is deleted, since the deletion code assumes that 3013 // when the float itself is deleted, since the deletion code assumes that if a
2868 // if a float is not in it's containing block's floating objects list, it 3014 // float is not in it's containing block's floating objects list, it isn't in
2869 // isn't in any floating objects list. In order to preserve this condition 3015 // any floating objects list. In order to preserve this condition (removing it
2870 // (removing it has serious performance implications), we need to copy the 3016 // has serious performance implications), we need to copy the floating objects
2871 // floating objects from the old block (this) to the new block (toBlockFlow). 3017 // from the old block (this) to the new block (toBlockFlow).
2872 // The float's metrics will likely all be wrong, but since toBlockFlow is 3018 // The float's metrics will likely all be wrong, but since toBlockFlow is
2873 // already marked for layout, this will get fixed before anything gets 3019 // already marked for layout, this will get fixed before anything gets
2874 // displayed. 3020 // displayed.
2875 // See bug https://code.google.com/p/chromium/issues/detail?id=230907 3021 // See bug https://code.google.com/p/chromium/issues/detail?id=230907
2876 if (m_floatingObjects) { 3022 if (m_floatingObjects) {
2877 if (!toBlockFlow->m_floatingObjects) 3023 if (!toBlockFlow->m_floatingObjects)
2878 toBlockFlow->createFloatingObjects(); 3024 toBlockFlow->createFloatingObjects();
2879 3025
2880 const FloatingObjectSet& fromFloatingObjectSet = m_floatingObjects->set(); 3026 const FloatingObjectSet& fromFloatingObjectSet = m_floatingObjects->set();
2881 FloatingObjectSetIterator end = fromFloatingObjectSet.end(); 3027 FloatingObjectSetIterator end = fromFloatingObjectSet.end();
(...skipping 12 matching lines...) Expand all
2894 } 3040 }
2895 3041
2896 void LayoutBlockFlow::childBecameFloatingOrOutOfFlow(LayoutBox* child) { 3042 void LayoutBlockFlow::childBecameFloatingOrOutOfFlow(LayoutBox* child) {
2897 makeChildrenInlineIfPossible(); 3043 makeChildrenInlineIfPossible();
2898 3044
2899 // Reparent the child to an adjacent anonymous block if one is available. 3045 // Reparent the child to an adjacent anonymous block if one is available.
2900 LayoutObject* prev = child->previousSibling(); 3046 LayoutObject* prev = child->previousSibling();
2901 if (prev && prev->isAnonymousBlock() && prev->isLayoutBlockFlow()) { 3047 if (prev && prev->isAnonymousBlock() && prev->isLayoutBlockFlow()) {
2902 LayoutBlockFlow* newContainer = toLayoutBlockFlow(prev); 3048 LayoutBlockFlow* newContainer = toLayoutBlockFlow(prev);
2903 moveChildTo(newContainer, child, nullptr, false); 3049 moveChildTo(newContainer, child, nullptr, false);
2904 // The anonymous block we've moved to may now be adjacent to former siblings of ours 3050 // The anonymous block we've moved to may now be adjacent to former siblings
2905 // that it can contain also. 3051 // of ours that it can contain also.
2906 newContainer->reparentSubsequentFloatingOrOutOfFlowSiblings(); 3052 newContainer->reparentSubsequentFloatingOrOutOfFlowSiblings();
2907 return; 3053 return;
2908 } 3054 }
2909 LayoutObject* next = child->nextSibling(); 3055 LayoutObject* next = child->nextSibling();
2910 if (next && next->isAnonymousBlock() && next->isLayoutBlockFlow()) { 3056 if (next && next->isAnonymousBlock() && next->isLayoutBlockFlow()) {
2911 LayoutBlockFlow* newContainer = toLayoutBlockFlow(next); 3057 LayoutBlockFlow* newContainer = toLayoutBlockFlow(next);
2912 moveChildTo(newContainer, child, newContainer->firstChild(), false); 3058 moveChildTo(newContainer, child, newContainer->firstChild(), false);
2913 } 3059 }
2914 } 3060 }
2915 3061
2916 void LayoutBlockFlow::collapseAnonymousBlockChild(LayoutBlockFlow* child) { 3062 void LayoutBlockFlow::collapseAnonymousBlockChild(LayoutBlockFlow* child) {
2917 // It's possible that this block's destruction may have been triggered by the 3063 // It's possible that this block's destruction may have been triggered by the
2918 // child's removal. Just bail if the anonymous child block is already being 3064 // child's removal. Just bail if the anonymous child block is already being
2919 // destroyed. See crbug.com/282088 3065 // destroyed. See crbug.com/282088
2920 if (child->beingDestroyed()) 3066 if (child->beingDestroyed())
2921 return; 3067 return;
2922 if (child->continuation()) 3068 if (child->continuation())
2923 return; 3069 return;
2924 // Ruby elements use anonymous wrappers for ruby runs and ruby bases by design , so we don't remove them. 3070 // Ruby elements use anonymous wrappers for ruby runs and ruby bases by
3071 // design, so we don't remove them.
2925 if (child->isRubyRun() || child->isRubyBase()) 3072 if (child->isRubyRun() || child->isRubyBase())
2926 return; 3073 return;
2927 setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation( 3074 setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
2928 LayoutInvalidationReason::ChildAnonymousBlockChanged); 3075 LayoutInvalidationReason::ChildAnonymousBlockChanged);
2929 3076
2930 child->moveAllChildrenTo(this, child->nextSibling(), child->hasLayer()); 3077 child->moveAllChildrenTo(this, child->nextSibling(), child->hasLayer());
2931 setChildrenInline(child->childrenInline()); 3078 setChildrenInline(child->childrenInline());
2932 3079
2933 children()->removeChildNode(this, child, child->hasLayer()); 3080 children()->removeChildNode(this, child, child->hasLayer());
2934 child->destroy(); 3081 child->destroy();
2935 } 3082 }
2936 3083
2937 bool LayoutBlockFlow::mergeSiblingContiguousAnonymousBlock( 3084 bool LayoutBlockFlow::mergeSiblingContiguousAnonymousBlock(
2938 LayoutBlockFlow* siblingThatMayBeDeleted) { 3085 LayoutBlockFlow* siblingThatMayBeDeleted) {
2939 // Note: |this| and |siblingThatMayBeDeleted| may not be adjacent siblings at this point. There 3086 // Note: |this| and |siblingThatMayBeDeleted| may not be adjacent siblings at
2940 // may be an object between them which is about to be removed. 3087 // this point. There may be an object between them which is about to be
3088 // removed.
2941 3089
2942 if (!isMergeableAnonymousBlock(this) || 3090 if (!isMergeableAnonymousBlock(this) ||
2943 !isMergeableAnonymousBlock(siblingThatMayBeDeleted)) 3091 !isMergeableAnonymousBlock(siblingThatMayBeDeleted))
2944 return false; 3092 return false;
2945 3093
2946 setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation( 3094 setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
2947 LayoutInvalidationReason::AnonymousBlockChange); 3095 LayoutInvalidationReason::AnonymousBlockChange);
2948 3096
2949 // If the inlineness of children of the two block don't match, we'd need speci al code here 3097 // If the inlineness of children of the two block don't match, we'd need
2950 // (but there should be no need for it). 3098 // special code here (but there should be no need for it).
2951 ASSERT(siblingThatMayBeDeleted->childrenInline() == childrenInline()); 3099 ASSERT(siblingThatMayBeDeleted->childrenInline() == childrenInline());
2952 // Take all the children out of the |next| block and put them in 3100 // Take all the children out of the |next| block and put them in
2953 // the |prev| block. 3101 // the |prev| block.
2954 siblingThatMayBeDeleted->moveAllChildrenIncludingFloatsTo( 3102 siblingThatMayBeDeleted->moveAllChildrenIncludingFloatsTo(
2955 this, siblingThatMayBeDeleted->hasLayer() || hasLayer()); 3103 this, siblingThatMayBeDeleted->hasLayer() || hasLayer());
2956 // Delete the now-empty block's lines and nuke it. 3104 // Delete the now-empty block's lines and nuke it.
2957 siblingThatMayBeDeleted->deleteLineBoxTree(); 3105 siblingThatMayBeDeleted->deleteLineBoxTree();
2958 siblingThatMayBeDeleted->destroy(); 3106 siblingThatMayBeDeleted->destroy();
2959 return true; 3107 return true;
2960 } 3108 }
(...skipping 25 matching lines...) Expand all
2986 LayoutBlockFlow* parentBlockFlow = toLayoutBlockFlow(parent()); 3134 LayoutBlockFlow* parentBlockFlow = toLayoutBlockFlow(parent());
2987 LayoutObject* child = previousSibling(); 3135 LayoutObject* child = previousSibling();
2988 while (child && child->isFloatingOrOutOfFlowPositioned()) { 3136 while (child && child->isFloatingOrOutOfFlowPositioned()) {
2989 LayoutObject* sibling = child->previousSibling(); 3137 LayoutObject* sibling = child->previousSibling();
2990 parentBlockFlow->moveChildTo(this, child, firstChild(), false); 3138 parentBlockFlow->moveChildTo(this, child, firstChild(), false);
2991 child = sibling; 3139 child = sibling;
2992 } 3140 }
2993 } 3141 }
2994 3142
2995 void LayoutBlockFlow::makeChildrenInlineIfPossible() { 3143 void LayoutBlockFlow::makeChildrenInlineIfPossible() {
2996 // Collapsing away anonymous wrappers isn't relevant for the children of anony mous blocks, unless they are ruby bases. 3144 // Collapsing away anonymous wrappers isn't relevant for the children of
3145 // anonymous blocks, unless they are ruby bases.
2997 if (isAnonymousBlock() && !isRubyBase()) 3146 if (isAnonymousBlock() && !isRubyBase())
2998 return; 3147 return;
2999 3148
3000 Vector<LayoutBlockFlow*, 3> blocksToRemove; 3149 Vector<LayoutBlockFlow*, 3> blocksToRemove;
3001 for (LayoutObject* child = firstChild(); child; 3150 for (LayoutObject* child = firstChild(); child;
3002 child = child->nextSibling()) { 3151 child = child->nextSibling()) {
3003 if (child->isFloating()) 3152 if (child->isFloating())
3004 continue; 3153 continue;
3005 if (child->isOutOfFlowPositioned()) 3154 if (child->isOutOfFlowPositioned())
3006 continue; 3155 continue;
3007 3156
3008 // There are still block children in the container, so any anonymous wrapper s are still needed. 3157 // There are still block children in the container, so any anonymous
3158 // wrappers are still needed.
3009 if (!child->isAnonymousBlock() || !child->isLayoutBlockFlow()) 3159 if (!child->isAnonymousBlock() || !child->isLayoutBlockFlow())
3010 return; 3160 return;
3011 // If one of the children is being destroyed then it is unsafe to clean up a nonymous wrappers as the 3161 // If one of the children is being destroyed then it is unsafe to clean up
3162 // anonymous wrappers as the
3012 // entire branch may be being destroyed. 3163 // entire branch may be being destroyed.
3013 if (toLayoutBlockFlow(child)->beingDestroyed()) 3164 if (toLayoutBlockFlow(child)->beingDestroyed())
3014 return; 3165 return;
3015 // We can't remove anonymous wrappers if they contain continuations as this means there are block children present. 3166 // We can't remove anonymous wrappers if they contain continuations as this
3167 // means there are block children present.
3016 if (toLayoutBlockFlow(child)->continuation()) 3168 if (toLayoutBlockFlow(child)->continuation())
3017 return; 3169 return;
3018 // We are only interested in removing anonymous wrappers if there are inline siblings underneath them. 3170 // We are only interested in removing anonymous wrappers if there are inline
3171 // siblings underneath them.
3019 if (!child->childrenInline()) 3172 if (!child->childrenInline())
3020 return; 3173 return;
3021 // Ruby elements use anonymous wrappers for ruby runs and ruby bases by desi gn, so we don't remove them. 3174 // Ruby elements use anonymous wrappers for ruby runs and ruby bases by
3175 // design, so we don't remove them.
3022 if (child->isRubyRun() || child->isRubyBase()) 3176 if (child->isRubyRun() || child->isRubyBase())
3023 return; 3177 return;
3024 3178
3025 blocksToRemove.append(toLayoutBlockFlow(child)); 3179 blocksToRemove.append(toLayoutBlockFlow(child));
3026 } 3180 }
3027 3181
3028 // If we make an object's children inline we are going to frustrate any future attempts to remove 3182 // If we make an object's children inline we are going to frustrate any future
3029 // floats from its children's float-lists before the next layout happens so cl ear down all the floatlists 3183 // attempts to remove floats from its children's float-lists before the next
3030 // now - they will be rebuilt at layout. 3184 // layout happens so clear down all the floatlists now - they will be rebuilt
3185 // at layout.
3031 removeFloatingObjectsFromDescendants(); 3186 removeFloatingObjectsFromDescendants();
3032 3187
3033 for (size_t i = 0; i < blocksToRemove.size(); i++) 3188 for (size_t i = 0; i < blocksToRemove.size(); i++)
3034 collapseAnonymousBlockChild(blocksToRemove[i]); 3189 collapseAnonymousBlockChild(blocksToRemove[i]);
3035 setChildrenInline(true); 3190 setChildrenInline(true);
3036 } 3191 }
3037 3192
3038 static void getInlineRun(LayoutObject* start, 3193 static void getInlineRun(LayoutObject* start,
3039 LayoutObject* boundary, 3194 LayoutObject* boundary,
3040 LayoutObject*& inlineRunStart, 3195 LayoutObject*& inlineRunStart,
3041 LayoutObject*& inlineRunEnd) { 3196 LayoutObject*& inlineRunEnd) {
3042 // Beginning at |start| we find the largest contiguous run of inlines that 3197 // Beginning at |start| we find the largest contiguous run of inlines that
3043 // we can. We denote the run with start and end points, |inlineRunStart| 3198 // we can. We denote the run with start and end points, |inlineRunStart|
3044 // and |inlineRunEnd|. Note that these two values may be the same if 3199 // and |inlineRunEnd|. Note that these two values may be the same if
3045 // we encounter only one inline. 3200 // we encounter only one inline.
3046 // 3201 //
3047 // We skip any non-inlines we encounter as long as we haven't found any 3202 // We skip any non-inlines we encounter as long as we haven't found any
3048 // inlines yet. 3203 // inlines yet.
3049 // 3204 //
3050 // |boundary| indicates a non-inclusive boundary point. Regardless of whether |boundary| 3205 // |boundary| indicates a non-inclusive boundary point. Regardless of whether
3051 // is inline or not, we will not include it in a run with inlines before it. It's as though we encountered 3206 // |boundary| is inline or not, we will not include it in a run with inlines
3052 // a non-inline. 3207 // before it. It's as though we encountered a non-inline.
3053 3208
3054 // Start by skipping as many non-inlines as we can. 3209 // Start by skipping as many non-inlines as we can.
3055 LayoutObject* curr = start; 3210 LayoutObject* curr = start;
3056 bool sawInline; 3211 bool sawInline;
3057 do { 3212 do {
3058 while (curr && 3213 while (curr &&
3059 !(curr->isInline() || curr->isFloatingOrOutOfFlowPositioned())) 3214 !(curr->isInline() || curr->isFloatingOrOutOfFlowPositioned()))
3060 curr = curr->nextSibling(); 3215 curr = curr->nextSibling();
3061 3216
3062 inlineRunStart = inlineRunEnd = curr; 3217 inlineRunStart = inlineRunEnd = curr;
(...skipping 10 matching lines...) Expand all
3073 inlineRunEnd = curr; 3228 inlineRunEnd = curr;
3074 if (curr->isInline()) 3229 if (curr->isInline())
3075 sawInline = true; 3230 sawInline = true;
3076 curr = curr->nextSibling(); 3231 curr = curr->nextSibling();
3077 } 3232 }
3078 } while (!sawInline); 3233 } while (!sawInline);
3079 } 3234 }
3080 3235
3081 void LayoutBlockFlow::makeChildrenNonInline(LayoutObject* insertionPoint) { 3236 void LayoutBlockFlow::makeChildrenNonInline(LayoutObject* insertionPoint) {
3082 // makeChildrenNonInline takes a block whose children are *all* inline and it 3237 // makeChildrenNonInline takes a block whose children are *all* inline and it
3083 // makes sure that inline children are coalesced under anonymous 3238 // makes sure that inline children are coalesced under anonymous blocks.
3084 // blocks. If |insertionPoint| is defined, then it represents the insertion p oint for 3239 // If |insertionPoint| is defined, then it represents the insertion point for
3085 // the new block child that is causing us to have to wrap all the inlines. Th is 3240 // the new block child that is causing us to have to wrap all the inlines.
3086 // means that we cannot coalesce inlines before |insertionPoint| with inlines following 3241 // This means that we cannot coalesce inlines before |insertionPoint| with
3087 // |insertionPoint|, because the new child is going to be inserted in between the inlines, 3242 // inlines following |insertionPoint|, because the new child is going to be
3088 // splitting them. 3243 // inserted in between the inlines, splitting them.
3089 ASSERT(!isInline() || isAtomicInlineLevel()); 3244 ASSERT(!isInline() || isAtomicInlineLevel());
3090 ASSERT(!insertionPoint || insertionPoint->parent() == this); 3245 ASSERT(!insertionPoint || insertionPoint->parent() == this);
3091 3246
3092 setChildrenInline(false); 3247 setChildrenInline(false);
3093 3248
3094 LayoutObject* child = firstChild(); 3249 LayoutObject* child = firstChild();
3095 if (!child) 3250 if (!child)
3096 return; 3251 return;
3097 3252
3098 deleteLineBoxTree(); 3253 deleteLineBoxTree();
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
3161 3316
3162 m_floatingObjects->clear(); 3317 m_floatingObjects->clear();
3163 } 3318 }
3164 3319
3165 LayoutPoint LayoutBlockFlow::flipFloatForWritingModeForChild( 3320 LayoutPoint LayoutBlockFlow::flipFloatForWritingModeForChild(
3166 const FloatingObject& child, 3321 const FloatingObject& child,
3167 const LayoutPoint& point) const { 3322 const LayoutPoint& point) const {
3168 if (!style()->isFlippedBlocksWritingMode()) 3323 if (!style()->isFlippedBlocksWritingMode())
3169 return point; 3324 return point;
3170 3325
3171 // This is similar to LayoutBox::flipForWritingModeForChild. We have to subtra ct out our left offsets twice, since 3326 // This is similar to LayoutBox::flipForWritingModeForChild. We have to
3172 // it's going to get added back in. We hide this complication here so that the calling code looks normal for the unflipped 3327 // subtract out our left offsets twice, since it's going to get added back in.
3173 // case. 3328 // We hide this complication here so that the calling code looks normal for
3329 // the unflipped case.
3174 return LayoutPoint(point.x() + size().width() - 3330 return LayoutPoint(point.x() + size().width() -
3175 child.layoutObject()->size().width() - 3331 child.layoutObject()->size().width() -
3176 2 * xPositionForFloatIncludingMargin(child), 3332 2 * xPositionForFloatIncludingMargin(child),
3177 point.y()); 3333 point.y());
3178 } 3334 }
3179 3335
3180 LayoutUnit LayoutBlockFlow::logicalLeftOffsetForPositioningFloat( 3336 LayoutUnit LayoutBlockFlow::logicalLeftOffsetForPositioningFloat(
3181 LayoutUnit logicalTop, 3337 LayoutUnit logicalTop,
3182 LayoutUnit fixedOffset, 3338 LayoutUnit fixedOffset,
3183 LayoutUnit* heightRemaining) const { 3339 LayoutUnit* heightRemaining) const {
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
3306 FloatingObjectSetIterator it = 3462 FloatingObjectSetIterator it =
3307 floatingObjectSet.find<FloatingObjectHashTranslator>(&floatBox); 3463 floatingObjectSet.find<FloatingObjectHashTranslator>(&floatBox);
3308 if (it != floatingObjectSet.end()) 3464 if (it != floatingObjectSet.end())
3309 return it->get(); 3465 return it->get();
3310 } 3466 }
3311 3467
3312 // Create the special object entry & append it to the list 3468 // Create the special object entry & append it to the list
3313 3469
3314 std::unique_ptr<FloatingObject> newObj = FloatingObject::create(&floatBox); 3470 std::unique_ptr<FloatingObject> newObj = FloatingObject::create(&floatBox);
3315 3471
3316 // Our location is irrelevant if we're unsplittable or no pagination is in eff ect. 3472 // Our location is irrelevant if we're unsplittable or no pagination is in
3317 // Just go ahead and lay out the float. 3473 // effect. Just go ahead and lay out the float.
3318 bool isChildLayoutBlock = floatBox.isLayoutBlock(); 3474 bool isChildLayoutBlock = floatBox.isLayoutBlock();
3319 if (isChildLayoutBlock && !floatBox.needsLayout() && 3475 if (isChildLayoutBlock && !floatBox.needsLayout() &&
3320 view()->layoutState()->pageLogicalHeightChanged()) 3476 view()->layoutState()->pageLogicalHeightChanged())
3321 floatBox.setChildNeedsLayout(MarkOnlyThis); 3477 floatBox.setChildNeedsLayout(MarkOnlyThis);
3322 3478
3323 floatBox.layoutIfNeeded(); 3479 floatBox.layoutIfNeeded();
3324 3480
3325 setLogicalWidthForFloat(*newObj, logicalWidthForChild(floatBox) + 3481 setLogicalWidthForFloat(*newObj, logicalWidthForChild(floatBox) +
3326 marginStartForChild(floatBox) + 3482 marginStartForChild(floatBox) +
3327 marginEndForChild(floatBox)); 3483 marginEndForChild(floatBox));
(...skipping 10 matching lines...) Expand all
3338 FloatingObject& floatingObject = *it->get(); 3494 FloatingObject& floatingObject = *it->get();
3339 if (childrenInline()) { 3495 if (childrenInline()) {
3340 LayoutUnit logicalTop = logicalTopForFloat(floatingObject); 3496 LayoutUnit logicalTop = logicalTopForFloat(floatingObject);
3341 LayoutUnit logicalBottom = logicalBottomForFloat(floatingObject); 3497 LayoutUnit logicalBottom = logicalBottomForFloat(floatingObject);
3342 3498
3343 // Fix for https://bugs.webkit.org/show_bug.cgi?id=54995. 3499 // Fix for https://bugs.webkit.org/show_bug.cgi?id=54995.
3344 if (logicalBottom < 0 || logicalBottom < logicalTop || 3500 if (logicalBottom < 0 || logicalBottom < logicalTop ||
3345 logicalTop == LayoutUnit::max()) { 3501 logicalTop == LayoutUnit::max()) {
3346 logicalBottom = LayoutUnit::max(); 3502 logicalBottom = LayoutUnit::max();
3347 } else { 3503 } else {
3348 // Special-case zero- and less-than-zero-height floats: those don't to uch 3504 // Special-case zero- and less-than-zero-height floats: those don't
3349 // the line that they're on, but it still needs to be dirtied. This is 3505 // touch the line that they're on, but it still needs to be dirtied.
3350 // accomplished by pretending they have a height of 1. 3506 // This is accomplished by pretending they have a height of 1.
3351 logicalBottom = std::max(logicalBottom, logicalTop + 1); 3507 logicalBottom = std::max(logicalBottom, logicalTop + 1);
3352 } 3508 }
3353 if (floatingObject.originatingLine()) { 3509 if (floatingObject.originatingLine()) {
3354 if (!selfNeedsLayout()) { 3510 if (!selfNeedsLayout()) {
3355 ASSERT( 3511 ASSERT(
3356 floatingObject.originatingLine()->getLineLayoutItem().isEqual( 3512 floatingObject.originatingLine()->getLineLayoutItem().isEqual(
3357 this)); 3513 this));
3358 floatingObject.originatingLine()->markDirty(); 3514 floatingObject.originatingLine()->markDirty();
3359 } 3515 }
3360 #if ENABLE(ASSERT) 3516 #if ENABLE(ASSERT)
(...skipping 28 matching lines...) Expand all
3389 return false; 3545 return false;
3390 3546
3391 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); 3547 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
3392 if (floatingObjectSet.isEmpty()) 3548 if (floatingObjectSet.isEmpty())
3393 return false; 3549 return false;
3394 3550
3395 // If all floats have already been positioned, then we have no work to do. 3551 // If all floats have already been positioned, then we have no work to do.
3396 if (floatingObjectSet.last()->isPlaced()) 3552 if (floatingObjectSet.last()->isPlaced())
3397 return false; 3553 return false;
3398 3554
3399 // Move backwards through our floating object list until we find a float that has 3555 // Move backwards through our floating object list until we find a float that
3400 // already been positioned. Then we'll be able to move forward, positioning al l of 3556 // has already been positioned. Then we'll be able to move forward,
3401 // the new floats that need it. 3557 // positioning all of the new floats that need it.
3402 FloatingObjectSetIterator it = floatingObjectSet.end(); 3558 FloatingObjectSetIterator it = floatingObjectSet.end();
3403 --it; // Go to last item. 3559 --it; // Go to last item.
3404 FloatingObjectSetIterator begin = floatingObjectSet.begin(); 3560 FloatingObjectSetIterator begin = floatingObjectSet.begin();
3405 FloatingObject* lastPlacedFloatingObject = nullptr; 3561 FloatingObject* lastPlacedFloatingObject = nullptr;
3406 while (it != begin) { 3562 while (it != begin) {
3407 --it; 3563 --it;
3408 if ((*it)->isPlaced()) { 3564 if ((*it)->isPlaced()) {
3409 lastPlacedFloatingObject = it->get(); 3565 lastPlacedFloatingObject = it->get();
3410 ++it; 3566 ++it;
3411 break; 3567 break;
3412 } 3568 }
3413 } 3569 }
3414 3570
3415 LayoutUnit logicalTop = logicalHeight(); 3571 LayoutUnit logicalTop = logicalHeight();
3416 3572
3417 // The float cannot start above the top position of the last positioned float. 3573 // The float cannot start above the top position of the last positioned float.
3418 if (lastPlacedFloatingObject) 3574 if (lastPlacedFloatingObject)
3419 logicalTop = 3575 logicalTop =
3420 std::max(logicalTopForFloat(*lastPlacedFloatingObject), logicalTop); 3576 std::max(logicalTopForFloat(*lastPlacedFloatingObject), logicalTop);
3421 3577
3422 FloatingObjectSetIterator end = floatingObjectSet.end(); 3578 FloatingObjectSetIterator end = floatingObjectSet.end();
3423 // Now walk through the set of unpositioned floats and place them. 3579 // Now walk through the set of unpositioned floats and place them.
3424 for (; it != end; ++it) { 3580 for (; it != end; ++it) {
3425 FloatingObject& floatingObject = *it->get(); 3581 FloatingObject& floatingObject = *it->get();
3426 // The containing block is responsible for positioning floats, so if we have floats in our 3582 // The containing block is responsible for positioning floats, so if we have
3427 // list that come from somewhere else, do not attempt to position them. 3583 // floats in our list that come from somewhere else, do not attempt to
3584 // position them.
3428 if (floatingObject.layoutObject()->containingBlock() != this) 3585 if (floatingObject.layoutObject()->containingBlock() != this)
3429 continue; 3586 continue;
3430 3587
3431 LayoutBox* childBox = floatingObject.layoutObject(); 3588 LayoutBox* childBox = floatingObject.layoutObject();
3432 3589
3433 // FIXME Investigate if this can be removed. crbug.com/370006 3590 // FIXME Investigate if this can be removed. crbug.com/370006
3434 childBox->setMayNeedPaintInvalidation(); 3591 childBox->setMayNeedPaintInvalidation();
3435 3592
3436 LayoutUnit childLogicalLeftMargin = style()->isLeftToRightDirection() 3593 LayoutUnit childLogicalLeftMargin = style()->isLeftToRightDirection()
3437 ? marginStartForChild(*childBox) 3594 ? marginStartForChild(*childBox)
3438 : marginEndForChild(*childBox); 3595 : marginEndForChild(*childBox);
3439 if (childBox->style()->clear() & ClearLeft) 3596 if (childBox->style()->clear() & ClearLeft)
3440 logicalTop = std::max(lowestFloatLogicalBottom(FloatingObject::FloatLeft), 3597 logicalTop = std::max(lowestFloatLogicalBottom(FloatingObject::FloatLeft),
3441 logicalTop); 3598 logicalTop);
3442 if (childBox->style()->clear() & ClearRight) 3599 if (childBox->style()->clear() & ClearRight)
3443 logicalTop = std::max( 3600 logicalTop = std::max(
3444 lowestFloatLogicalBottom(FloatingObject::FloatRight), logicalTop); 3601 lowestFloatLogicalBottom(FloatingObject::FloatRight), logicalTop);
3445 3602
3446 bool isPaginated = view()->layoutState()->isPaginated(); 3603 bool isPaginated = view()->layoutState()->isPaginated();
3447 if (isPaginated && !childrenInline()) { 3604 if (isPaginated && !childrenInline()) {
3448 // Forced breaks are inserted at class A break points. Floats may be affec ted by a 3605 // Forced breaks are inserted at class A break points. Floats may be
3449 // break-after value on the previous in-flow sibling. 3606 // affected by a break-after value on the previous in-flow sibling.
3450 if (LayoutBox* previousInFlowBox = childBox->previousInFlowSiblingBox()) 3607 if (LayoutBox* previousInFlowBox = childBox->previousInFlowSiblingBox())
3451 logicalTop = 3608 logicalTop =
3452 applyForcedBreak(logicalTop, previousInFlowBox->breakAfter()); 3609 applyForcedBreak(logicalTop, previousInFlowBox->breakAfter());
3453 } 3610 }
3454 3611
3455 LayoutPoint floatLogicalLocation = 3612 LayoutPoint floatLogicalLocation =
3456 computeLogicalLocationForFloat(floatingObject, logicalTop); 3613 computeLogicalLocationForFloat(floatingObject, logicalTop);
3457 3614
3458 setLogicalLeftForFloat(floatingObject, floatLogicalLocation.x()); 3615 setLogicalLeftForFloat(floatingObject, floatLogicalLocation.x());
3459 3616
3460 setLogicalLeftForChild(*childBox, 3617 setLogicalLeftForChild(*childBox,
3461 floatLogicalLocation.x() + childLogicalLeftMargin); 3618 floatLogicalLocation.x() + childLogicalLeftMargin);
3462 setLogicalTopForChild( 3619 setLogicalTopForChild(
3463 *childBox, floatLogicalLocation.y() + marginBeforeForChild(*childBox)); 3620 *childBox, floatLogicalLocation.y() + marginBeforeForChild(*childBox));
3464 3621
3465 SubtreeLayoutScope layoutScope(*childBox); 3622 SubtreeLayoutScope layoutScope(*childBox);
3466 if (isPaginated && !childBox->needsLayout()) 3623 if (isPaginated && !childBox->needsLayout())
3467 markChildForPaginationRelayoutIfNeeded(*childBox, layoutScope); 3624 markChildForPaginationRelayoutIfNeeded(*childBox, layoutScope);
3468 3625
3469 childBox->layoutIfNeeded(); 3626 childBox->layoutIfNeeded();
3470 3627
3471 if (isPaginated) { 3628 if (isPaginated) {
3472 LayoutBlockFlow* childBlockFlow = 3629 LayoutBlockFlow* childBlockFlow =
3473 childBox->isLayoutBlockFlow() ? toLayoutBlockFlow(childBox) : nullptr; 3630 childBox->isLayoutBlockFlow() ? toLayoutBlockFlow(childBox) : nullptr;
3474 // The first piece of content inside the child may have set a strut during layout. 3631 // The first piece of content inside the child may have set a strut during
3632 // layout.
3475 LayoutUnit strut = 3633 LayoutUnit strut =
3476 childBlockFlow ? childBlockFlow->paginationStrutPropagatedFromChild() 3634 childBlockFlow ? childBlockFlow->paginationStrutPropagatedFromChild()
3477 : LayoutUnit(); 3635 : LayoutUnit();
3478 if (!strut) { 3636 if (!strut) {
3479 // Otherwise, if we are unsplittable and don't fit, move to the next pag e or column 3637 // Otherwise, if we are unsplittable and don't fit, move to the next
3480 // if that helps the situation. 3638 // page or column if that helps the situation.
3481 strut = 3639 strut =
3482 adjustForUnsplittableChild(*childBox, floatLogicalLocation.y()) - 3640 adjustForUnsplittableChild(*childBox, floatLogicalLocation.y()) -
3483 floatLogicalLocation.y(); 3641 floatLogicalLocation.y();
3484 } 3642 }
3485 3643
3486 childBox->setPaginationStrut(strut); 3644 childBox->setPaginationStrut(strut);
3487 if (strut) { 3645 if (strut) {
3488 floatLogicalLocation = computeLogicalLocationForFloat( 3646 floatLogicalLocation = computeLogicalLocationForFloat(
3489 floatingObject, floatLogicalLocation.y() + strut); 3647 floatingObject, floatLogicalLocation.y() + strut);
3490 setLogicalLeftForFloat(floatingObject, floatLogicalLocation.x()); 3648 setLogicalLeftForFloat(floatingObject, floatLogicalLocation.x());
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
3529 return false; 3687 return false;
3530 3688
3531 return isOverhangingFloat(**it); 3689 return isOverhangingFloat(**it);
3532 } 3690 }
3533 3691
3534 void LayoutBlockFlow::addIntrudingFloats(LayoutBlockFlow* prev, 3692 void LayoutBlockFlow::addIntrudingFloats(LayoutBlockFlow* prev,
3535 LayoutUnit logicalLeftOffset, 3693 LayoutUnit logicalLeftOffset,
3536 LayoutUnit logicalTopOffset) { 3694 LayoutUnit logicalTopOffset) {
3537 ASSERT(!avoidsFloats()); 3695 ASSERT(!avoidsFloats());
3538 3696
3539 // If we create our own block formatting context then our contents don't inter act with floats outside it, even those from our parent. 3697 // If we create our own block formatting context then our contents don't
3698 // interact with floats outside it, even those from our parent.
3540 if (createsNewFormattingContext()) 3699 if (createsNewFormattingContext())
3541 return; 3700 return;
3542 3701
3543 // If the parent or previous sibling doesn't have any floats to add, don't bot her. 3702 // If the parent or previous sibling doesn't have any floats to add, don't
3703 // bother.
3544 if (!prev->m_floatingObjects) 3704 if (!prev->m_floatingObjects)
3545 return; 3705 return;
3546 3706
3547 logicalLeftOffset += marginLogicalLeft(); 3707 logicalLeftOffset += marginLogicalLeft();
3548 3708
3549 const FloatingObjectSet& prevSet = prev->m_floatingObjects->set(); 3709 const FloatingObjectSet& prevSet = prev->m_floatingObjects->set();
3550 FloatingObjectSetIterator prevEnd = prevSet.end(); 3710 FloatingObjectSetIterator prevEnd = prevSet.end();
3551 for (FloatingObjectSetIterator prevIt = prevSet.begin(); prevIt != prevEnd; 3711 for (FloatingObjectSetIterator prevIt = prevSet.begin(); prevIt != prevEnd;
3552 ++prevIt) { 3712 ++prevIt) {
3553 FloatingObject& floatingObject = *prevIt->get(); 3713 FloatingObject& floatingObject = *prevIt->get();
3554 if (logicalBottomForFloat(floatingObject) > logicalTopOffset) { 3714 if (logicalBottomForFloat(floatingObject) > logicalTopOffset) {
3555 if (!m_floatingObjects || 3715 if (!m_floatingObjects ||
3556 !m_floatingObjects->set().contains(&floatingObject)) { 3716 !m_floatingObjects->set().contains(&floatingObject)) {
3557 // We create the floating object list lazily. 3717 // We create the floating object list lazily.
3558 if (!m_floatingObjects) 3718 if (!m_floatingObjects)
3559 createFloatingObjects(); 3719 createFloatingObjects();
3560 3720
3561 // Applying the child's margin makes no sense in the case where the chil d was passed in. 3721 // Applying the child's margin makes no sense in the case where the
3562 // since this margin was added already through the modification of the | logicalLeftOffset| variable 3722 // child was passed in since this margin was added already through the
3563 // above. |logicalLeftOffset| will equal the margin in this case, so it' s already been taken 3723 // modification of the |logicalLeftOffset| variable above.
3564 // into account. Only apply this code if prev is the parent, since other wise the left margin 3724 // |logicalLeftOffset| will equal the margin in this case, so it's
3565 // will get applied twice. 3725 // already been taken into account. Only apply this code if prev is the
3726 // parent, since otherwise the left margin will get applied twice.
3566 LayoutSize offset = 3727 LayoutSize offset =
3567 isHorizontalWritingMode() 3728 isHorizontalWritingMode()
3568 ? LayoutSize( 3729 ? LayoutSize(
3569 logicalLeftOffset - (prev != parent() ? prev->marginLeft() 3730 logicalLeftOffset - (prev != parent() ? prev->marginLeft()
3570 : LayoutUnit()), 3731 : LayoutUnit()),
3571 logicalTopOffset) 3732 logicalTopOffset)
3572 : LayoutSize( 3733 : LayoutSize(
3573 logicalTopOffset, 3734 logicalTopOffset,
3574 logicalLeftOffset - (prev != parent() ? prev->marginTop() 3735 logicalLeftOffset - (prev != parent() ? prev->marginTop()
3575 : LayoutUnit())); 3736 : LayoutUnit()));
3576 3737
3577 m_floatingObjects->add(floatingObject.copyToNewContainer(offset)); 3738 m_floatingObjects->add(floatingObject.copyToNewContainer(offset));
3578 } 3739 }
3579 } 3740 }
3580 } 3741 }
3581 } 3742 }
3582 3743
3583 void LayoutBlockFlow::addOverhangingFloats(LayoutBlockFlow* child, 3744 void LayoutBlockFlow::addOverhangingFloats(LayoutBlockFlow* child,
3584 bool makeChildPaintOtherFloats) { 3745 bool makeChildPaintOtherFloats) {
3585 // Prevent floats from being added to the canvas by the root element, e.g., <h tml>. 3746 // Prevent floats from being added to the canvas by the root element, e.g.,
3747 // <html>.
3586 if (!child->containsFloats() || child->createsNewFormattingContext()) 3748 if (!child->containsFloats() || child->createsNewFormattingContext())
3587 return; 3749 return;
3588 3750
3589 LayoutUnit childLogicalTop = child->logicalTop(); 3751 LayoutUnit childLogicalTop = child->logicalTop();
3590 LayoutUnit childLogicalLeft = child->logicalLeft(); 3752 LayoutUnit childLogicalLeft = child->logicalLeft();
3591 3753
3592 // Floats that will remain the child's responsibility to paint should factor i nto its 3754 // Floats that will remain the child's responsibility to paint should factor
3593 // overflow. 3755 // into its overflow.
3594 FloatingObjectSetIterator childEnd = child->m_floatingObjects->set().end(); 3756 FloatingObjectSetIterator childEnd = child->m_floatingObjects->set().end();
3595 for (FloatingObjectSetIterator childIt = 3757 for (FloatingObjectSetIterator childIt =
3596 child->m_floatingObjects->set().begin(); 3758 child->m_floatingObjects->set().begin();
3597 childIt != childEnd; ++childIt) { 3759 childIt != childEnd; ++childIt) {
3598 FloatingObject& floatingObject = *childIt->get(); 3760 FloatingObject& floatingObject = *childIt->get();
3599 LayoutUnit logicalBottomForFloat = 3761 LayoutUnit logicalBottomForFloat =
3600 std::min(this->logicalBottomForFloat(floatingObject), 3762 std::min(this->logicalBottomForFloat(floatingObject),
3601 LayoutUnit::max() - childLogicalTop); 3763 LayoutUnit::max() - childLogicalTop);
3602 LayoutUnit logicalBottom = childLogicalTop + logicalBottomForFloat; 3764 LayoutUnit logicalBottom = childLogicalTop + logicalBottomForFloat;
3603 3765
3604 if (logicalBottom > logicalHeight()) { 3766 if (logicalBottom > logicalHeight()) {
3605 // If the object is not in the list, we add it now. 3767 // If the object is not in the list, we add it now.
3606 if (!containsFloat(floatingObject.layoutObject())) { 3768 if (!containsFloat(floatingObject.layoutObject())) {
3607 LayoutSize offset = 3769 LayoutSize offset =
3608 isHorizontalWritingMode() 3770 isHorizontalWritingMode()
3609 ? LayoutSize(-childLogicalLeft, -childLogicalTop) 3771 ? LayoutSize(-childLogicalLeft, -childLogicalTop)
3610 : LayoutSize(-childLogicalTop, -childLogicalLeft); 3772 : LayoutSize(-childLogicalTop, -childLogicalLeft);
3611 bool shouldPaint = false; 3773 bool shouldPaint = false;
3612 3774
3613 // The nearest enclosing layer always paints the float (so that zindex a nd stacking 3775 // The nearest enclosing layer always paints the float (so that zindex
3614 // behaves properly). We always want to propagate the desire to paint th e float as 3776 // and stacking behaves properly). We always want to propagate the
3615 // far out as we can, to the outermost block that overlaps the float, st opping only 3777 // desire to paint the float as far out as we can, to the outermost
3616 // if we hit a self-painting layer boundary. 3778 // block that overlaps the float, stopping only if we hit a
3779 // self-painting layer boundary.
3617 if (floatingObject.layoutObject()->enclosingFloatPaintingLayer() == 3780 if (floatingObject.layoutObject()->enclosingFloatPaintingLayer() ==
3618 enclosingFloatPaintingLayer() && 3781 enclosingFloatPaintingLayer() &&
3619 !floatingObject.isLowestNonOverhangingFloatInChild()) { 3782 !floatingObject.isLowestNonOverhangingFloatInChild()) {
3620 floatingObject.setShouldPaint(false); 3783 floatingObject.setShouldPaint(false);
3621 shouldPaint = true; 3784 shouldPaint = true;
3622 } 3785 }
3623 // We create the floating object list lazily. 3786 // We create the floating object list lazily.
3624 if (!m_floatingObjects) 3787 if (!m_floatingObjects)
3625 createFloatingObjects(); 3788 createFloatingObjects();
3626 3789
3627 m_floatingObjects->add( 3790 m_floatingObjects->add(
3628 floatingObject.copyToNewContainer(offset, shouldPaint, true)); 3791 floatingObject.copyToNewContainer(offset, shouldPaint, true));
3629 } 3792 }
3630 } else { 3793 } else {
3631 if (makeChildPaintOtherFloats && !floatingObject.shouldPaint() && 3794 if (makeChildPaintOtherFloats && !floatingObject.shouldPaint() &&
3632 !floatingObject.layoutObject()->hasSelfPaintingLayer() && 3795 !floatingObject.layoutObject()->hasSelfPaintingLayer() &&
3633 !floatingObject.isLowestNonOverhangingFloatInChild() && 3796 !floatingObject.isLowestNonOverhangingFloatInChild() &&
3634 floatingObject.layoutObject()->isDescendantOf(child) && 3797 floatingObject.layoutObject()->isDescendantOf(child) &&
3635 floatingObject.layoutObject()->enclosingFloatPaintingLayer() == 3798 floatingObject.layoutObject()->enclosingFloatPaintingLayer() ==
3636 child->enclosingFloatPaintingLayer()) { 3799 child->enclosingFloatPaintingLayer()) {
3637 // The float is not overhanging from this block, so if it is a descendan t of the child, the child should 3800 // The float is not overhanging from this block, so if it is a
3638 // paint it (the other case is that it is intruding into the child), unl ess it has its own layer or enclosing 3801 // descendant of the child, the child should paint it (the other case is
3639 // layer. 3802 // that it is intruding into the child), unless it has its own layer or
3640 // If makeChildPaintOtherFloats is false, it means that the child must a lready know about all the floats 3803 // enclosing layer.
3641 // it should paint. 3804 // If makeChildPaintOtherFloats is false, it means that the child must
3805 // already know about all the floats it should paint.
3642 floatingObject.setShouldPaint(true); 3806 floatingObject.setShouldPaint(true);
3643 } 3807 }
3644 3808
3645 // Since the float doesn't overhang, it didn't get put into our list. We n eed to go ahead and add its overflow in to the 3809 // Since the float doesn't overhang, it didn't get put into our list. We
3646 // child now. 3810 // need to go ahead and add its overflow in to the child now.
3647 if (floatingObject.isDescendant()) 3811 if (floatingObject.isDescendant())
3648 child->addOverflowFromChild( 3812 child->addOverflowFromChild(
3649 floatingObject.layoutObject(), 3813 floatingObject.layoutObject(),
3650 LayoutSize(xPositionForFloatIncludingMargin(floatingObject), 3814 LayoutSize(xPositionForFloatIncludingMargin(floatingObject),
3651 yPositionForFloatIncludingMargin(floatingObject))); 3815 yPositionForFloatIncludingMargin(floatingObject)));
3652 } 3816 }
3653 } 3817 }
3654 } 3818 }
3655 3819
3656 LayoutUnit LayoutBlockFlow::lowestFloatLogicalBottom( 3820 LayoutUnit LayoutBlockFlow::lowestFloatLogicalBottom(
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
3799 if (!ancestorFloatingObjects) 3963 if (!ancestorFloatingObjects)
3800 break; 3964 break;
3801 FloatingObjectSet::iterator it = ancestorFloatingObjects->mutableSet() 3965 FloatingObjectSet::iterator it = ancestorFloatingObjects->mutableSet()
3802 .find<FloatingObjectHashTranslator>( 3966 .find<FloatingObjectHashTranslator>(
3803 const_cast<LayoutBox*>(&floatBox)); 3967 const_cast<LayoutBox*>(&floatBox));
3804 if (it == ancestorFloatingObjects->mutableSet().end()) 3968 if (it == ancestorFloatingObjects->mutableSet().end())
3805 break; 3969 break;
3806 3970
3807 FloatingObject& floatingObject = **it; 3971 FloatingObject& floatingObject = **it;
3808 if (!floatBoxIsSelfPaintingLayer) { 3972 if (!floatBoxIsSelfPaintingLayer) {
3809 // This repeats the logic in addOverhangingFloats() about shouldPaint flag : 3973 // This repeats the logic in addOverhangingFloats() about shouldPaint
3810 // - The nearest enclosing block in which the float doesn't overhang paint s the float; 3974 // flag:
3811 // - Or even if the float overhangs, if the ancestor block has self-painti ng layer, it 3975 // - The nearest enclosing block in which the float doesn't overhang
3812 // paints the float. 3976 // paints the float;
3977 // - Or even if the float overhangs, if the ancestor block has
3978 // self-painting layer, it paints the float.
3813 if (ancestorBlock->hasSelfPaintingLayer() || 3979 if (ancestorBlock->hasSelfPaintingLayer() ||
3814 !ancestorBlock->isOverhangingFloat(floatingObject)) { 3980 !ancestorBlock->isOverhangingFloat(floatingObject)) {
3815 floatingObject.setShouldPaint(true); 3981 floatingObject.setShouldPaint(true);
3816 return; 3982 return;
3817 } 3983 }
3818 } else { 3984 } else {
3819 floatingObject.setShouldPaint(false); 3985 floatingObject.setShouldPaint(false);
3820 } 3986 }
3821 } 3987 }
3822 } 3988 }
3823 3989
3824 bool LayoutBlockFlow::allowsPaginationStrut() const { 3990 bool LayoutBlockFlow::allowsPaginationStrut() const {
3825 // The block needs to be contained by a LayoutBlockFlow (and not by e.g. a fle xbox, grid, or a 3991 // The block needs to be contained by a LayoutBlockFlow (and not by e.g. a
3826 // table (the latter being the case for table cell or table caption)). The rea son for this 3992 // flexbox, grid, or a table (the latter being the case for table cell or
3827 // limitation is simply that LayoutBlockFlow child layout code is the only pla ce where we pick 3993 // table caption)). The reason for this limitation is simply that
3828 // up the struts and handle them. We handle floats and regular in-flow childre n, and that's 3994 // LayoutBlockFlow child layout code is the only place where we pick up the
3829 // all. We could handle this in other layout modes as well (and even for out-o f-flow children), 3995 // struts and handle them. We handle floats and regular in-flow children, and
3830 // but currently we don't. 3996 // that's all. We could handle this in other layout modes as well (and even
3997 // for out-of-flow children), but currently we don't.
3831 // TODO(mstensho): But we *should*. 3998 // TODO(mstensho): But we *should*.
3832 if (isOutOfFlowPositioned()) 3999 if (isOutOfFlowPositioned())
3833 return false; 4000 return false;
3834 if (isLayoutFlowThread()) { 4001 if (isLayoutFlowThread()) {
3835 // Don't let the strut escape the fragmentation context and get lost. 4002 // Don't let the strut escape the fragmentation context and get lost.
3836 // TODO(mstensho): If we're in a nested fragmentation context, we should ide ally convert 4003 // TODO(mstensho): If we're in a nested fragmentation context, we should
3837 // and propagate the strut to the outer fragmentation context, so that the i nner one is 4004 // ideally convert and propagate the strut to the outer fragmentation
3838 // fully pushed to the next outer fragmentainer, instead of taking up unusab le space in the 4005 // context, so that the inner one is fully pushed to the next outer
3839 // previous one. But currently we have no mechanism in place to handle this. 4006 // fragmentainer, instead of taking up unusable space in the previous one.
4007 // But currently we have no mechanism in place to handle this.
3840 return false; 4008 return false;
3841 } 4009 }
3842 LayoutBlock* containingBlock = this->containingBlock(); 4010 LayoutBlock* containingBlock = this->containingBlock();
3843 return containingBlock && containingBlock->isLayoutBlockFlow(); 4011 return containingBlock && containingBlock->isLayoutBlockFlow();
3844 } 4012 }
3845 4013
3846 void LayoutBlockFlow::setPaginationStrutPropagatedFromChild(LayoutUnit strut) { 4014 void LayoutBlockFlow::setPaginationStrutPropagatedFromChild(LayoutUnit strut) {
3847 strut = std::max(strut, LayoutUnit()); 4015 strut = std::max(strut, LayoutUnit());
3848 if (!m_rareData) { 4016 if (!m_rareData) {
3849 if (!strut) 4017 if (!strut)
3850 return; 4018 return;
3851 m_rareData = wrapUnique(new LayoutBlockFlowRareData(this)); 4019 m_rareData = wrapUnique(new LayoutBlockFlowRareData(this));
3852 } 4020 }
3853 m_rareData->m_paginationStrutPropagatedFromChild = strut; 4021 m_rareData->m_paginationStrutPropagatedFromChild = strut;
3854 } 4022 }
3855 4023
3856 void LayoutBlockFlow::positionSpannerDescendant( 4024 void LayoutBlockFlow::positionSpannerDescendant(
3857 LayoutMultiColumnSpannerPlaceholder& child) { 4025 LayoutMultiColumnSpannerPlaceholder& child) {
3858 LayoutBox& spanner = *child.layoutObjectInFlowThread(); 4026 LayoutBox& spanner = *child.layoutObjectInFlowThread();
3859 // FIXME: |spanner| is a descendant, but never a direct child, so the names he re are bad, if 4027 // FIXME: |spanner| is a descendant, but never a direct child, so the names
3860 // nothing else. 4028 // here are bad, if nothing else.
3861 setLogicalTopForChild(spanner, child.logicalTop()); 4029 setLogicalTopForChild(spanner, child.logicalTop());
3862 determineLogicalLeftPositionForChild(spanner); 4030 determineLogicalLeftPositionForChild(spanner);
3863 } 4031 }
3864 4032
3865 bool LayoutBlockFlow::avoidsFloats() const { 4033 bool LayoutBlockFlow::avoidsFloats() const {
3866 // Floats can't intrude into our box if we have a non-auto column count or wid th. 4034 // Floats can't intrude into our box if we have a non-auto column count or
3867 // Note: we need to use LayoutBox::avoidsFloats here since LayoutBlock::avoids Floats is always true. 4035 // width.
4036 // Note: we need to use LayoutBox::avoidsFloats here since
4037 // LayoutBlock::avoidsFloats is always true.
3868 return LayoutBox::avoidsFloats() || !style()->hasAutoColumnCount() || 4038 return LayoutBox::avoidsFloats() || !style()->hasAutoColumnCount() ||
3869 !style()->hasAutoColumnWidth(); 4039 !style()->hasAutoColumnWidth();
3870 } 4040 }
3871 4041
3872 void LayoutBlockFlow::moveChildrenTo(LayoutBoxModelObject* toBoxModelObject, 4042 void LayoutBlockFlow::moveChildrenTo(LayoutBoxModelObject* toBoxModelObject,
3873 LayoutObject* startChild, 4043 LayoutObject* startChild,
3874 LayoutObject* endChild, 4044 LayoutObject* endChild,
3875 LayoutObject* beforeChild, 4045 LayoutObject* beforeChild,
3876 bool fullRemoveInsert) { 4046 bool fullRemoveInsert) {
3877 if (childrenInline()) 4047 if (childrenInline())
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
3939 // Paged overflow is currently done using the multicol implementation. 4109 // Paged overflow is currently done using the multicol implementation.
3940 return LayoutPagedFlowThread::createAnonymous(document(), styleRef()); 4110 return LayoutPagedFlowThread::createAnonymous(document(), styleRef());
3941 default: 4111 default:
3942 ASSERT_NOT_REACHED(); 4112 ASSERT_NOT_REACHED();
3943 return nullptr; 4113 return nullptr;
3944 } 4114 }
3945 } 4115 }
3946 4116
3947 void LayoutBlockFlow::createOrDestroyMultiColumnFlowThreadIfNeeded( 4117 void LayoutBlockFlow::createOrDestroyMultiColumnFlowThreadIfNeeded(
3948 const ComputedStyle* oldStyle) { 4118 const ComputedStyle* oldStyle) {
3949 // Paged overflow trumps multicol in this implementation. Ideally, it should b e possible to have 4119 // Paged overflow trumps multicol in this implementation. Ideally, it should
3950 // both paged overflow and multicol on the same element, but then we need two flow 4120 // be possible to have both paged overflow and multicol on the same element,
3951 // threads. Anyway, this is nothing to worry about until we can actually nest multicol properly 4121 // but then we need two flow threads. Anyway, this is nothing to worry about
3952 // inside other fragmentation contexts. 4122 // until we can actually nest multicol properly inside other fragmentation
4123 // contexts.
3953 FlowThreadType type = getFlowThreadType(styleRef()); 4124 FlowThreadType type = getFlowThreadType(styleRef());
3954 4125
3955 if (multiColumnFlowThread()) { 4126 if (multiColumnFlowThread()) {
3956 ASSERT(oldStyle); 4127 ASSERT(oldStyle);
3957 if (type != getFlowThreadType(*oldStyle)) { 4128 if (type != getFlowThreadType(*oldStyle)) {
3958 // If we're no longer to be multicol/paged, destroy the flow thread. Also destroy it 4129 // If we're no longer to be multicol/paged, destroy the flow thread. Also
3959 // when switching between multicol and paged, since that affects the colum n set 4130 // destroy it when switching between multicol and paged, since that
3960 // structure (multicol containers may have spanners, paged containers may not). 4131 // affects the column set structure (multicol containers may have
4132 // spanners, paged containers may not).
3961 multiColumnFlowThread()->evacuateAndDestroy(); 4133 multiColumnFlowThread()->evacuateAndDestroy();
3962 ASSERT(!multiColumnFlowThread()); 4134 ASSERT(!multiColumnFlowThread());
3963 } 4135 }
3964 } 4136 }
3965 4137
3966 if (type == NoFlowThread || multiColumnFlowThread()) 4138 if (type == NoFlowThread || multiColumnFlowThread())
3967 return; 4139 return;
3968 4140
3969 // Ruby elements manage child insertion in a special way, and would mess up in sertion of the 4141 // Ruby elements manage child insertion in a special way, and would mess up
3970 // flow thread. The flow thread needs to be a direct child of the multicol blo ck (|this|). 4142 // insertion of the flow thread. The flow thread needs to be a direct child of
4143 // the multicol block (|this|).
3971 if (isRuby()) 4144 if (isRuby())
3972 return; 4145 return;
3973 4146
3974 // Form controls are replaced content, and are therefore not supposed to suppo rt multicol. 4147 // Form controls are replaced content, and are therefore not supposed to
4148 // support multicol.
3975 if (isFileUploadControl() || isTextControl() || isListBox()) 4149 if (isFileUploadControl() || isTextControl() || isListBox())
3976 return; 4150 return;
3977 4151
3978 LayoutMultiColumnFlowThread* flowThread = createMultiColumnFlowThread(type); 4152 LayoutMultiColumnFlowThread* flowThread = createMultiColumnFlowThread(type);
3979 addChild(flowThread); 4153 addChild(flowThread);
3980 4154
3981 // Check that addChild() put the flow thread as a direct child, and didn't do fancy things. 4155 // Check that addChild() put the flow thread as a direct child, and didn't do
4156 // fancy things.
3982 ASSERT(flowThread->parent() == this); 4157 ASSERT(flowThread->parent() == this);
3983 4158
3984 flowThread->populate(); 4159 flowThread->populate();
3985 LayoutBlockFlowRareData& rareData = ensureRareData(); 4160 LayoutBlockFlowRareData& rareData = ensureRareData();
3986 ASSERT(!rareData.m_multiColumnFlowThread); 4161 ASSERT(!rareData.m_multiColumnFlowThread);
3987 rareData.m_multiColumnFlowThread = flowThread; 4162 rareData.m_multiColumnFlowThread = flowThread;
3988 } 4163 }
3989 4164
3990 LayoutBlockFlow::LayoutBlockFlowRareData& LayoutBlockFlow::ensureRareData() { 4165 LayoutBlockFlow::LayoutBlockFlowRareData& LayoutBlockFlow::ensureRareData() {
3991 if (m_rareData) 4166 if (m_rareData)
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
4039 if (toLayoutBox(o)->inlineBoxWrapper()) { 4214 if (toLayoutBox(o)->inlineBoxWrapper()) {
4040 RootInlineBox& box = toLayoutBox(o)->inlineBoxWrapper()->root(); 4215 RootInlineBox& box = toLayoutBox(o)->inlineBoxWrapper()->root();
4041 lineBoxes.add(&box); 4216 lineBoxes.add(&box);
4042 } 4217 }
4043 } else if (o->isText() || 4218 } else if (o->isText() ||
4044 (o->isLayoutInline() && !walker.atEndOfInline())) { 4219 (o->isLayoutInline() && !walker.atEndOfInline())) {
4045 o->clearNeedsLayout(); 4220 o->clearNeedsLayout();
4046 } 4221 }
4047 } 4222 }
4048 4223
4049 // FIXME: Glyph overflow will get lost in this case, but not really a big deal . 4224 // FIXME: Glyph overflow will get lost in this case, but not really a big
4225 // deal.
4050 GlyphOverflowAndFallbackFontsMap textBoxDataMap; 4226 GlyphOverflowAndFallbackFontsMap textBoxDataMap;
4051 for (ListHashSet<RootInlineBox*>::const_iterator it = lineBoxes.begin(); 4227 for (ListHashSet<RootInlineBox*>::const_iterator it = lineBoxes.begin();
4052 it != lineBoxes.end(); ++it) { 4228 it != lineBoxes.end(); ++it) {
4053 RootInlineBox* box = *it; 4229 RootInlineBox* box = *it;
4054 box->computeOverflow(box->lineTop(), box->lineBottom(), textBoxDataMap); 4230 box->computeOverflow(box->lineTop(), box->lineBottom(), textBoxDataMap);
4055 } 4231 }
4056 } 4232 }
4057 4233
4058 bool LayoutBlockFlow::recalcInlineChildrenOverflowAfterStyleChange() { 4234 bool LayoutBlockFlow::recalcInlineChildrenOverflowAfterStyleChange() {
4059 ASSERT(childrenInline()); 4235 ASSERT(childrenInline());
4060 bool childrenOverflowChanged = false; 4236 bool childrenOverflowChanged = false;
4061 ListHashSet<RootInlineBox*> lineBoxes; 4237 ListHashSet<RootInlineBox*> lineBoxes;
4062 for (InlineWalker walker(LineLayoutBlockFlow(this)); !walker.atEnd(); 4238 for (InlineWalker walker(LineLayoutBlockFlow(this)); !walker.atEnd();
4063 walker.advance()) { 4239 walker.advance()) {
4064 LayoutObject* layoutObject = walker.current().layoutObject(); 4240 LayoutObject* layoutObject = walker.current().layoutObject();
4065 if (recalcNormalFlowChildOverflowIfNeeded(layoutObject)) { 4241 if (recalcNormalFlowChildOverflowIfNeeded(layoutObject)) {
4066 childrenOverflowChanged = true; 4242 childrenOverflowChanged = true;
4067 if (InlineBox* inlineBoxWrapper = 4243 if (InlineBox* inlineBoxWrapper =
4068 toLayoutBlock(layoutObject)->inlineBoxWrapper()) 4244 toLayoutBlock(layoutObject)->inlineBoxWrapper())
4069 lineBoxes.add(&inlineBoxWrapper->root()); 4245 lineBoxes.add(&inlineBoxWrapper->root());
4070 } 4246 }
4071 } 4247 }
4072 4248
4073 // FIXME: Glyph overflow will get lost in this case, but not really a big deal . 4249 // FIXME: Glyph overflow will get lost in this case, but not really a big
4250 // deal.
4074 GlyphOverflowAndFallbackFontsMap textBoxDataMap; 4251 GlyphOverflowAndFallbackFontsMap textBoxDataMap;
4075 for (ListHashSet<RootInlineBox*>::const_iterator it = lineBoxes.begin(); 4252 for (ListHashSet<RootInlineBox*>::const_iterator it = lineBoxes.begin();
4076 it != lineBoxes.end(); ++it) { 4253 it != lineBoxes.end(); ++it) {
4077 RootInlineBox* box = *it; 4254 RootInlineBox* box = *it;
4078 box->clearKnownToHaveNoOverflow(); 4255 box->clearKnownToHaveNoOverflow();
4079 box->computeOverflow(box->lineTop(), box->lineBottom(), textBoxDataMap); 4256 box->computeOverflow(box->lineTop(), box->lineBottom(), textBoxDataMap);
4080 } 4257 }
4081 return childrenOverflowChanged; 4258 return childrenOverflowChanged;
4082 } 4259 }
4083 4260
(...skipping 13 matching lines...) Expand all
4097 LayoutPoint pointInLogicalContents(pointInContents); 4274 LayoutPoint pointInLogicalContents(pointInContents);
4098 if (!isHorizontalWritingMode()) 4275 if (!isHorizontalWritingMode())
4099 pointInLogicalContents = pointInLogicalContents.transposedPoint(); 4276 pointInLogicalContents = pointInLogicalContents.transposedPoint();
4100 4277
4101 if (!firstRootBox()) 4278 if (!firstRootBox())
4102 return createPositionWithAffinity(0); 4279 return createPositionWithAffinity(0);
4103 4280
4104 bool linesAreFlipped = style()->isFlippedLinesWritingMode(); 4281 bool linesAreFlipped = style()->isFlippedLinesWritingMode();
4105 bool blocksAreFlipped = style()->isFlippedBlocksWritingMode(); 4282 bool blocksAreFlipped = style()->isFlippedBlocksWritingMode();
4106 4283
4107 // look for the closest line box in the root box which is at the passed-in y c oordinate 4284 // look for the closest line box in the root box which is at the passed-in y
4285 // coordinate
4108 InlineBox* closestBox = nullptr; 4286 InlineBox* closestBox = nullptr;
4109 RootInlineBox* firstRootBoxWithChildren = nullptr; 4287 RootInlineBox* firstRootBoxWithChildren = nullptr;
4110 RootInlineBox* lastRootBoxWithChildren = nullptr; 4288 RootInlineBox* lastRootBoxWithChildren = nullptr;
4111 for (RootInlineBox* root = firstRootBox(); root; root = root->nextRootBox()) { 4289 for (RootInlineBox* root = firstRootBox(); root; root = root->nextRootBox()) {
4112 if (!root->firstLeafChild()) 4290 if (!root->firstLeafChild())
4113 continue; 4291 continue;
4114 if (!firstRootBoxWithChildren) 4292 if (!firstRootBoxWithChildren)
4115 firstRootBoxWithChildren = root; 4293 firstRootBoxWithChildren = root;
4116 4294
4117 if (!linesAreFlipped && root->isFirstAfterPageBreak() && 4295 if (!linesAreFlipped && root->isFirstAfterPageBreak() &&
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
4168 std::min<LayoutUnit>(firstRootBoxWithChildren->selectionTop(), 4346 std::min<LayoutUnit>(firstRootBoxWithChildren->selectionTop(),
4169 firstRootBoxWithChildren->logicalTop()); 4347 firstRootBoxWithChildren->logicalTop());
4170 if (pointInLogicalContents.y() < firstRootBoxWithChildrenTop || 4348 if (pointInLogicalContents.y() < firstRootBoxWithChildrenTop ||
4171 (blocksAreFlipped && 4349 (blocksAreFlipped &&
4172 pointInLogicalContents.y() == firstRootBoxWithChildrenTop)) { 4350 pointInLogicalContents.y() == firstRootBoxWithChildrenTop)) {
4173 InlineBox* box = firstRootBoxWithChildren->firstLeafChild(); 4351 InlineBox* box = firstRootBoxWithChildren->firstLeafChild();
4174 if (box->isLineBreak()) { 4352 if (box->isLineBreak()) {
4175 if (InlineBox* newBox = box->nextLeafChildIgnoringLineBreak()) 4353 if (InlineBox* newBox = box->nextLeafChildIgnoringLineBreak())
4176 box = newBox; 4354 box = newBox;
4177 } 4355 }
4178 // y coordinate is above first root line box, so return the start of the first 4356 // y coordinate is above first root line box, so return the start of the
4357 // first
4179 return PositionWithAffinity(positionForBox(box, true)); 4358 return PositionWithAffinity(positionForBox(box, true));
4180 } 4359 }
4181 } 4360 }
4182 4361
4183 // pass the box a top position that is inside it 4362 // pass the box a top position that is inside it
4184 LayoutPoint point(pointInLogicalContents.x(), 4363 LayoutPoint point(pointInLogicalContents.x(),
4185 closestBox->root().blockDirectionPointInLine()); 4364 closestBox->root().blockDirectionPointInLine());
4186 if (!isHorizontalWritingMode()) 4365 if (!isHorizontalWritingMode())
4187 point = point.transposedPoint(); 4366 point = point.transposedPoint();
4188 if (closestBox->getLineLayoutItem().isAtomicInlineLevel()) 4367 if (closestBox->getLineLayoutItem().isAtomicInlineLevel())
4189 return positionForPointRespectingEditingBoundaries( 4368 return positionForPointRespectingEditingBoundaries(
4190 LineLayoutBox(closestBox->getLineLayoutItem()), point); 4369 LineLayoutBox(closestBox->getLineLayoutItem()), point);
4191 return closestBox->getLineLayoutItem().positionForPoint(point); 4370 return closestBox->getLineLayoutItem().positionForPoint(point);
4192 } 4371 }
4193 4372
4194 if (lastRootBoxWithChildren) { 4373 if (lastRootBoxWithChildren) {
4195 // We hit this case for Mac behavior when the Y coordinate is below the last box. 4374 // We hit this case for Mac behavior when the Y coordinate is below the last
4375 // box.
4196 ASSERT(moveCaretToBoundary); 4376 ASSERT(moveCaretToBoundary);
4197 InlineBox* logicallyLastBox; 4377 InlineBox* logicallyLastBox;
4198 if (lastRootBoxWithChildren->getLogicalEndBoxWithNode(logicallyLastBox)) 4378 if (lastRootBoxWithChildren->getLogicalEndBoxWithNode(logicallyLastBox))
4199 return PositionWithAffinity(positionForBox(logicallyLastBox, false)); 4379 return PositionWithAffinity(positionForBox(logicallyLastBox, false));
4200 } 4380 }
4201 4381
4202 // Can't reach this. We have a root line box, but it has no kids. 4382 // Can't reach this. We have a root line box, but it has no kids.
4203 // FIXME: This should ASSERT_NOT_REACHED(), but clicking on placeholder text 4383 // FIXME: This should ASSERT_NOT_REACHED(), but clicking on placeholder text
4204 // seems to hit this code path. 4384 // seems to hit this code path.
4205 return createPositionWithAffinity(0); 4385 return createPositionWithAffinity(0);
(...skipping 12 matching lines...) Expand all
4218 root->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, 4398 root->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2,
4219 markedLabel2, obj, 1); 4399 markedLabel2, obj, 1);
4220 } 4400 }
4221 4401
4222 #endif 4402 #endif
4223 4403
4224 void LayoutBlockFlow::addOutlineRects( 4404 void LayoutBlockFlow::addOutlineRects(
4225 Vector<LayoutRect>& rects, 4405 Vector<LayoutRect>& rects,
4226 const LayoutPoint& additionalOffset, 4406 const LayoutPoint& additionalOffset,
4227 IncludeBlockVisualOverflowOrNot includeBlockOverflows) const { 4407 IncludeBlockVisualOverflowOrNot includeBlockOverflows) const {
4228 // For blocks inside inlines, we go ahead and include margins so that we run r ight up to the 4408 // For blocks inside inlines, we go ahead and include margins so that we run
4229 // inline boxes above and below us (thus getting merged with them to form a si ngle irregular 4409 // right up to the inline boxes above and below us (thus getting merged with
4230 // shape). 4410 // them to form a single irregular shape).
4231 const LayoutInline* inlineElementContinuation = 4411 const LayoutInline* inlineElementContinuation =
4232 this->inlineElementContinuation(); 4412 this->inlineElementContinuation();
4233 if (inlineElementContinuation) { 4413 if (inlineElementContinuation) {
4234 // FIXME: This check really isn't accurate. 4414 // FIXME: This check really isn't accurate.
4235 bool nextInlineHasLineBox = inlineElementContinuation->firstLineBox(); 4415 bool nextInlineHasLineBox = inlineElementContinuation->firstLineBox();
4236 // FIXME: This is wrong. The principal layoutObject may not be the continuat ion preceding this block. 4416 // FIXME: This is wrong. The principal layoutObject may not be the
4417 // continuation preceding this block.
4237 // FIXME: This is wrong for vertical writing-modes. 4418 // FIXME: This is wrong for vertical writing-modes.
4238 // https://bugs.webkit.org/show_bug.cgi?id=46781 4419 // https://bugs.webkit.org/show_bug.cgi?id=46781
4239 bool prevInlineHasLineBox = 4420 bool prevInlineHasLineBox =
4240 toLayoutInline(inlineElementContinuation->node()->layoutObject()) 4421 toLayoutInline(inlineElementContinuation->node()->layoutObject())
4241 ->firstLineBox(); 4422 ->firstLineBox();
4242 LayoutUnit topMargin = 4423 LayoutUnit topMargin =
4243 prevInlineHasLineBox ? collapsedMarginBefore() : LayoutUnit(); 4424 prevInlineHasLineBox ? collapsedMarginBefore() : LayoutUnit();
4244 LayoutUnit bottomMargin = 4425 LayoutUnit bottomMargin =
4245 nextInlineHasLineBox ? collapsedMarginAfter() : LayoutUnit(); 4426 nextInlineHasLineBox ? collapsedMarginAfter() : LayoutUnit();
4246 if (topMargin || bottomMargin) { 4427 if (topMargin || bottomMargin) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
4282 return LayoutBlock::invalidatePaintIfNeeded(paintInvalidationState); 4463 return LayoutBlock::invalidatePaintIfNeeded(paintInvalidationState);
4283 } 4464 }
4284 4465
4285 void LayoutBlockFlow::invalidateDisplayItemClients( 4466 void LayoutBlockFlow::invalidateDisplayItemClients(
4286 PaintInvalidationReason invalidationReason) const { 4467 PaintInvalidationReason invalidationReason) const {
4287 BlockFlowPaintInvalidator(*this).invalidateDisplayItemClients( 4468 BlockFlowPaintInvalidator(*this).invalidateDisplayItemClients(
4288 invalidationReason); 4469 invalidationReason);
4289 } 4470 }
4290 4471
4291 } // namespace blink 4472 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/layout/LayoutBlockFlow.h ('k') | third_party/WebKit/Source/core/layout/LayoutBlockFlowLine.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698