forked from LadybirdBrowser/ladybird
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
LibWeb: Correctly implement event listeners default passive attribute
This commit implements the default value of the passive attribute of event listeners according to the spec.
- Loading branch information
Showing
6 changed files
with
81 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
/* | ||
* Copyright (c) 2022, Andreas Kling <[email protected]> | ||
* Copyright (c) 2024, Glenn Skrzypczak <[email protected]> | ||
* | ||
* SPDX-License-Identifier: BSD-2-Clause | ||
*/ | ||
|
@@ -35,8 +36,8 @@ class DOMEventListener : public JS::Cell { | |
// capture (a boolean, initially false) | ||
bool capture { false }; | ||
|
||
// passive (a boolean, initially false) | ||
bool passive { false }; | ||
// passive (null or a boolean, initially null) | ||
Optional<bool> passive; | ||
|
||
// once (a boolean, initially false) | ||
bool once { false }; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
/* | ||
* Copyright (c) 2020-2022, Andreas Kling <[email protected]> | ||
* Copyright (c) 2024, Glenn Skrzypczak <[email protected]> | ||
* | ||
* SPDX-License-Identifier: BSD-2-Clause | ||
*/ | ||
|
@@ -81,7 +82,7 @@ bool EventDispatcher::inner_invoke(Event& event, Vector<GC::Root<DOM::DOMEventLi | |
} | ||
|
||
// 9. If listener’s passive is true, then set event’s in passive listener flag. | ||
if (listener->passive) | ||
if (listener->passive == true) | ||
event.set_in_passive_listener(true); | ||
|
||
// FIXME: 10. If global is a Window object, then record timing info for event listener given event and listener. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
/* | ||
* Copyright (c) 2020-2022, Andreas Kling <[email protected]> | ||
* Copyright (c) 2022, Luke Wilde <[email protected]> | ||
* Copyright (c) 2024, Glenn Skrzypczak <[email protected]> | ||
* | ||
* SPDX-License-Identifier: BSD-2-Clause | ||
*/ | ||
|
@@ -110,7 +111,7 @@ static bool flatten_event_listener_options(Variant<AddEventListenerOptions, bool | |
|
||
struct FlattenedAddEventListenerOptions { | ||
bool capture { false }; | ||
bool passive { false }; | ||
Optional<bool> passive { false }; | ||
bool once { false }; | ||
GC::Ptr<AbortSignal> signal; | ||
}; | ||
|
@@ -121,21 +122,24 @@ static FlattenedAddEventListenerOptions flatten_add_event_listener_options(Varia | |
// 1. Let capture be the result of flattening options. | ||
bool capture = flatten_event_listener_options(options); | ||
|
||
// 2. Let once and passive be false. | ||
// 2. Let once be false. | ||
bool once = false; | ||
bool passive = false; | ||
|
||
// 3. Let signal be null. | ||
// 3. Let passive and signal be null. | ||
Optional<bool> passive; | ||
GC::Ptr<AbortSignal> signal; | ||
|
||
// 4. If options is a dictionary, then: | ||
if (options.has<AddEventListenerOptions>()) { | ||
auto& add_event_listener_options = options.get<AddEventListenerOptions>(); | ||
auto const& add_event_listener_options = options.get<AddEventListenerOptions>(); | ||
|
||
// 1. Set passive to options["passive"] and once to options["once"]. | ||
passive = add_event_listener_options.passive; | ||
// 1. Set once to options["once"]. | ||
once = add_event_listener_options.once; | ||
|
||
// 2. If options["passive"] exists, then set passive to options["passive"]. | ||
if (add_event_listener_options.passive.has_value()) | ||
passive = add_event_listener_options.passive; | ||
|
||
// 2. If options["signal"] exists, then set signal to options["signal"]. | ||
if (add_event_listener_options.signal) | ||
signal = add_event_listener_options.signal; | ||
|
@@ -145,6 +149,28 @@ static FlattenedAddEventListenerOptions flatten_add_event_listener_options(Varia | |
return FlattenedAddEventListenerOptions { .capture = capture, .passive = passive, .once = once, .signal = signal.ptr() }; | ||
} | ||
|
||
// https://dom.spec.whatwg.org/#default-passive-value | ||
static bool default_passive_value(FlyString const& type, EventTarget* event_target) | ||
{ | ||
// 1. Return true if all of the following are true: | ||
// - type is one of "touchstart", "touchmove", "wheel", or "mousewheel". | ||
// - eventTarget is a Window object, or is a node whose node document is eventTarget, or is a node whose node document’s document element is eventTarget, | ||
// or is a node whose node document’s body element is eventTarget. | ||
if (type == "touchstart" || type == "touchmove" || type == "wheel" || type == "mousewheel") { | ||
if (is<HTML::Window>(event_target)) | ||
return true; | ||
|
||
if (is<Node>(event_target)) { | ||
auto* node = verify_cast<Node>(event_target); | ||
if (&node->document() == event_target || node->document().document_element() == event_target || node->document().body() == event_target) | ||
return true; | ||
} | ||
} | ||
|
||
// 2. Return false. | ||
return false; | ||
} | ||
|
||
// https://dom.spec.whatwg.org/#dom-eventtarget-addeventlistener | ||
void EventTarget::add_event_listener(FlyString const& type, IDLEventListener* callback, Variant<AddEventListenerOptions, bool> const& options) | ||
{ | ||
|
@@ -186,7 +212,12 @@ void EventTarget::add_an_event_listener(DOMEventListener& listener) | |
if (!listener.callback) | ||
return; | ||
|
||
// 4. If eventTarget’s event listener list does not contain an event listener whose type is listener’s type, callback is listener’s callback, | ||
// 4. If listener’s passive is null, then set it to the default passive value given listener’s type and eventTarget. | ||
if (!listener.passive.has_value()) { | ||
listener.passive = default_passive_value(listener.type, this); | ||
} | ||
|
||
// 5. If eventTarget’s event listener list does not contain an event listener whose type is listener’s type, callback is listener’s callback, | ||
// and capture is listener’s capture, then append listener to eventTarget’s event listener list. | ||
auto it = event_listener_list.find_if([&](auto& entry) { | ||
return entry->type == listener.type | ||
|
@@ -196,7 +227,7 @@ void EventTarget::add_an_event_listener(DOMEventListener& listener) | |
if (it == event_listener_list.end()) | ||
event_listener_list.append(listener); | ||
|
||
// 5. If listener’s signal is not null, then add the following abort steps to it: | ||
// 6. If listener’s signal is not null, then add the following abort steps to it: | ||
if (listener.signal) { | ||
// NOTE: `this` and `listener` are protected by AbortSignal using GC::HeapFunction. | ||
listener.signal->add_abort_algorithm([this, &listener] { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
/* | ||
* Copyright (c) 2020-2022, Andreas Kling <[email protected]> | ||
* Copyright (c) 2024, Glenn Skrzypczak <[email protected]> | ||
* | ||
* SPDX-License-Identifier: BSD-2-Clause | ||
*/ | ||
|
@@ -19,7 +20,7 @@ struct EventListenerOptions { | |
}; | ||
|
||
struct AddEventListenerOptions : public EventListenerOptions { | ||
bool passive { false }; | ||
Optional<bool> passive; | ||
bool once { false }; | ||
GC::Ptr<AbortSignal> signal; | ||
}; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters