From e21e326b3f434a51af3a9a243cb1a1f13e39da5b Mon Sep 17 00:00:00 2001 From: Linmj <33464433+cfmj@users.noreply.github.com> Date: Wed, 15 Jun 2022 01:04:36 +0800 Subject: [PATCH 1/6] fix: copy-code cannot be used under http protocol --- .../theme-default/composables/copy-code.ts | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/client/theme-default/composables/copy-code.ts b/src/client/theme-default/composables/copy-code.ts index bd5d73ab8f99..7f460380bbdb 100644 --- a/src/client/theme-default/composables/copy-code.ts +++ b/src/client/theme-default/composables/copy-code.ts @@ -1,6 +1,23 @@ import { nextTick, watch } from 'vue' import { inBrowser, useData } from 'vitepress' +let copyToClipboard: (text: string) => Promise; + +if (navigator.clipboard) { + copyToClipboard = (text: string) => navigator.clipboard.writeText(text); +} else { + copyToClipboard = async (text: string) => { + const tmp = document.createElement('TEXTAREA'); + const focus = document.activeElement; + tmp.value = text; + document.body.appendChild(tmp); + tmp.select(); + document.execCommand('copy'); + document.body.removeChild(tmp); + focus.focus(); + }; +} + export function useCopyCode() { const { page } = useData() @@ -38,7 +55,7 @@ function handleElement(el: HTMLElement) { text = text.replace(/^ *\$ /gm, '') } - navigator.clipboard.writeText(text).then(() => { + copyToClipboard(text).then(() => { el.classList.add('copied') setTimeout(() => { el.classList.remove('copied') From 1c1154652fc397376bc79de0673bbdc83847ced9 Mon Sep 17 00:00:00 2001 From: Linmj <33464433+cfmj@users.noreply.github.com> Date: Wed, 15 Jun 2022 01:38:11 +0800 Subject: [PATCH 2/6] fix: copy-code cannot be used under http protocol Fix the bug that copy-code cannot be used under http protocol --- src/client/theme-default/composables/copy-code.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/client/theme-default/composables/copy-code.ts b/src/client/theme-default/composables/copy-code.ts index 7f460380bbdb..8555d90547b9 100644 --- a/src/client/theme-default/composables/copy-code.ts +++ b/src/client/theme-default/composables/copy-code.ts @@ -7,14 +7,14 @@ if (navigator.clipboard) { copyToClipboard = (text: string) => navigator.clipboard.writeText(text); } else { copyToClipboard = async (text: string) => { - const tmp = document.createElement('TEXTAREA'); - const focus = document.activeElement; + const tmp = document.createElement('TEXTAREA') as HTMLTextAreaElement; + const activeElement = document.activeElement; tmp.value = text; document.body.appendChild(tmp); tmp.select(); document.execCommand('copy'); document.body.removeChild(tmp); - focus.focus(); + activeElement.focus(); }; } From 420109e8198dbeb4a53436928f436cd26730f008 Mon Sep 17 00:00:00 2001 From: Linmj <33464433+cfmj@users.noreply.github.com> Date: Wed, 15 Jun 2022 01:49:08 +0800 Subject: [PATCH 3/6] fix: copy-code cannot be used under http protoco Fix the bug that copy-code cannot be used under http protocol --- .../theme-default/composables/copy-code.ts | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/client/theme-default/composables/copy-code.ts b/src/client/theme-default/composables/copy-code.ts index 8555d90547b9..2dfd0ac88d62 100644 --- a/src/client/theme-default/composables/copy-code.ts +++ b/src/client/theme-default/composables/copy-code.ts @@ -1,21 +1,23 @@ import { nextTick, watch } from 'vue' import { inBrowser, useData } from 'vitepress' -let copyToClipboard: (text: string) => Promise; +let copyToClipboard: (text: string) => Promise if (navigator.clipboard) { - copyToClipboard = (text: string) => navigator.clipboard.writeText(text); + copyToClipboard = (text: string) => navigator.clipboard.writeText(text) } else { copyToClipboard = async (text: string) => { - const tmp = document.createElement('TEXTAREA') as HTMLTextAreaElement; - const activeElement = document.activeElement; - tmp.value = text; - document.body.appendChild(tmp); - tmp.select(); - document.execCommand('copy'); - document.body.removeChild(tmp); - activeElement.focus(); - }; + const tmp = document.createElement('TEXTAREA') as HTMLTextAreaElement + const activeElement = document.activeElement as HTMLElement + + tmp.value = text + document.body.appendChild(tmp) + tmp.select() + document.execCommand('copy') + document.body.removeChild(tmp) + + activeElement?.focus() + } } export function useCopyCode() { From 77fdf39a11982d71bf218d027c2abd7f73170e6d Mon Sep 17 00:00:00 2001 From: Divyansh Singh <40380293+brc-dd@users.noreply.github.com> Date: Tue, 14 Jun 2022 23:55:23 +0530 Subject: [PATCH 4/6] fix: improve `copyToClipboard` function --- .../theme-default/composables/copy-code.ts | 64 +++++++++++++------ 1 file changed, 45 insertions(+), 19 deletions(-) diff --git a/src/client/theme-default/composables/copy-code.ts b/src/client/theme-default/composables/copy-code.ts index 2dfd0ac88d62..6cf0dcccd90c 100644 --- a/src/client/theme-default/composables/copy-code.ts +++ b/src/client/theme-default/composables/copy-code.ts @@ -1,25 +1,6 @@ import { nextTick, watch } from 'vue' import { inBrowser, useData } from 'vitepress' -let copyToClipboard: (text: string) => Promise - -if (navigator.clipboard) { - copyToClipboard = (text: string) => navigator.clipboard.writeText(text) -} else { - copyToClipboard = async (text: string) => { - const tmp = document.createElement('TEXTAREA') as HTMLTextAreaElement - const activeElement = document.activeElement as HTMLElement - - tmp.value = text - document.body.appendChild(tmp) - tmp.select() - document.execCommand('copy') - document.body.removeChild(tmp) - - activeElement?.focus() - } -} - export function useCopyCode() { const { page } = useData() @@ -39,6 +20,51 @@ export function useCopyCode() { ) } +async function copyToClipboard(text: string) { + try { + return navigator.clipboard.writeText(text) + } catch { + const element = document.createElement('textarea') + const previouslyFocusedElement = document.activeElement + + element.value = text + + // Prevent keyboard from showing on mobile + element.setAttribute('readonly', '') + + element.style.contain = 'strict' + element.style.position = 'absolute' + element.style.left = '-9999px' + element.style.fontSize = '12pt' // Prevent zooming on iOS + + const selection = document.getSelection() + const originalRange = selection + ? selection.rangeCount > 0 && selection.getRangeAt(0) + : null + + document.body.append(element) + element.select() + + // Explicit selection workaround for iOS + element.selectionStart = 0 + element.selectionEnd = text.length + + document.execCommand('copy') + + element.remove() + + if (originalRange) { + selection!.removeAllRanges() // originalRange can't be truthy when selection is falsy + selection!.addRange(originalRange) + } + + // Get the focus back on the previously focused element, if any + if (previouslyFocusedElement) { + ;(previouslyFocusedElement as HTMLElement).focus() + } + } +} + function handleElement(el: HTMLElement) { el.onclick = () => { const parent = el.parentElement From a78cad719aa8a8452097aa758b974649153109b8 Mon Sep 17 00:00:00 2001 From: Divyansh Singh <40380293+brc-dd@users.noreply.github.com> Date: Thu, 16 Jun 2022 18:19:10 +0530 Subject: [PATCH 5/6] Update copy-code.ts --- src/client/theme-default/composables/copy-code.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/client/theme-default/composables/copy-code.ts b/src/client/theme-default/composables/copy-code.ts index 6cf0dcccd90c..15915ef259d1 100644 --- a/src/client/theme-default/composables/copy-code.ts +++ b/src/client/theme-default/composables/copy-code.ts @@ -42,7 +42,7 @@ async function copyToClipboard(text: string) { ? selection.rangeCount > 0 && selection.getRangeAt(0) : null - document.body.append(element) + document.body.appendChild(element) element.select() // Explicit selection workaround for iOS @@ -51,7 +51,7 @@ async function copyToClipboard(text: string) { document.execCommand('copy') - element.remove() + document.body.removeChild(element) if (originalRange) { selection!.removeAllRanges() // originalRange can't be truthy when selection is falsy From 5e5a2af3d896b18c9fadf21af261e59618e19dae Mon Sep 17 00:00:00 2001 From: Divyansh Singh <40380293+brc-dd@users.noreply.github.com> Date: Thu, 16 Jun 2022 18:20:11 +0530 Subject: [PATCH 6/6] Update copy-code.ts --- src/client/theme-default/composables/copy-code.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/client/theme-default/composables/copy-code.ts b/src/client/theme-default/composables/copy-code.ts index 15915ef259d1..35aca1c10579 100644 --- a/src/client/theme-default/composables/copy-code.ts +++ b/src/client/theme-default/composables/copy-code.ts @@ -50,7 +50,6 @@ async function copyToClipboard(text: string) { element.selectionEnd = text.length document.execCommand('copy') - document.body.removeChild(element) if (originalRange) {