mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
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>
This commit is contained in:
parent
cd9e831e91
commit
d470f219b1
24 changed files with 581 additions and 26 deletions
97
components/script/dom/clipboardevent.rs
Normal file
97
components/script/dom/clipboardevent.rs
Normal file
|
@ -0,0 +1,97 @@
|
|||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use dom_struct::dom_struct;
|
||||
use js::rust::HandleObject;
|
||||
|
||||
use crate::dom::bindings::codegen::Bindings::ClipboardEventBinding::{
|
||||
ClipboardEventInit, ClipboardEventMethods,
|
||||
};
|
||||
use crate::dom::bindings::codegen::Bindings::EventBinding::EventMethods;
|
||||
use crate::dom::bindings::inheritance::Castable;
|
||||
use crate::dom::bindings::reflector::reflect_dom_object_with_proto;
|
||||
use crate::dom::bindings::root::{DomRoot, MutNullableDom};
|
||||
use crate::dom::bindings::str::DOMString;
|
||||
use crate::dom::datatransfer::DataTransfer;
|
||||
use crate::dom::event::{Event, EventBubbles, EventCancelable};
|
||||
use crate::dom::window::Window;
|
||||
use crate::script_runtime::CanGc;
|
||||
|
||||
#[dom_struct]
|
||||
pub struct ClipboardEvent {
|
||||
event: Event,
|
||||
clipboard_data: MutNullableDom<DataTransfer>,
|
||||
}
|
||||
|
||||
impl ClipboardEvent {
|
||||
fn new_inherited() -> ClipboardEvent {
|
||||
ClipboardEvent {
|
||||
event: Event::new_inherited(),
|
||||
clipboard_data: MutNullableDom::new(None),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn new(
|
||||
window: &Window,
|
||||
proto: Option<HandleObject>,
|
||||
type_: DOMString,
|
||||
can_bubble: EventBubbles,
|
||||
cancelable: EventCancelable,
|
||||
clipboard_data: Option<&DataTransfer>,
|
||||
can_gc: CanGc,
|
||||
) -> DomRoot<ClipboardEvent> {
|
||||
let ev = reflect_dom_object_with_proto(
|
||||
Box::new(ClipboardEvent::new_inherited()),
|
||||
window,
|
||||
proto,
|
||||
can_gc,
|
||||
);
|
||||
ev.upcast::<Event>()
|
||||
.InitEvent(type_, bool::from(can_bubble), bool::from(cancelable));
|
||||
ev.clipboard_data.set(clipboard_data);
|
||||
ev
|
||||
}
|
||||
|
||||
pub(crate) fn set_clipboard_data(&self, clipboard_data: Option<&DataTransfer>) {
|
||||
self.clipboard_data.set(clipboard_data);
|
||||
}
|
||||
|
||||
pub(crate) fn get_clipboard_data(&self) -> Option<DomRoot<DataTransfer>> {
|
||||
self.clipboard_data.get()
|
||||
}
|
||||
}
|
||||
|
||||
impl ClipboardEventMethods<crate::DomTypeHolder> for ClipboardEvent {
|
||||
/// <https://www.w3.org/TR/clipboard-apis/#dom-clipboardevent-clipboardevent>
|
||||
fn Constructor(
|
||||
window: &Window,
|
||||
proto: Option<HandleObject>,
|
||||
can_gc: CanGc,
|
||||
type_: DOMString,
|
||||
init: &ClipboardEventInit,
|
||||
) -> DomRoot<ClipboardEvent> {
|
||||
// Missing composed field
|
||||
let bubbles = EventBubbles::from(init.parent.bubbles);
|
||||
let cancelable = EventCancelable::from(init.parent.cancelable);
|
||||
ClipboardEvent::new(
|
||||
window,
|
||||
proto,
|
||||
type_,
|
||||
bubbles,
|
||||
cancelable,
|
||||
init.clipboardData.as_deref(),
|
||||
can_gc,
|
||||
)
|
||||
}
|
||||
|
||||
/// <https://www.w3.org/TR/clipboard-apis/#dom-clipboardevent-clipboarddata>
|
||||
fn GetClipboardData(&self) -> Option<DomRoot<DataTransfer>> {
|
||||
self.clipboard_data.get()
|
||||
}
|
||||
|
||||
/// <https://dom.spec.whatwg.org/#dom-event-istrusted>
|
||||
fn IsTrusted(&self) -> bool {
|
||||
self.event.IsTrusted()
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::cell::{Ref, RefCell};
|
||||
use std::rc::Rc;
|
||||
|
||||
use dom_struct::dom_struct;
|
||||
|
@ -64,11 +64,8 @@ impl DataTransfer {
|
|||
window: &Window,
|
||||
proto: Option<HandleObject>,
|
||||
can_gc: CanGc,
|
||||
data_store: Rc<RefCell<Option<DragDataStore>>>,
|
||||
) -> DomRoot<DataTransfer> {
|
||||
let mut drag_data_store = DragDataStore::new();
|
||||
drag_data_store.set_mode(Mode::ReadWrite);
|
||||
|
||||
let data_store = Rc::new(RefCell::new(Some(drag_data_store)));
|
||||
let item_list = DataTransferItemList::new(window, Rc::clone(&data_store));
|
||||
|
||||
reflect_dom_object_with_proto(
|
||||
|
@ -78,6 +75,18 @@ impl DataTransfer {
|
|||
can_gc,
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn new(
|
||||
window: &Window,
|
||||
data_store: Rc<RefCell<Option<DragDataStore>>>,
|
||||
can_gc: CanGc,
|
||||
) -> DomRoot<DataTransfer> {
|
||||
Self::new_with_proto(window, None, can_gc, data_store)
|
||||
}
|
||||
|
||||
pub(crate) fn data_store(&self) -> Option<Ref<DragDataStore>> {
|
||||
Ref::filter_map(self.data_store.borrow(), |data_store| data_store.as_ref()).ok()
|
||||
}
|
||||
}
|
||||
|
||||
impl DataTransferMethods<crate::DomTypeHolder> for DataTransfer {
|
||||
|
@ -87,7 +96,12 @@ impl DataTransferMethods<crate::DomTypeHolder> for DataTransfer {
|
|||
proto: Option<HandleObject>,
|
||||
can_gc: CanGc,
|
||||
) -> DomRoot<DataTransfer> {
|
||||
DataTransfer::new_with_proto(window, proto, can_gc)
|
||||
let mut drag_data_store = DragDataStore::new();
|
||||
drag_data_store.set_mode(Mode::ReadWrite);
|
||||
|
||||
let data_store = Rc::new(RefCell::new(Some(drag_data_store)));
|
||||
|
||||
DataTransfer::new_with_proto(window, proto, can_gc, data_store)
|
||||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-datatransfer-dropeffect>
|
||||
|
|
|
@ -48,8 +48,9 @@ use profile_traits::ipc as profile_ipc;
|
|||
use profile_traits::time::{TimerMetadata, TimerMetadataFrameType, TimerMetadataReflowType};
|
||||
use script_layout_interface::{PendingRestyle, TrustedNodeAddress};
|
||||
use script_traits::{
|
||||
AnimationState, AnimationTickType, CompositorEvent, DocumentActivity, MouseButton,
|
||||
MouseEventType, ScriptMsg, TouchEventType, TouchId, UntrustedNodeAddress, WheelDelta,
|
||||
AnimationState, AnimationTickType, ClipboardEventType, CompositorEvent, DocumentActivity,
|
||||
MouseButton, MouseEventType, ScriptMsg, TouchEventType, TouchId, UntrustedNodeAddress,
|
||||
WheelDelta,
|
||||
};
|
||||
use servo_arc::Arc;
|
||||
use servo_atoms::Atom;
|
||||
|
@ -111,11 +112,13 @@ use crate::dom::bindings::xmlname::{
|
|||
namespace_from_domstring, validate_and_extract, xml_name_type,
|
||||
};
|
||||
use crate::dom::cdatasection::CDATASection;
|
||||
use crate::dom::clipboardevent::ClipboardEvent;
|
||||
use crate::dom::comment::Comment;
|
||||
use crate::dom::compositionevent::CompositionEvent;
|
||||
use crate::dom::cssstylesheet::CSSStyleSheet;
|
||||
use crate::dom::customelementregistry::CustomElementDefinition;
|
||||
use crate::dom::customevent::CustomEvent;
|
||||
use crate::dom::datatransfer::DataTransfer;
|
||||
use crate::dom::documentfragment::DocumentFragment;
|
||||
use crate::dom::documentorshadowroot::{DocumentOrShadowRoot, StyleSheetInDocument};
|
||||
use crate::dom::documenttype::DocumentType;
|
||||
|
@ -182,6 +185,7 @@ use crate::dom::wheelevent::WheelEvent;
|
|||
use crate::dom::window::Window;
|
||||
use crate::dom::windowproxy::WindowProxy;
|
||||
use crate::dom::xpathevaluator::XPathEvaluator;
|
||||
use crate::drag_data_store::{DragDataStore, Kind, Mode, PlainString};
|
||||
use crate::fetch::FetchCanceller;
|
||||
use crate::iframe_collection::IFrameCollection;
|
||||
use crate::messaging::{CommonScriptMsg, MainThreadScriptMsg};
|
||||
|
@ -1443,6 +1447,198 @@ impl Document {
|
|||
event.fire(target, can_gc);
|
||||
}
|
||||
|
||||
/// <https://www.w3.org/TR/clipboard-apis/#clipboard-actions>
|
||||
pub(crate) fn handle_clipboard_action(
|
||||
&self,
|
||||
action: ClipboardEventType,
|
||||
can_gc: CanGc,
|
||||
) -> bool {
|
||||
// The script_triggered flag is set if the action runs because of a script, e.g. document.execCommand()
|
||||
let script_triggered = false;
|
||||
|
||||
// The script_may_access_clipboard flag is set
|
||||
// if action is paste and the script thread is allowed to read from clipboard or
|
||||
// if action is copy or cut and the script thread is allowed to modify the clipboard
|
||||
let script_may_access_clipboard = false;
|
||||
|
||||
// Step 1 If the script-triggered flag is set and the script-may-access-clipboard flag is unset
|
||||
if script_triggered && !script_may_access_clipboard {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Step 2 Fire a clipboard event
|
||||
let event = ClipboardEvent::new(
|
||||
&self.window,
|
||||
None,
|
||||
DOMString::from(action.as_str()),
|
||||
EventBubbles::Bubbles,
|
||||
EventCancelable::Cancelable,
|
||||
None,
|
||||
can_gc,
|
||||
);
|
||||
self.fire_clipboard_event(&event, action, can_gc);
|
||||
|
||||
// Step 3 If a script doesn't call preventDefault()
|
||||
// the event will be handled inside target's VirtualMethods::handle_event
|
||||
|
||||
let e = event.upcast::<Event>();
|
||||
|
||||
if !e.IsTrusted() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Step 4 If the event was canceled, then
|
||||
if e.DefaultPrevented() {
|
||||
match e.Type().str() {
|
||||
"copy" => {
|
||||
// Step 4.1 Call the write content to the clipboard algorithm,
|
||||
// passing on the DataTransferItemList items, a clear-was-called flag and a types-to-clear list.
|
||||
if let Some(clipboard_data) = event.get_clipboard_data() {
|
||||
let drag_data_store =
|
||||
clipboard_data.data_store().expect("This shouldn't fail");
|
||||
self.write_content_to_the_clipboard(&drag_data_store);
|
||||
}
|
||||
},
|
||||
"cut" => {
|
||||
// Step 4.1 Call the write content to the clipboard algorithm,
|
||||
// passing on the DataTransferItemList items, a clear-was-called flag and a types-to-clear list.
|
||||
if let Some(clipboard_data) = event.get_clipboard_data() {
|
||||
let drag_data_store =
|
||||
clipboard_data.data_store().expect("This shouldn't fail");
|
||||
self.write_content_to_the_clipboard(&drag_data_store);
|
||||
}
|
||||
|
||||
// Step 4.2 Fire a clipboard event named clipboardchange
|
||||
self.fire_clipboardchange_event(can_gc);
|
||||
},
|
||||
"paste" => return false,
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
//Step 5
|
||||
true
|
||||
}
|
||||
|
||||
/// <https://www.w3.org/TR/clipboard-apis/#fire-a-clipboard-event>
|
||||
fn fire_clipboard_event(
|
||||
&self,
|
||||
event: &ClipboardEvent,
|
||||
action: ClipboardEventType,
|
||||
can_gc: CanGc,
|
||||
) {
|
||||
// Step 1 Let clear_was_called be false
|
||||
// Step 2 Let types_to_clear an empty list
|
||||
let mut drag_data_store = DragDataStore::new();
|
||||
|
||||
// Step 4 let clipboard-entry be the sequence number of clipboard content, null if the OS doesn't support it.
|
||||
|
||||
// Step 5 let trusted be true if the event is generated by the user agent, false otherwise
|
||||
let trusted = true;
|
||||
|
||||
// Step 6 if the context is editable:
|
||||
let focused = self.get_focused_element();
|
||||
let body = self.GetBody();
|
||||
|
||||
let target = match (&focused, &body) {
|
||||
(Some(focused), _) => focused.upcast(),
|
||||
(&None, Some(body)) => body.upcast(),
|
||||
(&None, &None) => self.window.upcast(),
|
||||
};
|
||||
// Step 6.2 else TODO require Selection see https://github.com/w3c/clipboard-apis/issues/70
|
||||
|
||||
// Step 7
|
||||
match action {
|
||||
ClipboardEventType::Copy | ClipboardEventType::Cut => {
|
||||
// Step 7.2.1
|
||||
drag_data_store.set_mode(Mode::ReadWrite);
|
||||
},
|
||||
ClipboardEventType::Paste(ref contents) => {
|
||||
// Step 7.1.1
|
||||
drag_data_store.set_mode(Mode::ReadOnly);
|
||||
// Step 7.1.2 If trusted or the implementation gives script-generated events access to the clipboard
|
||||
if trusted {
|
||||
// Step 7.1.2.1 For each clipboard-part on the OS clipboard:
|
||||
|
||||
// Step 7.1.2.1.1 If clipboard-part contains plain text, then
|
||||
let plain_string = PlainString::new(
|
||||
DOMString::from_string(contents.to_string()),
|
||||
DOMString::from("text/plain"),
|
||||
);
|
||||
let _ = drag_data_store.add(Kind::Text(plain_string));
|
||||
|
||||
// Step 7.1.2.1.2 TODO If clipboard-part represents file references, then for each file reference
|
||||
// Step 7.1.2.1.3 TODO If clipboard-part contains HTML- or XHTML-formatted text then
|
||||
|
||||
// Step 7.1.3 Update clipboard-event-data’s files to match clipboard-event-data’s items
|
||||
// Step 7.1.4 Update clipboard-event-data’s types to match clipboard-event-data’s items
|
||||
}
|
||||
},
|
||||
ClipboardEventType::Change => (),
|
||||
}
|
||||
|
||||
// Step 3
|
||||
let clipboard_event_data = DataTransfer::new(
|
||||
&self.window,
|
||||
Rc::new(RefCell::new(Some(drag_data_store))),
|
||||
can_gc,
|
||||
);
|
||||
|
||||
// Step 8
|
||||
event.set_clipboard_data(Some(&clipboard_event_data));
|
||||
let event = event.upcast::<Event>();
|
||||
// Step 9
|
||||
event.set_trusted(trusted);
|
||||
// Step 10 Set event’s composed to true.
|
||||
// Step 11
|
||||
event.dispatch(target, false, can_gc);
|
||||
}
|
||||
|
||||
pub(crate) fn fire_clipboardchange_event(&self, can_gc: CanGc) {
|
||||
let clipboardchange_event = ClipboardEvent::new(
|
||||
&self.window,
|
||||
None,
|
||||
DOMString::from("clipboardchange"),
|
||||
EventBubbles::Bubbles,
|
||||
EventCancelable::Cancelable,
|
||||
None,
|
||||
can_gc,
|
||||
);
|
||||
self.fire_clipboard_event(&clipboardchange_event, ClipboardEventType::Change, can_gc);
|
||||
}
|
||||
|
||||
/// <https://www.w3.org/TR/clipboard-apis/#write-content-to-the-clipboard>
|
||||
fn write_content_to_the_clipboard(&self, drag_data_store: &DragDataStore) {
|
||||
// Step 1
|
||||
if drag_data_store.list_len() > 0 {
|
||||
// Step 1.1 Clear the clipboard.
|
||||
self.send_to_embedder(EmbedderMsg::ClearClipboardContents);
|
||||
// Step 1.2
|
||||
for item in drag_data_store.iter_item_list() {
|
||||
match item {
|
||||
Kind::Text(string) => {
|
||||
// Step 1.2.1.1 Ensure encoding is correct per OS and locale conventions
|
||||
// Step 1.2.1.2 Normalize line endings according to platform conventions
|
||||
// Step 1.2.1.3
|
||||
self.send_to_embedder(EmbedderMsg::SetClipboardContents(string.data()));
|
||||
},
|
||||
Kind::File(_) => {
|
||||
// Step 1.2.2 If data is of a type listed in the mandatory data types list, then
|
||||
// Step 1.2.2.1 Place part on clipboard with the appropriate OS clipboard format description
|
||||
// Step 1.2.3 Else this is left to the implementation
|
||||
},
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Step 2.1
|
||||
if drag_data_store.clear_was_called {
|
||||
// Step 2.1.1 If types-to-clear list is empty, clear the clipboard
|
||||
self.send_to_embedder(EmbedderMsg::ClearClipboardContents);
|
||||
// Step 2.1.2 Else remove the types in the list from the clipboard
|
||||
// As of now this can't be done with Arboard, and it's possible that will be removed from the spec
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
pub(crate) unsafe fn handle_mouse_move_event(
|
||||
&self,
|
||||
|
|
|
@ -48,6 +48,7 @@ use crate::dom::bindings::inheritance::Castable;
|
|||
use crate::dom::bindings::reflector::DomObject;
|
||||
use crate::dom::bindings::root::{DomRoot, LayoutDom, MutNullableDom};
|
||||
use crate::dom::bindings::str::{DOMString, USVString};
|
||||
use crate::dom::clipboardevent::ClipboardEvent;
|
||||
use crate::dom::compositionevent::CompositionEvent;
|
||||
use crate::dom::document::Document;
|
||||
use crate::dom::element::{AttributeMutation, Element, LayoutElementHelpers};
|
||||
|
@ -79,7 +80,10 @@ use crate::textinput::KeyReaction::{
|
|||
DispatchInput, Nothing, RedrawSelection, TriggerDefaultAction,
|
||||
};
|
||||
use crate::textinput::Lines::Single;
|
||||
use crate::textinput::{Direction, SelectionDirection, TextInput, UTF16CodeUnits, UTF8Bytes};
|
||||
use crate::textinput::{
|
||||
handle_text_clipboard_action, Direction, SelectionDirection, TextInput, UTF16CodeUnits,
|
||||
UTF8Bytes,
|
||||
};
|
||||
|
||||
const DEFAULT_SUBMIT_VALUE: &str = "Submit";
|
||||
const DEFAULT_RESET_VALUE: &str = "Reset";
|
||||
|
@ -2648,6 +2652,10 @@ impl VirtualMethods for HTMLInputElement {
|
|||
}
|
||||
event.mark_as_handled();
|
||||
}
|
||||
} else if let Some(clipboard_event) = event.downcast::<ClipboardEvent>() {
|
||||
if !event.DefaultPrevented() {
|
||||
handle_text_clipboard_action(self, &self.textinput, clipboard_event, CanGc::note());
|
||||
}
|
||||
}
|
||||
|
||||
self.validity_state()
|
||||
|
|
|
@ -23,6 +23,7 @@ use crate::dom::bindings::error::ErrorResult;
|
|||
use crate::dom::bindings::inheritance::Castable;
|
||||
use crate::dom::bindings::root::{DomRoot, LayoutDom, MutNullableDom};
|
||||
use crate::dom::bindings::str::DOMString;
|
||||
use crate::dom::clipboardevent::ClipboardEvent;
|
||||
use crate::dom::compositionevent::CompositionEvent;
|
||||
use crate::dom::document::Document;
|
||||
use crate::dom::element::{AttributeMutation, Element, LayoutElementHelpers};
|
||||
|
@ -42,7 +43,8 @@ use crate::dom::validitystate::{ValidationFlags, ValidityState};
|
|||
use crate::dom::virtualmethods::VirtualMethods;
|
||||
use crate::script_runtime::CanGc;
|
||||
use crate::textinput::{
|
||||
Direction, KeyReaction, Lines, SelectionDirection, TextInput, UTF16CodeUnits, UTF8Bytes,
|
||||
handle_text_clipboard_action, Direction, KeyReaction, Lines, SelectionDirection, TextInput,
|
||||
UTF16CodeUnits, UTF8Bytes,
|
||||
};
|
||||
|
||||
#[dom_struct]
|
||||
|
@ -675,6 +677,10 @@ impl VirtualMethods for HTMLTextAreaElement {
|
|||
}
|
||||
event.mark_as_handled();
|
||||
}
|
||||
} else if let Some(clipboard_event) = event.downcast::<ClipboardEvent>() {
|
||||
if !event.DefaultPrevented() {
|
||||
handle_text_clipboard_action(self, &self.textinput, clipboard_event, CanGc::note());
|
||||
}
|
||||
}
|
||||
|
||||
self.validity_state()
|
||||
|
|
|
@ -254,6 +254,7 @@ pub(crate) mod channelmergernode;
|
|||
pub(crate) mod channelsplitternode;
|
||||
pub(crate) mod characterdata;
|
||||
pub(crate) mod client;
|
||||
pub(crate) mod clipboardevent;
|
||||
pub(crate) mod closeevent;
|
||||
pub(crate) mod comment;
|
||||
pub(crate) mod compositionevent;
|
||||
|
|
15
components/script/dom/webidls/ClipboardEvent.webidl
Normal file
15
components/script/dom/webidls/ClipboardEvent.webidl
Normal file
|
@ -0,0 +1,15 @@
|
|||
/* 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/. */
|
||||
|
||||
// https://w3c.github.io/clipboard-apis/
|
||||
|
||||
[Exposed=Window, Pref="dom_clipboardevent_enabled"]
|
||||
interface ClipboardEvent : Event {
|
||||
constructor (DOMString type, optional ClipboardEventInit eventInitDict = {});
|
||||
readonly attribute DataTransfer? clipboardData;
|
||||
};
|
||||
|
||||
dictionary ClipboardEventInit : EventInit {
|
||||
DataTransfer? clipboardData = null;
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue