diff --git a/packages/presentation/src/utils.ts b/packages/presentation/src/utils.ts index 787882bb06..0906e9daab 100644 --- a/packages/presentation/src/utils.ts +++ b/packages/presentation/src/utils.ts @@ -549,6 +549,23 @@ export async function getBlobURL (blob: Blob): Promise { }) } +/** + * @public + */ +export function copyTextToClipboardOldBrowser (text: string): void { + const textarea = document.createElement('textarea') + textarea.value = text + textarea.classList.add('hulyClipboardArea') + document.body.appendChild(textarea) + textarea.select() + try { + document.execCommand('copy') + } catch (err) { + console.error(err) + } + document.body.removeChild(textarea) +} + /** * @public */ @@ -562,7 +579,9 @@ export async function copyTextToClipboard (text: string | Promise): Prom await navigator.clipboard.write([clipboardItem]) } catch { // Fallback to default clipboard API implementation - await navigator.clipboard.writeText(text instanceof Promise ? await text : text) + if (navigator.clipboard != null && typeof navigator.clipboard.writeText === 'function') { + await navigator.clipboard.writeText(text instanceof Promise ? await text : text) + } else copyTextToClipboardOldBrowser(text instanceof Promise ? await text : text) } } diff --git a/packages/theme/styles/_layouts.scss b/packages/theme/styles/_layouts.scss index 0002c6d0e6..ff4842d656 100644 --- a/packages/theme/styles/_layouts.scss +++ b/packages/theme/styles/_layouts.scss @@ -917,6 +917,11 @@ a.no-line { .text-line-through { text-decoration: line-through; } +.hulyClipboardArea { + width: 0; + height: 0; + opacity: 0; +} .hidden-text { position: absolute; visibility: hidden; diff --git a/plugins/view-resources/src/actionImpl.ts b/plugins/view-resources/src/actionImpl.ts index b4d8304553..f0734891bb 100644 --- a/plugins/view-resources/src/actionImpl.ts +++ b/plugins/view-resources/src/actionImpl.ts @@ -9,7 +9,14 @@ import { getCurrentAccount } from '@hcengineering/core' import { type Asset, type IntlString, type Resource, getResource } from '@hcengineering/platform' -import { MessageBox, getClient, updateAttribute, type ContextStore, contextStore } from '@hcengineering/presentation' +import { + MessageBox, + getClient, + updateAttribute, + type ContextStore, + contextStore, + copyTextToClipboardOldBrowser +} from '@hcengineering/presentation' import { type AnyComponent, type AnySvelteComponent, @@ -73,7 +80,9 @@ async function CopyTextToClipboard ( const text = Array.isArray(doc) ? (await Promise.all(doc.map(async (d) => await getText(d, props.props)))).join(',') : await getText(doc, props.props) - await navigator.clipboard.writeText(text) + if (navigator.clipboard != null && typeof navigator.clipboard.writeText === 'function') { + await navigator.clipboard.writeText(text) + } else copyTextToClipboardOldBrowser(text) } }