UNPKG

9.32 kBMarkdownView Raw
1![Logo for clipboard-polyfill: an icon of a clipboard fading into a drafting paper grid.](clipboard-polyfill-logo.svg)
2
3# `clipboard-polyfill`
4
5Make copying on the web as easy as:
6
7 clipboard.writeText("hello world");
8
9As of October 2017, this library is a polyfill for the modern `Promise`-based [asynchronous clipboard API](https://www.w3.org/TR/clipboard-apis/#async-clipboard-api).
10
11## Why `clipboard-polyfill`?
12
13Browsers have implemented several clipboard APIs over time, and writing to the clipboard without [triggering bugs in various old and current browsers](https://github.com/lgarron/clipboard-polyfill/blob/master/experiment/Conclusions.md) is fairly tricky. In every browser that supports copying to the clipboard in some way, `clipboard-polyfill` attempts to act as close as possible to the async clipboard API. (Read to the end of this document for all the limitations.)
14
15Note: If you only need to copy text and want a super simple polyfill that gets you 80% of the way, consider using [this gist](https://gist.github.com/lgarron/d1dee380f4ed9d825ca7).
16
17# Get the Code
18
19Get the code using one of the following. If you don't know how to pick and want maximum browser compatibility, start by using "With Promise Polyfill".
20
21## Without Promise Polyfill
22
23This version is smaller, but does not work in Internet Explorer unless you add your own `Promise` polyfill (see below).
24
25- Download [`build/clipboard-polyfill.js`](https://raw.githubusercontent.com/lgarron/clipboard-polyfill/master/build/clipboard-polyfill.js) and include it using a `<script>` tag.
26- `npm install clipboard-polyfill` and one of:
27 - `import * as clipboard from "clipboard-polyfill"`
28 - `const clipboard = require("clipboard-polyfill");`
29
30## With Promise Polyfill
31
32This version works "out of the box" in all browsers that support copying to the clipboard, but is about 2.5x as large.
33
34- Download [`build/clipboard-polyfill.promise.js`](https://raw.githubusercontent.com/lgarron/clipboard-polyfill/master/build/clipboard-polyfill.promise.js) and include it using a `<script>` tag.
35- `npm install clipboard-polyfill` and one of:
36 - `import * as clipboard from "clipboard-polyfill/build/clipboard-polyfill.promise"`
37 - `const clipboard = require("clipboard-polyfill/build/clipboard-polyfill.promise");`
38
39## Which One?
40
41The async clipboard API design uses ES6 [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise), which is not supported in Internet Explorer. If you want the `clipboard-polyfill` to work in as many browsers as possible, you will need to include a polyfill for `Promise`. You can do this by either using the "With Promise Polyfill" version, or by using the "Without Promise Polyfill" version with a polyfill of your own choice. Recommendations include [es6-promise](https://github.com/stefanpenner/es6-promise) and [core-js](https://github.com/zloirock/core-js). Instructions for how to use these polyfills are dependent on your build system and can be found in the `README`s of these libraries.
42
43# Usage
44
45## Plain Text
46
47Copy text to the clipboard (all modern browsers):
48
49 clipboard.writeText("This text is plain.");
50
51Read text from the clipboard (IE 9-11 and Chrome 65+):
52
53 clipboard.readText().then(console.log, console.error);
54
55Caveats:
56
57- Browsers may require a user gesture or user permission to access the clipboard. In particular, you should write text only in response to an event listener, e.g. a button click listener.
58- Reading fails if the clipboard does not contain `text/plain` data.
59
60## Other Data Types (e.g. HTML)
61
62Write (all modern browsers):
63
64 var dt = new clipboard.DT();
65 dt.setData("text/plain", "Fallback markup text.");
66 dt.setData("text/html", "<i>Markup</i> <b>text</b>.");
67 clipboard.write(dt);
68
69Read (IE 9-11, Chrome 65+):
70
71 // The success callback receives a clipboard.DT object.
72 clipboard.read().then(console.log, console.error);
73
74Caveats:
75
76- Currently, `text/plain` and `text/html` are the only data types that can be written to the clipboard across most browsers.
77- Unsupported data types will be silently dropped. In general, it is not possible to tell which data types will be dropped.
78- This part of the clipboard API is still under active discussion, and may change.
79- Currently, reading will only return the `text/plain` data type, if it is on the clipboard.
80
81## Interface
82
83 clipboard {
84 static write: (data: clipboard.DT) => Promise<void>
85 static writeText: (s: string) => Promise<void>
86 static read: () => Promise<clipboard.DT>
87 static readText: () => Promise<string>
88 static suppressWarnings: () => void
89 }
90
91 clipboard.DT {
92 constructor()
93 setData: (type: string, value: string): void
94 getData: (type: string): string | undefined
95 }
96
97## A note on `clipboard.DT`
98
99The asynchronous clipboard API works like this:
100
101 var dt = new DataTransfer();
102 dt.setData("text/plain", "plain text");
103 navigator.clipboard.write(dt);
104
105Ideally, `clipboard-polyfill` would take a `DataTransfer`, so that the code above works verbatim when you replace `navigator.clipboard` with `clipboard`. However, *the `DataTransfer` constructor cannot be called* in most browsers. Thus, this library uses a light-weight alternative to `DataTransfer`, exposed as `clipboard.DT`:
106
107 var dt = new clipboard.DT();
108 dt.setData("text/plain", "plain text");
109 clipboard.write(dt);
110
111
112## This is way too complicated!
113
114Try [this gist](https://gist.github.com/lgarron/d1dee380f4ed9d825ca7) for a simpler solution.
115
116## [Can I use](http://caniuse.com/#feat=clipboard) it?
117
118- Chrome 42+
119- Firefox 41+
120- Opera 29+
121- Internet Explorer 9+ (text only)
122- Edge
123- Desktop Safari 10+
124- iOS Safari 10+ (text only in some versions)
125
126`clipboard-polyfill` uses a variety of heuristics to get around compatibility bugs. Please [let us know](https://github.com/lgarron/clipboard-polyfill/issues/new) if you are running into compatibility issues with any of the browsers listed above.
127
128### Limitations
129
130- In Microsoft Edge, it seems to be impossible to detect whether the copy action actually succeeded ([Edge Bug #14110451](https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/14110451/), [Edge Bug #14080262](https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/14080262/)). `clipboard-polyfill` will always call `resolve()` in Edge.
131- In Microsoft Edge, only the *last* data type you specify is copied to the clipboard ([Edge Bug #14080506](https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/14080506/)).
132 - `DataTransfer` and `clipbard.DT` keep track of the order in which you set items. If you care which data type Edge copies, call `setData()` with that data type last.
133- On iOS Safari ([WebKit Bug #177715](https://bugs.webkit.org/show_bug.cgi?id=177715)) and Internet Explorer, only text copying works.
134 - On iOS Safari, `clipboard-polyfill` needs to use the DOM to copy, so the text will be copied as rich text. `clipboard-polyfill` attempts to use shadow DOM in order to avoid some of the page formatting (e.g. background color) from affecting the copied text. However, such formatting might be copied if shadow DOM is not available.
135 - In other browsers, writing copy data that does *not* include the `text/plain` data type will succeed, but also show a console warning:
136
137> clipboard.write() was called without a `text/plain` data type. On some platforms, this may result in an empty clipboard. Call `clipboard.suppressWarnings()` to suppress this warning.
138
139- `clipboard-polyfill` attemps to avoid changing the document selection or modifying the DOM. However, `clipboard-polyfill` will automatically fall back to using such techniques if needed:
140 - On iOS Safari, the user's current selection will be cleared. This *should* not happen on other platforms unless there are unanticipated bugs. (Please [file an issue](https://github.com/lgarron/clipboard-polyfill/issues/new) if you observe this!)
141 - On iOS Safari and under certain conditions on desktop Safari ([WebKit Bug #177715](https://bugs.webkit.org/show_bug.cgi?id=156529)), `clipbard-polyfill` needs to add a temporary element to the DOM. This will trigger a [mutation observer](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver) if you have attached one to `document.body`. Please [file an issue](https://github.com/lgarron/clipboard-polyfill/issues/new) if you'd like to discuss how to detect temporary elements added by `clipboard-polyfill`.
142- `read()` currently only works in Internet Explorer.
143 - Internet Explorer can only read `text/plain` values from the clipboard.
144- Microsoft Edge (at least EdgeHTML version <17) does not write `text/html` to the clipboard using the Windows `CF_HTML` clipboard format ([Edge Bug #14372529](https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/14372529/)), which prevents other programs (including other browsers) from recognizing the copied HTML data ([issue #73](https://github.com/lgarron/clipboard-polyfill/issues/73)). `clipboard-polyfill` currently does not attempt to work around this issue.
145- Node with `--experimental-modules` seems to require using `import clipboard from "clipboard-polyfill"` (instead of `import * from`) as of October 2018. Some environments may also require this.
146
\No newline at end of file