UNPKG

2.79 kBPlain TextView Raw
1// Copyright (c) Jupyter Development Team.
2// Distributed under the terms of the Modified BSD License.
3
4import { MimeData } from '@lumino/coreutils';
5
6// 'string' is allowed so as to make it non-breaking for any 1.x releases
7export type ClipboardData = string | MimeData;
8
9/**
10 * The clipboard interface.
11 */
12export namespace Clipboard {
13 /**
14 * Get the application clipboard instance.
15 */
16 export function getInstance(): MimeData {
17 return Private.instance;
18 }
19
20 /**
21 * Set the application clipboard instance.
22 */
23 export function setInstance(value: MimeData): void {
24 Private.instance = value;
25 }
26
27 /**
28 * Copy text to the system clipboard.
29 *
30 * #### Notes
31 * This can only be called in response to a user input event.
32 */
33 export function copyToSystem(clipboardData: ClipboardData): void {
34 const node = document.body;
35 const handler = (event: ClipboardEvent) => {
36 const data = event.clipboardData || (window as any).clipboardData;
37 if (typeof clipboardData === 'string') {
38 data.setData('text', clipboardData);
39 } else {
40 (clipboardData as MimeData).types().map((mimeType: string) => {
41 data.setData(mimeType, clipboardData.getData(mimeType));
42 });
43 }
44 event.preventDefault();
45 node.removeEventListener('copy', handler);
46 };
47 node.addEventListener('copy', handler);
48 generateEvent(node);
49 }
50
51 /**
52 * Generate a clipboard event on a node.
53 *
54 * @param node - The element on which to generate the event.
55 *
56 * @param type - The type of event to generate.
57 * `'paste'` events cannot be programmatically generated.
58 *
59 * #### Notes
60 * This can only be called in response to a user input event.
61 */
62 export function generateEvent(
63 node: HTMLElement,
64 type: 'copy' | 'cut' = 'copy'
65 ): void {
66 // http://stackoverflow.com/a/5210367
67
68 // Identify selected text.
69 let sel = window.getSelection();
70
71 // Save the current selection.
72 const savedRanges: any[] = [];
73 for (let i = 0, len = sel?.rangeCount || 0; i < len; ++i) {
74 savedRanges[i] = sel!.getRangeAt(i).cloneRange();
75 }
76
77 // Select the node content.
78 const range = document.createRange();
79 range.selectNodeContents(node);
80 if (sel) {
81 sel.removeAllRanges();
82 sel.addRange(range);
83 }
84
85 // Execute the command.
86 document.execCommand(type);
87
88 // Restore the previous selection.
89 sel = window.getSelection();
90 if (sel) {
91 sel.removeAllRanges();
92 for (let i = 0, len = savedRanges.length; i < len; ++i) {
93 sel.addRange(savedRanges[i]);
94 }
95 }
96 }
97}
98
99/**
100 * The namespace for module private data.
101 */
102namespace Private {
103 /**
104 * The application clipboard instance.
105 */
106 export let instance = new MimeData();
107}