Chromium Code Reviews| Index: third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.cc |
| diff --git a/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.cc b/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.cc |
| index f6950ee5e8ad051d66ab09840b776efd166bc922..c9680c0d539e92ddfd9be965387dc6991d0804eb 100644 |
| --- a/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.cc |
| +++ b/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.cc |
| @@ -8,26 +8,45 @@ |
| #include "core/layout/ng/ng_block_node.h" |
| #include "core/layout/ng/ng_constraint_space_builder.h" |
| #include "core/layout/ng/ng_fragment.h" |
| +#include "core/layout/ng/ng_fragment_builder.h" |
| #include "core/layout/ng/ng_length_utils.h" |
| #include "core/layout/ng/ng_physical_fragment.h" |
| #include "core/style/ComputedStyle.h" |
| namespace blink { |
| +namespace { |
| + |
| +// True if the container will contain an absolute child. |
| +bool IsContainingBlockForAbsoluteChild(const ComputedStyle& container_style, |
| + const ComputedStyle& child_style) { |
| + EPosition position = child_style.position(); |
| + bool contains_fixed = container_style.canContainFixedPositionObjects(); |
| + bool contains_absolute = |
| + container_style.canContainAbsolutePositionObjects() || contains_fixed; |
| + |
| + return (contains_absolute && position == AbsolutePosition) || |
| + (contains_fixed && position == FixedPosition); |
| +} |
| + |
| +} // namespace |
| + |
| NGOutOfFlowLayoutPart::NGOutOfFlowLayoutPart( |
| - PassRefPtr<const ComputedStyle> container_style, |
| - NGLogicalSize container_size) { |
| + const ComputedStyle& container_style, |
| + NGFragmentBuilder* container_builder) |
| + : container_style_(container_style), container_builder_(container_builder) { |
| NGWritingMode writing_mode( |
| - FromPlatformWritingMode(container_style->getWritingMode())); |
| + FromPlatformWritingMode(container_style_.getWritingMode())); |
| - NGBoxStrut borders = ComputeBorders(*container_style); |
| + NGBoxStrut borders = ComputeBorders(container_style_); |
| parent_border_offset_ = |
| NGLogicalOffset{borders.inline_start, borders.block_start}; |
| parent_border_physical_offset_ = parent_border_offset_.ConvertToPhysical( |
| - writing_mode, container_style->direction(), |
| - container_size.ConvertToPhysical(writing_mode), NGPhysicalSize()); |
| + writing_mode, container_style_.direction(), |
| + container_builder_->Size().ConvertToPhysical(writing_mode), |
| + NGPhysicalSize()); |
| - NGLogicalSize space_size = container_size; |
| + NGLogicalSize space_size = container_builder_->Size(); |
| space_size.block_size -= borders.BlockSum(); |
| space_size.inline_size -= borders.InlineSum(); |
| @@ -36,14 +55,41 @@ NGOutOfFlowLayoutPart::NGOutOfFlowLayoutPart( |
| space_builder.SetAvailableSize(space_size); |
| space_builder.SetPercentageResolutionSize(space_size); |
| space_builder.SetIsNewFormattingContext(true); |
| - space_builder.SetTextDirection(container_style->direction()); |
| - parent_space_ = space_builder.ToConstraintSpace(); |
| + space_builder.SetTextDirection(container_style_.direction()); |
| + container_space_ = space_builder.ToConstraintSpace(); |
| +} |
| + |
| +void NGOutOfFlowLayoutPart::Run() { |
|
ikilpatrick
2017/01/20 23:48:30
plz halp, better name?
atotic
2017/01/23 07:37:56
I like Run(). Kinda like DoIt(), the all-purpose m
|
| + HeapLinkedHashSet<WeakMember<NGBlockNode>> out_of_flow_candidates; |
| + Vector<NGStaticPosition> out_of_flow_candidate_positions; |
| + |
| + container_builder_->GetAndClearOutOfFlowDescendantCandidates( |
| + &out_of_flow_candidates, &out_of_flow_candidate_positions); |
| + size_t position_index = 0; |
| + |
| + while (!out_of_flow_candidates.isEmpty()) { |
|
atotic
2017/01/23 07:37:56
Convert to standard iteration:
for (auto& child :
ikilpatrick
2017/01/24 19:11:32
Done.
|
| + NGBlockNode* child = out_of_flow_candidates.first(); |
| + out_of_flow_candidates.removeFirst(); |
| + |
| + NGStaticPosition static_position = |
| + out_of_flow_candidate_positions[position_index++]; |
| + |
| + if (IsContainingBlockForAbsoluteChild(container_style_, *child->Style())) { |
| + NGLogicalOffset offset; |
| + NGFragment* fragment = LayoutChild(*child, static_position, &offset); |
| + container_builder_->AddChild(fragment, offset); |
| + |
| + container_builder_->GetAndClearOutOfFlowDescendantCandidates( |
| + &out_of_flow_candidates, &out_of_flow_candidate_positions); |
| + } else { |
| + container_builder_->AddOutOfFlowDescendant(child, static_position); |
| + } |
| + } |
| } |
| -void NGOutOfFlowLayoutPart::Layout(NGBlockNode& node, |
| - NGStaticPosition static_position, |
| - NGFragment** fragment_out, |
| - NGLogicalOffset* offset) { |
| +NGFragment* NGOutOfFlowLayoutPart::LayoutChild(NGBlockNode& child, |
|
atotic
2017/01/23 07:37:56
Strictly, the routine is laying out a "positioned
ikilpatrick
2017/01/24 19:11:32
Renamed:
child->descendant
parent->container
f
|
| + NGStaticPosition static_position, |
| + NGLogicalOffset* offset) { |
| // Adjust the static_position origin. The static_position coordinate origin is |
| // relative to the parent's border box, ng_absolute_utils expects it to be |
| // relative to the parent's padding box. |
| @@ -53,44 +99,44 @@ void NGOutOfFlowLayoutPart::Layout(NGBlockNode& node, |
| Optional<MinAndMaxContentSizes> inline_estimate; |
| Optional<LayoutUnit> block_estimate; |
| - if (AbsoluteNeedsChildInlineSize(*node.Style())) { |
| - inline_estimate = node.ComputeMinAndMaxContentSizesSync(); |
| + if (AbsoluteNeedsChildInlineSize(*child.Style())) { |
| + inline_estimate = child.ComputeMinAndMaxContentSizesSync(); |
| } |
| NGAbsolutePhysicalPosition node_position = |
| ComputePartialAbsoluteWithChildInlineSize( |
| - *parent_space_, *node.Style(), static_position, inline_estimate); |
| + *container_space_, *child.Style(), static_position, inline_estimate); |
| - if (AbsoluteNeedsChildBlockSize(*node.Style())) { |
| - fragment = GenerateFragment(node, block_estimate, node_position); |
| + if (AbsoluteNeedsChildBlockSize(*child.Style())) { |
| + fragment = GenerateFragment(child, block_estimate, node_position); |
| block_estimate = fragment->BlockSize(); |
| } |
| - ComputeFullAbsoluteWithChildBlockSize(*parent_space_, *node.Style(), |
| + ComputeFullAbsoluteWithChildBlockSize(*container_space_, *child.Style(), |
| static_position, block_estimate, |
| &node_position); |
| // Skip this step if we produced a fragment when estimating the block size. |
| if (!fragment) { |
| block_estimate = |
| - node_position.size.ConvertToLogical(parent_space_->WritingMode()) |
| + node_position.size.ConvertToLogical(container_space_->WritingMode()) |
| .block_size; |
| - fragment = GenerateFragment(node, block_estimate, node_position); |
| + fragment = GenerateFragment(child, block_estimate, node_position); |
| } |
| - *fragment_out = fragment; |
| - |
| // Compute logical offset, NGAbsolutePhysicalPosition is calculated relative |
| // to the padding box so add back the parent's borders. |
| NGBoxStrut inset = node_position.inset.ConvertToLogical( |
| - parent_space_->WritingMode(), parent_space_->Direction()); |
| + container_space_->WritingMode(), container_space_->Direction()); |
| offset->inline_offset = |
| inset.inline_start + parent_border_offset_.inline_offset; |
| offset->block_offset = inset.block_start + parent_border_offset_.block_offset; |
| + |
| + return fragment; |
| } |
| NGFragment* NGOutOfFlowLayoutPart::GenerateFragment( |
| - NGBlockNode& node, |
| + NGBlockNode& child, |
| const Optional<LayoutUnit>& block_estimate, |
| const NGAbsolutePhysicalPosition node_position) { |
| // The fragment is generated in one of these two scenarios: |
| @@ -99,17 +145,17 @@ NGFragment* NGOutOfFlowLayoutPart::GenerateFragment( |
| // 2. To compute final fragment, when block size is known from the absolute |
| // position calculation. |
| LayoutUnit inline_size = |
| - node_position.size.ConvertToLogical(parent_space_->WritingMode()) |
| + node_position.size.ConvertToLogical(container_space_->WritingMode()) |
| .inline_size; |
| LayoutUnit block_size = block_estimate |
| ? *block_estimate |
| - : parent_space_->AvailableSize().block_size; |
| + : container_space_->AvailableSize().block_size; |
| NGLogicalSize available_size{inline_size, block_size}; |
| - NGConstraintSpaceBuilder builder(parent_space_->WritingMode()); |
| + NGConstraintSpaceBuilder builder(container_space_->WritingMode()); |
| builder.SetAvailableSize(available_size); |
| - builder.SetPercentageResolutionSize(parent_space_->AvailableSize()); |
| + builder.SetPercentageResolutionSize(container_space_->AvailableSize()); |
| if (block_estimate) |
| builder.SetIsFixedSizeBlock(true); |
| builder.SetIsFixedSizeInline(true); |
| @@ -117,12 +163,8 @@ NGFragment* NGOutOfFlowLayoutPart::GenerateFragment( |
| NGConstraintSpace* space = builder.ToConstraintSpace(); |
| NGFragment* fragment; |
| - node.LayoutSync(space, &fragment); |
| + child.LayoutSync(space, &fragment); |
| return fragment; |
| } |
| -DEFINE_TRACE(NGOutOfFlowLayoutPart) { |
| - visitor->trace(parent_space_); |
| -} |
| - |
| } // namespace blink |