diff --git a/components/script/Cargo.toml b/components/script/Cargo.toml index 63eaea80142e..f304ad155a69 100644 --- a/components/script/Cargo.toml +++ b/components/script/Cargo.toml @@ -69,6 +69,12 @@ git = "https://github.com/servo/string-cache" [dependencies.string_cache_plugin] git = "https://github.com/servo/string-cache" +[dependencies.xlib] +git = "https://github.com/servo/rust-xlib" + +[dependencies.clipboard] +git = "https://github.com/aweinstock314/rust-x11-clipboard" + [dependencies] encoding = "0.2" url = "0.2.16" diff --git a/components/script/lib.rs b/components/script/lib.rs index b9f4b42f84dc..f9a663217678 100644 --- a/components/script/lib.rs +++ b/components/script/lib.rs @@ -52,6 +52,7 @@ extern crate style; extern crate url; extern crate uuid; extern crate string_cache; +extern crate clipboard; pub mod cors; diff --git a/components/script/textinput.rs b/components/script/textinput.rs index c26549bff732..85bedec22d8b 100644 --- a/components/script/textinput.rs +++ b/components/script/textinput.rs @@ -14,6 +14,8 @@ use std::cmp::{min, max}; use std::default::Default; use std::num::SignedInt; +use clipboard::ClipboardContext; + #[derive(Copy, PartialEq)] pub enum Selection { Selected, @@ -29,6 +31,8 @@ pub struct TextPoint { pub index: usize, } +no_jsmanaged_fields!(ClipboardContext); + /// Encapsulated state for handling keyboard input in a single or multiline text input control. #[jstraceable] pub struct TextInput { @@ -40,6 +44,8 @@ pub struct TextInput { selection_begin: Option, /// Is this a multiline input? multiline: bool, + /// Means of accessing the clipboard + clipboard_ctx: ClipboardContext, } /// Resulting action to be taken by the owner of a text input that is handling an event. @@ -93,6 +99,7 @@ impl TextInput { edit_point: Default::default(), selection_begin: None, multiline: lines == Lines::Multiple, + clipboard_ctx: ClipboardContext::new().unwrap(), }; i.set_content(initial); i @@ -118,6 +125,15 @@ impl TextInput { self.replace_selection(ch.to_string()); } + /// Insert a string at the current editing point + fn insert_string(&mut self, s: &str) { + // it looks like this could be made performant by avoiding some redundant + // selection-related checks, but use the simple implementation for now + for ch in s.chars() { + self.insert_char(ch); + } + } + pub fn get_sorted_selection(&self) -> (TextPoint, TextPoint) { let begin = self.selection_begin.unwrap(); let end = self.edit_point; @@ -282,10 +298,15 @@ impl TextInput { self.select_all(); KeyReaction::Nothing }, + "v" if is_control_key(event) => { + let contents = self.clipboard_ctx.get_contents().unwrap(); + self.insert_string(contents.as_slice()); + KeyReaction::DispatchInput + }, // printable characters have single-character key values c if c.len() == 1 => { self.insert_char(c.char_at(0)); - return KeyReaction::DispatchInput; + KeyReaction::DispatchInput } "Space" => { self.insert_char(' '); diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock index 21b1955664d4..a4810689b052 100644 --- a/components/servo/Cargo.lock +++ b/components/servo/Cargo.lock @@ -822,6 +822,7 @@ dependencies = [ "url 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", "uuid 0.1.11 (git+https://github.com/rust-lang/uuid)", + "xlib 0.1.0 (git+https://github.com/servo/rust-xlib)", ] [[package]]