diff options
author | Pyfisch <pyfisch@gmail.com> | 2018-10-06 17:35:45 +0200 |
---|---|---|
committer | Pyfisch <pyfisch@gmail.com> | 2018-10-07 22:39:00 +0200 |
commit | 0ccaa7e1a9e9bf9472d869576019b9cda350ad87 (patch) | |
tree | 812a25be7dcad507d183b25d683a9ebaec3d493c /components/script/dom/document.rs | |
parent | 76ddbe4d7afd48b83b23f3fd0cff47b214a0a290 (diff) | |
download | servo-0ccaa7e1a9e9bf9472d869576019b9cda350ad87.tar.gz servo-0ccaa7e1a9e9bf9472d869576019b9cda350ad87.zip |
Use keyboard-types crate
Have embedders send DOM keys to servo and use a strongly typed KeyboardEvent
from the W3C UI Events spec. All keyboard handling now uses the new types.
Introduce a ShortcutMatcher to recognize key bindings. Shortcuts are now
recognized in a uniform way.
Updated the winit port.
Updated webdriver integration.
part of #20331
Diffstat (limited to 'components/script/dom/document.rs')
-rw-r--r-- | components/script/dom/document.rs | 105 |
1 files changed, 50 insertions, 55 deletions
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index d68f085af83..72d74b61ae4 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -61,7 +61,7 @@ use dom::htmlimageelement::HTMLImageElement; use dom::htmlmetaelement::HTMLMetaElement; use dom::htmlscriptelement::{HTMLScriptElement, ScriptResult}; use dom::htmltitleelement::HTMLTitleElement; -use dom::keyboardevent::KeyboardEvent; +use dom::keyboardevent::{KeyboardEvent, key_keycode}; use dom::location::Location; use dom::messageevent::MessageEvent; use dom::mouseevent::MouseEvent; @@ -100,9 +100,10 @@ use hyper_serde::Serde; use ipc_channel::ipc::{self, IpcSender}; use js::jsapi::{JSContext, JSObject, JSRuntime}; use js::jsapi::JS_GetRuntime; +use keyboard_types::{Key, KeyState, Modifiers}; use metrics::{InteractiveFlag, InteractiveMetrics, InteractiveWindow, ProfilerMetadataFactory, ProgressiveWebMetric}; use mime::{Mime, TopLevel, SubLevel}; -use msg::constellation_msg::{BrowsingContextId, Key, KeyModifiers, KeyState}; +use msg::constellation_msg::BrowsingContextId; use net_traits::{FetchResponseMsg, IpcSend, ReferrerPolicy}; use net_traits::CookieSource::NonHTTP; use net_traits::CoreResourceMsg::{GetCookiesForUrl, SetCookiesForUrl}; @@ -1350,36 +1351,39 @@ impl Document { /// The entry point for all key processing for web content pub fn dispatch_key_event( &self, - ch: Option<char>, - key: Key, - state: KeyState, - modifiers: KeyModifiers, + keyboard_event: ::keyboard_types::KeyboardEvent, ) { let focused = self.get_focused_element(); let body = self.GetBody(); + let printable = match keyboard_event.key { + Key::Character(_) => true, + _ => false, + }; + let target = match (&focused, &body) { (&Some(ref focused), _) => focused.upcast(), (&None, &Some(ref body)) => body.upcast(), (&None, &None) => self.window.upcast(), }; - let ctrl = modifiers.contains(KeyModifiers::CONTROL); - let alt = modifiers.contains(KeyModifiers::ALT); - let shift = modifiers.contains(KeyModifiers::SHIFT); - let meta = modifiers.contains(KeyModifiers::SUPER); - - let is_composing = false; - let is_repeating = state == KeyState::Repeated; let ev_type = DOMString::from( - match state { - KeyState::Pressed | KeyState::Repeated => "keydown", - KeyState::Released => "keyup", - }.to_owned(), - ); - - let props = KeyboardEvent::key_properties(ch, key, modifiers); - + match keyboard_event.state { + KeyState::Down => "keydown", + KeyState::Up => "keyup", + }.to_owned()); + + let char_code = if let Key::Character(ref c) = keyboard_event.key { + let mut chars = c.chars(); + let n = chars.next().map(|c| c as u32); + if chars.next().is_some() { + None + } else { + n + } + } else { + None + }; let keyevent = KeyboardEvent::new( &self.window, ev_type, @@ -1387,29 +1391,21 @@ impl Document { true, Some(&self.window), 0, - ch, - Some(key), - DOMString::from(props.key_string.clone()), - DOMString::from(props.code), - props.location, - is_repeating, - is_composing, - ctrl, - alt, - shift, - meta, - None, - props.key_code, + keyboard_event.key.clone(), + DOMString::from(keyboard_event.code.to_string()), + keyboard_event.location as u32, + keyboard_event.repeat, + keyboard_event.is_composing, + keyboard_event.modifiers, + char_code, + key_keycode(&keyboard_event.key), ); let event = keyevent.upcast::<Event>(); event.fire(target); let mut cancel_state = event.get_cancel_state(); // https://w3c.github.io/uievents/#keys-cancelable-keys - if state != KeyState::Released && - props.is_printable() && - cancel_state != EventDefault::Prevented - { + if keyboard_event.state != KeyState::Up && printable && cancel_state != EventDefault::Prevented { // https://w3c.github.io/uievents/#keypress-event-order let event = KeyboardEvent::new( &self.window, @@ -1418,18 +1414,13 @@ impl Document { true, Some(&self.window), 0, - ch, - Some(key), - DOMString::from(props.key_string), - DOMString::from(props.code), - props.location, - is_repeating, - is_composing, - ctrl, - alt, - shift, - meta, - props.char_code, + keyboard_event.key.clone(), + DOMString::from(keyboard_event.code.to_string()), + keyboard_event.location as u32, + keyboard_event.repeat, + keyboard_event.is_composing, + keyboard_event.modifiers, + None, 0, ); let ev = event.upcast::<Event>(); @@ -1438,7 +1429,7 @@ impl Document { } if cancel_state == EventDefault::Allowed { - let msg = EmbedderMsg::KeyEvent(ch, key, state, modifiers); + let msg = EmbedderMsg::Keyboard(keyboard_event.clone()); self.send_to_embedder(msg); // This behavior is unspecced @@ -1446,8 +1437,8 @@ impl Document { // however *when* we do it is up to us. // Here, we're dispatching it after the key event so the script has a chance to cancel it // https://www.w3.org/Bugs/Public/show_bug.cgi?id=27337 - match key { - Key::Space if state == KeyState::Released => { + match keyboard_event.key { + Key::Character(ref letter) if letter == " " && keyboard_event.state == KeyState::Up => { let maybe_elem = target.downcast::<Element>(); if let Some(el) = maybe_elem { synthetic_click_activation( @@ -1459,11 +1450,15 @@ impl Document { ActivationSource::NotFromClick, ) } - }, - Key::Enter if state == KeyState::Released => { + } + Key::Enter if keyboard_event.state == KeyState::Up => { let maybe_elem = target.downcast::<Element>(); if let Some(el) = maybe_elem { if let Some(a) = el.as_maybe_activatable() { + let ctrl = keyboard_event.modifiers.contains(Modifiers::CONTROL); + let alt = keyboard_event.modifiers.contains(Modifiers::ALT); + let shift = keyboard_event.modifiers.contains(Modifiers::SHIFT); + let meta = keyboard_event.modifiers.contains(Modifiers::META); a.implicit_submission(ctrl, alt, shift, meta); } } |