Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(866)

Side by Side Diff: third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc

Issue 2350603002: Ignore zero-height fragments during margin collapsing (Closed)
Patch Set: Set writing mode and fixed size on style_. Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/layout/ng/ng_block_layout_algorithm.h" 5 #include "core/layout/ng/ng_block_layout_algorithm.h"
6 6
7 #include "core/layout/ng/ng_constraint_space.h" 7 #include "core/layout/ng/ng_constraint_space.h"
8 #include "core/layout/ng/ng_fragment_builder.h" 8 #include "core/layout/ng/ng_fragment_builder.h"
9 #include "core/layout/ng/ng_fragment.h" 9 #include "core/layout/ng/ng_fragment.h"
10 #include "core/layout/ng/ng_length_utils.h" 10 #include "core/layout/ng/ng_length_utils.h"
(...skipping 11 matching lines...) Expand all
22 curr_margin_strut.margin_block_start) - 22 curr_margin_strut.margin_block_start) -
23 std::max(prev_margin_strut.negative_margin_block_end.abs(), 23 std::max(prev_margin_strut.negative_margin_block_end.abs(),
24 curr_margin_strut.negative_margin_block_start.abs()); 24 curr_margin_strut.negative_margin_block_start.abs());
25 } 25 }
26 26
27 } // namespace 27 } // namespace
28 28
29 NGBlockLayoutAlgorithm::NGBlockLayoutAlgorithm( 29 NGBlockLayoutAlgorithm::NGBlockLayoutAlgorithm(
30 PassRefPtr<const ComputedStyle> style, 30 PassRefPtr<const ComputedStyle> style,
31 NGBox* first_child) 31 NGBox* first_child)
32 : style_(style), first_child_(first_child), state_(kStateInit) { 32 : style_(style),
33 first_child_(first_child),
34 state_(kStateInit),
35 is_fragment_margin_strut_block_start_updated_(false) {
33 DCHECK(style_); 36 DCHECK(style_);
34 } 37 }
35 38
36 bool NGBlockLayoutAlgorithm::Layout(const NGConstraintSpace* constraint_space, 39 bool NGBlockLayoutAlgorithm::Layout(const NGConstraintSpace* constraint_space,
37 NGPhysicalFragment** out) { 40 NGPhysicalFragment** out) {
38 switch (state_) { 41 switch (state_) {
39 case kStateInit: { 42 case kStateInit: {
40 border_and_padding_ = 43 border_and_padding_ =
41 computeBorders(*style_) + computePadding(*constraint_space, *style_); 44 computeBorders(*style_) + computePadding(*constraint_space, *style_);
42 45
(...skipping 28 matching lines...) Expand all
71 case kStateChildLayout: { 74 case kStateChildLayout: {
72 if (current_child_) { 75 if (current_child_) {
73 NGFragment* fragment; 76 NGFragment* fragment;
74 if (!current_child_->Layout(constraint_space_for_children_, &fragment)) 77 if (!current_child_->Layout(constraint_space_for_children_, &fragment))
75 return false; 78 return false;
76 NGBoxStrut child_margins = computeMargins( 79 NGBoxStrut child_margins = computeMargins(
77 *constraint_space_for_children_, *current_child_->Style(), 80 *constraint_space_for_children_, *current_child_->Style(),
78 constraint_space_for_children_->WritingMode(), 81 constraint_space_for_children_->WritingMode(),
79 constraint_space_for_children_->Direction()); 82 constraint_space_for_children_->Direction());
80 83
81 LayoutUnit margin_block_start = CollapseMargins( 84 LayoutUnit margin_block_start =
82 *constraint_space, child_margins, fragment->MarginStrut()); 85 CollapseMargins(*constraint_space, child_margins, *fragment);
83 86
84 // TODO(layout-ng): Support auto margins 87 // TODO(layout-ng): Support auto margins
85 builder_->AddChild(fragment, 88 builder_->AddChild(fragment,
86 NGLogicalOffset(border_and_padding_.inline_start + 89 NGLogicalOffset(border_and_padding_.inline_start +
87 child_margins.inline_start, 90 child_margins.inline_start,
88 content_size_ + margin_block_start)); 91 content_size_ + margin_block_start));
89 92
90 content_size_ += fragment->BlockSize() + margin_block_start; 93 content_size_ += fragment->BlockSize() + margin_block_start;
91 max_inline_size_ = 94 max_inline_size_ =
92 std::max(max_inline_size_, fragment->InlineSize() + 95 std::max(max_inline_size_, fragment->InlineSize() +
(...skipping 21 matching lines...) Expand all
114 } 117 }
115 }; 118 };
116 NOTREACHED(); 119 NOTREACHED();
117 *out = nullptr; 120 *out = nullptr;
118 return true; 121 return true;
119 } 122 }
120 123
121 LayoutUnit NGBlockLayoutAlgorithm::CollapseMargins( 124 LayoutUnit NGBlockLayoutAlgorithm::CollapseMargins(
122 const NGConstraintSpace& space, 125 const NGConstraintSpace& space,
123 const NGBoxStrut& margins, 126 const NGBoxStrut& margins,
124 const NGMarginStrut& children_margin_strut) { 127 const NGFragment& fragment) {
125 // Calculate margin strut for the current child. 128 // TODO(chrome-layout-team): Do not collapse margins for elements that
126 NGMarginStrut curr_margin_strut = children_margin_strut; 129 // establish new block formatting contexts
130
131 // Zero-height boxes are ignored and do not participate in margin collapsing.
132 bool is_zero_height_box = !fragment.BlockSize() && margins.IsEmpty();
133 if (is_zero_height_box)
134 return LayoutUnit();
135
136 // Create the current child's margin strut from its children's margin strut.
137 NGMarginStrut curr_margin_strut = fragment.MarginStrut();
127 138
128 // Calculate borders and padding for the current child. 139 // Calculate borders and padding for the current child.
129 NGBoxStrut borders = computeBorders(*current_child_->Style()); 140 NGBoxStrut border_and_padding =
130 NGBoxStrut paddings = computePadding(space, *current_child_->Style()); 141 computeBorders(*current_child_->Style()) +
131 LayoutUnit border_and_padding_before = 142 computePadding(space, *current_child_->Style());
132 borders.block_start + paddings.block_start;
133 LayoutUnit border_and_padding_after = borders.block_end + paddings.block_end;
134 143
135 // Collapse BLOCK-START margins if there is no padding or border between 144 // Collapse BLOCK-START margins if there is no padding or border between
136 // parent (current child) and its first in-flow child. 145 // parent (current child) and its first in-flow child.
137 if (border_and_padding_before) { 146 if (border_and_padding.block_start) {
138 curr_margin_strut.SetMarginBlockStart(margins.block_start); 147 curr_margin_strut.SetMarginBlockStart(margins.block_start);
139 } else { 148 } else {
140 curr_margin_strut.AppendMarginBlockStart(margins.block_start); 149 curr_margin_strut.AppendMarginBlockStart(margins.block_start);
141 } 150 }
142 151
143 // Collapse BLOCK-END margins if 152 // Collapse BLOCK-END margins if
144 // 1) there is no padding or border between parent (current child) and its 153 // 1) there is no padding or border between parent (current child) and its
145 // first/last in-flow child 154 // first/last in-flow child
146 // 2) parent's logical height is auto. 155 // 2) parent's logical height is auto.
147 if (current_child_->Style()->logicalHeight().isAuto() && 156 if (current_child_->Style()->logicalHeight().isAuto() &&
148 !border_and_padding_after) { 157 !border_and_padding.block_end) {
149 curr_margin_strut.AppendMarginBlockEnd(margins.block_end); 158 curr_margin_strut.AppendMarginBlockEnd(margins.block_end);
150 } else { 159 } else {
151 curr_margin_strut.SetMarginBlockEnd(margins.block_end); 160 curr_margin_strut.SetMarginBlockEnd(margins.block_end);
152 } 161 }
153 162
154 // Set the margin strut for the resultant fragment if this is the first or 163 // Update the parent fragment's margin strut
155 // last child fragment. 164 UpdateMarginStrut(curr_margin_strut);
156 if (current_child_ == first_child_)
157 builder_->SetMarginStrutBlockStart(curr_margin_strut);
158 if (!current_child_->NextSibling())
159 builder_->SetMarginStrutBlockEnd(curr_margin_strut);
160 165
161 // Compute the margin block start for adjoining blocks. 166 // Compute the margin block start for adjoining blocks.
162 LayoutUnit margin_block_start; 167 LayoutUnit margin_block_start;
163 if (current_child_ != first_child_) 168 if (is_fragment_margin_strut_block_start_updated_) {
164 margin_block_start = ComputeCollapsedMarginBlockStart( 169 margin_block_start = ComputeCollapsedMarginBlockStart(
165 prev_child_margin_strut_, curr_margin_strut); 170 prev_child_margin_strut_, curr_margin_strut);
166 171 }
167 prev_child_margin_strut_ = curr_margin_strut; 172 prev_child_margin_strut_ = curr_margin_strut;
168 // TODO(layout-ng): support other Margin Collapsing use cases,
169 // i.e. support 0 height elements etc.
170 return margin_block_start; 173 return margin_block_start;
171 } 174 }
172 175
176 void NGBlockLayoutAlgorithm::UpdateMarginStrut(const NGMarginStrut& from) {
177 if (!is_fragment_margin_strut_block_start_updated_) {
178 builder_->SetMarginStrutBlockStart(from);
179 is_fragment_margin_strut_block_start_updated_ = true;
180 }
181 builder_->SetMarginStrutBlockEnd(from);
182 }
183
173 } // namespace blink 184 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698