1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "third_party/blink/renderer/core/layout/ng/ng_base_layout_algorithm_test.h"
6
7 #include "third_party/blink/renderer/core/dom/element.h"
8 #include "third_party/blink/renderer/core/layout/ng/layout_ng_block_flow.h"
9 #include "third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.h"
10 #include "third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h"
11 #include "third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.h"
12 #include "third_party/blink/renderer/core/layout/ng/ng_layout_result.h"
13 #include "third_party/blink/renderer/core/layout/ng/ng_length_utils.h"
14 #include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
15 #include "third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h"
16
17 namespace blink {
18
SetUp()19 void NGBaseLayoutAlgorithmTest::SetUp() {
20 EnableCompositing();
21 NGLayoutTest::SetUp();
22 }
23
AdvanceToLayoutPhase()24 void NGBaseLayoutAlgorithmTest::AdvanceToLayoutPhase() {
25 if (GetDocument().Lifecycle().GetState() ==
26 DocumentLifecycle::kInPerformLayout)
27 return;
28 GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kInStyleRecalc);
29 GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kStyleClean);
30 GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kInPerformLayout);
31 }
32
33 scoped_refptr<const NGPhysicalBoxFragment>
RunBlockLayoutAlgorithm(NGBlockNode node,const NGConstraintSpace & space,const NGBreakToken * break_token)34 NGBaseLayoutAlgorithmTest::RunBlockLayoutAlgorithm(
35 NGBlockNode node,
36 const NGConstraintSpace& space,
37 const NGBreakToken* break_token) {
38 NGFragmentGeometry fragment_geometry =
39 CalculateInitialFragmentGeometry(space, node);
40
41 scoped_refptr<const NGLayoutResult> result =
42 NGBlockLayoutAlgorithm(
43 {node, fragment_geometry, space, To<NGBlockBreakToken>(break_token)})
44 .Layout();
45
46 return To<NGPhysicalBoxFragment>(&result->PhysicalFragment());
47 }
48
49 std::pair<scoped_refptr<const NGPhysicalBoxFragment>, NGConstraintSpace>
RunBlockLayoutAlgorithmForElement(Element * element)50 NGBaseLayoutAlgorithmTest::RunBlockLayoutAlgorithmForElement(Element* element) {
51 auto* block_flow = To<LayoutBlockFlow>(element->GetLayoutObject());
52 NGBlockNode node(block_flow);
53 NGConstraintSpace space =
54 NGConstraintSpace::CreateFromLayoutObject(*block_flow);
55 NGFragmentGeometry fragment_geometry =
56 CalculateInitialFragmentGeometry(space, node);
57
58 scoped_refptr<const NGLayoutResult> result =
59 NGBlockLayoutAlgorithm({node, fragment_geometry, space}).Layout();
60 return std::make_pair(To<NGPhysicalBoxFragment>(&result->PhysicalFragment()),
61 std::move(space));
62 }
63
64 scoped_refptr<const NGPhysicalBoxFragment>
RunFieldsetLayoutAlgorithm(NGBlockNode node,const NGConstraintSpace & space,const NGBreakToken * break_token)65 NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(
66 NGBlockNode node,
67 const NGConstraintSpace& space,
68 const NGBreakToken* break_token) {
69 NGFragmentGeometry fragment_geometry =
70 CalculateInitialFragmentGeometry(space, node);
71
72 scoped_refptr<const NGLayoutResult> result =
73 NGFieldsetLayoutAlgorithm(
74 {node, fragment_geometry, space, To<NGBlockBreakToken>(break_token)})
75 .Layout();
76
77 return To<NGPhysicalBoxFragment>(&result->PhysicalFragment());
78 }
79
80 scoped_refptr<const NGPhysicalBoxFragment>
GetBoxFragmentByElementId(const char * id)81 NGBaseLayoutAlgorithmTest::GetBoxFragmentByElementId(const char* id) {
82 LayoutObject* layout_object = GetLayoutObjectByElementId(id);
83 CHECK(layout_object && layout_object->IsLayoutNGMixin());
84 scoped_refptr<const NGPhysicalBoxFragment> fragment =
85 To<LayoutBlockFlow>(layout_object)->CurrentFragment();
86 CHECK(fragment);
87 return fragment;
88 }
89
CurrentFragmentFor(const LayoutNGBlockFlow * block_flow)90 const NGPhysicalBoxFragment* NGBaseLayoutAlgorithmTest::CurrentFragmentFor(
91 const LayoutNGBlockFlow* block_flow) {
92 return block_flow->CurrentFragment();
93 }
94
NextChild(PhysicalOffset * fragment_offset)95 const NGPhysicalBoxFragment* FragmentChildIterator::NextChild(
96 PhysicalOffset* fragment_offset) {
97 if (!parent_)
98 return nullptr;
99 if (index_ >= parent_->Children().size())
100 return nullptr;
101 while (parent_->Children()[index_]->Type() !=
102 NGPhysicalFragment::kFragmentBox) {
103 ++index_;
104 if (index_ >= parent_->Children().size())
105 return nullptr;
106 }
107 auto& child = parent_->Children()[index_++];
108 if (fragment_offset)
109 *fragment_offset = child.Offset();
110 return To<NGPhysicalBoxFragment>(child.get());
111 }
112
ConstructBlockLayoutTestConstraintSpace(WritingMode writing_mode,TextDirection direction,LogicalSize size,bool shrink_to_fit,bool is_new_formatting_context,LayoutUnit fragmentainer_space_available)113 NGConstraintSpace ConstructBlockLayoutTestConstraintSpace(
114 WritingMode writing_mode,
115 TextDirection direction,
116 LogicalSize size,
117 bool shrink_to_fit,
118 bool is_new_formatting_context,
119 LayoutUnit fragmentainer_space_available) {
120 NGFragmentationType block_fragmentation =
121 fragmentainer_space_available != kIndefiniteSize
122 ? NGFragmentationType::kFragmentColumn
123 : NGFragmentationType::kFragmentNone;
124
125 NGConstraintSpaceBuilder builder(writing_mode, writing_mode,
126 is_new_formatting_context);
127 builder.SetAvailableSize(size);
128 builder.SetPercentageResolutionSize(size);
129 builder.SetTextDirection(direction);
130 builder.SetIsShrinkToFit(shrink_to_fit);
131 builder.SetFragmentainerBlockSize(fragmentainer_space_available);
132 builder.SetFragmentationType(block_fragmentation);
133 return builder.ToConstraintSpace();
134 }
135
136 } // namespace blink
137