Commit a8038d12 authored by Aleks Totic's avatar Aleks Totic Committed by Commit Bot

[LayoutNG] Initial implementation of scrollable overflow.

This patch was inspired by trying to fix scrollbar
appearance of
external/wpt/pointerevents/pointerevent_touch-action-span-test_touch-manual.html

Vertical scrollbar was missing, and horizontal scrollbar was too short.

Scrollable overflow is the space fragment will contribute to its
container's scrollable area. For box, and text fragments, this area
is equivalent to its border-box. Lineboxes are different, linebox
size is independent of its scrollable area because linebox height
is line height, and not "border-box" height.

https://drafts.csswg.org/css2/visudet.html#inline-non-replaced
"The vertical padding, border and margin of an inline,
non-replaced box start at the top and bottom of the
content area, and has nothing to do with the 'line-height'.
But only the 'line-height' is used when calculating the
height of the line box."

This patch adds ScrollableOverflow method to all fragments.
ScrollableOverflow of all fragment types except Linebox
return border-box.
Linebox returns sum of its children scroll overflows.

This fixed "missing vertical scrollbar" portion of my test case.

Tests:
I've added 2 tests for overflow with inline children.

overflow-inline-001.html tests padding and layout overflow.
This tests currently fails, will have to wait for the part 2
of this patch, "Inline_end padding for inline children".

overflow-inline-002.html tests linebox ScrollableOverflow.

1 test was rebased because results are closer to Legacy with NG
(1px diff)


Bug: 728378
Cq-Include-Trybots: master.tryserver.blink:linux_trusty_blink_rel;master.tryserver.chromium.linux:linux_layout_tests_layout_ng;master.tryserver.chromium.linux:linux_layout_tests_slimming_paint_v2
Change-Id: Id1bc204f0863eac23926c3cd1dbef0c544eb9b29
Reviewed-on: https://chromium-review.googlesource.com/1067243
Commit-Queue: Aleks Totic <atotic@chromium.org>
Reviewed-by: default avatarKoji Ishii <kojii@chromium.org>
Cr-Commit-Position: refs/heads/master@{#560367}
parent a418d353
......@@ -505,7 +505,6 @@ crbug.com/591099 external/wpt/payment-request/payment-allowed-by-feature-policy.
crbug.com/591099 external/wpt/payment-request/payment-disabled-by-feature-policy.https.sub.html [ Pass ]
crbug.com/591099 external/wpt/pointerevents/pointerevent_click_during_capture-manual.html [ Crash Timeout ]
crbug.com/591099 external/wpt/pointerevents/pointerevent_pointerleave_pen-manual.html [ Failure ]
crbug.com/591099 external/wpt/pointerevents/pointerevent_touch-action-span-test_touch-manual.html [ Failure ]
crbug.com/591099 external/wpt/quirks/line-height-calculation.html [ Failure ]
crbug.com/591099 external/wpt/quirks/table-cell-width-calculation.html [ Pass ]
crbug.com/591099 external/wpt/requestidlecallback/basic.html [ Pass ]
......@@ -722,9 +721,6 @@ crbug.com/591099 fast/events/sequential-focus-navigation-starting-point.html [ F
crbug.com/591099 fast/events/touch/compositor-touch-hit-rects.html [ Failure ]
crbug.com/591099 fast/events/wheel/mainthread-touchpad-fling-latching.html [ Pass ]
crbug.com/591099 fast/events/wheel/wheel-scroll-latching-on-scrollbar.html [ Pass ]
crbug.com/714962 fast/forms/calendar-picker/calendar-picker-mouse-operations.html [ Failure ]
crbug.com/714962 fast/forms/calendar-picker/month-picker-mouse-operations.html [ Failure ]
crbug.com/714962 fast/forms/calendar-picker/week-picker-mouse-operations.html [ Failure ]
crbug.com/591099 fast/forms/control-clip-overflow.html [ Failure ]
crbug.com/591099 fast/forms/fieldset/fieldset-with-float.html [ Failure ]
crbug.com/591099 fast/forms/form-hides-table.html [ Failure ]
......@@ -871,10 +867,6 @@ crbug.com/591099 fast/table/dynamic-descendant-percentage-height.html [ Failure
crbug.com/591099 fast/table/empty-table-percent-height.html [ Failure ]
crbug.com/591099 fast/table/fixed-table-layout/table-with-percent-width.html [ Failure ]
crbug.com/591099 fast/table/height-percent-test-vertical.html [ Failure ]
crbug.com/714962 fast/table/hittest-tablecell-bottom-edge.html [ Failure ]
crbug.com/714962 fast/table/hittest-tablecell-right-edge.html [ Failure ]
crbug.com/714962 fast/table/hittest-tablecell-with-borders-bottom-edge.html [ Failure ]
crbug.com/714962 fast/table/hittest-tablecell-with-borders-right-edge.html [ Failure ]
crbug.com/591099 fast/table/large-shrink-wrapped-width.html [ Failure ]
crbug.com/591099 fast/table/percent-height-overflow-auto-content-in-cell.html [ Failure ]
crbug.com/591099 fast/table/percent-height-overflow-scroll-content-in-cell.html [ Failure Pass ]
......@@ -1107,6 +1099,7 @@ crbug.com/591099 media/video-poster-scale.html [ Failure ]
crbug.com/591099 media/video-replaces-poster.html [ Failure ]
crbug.com/591099 media/video-zoom.html [ Failure ]
crbug.com/591099 netinfo/estimate-multiple-frames.html [ Failure Pass ]
crbug.com/728378 overflow/overflow-inline-001.html [ Failure ]
crbug.com/591099 paint/inline/focus-ring-under-absolute-with-relative-continuation.html [ Failure ]
crbug.com/591099 paint/invalidation/background/backgroundSizeRepaint.html [ Failure ]
crbug.com/591099 paint/invalidation/block-layout-inline-children-replaced.html [ Failure ]
......
......@@ -396,6 +396,7 @@ crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/webkit-margin-coll
### virtual/layout_ng/overflow
crbug.com/724701 virtual/layout_ng/overflow/overflow-basic-004.html [ Failure ]
crbug.com/724701 virtual/layout_ng/overflow/overflow-inline-001.html [ Failure ]
### single pixel underline Mac failures
crbug.com/635619 [ Mac ] virtual/layout_ng/fast/block/margin-collapse/001.html [ Failure ]
......
layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 790
layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 791
LayoutView at (0,0) size 800x600
layer at (0,0) size 785x790 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
LayoutNGBlockFlow {HTML} at (0,0) size 785x790.33
......
......@@ -15,7 +15,7 @@
background-color: rgba(0, 255, 0, 0.3);
}
</style>
<p>Overflow with container padding: container block_end, inline_end padding, are not part of overflow.</p>
<p>Overflow with container padding, and block children: container block_end padding is part of overflow, inline_end is not part of overflow.</p>
<div id="container">
<div id="target"></div>
</div>
......
<!doctype html>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<style>
#container {
overflow: auto;
outline: black solid 1px;
line-height: 0px;
width: 100px;
padding: 5px 10px 15px 20px;
}
#target {
font: 10px Ahem;
color: rgba(0,255.0, 0.3);
background-color: rgba(0, 255, 0, 0.3);
}
</style>
<p>Overflow with container padding for inline children: container padding
block_end and inline_end are part of overflow.</p>
<div id="container"><span id="target">01234567890123456789</span></div>
<script>
var container = document.querySelector('#container');
var target = document.querySelector('#target');
test(function() {
var containerStyle = window.getComputedStyle(container);
assert_equals(container.scrollHeight, target.offsetHeight +
parseInt(containerStyle.paddingTop) +
parseInt(containerStyle.paddingBottom), "vertical");
assert_equals(container.scrollWidth, target.offsetWidth +
parseInt(containerStyle.paddingLeft) +
parseInt(containerStyle.paddingRight), "horizontal");
}, "overflow with padding");
</script>
<!doctype html>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<style>
#container {
font: 20px Ahem;
overflow-y: scroll;
outline: black solid 1px;
width: 120px;
}
#target {
padding-bottom: 200px;
outline: rgba(0,255.0, 0.3) solid 3px;
}
</style>
<!--
#target's padding bottom does is not part line height of first linebox,
but is part of scroll overflow of first linebox.
-->
<p>Overflow of inline children descendants: linebox should propagate children
scroll overflow to container.
.</p>
<div id="container"><span id="ref">0 1 </span><span id="target">2</span> 3 4 5</div></div>
<script>
var container = document.querySelector('#container');
var target = document.querySelector('#target');
var ref = document.querySelector('#ref');
test(function() {
var targetStyle = window.getComputedStyle(target);
assert_equals(container.scrollHeight,
ref.offsetHeight + parseInt(targetStyle.paddingBottom),
"vertical");
}, "overflow with padding");
</script>
......@@ -147,17 +147,21 @@ scoped_refptr<NGLayoutResult> NGLineBoxFragmentBuilder::ToLineBoxFragment() {
NGPhysicalSize physical_size = Size().ConvertToPhysical(writing_mode);
NGPhysicalOffsetRect contents_visual_rect({}, physical_size);
NGPhysicalOffsetRect scrollable_overflow({}, physical_size);
for (size_t i = 0; i < children_.size(); ++i) {
NGPhysicalFragment* child = children_[i].get();
child->SetOffset(offsets_[i].ConvertToPhysical(
writing_mode, Direction(), physical_size, child->Size()));
child->PropagateContentsVisualRect(&contents_visual_rect);
NGPhysicalOffsetRect child_scroll_overflow = child->ScrollableOverflow();
child_scroll_overflow.offset += child->Offset();
scrollable_overflow.Unite(child_scroll_overflow);
}
scoped_refptr<NGPhysicalLineBoxFragment> fragment =
base::AdoptRef(new NGPhysicalLineBoxFragment(
Style(), physical_size, children_, contents_visual_rect, metrics_,
base_direction_,
Style(), physical_size, children_, contents_visual_rect,
scrollable_overflow, metrics_, base_direction_,
break_token_ ? std::move(break_token_)
: NGInlineBreakToken::Create(node_)));
......
......@@ -46,6 +46,7 @@ NGPhysicalLineBoxFragment::NGPhysicalLineBoxFragment(
NGPhysicalSize size,
Vector<scoped_refptr<NGPhysicalFragment>>& children,
const NGPhysicalOffsetRect& contents_visual_rect,
const NGPhysicalOffsetRect& scrollable_overflow,
const NGLineHeightMetrics& metrics,
TextDirection base_direction,
scoped_refptr<NGBreakToken> break_token)
......@@ -57,6 +58,7 @@ NGPhysicalLineBoxFragment::NGPhysicalLineBoxFragment(
children,
contents_visual_rect,
std::move(break_token)),
scrollable_overflow_(scrollable_overflow),
metrics_(metrics) {
base_direction_ = static_cast<unsigned>(base_direction);
}
......
......@@ -20,6 +20,7 @@ class CORE_EXPORT NGPhysicalLineBoxFragment final
NGPhysicalSize size,
Vector<scoped_refptr<NGPhysicalFragment>>& children,
const NGPhysicalOffsetRect& contents_visual_rect,
const NGPhysicalOffsetRect& scrollable_overflow,
const NGLineHeightMetrics&,
TextDirection base_direction,
scoped_refptr<NGBreakToken> break_token = nullptr);
......@@ -39,6 +40,11 @@ class CORE_EXPORT NGPhysicalLineBoxFragment final
// VisualRect of itself including contents, in the local coordinate.
NGPhysicalOffsetRect VisualRectWithContents() const;
// Scrollable overflow. including contents, in the local coordinate.
NGPhysicalOffsetRect ScrollableOverflow() const {
return scrollable_overflow_;
}
// Returns the first/last leaf fragment in the line in logical order. Returns
// nullptr if the line box is empty.
const NGPhysicalFragment* FirstLogicalLeaf() const;
......@@ -55,11 +61,12 @@ class CORE_EXPORT NGPhysicalLineBoxFragment final
scoped_refptr<NGPhysicalFragment> CloneWithoutOffset() const {
Vector<scoped_refptr<NGPhysicalFragment>> children_copy(children_);
return base::AdoptRef(new NGPhysicalLineBoxFragment(
Style(), size_, children_copy, contents_visual_rect_, metrics_,
BaseDirection(), break_token_));
Style(), size_, children_copy, contents_visual_rect_,
scrollable_overflow_, metrics_, BaseDirection(), break_token_));
}
private:
NGPhysicalOffsetRect scrollable_overflow_;
NGLineHeightMetrics metrics_;
};
......
......@@ -68,12 +68,14 @@ void LayoutNGMixin<Base>::AddOverflowFromChildren() {
physical_fragment->Style().OverflowY() != EOverflow::kHidden;
if (has_width || has_height) {
for (const auto& child : physical_fragment->Children()) {
NGPhysicalOffsetRect child_rect(child->Offset(), child->Size());
NGPhysicalOffsetRect child_overflow_rect =
child->ScrollableOverflow();
child_overflow_rect.offset += child->Offset();
if (!has_width)
child_rect.size.width = LayoutUnit();
child_overflow_rect.size.width = LayoutUnit();
if (!has_height)
child_rect.size.height = LayoutUnit();
Base::AddLayoutOverflow(child_rect.ToLayoutFlippedRect(
child_overflow_rect.size.height = LayoutUnit();
Base::AddLayoutOverflow(child_overflow_rect.ToLayoutFlippedRect(
physical_fragment->Style(), physical_fragment->Size()));
}
}
......
......@@ -329,6 +329,19 @@ NGPhysicalOffsetRect NGPhysicalFragment::VisualRectWithContents() const {
return {{}, Size()};
}
NGPhysicalOffsetRect NGPhysicalFragment::ScrollableOverflow() const {
switch (Type()) {
case NGPhysicalFragment::kFragmentBox:
return {{}, Size()};
case NGPhysicalFragment::kFragmentText:
return {{}, Size()};
case NGPhysicalFragment::kFragmentLineBox:
return ToNGPhysicalLineBoxFragment(*this).ScrollableOverflow();
}
NOTREACHED();
return {{}, Size()};
}
void NGPhysicalFragment::PropagateContentsVisualRect(
NGPhysicalOffsetRect* parent_visual_rect) const {
NGPhysicalOffsetRect visual_rect = VisualRectWithContents();
......
......@@ -169,6 +169,9 @@ class CORE_EXPORT NGPhysicalFragment
// VisualRect of itself including contents, in the local coordinate.
NGPhysicalOffsetRect VisualRectWithContents() const;
// Scrollable overflow. including contents, in the local coordinate.
NGPhysicalOffsetRect ScrollableOverflow() const;
// Unite visual rect to propagate to parent's ContentsVisualRect.
void PropagateContentsVisualRect(NGPhysicalOffsetRect*) const;
......
......@@ -793,7 +793,16 @@ bool NGBoxFragmentPainter::NodeAtPoint(
const LayoutPoint& accumulated_offset_for_legacy,
HitTestAction action) {
// TODO(eae): Switch to using NG geometry types.
LayoutSize offset(box_fragment_.Offset().left, box_fragment_.Offset().top);
LayoutSize offset;
if (box_fragment_.PhysicalFragment().IsPlacedByLayoutNG()) {
offset =
LayoutSize(box_fragment_.Offset().left, box_fragment_.Offset().top);
} else {
LayoutPoint location =
ToLayoutBox(box_fragment_.PhysicalFragment().GetLayoutObject())
->Location();
offset = LayoutSize(location.X(), location.Y());
}
LayoutPoint adjusted_location = accumulated_offset + offset;
LayoutSize size(box_fragment_.Size().width, box_fragment_.Size().height);
const ComputedStyle& style = box_fragment_.Style();
......
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