diff options
author | Gae24 <96017547+Gae24@users.noreply.github.com> | 2025-01-15 20:45:29 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-01-15 19:45:29 +0000 |
commit | d470f219b1cb80f50bb9050a7649627397f7a5d9 (patch) | |
tree | ab726a47db048f1a14edab25d686f2c2b10e52d5 /components/script/textinput.rs | |
parent | cd9e831e91e7587a71c5fa401b3721b5cfad8f43 (diff) | |
download | servo-d470f219b1cb80f50bb9050a7649627397f7a5d9.tar.gz servo-d470f219b1cb80f50bb9050a7649627397f7a5d9.zip |
Implement Clipboard Event Api (#33576)
* implement ClipboardEvent interface
Signed-off-by: Gae24 <96017547+Gae24@users.noreply.github.com>
* draft implementation of clipboard events
Signed-off-by: Gae24 <96017547+Gae24@users.noreply.github.com>
* handle received clipboard events inside html elemtents
Signed-off-by: Gae24 <96017547+Gae24@users.noreply.github.com>
* use rustdoc style
Signed-off-by: Gae24 <96017547+Gae24@users.noreply.github.com>
* fix compilation errors due to rebase
Signed-off-by: Gae24 <96017547+Gae24@users.noreply.github.com>
* update arboard crate
Signed-off-by: Gae24 <96017547+Gae24@users.noreply.github.com>
* improve paste events
Signed-off-by: Gae24 <96017547+Gae24@users.noreply.github.com>
* code cleanup
revert arboard crate's update, handle text only
Signed-off-by: Gae24 <96017547+Gae24@users.noreply.github.com>
* restrict visibility of some methods to script crate
Signed-off-by: Gae24 <96017547+Gae24@users.noreply.github.com>
* propagate CanGc argument
Signed-off-by: Gae24 <96017547+Gae24@users.noreply.github.com>
* simplify handle_clipboard_msg
Signed-off-by: Gae24 <96017547+Gae24@users.noreply.github.com>
* remove code duplication
Signed-off-by: Gae24 <96017547+Gae24@users.noreply.github.com>
* fix potential borrow hazard
Signed-off-by: Gae24 <96017547+Gae24@users.noreply.github.com>
* add clipboard_event pref, restore unit test code
Signed-off-by: Gae24 <96017547+Gae24@users.noreply.github.com>
* retrict visibility of some document's methods
Signed-off-by: Gae24 <96017547+Gae24@users.noreply.github.com>
* check if clipboardevent is trusted
Signed-off-by: Gae24 <96017547+Gae24@users.noreply.github.com>
* enable clipboardevent
Signed-off-by: Gae24 <96017547+Gae24@users.noreply.github.com>
* fix compilation for egl ports
Signed-off-by: Gae24 <96017547+Gae24@users.noreply.github.com>
---------
Signed-off-by: Gae24 <96017547+Gae24@users.noreply.github.com>
Diffstat (limited to 'components/script/textinput.rs')
-rw-r--r-- | components/script/textinput.rs | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/components/script/textinput.rs b/components/script/textinput.rs index 338303fc7b8..d59cd5b6a5d 100644 --- a/components/script/textinput.rs +++ b/components/script/textinput.rs @@ -10,12 +10,21 @@ use std::default::Default; use std::ops::{Add, AddAssign, Range}; use keyboard_types::{Key, KeyState, Modifiers, ShortcutMatcher}; +use script_traits::ScriptToConstellationChan; use unicode_segmentation::UnicodeSegmentation; use crate::clipboard_provider::ClipboardProvider; +use crate::dom::bindings::cell::DomRefCell; +use crate::dom::bindings::codegen::Bindings::EventBinding::Event_Binding::EventMethods; +use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::str::DOMString; use crate::dom::compositionevent::CompositionEvent; +use crate::dom::event::Event; use crate::dom::keyboardevent::KeyboardEvent; +use crate::dom::node::NodeTraits; +use crate::dom::types::ClipboardEvent; +use crate::drag_data_store::{DragDataStore, Kind}; +use crate::script_runtime::CanGc; #[derive(Clone, Copy, PartialEq)] pub enum Selection { @@ -1128,4 +1137,88 @@ impl<T: ClipboardProvider> TextInput<T> { .fold(UTF8Bytes::zero(), |acc, x| acc + x.len_utf8()); self.edit_point.index = byte_offset; } + + fn paste_contents(&mut self, drag_data_store: &DragDataStore) { + for item in drag_data_store.iter_item_list() { + if let Kind::Text(string) = item { + self.insert_string(string.data()); + } + } + } +} + +/// <https://www.w3.org/TR/clipboard-apis/#clipboard-actions> step 3 +pub(crate) fn handle_text_clipboard_action( + owning_node: &impl NodeTraits, + textinput: &DomRefCell<TextInput<ScriptToConstellationChan>>, + event: &ClipboardEvent, + can_gc: CanGc, +) -> bool { + let e = event.upcast::<Event>(); + + if !e.IsTrusted() { + return false; + } + + // Step 3 + match e.Type().str() { + "copy" => { + let selection = textinput.borrow().get_selection_text(); + + // Step 3.1 Copy the selected contents, if any, to the clipboard + if let Some(text) = selection { + textinput + .borrow_mut() + .clipboard_provider + .set_clipboard_contents(text); + } + + // Step 3.2 Fire a clipboard event named clipboardchange + owning_node + .owner_document() + .fire_clipboardchange_event(can_gc); + }, + "cut" => { + let selection = textinput.borrow().get_selection_text(); + + // Step 3.1 If there is a selection in an editable context where cutting is enabled, then + if let Some(text) = selection { + // Step 3.1.1 Copy the selected contents, if any, to the clipboard + textinput + .borrow_mut() + .clipboard_provider + .set_clipboard_contents(text); + + // Step 3.1.2 Remove the contents of the selection from the document and collapse the selection. + textinput.borrow_mut().delete_char(Direction::Backward); + + // Step 3.1.3 Fire a clipboard event named clipboardchange + owning_node + .owner_document() + .fire_clipboardchange_event(can_gc); + + // Step 3.1.4 Queue tasks to fire any events that should fire due to the modification. + } else { + // Step 3.2 Else, if there is no selection or the context is not editable, then + return false; + } + }, + "paste" => { + // Step 3.1 If there is a selection or cursor in an editable context where pasting is enabled, then + if let Some(data) = event.get_clipboard_data() { + // Step 3.1.1 Insert the most suitable content found on the clipboard, if any, into the context. + let drag_data_store = data.data_store().expect("This shouldn't fail"); + textinput.borrow_mut().paste_contents(&drag_data_store); + + // Step 3.1.2 Queue tasks to fire any events that should fire due to the modification. + } else { + // Step 3.2 Else return false. + return false; + } + }, + _ => (), + } + + //Step 5 + true } |