diff --git a/src/commandline_frame.ts b/src/commandline_frame.ts index 6982537f..28650854 100644 --- a/src/commandline_frame.ts +++ b/src/commandline_frame.ts @@ -321,56 +321,6 @@ export function fillcmdline( return result } -/** @hidden - * Create a temporary textarea and give it to fn. Remove the textarea afterwards - * - * Useful for document.execCommand - **/ -function applyWithTmpTextArea(fn) { - let textarea - try { - textarea = document.createElement("textarea") - // Scratchpad must be `display`ed, but can be tiny and invisible. - // Being tiny and invisible means it won't make the parent page move. - textarea.style.cssText = - "visible: invisible; width: 0; height: 0; position: fixed" - textarea.contentEditable = "true" - document.documentElement.appendChild(textarea) - return fn(textarea) - } finally { - document.documentElement.removeChild(textarea) - } -} - -/** @hidden **/ -export async function setClipboard(content: string) { - await Messaging.messageOwnTab("commandline_content", "focus") - applyWithTmpTextArea(scratchpad => { - scratchpad.value = content - scratchpad.select() - // This can return false spuriously so just ignore its return value - document.execCommand("Copy") - logger.info("set clipboard:", scratchpad.value) - }) - // Return focus to the document - await Messaging.messageOwnTab("commandline_content", "hide") - return Messaging.messageOwnTab("commandline_content", "blur") -} - -/** @hidden **/ -export async function getClipboard() { - await Messaging.messageOwnTab("commandline_content", "focus") - const result = applyWithTmpTextArea(scratchpad => { - scratchpad.focus() - document.execCommand("Paste") - return scratchpad.textContent - }) - // Return focus to the document - await Messaging.messageOwnTab("commandline_content", "hide") - await Messaging.messageOwnTab("commandline_content", "blur") - return result -} - /** @hidden **/ export function getContent() { return commandline_state.clInput.value diff --git a/src/excmds.ts b/src/excmds.ts index 86f268d1..877043cc 100644 --- a/src/excmds.ts +++ b/src/excmds.ts @@ -154,7 +154,6 @@ import "@src/lib/number.mod" import * as BGSELF from "@src/.excmds_background.generated" import { CmdlineCmds as BgCmdlineCmds } from "@src/background/commandline_cmds" import { EditorCmds as BgEditorCmds } from "@src/background/editor" -import { messageActiveTab } from "@src/lib/messaging" import { EditorCmds } from "@src/background/editor" import { firefoxVersionAtLeast } from "@src/lib/webext" import { parse_bind_args, modeMaps } from "@src/lib/binding" @@ -3089,48 +3088,65 @@ export function yank(...content: string[]) { } /** - * Copies a string to the clipboard/selection buffer depending on the user's preferences + * Copies a string to the clipboard/selection buffer depending on the user's preferences. * * @hidden */ //#background_helper -async function setclip(str) { - // Functions to avoid retyping everything everywhere +async function setclip(data: string) { + // Function to avoid retyping everything everywhere + const setclip_selection = data => Native.clipboard("set", data) - // Note: We're using fillcmdline here because exceptions are somehow not caught. We're rethrowing because otherwise the error message will be overwritten with the "yank successful" message. - const s = () => Native.clipboard("set", str) - const c = () => messageActiveTab("commandline_frame", "setClipboard", [str]) - - let promises = [] + let promises: Promise[] switch (await config.getAsync("yankto")) { case "selection": - promises = [s()] + promises = [setclip_selection(data)] break case "clipboard": - promises = [c()] + promises = [setclip_webapi(data)] break case "both": - promises = [s(), c()] + promises = [setclip_selection(data), setclip_webapi(data)] break } return Promise.all(promises) } +/** + * Copies a string to the clipboard using the Clipboard API. + * @hidden + * + * Has to be a background helper as it's only available on HTTPS and background pages. We want to be able to copy stuff to the clipboard from HTTP pages too. + */ +//#background_helper +async function setclip_webapi(data: string) { + return window.navigator.clipboard.writeText(data) +} + /** * Fetches the content of the clipboard/selection buffer depending on user's preferences * * Exposed for use with [[composite]], e.g. `composite getclip | fillcmdline` */ //#background -export async function getclip(fromm?: "clipboard" | "selection") { - if (fromm === undefined) fromm = await config.getAsync("putfrom") - if (fromm === "clipboard") { - return messageActiveTab("commandline_frame", "getClipboard") +export async function getclip(from?: "clipboard" | "selection") { + if (from === undefined) from = await config.getAsync("putfrom") + if (from === "clipboard") { + return getclip_webapi() } else { return Native.clipboard("get", "") } } +/** + * Gets the clipboard content using the Clipboard API. + * @hidden + */ +//#background_helper +async function getclip_webapi() { + return window.navigator.clipboard.readText() +} + /** Use the system clipboard. If `excmd === "open"`, call [[open]] with the contents of the clipboard. Similarly for [[tabopen]].