| Index: third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
|
| diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
|
| index 9a7fda32cb16d0d61cead49b2d3a0d93e6de72c5..edc7d660a96802fdae0b49e41322fe4dbf32f3fd 100644
|
| --- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
|
| +++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
|
| @@ -41,52 +41,46 @@ bool ShouldShrinkToFit(const NGConstraintSpace& parent_space,
|
| child_style.isFloating() || !is_in_parallel_flow;
|
| }
|
|
|
| -// Updates the fragment's BFC offset if it's not already set.
|
| -void UpdateFragmentBfcOffset(const NGLogicalOffset& offset,
|
| - NGFragmentBuilder* builder) {
|
| - if (!builder->BfcOffset())
|
| - builder->SetBfcOffset(offset);
|
| +// Returns max of 2 {@code WTF::Optional} values.
|
| +template <typename T>
|
| +WTF::Optional<T> OptionalMax(const WTF::Optional<T>& value1,
|
| + const WTF::Optional<T>& value2) {
|
| + if (value1 && value2) {
|
| + return std::max(value1.value(), value2.value());
|
| + } else if (value1) {
|
| + return value1;
|
| + }
|
| + return value2;
|
| }
|
|
|
| -// Adjusts content_size to respect the CSS "clear" property.
|
| -// Picks up the maximum between left/right exclusions and content_size depending
|
| -// on the value of style.clear() property.
|
| -void AdjustToClearance(const std::shared_ptr<NGExclusions>& exclusions,
|
| - const ComputedStyle& style,
|
| - const NGLogicalOffset& from_offset,
|
| - LayoutUnit* content_size) {
|
| - DCHECK(content_size) << "content_size cannot be null here";
|
| +WTF::Optional<LayoutUnit> GetClearanceOffset(
|
| + const std::shared_ptr<NGExclusions>& exclusions,
|
| + const ComputedStyle& style) {
|
| const NGExclusion* right_exclusion = exclusions->last_right_float;
|
| const NGExclusion* left_exclusion = exclusions->last_left_float;
|
|
|
| - LayoutUnit left_block_end_offset = *content_size;
|
| + WTF::Optional<LayoutUnit> left_offset;
|
| if (left_exclusion) {
|
| - left_block_end_offset = std::max(
|
| - left_exclusion->rect.BlockEndOffset() - from_offset.block_offset,
|
| - *content_size);
|
| + left_offset = left_exclusion->rect.BlockEndOffset();
|
| }
|
| - LayoutUnit right_block_end_offset = *content_size;
|
| + WTF::Optional<LayoutUnit> right_offset;
|
| if (right_exclusion) {
|
| - right_block_end_offset = std::max(
|
| - right_exclusion->rect.BlockEndOffset() - from_offset.block_offset,
|
| - *content_size);
|
| + right_offset = right_exclusion->rect.BlockEndOffset();
|
| }
|
|
|
| switch (style.clear()) {
|
| case EClear::kNone:
|
| - return; // nothing to do here.
|
| + return WTF::nullopt; // nothing to do here.
|
| case EClear::kLeft:
|
| - *content_size = left_block_end_offset;
|
| - break;
|
| + return left_offset;
|
| case EClear::kRight:
|
| - *content_size = right_block_end_offset;
|
| - break;
|
| + return right_offset;
|
| case EClear::kBoth:
|
| - *content_size = std::max(left_block_end_offset, right_block_end_offset);
|
| - break;
|
| + return OptionalMax<LayoutUnit>(left_offset, right_offset);
|
| default:
|
| ASSERT_NOT_REACHED();
|
| }
|
| + return WTF::nullopt;
|
| }
|
|
|
| // Creates an exclusion from the fragment that will be placed in the provided
|
| @@ -356,6 +350,18 @@ NGLogicalOffset NGBlockLayoutAlgorithm::CalculateLogicalOffset(
|
| return {inline_offset, block_offset};
|
| }
|
|
|
| +void NGBlockLayoutAlgorithm::UpdateFragmentBfcOffset(
|
| + const NGLogicalOffset& offset) {
|
| + if (!builder_->BfcOffset()) {
|
| + NGLogicalOffset bfc_offset = offset;
|
| + if (ConstraintSpace().ClearanceOffset()) {
|
| + bfc_offset.block_offset = std::max(
|
| + ConstraintSpace().ClearanceOffset().value(), offset.block_offset);
|
| + }
|
| + builder_->SetBfcOffset(bfc_offset);
|
| + }
|
| +}
|
| +
|
| RefPtr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() {
|
| WTF::Optional<MinAndMaxContentSizes> sizes;
|
| if (NeedMinAndMaxContentSizes(ConstraintSpace(), Style()))
|
| @@ -417,7 +423,7 @@ RefPtr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() {
|
| // border/padding between them.
|
| if (border_and_padding_.block_start) {
|
| curr_bfc_offset_.block_offset += curr_margin_strut_.Sum();
|
| - UpdateFragmentBfcOffset(curr_bfc_offset_, builder_.get());
|
| + UpdateFragmentBfcOffset(curr_bfc_offset_);
|
| curr_margin_strut_ = NGMarginStrut();
|
| }
|
|
|
| @@ -425,7 +431,7 @@ RefPtr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() {
|
| // If a new formatting context hits the if branch above then the BFC offset is
|
| // still {} as the margin strut from the constraint space must also be empty.
|
| if (ConstraintSpace().IsNewFormattingContext()) {
|
| - UpdateFragmentBfcOffset(curr_bfc_offset_, builder_.get());
|
| + UpdateFragmentBfcOffset(curr_bfc_offset_);
|
| DCHECK_EQ(builder_->BfcOffset().value(), NGLogicalOffset());
|
| DCHECK_EQ(curr_margin_strut_, NGMarginStrut());
|
| }
|
| @@ -485,7 +491,7 @@ RefPtr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() {
|
| // Non-empty blocks always know their position in space:
|
| if (block_size) {
|
| curr_bfc_offset_.block_offset += curr_margin_strut_.Sum();
|
| - UpdateFragmentBfcOffset(curr_bfc_offset_, builder_.get());
|
| + UpdateFragmentBfcOffset(curr_bfc_offset_);
|
| PositionPendingFloats(curr_bfc_offset_.block_offset, ConstraintSpace(),
|
| builder_.get());
|
| }
|
| @@ -577,7 +583,7 @@ void NGBlockLayoutAlgorithm::FinishCurrentChildLayout(
|
| bfc_offset.value().block_offset += curr_margin_strut_.Sum();
|
| }
|
| if (bfc_offset) {
|
| - UpdateFragmentBfcOffset(curr_bfc_offset_, builder_.get());
|
| + UpdateFragmentBfcOffset(curr_bfc_offset_);
|
| PositionPendingFloats(curr_bfc_offset_.block_offset, ConstraintSpace(),
|
| builder_.get());
|
| }
|
| @@ -799,14 +805,12 @@ NGBlockLayoutAlgorithm::CreateConstraintSpaceForCurrentChild() {
|
| space_builder_->SetFragmentainerSpaceAvailable(space_available);
|
|
|
| // Clearance :
|
| - // - Collapse margins
|
| - // - Update curr_bfc_offset and parent BFC offset if needed.
|
| - // - Position all pending floats as position is known now.
|
| - // TODO(glebl): Fix the use case with clear: left and an intruding right.
|
| - // https://software.hixie.ch/utilities/js/live-dom-viewer/saved/4847
|
| + // - *Always* collapse margins and update *container*'s BFC offset.
|
| + // - Position all pending floats since the fragment's BFC offset is known.
|
| + // - Set the clearance offset on the constraint space's builder.
|
| if (current_child_style.clear() != EClear::kNone) {
|
| curr_bfc_offset_.block_offset += curr_margin_strut_.Sum();
|
| - UpdateFragmentBfcOffset(curr_bfc_offset_, builder_.get());
|
| + UpdateFragmentBfcOffset(curr_bfc_offset_);
|
| // Only collapse margins if it's an adjoining block with clearance.
|
| if (!content_size_) {
|
| curr_margin_strut_ = NGMarginStrut();
|
| @@ -814,8 +818,9 @@ NGBlockLayoutAlgorithm::CreateConstraintSpaceForCurrentChild() {
|
| }
|
| PositionPendingFloats(curr_bfc_offset_.block_offset, ConstraintSpace(),
|
| builder_.get());
|
| - AdjustToClearance(constraint_space_->Exclusions(), current_child_style,
|
| - builder_->BfcOffset().value(), &content_size_);
|
| + WTF::Optional<LayoutUnit> clearance_offset = GetClearanceOffset(
|
| + constraint_space_->Exclusions(), current_child_style);
|
| + space_builder_->SetClearanceOffset(clearance_offset);
|
| }
|
|
|
| // Set estimated BFC offset to the next child's constraint space.
|
| @@ -841,5 +846,4 @@ NGBlockLayoutAlgorithm::CreateConstraintSpaceForCurrentChild() {
|
| return space_builder_->ToConstraintSpace(
|
| FromPlatformWritingMode(current_child_style.getWritingMode()));
|
| }
|
| -
|
| } // namespace blink
|
|
|