Commit 137ca588 authored by Suneel Kota's avatar Suneel Kota Committed by Commit Bot

Navigating to fragment scrolls with writing-mode: vertical-rl

This CL sets the alignment of the Anchor node in accordance, when
vertical-rl writing-mode is set

Bug: 844868
Change-Id: I8357bcccbc88ffcd3b5d01265737a5b60f1e59a8
Reviewed-on: https://chromium-review.googlesource.com/1075956
Commit-Queue: srirama chandra sekhar <srirama.m@samsung.com>
Reviewed-by: default avatarDavid Bokan <bokan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#569214}
parent c5604690
<!DOCTYPE html>
<title>CSSOM View - scrollIntoView considers vertical-rl writing mode</title>
<meta charset="utf-8">
<link rel="author" title="Suneel Kota" href="mailto:suneel.kota@samsung.com">
<link rel="help" href="https://drafts.csswg.org/cssom-view/#dom-element-scrollintoview">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
.box {
float: left;
width: 200px;
height: 200px;
}
#scroller {
writing-mode: vertical-rl;
overflow: scroll;
width: 300px;
height: 300px;
}
#container{
width: 600px;
height: 600px;
}
#target {
background-color: #ff0;
}
</style>
<body>
<div id="scroller">
<div id="container">
<!-- ROW-1 -->
<div class="row">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
<!-- ROW-2 -->
<div class="row">
<div class="box"></div>
<div class="box" id="target"></div>
<div class="box"></div>
</div>
<!-- ROW-3 -->
<div class="row">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
</div>
</div>
<script>
var target = document.getElementById("target");
var scroller = document.getElementById("scroller");
var scrollbar_width = scroller.offsetWidth - scroller.clientWidth;
var scroller_width = scroller.offsetWidth;
var scroller_height = scroller.offsetHeight;
var box_width = target.offsetWidth;
var box_height = target.offsetHeight;
var expectedX = [ ((2*box_width)-scroller_width)+scrollbar_width, ((3*box_width - scroller_width)/2)+ (scrollbar_width/2), box_width ];
var expectedY = [ box_height, ((3*box_height - scroller_height)/2) + (scrollbar_width/2), ((2*box_height)-scroller_height) + scrollbar_width ];
// As browsers differ in the meaning of scrollLeft when
// in a right-to-left mode, we adjust the expectation
// to match the semantics of scrollLeft.
if(scroller.scrollLeft === 0)
expectedX = [ -box_width, -(((3*box_width - scroller_width)/2)+ (scrollbar_width/2)), -(((2*box_width)-scroller_width)+scrollbar_width)];
// This formats dict as a string suitable as test name.
// format_value() is provided by testharness.js,
// which also preserves sign for -0.
function format_dict(dict) {
const props = [];
for (let prop in dict) {
props.push(`${prop}: ${format_value(dict[prop])}`);
}
return `{${props.join(", ")}}`;
}
[
[{block: "start", inline: "start"}, expectedX[0], expectedY[0]],
[{block: "start", inline: "center"}, expectedX[0], expectedY[1]],
[{block: "start", inline: "end"}, expectedX[0], expectedY[2]],
[{block: "center", inline: "start"}, expectedX[1], expectedY[0]],
[{block: "center", inline: "center"}, expectedX[1], expectedY[1]],
[{block: "center", inline: "end"}, expectedX[1], expectedY[2]],
[{block: "end", inline: "start"}, expectedX[2], expectedY[0]],
[{block: "end", inline: "center"}, expectedX[2], expectedY[1]],
[{block: "end", inline: "end"}, expectedX[2], expectedY[2]],
].forEach(([input, expectedX, expectedY]) => {
test(() => {
scroller.scrollTo(0, 0);
target.scrollIntoView(input);
assert_approx_equals(scroller.scrollLeft, expectedX, 0.5, "scrollX");
assert_approx_equals(scroller.scrollTop, expectedY, 0.5, "scrollY");
}, `scrollIntoView(${format_dict(input)})`);
})
</script>
</body>
</html>
This is a testharness.js-based test.
FAIL Fragment Navigation: Scroll to block start position in vertical-lr writing mode assert_equals: Scroll to the left border edge of #test expected 14 but got 0
Harness: the test ran to completion.
This is a testharness.js-based test.
FAIL Fragment Navigation: Scroll to block start position in vertical-rl writing mode assert_equals: Scroll to the right border edge of #test expected -14 but got 0
Harness: the test ran to completion.
......@@ -496,7 +496,8 @@ void Element::scrollIntoView(bool align_to_top) {
static ScrollAlignment ToPhysicalAlignment(const ScrollIntoViewOptions& options,
ScrollOrientation axis,
bool is_horizontal_writing_mode) {
bool is_horizontal_writing_mode,
bool is_flipped_blocks_mode) {
String alignment =
((axis == kHorizontalScroll && is_horizontal_writing_mode) ||
(axis == kVerticalScroll && !is_horizontal_writing_mode))
......@@ -508,12 +509,16 @@ static ScrollAlignment ToPhysicalAlignment(const ScrollIntoViewOptions& options,
if (alignment == "nearest")
return ScrollAlignment::kAlignToEdgeIfNeeded;
if (alignment == "start") {
return (axis == kHorizontalScroll) ? ScrollAlignment::kAlignLeftAlways
: ScrollAlignment::kAlignTopAlways;
return (axis == kHorizontalScroll)
? is_flipped_blocks_mode ? ScrollAlignment::kAlignRightAlways
: ScrollAlignment::kAlignLeftAlways
: ScrollAlignment::kAlignTopAlways;
}
if (alignment == "end") {
return (axis == kHorizontalScroll) ? ScrollAlignment::kAlignRightAlways
: ScrollAlignment::kAlignBottomAlways;
return (axis == kHorizontalScroll)
? is_flipped_blocks_mode ? ScrollAlignment::kAlignLeftAlways
: ScrollAlignment::kAlignRightAlways
: ScrollAlignment::kAlignBottomAlways;
}
// Default values
......@@ -527,7 +532,11 @@ static ScrollAlignment ToPhysicalAlignment(const ScrollIntoViewOptions& options,
void Element::scrollIntoViewWithOptions(const ScrollIntoViewOptions& options) {
GetDocument().EnsurePaintLocationDataValidForNode(this);
ScrollIntoViewNoVisualUpdate(options);
}
void Element::ScrollIntoViewNoVisualUpdate(
const ScrollIntoViewOptions& options) {
if (!GetLayoutObject() || !GetDocument().GetPage())
return;
......@@ -543,10 +552,14 @@ void Element::scrollIntoViewWithOptions(const ScrollIntoViewOptions& options) {
bool is_horizontal_writing_mode =
GetComputedStyle()->IsHorizontalWritingMode();
ScrollAlignment align_x = ToPhysicalAlignment(options, kHorizontalScroll,
is_horizontal_writing_mode);
bool is_flipped_blocks_mode =
GetComputedStyle()->IsFlippedBlocksWritingMode();
ScrollAlignment align_x =
ToPhysicalAlignment(options, kHorizontalScroll,
is_horizontal_writing_mode, is_flipped_blocks_mode);
ScrollAlignment align_y =
ToPhysicalAlignment(options, kVerticalScroll, is_horizontal_writing_mode);
ToPhysicalAlignment(options, kVerticalScroll, is_horizontal_writing_mode,
is_flipped_blocks_mode);
LayoutRect bounds = BoundingBoxForScrollIntoView();
GetLayoutObject()->ScrollRectToVisible(
......
......@@ -256,6 +256,7 @@ class CORE_EXPORT Element : public ContainerNode {
void scrollIntoView(ScrollIntoViewOptionsOrBoolean);
void scrollIntoView(bool align_to_top = true);
void scrollIntoViewWithOptions(const ScrollIntoViewOptions&);
void ScrollIntoViewNoVisualUpdate(const ScrollIntoViewOptions&);
void scrollIntoViewIfNeeded(bool center_if_needed = true);
int OffsetLeft();
......
......@@ -58,6 +58,7 @@
#include "third_party/blink/renderer/core/frame/remote_frame.h"
#include "third_party/blink/renderer/core/frame/remote_frame_view.h"
#include "third_party/blink/renderer/core/frame/root_frame_viewport.h"
#include "third_party/blink/renderer/core/frame/scroll_into_view_options.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/frame/visual_viewport.h"
#include "third_party/blink/renderer/core/fullscreen/fullscreen.h"
......@@ -2126,11 +2127,15 @@ void LocalFrameView::ScrollAndFocusFragmentAnchor() {
->SetSafeToPropagateScrollToParent(false);
}
// Scroll nested layers and frames to reveal the anchor.
// Align to the top and to the closest side (this matches other browsers).
anchor_node->GetLayoutObject()->ScrollRectToVisible(
rect, WebScrollIntoViewParams(ScrollAlignment::kAlignToEdgeIfNeeded,
ScrollAlignment::kAlignTopAlways));
Element* anchor_element = anchor_node->IsElementNode()
? ToElement(anchor_node)
: frame_->GetDocument()->documentElement();
if (anchor_element) {
ScrollIntoViewOptions options;
options.setBlock("start");
options.setInlinePosition("nearest");
anchor_element->ScrollIntoViewNoVisualUpdate(options);
}
if (boundary_frame && boundary_frame->IsLocalFrame()) {
ToLocalFrame(boundary_frame)
......
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