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

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

Issue 2700683002: [LayoutNG] Fix incorrectly positioned empty blocks inside of new BFC (Closed)
Patch Set: Created 3 years, 10 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_absolute_utils.h" 7 #include "core/layout/ng/ng_absolute_utils.h"
8 #include "core/layout/ng/ng_block_break_token.h" 8 #include "core/layout/ng/ng_block_break_token.h"
9 #include "core/layout/ng/ng_box_fragment.h" 9 #include "core/layout/ng/ng_box_fragment.h"
10 #include "core/layout/ng/ng_column_mapper.h" 10 #include "core/layout/ng/ng_column_mapper.h"
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after
411 content_size_ = border_and_padding_.block_start; 411 content_size_ = border_and_padding_.block_start;
412 current_child_ = first_child_; 412 current_child_ = first_child_;
413 } 413 }
414 414
415 curr_margin_strut_ = ConstraintSpace().MarginStrut(); 415 curr_margin_strut_ = ConstraintSpace().MarginStrut();
416 curr_bfc_offset_ = ConstraintSpace().BfcOffset(); 416 curr_bfc_offset_ = ConstraintSpace().BfcOffset();
417 417
418 // Margins collapsing: 418 // Margins collapsing:
419 // Do not collapse margins between parent and its child if there is 419 // Do not collapse margins between parent and its child if there is
420 // border/padding between them. 420 // border/padding between them.
421 if (border_and_padding_.block_start || 421 if (border_and_padding_.block_start) {
422 ConstraintSpace().IsNewFormattingContext()) {
423 curr_bfc_offset_.block_offset += curr_margin_strut_.Sum(); 422 curr_bfc_offset_.block_offset += curr_margin_strut_.Sum();
424 builder_->SetBfcOffset(curr_bfc_offset_); 423 UpdateFragmentBfcOffset(curr_bfc_offset_, builder_.get());
425 curr_margin_strut_ = NGMarginStrut(); 424 curr_margin_strut_ = NGMarginStrut();
426 } 425 }
ikilpatrick 2017/02/16 17:27:37 .nit nl below this?
Gleb Lanbin 2017/02/16 20:08:27 Done.
426 // Block that establishes new BFC knows its BFC offset == {}.
ikilpatrick 2017/02/16 17:27:37 Maybe some additional comments: Block that establ
Gleb Lanbin 2017/02/16 20:08:27 Done.
427 if (ConstraintSpace().IsNewFormattingContext()) {
428 UpdateFragmentBfcOffset(curr_bfc_offset_, builder_.get());
429 DCHECK_EQ(builder_->BfcOffset().value(), NGLogicalOffset());
430 DCHECK_EQ(curr_margin_strut_, NGMarginStrut());
431 }
432
427 curr_bfc_offset_.block_offset += content_size_; 433 curr_bfc_offset_.block_offset += content_size_;
428 434
429 while (current_child_) { 435 while (current_child_) {
430 if (current_child_->Type() == NGLayoutInputNode::kLegacyBlock) { 436 if (current_child_->Type() == NGLayoutInputNode::kLegacyBlock) {
431 NGBlockNode* current_block_child = toNGBlockNode(current_child_); 437 NGBlockNode* current_block_child = toNGBlockNode(current_child_);
432 EPosition position = current_block_child->Style().position(); 438 EPosition position = current_block_child->Style().position();
433 if (position == EPosition::kAbsolute || position == EPosition::kFixed) { 439 if (position == EPosition::kAbsolute || position == EPosition::kFixed) {
434 builder_->AddOutOfFlowChildCandidate(current_block_child, 440 builder_->AddOutOfFlowChildCandidate(current_block_child,
435 GetChildSpaceOffset()); 441 GetChildSpaceOffset());
436 current_child_ = current_block_child->NextSibling(); 442 current_child_ = current_block_child->NextSibling();
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
515 line_builder.CopyFragmentDataToLayoutBlockFlow(); 521 line_builder.CopyFragmentDataToLayoutBlockFlow();
516 FinishCurrentChildLayout(child_fragment.get()); 522 FinishCurrentChildLayout(child_fragment.get());
517 current_child_ = nullptr; 523 current_child_ = nullptr;
518 } 524 }
519 525
520 void NGBlockLayoutAlgorithm::FinishCurrentChildLayout( 526 void NGBlockLayoutAlgorithm::FinishCurrentChildLayout(
521 RefPtr<NGPhysicalBoxFragment> physical_fragment) { 527 RefPtr<NGPhysicalBoxFragment> physical_fragment) {
522 NGBoxFragment fragment(ConstraintSpace().WritingMode(), 528 NGBoxFragment fragment(ConstraintSpace().WritingMode(),
523 physical_fragment.get()); 529 physical_fragment.get());
524 530
525 if (!physical_fragment->UnpositionedFloats().isEmpty())
526 DCHECK(!builder_->BfcOffset()) << "Parent BFC offset shouldn't be set here";
527 // Pull out unpositioned floats to the current fragment. This may needed if 531 // Pull out unpositioned floats to the current fragment. This may needed if
528 // for example the child fragment could not position its floats because it's 532 // for example the child fragment could not position its floats because it's
529 // empty and therefore couldn't determine its position in space. 533 // empty and therefore couldn't determine its position in space.
530 builder_->MutableUnpositionedFloats().appendVector( 534 builder_->MutableUnpositionedFloats().appendVector(
531 physical_fragment->UnpositionedFloats()); 535 physical_fragment->UnpositionedFloats());
532 536
533 if (current_child_->Type() == NGLayoutInputNode::kLegacyBlock && 537 if (current_child_->Type() == NGLayoutInputNode::kLegacyBlock &&
534 CurrentChildStyle().isFloating()) { 538 CurrentChildStyle().isFloating()) {
535 NGFloatingObject* floating_object = 539 NGFloatingObject* floating_object =
536 new NGFloatingObject(physical_fragment.get(), space_for_current_child_, 540 new NGFloatingObject(physical_fragment.get(), space_for_current_child_,
(...skipping 16 matching lines...) Expand all
553 // Determine the fragment's position in the parent space either by using 557 // Determine the fragment's position in the parent space either by using
554 // content_size_ or known fragment's BFC offset. 558 // content_size_ or known fragment's BFC offset.
555 WTF::Optional<NGLogicalOffset> bfc_offset; 559 WTF::Optional<NGLogicalOffset> bfc_offset;
556 if (CurrentChildConstraintSpace().IsNewFormattingContext()) { 560 if (CurrentChildConstraintSpace().IsNewFormattingContext()) {
557 curr_bfc_offset_.block_offset += curr_margin_strut_.Sum(); 561 curr_bfc_offset_.block_offset += curr_margin_strut_.Sum();
558 bfc_offset = curr_bfc_offset_; 562 bfc_offset = curr_bfc_offset_;
559 } else if (fragment.BfcOffset()) { 563 } else if (fragment.BfcOffset()) {
560 // Fragment that knows its offset can be used to set parent's BFC position. 564 // Fragment that knows its offset can be used to set parent's BFC position.
561 curr_bfc_offset_.block_offset = fragment.BfcOffset().value().block_offset; 565 curr_bfc_offset_.block_offset = fragment.BfcOffset().value().block_offset;
562 bfc_offset = curr_bfc_offset_; 566 bfc_offset = curr_bfc_offset_;
567 } else if (builder_->BfcOffset()) {
ikilpatrick 2017/02/16 17:27:37 can you add a comment for when this will get hit,
Gleb Lanbin 2017/02/16 20:08:27 Done.
568 bfc_offset = curr_bfc_offset_;
569 bfc_offset.value().block_offset += curr_margin_strut_.Sum();
563 } 570 }
564 if (bfc_offset) { 571 if (bfc_offset) {
565 UpdateFragmentBfcOffset(curr_bfc_offset_, builder_.get()); 572 UpdateFragmentBfcOffset(curr_bfc_offset_, builder_.get());
566 PositionPendingFloats(curr_bfc_offset_.block_offset, ConstraintSpace(), 573 PositionPendingFloats(curr_bfc_offset_.block_offset, ConstraintSpace(),
567 builder_.get()); 574 builder_.get());
568 } 575 }
569 NGLogicalOffset logical_offset = CalculateLogicalOffset(bfc_offset); 576 NGLogicalOffset logical_offset = CalculateLogicalOffset(bfc_offset);
570 577
571 if (fragmentainer_mapper_) 578 if (fragmentainer_mapper_)
572 fragmentainer_mapper_->ToVisualOffset(logical_offset); 579 fragmentainer_mapper_->ToVisualOffset(logical_offset);
573 else 580 else
574 logical_offset.block_offset -= PreviousBreakOffset(); 581 logical_offset.block_offset -= PreviousBreakOffset();
575 582
576 // Update margin strut. 583 // Update margin strut.
577 curr_margin_strut_ = fragment.EndMarginStrut(); 584 curr_margin_strut_ = fragment.EndMarginStrut();
578 curr_margin_strut_.Append(curr_child_margins_.block_end); 585 curr_margin_strut_.Append(curr_child_margins_.block_end);
579 586
580 content_size_ = fragment.BlockSize() + logical_offset.block_offset; 587 // Only modify content_size if BlockSize is not empty. It's needed to prevent
588 // the situation when logical_offset is included in content_size for empty
589 // blocks. Example:
590 // <div style="overflow:hidden">
591 // <div style="margin-top: 8px"></div>
592 // <div style="margin-top: 10px"></div>
593 // </div>
594 if (fragment.BlockSize())
595 content_size_ = fragment.BlockSize() + logical_offset.block_offset;
581 max_inline_size_ = 596 max_inline_size_ =
582 std::max(max_inline_size_, fragment.InlineSize() + 597 std::max(max_inline_size_, fragment.InlineSize() +
583 curr_child_margins_.InlineSum() + 598 curr_child_margins_.InlineSum() +
584 border_and_padding_.InlineSum()); 599 border_and_padding_.InlineSum());
585 600
586 builder_->AddChild(std::move(physical_fragment), logical_offset); 601 builder_->AddChild(std::move(physical_fragment), logical_offset);
587 } 602 }
588 603
589 bool NGBlockLayoutAlgorithm::ProceedToNextUnfinishedSibling( 604 bool NGBlockLayoutAlgorithm::ProceedToNextUnfinishedSibling(
590 NGPhysicalFragment* child_fragment) { 605 NGPhysicalFragment* child_fragment) {
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
788 if (!content_size_) { 803 if (!content_size_) {
789 curr_margin_strut_ = NGMarginStrut(); 804 curr_margin_strut_ = NGMarginStrut();
790 curr_child_margins_.block_start = LayoutUnit(); 805 curr_child_margins_.block_start = LayoutUnit();
791 } 806 }
792 PositionPendingFloats(curr_bfc_offset_.block_offset, ConstraintSpace(), 807 PositionPendingFloats(curr_bfc_offset_.block_offset, ConstraintSpace(),
793 builder_.get()); 808 builder_.get());
794 AdjustToClearance(constraint_space_->Exclusions(), current_child_style, 809 AdjustToClearance(constraint_space_->Exclusions(), current_child_style,
795 builder_->BfcOffset().value(), &content_size_); 810 builder_->BfcOffset().value(), &content_size_);
796 } 811 }
797 812
798 // Append the current margin strut with child's block start margin.
799 // Non empty border/padding use cases are handled inside of the child's
800 // layout.
801 curr_margin_strut_.Append(curr_child_margins_.block_start);
802 space_builder_->SetMarginStrut(curr_margin_strut_);
803
804 // Set estimated BFC offset to the next child's constraint space. 813 // Set estimated BFC offset to the next child's constraint space.
805 curr_bfc_offset_ = builder_->BfcOffset() ? builder_->BfcOffset().value() 814 curr_bfc_offset_ = builder_->BfcOffset() ? builder_->BfcOffset().value()
806 : ConstraintSpace().BfcOffset(); 815 : ConstraintSpace().BfcOffset();
807 curr_bfc_offset_.block_offset += content_size_; 816 curr_bfc_offset_.block_offset += content_size_;
808 curr_bfc_offset_.inline_offset += border_and_padding_.inline_start; 817 curr_bfc_offset_.inline_offset += border_and_padding_.inline_start;
809 818
810 // Floats margins are not included in child's CS because they are used to 819 // Floats margins are not included in child's CS because
811 // calculate floating exclusions. 820 // 1) Floats do not participate in margins collapsing
821 // 2) Floats margins are used separately to calculate floating exclusions.
812 if (!CurrentChildStyle().isFloating()) { 822 if (!CurrentChildStyle().isFloating()) {
813 curr_bfc_offset_.inline_offset += curr_child_margins_.inline_start; 823 curr_bfc_offset_.inline_offset += curr_child_margins_.inline_start;
824 // Append the current margin strut with child's block start margin.
825 // Non empty border/padding use cases are handled inside of the child's
ikilpatrick 2017/02/16 17:27:38 .nit Non-empty?
Gleb Lanbin 2017/02/16 20:08:27 Done.
826 // layout.
827 curr_margin_strut_.Append(curr_child_margins_.block_start);
828 space_builder_->SetMarginStrut(curr_margin_strut_);
814 } 829 }
815 830
816 space_builder_->SetBfcOffset(curr_bfc_offset_); 831 space_builder_->SetBfcOffset(curr_bfc_offset_);
817 832
818 return space_builder_->ToConstraintSpace( 833 return space_builder_->ToConstraintSpace(
819 FromPlatformWritingMode(current_child_style.getWritingMode())); 834 FromPlatformWritingMode(current_child_style.getWritingMode()));
820 } 835 }
821 836
822 } // namespace blink 837 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698