{"record":{"id":"613adbaf246967d7","repo":"siyuan-note/siyuan","slug":"image-clipboard-is-unavailable","errorCode":null,"errorMessage":"image clipboard is unavailable","messagePattern":"image clipboard is unavailable","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"app/src/menus/util.ts","lineNumber":226,"sourceCode":"        });\n    }\n    /// #endif\n    if (onlyGetMenus) {\n        return openSubmenus;\n    }\n    window.siyuan.menus.menu.append(new MenuItem({\n        id: \"openBy\",\n        label: window.siyuan.languages.openBy,\n        icon: \"iconOpen\",\n        submenu: openSubmenus,\n    }).element);\n    /// #endif\n};\n\nexport const writePNGBlob = async (blob: Blob): Promise<boolean> => {\n    try {\n        if (!navigator.clipboard?.write || typeof ClipboardItem === \"undefined\") {\n            throw new Error(\"image clipboard is unavailable\");\n        }\n        await navigator.clipboard.write([\n            new ClipboardItem({\n                // @ts-ignore\n                [\"image/png\"]: blob\n            })\n        ]);\n        return true;\n    } catch (e) {\n        showMessage(window.siyuan.languages.clipboardPermissionDenied);\n        return false;\n    }\n};\n\nexport const copyPNGByLink = (link: string) => {\n    if (isInAndroid()) {\n        window.JSAndroid.writeImageClipboard(link);\n        return;","sourceCodeStart":208,"sourceCodeEnd":244,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/app/src/menus/util.ts#L208-L244","documentation":"writePNGBlob copies an image to the clipboard via the async Clipboard API (navigator.clipboard.write with a ClipboardItem). If either API is missing, it deliberately throws this error so the caller (copyBlob) can fall back to an alternative copy path.","triggerScenarios":"Calling copyBlob/writePNGBlob in an environment without navigator.clipboard.write or the ClipboardItem constructor — e.g. non-HTTPS origins, older browsers, WebViews (some Android/iOS WebView builds), or iframes without clipboard permission policy.","commonSituations":"Embedding the editor in a WebView or iframe lacking clipboard-write permission; serving over plain HTTP; unsupported browsers (older Firefox/Safari without full ClipboardItem support); document not focused during clipboard write.","solutions":["Ensure the page is served over HTTPS (or localhost) with clipboard-write permission","Use an environment that supports ClipboardItem (modern Chromium/Safari/Firefox)","Rely on the existing fallback path (copyImage/blobToPNGClipboard via img+canvas) instead of failing","For Electron, confirm the clipboard permission is not blocked in the BrowserWindow/webPreferences"],"exampleFix":"// before\nawait writePNGBlob(blob);\n// after\nif (navigator.clipboard?.write && typeof ClipboardItem !== \"undefined\") {\n    await writePNGBlob(blob);\n} else { fallbackCopyImage(blob); }","handlingStrategy":"fallback","validationCode":"const canUseImageClipboard = typeof navigator !== \"undefined\" && !!navigator.clipboard?.write && typeof ClipboardItem !== \"undefined\";","typeGuard":"const supportsClipboardWrite = (): boolean => !!navigator.clipboard?.write && typeof ClipboardItem !== \"undefined\";","tryCatchPattern":"try { await writePNGBlob(blob); } catch { fallbackCopyViaImgCanvas(blob); }","preventionTips":["Feature-detect navigator.clipboard.write and ClipboardItem before use","Serve over HTTPS/localhost so clipboard APIs are available","Always provide an img+canvas fallback for WebViews and older browsers"],"tags":["clipboard","browser-compatibility"],"backgroundTag":"unsupported-platform","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}