Commit 68a755f9 authored by Aleks Totic's avatar Aleks Totic Committed by Commit Bot

[LayoutNG] position:fixed has special ICB

There are two tests that test this, but they are currently failing
in Legacy too.
virtual/android/url-bar/bottom-and-top-fixed-sticks-to-top.html
virtual/android/url-bar/bottom-fixed-adjusted-when-showing-url-bar.html

I've confirment manually that position:fixed, bottom:0 Elements
stick to bottom on scrolling.

There is one remaining problem.
While scrolling is active, position:fixed, bottom:0 element does
not stick to the bottom of the viewport. It gets positioned correctly
after scrolling stops. Bug #906516

Bug: 870008
Change-Id: Ibe597141869794978865809caa3991cd4c2bd8a6
Reviewed-on: https://chromium-review.googlesource.com/c/1341127
Commit-Queue: Aleks Totic <atotic@chromium.org>
Reviewed-by: default avatarChristian Biesinger <cbiesinger@chromium.org>
Reviewed-by: default avatarKoji Ishii <kojii@chromium.org>
Reviewed-by: default avatarSteve Kobes <skobes@chromium.org>
Cr-Commit-Position: refs/heads/master@{#611045}
parent dbbbfb3c
......@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/core/layout/ng/layout_ng_block_flow.h"
#include "third_party/blink/renderer/core/layout/layout_analyzer.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/layout/min_max_size.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_fragment_traversal.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_data.h"
......@@ -15,6 +16,7 @@
#include "third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h"
#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
namespace blink {
......@@ -229,6 +231,17 @@ void LayoutNGBlockFlow::UpdateOutOfFlowBlockLayout() {
NGBlockNode(this), static_position,
css_container->IsBox() ? nullptr : css_container);
base::Optional<NGLogicalSize> initial_containing_block_fixed_size;
if (container->IsLayoutView() && !GetDocument().Printing()) {
if (LocalFrameView* frame_view = ToLayoutView(container)->GetFrameView()) {
IntSize size =
frame_view->LayoutViewport()->ExcludeScrollbars(frame_view->Size());
NGPhysicalSize physical_size =
NGPhysicalSize(LayoutUnit(size.Width()), LayoutUnit(size.Height()));
initial_containing_block_fixed_size =
physical_size.ConvertToLogical(container->Style()->GetWritingMode());
}
}
// We really only want to lay out ourselves here, so we pass |this| to
// Run(). Otherwise, NGOutOfFlowLayoutPart may also lay out other objects
// it discovers that are part of the same containing block, but those
......@@ -236,7 +249,7 @@ void LayoutNGBlockFlow::UpdateOutOfFlowBlockLayout() {
NGOutOfFlowLayoutPart(
&container_builder, css_container->CanContainAbsolutePositionObjects(),
css_container->CanContainFixedPositionObjects(), borders_and_scrollbars,
constraint_space, *container_style)
constraint_space, *container_style, initial_containing_block_fixed_size)
.Run(/* only_layout */ this);
scoped_refptr<NGLayoutResult> result = container_builder.ToBoxFragment();
// These are the unpositioned OOF descendants of the current OOF block.
......
......@@ -132,6 +132,10 @@ class CORE_EXPORT NGContainerFragmentBuilder : public NGFragmentBuilder {
Vector<NGOutOfFlowPositionedDescendant>* descendant_candidates,
const LayoutObject* container);
bool HasOutOfFlowDescendantCandidates() const {
return !oof_positioned_candidates_.IsEmpty();
}
// Utility routine to move all OOF descendant candidates to descendants.
// Use if fragment cannot position any OOF children.
void MoveOutOfFlowDescendantCandidatesToDescendants(
......
......@@ -27,23 +27,31 @@ NGOutOfFlowLayoutPart::NGOutOfFlowLayoutPart(
bool contains_fixed,
const NGBoxStrut& borders_and_scrollers,
const NGConstraintSpace& container_space,
const ComputedStyle& container_style)
const ComputedStyle& container_style,
base::Optional<NGLogicalSize> initial_containing_block_fixed_size)
: container_builder_(container_builder),
contains_absolute_(contains_absolute),
contains_fixed_(contains_fixed) {
if (!container_builder->HasOutOfFlowDescendantCandidates())
return;
NGPhysicalBoxStrut physical_borders = borders_and_scrollers.ConvertToPhysical(
container_style.GetWritingMode(), container_style.Direction());
default_containing_block_.style = &container_style;
default_containing_block_.content_size = container_builder_->Size();
default_containing_block_.content_size.inline_size =
std::max(default_containing_block_.content_size.inline_size -
default_containing_block_.content_size_for_absolute =
container_builder_->Size();
default_containing_block_.content_size_for_absolute.inline_size =
std::max(default_containing_block_.content_size_for_absolute.inline_size -
borders_and_scrollers.InlineSum(),
LayoutUnit());
default_containing_block_.content_size.block_size =
std::max(default_containing_block_.content_size.block_size -
default_containing_block_.content_size_for_absolute.block_size =
std::max(default_containing_block_.content_size_for_absolute.block_size -
borders_and_scrollers.BlockSum(),
LayoutUnit());
default_containing_block_.content_size_for_fixed =
initial_containing_block_fixed_size
? initial_containing_block_fixed_size.value()
: default_containing_block_.content_size_for_absolute;
default_containing_block_.content_offset = NGLogicalOffset{
borders_and_scrollers.inline_start, borders_and_scrollers.block_start};
default_containing_block_.content_physical_offset =
......@@ -267,10 +275,11 @@ void NGOutOfFlowLayoutPart::ComputeInlineContainingBlocks(
default_container_offset += inline_cb_borders.StartOffset();
}
containing_blocks_map_.insert(
block_info.key, ContainingBlockInfo{inline_cb_style, inline_cb_size,
inline_content_offset,
inline_content_physical_offset,
default_container_offset});
block_info.key,
ContainingBlockInfo{inline_cb_style, inline_cb_size, inline_cb_size,
inline_content_offset,
inline_content_physical_offset,
default_container_offset});
}
}
......@@ -291,7 +300,8 @@ scoped_refptr<NGLayoutResult> NGOutOfFlowLayoutPart::LayoutDescendant(
// and default_container border width.
NGStaticPosition static_position(descendant.static_position);
NGPhysicalSize default_containing_block_physical_size =
ToNGPhysicalSize(default_containing_block_.content_size,
ToNGPhysicalSize(default_containing_block_.ContentSize(
descendant.node.Style().GetPosition()),
default_containing_block_.style->GetWritingMode());
NGPhysicalOffset default_container_physical_offset =
container_info.default_container_offset.ConvertToPhysical(
......@@ -304,13 +314,15 @@ scoped_refptr<NGLayoutResult> NGOutOfFlowLayoutPart::LayoutDescendant(
default_containing_block_.content_physical_offset -
default_container_physical_offset;
NGLogicalSize container_content_size =
container_info.ContentSize(descendant.node.Style().GetPosition());
// The block estimate is in the descendant's writing mode.
NGConstraintSpace descendant_constraint_space =
NGConstraintSpaceBuilder(container_writing_mode, descendant_writing_mode,
/* is_new_fc */ true)
.SetTextDirection(container_info.style->Direction())
.SetAvailableSize(container_info.content_size)
.SetPercentageResolutionSize(container_info.content_size)
.SetAvailableSize(container_content_size)
.SetPercentageResolutionSize(container_content_size)
.ToConstraintSpace();
base::Optional<MinMaxSize> min_max_size;
base::Optional<LayoutUnit> block_estimate;
......@@ -431,8 +443,9 @@ scoped_refptr<NGLayoutResult> NGOutOfFlowLayoutPart::GenerateFragment(
// the constraint space in the descendant's writing mode.
WritingMode writing_mode(descendant.Style().GetWritingMode());
NGLogicalSize container_size(
ToNGPhysicalSize(container_info.content_size,
default_containing_block_.style->GetWritingMode())
ToNGPhysicalSize(
container_info.ContentSize(descendant.Style().GetPosition()),
default_containing_block_.style->GetWritingMode())
.ConvertToLogical(writing_mode));
LayoutUnit inline_size =
......
......@@ -10,6 +10,7 @@
#include "base/optional.h"
#include "third_party/blink/renderer/core/layout/ng/geometry/ng_physical_offset.h"
#include "third_party/blink/renderer/core/layout/ng/ng_absolute_utils.h"
#include "third_party/blink/renderer/core/style/computed_style_base_constants.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
namespace blink {
......@@ -37,12 +38,15 @@ class CORE_EXPORT NGOutOfFlowLayoutPart {
// block" of such an out-of-flow positioned descendant isn't a true block (but
// e.g. a relatively positioned inline instead), the containing block here is
// the containing block of said non-block.
NGOutOfFlowLayoutPart(NGBoxFragmentBuilder* container_builder,
bool contains_absolute,
bool contains_fixed,
const NGBoxStrut& borders_and_scrollers,
const NGConstraintSpace& container_space,
const ComputedStyle& container_style);
NGOutOfFlowLayoutPart(
NGBoxFragmentBuilder* container_builder,
bool contains_absolute,
bool contains_fixed,
const NGBoxStrut& borders_and_scrollers,
const NGConstraintSpace& container_space,
const ComputedStyle& container_style,
base::Optional<NGLogicalSize> initial_containing_block_fixed_size =
base::nullopt);
// Normally this function lays out and positions all out-of-flow objects
// from the container_builder and additional ones it discovers through laying
......@@ -70,7 +74,9 @@ class CORE_EXPORT NGOutOfFlowLayoutPart {
// Containing block style.
const ComputedStyle* style;
// Logical in containing block coordinates.
NGLogicalSize content_size;
NGLogicalSize content_size_for_absolute;
// Content size for fixed is different for icb
NGLogicalSize content_size_for_fixed;
// Content offset wrt border box.
NGLogicalOffset content_offset;
// Physical content offset wrt border box.
......@@ -78,6 +84,11 @@ class CORE_EXPORT NGOutOfFlowLayoutPart {
// Logical offset of container padding box
// wrt default containing block padding box.
NGLogicalOffset default_container_offset;
NGLogicalSize ContentSize(EPosition position) const {
return position == EPosition::kAbsolute ? content_size_for_absolute
: content_size_for_fixed;
}
};
ContainingBlockInfo GetContainingBlockInfo(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment