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 039ca524b65373f21255750a959c87ea33b288f2..c3eb0c6681bdbd3c37c1186f3c005df73f214d69 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 |
@@ -12,6 +12,7 @@ |
#include "core/layout/ng/ng_fragment.h" |
#include "core/layout/ng/ng_layout_opportunity_iterator.h" |
#include "core/layout/ng/ng_length_utils.h" |
+#include "core/layout/ng/ng_out_of_flow_layout_part.h" |
#include "core/layout/ng/ng_units.h" |
#include "core/style/ComputedStyle.h" |
#include "platform/LengthFunctions.h" |
@@ -243,23 +244,36 @@ NGLayoutStatus NGBlockLayoutAlgorithm::Layout( |
} |
case kStatePrepareForChildLayout: { |
if (current_child_) { |
- // TODO(atotic): uncomment this code when implementing oof layout. |
- // This code cannot be turned on because it prevents layout of |
- // oof children, and non-layedout objects trigger a DCHECK. |
- // EPosition position = current_child_->Style()->position(); |
- // if ((position == AbsolutePosition || position == FixedPosition)) { |
- // builder_->AddOutOfFlowCandidateChild(current_child_, |
- // GetChildSpaceOffset()); |
- // } |
- // else |
- space_for_current_child_ = CreateConstraintSpaceForCurrentChild(); |
- *algorithm_out = NGLayoutInputNode::AlgorithmForInputNode( |
- current_child_, space_for_current_child_); |
- state_ = kStateChildLayout; |
- return kChildAlgorithmRequired; |
+ EPosition position = current_child_->Style()->position(); |
+ if ((position == AbsolutePosition || position == FixedPosition)) { |
+ builder_->AddOutOfFlowChildCandidate(current_child_, |
+ GetChildSpaceOffset()); |
+ current_child_ = current_child_->NextSibling(); |
+ return kNotFinished; |
+ } else { |
cbiesinger
2016/12/21 21:38:50
No need for an "else" after a return.
atotic
2016/12/28 19:36:46
done
|
+ space_for_current_child_ = CreateConstraintSpaceForCurrentChild(); |
+ *algorithm_out = NGLayoutInputNode::AlgorithmForInputNode( |
+ current_child_, space_for_current_child_); |
+ state_ = kStateChildLayout; |
+ return kChildAlgorithmRequired; |
+ } |
} |
- state_ = kStateFinalize; |
+ // Prepare for kStateOutOfFlowLayout |
+ content_size_ += border_and_padding_.block_end; |
+ |
+ // Recompute the block-axis size now that we know our content size. |
+ LayoutUnit block_size = ComputeBlockSizeForFragment( |
+ ConstraintSpace(), Style(), content_size_); |
+ builder_->SetBlockSize(block_size); |
+ |
+ // Out of flow setup. |
+ out_of_flow_layout_ = new NGOutOfFlowLayoutPart(style_, builder_->Size()); |
+ builder_->GetAndClearOutOfFlowDescendantCandidates( |
+ &out_of_flow_candidates_, &out_of_flow_candidate_positions_); |
+ out_of_flow_candidate_positions_index_ = 0; |
+ current_child_ = nullptr; |
+ state_ = kStateOutOfFlowLayout; |
return kNotFinished; |
} |
case kStateChildLayout: { |
@@ -277,9 +291,11 @@ NGLayoutStatus NGBlockLayoutAlgorithm::Layout( |
state_ = kStatePrepareForChildLayout; |
return kNotFinished; |
} |
+ case kStateOutOfFlowLayout: |
+ if (LayoutOutOfFlowChild()) |
+ state_ = kStateFinalize; |
+ return kNotFinished; |
case kStateFinalize: { |
- content_size_ += border_and_padding_.block_end; |
- |
// Recompute the block-axis size now that we know our content size. |
LayoutUnit block_size = ComputeBlockSizeForFragment( |
cbiesinger
2016/12/21 21:38:50
You don't need this anymore since you're now calli
atotic
2016/12/28 19:36:45
done. Thanks, nice catch, I blame this on persiste
|
ConstraintSpace(), Style(), content_size_); |
@@ -314,6 +330,34 @@ void NGBlockLayoutAlgorithm::FinishCurrentChildLayout( |
builder_->AddChild(fragment, fragment_offset); |
} |
+bool NGBlockLayoutAlgorithm::LayoutOutOfFlowChild() { |
cbiesinger
2016/12/21 21:38:50
Maybe use NGLayoutStatus as the return type so it'
atotic
2016/12/28 19:36:45
Unsure about this.
Pros: not necessary to remembe
cbiesinger
2017/01/04 00:13:16
Just documentation is fine with me, though it seem
|
+ if (!current_child_) { |
+ if (out_of_flow_candidates_.isEmpty()) { |
+ out_of_flow_layout_ = nullptr; |
+ out_of_flow_candidate_positions_.clear(); |
+ return true; |
+ } |
+ current_child_ = out_of_flow_candidates_.first(); |
+ out_of_flow_candidates_.removeFirst(); |
+ NGStaticPosition position = out_of_flow_candidate_positions_ |
+ [out_of_flow_candidate_positions_index_++]; |
+ |
+ if (!out_of_flow_layout_->StartLayout(current_child_, position)) { |
+ builder_->AddOutOfFlowDescendant(current_child_, position); |
+ current_child_ = nullptr; |
+ return false; |
+ } |
+ } |
+ NGFragmentBase* fragment; |
+ NGLogicalOffset offset; |
+ if (out_of_flow_layout_->Layout(&fragment, &offset)) { |
+ // TODO(atotic) Do we need to adjust builder content size here? |
cbiesinger
2016/12/21 21:38:50
abspos does not change the width/height of the con
atotic
2016/12/28 19:36:46
done. Added a comment.
|
+ builder_->AddChild(fragment, offset); |
+ current_child_ = nullptr; |
+ } |
+ return false; |
+} |
+ |
NGBoxStrut NGBlockLayoutAlgorithm::CollapseMargins( |
const NGBoxStrut& margins, |
const NGFragment& fragment) { |
@@ -466,6 +510,8 @@ DEFINE_TRACE(NGBlockLayoutAlgorithm) { |
visitor->trace(space_builder_); |
visitor->trace(space_for_current_child_); |
visitor->trace(current_child_); |
+ visitor->trace(out_of_flow_layout_); |
+ visitor->trace(out_of_flow_candidates_); |
} |
} // namespace blink |