Apply suggestions

This commit is contained in:
Ayman Bagabas
2024-04-20 11:20:16 -04:00
parent 9ebfb11ac8
commit 0562f32af6
2 changed files with 104 additions and 114 deletions
+42 -63
View File
@@ -4,14 +4,17 @@
*/
import type { IDisposable, ITerminalAddon, Terminal } from '@xterm/xterm';
import { type IClipboardProvider, ClipboardSelectionType } from '@xterm/addon-clipboard';
import { type IClipboardProvider, ClipboardSelectionType, type IBase64 } from '@xterm/addon-clipboard';
import { Base64 as JSBase64 } from 'js-base64';
export class ClipboardAddon implements ITerminalAddon {
private _terminal?: Terminal;
private _disposable?: IDisposable;
constructor(private _provider: IClipboardProvider = new ClipboardProvider()) {}
constructor(
private _base64: IBase64 = new Base64(),
private _provider: IClipboardProvider = new BrowserClipboardProvider()
) {}
public activate(terminal: Terminal): void {
this._terminal = terminal;
@@ -22,90 +25,66 @@ export class ClipboardAddon implements ITerminalAddon {
return this._disposable?.dispose();
}
private _readText(sel: ClipboardSelectionType, data: string): void {
const b64 = this._base64.encodeText(data);
this._terminal?.input(`\x1b]52;${sel};${b64}\x07`, false);
}
private _setOrReportClipboard(data: string): boolean | Promise<boolean> {
const args = data.split(';');
if (args.length < 2) {
return true;
}
const pc = args[0];
const pc = args[0] as ClipboardSelectionType;
const pd = args[1];
switch (pc) {
case ClipboardSelectionType.SYSTEM:
case ClipboardSelectionType.PRIMARY:
try {
if (pd === '?') {
// Report clipboard
return this._provider.readText(pc).then((data) => {
this._terminal?.input(`\x1b]52;${pc};${data}\x07`, false);
return true;
});
}
return this._provider.writeText(pc, pd).then(() => true);
} catch (e) {
console.error(e);
}
if (pd === '?') {
const text = this._provider.readText(pc);
// Report clipboard
if (text instanceof Promise) {
return text.then((data) => {
this._readText(pc, data);
return true;
});
}
this._readText(pc, text);
return true;
}
// Clear clipboard if text is not a base64 encoded string.
let text = '';
try {
text = this._base64.decodeText(pd);
} catch {}
const result = this._provider.writeText(pc, text);
if (result instanceof Promise) {
return result.then(() => true);
}
return true;
}
}
export class ClipboardProvider implements IClipboardProvider {
private _base64: IBase64;
public limit: number;
constructor(
/**
* The base64 encoder/decoder to use.
*/
base64: IBase64 = new Base64(),
/**
* The maximum amount of data that can be copied to the clipboard.
* Zero means no limit.
*/
limit: number = 0 // unlimited
) {
this._base64 = base64;
this.limit = limit;
}
public readText(selection: ClipboardSelectionType): Promise<string> {
export class BrowserClipboardProvider implements IClipboardProvider {
public async readText(selection: ClipboardSelectionType): Promise<string> {
if (selection !== 'c') {
return Promise.resolve('');
}
return navigator.clipboard.readText().then(this._base64.encodeText);
return navigator.clipboard.readText();
}
public writeText(selection: ClipboardSelectionType, data: string): Promise<void> {
if (selection !== 'c' || (this.limit > 0 && data.length > this.limit)) {
public async writeText(selection: ClipboardSelectionType, text: string): Promise<void> {
if (selection !== 'c') {
return Promise.resolve();
}
try {
const text = this._base64.decodeText(data);
return navigator.clipboard.writeText(text);
} catch {
// clear the clipboard if the data is not valid base64
return navigator.clipboard.writeText('');
}
return navigator.clipboard.writeText(text);
}
}
export interface IBase64 {
/**
* Converts a utf-8 string to a base64 string.
* @param data The utf-8 string to convert to base64 string.
*/
encodeText(data: string): string;
/**
* Converts a base64 string to a utf-8 string.
* @param data The base64 string to convert to utf-8 string.
*/
decodeText(data: string): string;
}
export class Base64 implements IBase64 {
public encodeText(data: string): string {
return JSBase64.encode(data);
+62 -51
View File
@@ -28,16 +28,71 @@ declare module '@xterm/addon-clipboard' {
public dispose(): void
}
/**
* Clipboard selection type. This is used to specify which selection buffer to
* read or write to.
* - SYSTEM `c`: The system clipboard.
* - PRIMARY `p`: The primary clipboard. This is provided for compatibility
* with Linux X11.
*/
export const enum ClipboardSelectionType {
SYSTEM = 'c',
PRIMARY = 'p',
}
export interface IBase64 {
/**
* Converts a utf-8 string to a base64 string.
* @param data The utf-8 string to convert to base64 string.
*/
encodeText(data: string): string;
/**
* Converts a base64 string to a utf-8 string.
* @param data The base64 string to convert to utf-8 string.
* @throws An error if the input is not valid base64.
*/
decodeText(data: string): string;
}
/**
* A default Base64 encoding and decoding type.
**/
export class Base64 implements IBase64 {
/**
* Converts a utf-8 string to a base64 string.
* @param data The utf-8 string to convert to base64 string.
*/
public encodeText(data: string): string;
/**
* Converts a base64 string to a utf-8 string.
* @param data The base64 string to convert to utf-8 string.
* @throws An error if the input is not valid base64.
*/
public decodeText(data: string): string;
}
export interface IClipboardProvider {
/**
* Gets the clipboard content.
* @param selection The clipboard selection to read.
* @returns A promise that resolves with clipboard selection data.
*/
readText(selection: ClipboardSelectionType): string | Promise<string>;
/**
* Sets the clipboard content.
* @param selection The clipboard selection to set.
* @param data The clipboard text to write.
*/
writeText(selection: ClipboardSelectionType, text: string): void | Promise<void>;
}
/**
* The clipboard provider interface that enables xterm.js to access the system clipboard.
*/
export class ClipboardProvider implements IClipboardProvider{
/**
* Creates a new clipboard provider.
* @param _base64 The base64 encoder/decoder to use.
*/
constructor(base64?: IBase64, limit?: number);
export class BrowserClipboardProvider implements IClipboardProvider{
/**
* Reads text from the clipboard.
* @param selection The selection type to read from.
@@ -53,48 +108,4 @@ declare module '@xterm/addon-clipboard' {
*/
public writeText(selection: ClipboardSelectionType, data: string): Promise<void>;
}
export interface IBase64 {
/**
* Converts a utf-8 string to a base64 string.
* @param data The utf-8 string to convert to base64 string.
*/
encodeText(data: string): string;
/**
* Converts a base64 string to a utf-8 string.
* @param data The base64 string to convert to utf-8 string.
*/
decodeText(data: string): string;
}
export interface IClipboardProvider {
/**
* Gets the clipboard content.
* @param selection The clipboard selection to read.
* @returns A promise that resolves with the base64 encoded data.
*/
readText(selection: ClipboardSelectionType): Promise<string>;
/**
* Sets the clipboard content.
* @param selection The clipboard selection to set.
* @param data The base64 encoded data to set. If the data is invalid
* base64, the clipboard is cleared.
*/
writeText(selection: ClipboardSelectionType, data: string): Promise<void>;
}
/**
* Clipboard selection type. This is used to specify which selection buffer to
* read or write to.
* - SYSTEM `c`: The system clipboard.
* - PRIMARY `p`: The primary clipboard. This is provided for compatibility
* with Linux X11.
*/
export const enum ClipboardSelectionType {
SYSTEM = 'c',
PRIMARY = 'p',
}
}