mirror of
https://github.com/servo/servo.git
synced 2025-08-14 09:55:35 +01:00
script: Focus on mousedown instead of mouse click according to spec (#38589)
- Focus on mousedown instead of mouse click according to [spec](https://w3c.github.io/uievents/#handle-native-mouse-down) - Refactor to follow spec closer and make things more clear. - Add some spec link. - Remove some dead spec link. Still some preparation before implementing #38435. Testing: No regression in WebDriver & WPT. But update some outdated test. Fixes: #38588 --------- Signed-off-by: Euclid Ye <euclid.ye@huawei.com>
This commit is contained in:
parent
d2122c8bd8
commit
5d21234872
8 changed files with 69 additions and 31 deletions
|
@ -1546,6 +1546,7 @@ impl Document {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <https://w3c.github.io/uievents/#mouseevent-algorithms>
|
||||||
pub(crate) fn handle_mouse_button_event(
|
pub(crate) fn handle_mouse_button_event(
|
||||||
&self,
|
&self,
|
||||||
event: MouseButtonEvent,
|
event: MouseButtonEvent,
|
||||||
|
@ -1579,15 +1580,6 @@ impl Document {
|
||||||
if el.is_actually_disabled() {
|
if el.is_actually_disabled() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// For a node within a text input UA shadow DOM, delegate the focus target into its shadow host.
|
|
||||||
// TODO: This focus delegation should be done with shadow DOM delegateFocus attribute.
|
|
||||||
let target_el = el.find_focusable_shadow_host_if_necessary();
|
|
||||||
|
|
||||||
self.begin_focus_transaction();
|
|
||||||
// Try to focus `el`. If it's not focusable, focus the document instead.
|
|
||||||
self.request_focus(None, FocusInitiator::Local, can_gc);
|
|
||||||
self.request_focus(target_el.as_deref(), FocusInitiator::Local, can_gc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let dom_event = DomRoot::upcast::<Event>(MouseEvent::for_platform_mouse_event(
|
let dom_event = DomRoot::upcast::<Event>(MouseEvent::for_platform_mouse_event(
|
||||||
|
@ -1599,44 +1591,65 @@ impl Document {
|
||||||
can_gc,
|
can_gc,
|
||||||
));
|
));
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#run-authentic-click-activation-steps
|
|
||||||
let activatable = el.as_maybe_activatable();
|
let activatable = el.as_maybe_activatable();
|
||||||
match event.action {
|
match event.action {
|
||||||
|
// https://w3c.github.io/uievents/#handle-native-mouse-click
|
||||||
MouseButtonAction::Click => {
|
MouseButtonAction::Click => {
|
||||||
el.set_click_in_progress(true);
|
el.set_click_in_progress(true);
|
||||||
dom_event.fire(node.upcast(), can_gc);
|
dom_event.dispatch(node.upcast(), false, can_gc);
|
||||||
el.set_click_in_progress(false);
|
el.set_click_in_progress(false);
|
||||||
|
|
||||||
|
self.maybe_fire_dblclick(node, &hit_test_result, input_event, can_gc);
|
||||||
},
|
},
|
||||||
|
// https://w3c.github.io/uievents/#handle-native-mouse-down
|
||||||
MouseButtonAction::Down => {
|
MouseButtonAction::Down => {
|
||||||
|
// (TODO) Step 6. Maybe send pointerdown event with `dom_event`.
|
||||||
if let Some(a) = activatable {
|
if let Some(a) = activatable {
|
||||||
a.enter_formal_activation_state();
|
a.enter_formal_activation_state();
|
||||||
}
|
}
|
||||||
|
|
||||||
let target = node.upcast();
|
// For a node within a text input UA shadow DOM,
|
||||||
dom_event.fire(target, can_gc);
|
// delegate the focus target into its shadow host.
|
||||||
|
// TODO: This focus delegation should be done
|
||||||
|
// with shadow DOM delegateFocus attribute.
|
||||||
|
let target_el = el.find_focusable_shadow_host_if_necessary();
|
||||||
|
self.begin_focus_transaction();
|
||||||
|
// Try to focus `el`. If it's not focusable, focus the document instead.
|
||||||
|
self.request_focus(None, FocusInitiator::Local, can_gc);
|
||||||
|
self.request_focus(target_el.as_deref(), FocusInitiator::Local, can_gc);
|
||||||
|
|
||||||
|
// Step 7. Let result = dispatch event at target
|
||||||
|
let result = dom_event.dispatch(node.upcast(), false, can_gc);
|
||||||
|
|
||||||
|
// Step 8. If result is true and target is a focusable area
|
||||||
|
// that is click focusable, then Run the focusing steps at target.
|
||||||
|
if result && self.focus_transaction.borrow().is_some() {
|
||||||
|
self.commit_focus_transaction(FocusInitiator::Local, can_gc);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 9. If mbutton is the secondary mouse button, then
|
||||||
|
// Maybe show context menu with native, target.
|
||||||
|
if let (MouseButtonAction::Down, MouseButton::Right) = (event.action, event.button)
|
||||||
|
{
|
||||||
|
self.maybe_show_context_menu(
|
||||||
|
node.upcast(),
|
||||||
|
&hit_test_result,
|
||||||
|
input_event,
|
||||||
|
can_gc,
|
||||||
|
);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
// https://w3c.github.io/uievents/#handle-native-mouse-up
|
||||||
MouseButtonAction::Up => {
|
MouseButtonAction::Up => {
|
||||||
if let Some(a) = activatable {
|
if let Some(a) = activatable {
|
||||||
a.exit_formal_activation_state();
|
a.exit_formal_activation_state();
|
||||||
}
|
}
|
||||||
|
// (TODO) Step 6. Maybe send pointerup event with `dom_event``.
|
||||||
|
|
||||||
let target = node.upcast();
|
// Step 7. dispatch event at target.
|
||||||
dom_event.fire(target, can_gc);
|
dom_event.dispatch(node.upcast(), false, can_gc);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if let MouseButtonAction::Click = event.action {
|
|
||||||
if self.focus_transaction.borrow().is_some() {
|
|
||||||
self.commit_focus_transaction(FocusInitiator::Local, can_gc);
|
|
||||||
}
|
|
||||||
self.maybe_fire_dblclick(node, &hit_test_result, input_event, can_gc);
|
|
||||||
}
|
|
||||||
|
|
||||||
// When the contextmenu event is triggered by right mouse button
|
|
||||||
// the contextmenu event MUST be dispatched after the mousedown event.
|
|
||||||
if let (MouseButtonAction::Down, MouseButton::Right) = (event.action, event.button) {
|
|
||||||
self.maybe_show_context_menu(node.upcast(), &hit_test_result, input_event, can_gc);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://www.w3.org/TR/uievents/#maybe-show-context-menu>
|
/// <https://www.w3.org/TR/uievents/#maybe-show-context-menu>
|
||||||
|
|
|
@ -222,6 +222,7 @@ impl MouseEvent {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a [MouseEvent] triggered by the embedder
|
/// Create a [MouseEvent] triggered by the embedder
|
||||||
|
/// <https://w3c.github.io/uievents/#create-a-cancelable-mouseevent-id>
|
||||||
pub(crate) fn for_platform_mouse_event(
|
pub(crate) fn for_platform_mouse_event(
|
||||||
event: embedder_traits::MouseButtonEvent,
|
event: embedder_traits::MouseButtonEvent,
|
||||||
pressed_mouse_buttons: u16,
|
pressed_mouse_buttons: u16,
|
||||||
|
|
|
@ -1,9 +1,17 @@
|
||||||
[navigate.py]
|
[navigate.py]
|
||||||
expected: TIMEOUT
|
[test_link_from_toplevel_context_with_target[_blank\]]
|
||||||
[test_link_hash]
|
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[test_link_from_toplevel_context_with_target[_blank\]]
|
[test_link_from_nested_context_with_target[]]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[test_link_from_nested_context_with_target[_parent]]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[test_link_from_nested_context_with_target[_self]]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[test_link_from_nested_context_with_target[_top]]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[test_link_from_toplevel_context_with_target[_parent\]]
|
[test_link_from_toplevel_context_with_target[_parent\]]
|
||||||
|
|
|
@ -7,3 +7,9 @@
|
||||||
|
|
||||||
[test_dismiss[prompt-None\]]
|
[test_dismiss[prompt-None\]]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[test_accept[alert-None\]]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[test_dismiss[confirm-False\]]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -10,3 +10,6 @@
|
||||||
|
|
||||||
[test_seen_nodes[https coop\]]
|
[test_seen_nodes[https coop\]]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[test_removed_iframe]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
[navigation.py]
|
[navigation.py]
|
||||||
|
expected: TIMEOUT
|
||||||
[test_pointer]
|
[test_pointer]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
3
tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_modifier_click.py.ini
vendored
Normal file
3
tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_modifier_click.py.ini
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[pointer_modifier_click.py]
|
||||||
|
[test_many_modifiers_click]
|
||||||
|
expected: FAIL
|
|
@ -4,3 +4,6 @@
|
||||||
|
|
||||||
[test_set_to_available_size]
|
[test_set_to_available_size]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[test_negative_x_y]
|
||||||
|
expected: FAIL
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue