Commit d679a163 authored by Daniel Libby's avatar Daniel Libby Committed by Commit Bot

Add main thread percentage scrolling for keyboard and scrollbar

Keyboard arrow scrolling and scrollbar button scrolling should also
scroll a percentage of the scrollable area when percent based scrolling
is enabled.

This CL adds plumbing from the base::Feature to blink, and uses 1/8th as
the percentage to use for directional scrolls via keyboard arrows or
scrollbar buttons. Adds a test suite that runs scrollbar tests in
percentage mode. Keyboard is currently handled on the main thread so we
just use the runtimeFlag toggling via javascript and eventSender.

Bug: 1008153
Change-Id: I7ea7c5471298187da757cf22748620c4accaf192
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2057501
Commit-Queue: Daniel Libby <dlibby@microsoft.com>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Reviewed-by: default avatarDavid Bokan <bokan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#743455}
parent 6e1f28e0
...@@ -14,6 +14,10 @@ ...@@ -14,6 +14,10 @@
static constexpr int kPixelsPerLineStep = 40; static constexpr int kPixelsPerLineStep = 40;
static constexpr float kMinFractionToStepWhenPaging = 0.875f; static constexpr float kMinFractionToStepWhenPaging = 0.875f;
// Each directional scroll for percentage-based units should scroll 1/8th of
// the scrollable area.
static constexpr float kPercentDeltaForDirectionalScroll = 0.125f;
// Autoscrolling (on the main thread) happens by applying a delta every 50ms. // Autoscrolling (on the main thread) happens by applying a delta every 50ms.
// Hence, pixels per second for a autoscroll cc animation can be calculated as: // Hence, pixels per second for a autoscroll cc animation can be calculated as:
// autoscroll velocity = delta / 0.05 sec = delta x 20 // autoscroll velocity = delta / 0.05 sec = delta x 20
......
...@@ -305,6 +305,8 @@ void SetRuntimeFeaturesFromChromiumFeatures() { ...@@ -305,6 +305,8 @@ void SetRuntimeFeaturesFromChromiumFeatures() {
features::kBrowserVerifiedUserActivationKeyboard, kEnableOnly}, features::kBrowserVerifiedUserActivationKeyboard, kEnableOnly},
{wf::EnableBrowserVerifiedUserActivationMouse, {wf::EnableBrowserVerifiedUserActivationMouse,
features::kBrowserVerifiedUserActivationMouse, kEnableOnly}, features::kBrowserVerifiedUserActivationMouse, kEnableOnly},
{wf::EnablePercentBasedScrolling, features::kPercentBasedScrolling,
kUseFeatureState},
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
{wf::EnableWebNfc, {wf::EnableWebNfc,
features::kWebNfc, kDisableOnly}, features::kWebNfc, kDisableOnly},
......
...@@ -144,6 +144,7 @@ class WebRuntimeFeatures { ...@@ -144,6 +144,7 @@ class WebRuntimeFeatures {
bool); bool);
BLINK_PLATFORM_EXPORT static void EnablePaymentApp(bool); BLINK_PLATFORM_EXPORT static void EnablePaymentApp(bool);
BLINK_PLATFORM_EXPORT static void EnablePaymentRequest(bool); BLINK_PLATFORM_EXPORT static void EnablePaymentRequest(bool);
BLINK_PLATFORM_EXPORT static void EnablePercentBasedScrolling(bool);
BLINK_PLATFORM_EXPORT static void EnablePerformanceManagerInstrumentation( BLINK_PLATFORM_EXPORT static void EnablePerformanceManagerInstrumentation(
bool); bool);
BLINK_PLATFORM_EXPORT static void EnablePeriodicBackgroundSync(bool); BLINK_PLATFORM_EXPORT static void EnablePeriodicBackgroundSync(bool);
......
...@@ -77,25 +77,37 @@ bool MapKeyCodeForScroll(int key_code, ...@@ -77,25 +77,37 @@ bool MapKeyCodeForScroll(int key_code,
case VKEY_LEFT: case VKEY_LEFT:
*scroll_direction = *scroll_direction =
mojom::blink::ScrollDirection::kScrollLeftIgnoringWritingMode; mojom::blink::ScrollDirection::kScrollLeftIgnoringWritingMode;
*scroll_granularity = ScrollGranularity::kScrollByLine; *scroll_granularity =
RuntimeEnabledFeatures::PercentBasedScrollingEnabled()
? ScrollGranularity::kScrollByPercentage
: ScrollGranularity::kScrollByLine;
*scroll_use_uma = WebFeature::kScrollByKeyboardArrowKeys; *scroll_use_uma = WebFeature::kScrollByKeyboardArrowKeys;
break; break;
case VKEY_RIGHT: case VKEY_RIGHT:
*scroll_direction = *scroll_direction =
mojom::blink::ScrollDirection::kScrollRightIgnoringWritingMode; mojom::blink::ScrollDirection::kScrollRightIgnoringWritingMode;
*scroll_granularity = ScrollGranularity::kScrollByLine; *scroll_granularity =
RuntimeEnabledFeatures::PercentBasedScrollingEnabled()
? ScrollGranularity::kScrollByPercentage
: ScrollGranularity::kScrollByLine;
*scroll_use_uma = WebFeature::kScrollByKeyboardArrowKeys; *scroll_use_uma = WebFeature::kScrollByKeyboardArrowKeys;
break; break;
case VKEY_UP: case VKEY_UP:
*scroll_direction = *scroll_direction =
mojom::blink::ScrollDirection::kScrollUpIgnoringWritingMode; mojom::blink::ScrollDirection::kScrollUpIgnoringWritingMode;
*scroll_granularity = ScrollGranularity::kScrollByLine; *scroll_granularity =
RuntimeEnabledFeatures::PercentBasedScrollingEnabled()
? ScrollGranularity::kScrollByPercentage
: ScrollGranularity::kScrollByLine;
*scroll_use_uma = WebFeature::kScrollByKeyboardArrowKeys; *scroll_use_uma = WebFeature::kScrollByKeyboardArrowKeys;
break; break;
case VKEY_DOWN: case VKEY_DOWN:
*scroll_direction = *scroll_direction =
mojom::blink::ScrollDirection::kScrollDownIgnoringWritingMode; mojom::blink::ScrollDirection::kScrollDownIgnoringWritingMode;
*scroll_granularity = ScrollGranularity::kScrollByLine; *scroll_granularity =
RuntimeEnabledFeatures::PercentBasedScrollingEnabled()
? ScrollGranularity::kScrollByPercentage
: ScrollGranularity::kScrollByLine;
*scroll_use_uma = WebFeature::kScrollByKeyboardArrowKeys; *scroll_use_uma = WebFeature::kScrollByKeyboardArrowKeys;
break; break;
case VKEY_HOME: case VKEY_HOME:
......
...@@ -279,15 +279,20 @@ bool ScrollManager::LogicalScroll(mojom::blink::ScrollDirection direction, ...@@ -279,15 +279,20 @@ bool ScrollManager::LogicalScroll(mojom::blink::ScrollDirection direction,
ScrollableArea* scrollable_area = ScrollableArea::GetForScrolling(box); ScrollableArea* scrollable_area = ScrollableArea::GetForScrolling(box);
DCHECK(scrollable_area); DCHECK(scrollable_area);
ScrollOffset delta = ToScrollDelta(physical_direction, 1); ScrollOffset delta =
ToScrollDelta(physical_direction,
ScrollableArea::DirectionBasedScrollDelta(granularity));
delta.Scale(scrollable_area->ScrollStep(granularity, kHorizontalScrollbar), delta.Scale(scrollable_area->ScrollStep(granularity, kHorizontalScrollbar),
scrollable_area->ScrollStep(granularity, kVerticalScrollbar)); scrollable_area->ScrollStep(granularity, kVerticalScrollbar));
// Pressing the arrow key is considered as a scroll with intended direction // Pressing the arrow key is considered as a scroll with intended direction
// only. Pressing the PgUp/PgDn key is considered as a scroll with intended // only (this results in kScrollByLine or kScrollByPercentage, depending on
// direction and end position. Pressing the Home/End key is considered as a // REF::PercentBasedScrollingEnabled). Pressing the PgUp/PgDn key is
// scroll with intended end position only. // considered as a scroll with intended direction and end position. Pressing
// the Home/End key is considered as a scroll with intended end position
// only.
switch (granularity) { switch (granularity) {
case ScrollGranularity::kScrollByLine: { case ScrollGranularity::kScrollByLine:
case ScrollGranularity::kScrollByPercentage: {
if (scrollable_area->SnapForDirection(delta)) if (scrollable_area->SnapForDirection(delta))
return true; return true;
break; break;
...@@ -319,7 +324,10 @@ bool ScrollManager::LogicalScroll(mojom::blink::ScrollDirection direction, ...@@ -319,7 +324,10 @@ bool ScrollManager::LogicalScroll(mojom::blink::ScrollDirection direction,
}, },
WrapWeakPersistent(scrollable_area))); WrapWeakPersistent(scrollable_area)));
ScrollResult result = scrollable_area->UserScroll( ScrollResult result = scrollable_area->UserScroll(
granularity, ToScrollDelta(physical_direction, 1), std::move(callback)); granularity,
ToScrollDelta(physical_direction,
ScrollableArea::DirectionBasedScrollDelta(granularity)),
std::move(callback));
if (result.DidScroll()) if (result.DidScroll())
return true; return true;
......
...@@ -70,6 +70,13 @@ int ScrollableArea::MaxOverlapBetweenPages() const { ...@@ -70,6 +70,13 @@ int ScrollableArea::MaxOverlapBetweenPages() const {
return GetPageScrollbarTheme().MaxOverlapBetweenPages(); return GetPageScrollbarTheme().MaxOverlapBetweenPages();
} }
// static
float ScrollableArea::DirectionBasedScrollDelta(ScrollGranularity granularity) {
return (granularity == ScrollGranularity::kScrollByPercentage)
? kPercentDeltaForDirectionalScroll
: 1;
}
// static // static
mojom::blink::ScrollBehavior ScrollableArea::DetermineScrollBehavior( mojom::blink::ScrollBehavior ScrollableArea::DetermineScrollBehavior(
mojom::blink::ScrollBehavior behavior_from_param, mojom::blink::ScrollBehavior behavior_from_param,
......
...@@ -84,6 +84,10 @@ class CORE_EXPORT ScrollableArea : public GarbageCollectedMixin { ...@@ -84,6 +84,10 @@ class CORE_EXPORT ScrollableArea : public GarbageCollectedMixin {
static float MinFractionToStepWhenPaging(); static float MinFractionToStepWhenPaging();
int MaxOverlapBetweenPages() const; int MaxOverlapBetweenPages() const;
// Returns the amount of delta, in |granularity| units, for a direction-based
// (i.e. keyboard or scrollbar arrow) scroll.
static float DirectionBasedScrollDelta(ScrollGranularity granularity);
// Convert a non-finite scroll value (Infinity, -Infinity, NaN) to 0 as // Convert a non-finite scroll value (Infinity, -Infinity, NaN) to 0 as
// per https://drafts.csswg.org/cssom-view/#normalize-non-finite-values. // per https://drafts.csswg.org/cssom-view/#normalize-non-finite-values.
static float NormalizeNonFiniteScroll(float value) { static float NormalizeNonFiniteScroll(float value) {
......
...@@ -265,8 +265,11 @@ ScrollGranularity Scrollbar::PressedPartScrollGranularity() { ...@@ -265,8 +265,11 @@ ScrollGranularity Scrollbar::PressedPartScrollGranularity() {
if (pressed_part_ == kBackButtonStartPart || if (pressed_part_ == kBackButtonStartPart ||
pressed_part_ == kBackButtonEndPart || pressed_part_ == kBackButtonEndPart ||
pressed_part_ == kForwardButtonStartPart || pressed_part_ == kForwardButtonStartPart ||
pressed_part_ == kForwardButtonEndPart) pressed_part_ == kForwardButtonEndPart) {
return ScrollGranularity::kScrollByLine; return RuntimeEnabledFeatures::PercentBasedScrollingEnabled()
? ScrollGranularity::kScrollByPercentage
: ScrollGranularity::kScrollByLine;
}
return ScrollGranularity::kScrollByPage; return ScrollGranularity::kScrollByPage;
} }
...@@ -596,8 +599,10 @@ void Scrollbar::MouseDown(const WebMouseEvent& evt) { ...@@ -596,8 +599,10 @@ void Scrollbar::MouseDown(const WebMouseEvent& evt) {
void Scrollbar::InjectScrollGestureForPressedPart( void Scrollbar::InjectScrollGestureForPressedPart(
WebInputEvent::Type gesture_type) { WebInputEvent::Type gesture_type) {
ScrollOffset delta = ToScrollDelta(PressedPartScrollDirectionPhysical(), 1);
ScrollGranularity granularity = PressedPartScrollGranularity(); ScrollGranularity granularity = PressedPartScrollGranularity();
ScrollOffset delta =
ToScrollDelta(PressedPartScrollDirectionPhysical(),
ScrollableArea::DirectionBasedScrollDelta(granularity));
InjectScrollGesture(gesture_type, delta, granularity); InjectScrollGesture(gesture_type, delta, granularity);
} }
......
...@@ -344,6 +344,10 @@ void WebRuntimeFeatures::EnablePaymentRequest(bool enable) { ...@@ -344,6 +344,10 @@ void WebRuntimeFeatures::EnablePaymentRequest(bool enable) {
} }
} }
void WebRuntimeFeatures::EnablePercentBasedScrolling(bool enable) {
RuntimeEnabledFeatures::SetPercentBasedScrollingEnabled(enable);
}
void WebRuntimeFeatures::EnablePerformanceManagerInstrumentation(bool enable) { void WebRuntimeFeatures::EnablePerformanceManagerInstrumentation(bool enable) {
RuntimeEnabledFeatures::SetPerformanceManagerInstrumentationEnabled(enable); RuntimeEnabledFeatures::SetPerformanceManagerInstrumentationEnabled(enable);
} }
......
...@@ -1316,6 +1316,10 @@ ...@@ -1316,6 +1316,10 @@
name: "PaymentRetry", name: "PaymentRetry",
status: "stable", status: "stable",
}, },
{
name: "PercentBasedScrolling",
settable_from_internals: true,
},
{ {
name: "PerformanceManagerInstrumentation", name: "PerformanceManagerInstrumentation",
}, },
......
...@@ -97,6 +97,8 @@ crbug.com/1012590 [ Linux ] fast/overflow/rtl-scrollbar-drag-origin.html [ Skip ...@@ -97,6 +97,8 @@ crbug.com/1012590 [ Linux ] fast/overflow/rtl-scrollbar-drag-origin.html [ Skip
[ Mac ] virtual/scroll_customization/fast/scrolling/scrollbars/scrollbar-thumb-snapping.html [ Skip ] [ Mac ] virtual/scroll_customization/fast/scrolling/scrollbars/scrollbar-thumb-snapping.html [ Skip ]
[ Linux ] virtual/threaded-prefer-compositing/fast/scrolling/scrollbars/scrollbar-thumb-snapping.html [ Skip ] [ Linux ] virtual/threaded-prefer-compositing/fast/scrolling/scrollbars/scrollbar-thumb-snapping.html [ Skip ]
[ Mac ] virtual/threaded-prefer-compositing/fast/scrolling/scrollbars/scrollbar-thumb-snapping.html [ Skip ] [ Mac ] virtual/threaded-prefer-compositing/fast/scrolling/scrollbars/scrollbar-thumb-snapping.html [ Skip ]
[ Linux ] virtual/percent-based-scrolling/fast/scrolling/scrollbars/scrollbar-thumb-snapping.html [ Skip ]
[ Mac ] virtual/percent-based-scrolling/fast/scrolling/scrollbars/scrollbar-thumb-snapping.html [ Skip ]
# These tests are specific to Linux. # These tests are specific to Linux.
......
...@@ -298,6 +298,13 @@ ...@@ -298,6 +298,13 @@
"--enable-prefer-compositing-to-lcd-text", "--enable-prefer-compositing-to-lcd-text",
"--disable-smooth-scrolling"] "--disable-smooth-scrolling"]
}, },
{
"prefix": "percent-based-scrolling",
"bases": ["fast/scrolling/scrollbars"],
"args": ["--enable-features=PercentBasedScrolling",
"--enable-threaded-compositing",
"--enable-prefer-compositing-to-lcd-text"]
},
{ {
"prefix": "smooth_compositor_threaded_scrollbar_scrolling", "prefix": "smooth_compositor_threaded_scrollbar_scrolling",
"bases": ["fast/scrolling/scrollbars/scroll-chaining-for-gesture-based-scrolling.html"], "bases": ["fast/scrolling/scrollbars/scroll-chaining-for-gesture-based-scrolling.html"],
......
<!DOCTYPE html>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="../../resources/run-after-layout-and-paint.js"></script>
<div id="scroller" tabindex=1 style="width: 5px; height: 5px; overflow: scroll;">
<div style="width: 1000px; height:1000px;"></div>
</div>
<script>
"use strict";
function runTest() {
if (window.eventSender && window.internals) {
internals.settings.setScrollAnimatorEnabled(false);
internals.settings.setHideScrollbars(true);
internals.runtimeFlags.msExperimentalScrollingEnabled = true;
test(() => {
const scroller = document.getElementById("scroller");
scroller.focus();
assert_equals(document.activeElement.id, "scroller");
eventSender.keyDown("ArrowDown");
eventSender.keyDown("ArrowRight");
assert_greater_than(scroller.scrollTop, 0);
assert_greater_than(scroller.scrollLeft, 0);
}, "Ensure percent-based keyboard scroll can always scroll, even on small scrollers.");
}
}
addEventListener('load', runTest);
</script>
<!DOCTYPE html>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="../../resources/run-after-layout-and-paint.js"></script>
<div id="outerScroller" style="width: 400px; height: 400px; overflow: scroll;">
<!-- Set tabindex so the scroller is focusable even if layout hasn't yet run -->
<div id="innerScroller" tabindex=1 style="width: 200px; height: 200px; overflow: scroll;">
<div style="width: 1000px; height:1000px;"></div>
</div>
<div style="width: 1000px; height:1000px;"></div>
</div>
<script>
"use strict";
function runTest() {
if (window.eventSender && window.internals) {
internals.settings.setScrollAnimatorEnabled(false);
internals.settings.setHideScrollbars(true);
internals.runtimeFlags.percentBasedScrollingEnabled = true;
test(() => {
const scrollStepsPerViewport = 8;
const innerScroller = document.getElementById("innerScroller");
const outerScroller = document.getElementById("outerScroller");
innerScroller.focus();
assert_equals(document.activeElement.id, "innerScroller");
eventSender.keyDown("ArrowDown");
eventSender.keyDown("ArrowRight");
outerScroller.focus();
assert_equals(document.activeElement.id, "outerScroller");
eventSender.keyDown("ArrowDown");
eventSender.keyDown("ArrowRight");
assert_equals(innerScroller.scrollTop, innerScroller.clientHeight / scrollStepsPerViewport);
assert_equals(innerScroller.scrollLeft, innerScroller.clientWidth / scrollStepsPerViewport);
assert_equals(outerScroller.scrollTop, outerScroller.clientHeight / scrollStepsPerViewport);
assert_equals(outerScroller.scrollLeft, outerScroller.clientWidth / scrollStepsPerViewport);
}, "Scrolls a percentage of the viewport when using the keyboard arrow keys to scroll.");
}
}
addEventListener('load', runTest);
</script>
...@@ -91,7 +91,11 @@ window.onload = () => { ...@@ -91,7 +91,11 @@ window.onload = () => {
// Click on the Down arrow for standardRectFast. // Click on the Down arrow for standardRectFast.
await mouseClickOn(SCROLLBAR_BUTTON_FWD.x, SCROLLBAR_BUTTON_FWD.y); await mouseClickOn(SCROLLBAR_BUTTON_FWD.x, SCROLLBAR_BUTTON_FWD.y);
await waitForAnimationEndTimeBased(() => {return standardDivFast.scrollTop;}); await waitForAnimationEndTimeBased(() => {return standardDivFast.scrollTop;});
assert_equals(standardDivFast.scrollTop, 40, "Pressing the down arrow didn't scroll.");
const EXPECTED_SCROLL = (internals.runtimeFlags.percentBasedScrollingEnabled) ?
Math.floor(standardDivFast.clientHeight * SCROLLBAR_SCROLL_PERCENTAGE) : SCROLLBAR_SCROLL_PIXELS;
assert_equals(standardDivFast.scrollTop, EXPECTED_SCROLL, "Pressing the down arrow didn't scroll.");
}, "Test mouse click on non-custom composited div scrollbar arrows."); }, "Test mouse click on non-custom composited div scrollbar arrows.");
promise_test (async () => { promise_test (async () => {
......
...@@ -42,7 +42,9 @@ ...@@ -42,7 +42,9 @@
const TRACK_WIDTH = calculateScrollbarThickness(); const TRACK_WIDTH = calculateScrollbarThickness();
const BUTTON_WIDTH = TRACK_WIDTH; const BUTTON_WIDTH = TRACK_WIDTH;
const SCROLL_CORNER = TRACK_WIDTH; const SCROLL_CORNER = TRACK_WIDTH;
const SCROLL_DELTA = 400; const SCROLL_DELTA = (internals.runtimeFlags.percentBasedScrollingEnabled) ?
Math.floor(scroller.clientHeight * SCROLLBAR_SCROLL_PERCENTAGE) * 10 :
SCROLLBAR_SCROLL_PIXELS * 10;
const MAX_SCROLLER_OFFSET = 1915; const MAX_SCROLLER_OFFSET = 1915;
promise_test (async () => { promise_test (async () => {
......
...@@ -38,6 +38,11 @@ window.onload = () => { ...@@ -38,6 +38,11 @@ window.onload = () => {
const TRACK_WIDTH = calculateScrollbarThickness(); const TRACK_WIDTH = calculateScrollbarThickness();
const BUTTON_WIDTH = TRACK_WIDTH; const BUTTON_WIDTH = TRACK_WIDTH;
const SCROLL_CORNER = TRACK_WIDTH; const SCROLL_CORNER = TRACK_WIDTH;
assert_equals(standardDivFast.clientHeight, standardDivFast.clientWidth,
"This test assumes that the height and width of 'standardDivFast' are equivalent. If this changes please update SCROLL_AMOUNT to be X/Y specific");
const SCROLL_AMOUNT = internals.runtimeFlags.percentBasedScrollingEnabled ?
Math.floor(standardDivFast.clientHeight * SCROLLBAR_SCROLL_PERCENTAGE) :
SCROLLBAR_SCROLL_PIXELS;
promise_test (async () => { promise_test (async () => {
// Scrollbars on Mac don't have arrows. This test is irrelevant. // Scrollbars on Mac don't have arrows. This test is irrelevant.
...@@ -52,7 +57,7 @@ window.onload = () => { ...@@ -52,7 +57,7 @@ window.onload = () => {
let y = standardRectFast.bottom - SCROLL_CORNER - BUTTON_WIDTH / 2; let y = standardRectFast.bottom - SCROLL_CORNER - BUTTON_WIDTH / 2;
await mouseClickOn(x, y); await mouseClickOn(x, y);
await waitForAnimationEndTimeBased(() => {return standardDivFast.scrollTop;}); await waitForAnimationEndTimeBased(() => {return standardDivFast.scrollTop;});
assert_equals(standardDivFast.scrollTop, 40, "Pressing the down arrow didn't scroll."); assert_equals(standardDivFast.scrollTop, SCROLL_AMOUNT, "Pressing the down arrow didn't scroll.");
// Click on the Up arrow for standardRectFast. // Click on the Up arrow for standardRectFast.
x = standardRectFast.right - BUTTON_WIDTH / 2; x = standardRectFast.right - BUTTON_WIDTH / 2;
...@@ -66,7 +71,7 @@ window.onload = () => { ...@@ -66,7 +71,7 @@ window.onload = () => {
y = standardRectFast.bottom - BUTTON_WIDTH / 2; y = standardRectFast.bottom - BUTTON_WIDTH / 2;
await mouseClickOn(x, y); await mouseClickOn(x, y);
await waitForAnimationEndTimeBased(() => {return standardDivFast.scrollLeft;}); await waitForAnimationEndTimeBased(() => {return standardDivFast.scrollLeft;});
assert_equals(standardDivFast.scrollLeft, 40, "Pressing the right arrow didn't scroll."); assert_equals(standardDivFast.scrollLeft, SCROLL_AMOUNT, "Pressing the right arrow didn't scroll.");
// Click on the Left arrow for standardRectFast. // Click on the Left arrow for standardRectFast.
x = standardRectFast.left + BUTTON_WIDTH / 2; x = standardRectFast.left + BUTTON_WIDTH / 2;
......
...@@ -13,6 +13,10 @@ window.onload = () => { ...@@ -13,6 +13,10 @@ window.onload = () => {
const TRACK_WIDTH = calculateScrollbarThickness(); const TRACK_WIDTH = calculateScrollbarThickness();
const BUTTON_WIDTH = TRACK_WIDTH; const BUTTON_WIDTH = TRACK_WIDTH;
const SCROLL_CORNER = TRACK_WIDTH; const SCROLL_CORNER = TRACK_WIDTH;
const SCROLL_AMOUNT_Y = internals.runtimeFlags.percentBasedScrollingEnabled ?
Math.floor(document.scrollingElement.clientHeight * SCROLLBAR_SCROLL_PERCENTAGE) : SCROLLBAR_SCROLL_PIXELS;
const SCROLL_AMOUNT_X = internals.runtimeFlags.percentBasedScrollingEnabled ?
Math.floor(document.scrollingElement.clientWidth * SCROLLBAR_SCROLL_PERCENTAGE) : SCROLLBAR_SCROLL_PIXELS;
promise_test (async (test) => { promise_test (async (test) => {
// Scrollbars on Mac don't have arrows. This test is irrelevant. // Scrollbars on Mac don't have arrows. This test is irrelevant.
...@@ -27,7 +31,7 @@ window.onload = () => { ...@@ -27,7 +31,7 @@ window.onload = () => {
let y = window.innerHeight - SCROLL_CORNER - BUTTON_WIDTH / 2; let y = window.innerHeight - SCROLL_CORNER - BUTTON_WIDTH / 2;
await mouseClickOn(x, y); await mouseClickOn(x, y);
await waitForAnimationEndTimeBased(() => {return window.scrollY;}); await waitForAnimationEndTimeBased(() => {return window.scrollY;});
assert_equals(window.scrollY, 40, "Pressing the down arrow didn't scroll."); assert_equals(window.scrollY, SCROLL_AMOUNT_Y, "Pressing the down arrow didn't scroll.");
// Click on the Up arrow of the viewport. // Click on the Up arrow of the viewport.
x = window.innerWidth - BUTTON_WIDTH / 2; x = window.innerWidth - BUTTON_WIDTH / 2;
...@@ -41,7 +45,7 @@ window.onload = () => { ...@@ -41,7 +45,7 @@ window.onload = () => {
y = window.innerHeight - BUTTON_WIDTH / 2; y = window.innerHeight - BUTTON_WIDTH / 2;
await mouseClickOn(x, y); await mouseClickOn(x, y);
await waitForAnimationEndTimeBased(() => {return window.scrollX;}); await waitForAnimationEndTimeBased(() => {return window.scrollX;});
assert_equals(window.scrollX, 40, "Pressing the right arrow didn't scroll."); assert_equals(window.scrollX, SCROLL_AMOUNT_X, "Pressing the right arrow didn't scroll.");
// Click on the Left arrow of the viewport. // Click on the Left arrow of the viewport.
x = BUTTON_WIDTH / 2; x = BUTTON_WIDTH / 2;
......
...@@ -81,4 +81,4 @@ ...@@ -81,4 +81,4 @@
}, 'Drag a scrollbar and release it on another DIV, only the DIV owns the' + }, 'Drag a scrollbar and release it on another DIV, only the DIV owns the' +
' dragging scrollbar receive mouse events'); ' dragging scrollbar receive mouse events');
} }
</script> </script>
\ No newline at end of file
...@@ -66,7 +66,9 @@ ...@@ -66,7 +66,9 @@
// Remove the div and verify that scrolling takes place as expected. // Remove the div and verify that scrolling takes place as expected.
document.body.removeChild(occlusion_div); document.body.removeChild(occlusion_div);
await mouseClickOn(down_arrow_x, down_arrow_y); await mouseClickOn(down_arrow_x, down_arrow_y);
const expected = onMacPlatform ? 74 : 40; const EXPECTED_BUTTON_SCROLL_AMOUNT = internals.runtimeFlags.percentBasedScrollingEnabled ?
Math.floor(scroller.clientHeight * SCROLLBAR_SCROLL_PERCENTAGE) : SCROLLBAR_SCROLL_PIXELS;
const expected = onMacPlatform ? 74 : EXPECTED_BUTTON_SCROLL_AMOUNT;
const pressedPart = onMacPlatform ? "track" : "down arrow"; const pressedPart = onMacPlatform ? "track" : "down arrow";
await waitForAnimationEndTimeBased(() => {return scroller.scrollTop;}); await waitForAnimationEndTimeBased(() => {return scroller.scrollTop;});
assert_equals(scroller.scrollTop, expected, "Pressing the " + pressedPart + " didn't scroll."); assert_equals(scroller.scrollTop, expected, "Pressing the " + pressedPart + " didn't scroll.");
......
...@@ -37,4 +37,12 @@ function resetScrollOffset(scrollElement) { ...@@ -37,4 +37,12 @@ function resetScrollOffset(scrollElement) {
} }
} }
// TODO(arakeri): Add helpers for arrow widths. // The percentage scrollbar arrows will scroll, if percent-based scrolling
\ No newline at end of file // is enabled.
const SCROLLBAR_SCROLL_PERCENTAGE = 0.125;
// The number of pixels scrollbar arrows will scroll when percent-based
// scrolling is not enabled.
const SCROLLBAR_SCROLL_PIXELS = 40;
// TODO(arakeri): Add helpers for arrow widths.
This directory is dedicated for testing the "Percent-based scrolling" feature.
This directory is dedicated for testing the "Percent-based scrolling" feature.
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