Merge pull request #3078 from Rummskartoffel/clipboard-api

Update yank to use Clipboard API
This commit is contained in:
Oliver Blanthorn 2020-12-10 22:04:07 +00:00 committed by GitHub
commit ee295a212f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 66 deletions

View file

@ -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

View file

@ -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<any>[]
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]].