OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
290 { | 290 { |
291 ASSERT(shouldBreakAtLineToAvoidWidow()); | 291 ASSERT(shouldBreakAtLineToAvoidWidow()); |
292 if (!m_rareData) | 292 if (!m_rareData) |
293 return; | 293 return; |
294 | 294 |
295 m_rareData->m_lineBreakToAvoidWidow = -1; | 295 m_rareData->m_lineBreakToAvoidWidow = -1; |
296 } | 296 } |
297 | 297 |
298 bool LayoutBlockFlow::isSelfCollapsingBlock() const | 298 bool LayoutBlockFlow::isSelfCollapsingBlock() const |
299 { | 299 { |
300 m_hasOnlySelfCollapsingChildren = LayoutBlock::isSelfCollapsingBlock(); | 300 if (needsLayout()) { |
301 return m_hasOnlySelfCollapsingChildren; | 301 // Sometimes we don't lay out objects in DOM order (column spanners bein
g one such relevant |
| 302 // type of object right here). As long as the object in question establi
shes a new |
| 303 // formatting context, that's nothing to worry about, though. |
| 304 ASSERT(createsNewFormattingContext()); |
| 305 return false; |
| 306 } |
| 307 ASSERT(!m_isSelfCollapsing == !checkIfIsSelfCollapsingBlock()); |
| 308 return m_isSelfCollapsing; |
| 309 } |
| 310 |
| 311 bool LayoutBlockFlow::checkIfIsSelfCollapsingBlock() const |
| 312 { |
| 313 // We are not self-collapsing if we |
| 314 // (a) have a non-zero height according to layout (an optimization to avoid
wasting time) |
| 315 // (b) have border/padding, |
| 316 // (c) have a min-height |
| 317 // (d) have specified that one of our margins can't collapse using a CSS ext
ension |
| 318 // (e) establish a new block formatting context. |
| 319 |
| 320 // The early exit must be done before we check for clean layout. |
| 321 // We should be able to give a quick answer if the box is a relayout boundar
y. |
| 322 // Being a relayout boundary implies a block formatting context, and also |
| 323 // our internal layout shouldn't affect our container in any way. |
| 324 if (createsNewFormattingContext()) |
| 325 return false; |
| 326 |
| 327 // Placeholder elements are not laid out until the dimensions of their paren
t text control are known, so they |
| 328 // don't get layout until their parent has had layout - this is unique in th
e layout tree and means |
| 329 // when we call isSelfCollapsingBlock on them we find that they still need l
ayout. |
| 330 ASSERT(!needsLayout() || (node() && node()->isElementNode() && toElement(nod
e())->shadowPseudoId() == "-webkit-input-placeholder")); |
| 331 |
| 332 if (logicalHeight() > LayoutUnit() |
| 333 || borderAndPaddingLogicalHeight() |
| 334 || style()->logicalMinHeight().isPositive() |
| 335 || style()->marginBeforeCollapse() == MarginCollapseSeparate || style()-
>marginAfterCollapse() == MarginCollapseSeparate) |
| 336 return false; |
| 337 |
| 338 Length logicalHeightLength = style()->logicalHeight(); |
| 339 bool hasAutoHeight = logicalHeightLength.isAuto(); |
| 340 if (logicalHeightLength.hasPercent() && !document().inQuirksMode()) { |
| 341 hasAutoHeight = true; |
| 342 for (LayoutBlock* cb = containingBlock(); !cb->isLayoutView(); cb = cb->
containingBlock()) { |
| 343 if (cb->style()->logicalHeight().isFixed() || cb->isTableCell()) |
| 344 hasAutoHeight = false; |
| 345 } |
| 346 } |
| 347 |
| 348 // If the height is 0 or auto, then whether or not we are a self-collapsing
block depends |
| 349 // on whether we have content that is all self-collapsing or not. |
| 350 // TODO(alancutter): Make this work correctly for calc lengths. |
| 351 if (hasAutoHeight || ((logicalHeightLength.isFixed() || logicalHeightLength.
hasPercent()) && logicalHeightLength.isZero())) { |
| 352 // If the block has inline children, see if we generated any line boxes.
If we have any |
| 353 // line boxes, then we can't be self-collapsing, since we have content. |
| 354 if (childrenInline()) |
| 355 return !firstLineBox(); |
| 356 |
| 357 // Whether or not we collapse is dependent on whether all our normal flo
w children |
| 358 // are also self-collapsing. |
| 359 for (LayoutBox* child = firstChildBox(); child; child = child->nextSibli
ngBox()) { |
| 360 if (child->isFloatingOrOutOfFlowPositioned()) |
| 361 continue; |
| 362 if (!child->isSelfCollapsingBlock()) |
| 363 return false; |
| 364 } |
| 365 return true; |
| 366 } |
| 367 return false; |
302 } | 368 } |
303 | 369 |
304 void LayoutBlockFlow::layoutBlock(bool relayoutChildren) | 370 void LayoutBlockFlow::layoutBlock(bool relayoutChildren) |
305 { | 371 { |
306 ASSERT(needsLayout()); | 372 ASSERT(needsLayout()); |
307 ASSERT(isInlineBlockOrInlineTable() || !isInline()); | 373 ASSERT(isInlineBlockOrInlineTable() || !isInline()); |
308 | 374 |
309 // If we are self-collapsing with self-collapsing descendants this will get
set to save us burrowing through our | |
310 // descendants every time in |isSelfCollapsingBlock|. We reset it here so th
at |isSelfCollapsingBlock| attempts to burrow | |
311 // at least once and so that it always gives a reliable result reflecting th
e latest layout. | |
312 m_hasOnlySelfCollapsingChildren = false; | |
313 | |
314 if (!relayoutChildren && simplifiedLayout()) | 375 if (!relayoutChildren && simplifiedLayout()) |
315 return; | 376 return; |
316 | 377 |
317 LayoutAnalyzer::BlockScope analyzer(*this); | 378 LayoutAnalyzer::BlockScope analyzer(*this); |
318 SubtreeLayoutScope layoutScope(*this); | 379 SubtreeLayoutScope layoutScope(*this); |
319 | 380 |
320 // Multiple passes might be required for column based layout. | 381 // Multiple passes might be required for column based layout. |
321 // The number of passes could be as high as the number of columns. | 382 // The number of passes could be as high as the number of columns. |
322 bool done = false; | 383 bool done = false; |
323 LayoutUnit pageLogicalHeight; | 384 LayoutUnit pageLogicalHeight; |
(...skipping 16 matching lines...) Expand all Loading... |
340 hasVisibleContent = layer->hasVisibleContent(); | 401 hasVisibleContent = layer->hasVisibleContent(); |
341 } | 402 } |
342 if (hasVisibleContent) | 403 if (hasVisibleContent) |
343 setShouldInvalidateOverflowForPaint(); | 404 setShouldInvalidateOverflowForPaint(); |
344 } | 405 } |
345 | 406 |
346 if (isHTMLDialogElement(node()) && isOutOfFlowPositioned()) | 407 if (isHTMLDialogElement(node()) && isOutOfFlowPositioned()) |
347 positionDialog(); | 408 positionDialog(); |
348 | 409 |
349 clearNeedsLayout(); | 410 clearNeedsLayout(); |
| 411 m_isSelfCollapsing = checkIfIsSelfCollapsingBlock(); |
350 } | 412 } |
351 | 413 |
352 inline bool LayoutBlockFlow::layoutBlockFlow(bool relayoutChildren, LayoutUnit &
pageLogicalHeight, SubtreeLayoutScope& layoutScope) | 414 inline bool LayoutBlockFlow::layoutBlockFlow(bool relayoutChildren, LayoutUnit &
pageLogicalHeight, SubtreeLayoutScope& layoutScope) |
353 { | 415 { |
354 LayoutUnit oldLeft = logicalLeft(); | 416 LayoutUnit oldLeft = logicalLeft(); |
355 bool logicalWidthChanged = updateLogicalWidthAndColumnWidth(); | 417 bool logicalWidthChanged = updateLogicalWidthAndColumnWidth(); |
356 relayoutChildren |= logicalWidthChanged; | 418 relayoutChildren |= logicalWidthChanged; |
357 | 419 |
358 rebuildFloatsFromIntruding(); | 420 rebuildFloatsFromIntruding(); |
359 | 421 |
(...skipping 2678 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3038 // FIXME: Glyph overflow will get lost in this case, but not really a big de
al. | 3100 // FIXME: Glyph overflow will get lost in this case, but not really a big de
al. |
3039 GlyphOverflowAndFallbackFontsMap textBoxDataMap; | 3101 GlyphOverflowAndFallbackFontsMap textBoxDataMap; |
3040 for (ListHashSet<RootInlineBox*>::const_iterator it = lineBoxes.begin(); it
!= lineBoxes.end(); ++it) { | 3102 for (ListHashSet<RootInlineBox*>::const_iterator it = lineBoxes.begin(); it
!= lineBoxes.end(); ++it) { |
3041 RootInlineBox* box = *it; | 3103 RootInlineBox* box = *it; |
3042 box->computeOverflow(box->lineTop(), box->lineBottom(), textBoxDataMap); | 3104 box->computeOverflow(box->lineTop(), box->lineBottom(), textBoxDataMap); |
3043 } | 3105 } |
3044 return childrenOverflowChanged; | 3106 return childrenOverflowChanged; |
3045 } | 3107 } |
3046 | 3108 |
3047 } // namespace blink | 3109 } // namespace blink |
OLD | NEW |