From b742eeca050856b3055668c9021bacfb19b3de4a Mon Sep 17 00:00:00 2001 From: Avi Weinstock Date: Wed, 22 Apr 2015 13:25:05 -0400 Subject: [PATCH] Made the clipboard-related functionality in TextInput more testable. Added test_clipboard_paste to the "test-unit" suite. --- components/script/clipboard_provider.rs | 48 ++ components/script/dom/document.rs | 8 +- components/script/dom/htmlinputelement.rs | 5 +- components/script/dom/htmltextareaelement.rs | 5 +- components/script/dom/keyboardevent.rs | 790 ++++++++++--------- components/script/lib.rs | 1 + components/script/textinput.rs | 70 +- components/servo/Cargo.lock | 1 + tests/unit/script/Cargo.toml | 3 + tests/unit/script/lib.rs | 1 + tests/unit/script/textinput.rs | 36 +- 11 files changed, 532 insertions(+), 436 deletions(-) create mode 100644 components/script/clipboard_provider.rs diff --git a/components/script/clipboard_provider.rs b/components/script/clipboard_provider.rs new file mode 100644 index 00000000000..060c857b64b --- /dev/null +++ b/components/script/clipboard_provider.rs @@ -0,0 +1,48 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use msg::constellation_msg::ConstellationChan; +use msg::constellation_msg::Msg as ConstellationMsg; + +use collections::borrow::ToOwned; +use std::sync::mpsc::channel; + +pub trait ClipboardProvider { + // blocking method to get the clipboard contents + fn get_clipboard_contents(&mut self) -> String; + // blocking method to set the clipboard contents + fn set_clipboard_contents(&mut self, &str); +} + +impl ClipboardProvider for ConstellationChan { + fn get_clipboard_contents(&mut self) -> String { + let (tx, rx) = channel(); + self.0.send(ConstellationMsg::GetClipboardContents(tx)).unwrap(); + rx.recv().unwrap() + } + fn set_clipboard_contents(&mut self, _: &str) { + panic!("not yet implemented"); + } +} + +pub struct DummyClipboardContext { + content: String +} + +impl DummyClipboardContext { + pub fn new(s: &str) -> DummyClipboardContext { + DummyClipboardContext { + content: s.to_owned() + } + } +} + +impl ClipboardProvider for DummyClipboardContext { + fn get_clipboard_contents(&mut self) -> String { + self.content.clone() + } + fn set_clipboard_contents(&mut self, s: &str) { + self.content = s.to_owned(); + } +} diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index cbb8b8daec4..9c3b0b00511 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -701,8 +701,8 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> { let props = KeyboardEvent::key_properties(key, modifiers); let keyevent = KeyboardEvent::new(window.r(), ev_type, true, true, - Some(window.r()), 0, - props.key.to_owned(), props.code.to_owned(), + Some(window.r()), 0, Some(key), + props.key_string.to_owned(), props.code.to_owned(), props.location, is_repeating, is_composing, ctrl, alt, shift, meta, None, props.key_code).root(); @@ -714,8 +714,8 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> { if state != KeyState::Released && props.is_printable() && !prevented { // https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#keypress-event-order let event = KeyboardEvent::new(window.r(), "keypress".to_owned(), - true, true, Some(window.r()), - 0, props.key.to_owned(), props.code.to_owned(), + true, true, Some(window.r()), 0, Some(key), + props.key_string.to_owned(), props.code.to_owned(), props.location, is_repeating, is_composing, ctrl, alt, shift, meta, props.char_code, 0).root(); diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs index 17768a76c8b..58f34e791b7 100644 --- a/components/script/dom/htmlinputelement.rs +++ b/components/script/dom/htmlinputelement.rs @@ -35,6 +35,7 @@ use dom::window::WindowHelpers; use textinput::TextInput; use textinput::KeyReaction::{TriggerDefaultAction, DispatchInput, Nothing}; use textinput::Lines::Single; +use msg::constellation_msg::ConstellationChan; use util::str::DOMString; use string_cache::Atom; @@ -72,7 +73,7 @@ pub struct HTMLInputElement { indeterminate: Cell, value_changed: Cell, size: Cell, - textinput: DOMRefCell, + textinput: DOMRefCell>, activation_state: DOMRefCell, } @@ -122,7 +123,7 @@ impl HTMLInputElement { checked_changed: Cell::new(false), value_changed: Cell::new(false), size: Cell::new(DEFAULT_INPUT_SIZE), - textinput: DOMRefCell::new(TextInput::new(Single, "".to_owned(), Some(chan))), + textinput: DOMRefCell::new(TextInput::new(Single, "".to_owned(), chan)), activation_state: DOMRefCell::new(InputActivationState::new()) } } diff --git a/components/script/dom/htmltextareaelement.rs b/components/script/dom/htmltextareaelement.rs index 5e6724d5c63..bbd19b2d65c 100644 --- a/components/script/dom/htmltextareaelement.rs +++ b/components/script/dom/htmltextareaelement.rs @@ -30,6 +30,7 @@ use textinput::{TextInput, Lines, KeyReaction}; use dom::virtualmethods::VirtualMethods; use dom::window::WindowHelpers; use script_task::{ScriptMsg, Runnable}; +use msg::constellation_msg::ConstellationChan; use util::str::DOMString; use string_cache::Atom; @@ -40,7 +41,7 @@ use std::cell::Cell; #[dom_struct] pub struct HTMLTextAreaElement { htmlelement: HTMLElement, - textinput: DOMRefCell, + textinput: DOMRefCell>, cols: Cell, rows: Cell, // https://html.spec.whatwg.org/multipage/#concept-textarea-dirty @@ -95,7 +96,7 @@ impl HTMLTextAreaElement { let chan = document.window().root().r().constellation_chan(); HTMLTextAreaElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLTextAreaElement, localName, prefix, document), - textinput: DOMRefCell::new(TextInput::new(Lines::Multiple, "".to_owned(), Some(chan))), + textinput: DOMRefCell::new(TextInput::new(Lines::Multiple, "".to_owned(), chan)), cols: Cell::new(DEFAULT_COLS), rows: Cell::new(DEFAULT_ROWS), value_changed: Cell::new(false), diff --git a/components/script/dom/keyboardevent.rs b/components/script/dom/keyboardevent.rs index ab93eddbefa..2ff4018801e 100644 --- a/components/script/dom/keyboardevent.rs +++ b/components/script/dom/keyboardevent.rs @@ -14,15 +14,19 @@ use dom::event::{Event, EventTypeId}; use dom::uievent::UIEvent; use dom::window::Window; use msg::constellation_msg; +use msg::constellation_msg::{Key, KeyModifiers}; use util::str::DOMString; use std::borrow::ToOwned; use std::cell::{RefCell, Cell}; +no_jsmanaged_fields!(Key); + #[dom_struct] pub struct KeyboardEvent { uievent: UIEvent, - key: RefCell, + key: Cell>, + key_string: RefCell, code: RefCell, location: Cell, ctrl: Cell, @@ -45,7 +49,8 @@ impl KeyboardEvent { fn new_inherited() -> KeyboardEvent { KeyboardEvent { uievent: UIEvent::new_inherited(EventTypeId::KeyboardEvent), - key: RefCell::new("".to_owned()), + key: Cell::new(None), + key_string: RefCell::new("".to_owned()), code: RefCell::new("".to_owned()), location: Cell::new(0), ctrl: Cell::new(false), @@ -71,7 +76,8 @@ impl KeyboardEvent { cancelable: bool, view: Option>, _detail: i32, - key: DOMString, + key: Option, + key_string: DOMString, code: DOMString, location: u32, repeat: bool, @@ -83,10 +89,11 @@ impl KeyboardEvent { char_code: Option, key_code: u32) -> Temporary { let ev = KeyboardEvent::new_uninitialized(window).root(); - ev.r().InitKeyboardEvent(type_, canBubble, cancelable, view, key, location, + ev.r().InitKeyboardEvent(type_, canBubble, cancelable, view, key_string, location, "".to_owned(), repeat, "".to_owned()); // FIXME(https://github.com/rust-lang/rust/issues/23338) let ev = ev.r(); + ev.key.set(key); *ev.code.borrow_mut() = code; ev.ctrl.set(ctrlKey); ev.alt.set(altKey); @@ -105,7 +112,7 @@ impl KeyboardEvent { init.parent.parent.parent.bubbles, init.parent.parent.parent.cancelable, init.parent.parent.view.r(), - init.parent.parent.detail, + init.parent.parent.detail, None, init.key.clone(), init.code.clone(), init.location, init.repeat, init.isComposing, init.parent.ctrlKey, init.parent.altKey, init.parent.shiftKey, init.parent.metaKey, @@ -113,10 +120,10 @@ impl KeyboardEvent { Ok(event) } - pub fn key_properties(key: constellation_msg::Key, mods: constellation_msg::KeyModifiers) + pub fn key_properties(key: Key, mods: KeyModifiers) -> KeyEventProperties { KeyEventProperties { - key: key_value(key, mods), + key_string: key_value(key, mods), code: code_value(key), location: key_location(key), char_code: key_charcode(key, mods), @@ -125,321 +132,350 @@ impl KeyboardEvent { } } +pub trait KeyboardEventHelpers { + fn get_key(&self) -> Option; + fn get_key_modifiers(&self) -> KeyModifiers; +} + +impl<'a> KeyboardEventHelpers for JSRef<'a, KeyboardEvent> { + fn get_key(&self) -> Option { + self.key.get().clone() + } + + fn get_key_modifiers(&self) -> KeyModifiers { + let mut result = KeyModifiers::empty(); + if self.shift.get() { + result = result | constellation_msg::SHIFT; + } + if self.ctrl.get() { + result = result | constellation_msg::CONTROL; + } + if self.alt.get() { + result = result | constellation_msg::ALT; + } + if self.meta.get() { + result = result | constellation_msg::SUPER; + } + return result; + } +} + + // https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3Events-key.html -fn key_value(key: constellation_msg::Key, mods: constellation_msg::KeyModifiers) -> &'static str { +pub fn key_value(key: Key, mods: KeyModifiers) -> &'static str { let shift = mods.contains(constellation_msg::SHIFT); match key { - constellation_msg::Key::Space => " ", - constellation_msg::Key::Apostrophe if shift => "\"", - constellation_msg::Key::Apostrophe => "'", - constellation_msg::Key::Comma if shift => "<", - constellation_msg::Key::Comma => ",", - constellation_msg::Key::Minus if shift => "_", - constellation_msg::Key::Minus => "-", - constellation_msg::Key::Period if shift => ">", - constellation_msg::Key::Period => ".", - constellation_msg::Key::Slash if shift => "?", - constellation_msg::Key::Slash => "/", - constellation_msg::Key::GraveAccent if shift => "~", - constellation_msg::Key::GraveAccent => "`", - constellation_msg::Key::Num0 if shift => ")", - constellation_msg::Key::Num0 => "0", - constellation_msg::Key::Num1 if shift => "!", - constellation_msg::Key::Num1 => "1", - constellation_msg::Key::Num2 if shift => "@", - constellation_msg::Key::Num2 => "2", - constellation_msg::Key::Num3 if shift => "#", - constellation_msg::Key::Num3 => "3", - constellation_msg::Key::Num4 if shift => "$", - constellation_msg::Key::Num4 => "4", - constellation_msg::Key::Num5 if shift => "%", - constellation_msg::Key::Num5 => "5", - constellation_msg::Key::Num6 if shift => "^", - constellation_msg::Key::Num6 => "6", - constellation_msg::Key::Num7 if shift => "&", - constellation_msg::Key::Num7 => "7", - constellation_msg::Key::Num8 if shift => "*", - constellation_msg::Key::Num8 => "8", - constellation_msg::Key::Num9 if shift => "(", - constellation_msg::Key::Num9 => "9", - constellation_msg::Key::Semicolon if shift => ":", - constellation_msg::Key::Semicolon => ";", - constellation_msg::Key::Equal if shift => "+", - constellation_msg::Key::Equal => "=", - constellation_msg::Key::A if shift => "A", - constellation_msg::Key::A => "a", - constellation_msg::Key::B if shift => "B", - constellation_msg::Key::B => "b", - constellation_msg::Key::C if shift => "C", - constellation_msg::Key::C => "c", - constellation_msg::Key::D if shift => "D", - constellation_msg::Key::D => "d", - constellation_msg::Key::E if shift => "E", - constellation_msg::Key::E => "e", - constellation_msg::Key::F if shift => "F", - constellation_msg::Key::F => "f", - constellation_msg::Key::G if shift => "G", - constellation_msg::Key::G => "g", - constellation_msg::Key::H if shift => "H", - constellation_msg::Key::H => "h", - constellation_msg::Key::I if shift => "I", - constellation_msg::Key::I => "i", - constellation_msg::Key::J if shift => "J", - constellation_msg::Key::J => "j", - constellation_msg::Key::K if shift => "K", - constellation_msg::Key::K => "k", - constellation_msg::Key::L if shift => "L", - constellation_msg::Key::L => "l", - constellation_msg::Key::M if shift => "M", - constellation_msg::Key::M => "m", - constellation_msg::Key::N if shift => "N", - constellation_msg::Key::N => "n", - constellation_msg::Key::O if shift => "O", - constellation_msg::Key::O => "o", - constellation_msg::Key::P if shift => "P", - constellation_msg::Key::P => "p", - constellation_msg::Key::Q if shift => "Q", - constellation_msg::Key::Q => "q", - constellation_msg::Key::R if shift => "R", - constellation_msg::Key::R => "r", - constellation_msg::Key::S if shift => "S", - constellation_msg::Key::S => "s", - constellation_msg::Key::T if shift => "T", - constellation_msg::Key::T => "t", - constellation_msg::Key::U if shift => "U", - constellation_msg::Key::U => "u", - constellation_msg::Key::V if shift => "V", - constellation_msg::Key::V => "v", - constellation_msg::Key::W if shift => "W", - constellation_msg::Key::W => "w", - constellation_msg::Key::X if shift => "X", - constellation_msg::Key::X => "x", - constellation_msg::Key::Y if shift => "Y", - constellation_msg::Key::Y => "y", - constellation_msg::Key::Z if shift => "Z", - constellation_msg::Key::Z => "z", - constellation_msg::Key::LeftBracket if shift => "{", - constellation_msg::Key::LeftBracket => "[", - constellation_msg::Key::Backslash if shift => "|", - constellation_msg::Key::Backslash => "\\", - constellation_msg::Key::RightBracket if shift => "}", - constellation_msg::Key::RightBracket => "]", - constellation_msg::Key::World1 => "Unidentified", - constellation_msg::Key::World2 => "Unidentified", - constellation_msg::Key::Escape => "Escape", - constellation_msg::Key::Enter => "Enter", - constellation_msg::Key::Tab => "Tab", - constellation_msg::Key::Backspace => "Backspace", - constellation_msg::Key::Insert => "Insert", - constellation_msg::Key::Delete => "Delete", - constellation_msg::Key::Right => "ArrowRight", - constellation_msg::Key::Left => "ArrowLeft", - constellation_msg::Key::Down => "ArrowDown", - constellation_msg::Key::Up => "ArrowUp", - constellation_msg::Key::PageUp => "PageUp", - constellation_msg::Key::PageDown => "PageDown", - constellation_msg::Key::Home => "Home", - constellation_msg::Key::End => "End", - constellation_msg::Key::CapsLock => "CapsLock", - constellation_msg::Key::ScrollLock => "ScrollLock", - constellation_msg::Key::NumLock => "NumLock", - constellation_msg::Key::PrintScreen => "PrintScreen", - constellation_msg::Key::Pause => "Pause", - constellation_msg::Key::F1 => "F1", - constellation_msg::Key::F2 => "F2", - constellation_msg::Key::F3 => "F3", - constellation_msg::Key::F4 => "F4", - constellation_msg::Key::F5 => "F5", - constellation_msg::Key::F6 => "F6", - constellation_msg::Key::F7 => "F7", - constellation_msg::Key::F8 => "F8", - constellation_msg::Key::F9 => "F9", - constellation_msg::Key::F10 => "F10", - constellation_msg::Key::F11 => "F11", - constellation_msg::Key::F12 => "F12", - constellation_msg::Key::F13 => "F13", - constellation_msg::Key::F14 => "F14", - constellation_msg::Key::F15 => "F15", - constellation_msg::Key::F16 => "F16", - constellation_msg::Key::F17 => "F17", - constellation_msg::Key::F18 => "F18", - constellation_msg::Key::F19 => "F19", - constellation_msg::Key::F20 => "F20", - constellation_msg::Key::F21 => "F21", - constellation_msg::Key::F22 => "F22", - constellation_msg::Key::F23 => "F23", - constellation_msg::Key::F24 => "F24", - constellation_msg::Key::F25 => "F25", - constellation_msg::Key::Kp0 => "0", - constellation_msg::Key::Kp1 => "1", - constellation_msg::Key::Kp2 => "2", - constellation_msg::Key::Kp3 => "3", - constellation_msg::Key::Kp4 => "4", - constellation_msg::Key::Kp5 => "5", - constellation_msg::Key::Kp6 => "6", - constellation_msg::Key::Kp7 => "7", - constellation_msg::Key::Kp8 => "8", - constellation_msg::Key::Kp9 => "9", - constellation_msg::Key::KpDecimal => ".", - constellation_msg::Key::KpDivide => "/", - constellation_msg::Key::KpMultiply => "*", - constellation_msg::Key::KpSubtract => "-", - constellation_msg::Key::KpAdd => "+", - constellation_msg::Key::KpEnter => "Enter", - constellation_msg::Key::KpEqual => "=", - constellation_msg::Key::LeftShift => "Shift", - constellation_msg::Key::LeftControl => "Control", - constellation_msg::Key::LeftAlt => "Alt", - constellation_msg::Key::LeftSuper => "Super", - constellation_msg::Key::RightShift => "Shift", - constellation_msg::Key::RightControl => "Control", - constellation_msg::Key::RightAlt => "Alt", - constellation_msg::Key::RightSuper => "Super", - constellation_msg::Key::Menu => "ContextMenu", + Key::Space => " ", + Key::Apostrophe if shift => "\"", + Key::Apostrophe => "'", + Key::Comma if shift => "<", + Key::Comma => ",", + Key::Minus if shift => "_", + Key::Minus => "-", + Key::Period if shift => ">", + Key::Period => ".", + Key::Slash if shift => "?", + Key::Slash => "/", + Key::GraveAccent if shift => "~", + Key::GraveAccent => "`", + Key::Num0 if shift => ")", + Key::Num0 => "0", + Key::Num1 if shift => "!", + Key::Num1 => "1", + Key::Num2 if shift => "@", + Key::Num2 => "2", + Key::Num3 if shift => "#", + Key::Num3 => "3", + Key::Num4 if shift => "$", + Key::Num4 => "4", + Key::Num5 if shift => "%", + Key::Num5 => "5", + Key::Num6 if shift => "^", + Key::Num6 => "6", + Key::Num7 if shift => "&", + Key::Num7 => "7", + Key::Num8 if shift => "*", + Key::Num8 => "8", + Key::Num9 if shift => "(", + Key::Num9 => "9", + Key::Semicolon if shift => ":", + Key::Semicolon => ";", + Key::Equal if shift => "+", + Key::Equal => "=", + Key::A if shift => "A", + Key::A => "a", + Key::B if shift => "B", + Key::B => "b", + Key::C if shift => "C", + Key::C => "c", + Key::D if shift => "D", + Key::D => "d", + Key::E if shift => "E", + Key::E => "e", + Key::F if shift => "F", + Key::F => "f", + Key::G if shift => "G", + Key::G => "g", + Key::H if shift => "H", + Key::H => "h", + Key::I if shift => "I", + Key::I => "i", + Key::J if shift => "J", + Key::J => "j", + Key::K if shift => "K", + Key::K => "k", + Key::L if shift => "L", + Key::L => "l", + Key::M if shift => "M", + Key::M => "m", + Key::N if shift => "N", + Key::N => "n", + Key::O if shift => "O", + Key::O => "o", + Key::P if shift => "P", + Key::P => "p", + Key::Q if shift => "Q", + Key::Q => "q", + Key::R if shift => "R", + Key::R => "r", + Key::S if shift => "S", + Key::S => "s", + Key::T if shift => "T", + Key::T => "t", + Key::U if shift => "U", + Key::U => "u", + Key::V if shift => "V", + Key::V => "v", + Key::W if shift => "W", + Key::W => "w", + Key::X if shift => "X", + Key::X => "x", + Key::Y if shift => "Y", + Key::Y => "y", + Key::Z if shift => "Z", + Key::Z => "z", + Key::LeftBracket if shift => "{", + Key::LeftBracket => "[", + Key::Backslash if shift => "|", + Key::Backslash => "\\", + Key::RightBracket if shift => "}", + Key::RightBracket => "]", + Key::World1 => "Unidentified", + Key::World2 => "Unidentified", + Key::Escape => "Escape", + Key::Enter => "Enter", + Key::Tab => "Tab", + Key::Backspace => "Backspace", + Key::Insert => "Insert", + Key::Delete => "Delete", + Key::Right => "ArrowRight", + Key::Left => "ArrowLeft", + Key::Down => "ArrowDown", + Key::Up => "ArrowUp", + Key::PageUp => "PageUp", + Key::PageDown => "PageDown", + Key::Home => "Home", + Key::End => "End", + Key::CapsLock => "CapsLock", + Key::ScrollLock => "ScrollLock", + Key::NumLock => "NumLock", + Key::PrintScreen => "PrintScreen", + Key::Pause => "Pause", + Key::F1 => "F1", + Key::F2 => "F2", + Key::F3 => "F3", + Key::F4 => "F4", + Key::F5 => "F5", + Key::F6 => "F6", + Key::F7 => "F7", + Key::F8 => "F8", + Key::F9 => "F9", + Key::F10 => "F10", + Key::F11 => "F11", + Key::F12 => "F12", + Key::F13 => "F13", + Key::F14 => "F14", + Key::F15 => "F15", + Key::F16 => "F16", + Key::F17 => "F17", + Key::F18 => "F18", + Key::F19 => "F19", + Key::F20 => "F20", + Key::F21 => "F21", + Key::F22 => "F22", + Key::F23 => "F23", + Key::F24 => "F24", + Key::F25 => "F25", + Key::Kp0 => "0", + Key::Kp1 => "1", + Key::Kp2 => "2", + Key::Kp3 => "3", + Key::Kp4 => "4", + Key::Kp5 => "5", + Key::Kp6 => "6", + Key::Kp7 => "7", + Key::Kp8 => "8", + Key::Kp9 => "9", + Key::KpDecimal => ".", + Key::KpDivide => "/", + Key::KpMultiply => "*", + Key::KpSubtract => "-", + Key::KpAdd => "+", + Key::KpEnter => "Enter", + Key::KpEqual => "=", + Key::LeftShift => "Shift", + Key::LeftControl => "Control", + Key::LeftAlt => "Alt", + Key::LeftSuper => "Super", + Key::RightShift => "Shift", + Key::RightControl => "Control", + Key::RightAlt => "Alt", + Key::RightSuper => "Super", + Key::Menu => "ContextMenu", } } // https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3Events-code.html -fn code_value(key: constellation_msg::Key) -> &'static str { +fn code_value(key: Key) -> &'static str { match key { - constellation_msg::Key::Space => "Space", - constellation_msg::Key::Apostrophe => "Quote", - constellation_msg::Key::Comma => "Comma", - constellation_msg::Key::Minus => "Minus", - constellation_msg::Key::Period => "Period", - constellation_msg::Key::Slash => "Slash", - constellation_msg::Key::GraveAccent => "Backquote", - constellation_msg::Key::Num0 => "Digit0", - constellation_msg::Key::Num1 => "Digit1", - constellation_msg::Key::Num2 => "Digit2", - constellation_msg::Key::Num3 => "Digit3", - constellation_msg::Key::Num4 => "Digit4", - constellation_msg::Key::Num5 => "Digit5", - constellation_msg::Key::Num6 => "Digit6", - constellation_msg::Key::Num7 => "Digit7", - constellation_msg::Key::Num8 => "Digit8", - constellation_msg::Key::Num9 => "Digit9", - constellation_msg::Key::Semicolon => "Semicolon", - constellation_msg::Key::Equal => "Equal", - constellation_msg::Key::A => "KeyA", - constellation_msg::Key::B => "KeyB", - constellation_msg::Key::C => "KeyC", - constellation_msg::Key::D => "KeyD", - constellation_msg::Key::E => "KeyE", - constellation_msg::Key::F => "KeyF", - constellation_msg::Key::G => "KeyG", - constellation_msg::Key::H => "KeyH", - constellation_msg::Key::I => "KeyI", - constellation_msg::Key::J => "KeyJ", - constellation_msg::Key::K => "KeyK", - constellation_msg::Key::L => "KeyL", - constellation_msg::Key::M => "KeyM", - constellation_msg::Key::N => "KeyN", - constellation_msg::Key::O => "KeyO", - constellation_msg::Key::P => "KeyP", - constellation_msg::Key::Q => "KeyQ", - constellation_msg::Key::R => "KeyR", - constellation_msg::Key::S => "KeyS", - constellation_msg::Key::T => "KeyT", - constellation_msg::Key::U => "KeyU", - constellation_msg::Key::V => "KeyV", - constellation_msg::Key::W => "KeyW", - constellation_msg::Key::X => "KeyX", - constellation_msg::Key::Y => "KeyY", - constellation_msg::Key::Z => "KeyZ", - constellation_msg::Key::LeftBracket => "BracketLeft", - constellation_msg::Key::Backslash => "Backslash", - constellation_msg::Key::RightBracket => "BracketRight", + Key::Space => "Space", + Key::Apostrophe => "Quote", + Key::Comma => "Comma", + Key::Minus => "Minus", + Key::Period => "Period", + Key::Slash => "Slash", + Key::GraveAccent => "Backquote", + Key::Num0 => "Digit0", + Key::Num1 => "Digit1", + Key::Num2 => "Digit2", + Key::Num3 => "Digit3", + Key::Num4 => "Digit4", + Key::Num5 => "Digit5", + Key::Num6 => "Digit6", + Key::Num7 => "Digit7", + Key::Num8 => "Digit8", + Key::Num9 => "Digit9", + Key::Semicolon => "Semicolon", + Key::Equal => "Equal", + Key::A => "KeyA", + Key::B => "KeyB", + Key::C => "KeyC", + Key::D => "KeyD", + Key::E => "KeyE", + Key::F => "KeyF", + Key::G => "KeyG", + Key::H => "KeyH", + Key::I => "KeyI", + Key::J => "KeyJ", + Key::K => "KeyK", + Key::L => "KeyL", + Key::M => "KeyM", + Key::N => "KeyN", + Key::O => "KeyO", + Key::P => "KeyP", + Key::Q => "KeyQ", + Key::R => "KeyR", + Key::S => "KeyS", + Key::T => "KeyT", + Key::U => "KeyU", + Key::V => "KeyV", + Key::W => "KeyW", + Key::X => "KeyX", + Key::Y => "KeyY", + Key::Z => "KeyZ", + Key::LeftBracket => "BracketLeft", + Key::Backslash => "Backslash", + Key::RightBracket => "BracketRight", - constellation_msg::Key::World1 | - constellation_msg::Key::World2 => panic!("unknown char code for {:?}", key), + Key::World1 | + Key::World2 => panic!("unknown char code for {:?}", key), - constellation_msg::Key::Escape => "Escape", - constellation_msg::Key::Enter => "Enter", - constellation_msg::Key::Tab => "Tab", - constellation_msg::Key::Backspace => "Backspace", - constellation_msg::Key::Insert => "Insert", - constellation_msg::Key::Delete => "Delete", - constellation_msg::Key::Right => "ArrowRight", - constellation_msg::Key::Left => "ArrowLeft", - constellation_msg::Key::Down => "ArrowDown", - constellation_msg::Key::Up => "ArrowUp", - constellation_msg::Key::PageUp => "PageUp", - constellation_msg::Key::PageDown => "PageDown", - constellation_msg::Key::Home => "Home", - constellation_msg::Key::End => "End", - constellation_msg::Key::CapsLock => "CapsLock", - constellation_msg::Key::ScrollLock => "ScrollLock", - constellation_msg::Key::NumLock => "NumLock", - constellation_msg::Key::PrintScreen => "PrintScreen", - constellation_msg::Key::Pause => "Pause", - constellation_msg::Key::F1 => "F1", - constellation_msg::Key::F2 => "F2", - constellation_msg::Key::F3 => "F3", - constellation_msg::Key::F4 => "F4", - constellation_msg::Key::F5 => "F5", - constellation_msg::Key::F6 => "F6", - constellation_msg::Key::F7 => "F7", - constellation_msg::Key::F8 => "F8", - constellation_msg::Key::F9 => "F9", - constellation_msg::Key::F10 => "F10", - constellation_msg::Key::F11 => "F11", - constellation_msg::Key::F12 => "F12", - constellation_msg::Key::F13 => "F13", - constellation_msg::Key::F14 => "F14", - constellation_msg::Key::F15 => "F15", - constellation_msg::Key::F16 => "F16", - constellation_msg::Key::F17 => "F17", - constellation_msg::Key::F18 => "F18", - constellation_msg::Key::F19 => "F19", - constellation_msg::Key::F20 => "F20", - constellation_msg::Key::F21 => "F21", - constellation_msg::Key::F22 => "F22", - constellation_msg::Key::F23 => "F23", - constellation_msg::Key::F24 => "F24", - constellation_msg::Key::F25 => "F25", - constellation_msg::Key::Kp0 => "Numpad0", - constellation_msg::Key::Kp1 => "Numpad1", - constellation_msg::Key::Kp2 => "Numpad2", - constellation_msg::Key::Kp3 => "Numpad3", - constellation_msg::Key::Kp4 => "Numpad4", - constellation_msg::Key::Kp5 => "Numpad5", - constellation_msg::Key::Kp6 => "Numpad6", - constellation_msg::Key::Kp7 => "Numpad7", - constellation_msg::Key::Kp8 => "Numpad8", - constellation_msg::Key::Kp9 => "Numpad9", - constellation_msg::Key::KpDecimal => "NumpadDecimal", - constellation_msg::Key::KpDivide => "NumpadDivide", - constellation_msg::Key::KpMultiply => "NumpadMultiply", - constellation_msg::Key::KpSubtract => "NumpadSubtract", - constellation_msg::Key::KpAdd => "NumpadAdd", - constellation_msg::Key::KpEnter => "NumpadEnter", - constellation_msg::Key::KpEqual => "NumpadEqual", - constellation_msg::Key::LeftShift | constellation_msg::Key::RightShift => "Shift", - constellation_msg::Key::LeftControl | constellation_msg::Key::RightControl => "Control", - constellation_msg::Key::LeftAlt | constellation_msg::Key::RightAlt => "Alt", - constellation_msg::Key::LeftSuper | constellation_msg::Key::RightSuper => "Super", - constellation_msg::Key::Menu => "Menu", + Key::Escape => "Escape", + Key::Enter => "Enter", + Key::Tab => "Tab", + Key::Backspace => "Backspace", + Key::Insert => "Insert", + Key::Delete => "Delete", + Key::Right => "ArrowRight", + Key::Left => "ArrowLeft", + Key::Down => "ArrowDown", + Key::Up => "ArrowUp", + Key::PageUp => "PageUp", + Key::PageDown => "PageDown", + Key::Home => "Home", + Key::End => "End", + Key::CapsLock => "CapsLock", + Key::ScrollLock => "ScrollLock", + Key::NumLock => "NumLock", + Key::PrintScreen => "PrintScreen", + Key::Pause => "Pause", + Key::F1 => "F1", + Key::F2 => "F2", + Key::F3 => "F3", + Key::F4 => "F4", + Key::F5 => "F5", + Key::F6 => "F6", + Key::F7 => "F7", + Key::F8 => "F8", + Key::F9 => "F9", + Key::F10 => "F10", + Key::F11 => "F11", + Key::F12 => "F12", + Key::F13 => "F13", + Key::F14 => "F14", + Key::F15 => "F15", + Key::F16 => "F16", + Key::F17 => "F17", + Key::F18 => "F18", + Key::F19 => "F19", + Key::F20 => "F20", + Key::F21 => "F21", + Key::F22 => "F22", + Key::F23 => "F23", + Key::F24 => "F24", + Key::F25 => "F25", + Key::Kp0 => "Numpad0", + Key::Kp1 => "Numpad1", + Key::Kp2 => "Numpad2", + Key::Kp3 => "Numpad3", + Key::Kp4 => "Numpad4", + Key::Kp5 => "Numpad5", + Key::Kp6 => "Numpad6", + Key::Kp7 => "Numpad7", + Key::Kp8 => "Numpad8", + Key::Kp9 => "Numpad9", + Key::KpDecimal => "NumpadDecimal", + Key::KpDivide => "NumpadDivide", + Key::KpMultiply => "NumpadMultiply", + Key::KpSubtract => "NumpadSubtract", + Key::KpAdd => "NumpadAdd", + Key::KpEnter => "NumpadEnter", + Key::KpEqual => "NumpadEqual", + Key::LeftShift | Key::RightShift => "Shift", + Key::LeftControl | Key::RightControl => "Control", + Key::LeftAlt | Key::RightAlt => "Alt", + Key::LeftSuper | Key::RightSuper => "Super", + Key::Menu => "Menu", } } -fn key_location(key: constellation_msg::Key) -> u32 { +fn key_location(key: Key) -> u32 { match key { - constellation_msg::Key::Kp0 | constellation_msg::Key::Kp1 | constellation_msg::Key::Kp2 | - constellation_msg::Key::Kp3 | constellation_msg::Key::Kp4 | constellation_msg::Key::Kp5 | - constellation_msg::Key::Kp6 | constellation_msg::Key::Kp7 | constellation_msg::Key::Kp8 | - constellation_msg::Key::Kp9 | constellation_msg::Key::KpDecimal | - constellation_msg::Key::KpDivide | constellation_msg::Key::KpMultiply | - constellation_msg::Key::KpSubtract | constellation_msg::Key::KpAdd | - constellation_msg::Key::KpEnter | constellation_msg::Key::KpEqual => + Key::Kp0 | Key::Kp1 | Key::Kp2 | + Key::Kp3 | Key::Kp4 | Key::Kp5 | + Key::Kp6 | Key::Kp7 | Key::Kp8 | + Key::Kp9 | Key::KpDecimal | + Key::KpDivide | Key::KpMultiply | + Key::KpSubtract | Key::KpAdd | + Key::KpEnter | Key::KpEqual => KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD, - constellation_msg::Key::LeftShift | constellation_msg::Key::LeftAlt | - constellation_msg::Key::LeftControl | constellation_msg::Key::LeftSuper => + Key::LeftShift | Key::LeftAlt | + Key::LeftControl | Key::LeftSuper => KeyboardEventConstants::DOM_KEY_LOCATION_LEFT, - constellation_msg::Key::RightShift | constellation_msg::Key::RightAlt | - constellation_msg::Key::RightControl | constellation_msg::Key::RightSuper => + Key::RightShift | Key::RightAlt | + Key::RightControl | Key::RightSuper => KeyboardEventConstants::DOM_KEY_LOCATION_RIGHT, _ => KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD, @@ -447,89 +483,89 @@ fn key_location(key: constellation_msg::Key) -> u32 { } // https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#widl-KeyboardEvent-charCode -fn key_charcode(key: constellation_msg::Key, mods: constellation_msg::KeyModifiers) -> Option { - let key = key_value(key, mods); - if key.len() == 1 { - Some(key.chars().next().unwrap() as u32) +fn key_charcode(key: Key, mods: KeyModifiers) -> Option { + let key_string = key_value(key, mods); + if key_string.len() == 1 { + Some(key_string.chars().next().unwrap() as u32) } else { None } } // https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#legacy-key-models -fn key_keycode(key: constellation_msg::Key) -> u32 { +fn key_keycode(key: Key) -> u32 { match key { // https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#legacy-key-models - constellation_msg::Key::Backspace => 8, - constellation_msg::Key::Tab => 9, - constellation_msg::Key::Enter => 13, - constellation_msg::Key::LeftShift | constellation_msg::Key::RightShift => 16, - constellation_msg::Key::LeftControl | constellation_msg::Key::RightControl => 17, - constellation_msg::Key::LeftAlt | constellation_msg::Key::RightAlt => 18, - constellation_msg::Key::CapsLock => 20, - constellation_msg::Key::Escape => 27, - constellation_msg::Key::Space => 32, - constellation_msg::Key::PageUp => 33, - constellation_msg::Key::PageDown => 34, - constellation_msg::Key::End => 35, - constellation_msg::Key::Home => 36, - constellation_msg::Key::Left => 37, - constellation_msg::Key::Up => 38, - constellation_msg::Key::Right => 39, - constellation_msg::Key::Down => 40, - constellation_msg::Key::Delete => 46, + Key::Backspace => 8, + Key::Tab => 9, + Key::Enter => 13, + Key::LeftShift | Key::RightShift => 16, + Key::LeftControl | Key::RightControl => 17, + Key::LeftAlt | Key::RightAlt => 18, + Key::CapsLock => 20, + Key::Escape => 27, + Key::Space => 32, + Key::PageUp => 33, + Key::PageDown => 34, + Key::End => 35, + Key::Home => 36, + Key::Left => 37, + Key::Up => 38, + Key::Right => 39, + Key::Down => 40, + Key::Delete => 46, // https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#optionally-fixed-virtual-key-codes - constellation_msg::Key::Semicolon => 186, - constellation_msg::Key::Equal => 187, - constellation_msg::Key::Comma => 188, - constellation_msg::Key::Minus => 189, - constellation_msg::Key::Period => 190, - constellation_msg::Key::Slash => 191, - constellation_msg::Key::LeftBracket => 219, - constellation_msg::Key::Backslash => 220, - constellation_msg::Key::RightBracket => 221, - constellation_msg::Key::Apostrophe => 222, + Key::Semicolon => 186, + Key::Equal => 187, + Key::Comma => 188, + Key::Minus => 189, + Key::Period => 190, + Key::Slash => 191, + Key::LeftBracket => 219, + Key::Backslash => 220, + Key::RightBracket => 221, + Key::Apostrophe => 222, //§ B.2.1.3 - constellation_msg::Key::Num0 | - constellation_msg::Key::Num1 | - constellation_msg::Key::Num2 | - constellation_msg::Key::Num3 | - constellation_msg::Key::Num4 | - constellation_msg::Key::Num5 | - constellation_msg::Key::Num6 | - constellation_msg::Key::Num7 | - constellation_msg::Key::Num8 | - constellation_msg::Key::Num9 => key as u32 - constellation_msg::Key::Num0 as u32 + '0' as u32, + Key::Num0 | + Key::Num1 | + Key::Num2 | + Key::Num3 | + Key::Num4 | + Key::Num5 | + Key::Num6 | + Key::Num7 | + Key::Num8 | + Key::Num9 => key as u32 - Key::Num0 as u32 + '0' as u32, //§ B.2.1.4 - constellation_msg::Key::A | - constellation_msg::Key::B | - constellation_msg::Key::C | - constellation_msg::Key::D | - constellation_msg::Key::E | - constellation_msg::Key::F | - constellation_msg::Key::G | - constellation_msg::Key::H | - constellation_msg::Key::I | - constellation_msg::Key::J | - constellation_msg::Key::K | - constellation_msg::Key::L | - constellation_msg::Key::M | - constellation_msg::Key::N | - constellation_msg::Key::O | - constellation_msg::Key::P | - constellation_msg::Key::Q | - constellation_msg::Key::R | - constellation_msg::Key::S | - constellation_msg::Key::T | - constellation_msg::Key::U | - constellation_msg::Key::V | - constellation_msg::Key::W | - constellation_msg::Key::X | - constellation_msg::Key::Y | - constellation_msg::Key::Z => key as u32 - constellation_msg::Key::A as u32 + 'A' as u32, + Key::A | + Key::B | + Key::C | + Key::D | + Key::E | + Key::F | + Key::G | + Key::H | + Key::I | + Key::J | + Key::K | + Key::L | + Key::M | + Key::N | + Key::O | + Key::P | + Key::Q | + Key::R | + Key::S | + Key::T | + Key::U | + Key::V | + Key::W | + Key::X | + Key::Y | + Key::Z => key as u32 - Key::A as u32 + 'A' as u32, //§ B.2.1.8 _ => 0 @@ -537,7 +573,7 @@ fn key_keycode(key: constellation_msg::Key) -> u32 { } pub struct KeyEventProperties { - pub key: &'static str, + pub key_string: &'static str, pub code: &'static str, pub location: u32, pub char_code: Option, @@ -568,15 +604,15 @@ impl<'a> KeyboardEventMethods for JSRef<'a, KeyboardEvent> { let uievent: JSRef = UIEventCast::from_ref(self); uievent.InitUIEvent(typeArg, canBubbleArg, cancelableArg, viewArg, 0); - *self.key.borrow_mut() = keyArg; + *self.key_string.borrow_mut() = keyArg; self.location.set(locationArg); self.repeat.set(repeat); } fn Key(self) -> DOMString { // FIXME(https://github.com/rust-lang/rust/issues/23338) - let key = self.key.borrow(); - key.clone() + let key_string = self.key_string.borrow(); + key_string.clone() } fn Code(self) -> DOMString { diff --git a/components/script/lib.rs b/components/script/lib.rs index 3232ecec963..09340e7446e 100644 --- a/components/script/lib.rs +++ b/components/script/lib.rs @@ -66,6 +66,7 @@ pub mod page; pub mod script_task; mod timers; pub mod textinput; +pub mod clipboard_provider; mod devtools; mod horribly_inefficient_timers; mod webdriver_handlers; 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 { /// Current text input content, split across lines without trailing '\n' lines: Vec, /// Current cursor input point @@ -42,7 +42,7 @@ pub struct TextInput { selection_begin: Option, /// Is this a multiline input? multiline: bool, - constellation_channel: Option + 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) -> 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) -> bool { - event.CtrlKey() && !event.MetaKey() && !event.AltKey() +fn is_control_key(mods: KeyModifiers) -> bool { + mods.contains(CONTROL) && !mods.contains(SUPER | ALT) } -impl TextInput { +impl TextInput { /// Instantiate a new text input control - pub fn new(lines: Lines, initial: DOMString, cc: Option) -> TextInput { + pub fn new(lines: Lines, initial: DOMString, clipboard_provider: T) -> TextInput { 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) -> KeyReaction { - //A simple way to convert an event to a selection - fn maybe_select(event: JSRef) -> 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, diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock index 060328b59da..437e3bba76c 100644 --- a/components/servo/Cargo.lock +++ b/components/servo/Cargo.lock @@ -1035,6 +1035,7 @@ dependencies = [ name = "script_tests" version = "0.0.1" dependencies = [ + "msg 0.0.1", "script 0.0.1", ] diff --git a/tests/unit/script/Cargo.toml b/tests/unit/script/Cargo.toml index 759e0581545..52b4e4b2e80 100644 --- a/tests/unit/script/Cargo.toml +++ b/tests/unit/script/Cargo.toml @@ -8,5 +8,8 @@ name = "script_tests" path = "lib.rs" doctest = false +[dependencies.msg] +path = "../../../components/msg" + [dependencies.script] path = "../../../components/script" diff --git a/tests/unit/script/lib.rs b/tests/unit/script/lib.rs index 3073fcb8588..f0d22cd2ca6 100644 --- a/tests/unit/script/lib.rs +++ b/tests/unit/script/lib.rs @@ -3,6 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ extern crate script; +extern crate msg; #[cfg(all(test, target_pointer_width = "64"))] mod size_of; #[cfg(test)] mod textinput; diff --git a/tests/unit/script/textinput.rs b/tests/unit/script/textinput.rs index 0d7326685db..c5ede5262d1 100644 --- a/tests/unit/script/textinput.rs +++ b/tests/unit/script/textinput.rs @@ -7,12 +7,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use msg::constellation_msg::{Key, CONTROL}; use script::textinput::{TextInput, Selection, Lines, DeleteDir}; +use script::clipboard_provider::DummyClipboardContext; use std::borrow::ToOwned; #[test] fn test_textinput_delete_char() { - let mut textinput = TextInput::new(Lines::Single, "abcdefg".to_owned(), None); + let mut textinput = TextInput::new(Lines::Single, "abcdefg".to_owned(), DummyClipboardContext::new("")); textinput.adjust_horizontal(2, Selection::NotSelected); textinput.delete_char(DeleteDir::Backward); assert_eq!(textinput.get_content(), "acdefg"); @@ -27,7 +29,7 @@ fn test_textinput_delete_char() { #[test] fn test_textinput_insert_char() { - let mut textinput = TextInput::new(Lines::Single, "abcdefg".to_owned(), None); + let mut textinput = TextInput::new(Lines::Single, "abcdefg".to_owned(), DummyClipboardContext::new("")); textinput.adjust_horizontal(2, Selection::NotSelected); textinput.insert_char('a'); assert_eq!(textinput.get_content(), "abacdefg"); @@ -39,7 +41,7 @@ fn test_textinput_insert_char() { #[test] fn test_textinput_get_sorted_selection() { - let mut textinput = TextInput::new(Lines::Single, "abcdefg".to_owned(), None); + let mut textinput = TextInput::new(Lines::Single, "abcdefg".to_owned(), DummyClipboardContext::new("")); textinput.adjust_horizontal(2, Selection::NotSelected); textinput.adjust_horizontal(2, Selection::Selected); let (begin, end) = textinput.get_sorted_selection(); @@ -56,7 +58,7 @@ fn test_textinput_get_sorted_selection() { #[test] fn test_textinput_replace_selection() { - let mut textinput = TextInput::new(Lines::Single, "abcdefg".to_owned(), None); + let mut textinput = TextInput::new(Lines::Single, "abcdefg".to_owned(), DummyClipboardContext::new("")); textinput.adjust_horizontal(2, Selection::NotSelected); textinput.adjust_horizontal(2, Selection::Selected); @@ -66,7 +68,7 @@ fn test_textinput_replace_selection() { #[test] fn test_textinput_current_line_length() { - let mut textinput = TextInput::new(Lines::Multiple, "abc\nde\nf".to_owned(), None); + let mut textinput = TextInput::new(Lines::Multiple, "abc\nde\nf".to_owned(), DummyClipboardContext::new("")); assert_eq!(textinput.current_line_length(), 3); textinput.adjust_vertical(1, Selection::NotSelected); @@ -78,7 +80,7 @@ fn test_textinput_current_line_length() { #[test] fn test_textinput_adjust_vertical() { - let mut textinput = TextInput::new(Lines::Multiple, "abc\nde\nf".to_owned(), None); + let mut textinput = TextInput::new(Lines::Multiple, "abc\nde\nf".to_owned(), DummyClipboardContext::new("")); textinput.adjust_horizontal(3, Selection::NotSelected); textinput.adjust_vertical(1, Selection::NotSelected); assert_eq!(textinput.edit_point.line, 1); @@ -95,7 +97,7 @@ fn test_textinput_adjust_vertical() { #[test] fn test_textinput_adjust_horizontal() { - let mut textinput = TextInput::new(Lines::Multiple, "abc\nde\nf".to_owned(), None); + let mut textinput = TextInput::new(Lines::Multiple, "abc\nde\nf".to_owned(), DummyClipboardContext::new("")); textinput.adjust_horizontal(4, Selection::NotSelected); assert_eq!(textinput.edit_point.line, 1); assert_eq!(textinput.edit_point.index, 0); @@ -115,12 +117,12 @@ fn test_textinput_adjust_horizontal() { #[test] fn test_textinput_handle_return() { - let mut single_line_textinput = TextInput::new(Lines::Single, "abcdef".to_owned(), None); + let mut single_line_textinput = TextInput::new(Lines::Single, "abcdef".to_owned(), DummyClipboardContext::new("")); single_line_textinput.adjust_horizontal(3, Selection::NotSelected); single_line_textinput.handle_return(); assert_eq!(single_line_textinput.get_content(), "abcdef"); - let mut multi_line_textinput = TextInput::new(Lines::Multiple, "abcdef".to_owned(), None); + let mut multi_line_textinput = TextInput::new(Lines::Multiple, "abcdef".to_owned(), DummyClipboardContext::new("")); multi_line_textinput.adjust_horizontal(3, Selection::NotSelected); multi_line_textinput.handle_return(); assert_eq!(multi_line_textinput.get_content(), "abc\ndef"); @@ -128,7 +130,7 @@ fn test_textinput_handle_return() { #[test] fn test_textinput_select_all() { - let mut textinput = TextInput::new(Lines::Multiple, "abc\nde\nf".to_owned(), None); + let mut textinput = TextInput::new(Lines::Multiple, "abc\nde\nf".to_owned(), DummyClipboardContext::new("")); assert_eq!(textinput.edit_point.line, 0); assert_eq!(textinput.edit_point.index, 0); @@ -139,16 +141,16 @@ fn test_textinput_select_all() { #[test] fn test_textinput_get_content() { - let single_line_textinput = TextInput::new(Lines::Single, "abcdefg".to_owned(), None); + let single_line_textinput = TextInput::new(Lines::Single, "abcdefg".to_owned(), DummyClipboardContext::new("")); assert_eq!(single_line_textinput.get_content(), "abcdefg"); - let multi_line_textinput = TextInput::new(Lines::Multiple, "abc\nde\nf".to_owned(), None); + let multi_line_textinput = TextInput::new(Lines::Multiple, "abc\nde\nf".to_owned(), DummyClipboardContext::new("")); assert_eq!(multi_line_textinput.get_content(), "abc\nde\nf"); } #[test] fn test_textinput_set_content() { - let mut textinput = TextInput::new(Lines::Multiple, "abc\nde\nf".to_owned(), None); + let mut textinput = TextInput::new(Lines::Multiple, "abc\nde\nf".to_owned(), DummyClipboardContext::new("")); assert_eq!(textinput.get_content(), "abc\nde\nf"); textinput.set_content("abc\nf".to_owned()); @@ -165,3 +167,11 @@ fn test_textinput_set_content() { assert_eq!(textinput.edit_point.index, 2); } +#[test] +fn test_clipboard_paste() { + let mut textinput = TextInput::new(Lines::Single, "defg".to_owned(), DummyClipboardContext::new("abc")); + assert_eq!(textinput.get_content(), "defg"); + assert_eq!(textinput.edit_point.index, 0); + textinput.handle_keydown_aux(Key::V, CONTROL); + assert_eq!(textinput.get_content(), "abcdefg"); +}