mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
Add set_clipboard_context function and relevant plumbing. Use Option more consistantly (less unwraps) in textinput's selection handling.
This commit is contained in:
parent
52c2049f2a
commit
f86252a60b
5 changed files with 83 additions and 48 deletions
|
@ -475,6 +475,13 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
|
||||||
);
|
);
|
||||||
sender.send(result).unwrap();
|
sender.send(result).unwrap();
|
||||||
}
|
}
|
||||||
|
ConstellationMsg::SetClipboardContents(s) => {
|
||||||
|
if let Some(ref ctx) = self.clipboard_ctx {
|
||||||
|
if let Err(e) = ctx.set_contents(s) {
|
||||||
|
debug!("Error setting clipboard contents ({})", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
ConstellationMsg::WebDriverCommand(command) => {
|
ConstellationMsg::WebDriverCommand(command) => {
|
||||||
debug!("constellation got webdriver command message");
|
debug!("constellation got webdriver command message");
|
||||||
self.handle_webdriver_msg(command);
|
self.handle_webdriver_msg(command);
|
||||||
|
|
|
@ -247,6 +247,8 @@ pub enum Msg {
|
||||||
Focus(PipelineId),
|
Focus(PipelineId),
|
||||||
/// Requests that the constellation retrieve the current contents of the clipboard
|
/// Requests that the constellation retrieve the current contents of the clipboard
|
||||||
GetClipboardContents(IpcSender<String>),
|
GetClipboardContents(IpcSender<String>),
|
||||||
|
/// Requests that the constellation set the contents of the clipboard
|
||||||
|
SetClipboardContents(String),
|
||||||
/// Dispatch a webdriver command
|
/// Dispatch a webdriver command
|
||||||
WebDriverCommand(WebDriverCommandMsg),
|
WebDriverCommand(WebDriverCommandMsg),
|
||||||
/// Notifies the constellation that the viewport has been constrained in some manner
|
/// Notifies the constellation that the viewport has been constrained in some manner
|
||||||
|
|
|
@ -13,7 +13,7 @@ pub trait ClipboardProvider {
|
||||||
// blocking method to get the clipboard contents
|
// blocking method to get the clipboard contents
|
||||||
fn clipboard_contents(&mut self) -> String;
|
fn clipboard_contents(&mut self) -> String;
|
||||||
// blocking method to set the clipboard contents
|
// blocking method to set the clipboard contents
|
||||||
fn set_clipboard_contents(&mut self, &str);
|
fn set_clipboard_contents(&mut self, String);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ClipboardProvider for ConstellationChan {
|
impl ClipboardProvider for ConstellationChan {
|
||||||
|
@ -22,8 +22,8 @@ impl ClipboardProvider for ConstellationChan {
|
||||||
self.0.send(ConstellationMsg::GetClipboardContents(tx)).unwrap();
|
self.0.send(ConstellationMsg::GetClipboardContents(tx)).unwrap();
|
||||||
rx.recv().unwrap()
|
rx.recv().unwrap()
|
||||||
}
|
}
|
||||||
fn set_clipboard_contents(&mut self, _: &str) {
|
fn set_clipboard_contents(&mut self, s: String) {
|
||||||
panic!("not yet implemented");
|
self.0.send(ConstellationMsg::SetClipboardContents(s)).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ impl ClipboardProvider for DummyClipboardContext {
|
||||||
fn clipboard_contents(&mut self) -> String {
|
fn clipboard_contents(&mut self) -> String {
|
||||||
self.content.clone()
|
self.content.clone()
|
||||||
}
|
}
|
||||||
fn set_clipboard_contents(&mut self, s: &str) {
|
fn set_clipboard_contents(&mut self, s: String) {
|
||||||
self.content = s.to_owned();
|
self.content = s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,8 +143,8 @@ impl<T: ClipboardProvider> TextInput<T> {
|
||||||
self.replace_selection(s.into());
|
self.replace_selection(s.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_sorted_selection(&self) -> (TextPoint, TextPoint) {
|
pub fn get_sorted_selection(&self) -> Option<(TextPoint, TextPoint)> {
|
||||||
let begin = self.selection_begin.unwrap();
|
self.selection_begin.map(|begin| {
|
||||||
let end = self.edit_point;
|
let end = self.edit_point;
|
||||||
|
|
||||||
if begin.line < end.line || (begin.line == end.line && begin.index < end.index) {
|
if begin.line < end.line || (begin.line == end.line && begin.index < end.index) {
|
||||||
|
@ -152,10 +152,29 @@ impl<T: ClipboardProvider> TextInput<T> {
|
||||||
} else {
|
} else {
|
||||||
(end, begin)
|
(end, begin)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_selection_text(&self) -> Option<String> {
|
||||||
|
self.get_sorted_selection().map(|(begin, end)| {
|
||||||
|
if begin.line != end.line {
|
||||||
|
let mut s = String::new();
|
||||||
|
s.push_str(self.lines[begin.line].slice_chars(begin.index, self.lines[begin.line].len()));
|
||||||
|
for (_, line) in self.lines.iter().enumerate().filter(|&(i,_)| begin.line < i && i < end.line) {
|
||||||
|
s.push_str("\n");
|
||||||
|
s.push_str(line);
|
||||||
|
}
|
||||||
|
s.push_str("\n");
|
||||||
|
s.push_str(self.lines[end.line].slice_chars(0, end.index));
|
||||||
|
s
|
||||||
|
} else {
|
||||||
|
self.lines[begin.line].slice_chars(begin.index, end.index).to_owned()
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn replace_selection(&mut self, insert: String) {
|
pub fn replace_selection(&mut self, insert: String) {
|
||||||
let (begin, end) = self.get_sorted_selection();
|
if let Some((begin, end)) = self.get_sorted_selection() {
|
||||||
self.clear_selection();
|
self.clear_selection();
|
||||||
|
|
||||||
let new_lines = {
|
let new_lines = {
|
||||||
|
@ -189,6 +208,7 @@ impl<T: ClipboardProvider> TextInput<T> {
|
||||||
|
|
||||||
self.lines = new_lines;
|
self.lines = new_lines;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Return the length of the current line under the editing point.
|
/// Return the length of the current line under the editing point.
|
||||||
pub fn current_line_length(&self) -> usize {
|
pub fn current_line_length(&self) -> usize {
|
||||||
|
@ -237,8 +257,7 @@ impl<T: ClipboardProvider> TextInput<T> {
|
||||||
self.selection_begin = Some(self.edit_point);
|
self.selection_begin = Some(self.edit_point);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if self.selection_begin.is_some() {
|
if let Some((begin, end)) = self.get_sorted_selection() {
|
||||||
let (begin, end) = self.get_sorted_selection();
|
|
||||||
self.edit_point = if adjust < 0 {begin} else {end};
|
self.edit_point = if adjust < 0 {begin} else {end};
|
||||||
self.clear_selection();
|
self.clear_selection();
|
||||||
return
|
return
|
||||||
|
@ -308,6 +327,13 @@ impl<T: ClipboardProvider> TextInput<T> {
|
||||||
self.select_all();
|
self.select_all();
|
||||||
KeyReaction::Nothing
|
KeyReaction::Nothing
|
||||||
},
|
},
|
||||||
|
Key::C if is_control_key(mods) => {
|
||||||
|
if let Some(text) = self.get_selection_text() {
|
||||||
|
println!("get_selection_text(): {}", &text);
|
||||||
|
self.clipboard_provider.set_clipboard_contents(text);
|
||||||
|
}
|
||||||
|
KeyReaction::DispatchInput
|
||||||
|
},
|
||||||
Key::V if is_control_key(mods) => {
|
Key::V if is_control_key(mods) => {
|
||||||
let contents = self.clipboard_provider.clipboard_contents();
|
let contents = self.clipboard_provider.clipboard_contents();
|
||||||
self.insert_string(contents);
|
self.insert_string(contents);
|
||||||
|
|
|
@ -50,14 +50,14 @@ fn test_textinput_get_sorted_selection() {
|
||||||
let mut textinput = TextInput::new(Lines::Single, "abcdefg".to_owned(), DummyClipboardContext::new(""));
|
let mut textinput = TextInput::new(Lines::Single, "abcdefg".to_owned(), DummyClipboardContext::new(""));
|
||||||
textinput.adjust_horizontal(2, Selection::NotSelected);
|
textinput.adjust_horizontal(2, Selection::NotSelected);
|
||||||
textinput.adjust_horizontal(2, Selection::Selected);
|
textinput.adjust_horizontal(2, Selection::Selected);
|
||||||
let (begin, end) = textinput.get_sorted_selection();
|
let (begin, end) = textinput.get_sorted_selection().unwrap();
|
||||||
assert_eq!(begin.index, 2);
|
assert_eq!(begin.index, 2);
|
||||||
assert_eq!(end.index, 4);
|
assert_eq!(end.index, 4);
|
||||||
|
|
||||||
textinput.clear_selection();
|
textinput.clear_selection();
|
||||||
|
|
||||||
textinput.adjust_horizontal(-2, Selection::Selected);
|
textinput.adjust_horizontal(-2, Selection::Selected);
|
||||||
let (begin, end) = textinput.get_sorted_selection();
|
let (begin, end) = textinput.get_sorted_selection().unwrap();
|
||||||
assert_eq!(begin.index, 2);
|
assert_eq!(begin.index, 2);
|
||||||
assert_eq!(end.index, 4);
|
assert_eq!(end.index, 4);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue