clipboard
This commit is contained in:
parent
b5d0f52da0
commit
850ef7bfb3
4 changed files with 325 additions and 10 deletions
|
|
@ -441,6 +441,33 @@ function domStopFrameLoop() {
|
|||
}
|
||||
|
||||
// ─── Clipboard ────────────────────────────────────────────────────────
|
||||
//
|
||||
// Read path is necessarily a latched buffer: navigator.clipboard.readText
|
||||
// is async (Promise) but the C++ Clipboard::GetText signature is
|
||||
// synchronous to match the Wayland / Win32 backends. Two feeders keep
|
||||
// the cache fresh:
|
||||
//
|
||||
// 1. A capture-phase `paste` listener on `window` reads
|
||||
// event.clipboardData.getData('text/plain') synchronously — this
|
||||
// covers the standard Ctrl+V flow, where the paste event fires
|
||||
// in the same task as the C++ key handler that will call GetText.
|
||||
// 2. Each GetText call also kicks off a navigator.clipboard.readText
|
||||
// in the background. The promise resolves in a later task; the
|
||||
// first call usually still returns the latched paste value (or
|
||||
// nullopt), subsequent calls see the readText result.
|
||||
|
||||
let __clipboardCache = null;
|
||||
|
||||
window.addEventListener("paste", (event) => {
|
||||
try {
|
||||
const t = event.clipboardData &&
|
||||
event.clipboardData.getData("text/plain");
|
||||
if (typeof t === "string") __clipboardCache = t;
|
||||
} catch (err) {
|
||||
// Some browsers reject clipboardData access inside non-input
|
||||
// targets; the async readText fallback still has a chance.
|
||||
}
|
||||
}, true);
|
||||
|
||||
function clipboardSetText(strPtr, strLen) {
|
||||
try {
|
||||
|
|
@ -452,6 +479,19 @@ function clipboardSetText(strPtr, strLen) {
|
|||
}
|
||||
}
|
||||
|
||||
function clipboardGetText() {
|
||||
// Best-effort async refresh. Permission/focus rejections are
|
||||
// expected in non-activated contexts — swallow them so we don't
|
||||
// spam the console on every paste check.
|
||||
if (navigator.clipboard && navigator.clipboard.readText) {
|
||||
navigator.clipboard.readText()
|
||||
.then((t) => { if (typeof t === "string") __clipboardCache = t; })
|
||||
.catch(() => {});
|
||||
}
|
||||
if (__clipboardCache === null) return 0;
|
||||
return __writeUtf8(__clipboardCache);
|
||||
}
|
||||
|
||||
// ─── History / routing ────────────────────────────────────────────────
|
||||
|
||||
function pushState(dataPtr, dataLen, titlePtr, titleLen, urlPtr, urlLen) {
|
||||
|
|
@ -547,7 +587,7 @@ Object.assign(window.crafter_webbuild_env, {
|
|||
domStartFrameLoop, domStopFrameLoop,
|
||||
|
||||
// Clipboard
|
||||
clipboardSetText,
|
||||
clipboardSetText, clipboardGetText,
|
||||
|
||||
// History
|
||||
pushState, addPopStateListener, removePopStateListener, getPathName,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue