@basthon/console-react 0.5.5 → 0.5.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -27,14 +27,20 @@ export default class Terminal {
27
27
  * Force waiting for input to end.
28
28
  */
29
29
  private _stopWaitInput;
30
+ /**
31
+ * Mask user input and keep it out of the history
32
+ * (password input).
33
+ */
34
+ private _setPasswordMode;
30
35
  /**
31
36
  * Print a string in the terminal.
37
+ * If `className` is provided, the text is wrapped in a span with this class.
32
38
  */
33
- echo(message: string): void;
39
+ echo(message: string, className?: string): void;
34
40
  /**
35
41
  * Print error in terminal (in red).
36
42
  */
37
- error(message: string): JQueryTerminal<HTMLElement>;
43
+ error(message: string): void;
38
44
  /**
39
45
  * Pause the terminal execution (usefull to wait for event or promise).
40
46
  */
@@ -25,6 +25,21 @@ export default class Terminal {
25
25
  await kernel.ready();
26
26
  return (await kernel.complete(command))?.[0] ?? [];
27
27
  },
28
+ keymap: {
29
+ // JQuery.terminal's CTRL+C copies echoed commands twice (they share
30
+ // role="presentation" with the command line) so we copy the
31
+ // selected text ourselves (like right click > copy)
32
+ "CTRL+C": (e, original) => {
33
+ const text = window.getSelection()?.toString();
34
+ if (!text)
35
+ return original(e);
36
+ // without clipboard API, fallback to browser's native copy
37
+ if (navigator.clipboard == null)
38
+ return true;
39
+ navigator.clipboard.writeText(text.replace(/\xA0/g, " "));
40
+ return false;
41
+ },
42
+ },
28
43
  });
29
44
  // this prevents JQuery Terminal to redraw terminal and remove
30
45
  // script wrapping feature
@@ -55,6 +70,7 @@ export default class Terminal {
55
70
  },
56
71
  "eval.input": (data) => {
57
72
  this._inputMode = true;
73
+ this._setPasswordMode(data?.content?.password === true);
58
74
  const prompt = data?.content?.prompt;
59
75
  if (prompt != null)
60
76
  this.echo(prompt);
@@ -90,6 +106,7 @@ export default class Terminal {
90
106
  if (this._inputMode) {
91
107
  this._term.set_prompt("");
92
108
  this._inputMode = false;
109
+ this._setPasswordMode(false);
93
110
  this.pause();
94
111
  this._inputResolve?.(command);
95
112
  return;
@@ -114,14 +131,29 @@ export default class Terminal {
114
131
  return;
115
132
  this._inputResolve?.();
116
133
  this._inputMode = false;
134
+ this._setPasswordMode(false);
135
+ }
136
+ /**
137
+ * Mask user input and keep it out of the history
138
+ * (password input).
139
+ */
140
+ _setPasswordMode(on) {
141
+ this._term.set_mask(on);
142
+ if (on)
143
+ this._term.history().disable();
144
+ else
145
+ this._term.history().enable();
117
146
  }
118
147
  /**
119
148
  * Print a string in the terminal.
149
+ * If `className` is provided, the text is wrapped in a span with this class.
120
150
  */
121
- echo(message) {
151
+ echo(message, className) {
122
152
  // JQuery.terminal adds a trailing newline that is not easy
123
153
  // to remove with the current API. Doing our best here.
124
- message = message.toString();
154
+ // escape brackets to prevent JQuery.terminal from interpreting
155
+ // [[...]] (e.g. Python's nested lists) as formatting or commands
156
+ message = $.terminal.escape_brackets(message.toString());
125
157
  // prompt can be polluted with previous echo
126
158
  // _prompt_tail is the line part just before the prompt
127
159
  const term = this._term;
@@ -132,14 +164,17 @@ export default class Terminal {
132
164
  else
133
165
  prompt_tail = "";
134
166
  // here, prompt and _prompt_tail should be correctly isolated
135
- const lines = message.split("\n");
167
+ let lines = message.split("\n");
168
+ // formatting is applied line by line (empty formatting is avoided)
169
+ if (className != null)
170
+ lines = lines.map((l) => (l ? `[[;;;${className}]${l}]` : l));
136
171
  lines[0] = prompt_tail + lines[0];
137
172
  prompt_tail = lines.pop() ?? "";
138
173
  term.set_prompt(prompt_tail + prompt);
139
174
  if (lines.length) {
140
175
  // term.echo("") does not display blank line
141
176
  // so we replace this call with term.echo('\b')
142
- term.echo(lines.join("\n") || "\b");
177
+ term.echo(lines.join("\n") || "\b", { exec: false });
143
178
  }
144
179
  this._prompt_tail = prompt_tail;
145
180
  }
@@ -147,10 +182,9 @@ export default class Terminal {
147
182
  * Print error in terminal (in red).
148
183
  */
149
184
  error(message) {
150
- // JQuery.terminal adds a trailing newline that is not easy
151
- // to remove with the current API. Doing our best here.
152
- message = message.toString();
153
- return this._term.error(message.replace(/\n+$/, ""));
185
+ // stderr can be written in several chunks (not always ending with
186
+ // a newline) so we rely on echo to handle partial lines
187
+ this.echo(message, "terminal-error");
154
188
  }
155
189
  /**
156
190
  * Pause the terminal execution (usefull to wait for event or promise).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@basthon/console-react",
3
- "version": "0.5.5",
3
+ "version": "0.5.8",
4
4
  "description": "Basthon - Console React Component",
5
5
  "homepage": "https://basthon.fr",
6
6
  "bugs": {
@@ -15,12 +15,10 @@
15
15
  "main": "lib/index.js",
16
16
  "types": "lib/index.d.ts",
17
17
  "directories": {
18
- "lib": "lib/",
19
- "patches": "patches/"
18
+ "lib": "lib/"
20
19
  },
21
20
  "files": [
22
- "lib",
23
- "patches"
21
+ "lib"
24
22
  ],
25
23
  "exports": {
26
24
  ".": {
@@ -55,7 +53,7 @@
55
53
  "clean": "rimraf lib/"
56
54
  },
57
55
  "dependencies": {
58
- "@basthon/gui-react": "0.78.5",
56
+ "@basthon/gui-react": "0.78.6",
59
57
  "@fontsource/open-sans": "^5.2.7",
60
58
  "@fortawesome/fontawesome-svg-core": "7.3.0",
61
59
  "@fortawesome/free-regular-svg-icons": "7.3.0",
@@ -65,7 +63,7 @@
65
63
  "constants-browserify": "^1.0.0",
66
64
  "immer": "10.2.0",
67
65
  "jquery": "^3.6.4",
68
- "jquery.terminal": "patch:jquery.terminal@npm%3A2.45.2#./patches/jquery.terminal-npm-2.45.2-065beff1cb.patch",
66
+ "jquery.terminal": "2.45.2",
69
67
  "notie": "^4.3.1",
70
68
  "react-ace": "^13.0.0",
71
69
  "tty-browserify": "^0.0.1",
@@ -1,13 +0,0 @@
1
- diff --git a/js/jquery.terminal.js b/js/jquery.terminal.js
2
- index ed30f14fac229448c2b5b4ce8ed5437567723805..4aef6feaac0ba5a8ffc0dc34ac4e92e1ea725db5 100644
3
- --- a/js/jquery.terminal.js
4
- +++ b/js/jquery.terminal.js
5
- @@ -1286,7 +1286,7 @@
6
- var command_re = /((?:"[^"\\]*(?:\\[\S\s][^"\\]*)*"|'[^'\\]*(?:\\[\S\s][^'\\]*)*'|`[^`\\]*(?:\\[\S\s][^`\\]*)*`|\/[^\/\\]*(?:\\[\S\s][^\/\\]*)*\/[gimsuy]*(?=\s|$)|(?:\\\s|\S))+)(?=\s|$)/gi;
7
- var extended_command_re = /^\s*((terminal|cmd)::([a-z_]+)\(([\s\S]*)\))\s*$/;
8
- var format_exec_split_re = /(\[\[(?:-?[@!gbiusor])*;[^\]]+\](?:\\[[\]]|[^\]])*\]|\[\[[\s\S]+?\]\])/;
9
- - var format_exec_re = /(\[\[[\s\S]+?\]\])/;
10
- + var format_exec_re = /(\[\[(?:[^\][]|\\\])+\]\])/;
11
- var float_re = /^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$/;
12
- var re_re = /^\/((?:\\\/|[^/]|\[[^\]]*\/[^\]]*\])+)\/([gimsuy]*)$/;
13
- var string_re = /("(?:[^"\\]|\\(?:\\\\)*"|\\\\)*"|'(?:[^'\\]|\\(?:\\\\)*'|\\\\)*'|`(?:[^`\\]|\\(?:\\\\)*`|\\\\)*`)/;