diff options
author | Avi Weinstock <aweinstock314@gmail.com> | 2015-04-22 13:25:05 -0400 |
---|---|---|
committer | Avi Weinstock <aweinstock314@gmail.com> | 2015-05-06 11:46:18 -0400 |
commit | b742eeca050856b3055668c9021bacfb19b3de4a (patch) | |
tree | 231032915096b819248519d5885161d6d1867090 /components/script/textinput.rs | |
parent | 387836c42e2377fc53d51d3404e6b91d170727a8 (diff) | |
download | servo-b742eeca050856b3055668c9021bacfb19b3de4a.tar.gz servo-b742eeca050856b3055668c9021bacfb19b3de4a.zip |
Made the clipboard-related functionality in TextInput more testable. Added test_clipboard_paste to the "test-unit" suite.
Diffstat (limited to 'components/script/textinput.rs')
-rw-r--r-- | components/script/textinput.rs | 70 |
1 files changed, 32 insertions, 38 deletions
diff --git a/components/script/textinput.rs b/components/script/textinput.rs index f99f5e8781c..b676ab2f13e 100644 --- a/components/script/textinput.rs +++ b/components/script/textinput.rs @@ -4,17 +4,17 @@ //! Common handling of keyboard input and state management for text input controls -use dom::bindings::codegen::Bindings::KeyboardEventBinding::KeyboardEventMethods; +use clipboard_provider::ClipboardProvider; use dom::bindings::js::JSRef; -use msg::constellation_msg::ConstellationChan; -use msg::constellation_msg::Msg as ConstellationMsg; -use dom::keyboardevent::KeyboardEvent; +use dom::keyboardevent::{KeyboardEvent, KeyboardEventHelpers, key_value}; +use msg::constellation_msg::{SHIFT, CONTROL, ALT, SUPER}; +use msg::constellation_msg::{Key, KeyModifiers}; use util::str::DOMString; use std::borrow::ToOwned; use std::cmp::{min, max}; use std::default::Default; -use std::sync::mpsc::channel; + #[derive(Copy, Clone, PartialEq)] pub enum Selection { @@ -33,7 +33,7 @@ pub struct TextPoint { /// Encapsulated state for handling keyboard input in a single or multiline text input control. #[jstraceable] -pub struct TextInput { +pub struct TextInput<T: ClipboardProvider> { /// Current text input content, split across lines without trailing '\n' lines: Vec<DOMString>, /// Current cursor input point @@ -42,7 +42,7 @@ pub struct TextInput { selection_begin: Option<TextPoint>, /// Is this a multiline input? multiline: bool, - constellation_channel: Option<ConstellationChan> + clipboard_provider: T, } /// Resulting action to be taken by the owner of a text input that is handling an event. @@ -79,24 +79,24 @@ pub enum DeleteDir { /// Was the keyboard event accompanied by the standard control modifier, /// i.e. cmd on Mac OS or ctrl on other platforms. #[cfg(target_os="macos")] -fn is_control_key(event: JSRef<KeyboardEvent>) -> bool { - event.MetaKey() && !event.CtrlKey() && !event.AltKey() +fn is_control_key(mods: KeyModifiers) -> bool { + mods.contains(SUPER) && !mods.contains(CONTROL | ALT) } #[cfg(not(target_os="macos"))] -fn is_control_key(event: JSRef<KeyboardEvent>) -> bool { - event.CtrlKey() && !event.MetaKey() && !event.AltKey() +fn is_control_key(mods: KeyModifiers) -> bool { + mods.contains(CONTROL) && !mods.contains(SUPER | ALT) } -impl TextInput { +impl<T: ClipboardProvider> TextInput<T> { /// Instantiate a new text input control - pub fn new(lines: Lines, initial: DOMString, cc: Option<ConstellationChan>) -> TextInput { + pub fn new(lines: Lines, initial: DOMString, clipboard_provider: T) -> TextInput<T> { let mut i = TextInput { lines: vec!(), edit_point: Default::default(), selection_begin: None, multiline: lines == Lines::Multiple, - constellation_channel: cc, + clipboard_provider: clipboard_provider }; i.set_content(initial); i @@ -283,28 +283,22 @@ impl TextInput { /// Process a given `KeyboardEvent` and return an action for the caller to execute. pub fn handle_keydown(&mut self, event: JSRef<KeyboardEvent>) -> KeyReaction { - //A simple way to convert an event to a selection - fn maybe_select(event: JSRef<KeyboardEvent>) -> Selection { - if event.ShiftKey() { - return Selection::Selected - } - return Selection::NotSelected + if let Some(key) = event.get_key() { + self.handle_keydown_aux(key, event.get_key_modifiers()) + } else { + KeyReaction::Nothing } - match &*event.Key() { - "a" if is_control_key(event) => { + } + pub fn handle_keydown_aux(&mut self, key: Key, mods: KeyModifiers) -> KeyReaction { + let maybe_select = if mods.contains(SHIFT) { Selection::Selected } else { Selection::NotSelected }; + match key_value(key, mods) { + "a" if is_control_key(mods) => { self.select_all(); KeyReaction::Nothing }, - "v" if is_control_key(event) => { - let (tx, rx) = channel(); - let mut contents = None; - if let Some(ref cc) = self.constellation_channel { - cc.0.send(ConstellationMsg::GetClipboardContents(tx)).unwrap(); - contents = Some(rx.recv().unwrap()); - } - if let Some(contents) = contents { - self.insert_string(&contents); - } + "v" if is_control_key(mods) => { + let contents = self.clipboard_provider.get_clipboard_contents(); + self.insert_string(&contents); KeyReaction::DispatchInput }, // printable characters have single-character key values @@ -325,19 +319,19 @@ impl TextInput { KeyReaction::DispatchInput } "ArrowLeft" => { - self.adjust_horizontal(-1, maybe_select(event)); + self.adjust_horizontal(-1, maybe_select); KeyReaction::Nothing } "ArrowRight" => { - self.adjust_horizontal(1, maybe_select(event)); + self.adjust_horizontal(1, maybe_select); KeyReaction::Nothing } "ArrowUp" => { - self.adjust_vertical(-1, maybe_select(event)); + self.adjust_vertical(-1, maybe_select); KeyReaction::Nothing } "ArrowDown" => { - self.adjust_vertical(1, maybe_select(event)); + self.adjust_vertical(1, maybe_select); KeyReaction::Nothing } "Enter" => self.handle_return(), @@ -350,11 +344,11 @@ impl TextInput { KeyReaction::Nothing } "PageUp" => { - self.adjust_vertical(-28, maybe_select(event)); + self.adjust_vertical(-28, maybe_select); KeyReaction::Nothing } "PageDown" => { - self.adjust_vertical(28, maybe_select(event)); + self.adjust_vertical(28, maybe_select); KeyReaction::Nothing } "Tab" => KeyReaction::TriggerDefaultAction, |