|
@@ -8,6 +8,7 @@ import { SVG_EXPORT_TAG } from "./scene/export";
|
|
|
import { tryParseSpreadsheet, Spreadsheet, VALID_SPREADSHEET } from "./charts";
|
|
|
import { EXPORT_DATA_TYPES, MIME_TYPES } from "./constants";
|
|
|
import { isInitializedImageElement } from "./element/typeChecks";
|
|
|
+import { isPromiseLike } from "./utils";
|
|
|
|
|
|
type ElementsClipboard = {
|
|
|
type: typeof EXPORT_DATA_TYPES.excalidrawClipboard;
|
|
@@ -166,10 +167,35 @@ export const parseClipboard = async (
|
|
|
}
|
|
|
};
|
|
|
|
|
|
-export const copyBlobToClipboardAsPng = async (blob: Blob) => {
|
|
|
- await navigator.clipboard.write([
|
|
|
- new window.ClipboardItem({ [MIME_TYPES.png]: blob }),
|
|
|
- ]);
|
|
|
+export const copyBlobToClipboardAsPng = async (blob: Blob | Promise<Blob>) => {
|
|
|
+ let promise;
|
|
|
+ try {
|
|
|
+ // in Safari so far we need to construct the ClipboardItem synchronously
|
|
|
+ // (i.e. in the same tick) otherwise browser will complain for lack of
|
|
|
+ // user intent. Using a Promise ClipboardItem constructor solves this.
|
|
|
+ // https://bugs.webkit.org/show_bug.cgi?id=222262
|
|
|
+ //
|
|
|
+ // not await so that we can detect whether the thrown error likely relates
|
|
|
+ // to a lack of support for the Promise ClipboardItem constructor
|
|
|
+ promise = navigator.clipboard.write([
|
|
|
+ new window.ClipboardItem({
|
|
|
+ [MIME_TYPES.png]: blob,
|
|
|
+ }),
|
|
|
+ ]);
|
|
|
+ } catch (error: any) {
|
|
|
+ // if we're using a Promise ClipboardItem, let's try constructing
|
|
|
+ // with resolution value instead
|
|
|
+ if (isPromiseLike(blob)) {
|
|
|
+ await navigator.clipboard.write([
|
|
|
+ new window.ClipboardItem({
|
|
|
+ [MIME_TYPES.png]: await blob,
|
|
|
+ }),
|
|
|
+ ]);
|
|
|
+ } else {
|
|
|
+ throw error;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ await promise;
|
|
|
};
|
|
|
|
|
|
export const copyTextToSystemClipboard = async (text: string | null) => {
|