mirror of
https://github.com/novnc/noVNC.git
synced 2026-05-26 23:19:41 +00:00
Clipboard permissions must be supported, with states "granted" or "prompt" for both write and read.
73 lines
1.9 KiB
JavaScript
73 lines
1.9 KiB
JavaScript
/*
|
|
* noVNC: HTML5 VNC client
|
|
* Copyright (c) 2025 The noVNC authors
|
|
* Licensed under MPL 2.0 or any later version (see LICENSE.txt)
|
|
*/
|
|
|
|
import * as Log from './util/logging.js';
|
|
import { browserAsyncClipboardSupport } from './util/browser.js';
|
|
|
|
export default class AsyncClipboard {
|
|
constructor(target) {
|
|
this._target = target || null;
|
|
|
|
this._isAvailable = null;
|
|
|
|
this._eventHandlers = {
|
|
'focus': this._handleFocus.bind(this),
|
|
};
|
|
|
|
// ===== EVENT HANDLERS =====
|
|
|
|
this.onpaste = () => {};
|
|
}
|
|
|
|
// ===== PRIVATE METHODS =====
|
|
|
|
async _ensureAvailable() {
|
|
if (this._isAvailable !== null) return this._isAvailable;
|
|
try {
|
|
const status = await browserAsyncClipboardSupport();
|
|
this._isAvailable = (status === 'available');
|
|
} catch {
|
|
this._isAvailable = false;
|
|
}
|
|
return this._isAvailable;
|
|
}
|
|
|
|
async _handleFocus(event) {
|
|
if (!(await this._ensureAvailable())) return;
|
|
try {
|
|
const text = await navigator.clipboard.readText();
|
|
this.onpaste(text);
|
|
} catch (error) {
|
|
Log.Error("Clipboard read failed: ", error);
|
|
}
|
|
}
|
|
|
|
// ===== PUBLIC METHODS =====
|
|
|
|
writeClipboard(text) {
|
|
// Can lazily check cached availability
|
|
if (!this._isAvailable) return false;
|
|
navigator.clipboard.writeText(text)
|
|
.catch(error => Log.Error("Clipboard write failed: ", error));
|
|
return true;
|
|
}
|
|
|
|
grab() {
|
|
if (!this._target) return;
|
|
this._ensureAvailable()
|
|
.then((isAvailable) => {
|
|
if (isAvailable) {
|
|
this._target.addEventListener('focus', this._eventHandlers.focus);
|
|
}
|
|
});
|
|
}
|
|
|
|
ungrab() {
|
|
if (!this._target) return;
|
|
this._target.removeEventListener('focus', this._eventHandlers.focus);
|
|
}
|
|
}
|