forked from w3c/clipboard-apis
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.bs
1337 lines (954 loc) · 46.3 KB
/
index.bs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<h1>Clipboard API and events</h1>
<pre class="metadata">
Shortname: clipboard-apis
Level:
Group: webplatform
Status: ED
TR: https://www.w3.org/TR/clipboard-apis/
ED: https://w3c.github.io/clipboard-apis/
Repository: w3c/clipboard-apis
Editor: Gary Kacmarcik, Google, [email protected]
Editor: Grisha Lyukshin, Microsoft, [email protected]
Editor: Hallvord R. M. Steen, Mozilla - emeritus
Abstract:
This document describes APIs for clipboard operations such as copy, cut and
paste in web applications.
</pre>
<pre class="anchors">
urlPrefix: https://html.spec.whatwg.org/multipage/interaction.html#; type: dfn;
text: drag data store mode
text: drag data item kind
text: drag data item type string
text: concept dnd rw
text: concept dnd ro
text: concept dnd p
text: focusable area
text: dom anchor
url: https://html.spec.whatwg.org/multipage/dom.html#the-body-element-2; type: dfn;
text: the body element
urlPrefix: http://www.w3.org/TR/html5/browsers.html#; type: dfn;
text: allowed to show a popup
urlPrefix: https://dom.spec.whatwg.org/#; type: dfn;
text: constructing events
urlPrefix: http://w3c.github.io/editing/contentEditable.html#dfn-; type: dfn;
text: editing host
spec: ecma-262; urlPrefix: http://tc39.github.io/ecma262/
type: dfn
text: Assert; url: sec-algorithm-conventions
text: promise; url: sec-promise-objects
</pre>
<pre class="biblio">
{
"RFC2392": {
"title": "Content-ID and Message-ID Uniform Resource Locators. August 1998. Internet RFC 2392.",
"href": "http://www.ietf.org/rfc/rfc2392.txt",
"authors": [ "E. Levinson" ]
},
"HTMLEA": {
"title": "HTML Editing APIs",
"href": "https://dvcs.w3.org/hg/editing/raw-file/tip/editing.html",
"authors": ["Aryeh Gregor. W3C Editing APIs CG."]
},
"HTMLLS": {
"title": "HTML Living Standard",
"href": "https://html.spec.whatwg.org/multipage/",
"authors": [ "Ian Hickson. WHATWG." ]
},
"MICROSOFT-CLIP-OP": {
"title": "About DHTML Data Transfer. Microsoft Developer Network.",
"href": "http://msdn.microsoft.com/en-us/library/ms537658.aspx"
}
}
</pre>
<h2 id="secintro">Introduction</h2>
<i>This section is non-normative.</i>
This specification defines the common clipboard operations of cutting,
copying and pasting, in such a way that they are exposed to Web Applications
and can be adapted to provide advanced functionalities. Its goal is to
provide for compatibility where possible with existing implementations.
<h2 id="Cases">Use Cases</h2>
<i>This section is non-normative.</i>
There are many use cases for being able to change the default clipboard
operations (cut/copy/paste). We have collected
a few samples to demonstrate possible uses, although these may not all be
supported by this specification.
<h3 id="Rich">Rich content editing</h3>
When copying text which contains hyperlinks or other structure,
it is often useful to be able to reformat the content to preserve
important information.
<h3 id="graphics-semantics">Graphics with built-in semantics</h3>
In order to make web applications which allow the manipulation of rich
text, or of graphic content such as [[SVG]], it is useful to provide a
mechanism that allows for copying more than just the rendered content.
<h3 id="Mathematic">Mathematical information</h3>
With content such as mathematics, simply copying rendered text and pasting
it into another application generally leads to most of the semantics being
lost. MathML often needs to be transformed to be copied as plain text, for
example to make sure "to the power of" is shown with the caret "^" sign
in a formula plain-text input. The XML source could also be placed in the
clipboard with the appropriate transformation occurring at paste time.
<h2 id="terminolofy">Terminology</h2>
The term <dfn>editable context</dfn> means any element that is either an
[=editing host=], a textarea element, or an input element with its type
attribute set to any of "text", "search", "tel",
"url", "email", "password" or "number".
<h2 id="model">Model</h2>
The platform provides a <dfn>system clipboard</dfn>.
The [=system clipboard=] has a list of clipboard items that are collectively
called the <dfn>system clipboard data</dfn>. The [=system clipboard data=] is
a {{DataTransfer}} object that mirrors the contents of the clipboard.
<h2 id="clipboard-events-and-interfaces">Clipboard Events</h2>
<h3 id="clipboard-event-interfaces">Clipboard event interfaces</h3>
The ClipboardEvent interface extends the {{Event}} interface.
<div id="clipboardeventinit-idl">
<pre class="idl" data-highlight="webidl">
dictionary ClipboardEventInit : EventInit {
DataTransfer? clipboardData = null;
};
</pre>
: <dfn for="ClipboardEventInit">clipboardData</dfn>
:: A {{DataTransfer}} object to hold data and meta data related to the event.
</div>
<div id="clipboardevent-idl">
<pre class="idl" data-highlight="webidl">
[Constructor(DOMString type, optional ClipboardEventInit eventInitDict)]
interface ClipboardEvent : Event {
readonly attribute DataTransfer? clipboardData;
};
</pre>
: <dfn for="ClipboardEvent">clipboardData</dfn>
:: The clipboardData attribute is an instance of the {{DataTransfer}}
interface which lets a script read and manipulate values on the system
clipboard during user-initiated copy, cut and paste operations. The
associated drag data store is a live but filtered view of the system
clipboard, exposing [=mandatory data types=] the implementation knows
the script can safely access. For synthetic events, the drag data store
contains the data added by the script that created the event.
:: The clipboardData object's {{DataTransfer/items}} and
{{DataTransfer/files}} properties enable processing of multi-part or
non-textual data from the clipboard.
</div>
The interface can be used to <a lt="constructing events">construct events</a>.
An example is given below:
<pre class="example javascript">
var pasteEvent = new ClipboardEvent('paste');
pasteEvent.clipboardData.items.add('My string', 'text/plain');
document.dispatchEvent(pasteEvent);
</pre>
Note: Synthetic clipboard events will not actually modify the clipboard or
the document. In other words, while the script above will fire a paste event,
the data will not be pasted into the document.
<!-- Issue: There should be a way a script can check if a clipboard format
is registered and whether the implementation allows writing this format to
the clipboard! event.clipboardData.isTypeSupported('mime/type')</em>?
-->
<h3 id="clipboard-event-definitions"><dfn>Clipboard events</dfn></h3>
<h4 id="clipboard-event-clipboardchange">The <dfn>clipboardchange</dfn> event</h4>
The [=clipboardchange=] event fires whenever the contents of the
[=system clipboard=] are changed. These changes could be due to any of the
following (non-exhaustive):
* User-initiated cut or copy actions
* Scripts that use the [[#async-clipboard-api]] to write to the clipboard
* Actions that update the clipboard outside the user agent
If the clipboard contents are changed outside the user agent, then the
[=clipboardchange=] event MUST fire when the user agent regains focus.
Since synthetic [=cut=] and [=copy=] events do not update the [=system clipboard=],
they will not trigger a "clipboardchange" event.
<h4 id="clipboard-event-copy">The <dfn>copy</dfn> event</h4>
When the user initiates a copy action, the user agent
[=fire a clipboard event|fires a clipboard event=] named
[=copy=].
If the event is not canceled, the currently selected
data will be copied to the [=system clipboard=].
The current document selection is not affected.
The [=copy=] event bubbles and is cancelable.
See [[#copy-action]] for a detailed description of the processing model for
this event.
A synthetic [=copy=] event can be manually constructed and dispatched, but it
will not affect the contents of the [=system clipboard=].
<h4 id="clipboard-event-cut">The <dfn>cut</dfn> event</h4>
When the user initiates a cut action, the user agent
[=fire a clipboard event|fires a clipboard event=] named
[=cut=].
In an [=editable context=], if the event is not
canceled the action will place the currently selected data on the
[=system clipboard=] and remove the selection from the document.
The [=cut=] event fires before the selected data is removed. When
the cut operation is completed, the selection is collapsed.
In a non-[=editable context=], the {{ClipboardEvent/clipboardData}} will
be an empty list. Note that the [=cut=] event will still be fired
in this case.
The [=cut=] event bubbles and is cancelable.
See [[#cut-action]] for a detailed description of the processing model for
this event.
A synthetic [=cut=] event can be manually constructed and dispatched, but it
will not affect the contents of the document or of the [=system clipboard=].
<h4 id="clipboard-event-paste">The <dfn>paste</dfn> event</h4>
When a user initiates a paste action, the user agent
[=fire a clipboard event|fires a clipboard event=] named
[=paste=]. The event fires before any clipboard data is inserted
into the document.
If the cursor is in an [=editable context=], the paste action will
insert clipboard data in the most suitable format (if any) supported
for the given context.
The paste action has no effect in a non-[=editable context=],
but the [=paste=] event fires regardless.
The [=paste=] event bubbles and is cancelable.
See [[#paste-action]] for a detailed description of the processing model for
this event.
A synthetic [=paste=] event can be manually constructed and dispatched, but it
will not affect the contents of the document.
<h3 id="integration-with-other-scripts-and-events">Integration with other scripts and events</h3>
<h4 id="allow-modify-clipboard">Event handlers that are <dfn>allowed to modify the clipboard</dfn></h4>
Event handlers may write to the clipboard if any of the following is
true:
* The action which triggers the event is invoked from the user-agent's
own user interface, e.g. from a "Copy" menu entry or shortcut key.
* The action which triggers the event is invoked from a scripting thread
which is [=allowed to show a popup=].
The implementation <em>may</em> allow other trusted event types to
modify the clipboard if the implementation authors believe that those
event types are likely to express user intention. The implementation
<em>may</em> also support configuration that trusts specific sites or
apps to modify the clipboard regardless of the origin of the scripting
thread.
Synthetic [=cut=] and [=copy=] events <em>must not</em> modify data on the
system clipboard.
<h4 id="allow-read-clipboard">Event handlers that are <dfn>allowed to read from clipboard</dfn></h4>
Event handlers may read data from the system clipboard if either of the
following is true
* The action that triggers the event is invoked from the user-agent's
own user interface, e.g. a "Paste" menu entry or shortcut key.
* The script that triggers the action is running on a site which through
an implementation-dependant mechanism is given permission to read
data from the clipboard.
* The action that triggers the event is triggered in an app with
permissions to read the clipboard.
Synthetic [=paste=] events <em>must not</em> give a script access to data on
the real system clipboard.
<h4 id="integration-with-rich-text-editing">Integration with rich text editing APIs</h4>
If an implementation supports ways to execute clipboard commands through
scripting, for example by calling the
<code>document.execCommand()</code> method with the commands "cut",
"copy" and "paste", the implementation <em>must</em> trigger the
corresponding action, which again will dispatch the associated clipboard
event.
These are the steps to follow when triggering copy, cut or paste actions
through a scripting API:
1. Execute the corresponding action synchronously.
1. Use the action's return value as the return value for the API call.
Note: Copy and cut commands triggered through a scripting API will only
affect the contents of the real clipboard if the event is dispatched
from an event that is trusted and triggered by the user, or if the
implementation is configured to allow this. Paste commands triggered
through a scripting API will only fire paste events and give access to
clipboard contents if the implementation is configured to allow this.
How implementations can be configured to allow read or write access to
the clipboard is outside the scope of this specification.
<h4 id="otherevents">Interaction with other events</h4>
If the clipboard operation is triggered by keyboard input, the
implementation <em>must</em> fire the corresponding event that initiates
the clipboard operation. The event is asynchronous but <em>must</em> be
dispatched before <b>keyup</b> events for the relevant keys.
The cut and paste actions <em>may</em> cause the implementation to
dispatch other supported events, such as textInput, input, change,
validation events, DOMCharacterDataModified and DOMNodeRemoved /
DOMNodeInserted. Any such events are queued up to fire after processing
of the cut/paste event is finished.
The implementation <em>must not</em> dispatch other input-related events
like textInput, input, change, and validation events in response to the
copy operation.
<h4 id="selection-mod">Event listeners that modify selection or focus</h4>
If the event listener modifies the selection or [=focusable area=], the clipboard
action <em>must</em> be completed on the modified selection.
<h2 id="sync-clipboard-api">Synchronous Clipboard API</h2>
The Synchronous Clipboard API allows you to override the default cut, copy
and paste behavior of the user agent.
Synchronous access to the clipboard is performed using the standard
{{DataTransfer}} methods to mutate the {{DataTransfer/items}} on a
{{ClipboardEvent}}'s {{ClipboardEvent/clipboardData}} attribute.
One consequence of this is that the synchronous clipboard APIs can only
access clipboard data in the context of a {{ClipboardEvent}} handler.
Note: If you need to access the clipboard outside of a clipboard event
handler, see [[#async-clipboard-api]].
<h3 id="override-copy">Overriding the copy event</h3>
To override the default [=copy=] event behavior, a [=copy=] event
handler must be added and this event handler must call
{{Event/preventDefault()}} to cancel the event.
Canceling the event is required in order for the [=system clipboard=] to be
updated with the data in {{ClipboardEvent/clipboardData}}.
If the {{ClipboardEvent}} is not canceled, then the data from the
current document selection will be copied instead.
<pre class="example javascript">
// Overwrite what is being copied to the clipboard.
document.addEventListener('copy', function(e) {
// e.clipboardData is initially empty, but we can set it to the
// data that we want copied onto the clipboard.
e.clipboardData.setData('text/plain', 'Hello, world!');
e.clipboardData.setData('text/html', '<b>Hello, world!</b>');
// This is necessary to prevent the current document selection from
// being written to the clipboard.
e.preventDefault();
});
</pre>
<h3 id="override-cut">Overriding the cut event</h3>
To override the default [=cut=] event behavior, a [=cut=] event
handler must be added and this event handler must call
{{Event/preventDefault()}} to cancel the event.
Canceling the event is required in order for the [=system clipboard=] to be
updated with the data in {{ClipboardEvent/clipboardData}}.
If the {{ClipboardEvent}} is not canceled, then the data from the
current document selection will be copied instead.
Note that canceling the [=cut=] event will also prevent the document from
being updated (i.e., the current selection will not be removed). The event
handler will need to manually update the document to remove the currently
selected text.
<pre class="example javascript">
// Overwrite what is copied to the clipboard.
document.addEventListener('cut', function(e) {
// e.clipboardData is initially empty, but we can set it to the
// data that we want copied onto the clipboard as part of the cut.
// Write the data that we want copied onto the clipboard.
e.clipboardData.setData('text/plain', 'Hello, world!');
e.clipboardData.setData('text/html', '<b>Hello, world!</b>');
// Since we will be canceling the cut operation, we need to manually
// update the document to remove the currently selected text.
deleteCurrentDocumentSelection();
// This is necessary to prevent the document selection from being
// written to the clipboard.
e.preventDefault();
});
</pre>
<h3 id="override-paste">Overriding the paste event</h3>
To override the default [=paste=] event behavior, a [=paste=] event
handler must be added and this event handler must call
{{Event/preventDefault()}} to cancel the event.
Canceling the event is required so that the user agent does not update the
document with data from the [=system clipboard=].
Note that canceling the [=paste=] event will also prevent the document from
being updated (i.e., nothing will be pasted into the document). The event
handler will need to manually paste the data into the document.
Also note that, when pasting, the [=drag data store mode=] flag is
<a lt="concept dnd ro">read/only</a>, hence calling {{DataTransfer/setData()}} from a
[=paste=] event handler will not modify the data that is
inserted, and not modify the data on the clipboard.
<pre class="example javascript">
// Overwrite what is being pasted onto the clipboard.
document.addEventListener('paste', function(e) {
// e.clipboardData contains the data that is about to be pasted.
if (e.clipboardData.types.indexOf('text/html') > -1) {
var oldData = e.clipboardData.getData('text/html');
var newData = '<b>Ha Ha!</b> ' + oldData;
// Since we are canceling the paste operation, we need to manually
// paste the data into the document.
pasteClipboardData(newData);
// This is necessary to prevent the default paste action.
e.preventDefault();
}
});
</pre>
<h2 id="async-clipboard-api">Asynchronous Clipboard API</h2>
<h3 id="navigator-interface">Navigator Interface</h3>
<pre class="idl" data-highlight="webidl">
partial interface Navigator {
[SecureContext SameObject] readonly attribute Clipboard clipboard;
};
</pre>
<div id="navigator-idl" dfn-for="Navigator">
<div class="algorithm" data-algorithm="navigator-clipboard">
<h4 id="h-navigator-clipboard"><dfn>clipboard</dfn></h4>
The [=clipboard=] attribute must return the {{Navigator}}'s [=clipboard=] object.
</div>
</div><!-- dfn-for Navigator -->
<h3 id="clipboard-interface">Clipboard Interface</h3>
<pre class="idl" data-highlight="webidl">
[SecureContext] interface Clipboard : EventTarget {
Promise<DataTransfer> read();
Promise<DOMString> readText();
Promise<void> write(DataTransfer data);
Promise<void> writeText(DOMString data);
};
</pre>
<div id="clipboard-idl" dfn-for="Clipboard">
<div class="algorithm" data-algorithm="clipboard-read">
<h4 id="h-clipboard-read"><dfn>read()</dfn></h4>
The [=read()=] method must run these steps:
1. Let |p| be a new [=Promise=].
1. TODO: Handle access permissions. Reject promise if not allowed.
1. Run the following steps [=in parallel=]:
1. Let |data| be a copy of the [=system clipboard data=].
1. Resolve |p| with |data|.
1. Return |p|.
<div></div>
<pre class="example javascript">
navigator.clipboard.read().then(function(data) {
for (var i = 0; i < data.items.length; i++) {
if (data.items[i].type == "text/plain") {
console.log(“Your string: ”, data.items[i].getAs(“text/plain”));
} else {
console.error(“No text/plain data on clipboard.”);
}
}
});
</pre>
</div><!-- read() -->
<div class="algorithm" data-algorithm="clipboard-readtext">
<h4 id="h-clipboard-readtext"><dfn>readText()</dfn></h4>
The [=readText()=] method must run these steps:
1. Let |p| be a new [=Promise=].
1. TODO: Handle access permissions. Reject promise if not allowed.
1. Run the following steps [=in parallel=]:
1. Let |data| be a copy of the [=system clipboard data=].
1. Let |textData| be an empty string.
1. If |data|'s {{DataTransfer/items}} list contains a "text/plain" item |textItem|, then:
1. Set |textData| to be a copy of |textItem|'s string data
1. Resolve |p| with |textData|.
1. Return |p|.
<div></div>
<pre class="example javascript">
navigator.clipboard.read().then(function(data) {
console.log(“Your string: ”, data);
});
</pre>
</div><!-- readText() -->
<div class="algorithm" data-algorithm="clipboard-write">
<h4 id="h-clipboard-write-data"><dfn>write(|data|)</dfn></h4>
The [=write(data)=] method must run these steps:
1. Let |p| be a new [=Promise=].
1. TODO: Handle access permissions. Reject promise if not allowed.
1. Run the following steps [=in parallel=]:
1. Let |cleanItemList| be an empty {{DataTransferItemList}}.
1. For each {{DataTransferItem}} |item| in |data|'s {{DataTransfer/items}} list:
1. Let |cleanItem| be a sanitized copy of |item|.
1. If unable to create a sanitized copy, then reject |p|.
1. Add |cleanItem| to |cleanItemList|.
1. Replace the [=system clipboard data=]'s {{DataTransfer/items}}
list with |cleanItemList|.
1. Resolve |p|.
1. Return |p|.
<div></div>
<pre class="example javascript">
var data = new DataTransfer();
data.items.add("text/plain", "Howdy, partner!");
navigator.clipboard.write(data).then(function() {
console.log(“Copied to clipboard successfully!”);
}, function() {
console.error(“Unable to write to clipboard. :-(”);
});
</pre>
</div><!-- write() -->
<div class="algorithm" data-algorithm="clipboard-writetext">
<h4 id="h-clipboard-writetext-data"><dfn>writeText(|data|)</dfn></h4>
The [=writeText(data)=] method must run these steps:
1. Let |p| be a new [=Promise=].
1. TODO: Handle access permissions. Reject promise if not allowed.
1. Run the following steps [=in parallel=]:
1. Let |newItemList| be an empty {{DataTransferItemList}}.
1. Let |newItem| be a new {{DataTransferItem}} with
[=drag data item kind=] set to <em>string</em> and
[=drag data item type string=] set to <em>text/plain</em>.
1. Set |newItem|'s data to |data|.
1. Add |newItem| to |newItemList|.
1. Replace the [=system clipboard data=]'s {{DataTransfer/items}}
list with |newItemList|.
1. Resolve |p|.
1. Return |p|.
<div></div>
<pre class="example javascript">
navigator.clipboard.writeText("Howdy, partner!").then(function() {
console.log(“Copied to clipboard successfully!”);
}, function() {
console.error(“Unable to write to clipboard. :-(”);
});
</pre>
</div><!-- writeText() -->
</div><!-- dfn-for Clipboard -->
<h2 id="clipboard-actions">Clipboard Actions</h2>
This section defines clipboard actions and the processing model
for event dispatch.
Each clipboard action has two flags called <em>script-triggered</em> and
<em>script-may-access-clipboard</em>.
The <dfn>script-triggered</dfn> flag is set if the action runs because
of a script, for example a <code>document.execCommand()</code> call.
Future scripting APIs that interact with the clipboard should also use
these actions, and the <em>script-triggered</em> flag must be set
accordingly.
<div class="algorithm" data-algorithm="script-may-access-clipboard">
The <dfn>script-may-access-clipboard</dfn> flag is set as follows:
1. If action is <em>copy</em> or <em>cut</em> and the script thread
is [=allowed to modify the clipboard=], then
1. Set the action's <em>script-may-access-clipboard</em> flag
1. If action is <em>paste</em> and the script thread is [=allowed to
read from clipboard=], then
1. Set the action's <em>script-may-access-clipboard</em> flag.
</div><!-- algorithm -->
<h3 id="copy-action">The copy action</h3>
<div class="algorithm" data-algorithm="clipboard-copy-action">
The copy action consists of the following steps:
1. If the <em>script-triggered</em> flag is set, then
1. If the <em>script-may-access-clipboard</em> flag is unset, then
1. Return false from the copy action, terminate this algorithm
1. [=Fire a clipboard event=] named [=copy=]
1. If the event was not canceled, then
1. Copy the selected contents, if any, to the clipboard.
Implementations <em>should</em> create alternate text/html and
text/plain clipboard formats when content in a web page is selected.
1. [=Fire a clipboard event=] named [=clipboardchange=]
1. Else, if the event was canceled, then
1. Call the [=write content to the clipboard=] algorithm,
passing on the {{DataTransferItemList}} list <em>items</em>,
a <em>clear-was-called</em> flag and a <em>types-to-clear</em>
list.
1. Return true from the copy action
</div><!-- algorithm -->
<h3 id="cut-action">The cut action</h3>
<div class="algorithm" data-algorithm="clipboard-cut-action">
The cut action consists of the following steps:
1. If the <em>script-triggered</em> flag is set, then
1. If the <em>script-may-access-clipboard</em> flag is unset, then
1. Return false from the cut action, terminate this algorithm
1. [=Fire a clipboard event=] named [=cut=]
1. If the event was not canceled, then
1. If there is a selection in an [=editable context=] where
cutting is enabled, then
1. Copy the selected contents, if any, to the clipboard.
Implementations <em>should</em> create alternate
text/html and text/plain clipboard formats when content
in a web page is selected.
1. Remove the contents of the selection from the document
and collapse the selection.
1. [=Fire a clipboard event=] named [=clipboardchange=]
1. Queue tasks to fire any events that should fire due to the
modification, see
[[#integration-with-other-scripts-and-events]]
for details.
1. Else, if there is no selection or the context is not editable, then
1. Return false
1. Else, if the event was canceled, then
1. Call the [=write content to the clipboard=] algorithm,
passing on the {{DataTransferItemList}} list <em>items</em>,
a <em>clear-was-called</em> flag and a <em>types-to-clear</em>
list.
1. [=Fire a clipboard event=] named [=clipboardchange=]
1. Return true from the cut action
</div><!-- algorithm -->
<h3 id="paste-action">The paste action</h3>
For the paste action, the <em>script-may-access-clipboard</em> flag
depends on an implementation-specific permission mechanism for
determining what sites or apps may read from the clipboard. When a
paste action is triggered by a script, the implementation must not
make clipboard contents available without the user's permission. If
the permission has not already been granted, the permission prompt
must include the hostname of the document associated with the script
thread.
<div class="algorithm" data-algorithm="clipboard-paste-action">
The paste action consists of the following steps:
1. If the <em>script-triggered</em> flag is set, then
1. If <em>script-may-access-clipboard</em> is unset, then
1. Return false from the paste action, terminate this algorithm
1. <a href="#fire-a-clipboard-event">Fire a clipboard event</a>
named [=paste=]
1. If the event was not canceled, then
1. If there is a selection or cursor in an [=editable context=]
where pasting is enabled, then
1. Insert the most suitable content found on the clipboard,
if any, into the context.
1. Queue tasks to fire any events that should fire due to
the modification, see
[[#integration-with-other-scripts-and-events]] for details.
1. Else
1. Return false
1. Else, if the event was canceled
1. Return false
1. Return true from the action
</div><!-- algorithm -->
<h2 id="mandatory-data-types-x"><dfn>Mandatory data types</dfn></h2>
The implementation must recognise the native OS clipboard format description
for the following data types, to be able to populate the
{{DataTransferItemList}} with the correct description for paste events, and
set the correct data format on the OS clipboard in response to copy and cut
events.
<h3 id="reading-from-clipboard">Reading from the clipboard</h3>
These data types must be exposed by <em>paste</em> events if a
corresponding native type exists on the clipboard:
* text/plain
* text/uri-list
* text/csv
* text/css
* text/html
* application/xhtml+xml
* image/png
* image/jpg, image/jpeg
* image/gif
* image/svg+xml
* application/xml, text/xml
* application/javascript
* application/json
* application/octet-stream
<h3 id="writing-to-clipboard">Writing to the clipboard</h3>
These data types must be placed on the clipboard with a corresponding
native type description if added to a {{DataTransfer}} object during
<em>copy</em> and <em>cut</em> events.
* text/plain
* text/uri-list
* text/csv
* text/html
* image/svg+xml
* application/xml, text/xml
* application/json
Advisement: Warning! The data types that untrusted scripts are allowed to write to the
clipboard are limited as a security precaution. Untrusted scripts can
attempt to exploit security vulnerabilities in local software by placing
data known to trigger those vulnerabilities on the clipboard.
<h2 id="security">Security Considerations</h2>
Enabling authors to change what is copied by a user, or to make an automated
copy of something that was never selected and allowing unrestricted calls to
paste information can raise various security and privacy concerns.
An example scenario of a problem is where a user selects a link and copies
it, but a different link is copied to the clipboard. The effect of this can
range from an unexpected result on pasting to an attempted "phishing" attack.
<h3 id="pasting-html">Pasting HTML and multi-part data</h3>
<em>This section is non-normative.</em>
There are certain security risks associated with pasting formatted or
multi-part data.
* The user might paste hidden data without realising is there. This may
happen if, for example, the markup includes
<input type="hidden"> tags or HTML comments. Such hidden data
might contain sensitive information.
* The user might paste malicious JavaScript into a trusted page.
* The implementation might grant scripts access to local files the user
did not intend to expose.
To determine what policies to use, the factors we consider are:
* The origin of the data being pasted
* The origin of data sub-parts such as referenced images
* The origin of the running script
This is an overview of the scenarios and the possible security policies:
<table class="simple">
<tr>
<th>Origin of data</th>
<th>Origin of script</th>
<th>Rules</th>
</tr>
<tr>
<td rowspan="2">Originates from online source</td>
<td>Same as data</td>
<td>Do not sanitize HTML. Do not access any local files.</td>
</tr>
<tr>
<!-- cell span from previous row -->
<td>Different origin</td>
<td>Optionally sanitize content. Do not access any local files.</td>
</tr>
<tr>
<td>Originates from local application</td>
<td>Any</td>
<td>Do not sanitize HTML. Grant access to local files</td>
</tr>
</table>
Some implementations mitigate the risks associated with pasting rich
text by stripping potentially malicious content such as SCRIPT elements
and javascript: links by default when pasting rich text, but allow a
paste event handler to retrieve and process the original, un-sanitized
data.
<h3 id="general-security-policies">General security policies</h3>
The implementation <em>must not</em> download referenced online
resources, or expose their contents in the {{DataTransfer/files}} list
or {{DataTransferItemList}}.
If the data on the clipboard is not from a local application, the
implementation <em>must not</em> give access to any referenced local
files. For example, if the data contains
<img src="file://localhost/example.jpg">
but the data's origin is an online resource, the implementation must not
add an entry for example.jpg to the clipboardData.items list.
<h3 id="nuisances">Nuisance considerations</h3>
Scripts may use the {{DataTransfer}} API to annoy and confuse users by
altering the data on the system clipboard from copy and cut events. This
specification does not attempt to prevent such nuisances, though
implementations may add additional restrictions.
Implementations must handle scripts that try to place excessive amounts
of data on the clipboard gracefully.
<h2 id="privacy">Privacy Considerations</h2>
Untrusted scripts should not get uncontrolled access to a user's
clipboard data. This specification assumes that granting access to the
current clipboard data when a user explicitly initiates a paste
operation from the user agent's trusted chrome is acceptable. However,
implementors must proceed carefully, and as a minimum implement the
precautions below:
* Objects implementing the {{DataTransfer}} interface to return
clipboard data <em>must not</em> be available outside the
ClipboardEvent event handler.
* If a script stores a reference to an object implementing the
{{DataTransfer}} interface to use from outside the ClipboardEvent
event handler, all methods <em>must</em> be no-ops when called
outside the expected context.
* Implementations <em>must not</em> let scripts create synthetic
clipboard events to get access to real clipboard data except if
configured to do so.
* Implementations <em>should not</em> let scripts call
document.execCommand("paste") unless the user has explicitly allowed
it.
Implementations may choose to further limit the functionality provided
by the {{DataTransfer}} interface. For example, an implementation may
allow the user to disable this API, or configure which web sites should
be granted access to it.
<h2 id="acknowledge">Acknowledgements</h2>
<em>This section is informative</em>
The editors would like to acknowledge the contributions of the former
editors who helped shepherd this specification through various
meetings and mailing-list discussions to bring it to its current state.
* Hallvord R. M. Steen
The editors would also like to acknowledge their intellectual debt to the
documentation of Data Transfer functionalities from Microsoft
[[MICROSOFT-CLIP-OP]] and earlier drafts of the [[HTML5]] specification.
We are also grateful for the draft "safe copy and paste" from Paul Libbrecht
(this draft is no longer available on the Web).
And finally, we would like to acknowledge the contributions made by the following:
Adam Barth,
Shawn Carnell,
Daniel Cheng,
Daniel Dardailler,
Al Gilman,
James Graham,
James Greene,
Ian Hickson,
Lachlan Hunt,
Philip Jägenstedt,
Anne van Kesteren,
Aaron Leventhal,
Jim Ley,
Paul Libbrecht,