Commit 6eea3396 authored by Sahel Sharify's avatar Sahel Sharify Committed by Commit Bot

scrollend/overscroll events targeted at document node bubble to window.

This cl changes scrollend/overscroll events to bubbling when the target node is
document. With this change overscroll/scrollend events' bubbling behavior will
be identical to the bubbling behavior of scroll event and registering an
overscroll/scrollend event listener on window will work. To try the cl locally
use --enable-blink-features=OverscrollCustomization runtime flag.

Bug: 907601
Change-Id: I9a170a5ba3406f82d08e06c8c20e51bc5b001f6c
Reviewed-on: https://chromium-review.googlesource.com/c/1483350Reviewed-by: default avatarDavid Bokan <bokan@chromium.org>
Reviewed-by: default avatarSahel Sharify <sahel@chromium.org>
Commit-Queue: Sahel Sharify <sahel@chromium.org>
Cr-Commit-Position: refs/heads/master@{#635204}
parent 2c3849ca
...@@ -5148,7 +5148,11 @@ void Document::EnqueueScrollEventForNode(Node* target) { ...@@ -5148,7 +5148,11 @@ void Document::EnqueueScrollEventForNode(Node* target) {
} }
void Document::EnqueueScrollEndEventForNode(Node* target) { void Document::EnqueueScrollEndEventForNode(Node* target) {
Event* scroll_end_event = Event::Create(event_type_names::kScrollend); // Mimic bubbling behavior of scroll event for consistency.
Event* scroll_end_event =
target->IsDocumentNode()
? Event::CreateBubble(event_type_names::kScrollend)
: Event::Create(event_type_names::kScrollend);
scroll_end_event->SetTarget(target); scroll_end_event->SetTarget(target);
EnsureScriptedAnimationController().EnqueuePerFrameEvent(scroll_end_event); EnsureScriptedAnimationController().EnqueuePerFrameEvent(scroll_end_event);
} }
...@@ -5156,8 +5160,10 @@ void Document::EnqueueScrollEndEventForNode(Node* target) { ...@@ -5156,8 +5160,10 @@ void Document::EnqueueScrollEndEventForNode(Node* target) {
void Document::EnqueueOverscrollEventForNode(Node* target, void Document::EnqueueOverscrollEventForNode(Node* target,
double delta_x, double delta_x,
double delta_y) { double delta_y) {
Event* overscroll_event = // Mimic bubbling behavior of scroll event for consistency.
OverscrollEvent::Create(event_type_names::kOverscroll, delta_x, delta_y); bool bubbles = target->IsDocumentNode();
Event* overscroll_event = OverscrollEvent::Create(
event_type_names::kOverscroll, bubbles, delta_x, delta_y);
overscroll_event->SetTarget(target); overscroll_event->SetTarget(target);
EnsureScriptedAnimationController().EnqueuePerFrameEvent(overscroll_event); EnsureScriptedAnimationController().EnqueuePerFrameEvent(overscroll_event);
} }
......
...@@ -6,15 +6,17 @@ ...@@ -6,15 +6,17 @@
namespace blink { namespace blink {
OverscrollEvent::OverscrollEvent(const AtomicString& type, OverscrollEvent::OverscrollEvent(const AtomicString& type,
bool bubbles,
double delta_x, double delta_x,
double delta_y) double delta_y)
: Event(type, Bubbles::kNo, Cancelable::kNo), : Event(type, (bubbles ? Bubbles::kYes : Bubbles::kNo), Cancelable::kNo),
delta_x_(delta_x), delta_x_(delta_x),
delta_y_(delta_y) {} delta_y_(delta_y) {}
OverscrollEvent::OverscrollEvent(const AtomicString& type, OverscrollEvent::OverscrollEvent(const AtomicString& type,
bool bubbles,
const OverscrollEventInit* initializer) const OverscrollEventInit* initializer)
: Event(type, Bubbles::kNo, Cancelable::kNo), : Event(type, (bubbles ? Bubbles::kYes : Bubbles::kNo), Cancelable::kNo),
delta_x_(initializer->deltaX()), delta_x_(initializer->deltaX()),
delta_y_(initializer->deltaY()) {} delta_y_(initializer->deltaY()) {}
......
...@@ -15,17 +15,25 @@ class OverscrollEvent final : public Event { ...@@ -15,17 +15,25 @@ class OverscrollEvent final : public Event {
public: public:
static OverscrollEvent* Create(const AtomicString& type, static OverscrollEvent* Create(const AtomicString& type,
bool bubbles,
double delta_x, double delta_x,
double delta_y) { double delta_y) {
return MakeGarbageCollected<OverscrollEvent>(type, delta_x, delta_y); return MakeGarbageCollected<OverscrollEvent>(type, bubbles, delta_x,
delta_y);
} }
static OverscrollEvent* Create(const AtomicString& type, static OverscrollEvent* Create(const AtomicString& type,
bool bubbles,
const OverscrollEventInit* initializer) { const OverscrollEventInit* initializer) {
return MakeGarbageCollected<OverscrollEvent>(type, initializer); return MakeGarbageCollected<OverscrollEvent>(type, bubbles, initializer);
} }
OverscrollEvent(const AtomicString&, double delta_x, double delta_y); OverscrollEvent(const AtomicString&,
OverscrollEvent(const AtomicString&, const OverscrollEventInit*); bool bubbles,
double delta_x,
double delta_y);
OverscrollEvent(const AtomicString&,
bool bubbles,
const OverscrollEventInit*);
double deltaX() const { return delta_x_; } double deltaX() const { return delta_x_; }
double deltaY() const { return delta_y_; } double deltaY() const { return delta_y_; }
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
// TODO(sahel): Add link to w3c. https://crbugs.com/907601 // TODO(sahel): Add link to w3c. https://crbugs.com/907601
[ [
Constructor(DOMString type, optional OverscrollEventInit eventInitDict), Constructor(DOMString type, boolean bubbles, optional OverscrollEventInit eventInitDict),
RuntimeEnabled=OverscrollCustomization RuntimeEnabled=OverscrollCustomization
] interface OverscrollEvent : Event { ] interface OverscrollEvent : Event {
readonly attribute double deltaX; readonly attribute double deltaX;
......
...@@ -42,7 +42,8 @@ var overscrolled_x_delta = 0; ...@@ -42,7 +42,8 @@ var overscrolled_x_delta = 0;
var overscrolled_y_delta = 0; var overscrolled_y_delta = 0;
function onOverscroll(event) { function onOverscroll(event) {
assert_false(event.cancelable); assert_false(event.cancelable);
assert_false(event.bubbles); // overscroll events are bubbled when the target node is document.
assert_true(event.bubbles);
overscrolled_x_delta = event.deltaX; overscrolled_x_delta = event.deltaX;
overscrolled_y_delta = event.deltaY; overscrolled_y_delta = event.deltaY;
} }
......
<!DOCTYPE HTML>
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<script src="../../../resources/gesture-util.js"></script>
<style>
#targetDiv {
width: 200px;
height: 200px;
overflow: scroll;
}
#innerDiv {
width: 400px;
height: 400px;
}
</style>
<body style="margin:0">
<div id="targetDiv">
<div id="innerDiv">
</div>
</div>
</body>
<script>
if (window.internals)
internals.runtimeFlags.overscrollCustomizationEnabled = true;
var target_div = document.getElementById('targetDiv');
var rect = target_div.getBoundingClientRect();
var x = rect.left + rect.width / 2;
var y = rect.top + rect.height / 2;
function scrollUp() {
return smoothScroll(1000, x, y, GestureSourceType.TOUCH_INPUT, "up");
}
var window_received_autoscroll = false;
function onOverscroll(event) {
assert_false(event.cancelable);
// overscroll events targetting document are bubbled to the window.
assert_true(event.bubbles);
window_received_autoscroll = true;
}
window.addEventListener("overscroll", onOverscroll);
promise_test (async (t) => {
// Make sure that no overscroll event is sent to target_div.
target_div.addEventListener("overscroll",
t.unreached_func("target_div got unexpected overscroll event."));
await waitForCompositorCommit();
// Scroll up on target div and wait for the window to get overscroll event.
await scrollUp();
await waitFor(() => { return window_received_autoscroll; },
'Window did not receive overscroll event after scroll up on target.');
}, 'Tests that the window gets overscroll event when no element scrolls.');
</script>
...@@ -44,12 +44,14 @@ var horizontal_scrollend_arrived = false; ...@@ -44,12 +44,14 @@ var horizontal_scrollend_arrived = false;
var vertical_scrollend_arrived = false; var vertical_scrollend_arrived = false;
function onHorizontalScrollEnd(event) { function onHorizontalScrollEnd(event) {
assert_false(event.cancelable); assert_false(event.cancelable);
assert_false(event.bubbles); // scrollend events are bubbled when the target node is document.
assert_true(event.bubbles);
horizontal_scrollend_arrived = true; horizontal_scrollend_arrived = true;
} }
function onVerticalScrollEnd(event) { function onVerticalScrollEnd(event) {
assert_false(event.cancelable); assert_false(event.cancelable);
assert_false(event.bubbles); // scrollend events are bubbled when the target node is document.
assert_true(event.bubbles);
vertical_scrollend_arrived = true; vertical_scrollend_arrived = true;
} }
document.addEventListener("scrollend", onHorizontalScrollEnd); document.addEventListener("scrollend", onHorizontalScrollEnd);
......
<!DOCTYPE HTML>
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<script src="../../../resources/gesture-util.js"></script>
<style>
#targetDiv {
width: 200px;
height: 200px;
overflow: scroll;
}
#innerDiv {
width: 400px;
height: 400px;
}
</style>
<body style="margin:0">
<div id="targetDiv">
<div id="innerDiv">
</div>
</div>
</body>
<script>
if (window.internals)
internals.runtimeFlags.overscrollCustomizationEnabled = true;
var target_div = document.getElementById('targetDiv');
var rect = target_div.getBoundingClientRect();
var x = rect.left + rect.width / 2;
var y = rect.top + rect.height / 2;
function scrollUp() {
return smoothScroll(1000, x, y, GestureSourceType.TOUCH_INPUT, "up",
SPEED_INSTANT);
}
var scrollend_arrived = false;
function onScrollEnd(event) {
assert_false(event.cancelable);
// scrollend events targetting document are bubbled to the window.
assert_true(event.bubbles);
scrollend_arrived = true;
}
window.addEventListener("scrollend", onScrollEnd);
promise_test (async (t) => {
// Make sure that no scrollend event is sent to target_div.
target_div.addEventListener("scrollend",
t.unreached_func("target_div got unexpected scrollend event."));
await waitForCompositorCommit();
// Scroll up on target div and wait for the doc to get scrollend event.
await scrollUp();
await waitFor(() => { return scrollend_arrived; },
'Window did not receive scrollend event after scroll up on target.');
assert_equals(target_div.scrollTop, 0);
}, 'Tests that the window gets scrollend event when no element scrolls.');
</script>
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