| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2012 Apple Inc. All rights reserved. | 2 * Copyright (C) 2012 Apple 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 | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 354 m_inBalancingPass = needsRelayout; | 354 m_inBalancingPass = needsRelayout; |
| 355 return needsRelayout; | 355 return needsRelayout; |
| 356 } | 356 } |
| 357 | 357 |
| 358 void LayoutMultiColumnFlowThread::columnRuleStyleDidChange() | 358 void LayoutMultiColumnFlowThread::columnRuleStyleDidChange() |
| 359 { | 359 { |
| 360 for (LayoutMultiColumnSet* columnSet = firstMultiColumnSet(); columnSet; col
umnSet = columnSet->nextSiblingMultiColumnSet()) | 360 for (LayoutMultiColumnSet* columnSet = firstMultiColumnSet(); columnSet; col
umnSet = columnSet->nextSiblingMultiColumnSet()) |
| 361 columnSet->setShouldDoFullPaintInvalidation(PaintInvalidationStyleChange
); | 361 columnSet->setShouldDoFullPaintInvalidation(PaintInvalidationStyleChange
); |
| 362 } | 362 } |
| 363 | 363 |
| 364 bool LayoutMultiColumnFlowThread::removeSpannerPlaceholderIfNoLongerValid(Layout
Box* spannerObjectInFlowThread) |
| 365 { |
| 366 ASSERT(spannerObjectInFlowThread->spannerPlaceholder()); |
| 367 if (descendantIsValidColumnSpanner(spannerObjectInFlowThread)) |
| 368 return false; // Still a valid spanner. |
| 369 |
| 370 // No longer a valid spanner. Get rid of the placeholder. |
| 371 destroySpannerPlaceholder(spannerObjectInFlowThread->spannerPlaceholder()); |
| 372 ASSERT(!spannerObjectInFlowThread->spannerPlaceholder()); |
| 373 |
| 374 // We may have a new containing block, since we're no longer a spanner. Mark
it for relayout. |
| 375 spannerObjectInFlowThread->containingBlock()->setNeedsLayoutAndPrefWidthsRec
alc(LayoutInvalidationReason::ColumnsChanged); |
| 376 |
| 377 // Now generate a column set for this ex-spanner, if needed and none is ther
e for us already. |
| 378 flowThreadDescendantWasInserted(spannerObjectInFlowThread); |
| 379 |
| 380 return true; |
| 381 } |
| 382 |
| 364 void LayoutMultiColumnFlowThread::calculateColumnCountAndWidth(LayoutUnit& width
, unsigned& count) const | 383 void LayoutMultiColumnFlowThread::calculateColumnCountAndWidth(LayoutUnit& width
, unsigned& count) const |
| 365 { | 384 { |
| 366 LayoutBlock* columnBlock = multiColumnBlockFlow(); | 385 LayoutBlock* columnBlock = multiColumnBlockFlow(); |
| 367 const ComputedStyle* columnStyle = columnBlock->style(); | 386 const ComputedStyle* columnStyle = columnBlock->style(); |
| 368 LayoutUnit availableWidth = columnBlock->contentLogicalWidth(); | 387 LayoutUnit availableWidth = columnBlock->contentLogicalWidth(); |
| 369 LayoutUnit columnGap = columnBlock->columnGap(); | 388 LayoutUnit columnGap = columnBlock->columnGap(); |
| 370 LayoutUnit computedColumnWidth = max<LayoutUnit>(1, LayoutUnit(columnStyle->
columnWidth())); | 389 LayoutUnit computedColumnWidth = max<LayoutUnit>(1, LayoutUnit(columnStyle->
columnWidth())); |
| 371 unsigned computedColumnCount = max<int>(1, columnStyle->columnCount()); | 390 unsigned computedColumnCount = max<int>(1, columnStyle->columnCount()); |
| 372 | 391 |
| 373 ASSERT(!columnStyle->hasAutoColumnCount() || !columnStyle->hasAutoColumnWidt
h()); | 392 ASSERT(!columnStyle->hasAutoColumnCount() || !columnStyle->hasAutoColumnWidt
h()); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 451 nextColumnBox->destroy(); | 470 nextColumnBox->destroy(); |
| 452 previousColumnBox->setNeedsLayout(LayoutInvalidationReason::ColumnsC
hanged); | 471 previousColumnBox->setNeedsLayout(LayoutInvalidationReason::ColumnsC
hanged); |
| 453 invalidateColumnSets(); | 472 invalidateColumnSets(); |
| 454 } | 473 } |
| 455 } | 474 } |
| 456 placeholder->destroy(); | 475 placeholder->destroy(); |
| 457 } | 476 } |
| 458 | 477 |
| 459 bool LayoutMultiColumnFlowThread::descendantIsValidColumnSpanner(LayoutObject* d
escendant) const | 478 bool LayoutMultiColumnFlowThread::descendantIsValidColumnSpanner(LayoutObject* d
escendant) const |
| 460 { | 479 { |
| 480 // This method needs to behave correctly in the following situations: |
| 481 // - When the descendant doesn't have a spanner placeholder but should have
one (return true) |
| 482 // - When the descendant doesn't have a spanner placeholder and still should
not have one (return false) |
| 483 // - When the descendant has a spanner placeholder but should no longer have
one (return false) |
| 484 // - When the descendant has a spanner placeholder and should still have one
(return true) |
| 485 |
| 461 // We assume that we're inside the flow thread. This function is not to be c
alled otherwise. | 486 // We assume that we're inside the flow thread. This function is not to be c
alled otherwise. |
| 462 ASSERT(descendant->isDescendantOf(this)); | 487 ASSERT(descendant->isDescendantOf(this)); |
| 463 | 488 |
| 464 // We're evaluating if the descendant should be turned into a proper spanner
. It shouldn't | |
| 465 // already be one. | |
| 466 ASSERT(!descendant->spannerPlaceholder()); | |
| 467 | |
| 468 // The spec says that column-span only applies to in-flow block-level elemen
ts. | 489 // The spec says that column-span only applies to in-flow block-level elemen
ts. |
| 469 if (descendant->style()->columnSpan() != ColumnSpanAll || !descendant->isBox
() || descendant->isInline() || descendant->isFloatingOrOutOfFlowPositioned()) | 490 if (descendant->style()->columnSpan() != ColumnSpanAll || !descendant->isBox
() || descendant->isInline() || descendant->isFloatingOrOutOfFlowPositioned()) |
| 470 return false; | 491 return false; |
| 471 | 492 |
| 472 if (!descendant->containingBlock()->isLayoutBlockFlow()) { | 493 if (!descendant->containingBlock()->isLayoutBlockFlow()) { |
| 473 // Needs to be in a block-flow container, and not e.g. a table. | 494 // Needs to be in a block-flow container, and not e.g. a table. |
| 474 return false; | 495 return false; |
| 475 } | 496 } |
| 476 | 497 |
| 477 // This looks like a spanner, but if we're inside something unbreakable, it'
s not to be treated as one. | 498 // This looks like a spanner, but if we're inside something unbreakable, it'
s not to be treated as one. |
| 478 for (LayoutBlock* ancestor = descendant->containingBlock(); ancestor; ancest
or = ancestor->containingBlock()) { | 499 for (LayoutBox* ancestor = toLayoutBox(descendant)->parentBox(); ancestor; a
ncestor = ancestor->containingBlock()) { |
| 479 if (ancestor->isLayoutFlowThread()) { | 500 if (ancestor->isLayoutFlowThread()) { |
| 480 ASSERT(ancestor == this); | 501 ASSERT(ancestor == this); |
| 481 return true; | 502 return true; |
| 482 } | 503 } |
| 483 if (ancestor->spannerPlaceholder()) { | 504 if (ancestor->spannerPlaceholder()) { |
| 484 // FIXME: do we want to support nested spanners in a different way?
The outer spanner | 505 // FIXME: do we want to support nested spanners in a different way?
The outer spanner |
| 485 // has already broken out from the columns to become sized by the mu
lticol container, | 506 // has already broken out from the columns to become sized by the mu
lticol container, |
| 486 // which may be good enough for the inner spanner. But margins, bord
ers, padding and | 507 // which may be good enough for the inner spanner. But margins, bord
ers, padding and |
| 487 // explicit widths on the outer spanner, or on any children between
the outer and inner | 508 // explicit widths on the outer spanner, or on any children between
the outer and inner |
| 488 // spanner, will affect the width of the inner spanner this way, whi
ch might be | 509 // spanner, will affect the width of the inner spanner this way, whi
ch might be |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 705 void LayoutMultiColumnFlowThread::flowThreadDescendantStyleDidChange(LayoutObjec
t* descendant, StyleDifference diff, const ComputedStyle& oldStyle) | 726 void LayoutMultiColumnFlowThread::flowThreadDescendantStyleDidChange(LayoutObjec
t* descendant, StyleDifference diff, const ComputedStyle& oldStyle) |
| 706 { | 727 { |
| 707 // If an out-of-flow descendant goes in-flow, we may have to insert a column
set. | 728 // If an out-of-flow descendant goes in-flow, we may have to insert a column
set. |
| 708 if (descendant->isText()) { | 729 if (descendant->isText()) { |
| 709 // Text nodes inherit all properties from the parent node (including non
-inheritable | 730 // Text nodes inherit all properties from the parent node (including non
-inheritable |
| 710 // ones). We don't care what its 'position' is. In fact, we _must_ ignor
e it, since the | 731 // ones). We don't care what its 'position' is. In fact, we _must_ ignor
e it, since the |
| 711 // parent may be the multicol container, and having that accidentally le
aked into children | 732 // parent may be the multicol container, and having that accidentally le
aked into children |
| 712 // of the multicol is bad. | 733 // of the multicol is bad. |
| 713 return; | 734 return; |
| 714 } | 735 } |
| 715 if (oldStyle.hasOutOfFlowPosition() && !styleRef().hasOutOfFlowPosition()) | 736 if (styleRef().hasOutOfFlowPosition()) |
| 737 return; |
| 738 |
| 739 // We're not out of flow. |
| 740 if (oldStyle.hasOutOfFlowPosition()) { |
| 741 // ... but we used to be out of flow. So we might need to insert a colum
n set (or |
| 742 // spanner placeholder, in case this descendant is now a valid column sp
anner). |
| 716 flowThreadDescendantWasInserted(descendant); | 743 flowThreadDescendantWasInserted(descendant); |
| 744 return; |
| 745 } |
| 746 if (descendantIsValidColumnSpanner(descendant)) { |
| 747 // We went from being regular column content to becoming a spanner. |
| 748 ASSERT(!toLayoutBox(descendant)->spannerPlaceholder()); |
| 749 |
| 750 // First remove this as regular column content. Note that this will walk
the entire subtree |
| 751 // of |descendant|. There might be spanners there (which won't be spanne
rs anymore, since |
| 752 // we're not allowed to nest spanners), whose placeholders must die. |
| 753 flowThreadDescendantWillBeRemoved(descendant); |
| 754 |
| 755 createAndInsertSpannerPlaceholder(toLayoutBox(descendant), nextInPreOrde
rAfterChildrenSkippingOutOfFlow(this, descendant)); |
| 756 } |
| 717 } | 757 } |
| 718 | 758 |
| 719 void LayoutMultiColumnFlowThread::computePreferredLogicalWidths() | 759 void LayoutMultiColumnFlowThread::computePreferredLogicalWidths() |
| 720 { | 760 { |
| 721 LayoutFlowThread::computePreferredLogicalWidths(); | 761 LayoutFlowThread::computePreferredLogicalWidths(); |
| 722 | 762 |
| 723 // The min/max intrinsic widths calculated really tell how much space elemen
ts need when | 763 // The min/max intrinsic widths calculated really tell how much space elemen
ts need when |
| 724 // laid out inside the columns. In order to eventually end up with the desir
ed column width, | 764 // laid out inside the columns. In order to eventually end up with the desir
ed column width, |
| 725 // we need to convert them to values pertaining to the multicol container. | 765 // we need to convert them to values pertaining to the multicol container. |
| 726 const LayoutBlockFlow* multicolContainer = multiColumnBlockFlow(); | 766 const LayoutBlockFlow* multicolContainer = multiColumnBlockFlow(); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 804 } | 844 } |
| 805 | 845 |
| 806 bool LayoutMultiColumnFlowThread::isPageLogicalHeightKnown() const | 846 bool LayoutMultiColumnFlowThread::isPageLogicalHeightKnown() const |
| 807 { | 847 { |
| 808 if (LayoutMultiColumnSet* columnSet = lastMultiColumnSet()) | 848 if (LayoutMultiColumnSet* columnSet = lastMultiColumnSet()) |
| 809 return columnSet->pageLogicalHeight(); | 849 return columnSet->pageLogicalHeight(); |
| 810 return false; | 850 return false; |
| 811 } | 851 } |
| 812 | 852 |
| 813 } | 853 } |
| OLD | NEW |