terminal: support OSC 52 for copy for xterm.js
Bug: b/236205389
Change-Id: I90168ef268058d26f5abadeed966224962d32283
Reviewed-on: https://chromium-review.googlesource.com/c/apps/libapps/+/3864200
Reviewed-by: Joel Hockey <joelhockey@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
diff --git a/terminal/js/terminal_emulator.js b/terminal/js/terminal_emulator.js
index 4568fdc..b821926 100644
--- a/terminal/js/terminal_emulator.js
+++ b/terminal/js/terminal_emulator.js
@@ -178,6 +178,7 @@
() => this.onFontLoadingDone_());
this.installUnimplementedStubs_();
+ this.installEscapeSequenceHandlers_();
this.term.onResize(({cols, rows}) => this.io.onTerminalResize(cols, rows));
// We could also use `this.io.sendString()` except for the nassh exit
@@ -261,6 +262,32 @@
};
}
+ installEscapeSequenceHandlers_() {
+ // OSC 52 for copy.
+ this.term.parser.registerOscHandler(52, (args) => {
+ // Args comes in as a single 'clipboard;b64-data' string. The clipboard
+ // parameter is used to select which of the X clipboards to address. Since
+ // we're not integrating with X, we treat them all the same.
+ const parsedArgs = args.match(/^[cps01234567]*;(.*)/);
+ if (!parsedArgs) {
+ return true;
+ }
+
+ let data;
+ try {
+ data = window.atob(parsedArgs[1]);
+ } catch (e) {
+ // If the user sent us invalid base64 content, silently ignore it.
+ return true;
+ }
+ const decoder = new TextDecoder();
+ const bytes = lib.codec.stringToCodeUnitArray(data);
+ this.copyString_(decoder.decode(bytes));
+
+ return true;
+ });
+ }
+
/**
* One-time initialization at the beginning.
*/
@@ -463,11 +490,15 @@
}
copySelection_() {
- const selection = this.term.getSelection();
- if (!selection) {
+ this.copyString_(this.term.getSelection());
+ }
+
+ /** @param {string} data */
+ copyString_(data) {
+ if (!data) {
return;
}
- navigator.clipboard?.writeText(selection);
+ navigator.clipboard?.writeText(data);
if (!this.copyNotice_) {
this.copyNotice_ = document.createElement('terminal-copy-notice');
}