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