File chromium-override.patch of Package chromium.openSUSE_Leap_42.3_Update

Index: third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm.cc
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm.cc
index 1a426a995436c58bfa9aa557018415994cbed4bb..89db06af1f7341070566b05b9763c1f7a126498e 100644
--- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm.cc
+++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm.cc
@@ -55,11 +55,11 @@ NGInlineLayoutAlgorithm::NGInlineLayoutAlgorithm(
   // Only resolve our BFC offset if we know that we are non-empty as we may
   // need to pass through our margin strut.
   if (!inline_node->Items().IsEmpty()) {
-    NGLogicalOffset bfc_offset = ConstraintSpace().BfcOffset();
-    bfc_offset.block_offset += ConstraintSpace().MarginStrut().Sum();
-    MaybeUpdateFragmentBfcOffset(ConstraintSpace(), bfc_offset,
+    LayoutUnit bfc_block_offset = ConstraintSpace().BfcOffset().block_offset;
+    bfc_block_offset += ConstraintSpace().MarginStrut().Sum();
+    MaybeUpdateFragmentBfcOffset(ConstraintSpace(), bfc_block_offset,
                                  &container_builder_);
-    PositionPendingFloats(bfc_offset.block_offset, &container_builder_,
+    PositionPendingFloats(bfc_block_offset, &container_builder_,
                           MutableConstraintSpace());
   }
 
Index: third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
index 261d588dd69b4e9f05a23a9aac076f517da9d217..03f669188987dd95f3c0b65479814b192a655156 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
@@ -67,14 +67,31 @@ bool IsOutOfSpace(const NGConstraintSpace& space, LayoutUnit content_size) {
 
 }  // namespace
 
+// This struct is used for communicating to a child the position of the
+// previous inflow child.
+struct NGPreviousInflowPosition {
+  LayoutUnit bfc_block_offset;
+  LayoutUnit logical_block_offset;
+  NGMarginStrut margin_strut;
+};
+
+// This strut holds information for the current inflow child. The data is not
+// useful outside of handling this single inflow child.
+struct NGInflowChildData {
+  NGLogicalOffset bfc_offset_estimate;
+  NGMarginStrut margin_strut;
+  NGBoxStrut margins;
+};
+
 void MaybeUpdateFragmentBfcOffset(const NGConstraintSpace& space,
-                                  const NGLogicalOffset& offset,
+                                  LayoutUnit bfc_block_offset,
                                   NGFragmentBuilder* builder) {
   DCHECK(builder);
   if (!builder->BfcOffset()) {
-    NGLogicalOffset mutable_offset(offset);
-    AdjustToClearance(space.ClearanceOffset(), &mutable_offset);
-    builder->SetBfcOffset(mutable_offset);
+    NGLogicalOffset bfc_offset = {space.BfcOffset().inline_offset,
+                                  bfc_block_offset};
+    AdjustToClearance(space.ClearanceOffset(), &bfc_offset);
+    builder->SetBfcOffset(bfc_offset);
   }
 }
 
@@ -150,11 +167,13 @@ Optional<MinMaxContentSize> NGBlockLayoutAlgorithm::ComputeMinMaxContentSize()
 }
 
 NGLogicalOffset NGBlockLayoutAlgorithm::CalculateLogicalOffset(
+    const NGBoxStrut& child_margins,
     const WTF::Optional<NGLogicalOffset>& known_fragment_offset) {
   if (known_fragment_offset)
     return known_fragment_offset.value() - ContainerBfcOffset();
   LayoutUnit inline_offset =
-      border_and_padding_.inline_start + curr_child_margins_.inline_start;
+      border_and_padding_.inline_start + child_margins.inline_start;
+  // TODO(ikilpatrick): Using the content_size_ here looks suspicious - check.
   return {inline_offset, content_size_};
 }
 
@@ -199,17 +218,20 @@ RefPtr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() {
   // within a previous fragment.
   content_size_ = BreakToken() ? LayoutUnit() : border_and_padding_.block_start;
 
-  curr_margin_strut_ = ConstraintSpace().MarginStrut();
-  curr_bfc_offset_ = ConstraintSpace().BfcOffset();
+  NGMarginStrut input_margin_strut = ConstraintSpace().MarginStrut();
+  LayoutUnit input_bfc_block_offset =
+      ConstraintSpace().BfcOffset().block_offset;
 
   // Margins collapsing:
   //   Do not collapse margins between parent and its child if there is
   //   border/padding between them.
   if (border_and_padding_.block_start) {
-    curr_bfc_offset_.block_offset += curr_margin_strut_.Sum();
-    MaybeUpdateFragmentBfcOffset(ConstraintSpace(), curr_bfc_offset_,
+    input_bfc_block_offset += input_margin_strut.Sum();
+    MaybeUpdateFragmentBfcOffset(ConstraintSpace(), input_bfc_block_offset,
                                  &container_builder_);
-    curr_margin_strut_ = NGMarginStrut();
+    // We reset the block offset here as it may have been effected by clearance.
+    input_bfc_block_offset = ContainerBfcOffset().block_offset;
+    input_margin_strut = NGMarginStrut();
   }
 
   // If a new formatting context hits the margin collapsing if-branch above
@@ -218,29 +240,34 @@ RefPtr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() {
   // If we are resuming layout from a break token the same rule applies. Margin
   // struts cannot pass through break tokens.
   if (ConstraintSpace().IsNewFormattingContext() || BreakToken()) {
-    MaybeUpdateFragmentBfcOffset(ConstraintSpace(), curr_bfc_offset_,
+    MaybeUpdateFragmentBfcOffset(ConstraintSpace(), input_bfc_block_offset,
                                  &container_builder_);
-    DCHECK_EQ(curr_margin_strut_, NGMarginStrut());
+    DCHECK_EQ(input_margin_strut, NGMarginStrut());
     DCHECK_EQ(container_builder_.BfcOffset().value(), NGLogicalOffset());
-    curr_bfc_offset_ = {};
   }
 
-  curr_bfc_offset_.block_offset += content_size_;
+  input_bfc_block_offset += content_size_;
+
+  NGPreviousInflowPosition previous_inflow_position = {
+      input_bfc_block_offset, content_size_, input_margin_strut};
 
   while (child) {
     if (child->IsOutOfFlowPositioned()) {
       DCHECK(!child_break_token);
-      HandleOutOfFlowPositioned(ToNGBlockNode(child));
+      HandleOutOfFlowPositioned(previous_inflow_position, ToNGBlockNode(child));
     } else if (child->IsFloating()) {
-      HandleFloating(ToNGBlockNode(child),
+      HandleFloating(previous_inflow_position, ToNGBlockNode(child),
                      ToNGBlockBreakToken(child_break_token));
     } else {
-      NGLogicalOffset child_bfc_offset = PrepareChildLayout(child);
+      NGInflowChildData child_data =
+          PrepareChildLayout(previous_inflow_position, child);
       RefPtr<NGConstraintSpace> child_space =
-          CreateConstraintSpaceForChild(child_bfc_offset, *child);
+          CreateConstraintSpaceForChild(*child, child_data);
       RefPtr<NGLayoutResult> layout_result =
           child->Layout(child_space.Get(), child_break_token);
-      FinishChildLayout(*child_space, child, layout_result.Get());
+      previous_inflow_position =
+          FinishChildLayout(*child_space, previous_inflow_position, child_data,
+                            child, layout_result.Get());
     }
 
     entry = child_iterator.NextChild();
@@ -251,6 +278,9 @@ RefPtr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() {
       break;
   }
 
+  NGMarginStrut end_margin_strut = previous_inflow_position.margin_strut;
+  LayoutUnit end_bfc_block_offset = previous_inflow_position.bfc_block_offset;
+
   // Margins collapsing:
   //   Bottom margins of an in-flow block box doesn't collapse with its last
   //   in-flow block-level child's bottom margin if the box has bottom
@@ -258,8 +288,8 @@ RefPtr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() {
   content_size_ += border_and_padding_.block_end;
   if (border_and_padding_.block_end ||
       ConstraintSpace().IsNewFormattingContext()) {
-    content_size_ += curr_margin_strut_.Sum();
-    curr_margin_strut_ = NGMarginStrut();
+    content_size_ += end_margin_strut.Sum();
+    end_margin_strut = NGMarginStrut();
   }
 
   // Recompute the block-axis size now that we know our content size.
@@ -273,10 +303,10 @@ RefPtr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() {
   // Non-empty blocks always know their position in space.
   // TODO(ikilpatrick): This check for a break token seems error prone.
   if (size.block_size || BreakToken()) {
-    curr_bfc_offset_.block_offset += curr_margin_strut_.Sum();
-    MaybeUpdateFragmentBfcOffset(ConstraintSpace(), curr_bfc_offset_,
+    end_bfc_block_offset += end_margin_strut.Sum();
+    MaybeUpdateFragmentBfcOffset(ConstraintSpace(), end_bfc_block_offset,
                                  &container_builder_);
-    PositionPendingFloats(curr_bfc_offset_.block_offset, &container_builder_,
+    PositionPendingFloats(end_bfc_block_offset, &container_builder_,
                           MutableConstraintSpace());
   }
 
@@ -285,9 +315,9 @@ RefPtr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() {
   //   of its parent if the parent has height != auto()
   if (!Style().LogicalHeight().IsAuto()) {
     // TODO(glebl): handle minLogicalHeight, maxLogicalHeight.
-    curr_margin_strut_ = NGMarginStrut();
+    end_margin_strut = NGMarginStrut();
   }
-  container_builder_.SetEndMarginStrut(curr_margin_strut_);
+  container_builder_.SetEndMarginStrut(end_margin_strut);
 
   container_builder_.SetOverflowSize(
       NGLogicalSize(max_inline_size_, content_size_));
@@ -302,33 +332,32 @@ RefPtr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() {
   return container_builder_.ToBoxFragment();
 }
 
-void NGBlockLayoutAlgorithm::HandleOutOfFlowPositioned(NGBlockNode* child) {
-  NGLogicalOffset offset = {border_and_padding_.inline_start, content_size_};
+void NGBlockLayoutAlgorithm::HandleOutOfFlowPositioned(
+    const NGPreviousInflowPosition& previous_inflow_position,
+    NGBlockNode* child) {
+  NGLogicalOffset offset = {border_and_padding_.inline_start,
+                            previous_inflow_position.logical_block_offset};
 
   // We only include the margin strut in the OOF static-position if we know we
   // aren't going to be a zero-block-size fragment.
   if (container_builder_.BfcOffset())
-    offset.block_offset += curr_margin_strut_.Sum();
+    offset.block_offset += previous_inflow_position.margin_strut.Sum();
 
   container_builder_.AddOutOfFlowChildCandidate(child, offset);
 }
 
-void NGBlockLayoutAlgorithm::HandleFloating(NGBlockNode* child,
-                                            NGBlockBreakToken* token) {
-  // TODO(ikilpatrick): Pass in BFC offset from previous in-flow child.
-  curr_bfc_offset_ = container_builder_.BfcOffset()
-                         ? container_builder_.BfcOffset().value()
-                         : ConstraintSpace().BfcOffset();
-  curr_bfc_offset_.block_offset += content_size_;
-
+void NGBlockLayoutAlgorithm::HandleFloating(
+    const NGPreviousInflowPosition& previous_inflow_position,
+    NGBlockNode* child,
+    NGBlockBreakToken* token) {
   // Calculate margins in the BFC's writing mode.
-  curr_child_margins_ = CalculateMargins(child);
+  NGBoxStrut margins = CalculateMargins(child);
 
   NGLogicalOffset origin_offset = constraint_space_->BfcOffset();
   origin_offset.inline_offset += border_and_padding_.inline_start;
   RefPtr<NGUnpositionedFloat> unpositioned_float = NGUnpositionedFloat::Create(
       child_available_size_, child_percentage_size_, origin_offset,
-      constraint_space_->BfcOffset(), curr_child_margins_, child, token);
+      constraint_space_->BfcOffset(), margins, child, token);
   container_builder_.AddUnpositionedFloat(unpositioned_float);
 
   // If there is a break token for a float we must be resuming layout, we must
@@ -337,29 +366,28 @@ void NGBlockLayoutAlgorithm::HandleFloating(NGBlockNode* child,
 
   // No need to postpone the positioning if we know the correct offset.
   if (container_builder_.BfcOffset()) {
-    NGLogicalOffset origin_point = curr_bfc_offset_;
     // Adjust origin point to the margins of the last child.
     // Example: <div style="margin-bottom: 20px"><float></div>
     //          <div style="margin-bottom: 30px"></div>
-    origin_point.block_offset += curr_margin_strut_.Sum();
-    PositionPendingFloats(origin_point.block_offset, &container_builder_,
+    LayoutUnit origin_block_offset =
+        previous_inflow_position.bfc_block_offset +
+        previous_inflow_position.margin_strut.Sum();
+    PositionPendingFloats(origin_block_offset, &container_builder_,
                           MutableConstraintSpace());
   }
 }
 
-NGLogicalOffset NGBlockLayoutAlgorithm::PrepareChildLayout(
+NGInflowChildData NGBlockLayoutAlgorithm::PrepareChildLayout(
+    const NGPreviousInflowPosition& previous_inflow_position,
     NGLayoutInputNode* child) {
   DCHECK(child);
   DCHECK(!child->IsFloating());
 
-  // TODO(ikilpatrick): Pass in BFC offset from previous in-flow child.
-  curr_bfc_offset_ = container_builder_.BfcOffset()
-                         ? container_builder_.BfcOffset().value()
-                         : ConstraintSpace().BfcOffset();
-  curr_bfc_offset_.block_offset += content_size_;
+  LayoutUnit bfc_block_offset = previous_inflow_position.bfc_block_offset;
 
   // Calculate margins in parent's writing mode.
-  curr_child_margins_ = CalculateMargins(child);
+  NGBoxStrut margins = CalculateMargins(child);
+  NGMarginStrut margin_strut = previous_inflow_position.margin_strut;
 
   bool should_position_pending_floats =
       !IsNewFormattingContextForBlockLevelChild(Style(), *child) &&
@@ -371,45 +399,50 @@ NGLogicalOffset NGBlockLayoutAlgorithm::PrepareChildLayout(
   // be positioned before layout. This also resolves the fragment's bfc offset.
   if (should_position_pending_floats) {
     LayoutUnit origin_point_block_offset =
-        curr_bfc_offset_.block_offset + curr_margin_strut_.Sum();
-    MaybeUpdateFragmentBfcOffset(
-        ConstraintSpace(),
-        {curr_bfc_offset_.inline_offset, origin_point_block_offset},
-        &container_builder_);
+        bfc_block_offset + margin_strut.Sum();
+    MaybeUpdateFragmentBfcOffset(ConstraintSpace(), origin_point_block_offset,
+                                 &container_builder_);
+    // TODO(ikilpatrick): Check if origin_point_block_offset is correct -
+    // MaybeUpdateFragmentBfcOffset might have changed it due to clearance.
     PositionPendingFloats(origin_point_block_offset, &container_builder_,
                           MutableConstraintSpace());
   }
 
-  NGLogicalOffset child_bfc_offset = curr_bfc_offset_;
-  child_bfc_offset.inline_offset +=
-      {border_and_padding_.inline_start + curr_child_margins_.inline_start};
+  NGLogicalOffset child_bfc_offset = {
+      ConstraintSpace().BfcOffset().inline_offset +
+          border_and_padding_.inline_start + margins.inline_start,
+      bfc_block_offset};
+
+  bool is_new_fc = IsNewFormattingContextForBlockLevelChild(Style(), *child);
 
   // Append the current margin strut with child's block start margin.
   // Non empty border/padding, and new FC use cases are handled inside of the
   // child's layout.
-  if (!IsNewFormattingContextForBlockLevelChild(Style(), *child))
-    curr_margin_strut_.Append(curr_child_margins_.block_start);
+  if (!is_new_fc)
+    margin_strut.Append(margins.block_start);
 
   // TODO(crbug.com/716930): We should also collapse margins below once we
   // remove LayoutInline splitting.
 
   // Should collapse margins if our child is a legacy block.
-  if (IsLegacyBlock(*child)) {
-    curr_bfc_offset_ +=
-        {border_and_padding_.inline_start + curr_child_margins_.inline_start,
-         curr_margin_strut_.Sum()};
-    MaybeUpdateFragmentBfcOffset(ConstraintSpace(), curr_bfc_offset_,
-                                 &container_builder_);
-    PositionPendingFloats(curr_bfc_offset_.block_offset, &container_builder_,
+  // TODO(ikilpatrick): I think this can be removed.
+  if (IsLegacyBlock(*child) && !is_new_fc) {
+    child_bfc_offset.block_offset += margin_strut.Sum();
+    MaybeUpdateFragmentBfcOffset(
+        ConstraintSpace(), child_bfc_offset.block_offset, &container_builder_);
+    // TODO(ikilpatrick): Check if child_bfc_offset.block_offset is correct -
+    // MaybeUpdateFragmentBfcOffset might have changed it due to clearance.
+    PositionPendingFloats(child_bfc_offset.block_offset, &container_builder_,
                           MutableConstraintSpace());
-    curr_margin_strut_ = {};
+    margin_strut = {};
   }
-  child_bfc_offset.block_offset = curr_bfc_offset_.block_offset;
-  return child_bfc_offset;
+  return {child_bfc_offset, margin_strut, margins};
 }
 
-void NGBlockLayoutAlgorithm::FinishChildLayout(
+NGPreviousInflowPosition NGBlockLayoutAlgorithm::FinishChildLayout(
     const NGConstraintSpace& child_space,
+    const NGPreviousInflowPosition& previous_inflow_position,
+    const NGInflowChildData& child_data,
     const NGLayoutInputNode* child,
     NGLayoutResult* layout_result) {
   // Pull out unpositioned floats to the current fragment. This may needed if
@@ -425,97 +458,134 @@ void NGBlockLayoutAlgorithm::FinishChildLayout(
   // Determine the fragment's position in the parent space.
   WTF::Optional<NGLogicalOffset> child_bfc_offset;
   if (child_space.IsNewFormattingContext())
-    child_bfc_offset = PositionNewFc(fragment, child_space);
+    child_bfc_offset = PositionNewFc(*child, previous_inflow_position, fragment,
+                                     child_data, child_space);
   else if (fragment.BfcOffset())
     child_bfc_offset = PositionWithBfcOffset(fragment);
   else if (IsLegacyBlock(*child))
-    child_bfc_offset = PositionLegacy(child_space);
+    child_bfc_offset = PositionLegacy(child_space, child_data);
   else if (container_builder_.BfcOffset())
-    child_bfc_offset = PositionWithParentBfc(child_space, fragment);
+    child_bfc_offset = PositionWithParentBfc(child_space, child_data, fragment);
 
-  NGLogicalOffset logical_offset = CalculateLogicalOffset(child_bfc_offset);
+  NGLogicalOffset logical_offset =
+      CalculateLogicalOffset(child_data.margins, child_bfc_offset);
 
-  // Update margin strut.
-  curr_margin_strut_ = fragment.EndMarginStrut();
-  curr_margin_strut_.Append(curr_child_margins_.block_end);
+  NGMarginStrut margin_strut = fragment.EndMarginStrut();
+  margin_strut.Append(child_data.margins.block_end);
 
-  // Only modify content_size if BlockSize is not empty. It's needed to prevent
-  // the situation when logical_offset is included in content_size for empty
-  // blocks. Example:
+  // Only modify content_size_ if the fragment's BlockSize is not empty. This is
+  // needed to prevent the situation when logical_offset is included in
+  // content_size_ for empty blocks. Example:
   //   <div style="overflow:hidden">
   //     <div style="margin-top: 8px"></div>
   //     <div style="margin-top: 10px"></div>
   //   </div>
   if (fragment.BlockSize())
-    content_size_ = fragment.BlockSize() + logical_offset.block_offset;
-  max_inline_size_ =
-      std::max(max_inline_size_, fragment.InlineSize() +
-                                     curr_child_margins_.InlineSum() +
-                                     border_and_padding_.InlineSum());
+    content_size_ = std::max(
+        content_size_, logical_offset.block_offset + fragment.BlockSize());
+  max_inline_size_ = std::max(
+      max_inline_size_, fragment.InlineSize() + child_data.margins.InlineSum() +
+                            border_and_padding_.InlineSum());
 
   container_builder_.AddChild(layout_result, logical_offset);
+
+  // Determine the child's end BFC block offset for the next child to use.
+  LayoutUnit child_end_bfc_block_offset;
+  if (child_bfc_offset) {
+    // TODO(crbug.com/716930): I think the fragment.BfcOffset() condition here
+    // can be removed once we've removed inline splitting.
+    if (fragment.BlockSize() || fragment.BfcOffset()) {
+      child_end_bfc_block_offset =
+          child_bfc_offset.value().block_offset + fragment.BlockSize();
+    } else {
+      DCHECK_EQ(LayoutUnit(), fragment.BlockSize());
+      child_end_bfc_block_offset = previous_inflow_position.bfc_block_offset;
+    }
+  } else {
+    child_end_bfc_block_offset = ConstraintSpace().BfcOffset().block_offset;
+  }
+
+  return {child_end_bfc_block_offset,
+          logical_offset.block_offset + fragment.BlockSize(), margin_strut};
 }
 
 NGLogicalOffset NGBlockLayoutAlgorithm::PositionNewFc(
+    const NGLayoutInputNode& child,
+    const NGPreviousInflowPosition& previous_inflow_position,
     const NGBoxFragment& fragment,
+    const NGInflowChildData& child_data,
     const NGConstraintSpace& child_space) {
+  const ComputedStyle& child_style = child.Style();
+
+  LayoutUnit child_bfc_offset_estimate =
+      child_data.bfc_offset_estimate.block_offset;
+
   // 1. Position all pending floats to a temporary space.
   RefPtr<NGConstraintSpace> tmp_space =
       NGConstraintSpaceBuilder(&child_space)
           .SetIsNewFormattingContext(false)
           .ToConstraintSpace(child_space.WritingMode());
-  PositionFloats(curr_bfc_offset_.block_offset, curr_bfc_offset_.block_offset,
-                 curr_bfc_offset_.block_offset,
+  PositionFloats(child_bfc_offset_estimate, child_bfc_offset_estimate,
+                 child_bfc_offset_estimate,
                  container_builder_.UnpositionedFloats(), tmp_space.Get());
 
-  NGLogicalOffset origin_offset = curr_bfc_offset_;
-  origin_offset.inline_offset += border_and_padding_.inline_start;
+  NGLogicalOffset origin_offset = {ConstraintSpace().BfcOffset().inline_offset +
+                                       border_and_padding_.inline_start,
+                                   child_bfc_offset_estimate};
+  AdjustToClearance(
+      GetClearanceOffset(ConstraintSpace().Exclusions(), child_style.Clear()),
+      &origin_offset);
 
   // 2. Find an estimated layout opportunity for our fragment.
   NGLayoutOpportunity opportunity = FindLayoutOpportunityForFragment(
       tmp_space->Exclusions().get(), child_space.AvailableSize(), origin_offset,
-      curr_child_margins_, fragment.Size());
+      child_data.margins, fragment.Size());
+
+  NGMarginStrut margin_strut = previous_inflow_position.margin_strut;
 
   // 3. If the found opportunity lies on the same line with our estimated
   //    child's BFC offset then merge fragment's margins with the current
   //    MarginStrut.
-  if (opportunity.offset.block_offset == curr_bfc_offset_.block_offset)
-    curr_margin_strut_.Append(curr_child_margins_.block_start);
-  curr_bfc_offset_.block_offset += curr_margin_strut_.Sum();
-  curr_margin_strut_ = {};
+  if (opportunity.offset.block_offset == child_bfc_offset_estimate)
+    margin_strut.Append(child_data.margins.block_start);
+  child_bfc_offset_estimate += margin_strut.Sum();
 
   // 4. The child's BFC block offset is known here.
-  MaybeUpdateFragmentBfcOffset(ConstraintSpace(), curr_bfc_offset_,
+  MaybeUpdateFragmentBfcOffset(ConstraintSpace(), child_bfc_offset_estimate,
                                &container_builder_);
-  PositionPendingFloats(curr_bfc_offset_.block_offset, &container_builder_,
+  PositionPendingFloats(child_bfc_offset_estimate, &container_builder_,
                         MutableConstraintSpace());
 
-  origin_offset = curr_bfc_offset_;
-  origin_offset.inline_offset += border_and_padding_.inline_start;
+  origin_offset = {ConstraintSpace().BfcOffset().inline_offset +
+                       border_and_padding_.inline_start,
+                   child_bfc_offset_estimate};
+  AdjustToClearance(
+      GetClearanceOffset(ConstraintSpace().Exclusions(), child_style.Clear()),
+      &origin_offset);
 
   // 5. Find the final layout opportunity for the fragment after all pending
   // floats are positioned at the correct BFC block's offset.
   opportunity = FindLayoutOpportunityForFragment(
       MutableConstraintSpace()->Exclusions().get(), child_space.AvailableSize(),
-      origin_offset, curr_child_margins_, fragment.Size());
+      origin_offset, child_data.margins, fragment.Size());
 
-  curr_bfc_offset_ = opportunity.offset;
-  return curr_bfc_offset_;
+  return opportunity.offset;
 }
 
 NGLogicalOffset NGBlockLayoutAlgorithm::PositionWithBfcOffset(
     const NGBoxFragment& fragment) {
   DCHECK(fragment.BfcOffset());
-  curr_bfc_offset_.block_offset = fragment.BfcOffset().value().block_offset;
-  MaybeUpdateFragmentBfcOffset(ConstraintSpace(), curr_bfc_offset_,
+  LayoutUnit bfc_block_offset = fragment.BfcOffset().value().block_offset;
+  MaybeUpdateFragmentBfcOffset(ConstraintSpace(), bfc_block_offset,
                                &container_builder_);
-  PositionPendingFloats(curr_bfc_offset_.block_offset, &container_builder_,
+  PositionPendingFloats(bfc_block_offset, &container_builder_,
                         MutableConstraintSpace());
   return fragment.BfcOffset().value();
 }
 
 NGLogicalOffset NGBlockLayoutAlgorithm::PositionWithParentBfc(
     const NGConstraintSpace& space,
+    const NGInflowChildData& child_data,
     const NGBoxFragment& fragment) {
   // The child must be an in-flow zero-block-size fragment, use its end margin
   // strut for positioning.
@@ -523,22 +593,28 @@ NGLogicalOffset NGBlockLayoutAlgorithm::PositionWithParentBfc(
   DCHECK_EQ(fragment.BlockSize(), LayoutUnit());
 
   NGMarginStrut margin_strut = fragment.EndMarginStrut();
-  margin_strut.Append(curr_child_margins_.block_end);
-
-  curr_bfc_offset_ +=
-      {border_and_padding_.inline_start + curr_child_margins_.inline_start,
-       margin_strut.Sum()};
-  AdjustToClearance(space.ClearanceOffset(), &curr_bfc_offset_);
-  PositionPendingFloatsFromOffset(
-      curr_bfc_offset_.block_offset, curr_bfc_offset_.block_offset,
-      &container_builder_, MutableConstraintSpace());
-  return curr_bfc_offset_;
+  margin_strut.Append(child_data.margins.block_end);
+
+  NGLogicalOffset bfc_offset = {
+      ConstraintSpace().BfcOffset().inline_offset +
+          border_and_padding_.inline_start + child_data.margins.inline_start,
+      child_data.bfc_offset_estimate.block_offset + margin_strut.Sum()};
+  AdjustToClearance(space.ClearanceOffset(), &bfc_offset);
+  PositionPendingFloatsFromOffset(bfc_offset.block_offset,
+                                  bfc_offset.block_offset, &container_builder_,
+                                  MutableConstraintSpace());
+  return bfc_offset;
 }
 
 NGLogicalOffset NGBlockLayoutAlgorithm::PositionLegacy(
-    const NGConstraintSpace& child_space) {
-  AdjustToClearance(child_space.ClearanceOffset(), &curr_bfc_offset_);
-  return curr_bfc_offset_;
+    const NGConstraintSpace& child_space,
+    const NGInflowChildData& child_data) {
+  NGLogicalOffset bfc_offset = {ConstraintSpace().BfcOffset().inline_offset +
+                                    border_and_padding_.inline_start +
+                                    child_data.margins.inline_start,
+                                child_data.bfc_offset_estimate.block_offset};
+  AdjustToClearance(child_space.ClearanceOffset(), &bfc_offset);
+  return bfc_offset;
 }
 
 void NGBlockLayoutAlgorithm::FinalizeForFragmentation() {
@@ -609,8 +685,8 @@ NGBoxStrut NGBlockLayoutAlgorithm::CalculateMargins(NGLayoutInputNode* child) {
 }
 
 RefPtr<NGConstraintSpace> NGBlockLayoutAlgorithm::CreateConstraintSpaceForChild(
-    const NGLogicalOffset& child_bfc_offset,
-    const NGLayoutInputNode& child) {
+    const NGLayoutInputNode& child,
+    const NGInflowChildData& child_data) {
   NGConstraintSpaceBuilder space_builder(MutableConstraintSpace());
   space_builder.SetAvailableSize(child_available_size_)
       .SetPercentageResolutionSize(child_percentage_size_);
@@ -618,8 +694,8 @@ RefPtr<NGConstraintSpace> NGBlockLayoutAlgorithm::CreateConstraintSpaceForChild(
   const ComputedStyle& child_style = child.Style();
   bool is_new_bfc = IsNewFormattingContextForBlockLevelChild(Style(), child);
   space_builder.SetIsNewFormattingContext(is_new_bfc)
-      .SetBfcOffset(child_bfc_offset)
-      .SetMarginStrut(curr_margin_strut_);
+      .SetBfcOffset(child_data.bfc_offset_estimate)
+      .SetMarginStrut(child_data.margin_strut);
 
   if (!is_new_bfc) {
     space_builder.SetUnpositionedFloats(
@@ -646,7 +722,7 @@ RefPtr<NGConstraintSpace> NGBlockLayoutAlgorithm::CreateConstraintSpaceForChild(
     // position in the formatting context, and are able to adjust the
     // fragmentation line.
     if (is_new_bfc) {
-      space_available -= child_bfc_offset.block_offset;
+      space_available -= child_data.bfc_offset_estimate.block_offset;
     }
   }
   space_builder.SetFragmentainerSpaceAvailable(space_available);
Index: third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h
index 9ce63c41d0663e66ba24618426cf899c58ee19c5..6b465109af92381fd70ea9c020ecea348a25e807 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h
@@ -18,10 +18,12 @@ namespace blink {
 
 class NGConstraintSpace;
 class NGLayoutResult;
+struct NGInflowChildData;
+struct NGPreviousInflowPosition;
 
 // Updates the fragment's BFC offset if it's not already set.
 void MaybeUpdateFragmentBfcOffset(const NGConstraintSpace&,
-                                  const NGLogicalOffset&,
+                                  LayoutUnit bfc_block_offset,
                                   NGFragmentBuilder* builder);
 
 // Positions pending floats starting from {@origin_block_offset} and relative
@@ -52,15 +54,19 @@ class CORE_EXPORT NGBlockLayoutAlgorithm
 
   // Creates a new constraint space for the current child.
   RefPtr<NGConstraintSpace> CreateConstraintSpaceForChild(
-      const NGLogicalOffset& child_bfc_offset,
-      const NGLayoutInputNode&);
+      const NGLayoutInputNode& child,
+      const NGInflowChildData& child_data);
 
   // @return Estimated BFC offset for the "to be layout" child.
-  NGLogicalOffset PrepareChildLayout(NGLayoutInputNode*);
+  NGInflowChildData PrepareChildLayout(const NGPreviousInflowPosition&,
+                                       NGLayoutInputNode*);
 
-  void FinishChildLayout(const NGConstraintSpace&,
-                         const NGLayoutInputNode* child,
-                         NGLayoutResult*);
+  NGPreviousInflowPosition FinishChildLayout(
+      const NGConstraintSpace&,
+      const NGPreviousInflowPosition& prev_data,
+      const NGInflowChildData& child_data,
+      const NGLayoutInputNode* child,
+      NGLayoutResult*);
 
   // Positions the fragment that establishes a new formatting context.
   //
@@ -81,7 +87,10 @@ class CORE_EXPORT NGBlockLayoutAlgorithm
   //    then it will be placed there and we collapse its margin.
   // 2) If #new-fc is too big then we need to clear its position and place it
   //    below #float ignoring its vertical margin.
-  NGLogicalOffset PositionNewFc(const NGBoxFragment&,
+  NGLogicalOffset PositionNewFc(const NGLayoutInputNode& child,
+                                const NGPreviousInflowPosition&,
+                                const NGBoxFragment&,
+                                const NGInflowChildData& child_data,
                                 const NGConstraintSpace& child_space);
 
   // Positions the fragment that knows its BFC offset.
@@ -95,12 +104,16 @@ class CORE_EXPORT NGBlockLayoutAlgorithm
   //   <div style="padding: 1px">
   //     <div id="empty-div" style="margins: 1px"></div>
   NGLogicalOffset PositionWithParentBfc(const NGConstraintSpace&,
+                                        const NGInflowChildData& child_data,
                                         const NGBoxFragment&);
 
-  NGLogicalOffset PositionLegacy(const NGConstraintSpace& child_space);
+  NGLogicalOffset PositionLegacy(const NGConstraintSpace& child_space,
+                                 const NGInflowChildData& child_data);
 
-  void HandleOutOfFlowPositioned(NGBlockNode*);
-  void HandleFloating(NGBlockNode*, NGBlockBreakToken*);
+  void HandleOutOfFlowPositioned(const NGPreviousInflowPosition&, NGBlockNode*);
+  void HandleFloating(const NGPreviousInflowPosition&,
+                      NGBlockNode*,
+                      NGBlockBreakToken*);
 
   // Final adjustments before fragment creation. We need to prevent the
   // fragment from crossing fragmentainer boundaries, and rather create a break
@@ -112,6 +125,7 @@ class CORE_EXPORT NGBlockLayoutAlgorithm
   // or {@code known_fragment_offset} if the fragment knows it's offset
   // @return Fragment's offset relative to the fragment's parent.
   NGLogicalOffset CalculateLogicalOffset(
+      const NGBoxStrut& child_margins,
       const WTF::Optional<NGLogicalOffset>& known_fragment_offset);
 
   NGLogicalSize child_available_size_;
@@ -120,10 +134,6 @@ class CORE_EXPORT NGBlockLayoutAlgorithm
   NGBoxStrut border_and_padding_;
   LayoutUnit content_size_;
   LayoutUnit max_inline_size_;
-  // MarginStrut for the previous child.
-  NGMarginStrut curr_margin_strut_;
-  NGLogicalOffset curr_bfc_offset_;
-  NGBoxStrut curr_child_margins_;
 };
 
 }  // namespace blink
openSUSE Build Service is sponsored by