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

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

Issue 2456973002: [LayoutNG] Move ng_block_layout_algorithm to use constraint space builder. (Closed)
Patch Set: rebase. Created 4 years, 1 month 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_constraint_space_builder.h"
8 #include "core/layout/ng/ng_fragment_builder.h" 9 #include "core/layout/ng/ng_fragment_builder.h"
9 #include "core/layout/ng/ng_fragment.h" 10 #include "core/layout/ng/ng_fragment.h"
10 #include "core/layout/ng/ng_layout_opportunity_iterator.h" 11 #include "core/layout/ng/ng_layout_opportunity_iterator.h"
11 #include "core/layout/ng/ng_length_utils.h" 12 #include "core/layout/ng/ng_length_utils.h"
12 #include "core/layout/ng/ng_units.h" 13 #include "core/layout/ng/ng_units.h"
13 #include "core/style/ComputedStyle.h" 14 #include "core/style/ComputedStyle.h"
14 #include "platform/LengthFunctions.h" 15 #include "platform/LengthFunctions.h"
15 16
16 namespace blink { 17 namespace blink {
17 namespace { 18 namespace {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 // It iterates over all layout opportunities in the constraint space and returns 52 // It iterates over all layout opportunities in the constraint space and returns
52 // the first layout opportunity that is wider than the fragment or returns the 53 // the first layout opportunity that is wider than the fragment or returns the
53 // last one which is always the widest. 54 // last one which is always the widest.
54 // 55 //
55 // @param space Constraint space that is used to find layout opportunity for 56 // @param space Constraint space that is used to find layout opportunity for
56 // the fragment. 57 // the fragment.
57 // @param fragment Fragment that needs to be placed. 58 // @param fragment Fragment that needs to be placed.
58 // @param margins Margins of the fragment. 59 // @param margins Margins of the fragment.
59 // @return Layout opportunity for the fragment. 60 // @return Layout opportunity for the fragment.
60 const NGLayoutOpportunity FindLayoutOpportunityForFragment( 61 const NGLayoutOpportunity FindLayoutOpportunityForFragment(
61 const Member<NGConstraintSpace>& space, 62 NGConstraintSpace* space,
62 const NGFragment& fragment, 63 const NGFragment& fragment,
63 const NGBoxStrut& margins) { 64 const NGBoxStrut& margins) {
64 NGLayoutOpportunityIterator* opportunity_iter = space->LayoutOpportunities(); 65 NGLayoutOpportunityIterator* opportunity_iter = space->LayoutOpportunities();
65 NGLayoutOpportunity opportunity; 66 NGLayoutOpportunity opportunity;
66 NGLayoutOpportunity opportunity_candidate = opportunity_iter->Next(); 67 NGLayoutOpportunity opportunity_candidate = opportunity_iter->Next();
67 68
68 while (!opportunity_candidate.IsEmpty()) { 69 while (!opportunity_candidate.IsEmpty()) {
69 opportunity = opportunity_candidate; 70 opportunity = opportunity_candidate;
70 // Checking opportunity's block size is not necessary as a float cannot be 71 // Checking opportunity's block size is not necessary as a float cannot be
71 // positioned on top of another float inside of the same constraint space. 72 // positioned on top of another float inside of the same constraint space.
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 if (display == EDisplay::Grid || display == EDisplay::Flex || 133 if (display == EDisplay::Grid || display == EDisplay::Flex ||
133 display == EDisplay::Box) 134 display == EDisplay::Box)
134 return true; 135 return true;
135 136
136 if (space.WritingMode() != FromPlatformWritingMode(style.getWritingMode())) 137 if (space.WritingMode() != FromPlatformWritingMode(style.getWritingMode()))
137 return true; 138 return true;
138 139
139 return false; 140 return false;
140 } 141 }
141 142
143 // Creates a new constraint space for a child.
144 NGConstraintSpace* CreateConstraintSpaceForChild(
145 const NGConstraintSpace& space,
146 const NGBox& child,
147 NGConstraintSpaceBuilder* builder) {
148 builder->SetIsNewFormattingContext(
149 IsNewFormattingContextForInFlowBlockLevelChild(space, *child.Style()));
150 return new NGConstraintSpace(space.WritingMode(), space.Direction(),
151 builder->ToConstraintSpace());
152 }
153
142 } // namespace 154 } // namespace
143 155
144 NGBlockLayoutAlgorithm::NGBlockLayoutAlgorithm( 156 NGBlockLayoutAlgorithm::NGBlockLayoutAlgorithm(
145 PassRefPtr<const ComputedStyle> style, 157 PassRefPtr<const ComputedStyle> style,
146 NGBox* first_child) 158 NGBox* first_child,
147 : style_(style), 159 NGConstraintSpace* constraint_space)
160 : state_(kStateInit),
161 style_(style),
148 first_child_(first_child), 162 first_child_(first_child),
149 state_(kStateInit), 163 constraint_space_(constraint_space),
150 is_fragment_margin_strut_block_start_updated_(false) { 164 is_fragment_margin_strut_block_start_updated_(false) {
151 DCHECK(style_); 165 DCHECK(style_);
152 } 166 }
153 167
154 bool NGBlockLayoutAlgorithm::Layout(const NGConstraintSpace* constraint_space, 168 bool NGBlockLayoutAlgorithm::Layout(NGPhysicalFragment** out) {
155 NGPhysicalFragment** out) {
156 switch (state_) { 169 switch (state_) {
157 case kStateInit: { 170 case kStateInit: {
158 border_and_padding_ = 171 border_and_padding_ =
159 ComputeBorders(Style()) + ComputePadding(*constraint_space, Style()); 172 ComputeBorders(Style()) + ComputePadding(*constraint_space_, Style());
160 173
161 LayoutUnit inline_size = 174 LayoutUnit inline_size =
162 ComputeInlineSizeForFragment(*constraint_space, Style()); 175 ComputeInlineSizeForFragment(*constraint_space_, Style());
163 LayoutUnit adjusted_inline_size = 176 LayoutUnit adjusted_inline_size =
164 inline_size - border_and_padding_.InlineSum(); 177 inline_size - border_and_padding_.InlineSum();
165 // TODO(layout-ng): For quirks mode, should we pass blockSize instead of 178 // TODO(layout-ng): For quirks mode, should we pass blockSize instead of
166 // -1? 179 // -1?
167 LayoutUnit block_size = ComputeBlockSizeForFragment( 180 LayoutUnit block_size = ComputeBlockSizeForFragment(
168 *constraint_space, Style(), NGSizeIndefinite); 181 *constraint_space_, Style(), NGSizeIndefinite);
169 LayoutUnit adjusted_block_size(block_size); 182 LayoutUnit adjusted_block_size(block_size);
170 // Our calculated block-axis size may be indefinite at this point. 183 // Our calculated block-axis size may be indefinite at this point.
171 // If so, just leave the size as NGSizeIndefinite instead of subtracting 184 // If so, just leave the size as NGSizeIndefinite instead of subtracting
172 // borders and padding. 185 // borders and padding.
173 if (adjusted_block_size != NGSizeIndefinite) 186 if (adjusted_block_size != NGSizeIndefinite)
174 adjusted_block_size -= border_and_padding_.BlockSum(); 187 adjusted_block_size -= border_and_padding_.BlockSum();
175 constraint_space_for_children_ = new NGConstraintSpace( 188
176 FromPlatformWritingMode(Style().getWritingMode()), 189 space_builder_ =
177 FromPlatformDirection(Style().direction()), *constraint_space, 190 new NGConstraintSpaceBuilder(constraint_space_->WritingMode());
191 space_builder_->SetContainerSize(
178 NGLogicalSize(adjusted_inline_size, adjusted_block_size)); 192 NGLogicalSize(adjusted_inline_size, adjusted_block_size));
193
194 constraint_space_->SetSize(
195 NGLogicalSize(adjusted_inline_size, adjusted_block_size));
196
179 content_size_ = border_and_padding_.block_start; 197 content_size_ = border_and_padding_.block_start;
180 198
181 builder_ = new NGFragmentBuilder(NGPhysicalFragmentBase::FragmentBox); 199 builder_ = new NGFragmentBuilder(NGPhysicalFragmentBase::FragmentBox);
182 builder_->SetDirection(constraint_space->Direction()); 200 builder_->SetDirection(constraint_space_->Direction());
183 builder_->SetWritingMode(constraint_space->WritingMode()); 201 builder_->SetWritingMode(constraint_space_->WritingMode());
184 builder_->SetInlineSize(inline_size).SetBlockSize(block_size); 202 builder_->SetInlineSize(inline_size).SetBlockSize(block_size);
185 current_child_ = first_child_; 203 current_child_ = first_child_;
204 if (current_child_)
205 space_for_current_child_ = CreateConstraintSpaceForChild(
206 *constraint_space_, *current_child_, space_builder_);
207
186 state_ = kStateChildLayout; 208 state_ = kStateChildLayout;
187 return false; 209 return false;
188 } 210 }
189 case kStateChildLayout: { 211 case kStateChildLayout: {
190 if (current_child_) { 212 if (current_child_) {
191 if (!LayoutCurrentChild(constraint_space)) 213 if (!LayoutCurrentChild())
192 return false; 214 return false;
193 current_child_ = current_child_->NextSibling(); 215 current_child_ = current_child_->NextSibling();
194 if (current_child_) 216 if (current_child_) {
217 space_for_current_child_ = CreateConstraintSpaceForChild(
218 *constraint_space_, *current_child_, space_builder_);
195 return false; 219 return false;
220 }
196 } 221 }
197 state_ = kStateFinalize; 222 state_ = kStateFinalize;
198 return false; 223 return false;
199 } 224 }
200 case kStateFinalize: { 225 case kStateFinalize: {
201 content_size_ += border_and_padding_.block_end; 226 content_size_ += border_and_padding_.block_end;
202 227
203 // Recompute the block-axis size now that we know our content size. 228 // Recompute the block-axis size now that we know our content size.
204 LayoutUnit block_size = ComputeBlockSizeForFragment( 229 LayoutUnit block_size = ComputeBlockSizeForFragment(
205 *constraint_space, Style(), content_size_); 230 *constraint_space_, Style(), content_size_);
206 231
207 builder_->SetBlockSize(block_size) 232 builder_->SetBlockSize(block_size)
208 .SetInlineOverflow(max_inline_size_) 233 .SetInlineOverflow(max_inline_size_)
209 .SetBlockOverflow(content_size_); 234 .SetBlockOverflow(content_size_);
210 *out = builder_->ToFragment(); 235 *out = builder_->ToFragment();
211 state_ = kStateInit; 236 state_ = kStateInit;
212 return true; 237 return true;
213 } 238 }
214 }; 239 };
215 NOTREACHED(); 240 NOTREACHED();
216 *out = nullptr; 241 *out = nullptr;
217 return true; 242 return true;
218 } 243 }
219 244
220 bool NGBlockLayoutAlgorithm::LayoutCurrentChild( 245 bool NGBlockLayoutAlgorithm::LayoutCurrentChild() {
221 const NGConstraintSpace* constraint_space) {
222 constraint_space_for_children_->SetIsNewFormattingContext(
223 IsNewFormattingContextForInFlowBlockLevelChild(*constraint_space,
224 *current_child_->Style()));
225
226 NGFragment* fragment; 246 NGFragment* fragment;
227 if (!current_child_->Layout(constraint_space_for_children_, &fragment)) 247 if (!current_child_->Layout(space_for_current_child_, &fragment))
228 return false; 248 return false;
229 249
230 NGBoxStrut child_margins = 250 NGBoxStrut child_margins = ComputeMargins(
231 ComputeMargins(*constraint_space_for_children_, *current_child_->Style(), 251 *space_for_current_child_, *current_child_->Style(),
232 constraint_space_for_children_->WritingMode(), 252 constraint_space_->WritingMode(), constraint_space_->Direction());
233 constraint_space_for_children_->Direction());
234 253
235 NGLogicalOffset fragment_offset; 254 NGLogicalOffset fragment_offset;
236 if (current_child_->Style()->isFloating()) { 255 if (current_child_->Style()->isFloating()) {
237 fragment_offset = PositionFloatFragment(*fragment, child_margins); 256 fragment_offset = PositionFloatFragment(*fragment, child_margins);
238 } else { 257 } else {
239 // TODO(layout-ng): move ApplyAutoMargins to PositionFragment 258 ApplyAutoMargins(*space_for_current_child_, *current_child_->Style(),
240 ApplyAutoMargins(*constraint_space_for_children_, *current_child_->Style(),
241 *fragment, &child_margins); 259 *fragment, &child_margins);
242 fragment_offset = 260 fragment_offset = PositionFragment(*fragment, child_margins);
243 PositionFragment(*fragment, child_margins, *constraint_space);
244 } 261 }
245 builder_->AddChild(fragment, fragment_offset); 262 builder_->AddChild(fragment, fragment_offset);
246 return true; 263 return true;
247 } 264 }
248 265
249 NGBoxStrut NGBlockLayoutAlgorithm::CollapseMargins( 266 NGBoxStrut NGBlockLayoutAlgorithm::CollapseMargins(
250 const NGConstraintSpace& space,
251 const NGBoxStrut& margins, 267 const NGBoxStrut& margins,
252 const NGFragment& fragment) { 268 const NGFragment& fragment) {
253 bool is_zero_height_box = !fragment.BlockSize() && margins.IsEmpty() && 269 bool is_zero_height_box = !fragment.BlockSize() && margins.IsEmpty() &&
254 fragment.MarginStrut().IsEmpty(); 270 fragment.MarginStrut().IsEmpty();
255 // Create the current child's margin strut from its children's margin strut or 271 // Create the current child's margin strut from its children's margin strut or
256 // use margin strut from the the last non-empty child. 272 // use margin strut from the the last non-empty child.
257 NGMarginStrut curr_margin_strut = 273 NGMarginStrut curr_margin_strut =
258 is_zero_height_box ? prev_child_margin_strut_ : fragment.MarginStrut(); 274 is_zero_height_box ? prev_child_margin_strut_ : fragment.MarginStrut();
259 275
260 // Calculate borders and padding for the current child. 276 // Calculate borders and padding for the current child.
261 NGBoxStrut border_and_padding = 277 NGBoxStrut border_and_padding =
262 ComputeBorders(*current_child_->Style()) + 278 ComputeBorders(*current_child_->Style()) +
263 ComputePadding(space, *current_child_->Style()); 279 ComputePadding(*constraint_space_, *current_child_->Style());
264 280
265 // Collapse BLOCK-START margins if there is no padding or border between 281 // Collapse BLOCK-START margins if there is no padding or border between
266 // parent (current child) and its first in-flow child. 282 // parent (current child) and its first in-flow child.
267 if (border_and_padding.block_start) { 283 if (border_and_padding.block_start) {
268 curr_margin_strut.SetMarginBlockStart(margins.block_start); 284 curr_margin_strut.SetMarginBlockStart(margins.block_start);
269 } else { 285 } else {
270 curr_margin_strut.AppendMarginBlockStart(margins.block_start); 286 curr_margin_strut.AppendMarginBlockStart(margins.block_start);
271 } 287 }
272 288
273 // Collapse BLOCK-END margins if 289 // Collapse BLOCK-END margins if
274 // 1) there is no padding or border between parent (current child) and its 290 // 1) there is no padding or border between parent (current child) and its
275 // first/last in-flow child 291 // first/last in-flow child
276 // 2) parent's logical height is auto. 292 // 2) parent's logical height is auto.
277 if (current_child_->Style()->logicalHeight().isAuto() && 293 if (current_child_->Style()->logicalHeight().isAuto() &&
278 !border_and_padding.block_end) { 294 !border_and_padding.block_end) {
279 curr_margin_strut.AppendMarginBlockEnd(margins.block_end); 295 curr_margin_strut.AppendMarginBlockEnd(margins.block_end);
280 } else { 296 } else {
281 curr_margin_strut.SetMarginBlockEnd(margins.block_end); 297 curr_margin_strut.SetMarginBlockEnd(margins.block_end);
282 } 298 }
283 299
284 NGBoxStrut result_margins; 300 NGBoxStrut result_margins;
285 // Margins of the newly established formatting context do not participate 301 // Margins of the newly established formatting context do not participate
286 // in Collapsing Margins: 302 // in Collapsing Margins:
287 // - Compute margins block start for adjoining blocks *including* 1st block. 303 // - Compute margins block start for adjoining blocks *including* 1st block.
288 // - Compute margins block end for the last block. 304 // - Compute margins block end for the last block.
289 // - Do not set the computed margins to the parent fragment. 305 // - Do not set the computed margins to the parent fragment.
290 if (space.IsNewFormattingContext()) { 306 if (constraint_space_->IsNewFormattingContext()) {
291 result_margins.block_start = ComputeCollapsedMarginBlockStart( 307 result_margins.block_start = ComputeCollapsedMarginBlockStart(
292 prev_child_margin_strut_, curr_margin_strut); 308 prev_child_margin_strut_, curr_margin_strut);
293 bool is_last_child = !current_child_->NextSibling(); 309 bool is_last_child = !current_child_->NextSibling();
294 if (is_last_child) 310 if (is_last_child)
295 result_margins.block_end = curr_margin_strut.BlockEndSum(); 311 result_margins.block_end = curr_margin_strut.BlockEndSum();
296 return result_margins; 312 return result_margins;
297 } 313 }
298 314
299 // Zero-height boxes are ignored and do not participate in margin collapsing. 315 // Zero-height boxes are ignored and do not participate in margin collapsing.
300 if (is_zero_height_box) 316 if (is_zero_height_box)
301 return result_margins; 317 return result_margins;
302 318
303 // Compute the margin block start for adjoining blocks *excluding* 1st block 319 // Compute the margin block start for adjoining blocks *excluding* 1st block
304 if (is_fragment_margin_strut_block_start_updated_) { 320 if (is_fragment_margin_strut_block_start_updated_) {
305 result_margins.block_start = ComputeCollapsedMarginBlockStart( 321 result_margins.block_start = ComputeCollapsedMarginBlockStart(
306 prev_child_margin_strut_, curr_margin_strut); 322 prev_child_margin_strut_, curr_margin_strut);
307 } 323 }
308 324
309 // Update the parent fragment's margin strut 325 // Update the parent fragment's margin strut
310 UpdateMarginStrut(curr_margin_strut); 326 UpdateMarginStrut(curr_margin_strut);
311 327
312 prev_child_margin_strut_ = curr_margin_strut; 328 prev_child_margin_strut_ = curr_margin_strut;
313 return result_margins; 329 return result_margins;
314 } 330 }
315 331
316 NGLogicalOffset NGBlockLayoutAlgorithm::PositionFragment( 332 NGLogicalOffset NGBlockLayoutAlgorithm::PositionFragment(
317 const NGFragment& fragment, 333 const NGFragment& fragment,
318 const NGBoxStrut& child_margins, 334 const NGBoxStrut& child_margins) {
319 const NGConstraintSpace& space) { 335 const NGBoxStrut collapsed_margins = CollapseMargins(child_margins, fragment);
320 const NGBoxStrut collapsed_margins =
321 CollapseMargins(space, child_margins, fragment);
322 336
323 LayoutUnit inline_offset = 337 LayoutUnit inline_offset =
324 border_and_padding_.inline_start + child_margins.inline_start; 338 border_and_padding_.inline_start + child_margins.inline_start;
325 LayoutUnit block_offset = content_size_ + collapsed_margins.block_start; 339 LayoutUnit block_offset = content_size_ + collapsed_margins.block_start;
326 340
327 content_size_ += fragment.BlockSize() + collapsed_margins.BlockSum(); 341 content_size_ += fragment.BlockSize() + collapsed_margins.BlockSum();
328 max_inline_size_ = std::max( 342 max_inline_size_ = std::max(
329 max_inline_size_, fragment.InlineSize() + child_margins.InlineSum() + 343 max_inline_size_, fragment.InlineSize() + child_margins.InlineSum() +
330 border_and_padding_.InlineSum()); 344 border_and_padding_.InlineSum());
331 return NGLogicalOffset(inline_offset, block_offset); 345 return NGLogicalOffset(inline_offset, block_offset);
332 } 346 }
333 347
334 NGLogicalOffset NGBlockLayoutAlgorithm::PositionFloatFragment( 348 NGLogicalOffset NGBlockLayoutAlgorithm::PositionFloatFragment(
335 const NGFragment& fragment, 349 const NGFragment& fragment,
336 const NGBoxStrut& margins) { 350 const NGBoxStrut& margins) {
337 // TODO(glebl@chromium.org): Support the top edge alignment rule. 351 // TODO(glebl@chromium.org): Support the top edge alignment rule.
338 // Find a layout opportunity that will fit our float. 352 // Find a layout opportunity that will fit our float.
339 const NGLayoutOpportunity opportunity = FindLayoutOpportunityForFragment( 353 const NGLayoutOpportunity opportunity =
340 constraint_space_for_children_, fragment, margins); 354 FindLayoutOpportunityForFragment(constraint_space_, fragment, margins);
341 DCHECK(!opportunity.IsEmpty()) << "Opportunity is empty but it shouldn't be"; 355 DCHECK(!opportunity.IsEmpty()) << "Opportunity is empty but it shouldn't be";
342 356
343 // Calculate the float offset if needed. 357 // Calculate the float offset if needed.
344 LayoutUnit float_offset; 358 LayoutUnit float_offset;
345 if (current_child_->Style()->floating() == EFloat::Right) { 359 if (current_child_->Style()->floating() == EFloat::Right) {
346 float_offset = opportunity.size.inline_size - fragment.InlineSize(); 360 float_offset = opportunity.size.inline_size - fragment.InlineSize();
347 } 361 }
348 362
349 // Add the float as an exclusion. 363 // Add the float as an exclusion.
350 const NGExclusion* exclusion = 364 const NGExclusion* exclusion =
351 CreateExclusion(fragment, opportunity, float_offset, margins); 365 CreateExclusion(fragment, opportunity, float_offset, margins);
352 constraint_space_for_children_->AddExclusion(exclusion); 366 constraint_space_->AddExclusion(exclusion);
353 367
354 return CalculateLogicalOffsetForOpportunity(opportunity, border_and_padding_, 368 return CalculateLogicalOffsetForOpportunity(opportunity, border_and_padding_,
355 float_offset, margins); 369 float_offset, margins);
356 } 370 }
357 371
358 void NGBlockLayoutAlgorithm::UpdateMarginStrut(const NGMarginStrut& from) { 372 void NGBlockLayoutAlgorithm::UpdateMarginStrut(const NGMarginStrut& from) {
359 if (!is_fragment_margin_strut_block_start_updated_) { 373 if (!is_fragment_margin_strut_block_start_updated_) {
360 builder_->SetMarginStrutBlockStart(from); 374 builder_->SetMarginStrutBlockStart(from);
361 is_fragment_margin_strut_block_start_updated_ = true; 375 is_fragment_margin_strut_block_start_updated_ = true;
362 } 376 }
363 builder_->SetMarginStrutBlockEnd(from); 377 builder_->SetMarginStrutBlockEnd(from);
364 } 378 }
365 379
366 DEFINE_TRACE(NGBlockLayoutAlgorithm) { 380 DEFINE_TRACE(NGBlockLayoutAlgorithm) {
367 NGLayoutAlgorithm::trace(visitor); 381 NGLayoutAlgorithm::trace(visitor);
368 visitor->trace(first_child_); 382 visitor->trace(first_child_);
383 visitor->trace(constraint_space_);
369 visitor->trace(builder_); 384 visitor->trace(builder_);
370 visitor->trace(constraint_space_for_children_); 385 visitor->trace(space_builder_);
386 visitor->trace(space_for_current_child_);
371 visitor->trace(current_child_); 387 visitor->trace(current_child_);
372 } 388 }
373 389
374 } // namespace blink 390 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698