@capawesome/capacitor-clipboard 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CapawesomeCapacitorClipboard.podspec +17 -0
- package/LICENSE +21 -0
- package/Package.swift +28 -0
- package/README.md +220 -0
- package/android/build.gradle +58 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/clipboard/Clipboard.java +141 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/clipboard/ClipboardPlugin.java +96 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/clipboard/classes/ClipboardContentType.java +22 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/clipboard/classes/CustomException.java +20 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/clipboard/classes/CustomExceptions.java +12 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/clipboard/classes/options/WriteOptions.java +60 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/clipboard/classes/results/ReadResult.java +29 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/clipboard/interfaces/Callback.java +5 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/clipboard/interfaces/EmptyCallback.java +5 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/clipboard/interfaces/NonEmptyResultCallback.java +7 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/clipboard/interfaces/Result.java +7 -0
- package/android/src/main/res/.gitkeep +0 -0
- package/dist/docs.json +249 -0
- package/dist/esm/definitions.d.ts +144 -0
- package/dist/esm/definitions.js +57 -0
- package/dist/esm/definitions.js.map +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/web.d.ts +16 -0
- package/dist/esm/web.js +109 -0
- package/dist/esm/web.js.map +1 -0
- package/dist/plugin.cjs.js +179 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.js +182 -0
- package/dist/plugin.js.map +1 -0
- package/ios/Plugin/Classes/Options/WriteOptions.swift +19 -0
- package/ios/Plugin/Classes/Results/ReadResult.swift +19 -0
- package/ios/Plugin/Clipboard.swift +74 -0
- package/ios/Plugin/ClipboardPlugin.swift +62 -0
- package/ios/Plugin/Enums/ClipboardContentType.swift +8 -0
- package/ios/Plugin/Enums/CustomError.swift +36 -0
- package/ios/Plugin/Info.plist +24 -0
- package/ios/Plugin/Protocols/Result.swift +5 -0
- package/package.json +94 -0
package/dist/esm/web.js
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { CapacitorException, WebPlugin } from '@capacitor/core';
|
|
2
|
+
import { ClipboardContentType, ErrorCode } from './definitions';
|
|
3
|
+
export class ClipboardWeb extends WebPlugin {
|
|
4
|
+
async read() {
|
|
5
|
+
if (navigator.clipboard.read) {
|
|
6
|
+
try {
|
|
7
|
+
const items = await navigator.clipboard.read();
|
|
8
|
+
for (const item of items) {
|
|
9
|
+
const imageType = item.types.find(type => type.startsWith('image/'));
|
|
10
|
+
if (imageType) {
|
|
11
|
+
const blob = await item.getType(imageType);
|
|
12
|
+
const value = await ClipboardWeb.convertBlobToDataUrl(blob);
|
|
13
|
+
return { type: ClipboardContentType.Image, value };
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
for (const item of items) {
|
|
17
|
+
if (item.types.includes('text/html')) {
|
|
18
|
+
const blob = await item.getType('text/html');
|
|
19
|
+
const value = await blob.text();
|
|
20
|
+
return { type: ClipboardContentType.Html, value };
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
throw ClipboardWeb.createException(ClipboardWeb.errorReadFailed, ErrorCode.ReadFailed);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
let value;
|
|
29
|
+
try {
|
|
30
|
+
value = await navigator.clipboard.readText();
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
throw ClipboardWeb.createException(ClipboardWeb.errorReadFailed, ErrorCode.ReadFailed);
|
|
34
|
+
}
|
|
35
|
+
if (!value) {
|
|
36
|
+
throw ClipboardWeb.createException(ClipboardWeb.errorEmptyClipboard, ErrorCode.EmptyClipboard);
|
|
37
|
+
}
|
|
38
|
+
return { type: ClipboardWeb.resolveTextType(value), value };
|
|
39
|
+
}
|
|
40
|
+
async write(options) {
|
|
41
|
+
if (options.html === undefined &&
|
|
42
|
+
options.image === undefined &&
|
|
43
|
+
options.text === undefined &&
|
|
44
|
+
options.url === undefined) {
|
|
45
|
+
throw new Error(ClipboardWeb.errorContentMissing);
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
if (options.image !== undefined) {
|
|
49
|
+
await ClipboardWeb.writeRichContent({
|
|
50
|
+
'image/png': await ClipboardWeb.convertDataUrlToBlob(options.image),
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
else if (options.html !== undefined) {
|
|
54
|
+
const data = {
|
|
55
|
+
'text/html': new Blob([options.html], { type: 'text/html' }),
|
|
56
|
+
};
|
|
57
|
+
if (options.text !== undefined) {
|
|
58
|
+
data['text/plain'] = new Blob([options.text], { type: 'text/plain' });
|
|
59
|
+
}
|
|
60
|
+
await ClipboardWeb.writeRichContent(data);
|
|
61
|
+
}
|
|
62
|
+
else if (options.url !== undefined) {
|
|
63
|
+
await navigator.clipboard.writeText(options.url);
|
|
64
|
+
}
|
|
65
|
+
else if (options.text !== undefined) {
|
|
66
|
+
await navigator.clipboard.writeText(options.text);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
if (error instanceof CapacitorException) {
|
|
71
|
+
throw error;
|
|
72
|
+
}
|
|
73
|
+
throw ClipboardWeb.createException(ClipboardWeb.errorWriteFailed, ErrorCode.WriteFailed);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
static convertBlobToDataUrl(blob) {
|
|
77
|
+
return new Promise((resolve, reject) => {
|
|
78
|
+
const reader = new FileReader();
|
|
79
|
+
reader.onloadend = () => resolve(reader.result);
|
|
80
|
+
reader.onerror = () => reject(reader.error);
|
|
81
|
+
reader.readAsDataURL(blob);
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
static async convertDataUrlToBlob(dataUrl) {
|
|
85
|
+
const response = await fetch(dataUrl);
|
|
86
|
+
return response.blob();
|
|
87
|
+
}
|
|
88
|
+
static createException(message, code) {
|
|
89
|
+
return new CapacitorException(message, undefined, { code });
|
|
90
|
+
}
|
|
91
|
+
static resolveTextType(value) {
|
|
92
|
+
if (value.startsWith('http://') || value.startsWith('https://')) {
|
|
93
|
+
return ClipboardContentType.Url;
|
|
94
|
+
}
|
|
95
|
+
return ClipboardContentType.Text;
|
|
96
|
+
}
|
|
97
|
+
static async writeRichContent(data) {
|
|
98
|
+
if (typeof ClipboardItem === 'undefined') {
|
|
99
|
+
throw ClipboardWeb.createException(ClipboardWeb.errorRichContentNotSupported, ErrorCode.WriteFailed);
|
|
100
|
+
}
|
|
101
|
+
await navigator.clipboard.write([new ClipboardItem(data)]);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
ClipboardWeb.errorContentMissing = 'One of text, html, image or url must be provided.';
|
|
105
|
+
ClipboardWeb.errorEmptyClipboard = 'The clipboard is empty.';
|
|
106
|
+
ClipboardWeb.errorReadFailed = 'The clipboard content could not be read.';
|
|
107
|
+
ClipboardWeb.errorRichContentNotSupported = 'This browser does not support writing rich content to the clipboard.';
|
|
108
|
+
ClipboardWeb.errorWriteFailed = 'The content could not be written to the clipboard.';
|
|
109
|
+
//# sourceMappingURL=web.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"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","sourcesContent":["import { CapacitorException, WebPlugin } from '@capacitor/core';\n\nimport { ClipboardContentType, ErrorCode } from './definitions';\nimport type { ClipboardPlugin, ReadResult, WriteOptions } from './definitions';\n\nexport class ClipboardWeb extends WebPlugin implements ClipboardPlugin {\n private static readonly errorContentMissing =\n 'One of text, html, image or url must be provided.';\n private static readonly errorEmptyClipboard = 'The clipboard is empty.';\n private static readonly errorReadFailed =\n 'The clipboard content could not be read.';\n private static readonly errorRichContentNotSupported =\n 'This browser does not support writing rich content to the clipboard.';\n private static readonly errorWriteFailed =\n 'The content could not be written to the clipboard.';\n\n async read(): Promise<ReadResult> {\n if (navigator.clipboard.read) {\n try {\n const items = await navigator.clipboard.read();\n for (const item of items) {\n const imageType = item.types.find(type => type.startsWith('image/'));\n if (imageType) {\n const blob = await item.getType(imageType);\n const value = await ClipboardWeb.convertBlobToDataUrl(blob);\n return { type: ClipboardContentType.Image, value };\n }\n }\n for (const item of items) {\n if (item.types.includes('text/html')) {\n const blob = await item.getType('text/html');\n const value = await blob.text();\n return { type: ClipboardContentType.Html, value };\n }\n }\n } catch (error) {\n throw ClipboardWeb.createException(\n ClipboardWeb.errorReadFailed,\n ErrorCode.ReadFailed,\n );\n }\n }\n let value: string;\n try {\n value = await navigator.clipboard.readText();\n } catch (error) {\n throw ClipboardWeb.createException(\n ClipboardWeb.errorReadFailed,\n ErrorCode.ReadFailed,\n );\n }\n if (!value) {\n throw ClipboardWeb.createException(\n ClipboardWeb.errorEmptyClipboard,\n ErrorCode.EmptyClipboard,\n );\n }\n return { type: ClipboardWeb.resolveTextType(value), value };\n }\n\n async write(options: WriteOptions): Promise<void> {\n if (\n options.html === undefined &&\n options.image === undefined &&\n options.text === undefined &&\n options.url === undefined\n ) {\n throw new Error(ClipboardWeb.errorContentMissing);\n }\n try {\n if (options.image !== undefined) {\n await ClipboardWeb.writeRichContent({\n 'image/png': await ClipboardWeb.convertDataUrlToBlob(options.image),\n });\n } else if (options.html !== undefined) {\n const data: Record<string, Blob> = {\n 'text/html': new Blob([options.html], { type: 'text/html' }),\n };\n if (options.text !== undefined) {\n data['text/plain'] = new Blob([options.text], { type: 'text/plain' });\n }\n await ClipboardWeb.writeRichContent(data);\n } else if (options.url !== undefined) {\n await navigator.clipboard.writeText(options.url);\n } else if (options.text !== undefined) {\n await navigator.clipboard.writeText(options.text);\n }\n } catch (error) {\n if (error instanceof CapacitorException) {\n throw error;\n }\n throw ClipboardWeb.createException(\n ClipboardWeb.errorWriteFailed,\n ErrorCode.WriteFailed,\n );\n }\n }\n\n private static convertBlobToDataUrl(blob: Blob): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onloadend = () => resolve(reader.result as string);\n reader.onerror = () => reject(reader.error);\n reader.readAsDataURL(blob);\n });\n }\n\n private static async convertDataUrlToBlob(dataUrl: string): Promise<Blob> {\n const response = await fetch(dataUrl);\n return response.blob();\n }\n\n private static createException(\n message: string,\n code: ErrorCode,\n ): CapacitorException {\n return new CapacitorException(message, undefined, { code });\n }\n\n private static resolveTextType(value: string): ClipboardContentType {\n if (value.startsWith('http://') || value.startsWith('https://')) {\n return ClipboardContentType.Url;\n }\n return ClipboardContentType.Text;\n }\n\n private static async writeRichContent(\n data: Record<string, Blob>,\n ): Promise<void> {\n if (typeof ClipboardItem === 'undefined') {\n throw ClipboardWeb.createException(\n ClipboardWeb.errorRichContentNotSupported,\n ErrorCode.WriteFailed,\n );\n }\n await navigator.clipboard.write([new ClipboardItem(data)]);\n }\n}\n"]}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var core = require('@capacitor/core');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The type of content stored on the clipboard.
|
|
7
|
+
*
|
|
8
|
+
* @since 0.1.0
|
|
9
|
+
*/
|
|
10
|
+
exports.ClipboardContentType = void 0;
|
|
11
|
+
(function (ClipboardContentType) {
|
|
12
|
+
/**
|
|
13
|
+
* The content is HTML.
|
|
14
|
+
*
|
|
15
|
+
* @since 0.1.0
|
|
16
|
+
*/
|
|
17
|
+
ClipboardContentType["Html"] = "HTML";
|
|
18
|
+
/**
|
|
19
|
+
* The content is an image, returned as a Base64-encoded data URL.
|
|
20
|
+
*
|
|
21
|
+
* @since 0.1.0
|
|
22
|
+
*/
|
|
23
|
+
ClipboardContentType["Image"] = "IMAGE";
|
|
24
|
+
/**
|
|
25
|
+
* The content is plain text.
|
|
26
|
+
*
|
|
27
|
+
* @since 0.1.0
|
|
28
|
+
*/
|
|
29
|
+
ClipboardContentType["Text"] = "TEXT";
|
|
30
|
+
/**
|
|
31
|
+
* The content is a URL.
|
|
32
|
+
*
|
|
33
|
+
* @since 0.1.0
|
|
34
|
+
*/
|
|
35
|
+
ClipboardContentType["Url"] = "URL";
|
|
36
|
+
})(exports.ClipboardContentType || (exports.ClipboardContentType = {}));
|
|
37
|
+
/**
|
|
38
|
+
* @since 0.1.0
|
|
39
|
+
*/
|
|
40
|
+
exports.ErrorCode = void 0;
|
|
41
|
+
(function (ErrorCode) {
|
|
42
|
+
/**
|
|
43
|
+
* The clipboard is empty.
|
|
44
|
+
*
|
|
45
|
+
* @since 0.1.0
|
|
46
|
+
*/
|
|
47
|
+
ErrorCode["EmptyClipboard"] = "EMPTY_CLIPBOARD";
|
|
48
|
+
/**
|
|
49
|
+
* The clipboard content could not be read.
|
|
50
|
+
*
|
|
51
|
+
* @since 0.1.0
|
|
52
|
+
*/
|
|
53
|
+
ErrorCode["ReadFailed"] = "READ_FAILED";
|
|
54
|
+
/**
|
|
55
|
+
* The content could not be written to the clipboard.
|
|
56
|
+
*
|
|
57
|
+
* @since 0.1.0
|
|
58
|
+
*/
|
|
59
|
+
ErrorCode["WriteFailed"] = "WRITE_FAILED";
|
|
60
|
+
})(exports.ErrorCode || (exports.ErrorCode = {}));
|
|
61
|
+
|
|
62
|
+
const Clipboard = core.registerPlugin('Clipboard', {
|
|
63
|
+
web: () => Promise.resolve().then(function () { return web; }).then(m => new m.ClipboardWeb()),
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
class ClipboardWeb extends core.WebPlugin {
|
|
67
|
+
async read() {
|
|
68
|
+
if (navigator.clipboard.read) {
|
|
69
|
+
try {
|
|
70
|
+
const items = await navigator.clipboard.read();
|
|
71
|
+
for (const item of items) {
|
|
72
|
+
const imageType = item.types.find(type => type.startsWith('image/'));
|
|
73
|
+
if (imageType) {
|
|
74
|
+
const blob = await item.getType(imageType);
|
|
75
|
+
const value = await ClipboardWeb.convertBlobToDataUrl(blob);
|
|
76
|
+
return { type: exports.ClipboardContentType.Image, value };
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
for (const item of items) {
|
|
80
|
+
if (item.types.includes('text/html')) {
|
|
81
|
+
const blob = await item.getType('text/html');
|
|
82
|
+
const value = await blob.text();
|
|
83
|
+
return { type: exports.ClipboardContentType.Html, value };
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
throw ClipboardWeb.createException(ClipboardWeb.errorReadFailed, exports.ErrorCode.ReadFailed);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
let value;
|
|
92
|
+
try {
|
|
93
|
+
value = await navigator.clipboard.readText();
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
throw ClipboardWeb.createException(ClipboardWeb.errorReadFailed, exports.ErrorCode.ReadFailed);
|
|
97
|
+
}
|
|
98
|
+
if (!value) {
|
|
99
|
+
throw ClipboardWeb.createException(ClipboardWeb.errorEmptyClipboard, exports.ErrorCode.EmptyClipboard);
|
|
100
|
+
}
|
|
101
|
+
return { type: ClipboardWeb.resolveTextType(value), value };
|
|
102
|
+
}
|
|
103
|
+
async write(options) {
|
|
104
|
+
if (options.html === undefined &&
|
|
105
|
+
options.image === undefined &&
|
|
106
|
+
options.text === undefined &&
|
|
107
|
+
options.url === undefined) {
|
|
108
|
+
throw new Error(ClipboardWeb.errorContentMissing);
|
|
109
|
+
}
|
|
110
|
+
try {
|
|
111
|
+
if (options.image !== undefined) {
|
|
112
|
+
await ClipboardWeb.writeRichContent({
|
|
113
|
+
'image/png': await ClipboardWeb.convertDataUrlToBlob(options.image),
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
else if (options.html !== undefined) {
|
|
117
|
+
const data = {
|
|
118
|
+
'text/html': new Blob([options.html], { type: 'text/html' }),
|
|
119
|
+
};
|
|
120
|
+
if (options.text !== undefined) {
|
|
121
|
+
data['text/plain'] = new Blob([options.text], { type: 'text/plain' });
|
|
122
|
+
}
|
|
123
|
+
await ClipboardWeb.writeRichContent(data);
|
|
124
|
+
}
|
|
125
|
+
else if (options.url !== undefined) {
|
|
126
|
+
await navigator.clipboard.writeText(options.url);
|
|
127
|
+
}
|
|
128
|
+
else if (options.text !== undefined) {
|
|
129
|
+
await navigator.clipboard.writeText(options.text);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
if (error instanceof core.CapacitorException) {
|
|
134
|
+
throw error;
|
|
135
|
+
}
|
|
136
|
+
throw ClipboardWeb.createException(ClipboardWeb.errorWriteFailed, exports.ErrorCode.WriteFailed);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
static convertBlobToDataUrl(blob) {
|
|
140
|
+
return new Promise((resolve, reject) => {
|
|
141
|
+
const reader = new FileReader();
|
|
142
|
+
reader.onloadend = () => resolve(reader.result);
|
|
143
|
+
reader.onerror = () => reject(reader.error);
|
|
144
|
+
reader.readAsDataURL(blob);
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
static async convertDataUrlToBlob(dataUrl) {
|
|
148
|
+
const response = await fetch(dataUrl);
|
|
149
|
+
return response.blob();
|
|
150
|
+
}
|
|
151
|
+
static createException(message, code) {
|
|
152
|
+
return new core.CapacitorException(message, undefined, { code });
|
|
153
|
+
}
|
|
154
|
+
static resolveTextType(value) {
|
|
155
|
+
if (value.startsWith('http://') || value.startsWith('https://')) {
|
|
156
|
+
return exports.ClipboardContentType.Url;
|
|
157
|
+
}
|
|
158
|
+
return exports.ClipboardContentType.Text;
|
|
159
|
+
}
|
|
160
|
+
static async writeRichContent(data) {
|
|
161
|
+
if (typeof ClipboardItem === 'undefined') {
|
|
162
|
+
throw ClipboardWeb.createException(ClipboardWeb.errorRichContentNotSupported, exports.ErrorCode.WriteFailed);
|
|
163
|
+
}
|
|
164
|
+
await navigator.clipboard.write([new ClipboardItem(data)]);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
ClipboardWeb.errorContentMissing = 'One of text, html, image or url must be provided.';
|
|
168
|
+
ClipboardWeb.errorEmptyClipboard = 'The clipboard is empty.';
|
|
169
|
+
ClipboardWeb.errorReadFailed = 'The clipboard content could not be read.';
|
|
170
|
+
ClipboardWeb.errorRichContentNotSupported = 'This browser does not support writing rich content to the clipboard.';
|
|
171
|
+
ClipboardWeb.errorWriteFailed = 'The content could not be written to the clipboard.';
|
|
172
|
+
|
|
173
|
+
var web = /*#__PURE__*/Object.freeze({
|
|
174
|
+
__proto__: null,
|
|
175
|
+
ClipboardWeb: ClipboardWeb
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
exports.Clipboard = Clipboard;
|
|
179
|
+
//# sourceMappingURL=plugin.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.cjs.js","sources":["esm/definitions.js","esm/index.js","esm/web.js"],"sourcesContent":["/**\n * The type of content stored on the clipboard.\n *\n * @since 0.1.0\n */\nexport var ClipboardContentType;\n(function (ClipboardContentType) {\n /**\n * The content is HTML.\n *\n * @since 0.1.0\n */\n ClipboardContentType[\"Html\"] = \"HTML\";\n /**\n * The content is an image, returned as a Base64-encoded data URL.\n *\n * @since 0.1.0\n */\n ClipboardContentType[\"Image\"] = \"IMAGE\";\n /**\n * The content is plain text.\n *\n * @since 0.1.0\n */\n ClipboardContentType[\"Text\"] = \"TEXT\";\n /**\n * The content is a URL.\n *\n * @since 0.1.0\n */\n ClipboardContentType[\"Url\"] = \"URL\";\n})(ClipboardContentType || (ClipboardContentType = {}));\n/**\n * @since 0.1.0\n */\nexport var ErrorCode;\n(function (ErrorCode) {\n /**\n * The clipboard is empty.\n *\n * @since 0.1.0\n */\n ErrorCode[\"EmptyClipboard\"] = \"EMPTY_CLIPBOARD\";\n /**\n * The clipboard content could not be read.\n *\n * @since 0.1.0\n */\n ErrorCode[\"ReadFailed\"] = \"READ_FAILED\";\n /**\n * The content could not be written to the clipboard.\n *\n * @since 0.1.0\n */\n ErrorCode[\"WriteFailed\"] = \"WRITE_FAILED\";\n})(ErrorCode || (ErrorCode = {}));\n//# sourceMappingURL=definitions.js.map","import { registerPlugin } from '@capacitor/core';\nconst Clipboard = registerPlugin('Clipboard', {\n web: () => import('./web').then(m => new m.ClipboardWeb()),\n});\nexport * from './definitions';\nexport { Clipboard };\n//# sourceMappingURL=index.js.map","import { CapacitorException, WebPlugin } from '@capacitor/core';\nimport { ClipboardContentType, ErrorCode } from './definitions';\nexport class ClipboardWeb extends WebPlugin {\n async read() {\n if (navigator.clipboard.read) {\n try {\n const items = await navigator.clipboard.read();\n for (const item of items) {\n const imageType = item.types.find(type => type.startsWith('image/'));\n if (imageType) {\n const blob = await item.getType(imageType);\n const value = await ClipboardWeb.convertBlobToDataUrl(blob);\n return { type: ClipboardContentType.Image, value };\n }\n }\n for (const item of items) {\n if (item.types.includes('text/html')) {\n const blob = await item.getType('text/html');\n const value = await blob.text();\n return { type: ClipboardContentType.Html, value };\n }\n }\n }\n catch (error) {\n throw ClipboardWeb.createException(ClipboardWeb.errorReadFailed, ErrorCode.ReadFailed);\n }\n }\n let value;\n try {\n value = await navigator.clipboard.readText();\n }\n catch (error) {\n throw ClipboardWeb.createException(ClipboardWeb.errorReadFailed, ErrorCode.ReadFailed);\n }\n if (!value) {\n throw ClipboardWeb.createException(ClipboardWeb.errorEmptyClipboard, ErrorCode.EmptyClipboard);\n }\n return { type: ClipboardWeb.resolveTextType(value), value };\n }\n async write(options) {\n if (options.html === undefined &&\n options.image === undefined &&\n options.text === undefined &&\n options.url === undefined) {\n throw new Error(ClipboardWeb.errorContentMissing);\n }\n try {\n if (options.image !== undefined) {\n await ClipboardWeb.writeRichContent({\n 'image/png': await ClipboardWeb.convertDataUrlToBlob(options.image),\n });\n }\n else if (options.html !== undefined) {\n const data = {\n 'text/html': new Blob([options.html], { type: 'text/html' }),\n };\n if (options.text !== undefined) {\n data['text/plain'] = new Blob([options.text], { type: 'text/plain' });\n }\n await ClipboardWeb.writeRichContent(data);\n }\n else if (options.url !== undefined) {\n await navigator.clipboard.writeText(options.url);\n }\n else if (options.text !== undefined) {\n await navigator.clipboard.writeText(options.text);\n }\n }\n catch (error) {\n if (error instanceof CapacitorException) {\n throw error;\n }\n throw ClipboardWeb.createException(ClipboardWeb.errorWriteFailed, ErrorCode.WriteFailed);\n }\n }\n static convertBlobToDataUrl(blob) {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onloadend = () => resolve(reader.result);\n reader.onerror = () => reject(reader.error);\n reader.readAsDataURL(blob);\n });\n }\n static async convertDataUrlToBlob(dataUrl) {\n const response = await fetch(dataUrl);\n return response.blob();\n }\n static createException(message, code) {\n return new CapacitorException(message, undefined, { code });\n }\n static resolveTextType(value) {\n if (value.startsWith('http://') || value.startsWith('https://')) {\n return ClipboardContentType.Url;\n }\n return ClipboardContentType.Text;\n }\n static async writeRichContent(data) {\n if (typeof ClipboardItem === 'undefined') {\n throw ClipboardWeb.createException(ClipboardWeb.errorRichContentNotSupported, ErrorCode.WriteFailed);\n }\n await navigator.clipboard.write([new ClipboardItem(data)]);\n }\n}\nClipboardWeb.errorContentMissing = 'One of text, html, image or url must be provided.';\nClipboardWeb.errorEmptyClipboard = 'The clipboard is empty.';\nClipboardWeb.errorReadFailed = 'The clipboard content could not be read.';\nClipboardWeb.errorRichContentNotSupported = 'This browser does not support writing rich content to the clipboard.';\nClipboardWeb.errorWriteFailed = 'The content could not be written to the clipboard.';\n//# sourceMappingURL=web.js.map"],"names":["ClipboardContentType","ErrorCode","registerPlugin","WebPlugin","CapacitorException"],"mappings":";;;;AAAA;AACA;AACA;AACA;AACA;AACWA;AACX,CAAC,UAAU,oBAAoB,EAAE;AACjC;AACA;AACA;AACA;AACA;AACA,IAAI,oBAAoB,CAAC,MAAM,CAAC,GAAG,MAAM;AACzC;AACA;AACA;AACA;AACA;AACA,IAAI,oBAAoB,CAAC,OAAO,CAAC,GAAG,OAAO;AAC3C;AACA;AACA;AACA;AACA;AACA,IAAI,oBAAoB,CAAC,MAAM,CAAC,GAAG,MAAM;AACzC;AACA;AACA;AACA;AACA;AACA,IAAI,oBAAoB,CAAC,KAAK,CAAC,GAAG,KAAK;AACvC,CAAC,EAAEA,4BAAoB,KAAKA,4BAAoB,GAAG,EAAE,CAAC,CAAC;AACvD;AACA;AACA;AACWC;AACX,CAAC,UAAU,SAAS,EAAE;AACtB;AACA;AACA;AACA;AACA;AACA,IAAI,SAAS,CAAC,gBAAgB,CAAC,GAAG,iBAAiB;AACnD;AACA;AACA;AACA;AACA;AACA,IAAI,SAAS,CAAC,YAAY,CAAC,GAAG,aAAa;AAC3C;AACA;AACA;AACA;AACA;AACA,IAAI,SAAS,CAAC,aAAa,CAAC,GAAG,cAAc;AAC7C,CAAC,EAAEA,iBAAS,KAAKA,iBAAS,GAAG,EAAE,CAAC,CAAC;;ACtD5B,MAAC,SAAS,GAAGC,mBAAc,CAAC,WAAW,EAAE;AAC9C,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,YAAY,EAAE,CAAC;AAC9D,CAAC;;ACDM,MAAM,YAAY,SAASC,cAAS,CAAC;AAC5C,IAAI,MAAM,IAAI,GAAG;AACjB,QAAQ,IAAI,SAAS,CAAC,SAAS,CAAC,IAAI,EAAE;AACtC,YAAY,IAAI;AAChB,gBAAgB,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,SAAS,CAAC,IAAI,EAAE;AAC9D,gBAAgB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;AAC1C,oBAAoB,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;AACxF,oBAAoB,IAAI,SAAS,EAAE;AACnC,wBAAwB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC;AAClE,wBAAwB,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,oBAAoB,CAAC,IAAI,CAAC;AACnF,wBAAwB,OAAO,EAAE,IAAI,EAAEH,4BAAoB,CAAC,KAAK,EAAE,KAAK,EAAE;AAC1E,oBAAoB;AACpB,gBAAgB;AAChB,gBAAgB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;AAC1C,oBAAoB,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE;AAC1D,wBAAwB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC;AACpE,wBAAwB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE;AACvD,wBAAwB,OAAO,EAAE,IAAI,EAAEA,4BAAoB,CAAC,IAAI,EAAE,KAAK,EAAE;AACzE,oBAAoB;AACpB,gBAAgB;AAChB,YAAY;AACZ,YAAY,OAAO,KAAK,EAAE;AAC1B,gBAAgB,MAAM,YAAY,CAAC,eAAe,CAAC,YAAY,CAAC,eAAe,EAAEC,iBAAS,CAAC,UAAU,CAAC;AACtG,YAAY;AACZ,QAAQ;AACR,QAAQ,IAAI,KAAK;AACjB,QAAQ,IAAI;AACZ,YAAY,KAAK,GAAG,MAAM,SAAS,CAAC,SAAS,CAAC,QAAQ,EAAE;AACxD,QAAQ;AACR,QAAQ,OAAO,KAAK,EAAE;AACtB,YAAY,MAAM,YAAY,CAAC,eAAe,CAAC,YAAY,CAAC,eAAe,EAAEA,iBAAS,CAAC,UAAU,CAAC;AAClG,QAAQ;AACR,QAAQ,IAAI,CAAC,KAAK,EAAE;AACpB,YAAY,MAAM,YAAY,CAAC,eAAe,CAAC,YAAY,CAAC,mBAAmB,EAAEA,iBAAS,CAAC,cAAc,CAAC;AAC1G,QAAQ;AACR,QAAQ,OAAO,EAAE,IAAI,EAAE,YAAY,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE;AACnE,IAAI;AACJ,IAAI,MAAM,KAAK,CAAC,OAAO,EAAE;AACzB,QAAQ,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS;AACtC,YAAY,OAAO,CAAC,KAAK,KAAK,SAAS;AACvC,YAAY,OAAO,CAAC,IAAI,KAAK,SAAS;AACtC,YAAY,OAAO,CAAC,GAAG,KAAK,SAAS,EAAE;AACvC,YAAY,MAAM,IAAI,KAAK,CAAC,YAAY,CAAC,mBAAmB,CAAC;AAC7D,QAAQ;AACR,QAAQ,IAAI;AACZ,YAAY,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,EAAE;AAC7C,gBAAgB,MAAM,YAAY,CAAC,gBAAgB,CAAC;AACpD,oBAAoB,WAAW,EAAE,MAAM,YAAY,CAAC,oBAAoB,CAAC,OAAO,CAAC,KAAK,CAAC;AACvF,iBAAiB,CAAC;AAClB,YAAY;AACZ,iBAAiB,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE;AACjD,gBAAgB,MAAM,IAAI,GAAG;AAC7B,oBAAoB,WAAW,EAAE,IAAI,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;AAChF,iBAAiB;AACjB,gBAAgB,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE;AAChD,oBAAoB,IAAI,CAAC,YAAY,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;AACzF,gBAAgB;AAChB,gBAAgB,MAAM,YAAY,CAAC,gBAAgB,CAAC,IAAI,CAAC;AACzD,YAAY;AACZ,iBAAiB,IAAI,OAAO,CAAC,GAAG,KAAK,SAAS,EAAE;AAChD,gBAAgB,MAAM,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC;AAChE,YAAY;AACZ,iBAAiB,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE;AACjD,gBAAgB,MAAM,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC;AACjE,YAAY;AACZ,QAAQ;AACR,QAAQ,OAAO,KAAK,EAAE;AACtB,YAAY,IAAI,KAAK,YAAYG,uBAAkB,EAAE;AACrD,gBAAgB,MAAM,KAAK;AAC3B,YAAY;AACZ,YAAY,MAAM,YAAY,CAAC,eAAe,CAAC,YAAY,CAAC,gBAAgB,EAAEH,iBAAS,CAAC,WAAW,CAAC;AACpG,QAAQ;AACR,IAAI;AACJ,IAAI,OAAO,oBAAoB,CAAC,IAAI,EAAE;AACtC,QAAQ,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK;AAChD,YAAY,MAAM,MAAM,GAAG,IAAI,UAAU,EAAE;AAC3C,YAAY,MAAM,CAAC,SAAS,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC;AAC3D,YAAY,MAAM,CAAC,OAAO,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;AACvD,YAAY,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC;AACtC,QAAQ,CAAC,CAAC;AACV,IAAI;AACJ,IAAI,aAAa,oBAAoB,CAAC,OAAO,EAAE;AAC/C,QAAQ,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC;AAC7C,QAAQ,OAAO,QAAQ,CAAC,IAAI,EAAE;AAC9B,IAAI;AACJ,IAAI,OAAO,eAAe,CAAC,OAAO,EAAE,IAAI,EAAE;AAC1C,QAAQ,OAAO,IAAIG,uBAAkB,CAAC,OAAO,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,CAAC;AACnE,IAAI;AACJ,IAAI,OAAO,eAAe,CAAC,KAAK,EAAE;AAClC,QAAQ,IAAI,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE;AACzE,YAAY,OAAOJ,4BAAoB,CAAC,GAAG;AAC3C,QAAQ;AACR,QAAQ,OAAOA,4BAAoB,CAAC,IAAI;AACxC,IAAI;AACJ,IAAI,aAAa,gBAAgB,CAAC,IAAI,EAAE;AACxC,QAAQ,IAAI,OAAO,aAAa,KAAK,WAAW,EAAE;AAClD,YAAY,MAAM,YAAY,CAAC,eAAe,CAAC,YAAY,CAAC,4BAA4B,EAAEC,iBAAS,CAAC,WAAW,CAAC;AAChH,QAAQ;AACR,QAAQ,MAAM,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,IAAI,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC;AAClE,IAAI;AACJ;AACA,YAAY,CAAC,mBAAmB,GAAG,mDAAmD;AACtF,YAAY,CAAC,mBAAmB,GAAG,yBAAyB;AAC5D,YAAY,CAAC,eAAe,GAAG,0CAA0C;AACzE,YAAY,CAAC,4BAA4B,GAAG,sEAAsE;AAClH,YAAY,CAAC,gBAAgB,GAAG,oDAAoD;;;;;;;;;"}
|
package/dist/plugin.js
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
var capacitorClipboard = (function (exports, core) {
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The type of content stored on the clipboard.
|
|
6
|
+
*
|
|
7
|
+
* @since 0.1.0
|
|
8
|
+
*/
|
|
9
|
+
exports.ClipboardContentType = void 0;
|
|
10
|
+
(function (ClipboardContentType) {
|
|
11
|
+
/**
|
|
12
|
+
* The content is HTML.
|
|
13
|
+
*
|
|
14
|
+
* @since 0.1.0
|
|
15
|
+
*/
|
|
16
|
+
ClipboardContentType["Html"] = "HTML";
|
|
17
|
+
/**
|
|
18
|
+
* The content is an image, returned as a Base64-encoded data URL.
|
|
19
|
+
*
|
|
20
|
+
* @since 0.1.0
|
|
21
|
+
*/
|
|
22
|
+
ClipboardContentType["Image"] = "IMAGE";
|
|
23
|
+
/**
|
|
24
|
+
* The content is plain text.
|
|
25
|
+
*
|
|
26
|
+
* @since 0.1.0
|
|
27
|
+
*/
|
|
28
|
+
ClipboardContentType["Text"] = "TEXT";
|
|
29
|
+
/**
|
|
30
|
+
* The content is a URL.
|
|
31
|
+
*
|
|
32
|
+
* @since 0.1.0
|
|
33
|
+
*/
|
|
34
|
+
ClipboardContentType["Url"] = "URL";
|
|
35
|
+
})(exports.ClipboardContentType || (exports.ClipboardContentType = {}));
|
|
36
|
+
/**
|
|
37
|
+
* @since 0.1.0
|
|
38
|
+
*/
|
|
39
|
+
exports.ErrorCode = void 0;
|
|
40
|
+
(function (ErrorCode) {
|
|
41
|
+
/**
|
|
42
|
+
* The clipboard is empty.
|
|
43
|
+
*
|
|
44
|
+
* @since 0.1.0
|
|
45
|
+
*/
|
|
46
|
+
ErrorCode["EmptyClipboard"] = "EMPTY_CLIPBOARD";
|
|
47
|
+
/**
|
|
48
|
+
* The clipboard content could not be read.
|
|
49
|
+
*
|
|
50
|
+
* @since 0.1.0
|
|
51
|
+
*/
|
|
52
|
+
ErrorCode["ReadFailed"] = "READ_FAILED";
|
|
53
|
+
/**
|
|
54
|
+
* The content could not be written to the clipboard.
|
|
55
|
+
*
|
|
56
|
+
* @since 0.1.0
|
|
57
|
+
*/
|
|
58
|
+
ErrorCode["WriteFailed"] = "WRITE_FAILED";
|
|
59
|
+
})(exports.ErrorCode || (exports.ErrorCode = {}));
|
|
60
|
+
|
|
61
|
+
const Clipboard = core.registerPlugin('Clipboard', {
|
|
62
|
+
web: () => Promise.resolve().then(function () { return web; }).then(m => new m.ClipboardWeb()),
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
class ClipboardWeb extends core.WebPlugin {
|
|
66
|
+
async read() {
|
|
67
|
+
if (navigator.clipboard.read) {
|
|
68
|
+
try {
|
|
69
|
+
const items = await navigator.clipboard.read();
|
|
70
|
+
for (const item of items) {
|
|
71
|
+
const imageType = item.types.find(type => type.startsWith('image/'));
|
|
72
|
+
if (imageType) {
|
|
73
|
+
const blob = await item.getType(imageType);
|
|
74
|
+
const value = await ClipboardWeb.convertBlobToDataUrl(blob);
|
|
75
|
+
return { type: exports.ClipboardContentType.Image, value };
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
for (const item of items) {
|
|
79
|
+
if (item.types.includes('text/html')) {
|
|
80
|
+
const blob = await item.getType('text/html');
|
|
81
|
+
const value = await blob.text();
|
|
82
|
+
return { type: exports.ClipboardContentType.Html, value };
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
throw ClipboardWeb.createException(ClipboardWeb.errorReadFailed, exports.ErrorCode.ReadFailed);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
let value;
|
|
91
|
+
try {
|
|
92
|
+
value = await navigator.clipboard.readText();
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
throw ClipboardWeb.createException(ClipboardWeb.errorReadFailed, exports.ErrorCode.ReadFailed);
|
|
96
|
+
}
|
|
97
|
+
if (!value) {
|
|
98
|
+
throw ClipboardWeb.createException(ClipboardWeb.errorEmptyClipboard, exports.ErrorCode.EmptyClipboard);
|
|
99
|
+
}
|
|
100
|
+
return { type: ClipboardWeb.resolveTextType(value), value };
|
|
101
|
+
}
|
|
102
|
+
async write(options) {
|
|
103
|
+
if (options.html === undefined &&
|
|
104
|
+
options.image === undefined &&
|
|
105
|
+
options.text === undefined &&
|
|
106
|
+
options.url === undefined) {
|
|
107
|
+
throw new Error(ClipboardWeb.errorContentMissing);
|
|
108
|
+
}
|
|
109
|
+
try {
|
|
110
|
+
if (options.image !== undefined) {
|
|
111
|
+
await ClipboardWeb.writeRichContent({
|
|
112
|
+
'image/png': await ClipboardWeb.convertDataUrlToBlob(options.image),
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
else if (options.html !== undefined) {
|
|
116
|
+
const data = {
|
|
117
|
+
'text/html': new Blob([options.html], { type: 'text/html' }),
|
|
118
|
+
};
|
|
119
|
+
if (options.text !== undefined) {
|
|
120
|
+
data['text/plain'] = new Blob([options.text], { type: 'text/plain' });
|
|
121
|
+
}
|
|
122
|
+
await ClipboardWeb.writeRichContent(data);
|
|
123
|
+
}
|
|
124
|
+
else if (options.url !== undefined) {
|
|
125
|
+
await navigator.clipboard.writeText(options.url);
|
|
126
|
+
}
|
|
127
|
+
else if (options.text !== undefined) {
|
|
128
|
+
await navigator.clipboard.writeText(options.text);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
if (error instanceof core.CapacitorException) {
|
|
133
|
+
throw error;
|
|
134
|
+
}
|
|
135
|
+
throw ClipboardWeb.createException(ClipboardWeb.errorWriteFailed, exports.ErrorCode.WriteFailed);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
static convertBlobToDataUrl(blob) {
|
|
139
|
+
return new Promise((resolve, reject) => {
|
|
140
|
+
const reader = new FileReader();
|
|
141
|
+
reader.onloadend = () => resolve(reader.result);
|
|
142
|
+
reader.onerror = () => reject(reader.error);
|
|
143
|
+
reader.readAsDataURL(blob);
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
static async convertDataUrlToBlob(dataUrl) {
|
|
147
|
+
const response = await fetch(dataUrl);
|
|
148
|
+
return response.blob();
|
|
149
|
+
}
|
|
150
|
+
static createException(message, code) {
|
|
151
|
+
return new core.CapacitorException(message, undefined, { code });
|
|
152
|
+
}
|
|
153
|
+
static resolveTextType(value) {
|
|
154
|
+
if (value.startsWith('http://') || value.startsWith('https://')) {
|
|
155
|
+
return exports.ClipboardContentType.Url;
|
|
156
|
+
}
|
|
157
|
+
return exports.ClipboardContentType.Text;
|
|
158
|
+
}
|
|
159
|
+
static async writeRichContent(data) {
|
|
160
|
+
if (typeof ClipboardItem === 'undefined') {
|
|
161
|
+
throw ClipboardWeb.createException(ClipboardWeb.errorRichContentNotSupported, exports.ErrorCode.WriteFailed);
|
|
162
|
+
}
|
|
163
|
+
await navigator.clipboard.write([new ClipboardItem(data)]);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
ClipboardWeb.errorContentMissing = 'One of text, html, image or url must be provided.';
|
|
167
|
+
ClipboardWeb.errorEmptyClipboard = 'The clipboard is empty.';
|
|
168
|
+
ClipboardWeb.errorReadFailed = 'The clipboard content could not be read.';
|
|
169
|
+
ClipboardWeb.errorRichContentNotSupported = 'This browser does not support writing rich content to the clipboard.';
|
|
170
|
+
ClipboardWeb.errorWriteFailed = 'The content could not be written to the clipboard.';
|
|
171
|
+
|
|
172
|
+
var web = /*#__PURE__*/Object.freeze({
|
|
173
|
+
__proto__: null,
|
|
174
|
+
ClipboardWeb: ClipboardWeb
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
exports.Clipboard = Clipboard;
|
|
178
|
+
|
|
179
|
+
return exports;
|
|
180
|
+
|
|
181
|
+
})({}, capacitorExports);
|
|
182
|
+
//# sourceMappingURL=plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sources":["esm/definitions.js","esm/index.js","esm/web.js"],"sourcesContent":["/**\n * The type of content stored on the clipboard.\n *\n * @since 0.1.0\n */\nexport var ClipboardContentType;\n(function (ClipboardContentType) {\n /**\n * The content is HTML.\n *\n * @since 0.1.0\n */\n ClipboardContentType[\"Html\"] = \"HTML\";\n /**\n * The content is an image, returned as a Base64-encoded data URL.\n *\n * @since 0.1.0\n */\n ClipboardContentType[\"Image\"] = \"IMAGE\";\n /**\n * The content is plain text.\n *\n * @since 0.1.0\n */\n ClipboardContentType[\"Text\"] = \"TEXT\";\n /**\n * The content is a URL.\n *\n * @since 0.1.0\n */\n ClipboardContentType[\"Url\"] = \"URL\";\n})(ClipboardContentType || (ClipboardContentType = {}));\n/**\n * @since 0.1.0\n */\nexport var ErrorCode;\n(function (ErrorCode) {\n /**\n * The clipboard is empty.\n *\n * @since 0.1.0\n */\n ErrorCode[\"EmptyClipboard\"] = \"EMPTY_CLIPBOARD\";\n /**\n * The clipboard content could not be read.\n *\n * @since 0.1.0\n */\n ErrorCode[\"ReadFailed\"] = \"READ_FAILED\";\n /**\n * The content could not be written to the clipboard.\n *\n * @since 0.1.0\n */\n ErrorCode[\"WriteFailed\"] = \"WRITE_FAILED\";\n})(ErrorCode || (ErrorCode = {}));\n//# sourceMappingURL=definitions.js.map","import { registerPlugin } from '@capacitor/core';\nconst Clipboard = registerPlugin('Clipboard', {\n web: () => import('./web').then(m => new m.ClipboardWeb()),\n});\nexport * from './definitions';\nexport { Clipboard };\n//# sourceMappingURL=index.js.map","import { CapacitorException, WebPlugin } from '@capacitor/core';\nimport { ClipboardContentType, ErrorCode } from './definitions';\nexport class ClipboardWeb extends WebPlugin {\n async read() {\n if (navigator.clipboard.read) {\n try {\n const items = await navigator.clipboard.read();\n for (const item of items) {\n const imageType = item.types.find(type => type.startsWith('image/'));\n if (imageType) {\n const blob = await item.getType(imageType);\n const value = await ClipboardWeb.convertBlobToDataUrl(blob);\n return { type: ClipboardContentType.Image, value };\n }\n }\n for (const item of items) {\n if (item.types.includes('text/html')) {\n const blob = await item.getType('text/html');\n const value = await blob.text();\n return { type: ClipboardContentType.Html, value };\n }\n }\n }\n catch (error) {\n throw ClipboardWeb.createException(ClipboardWeb.errorReadFailed, ErrorCode.ReadFailed);\n }\n }\n let value;\n try {\n value = await navigator.clipboard.readText();\n }\n catch (error) {\n throw ClipboardWeb.createException(ClipboardWeb.errorReadFailed, ErrorCode.ReadFailed);\n }\n if (!value) {\n throw ClipboardWeb.createException(ClipboardWeb.errorEmptyClipboard, ErrorCode.EmptyClipboard);\n }\n return { type: ClipboardWeb.resolveTextType(value), value };\n }\n async write(options) {\n if (options.html === undefined &&\n options.image === undefined &&\n options.text === undefined &&\n options.url === undefined) {\n throw new Error(ClipboardWeb.errorContentMissing);\n }\n try {\n if (options.image !== undefined) {\n await ClipboardWeb.writeRichContent({\n 'image/png': await ClipboardWeb.convertDataUrlToBlob(options.image),\n });\n }\n else if (options.html !== undefined) {\n const data = {\n 'text/html': new Blob([options.html], { type: 'text/html' }),\n };\n if (options.text !== undefined) {\n data['text/plain'] = new Blob([options.text], { type: 'text/plain' });\n }\n await ClipboardWeb.writeRichContent(data);\n }\n else if (options.url !== undefined) {\n await navigator.clipboard.writeText(options.url);\n }\n else if (options.text !== undefined) {\n await navigator.clipboard.writeText(options.text);\n }\n }\n catch (error) {\n if (error instanceof CapacitorException) {\n throw error;\n }\n throw ClipboardWeb.createException(ClipboardWeb.errorWriteFailed, ErrorCode.WriteFailed);\n }\n }\n static convertBlobToDataUrl(blob) {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onloadend = () => resolve(reader.result);\n reader.onerror = () => reject(reader.error);\n reader.readAsDataURL(blob);\n });\n }\n static async convertDataUrlToBlob(dataUrl) {\n const response = await fetch(dataUrl);\n return response.blob();\n }\n static createException(message, code) {\n return new CapacitorException(message, undefined, { code });\n }\n static resolveTextType(value) {\n if (value.startsWith('http://') || value.startsWith('https://')) {\n return ClipboardContentType.Url;\n }\n return ClipboardContentType.Text;\n }\n static async writeRichContent(data) {\n if (typeof ClipboardItem === 'undefined') {\n throw ClipboardWeb.createException(ClipboardWeb.errorRichContentNotSupported, ErrorCode.WriteFailed);\n }\n await navigator.clipboard.write([new ClipboardItem(data)]);\n }\n}\nClipboardWeb.errorContentMissing = 'One of text, html, image or url must be provided.';\nClipboardWeb.errorEmptyClipboard = 'The clipboard is empty.';\nClipboardWeb.errorReadFailed = 'The clipboard content could not be read.';\nClipboardWeb.errorRichContentNotSupported = 'This browser does not support writing rich content to the clipboard.';\nClipboardWeb.errorWriteFailed = 'The content could not be written to the clipboard.';\n//# sourceMappingURL=web.js.map"],"names":["ClipboardContentType","ErrorCode","registerPlugin","WebPlugin","CapacitorException"],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import Capacitor
|
|
3
|
+
|
|
4
|
+
@objc public class WriteOptions: NSObject {
|
|
5
|
+
let html: String?
|
|
6
|
+
let image: String?
|
|
7
|
+
let text: String?
|
|
8
|
+
let url: String?
|
|
9
|
+
|
|
10
|
+
init(_ call: CAPPluginCall) throws {
|
|
11
|
+
self.html = call.getString("html")
|
|
12
|
+
self.image = call.getString("image")
|
|
13
|
+
self.text = call.getString("text")
|
|
14
|
+
self.url = call.getString("url")
|
|
15
|
+
if html == nil && image == nil && text == nil && url == nil {
|
|
16
|
+
throw CustomError.contentMissing
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import Capacitor
|
|
3
|
+
|
|
4
|
+
@objc public class ReadResult: NSObject, Result {
|
|
5
|
+
let type: ClipboardContentType
|
|
6
|
+
let value: String
|
|
7
|
+
|
|
8
|
+
init(type: ClipboardContentType, value: String) {
|
|
9
|
+
self.type = type
|
|
10
|
+
self.value = value
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
@objc public func toJSObject() -> AnyObject {
|
|
14
|
+
var result = JSObject()
|
|
15
|
+
result["type"] = type.rawValue
|
|
16
|
+
result["value"] = value
|
|
17
|
+
return result as AnyObject
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import Capacitor
|
|
3
|
+
import UIKit
|
|
4
|
+
import UniformTypeIdentifiers
|
|
5
|
+
|
|
6
|
+
@objc public class Clipboard: NSObject {
|
|
7
|
+
private let plugin: ClipboardPlugin
|
|
8
|
+
|
|
9
|
+
init(plugin: ClipboardPlugin) {
|
|
10
|
+
self.plugin = plugin
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
@objc public func read(completion: @escaping (ReadResult?, Error?) -> Void) {
|
|
14
|
+
DispatchQueue.main.async {
|
|
15
|
+
let pasteboard = UIPasteboard.general
|
|
16
|
+
if let image = pasteboard.image, let data = image.pngData() {
|
|
17
|
+
let value = "data:image/png;base64," + data.base64EncodedString()
|
|
18
|
+
completion(ReadResult(type: .image, value: value), nil)
|
|
19
|
+
return
|
|
20
|
+
}
|
|
21
|
+
if let data = pasteboard.data(forPasteboardType: UTType.html.identifier), let html = String(data: data, encoding: .utf8) {
|
|
22
|
+
completion(ReadResult(type: .html, value: html), nil)
|
|
23
|
+
return
|
|
24
|
+
}
|
|
25
|
+
if let string = pasteboard.string {
|
|
26
|
+
let type: ClipboardContentType = string.hasPrefix("http://") || string.hasPrefix("https://") ? .url : .text
|
|
27
|
+
completion(ReadResult(type: type, value: string), nil)
|
|
28
|
+
return
|
|
29
|
+
}
|
|
30
|
+
if let url = pasteboard.url {
|
|
31
|
+
completion(ReadResult(type: .url, value: url.absoluteString), nil)
|
|
32
|
+
return
|
|
33
|
+
}
|
|
34
|
+
completion(nil, CustomError.emptyClipboard)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@objc public func write(_ options: WriteOptions, completion: @escaping (Error?) -> Void) {
|
|
39
|
+
DispatchQueue.main.async {
|
|
40
|
+
let pasteboard = UIPasteboard.general
|
|
41
|
+
if let image = options.image {
|
|
42
|
+
guard let decodedImage = self.decodeDataUrl(image) else {
|
|
43
|
+
completion(CustomError.writeFailed)
|
|
44
|
+
return
|
|
45
|
+
}
|
|
46
|
+
pasteboard.image = decodedImage
|
|
47
|
+
} else if let html = options.html {
|
|
48
|
+
var item: [String: Any] = [UTType.html.identifier: html]
|
|
49
|
+
item[UTType.utf8PlainText.identifier] = options.text ?? html
|
|
50
|
+
pasteboard.items = [item]
|
|
51
|
+
} else if let url = options.url {
|
|
52
|
+
guard let url = URL(string: url) else {
|
|
53
|
+
completion(CustomError.writeFailed)
|
|
54
|
+
return
|
|
55
|
+
}
|
|
56
|
+
pasteboard.url = url
|
|
57
|
+
} else if let text = options.text {
|
|
58
|
+
pasteboard.string = text
|
|
59
|
+
}
|
|
60
|
+
completion(nil)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
private func decodeDataUrl(_ dataUrl: String) -> UIImage? {
|
|
65
|
+
var base64 = dataUrl
|
|
66
|
+
if let range = dataUrl.range(of: ",") {
|
|
67
|
+
base64 = String(dataUrl[range.upperBound...])
|
|
68
|
+
}
|
|
69
|
+
guard let data = Data(base64Encoded: base64) else {
|
|
70
|
+
return nil
|
|
71
|
+
}
|
|
72
|
+
return UIImage(data: data)
|
|
73
|
+
}
|
|
74
|
+
}
|