1 | import Emitter from 'tiny-emitter';
|
2 | import listen from 'good-listener';
|
3 | import ClipboardAction from './clipboard-action';
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 | function getAttributeValue(suffix, element) {
|
11 | const attribute = `data-clipboard-${suffix}`;
|
12 |
|
13 | if (!element.hasAttribute(attribute)) {
|
14 | return;
|
15 | }
|
16 |
|
17 | return element.getAttribute(attribute);
|
18 | }
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 | class Clipboard extends Emitter {
|
25 | |
26 |
|
27 |
|
28 |
|
29 | constructor(trigger, options) {
|
30 | super();
|
31 |
|
32 | this.resolveOptions(options);
|
33 | this.listenClick(trigger);
|
34 | }
|
35 |
|
36 | |
37 |
|
38 |
|
39 |
|
40 |
|
41 | resolveOptions(options = {}) {
|
42 | this.action =
|
43 | typeof options.action === 'function'
|
44 | ? options.action
|
45 | : this.defaultAction;
|
46 | this.target =
|
47 | typeof options.target === 'function'
|
48 | ? options.target
|
49 | : this.defaultTarget;
|
50 | this.text =
|
51 | typeof options.text === 'function' ? options.text : this.defaultText;
|
52 | this.container =
|
53 | typeof options.container === 'object' ? options.container : document.body;
|
54 | }
|
55 |
|
56 | |
57 |
|
58 |
|
59 |
|
60 | listenClick(trigger) {
|
61 | this.listener = listen(trigger, 'click', (e) => this.onClick(e));
|
62 | }
|
63 |
|
64 | |
65 |
|
66 |
|
67 |
|
68 | onClick(e) {
|
69 | const trigger = e.delegateTarget || e.currentTarget;
|
70 |
|
71 | if (this.clipboardAction) {
|
72 | this.clipboardAction = null;
|
73 | }
|
74 |
|
75 | this.clipboardAction = new ClipboardAction({
|
76 | action: this.action(trigger),
|
77 | target: this.target(trigger),
|
78 | text: this.text(trigger),
|
79 | container: this.container,
|
80 | trigger,
|
81 | emitter: this,
|
82 | });
|
83 | }
|
84 |
|
85 | |
86 |
|
87 |
|
88 |
|
89 | defaultAction(trigger) {
|
90 | return getAttributeValue('action', trigger);
|
91 | }
|
92 |
|
93 | |
94 |
|
95 |
|
96 |
|
97 | defaultTarget(trigger) {
|
98 | const selector = getAttributeValue('target', trigger);
|
99 |
|
100 | if (selector) {
|
101 | return document.querySelector(selector);
|
102 | }
|
103 | }
|
104 |
|
105 | |
106 |
|
107 |
|
108 |
|
109 |
|
110 | static isSupported(action = ['copy', 'cut']) {
|
111 | const actions = typeof action === 'string' ? [action] : action;
|
112 | let support = !!document.queryCommandSupported;
|
113 |
|
114 | actions.forEach((action) => {
|
115 | support = support && !!document.queryCommandSupported(action);
|
116 | });
|
117 |
|
118 | return support;
|
119 | }
|
120 |
|
121 | |
122 |
|
123 |
|
124 |
|
125 | defaultText(trigger) {
|
126 | return getAttributeValue('text', trigger);
|
127 | }
|
128 |
|
129 | |
130 |
|
131 |
|
132 | destroy() {
|
133 | this.listener.destroy();
|
134 |
|
135 | if (this.clipboardAction) {
|
136 | this.clipboardAction.destroy();
|
137 | this.clipboardAction = null;
|
138 | }
|
139 | }
|
140 | }
|
141 |
|
142 | export default Clipboard;
|