@n42/cli 0.3.16 → 0.3.50
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.
- package/README.md +10 -2
- package/dist/assets/discover.html.template +1 -1
- package/dist/assets/discover.js +77 -4
- package/dist/assets/terminal-dark.css +10 -3
- package/dist/assets/terminal-light.css +8 -1
- package/dist/assets/terminal.js +122 -144
- package/dist/assets/theme-light.svg +46 -0
- package/dist/n42 +1 -1
- package/package.json +1 -1
- package/src/assets/discover.html.template +1 -1
- package/src/assets/discover.js +77 -4
- package/src/assets/terminal-dark.css +10 -3
- package/src/assets/terminal-light.css +8 -1
- package/src/assets/terminal.js +122 -144
- package/src/assets/theme-light.svg +46 -0
package/README.md
CHANGED
|
@@ -115,6 +115,14 @@ n42 discover peppol <participantId>
|
|
|
115
115
|
- **--reverse-lookup** Enable reverse lookup
|
|
116
116
|
- **--probe-endpoints** Probe resolved endpoints
|
|
117
117
|
|
|
118
|
+
Example output:
|
|
119
|
+
```bash
|
|
120
|
+
Discovery completed
|
|
121
|
+
PID : 0007:node42
|
|
122
|
+
Artefact : 2b40c904.svg [Open Diagram]
|
|
123
|
+
Usage : 53 (100)
|
|
124
|
+
```
|
|
125
|
+
|
|
118
126
|
### History
|
|
119
127
|
|
|
120
128
|
``` bash
|
|
@@ -127,8 +135,8 @@ Example output:
|
|
|
127
135
|
Found 2 artefact(s)
|
|
128
136
|
|
|
129
137
|
DATE PID FILE
|
|
130
|
-
2026-01-30 16:53:28 9930:
|
|
131
|
-
2026-01-30 16:53:08 9930:
|
|
138
|
+
2026-01-30 16:53:28 9930:de81248... 5e0800fc.svg [Open Diagram]
|
|
139
|
+
2026-01-30 16:53:08 9930:de78231... 6eeb73d0.svg [Open Diagram]
|
|
132
140
|
```
|
|
133
141
|
|
|
134
142
|
#### Available options:
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<meta charset="utf-8" />
|
|
5
5
|
<title>Node42</title>
|
|
6
6
|
<link rel="stylesheet" href="../../assets/wrapper-light.css">
|
|
7
|
-
<link rel="stylesheet" href="../../assets/terminal-light.css">
|
|
7
|
+
<link id="terminal-style" rel="stylesheet" href="../../assets/terminal-light.css">
|
|
8
8
|
</head>
|
|
9
9
|
<body>
|
|
10
10
|
<div id="app-header">
|
package/dist/assets/discover.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
const apiUrl = "https://api.node42.dev";
|
|
2
|
+
const wwwUrl = "https://www.node42.dev";
|
|
3
|
+
|
|
1
4
|
let terminal;
|
|
2
5
|
let discoveryTrace;
|
|
3
6
|
|
|
@@ -66,8 +69,78 @@ function addSvgClickListener() {
|
|
|
66
69
|
});
|
|
67
70
|
}
|
|
68
71
|
else {
|
|
69
|
-
|
|
70
|
-
|
|
72
|
+
let itemUrl = null;
|
|
73
|
+
|
|
74
|
+
const item = url.replace("#", "");
|
|
75
|
+
switch (item) {
|
|
76
|
+
case "DISCOVERY": {
|
|
77
|
+
const discoveryId = link.getAttribute("data-discovery");
|
|
78
|
+
console.log("discoveryId: " + discoveryId);
|
|
79
|
+
|
|
80
|
+
terminal.show({
|
|
81
|
+
command: "trace",
|
|
82
|
+
run: true
|
|
83
|
+
});
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
case "N42": {
|
|
88
|
+
itemUrl = link.getAttribute("data-n42-url");
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
case "BCARD": {
|
|
93
|
+
itemUrl = link.getAttribute("data-bcard-url");
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
case "NAPTR": {
|
|
98
|
+
const naptrUrl = link.getAttribute("data-naptr-url");
|
|
99
|
+
console.log("naptr: " + naptrUrl);
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
case "SMP": {
|
|
104
|
+
itemUrl = link.getAttribute("data-smp-url");
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
case "SMP-SG": {
|
|
109
|
+
//itemUrl = link.getAttribute("data-smp-sg-url");
|
|
110
|
+
const trace = discoveryTrace.find(t => t.step === "smp.serviceGroup.url");
|
|
111
|
+
itemUrl = trace.data.url;
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
case "SMP-SM": {
|
|
116
|
+
//itemUrl = link.getAttribute("data-smp-sm-url");
|
|
117
|
+
const trace = discoveryTrace.find(t => t.step === "smp.serviceMetadata.url");
|
|
118
|
+
itemUrl = trace.data.url;
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
case "AP": {
|
|
123
|
+
itemUrl = link.getAttribute("data-ap-url");
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
case "EP": {
|
|
128
|
+
itemUrl = link.getAttribute("data-ep-url");
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
case "TLS": {
|
|
133
|
+
itemUrl = link.getAttribute("data-tls-url");
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (itemUrl && itemUrl.length) {
|
|
139
|
+
terminal.open({
|
|
140
|
+
url: itemUrl,
|
|
141
|
+
method: "GET"
|
|
142
|
+
});
|
|
143
|
+
}
|
|
71
144
|
}
|
|
72
145
|
}
|
|
73
146
|
}
|
|
@@ -106,8 +179,8 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
|
106
179
|
terminal = new Terminal({
|
|
107
180
|
title: "Terminal",
|
|
108
181
|
brand: "curl",
|
|
109
|
-
|
|
110
|
-
|
|
182
|
+
theme: "light",
|
|
183
|
+
pkgVersion: "0.3.19"
|
|
111
184
|
});
|
|
112
185
|
|
|
113
186
|
addSvgClickListener();
|
|
@@ -93,7 +93,7 @@
|
|
|
93
93
|
.cm-term {
|
|
94
94
|
white-space: pre-wrap;
|
|
95
95
|
word-break: break-word;
|
|
96
|
-
color: #
|
|
96
|
+
color: #d6dde6;;
|
|
97
97
|
line-height: 1.35;
|
|
98
98
|
font-size: 12px;
|
|
99
99
|
}
|
|
@@ -131,9 +131,16 @@
|
|
|
131
131
|
.cm-input {
|
|
132
132
|
flex: 1;
|
|
133
133
|
background: transparent;
|
|
134
|
-
color: #
|
|
134
|
+
color: #d6dde6;
|
|
135
135
|
border: none;
|
|
136
136
|
outline: none;
|
|
137
137
|
font-family: inherit;
|
|
138
138
|
font-size: 12px;
|
|
139
|
-
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.cm-json-key { color: #3f9cff; }
|
|
142
|
+
.cm-json-string { color: #a07c4f }
|
|
143
|
+
.cm-json-number { color: #f59e0b; }
|
|
144
|
+
.cm-json-boolean { color: #ec4899; }
|
|
145
|
+
.cm-json-null { color: #94a3b8; }
|
|
146
|
+
.cm-json-step { color: #4cb56f; }
|
|
@@ -143,4 +143,11 @@
|
|
|
143
143
|
outline: none;
|
|
144
144
|
font-family: inherit;
|
|
145
145
|
font-size: 12px;
|
|
146
|
-
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.cm-json-key { color: #3f9cff; }
|
|
149
|
+
.cm-json-string { color: #a07c4f }
|
|
150
|
+
.cm-json-number { color: #f59e0b; }
|
|
151
|
+
.cm-json-boolean { color: #ec4899; }
|
|
152
|
+
.cm-json-null { color: #94a3b8; }
|
|
153
|
+
.cm-json-step { color: #4cb56f; }
|
package/dist/assets/terminal.js
CHANGED
|
@@ -12,6 +12,23 @@ class Terminal {
|
|
|
12
12
|
|
|
13
13
|
this._history = [];
|
|
14
14
|
this._historyIndex = -1;
|
|
15
|
+
|
|
16
|
+
// ---- reusable events ----
|
|
17
|
+
this.enterEvent = new KeyboardEvent("keydown", {
|
|
18
|
+
key: "Enter",
|
|
19
|
+
code: "Enter",
|
|
20
|
+
keyCode: 13,
|
|
21
|
+
which: 13,
|
|
22
|
+
bubbles: true
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
this.escEvent = new KeyboardEvent("keydown", {
|
|
26
|
+
key: "Escape",
|
|
27
|
+
code: "Escape",
|
|
28
|
+
keyCode: 27,
|
|
29
|
+
which: 27,
|
|
30
|
+
bubbles: true
|
|
31
|
+
});
|
|
15
32
|
}
|
|
16
33
|
|
|
17
34
|
async openAndRun(req) {
|
|
@@ -44,6 +61,34 @@ class Terminal {
|
|
|
44
61
|
document.documentElement.style.overflow = "hidden";
|
|
45
62
|
}
|
|
46
63
|
|
|
64
|
+
show(input) {
|
|
65
|
+
if (!this.overlay) {
|
|
66
|
+
this._ensureDom();
|
|
67
|
+
this._printHelp();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (this._active) return;
|
|
71
|
+
this._active = true;
|
|
72
|
+
|
|
73
|
+
this._lastFocused = document.activeElement;
|
|
74
|
+
|
|
75
|
+
this.overlay.classList.remove("hidden");
|
|
76
|
+
this.dialog.classList.remove("hidden");
|
|
77
|
+
|
|
78
|
+
this.title.textContent = `Terminal [CMD]: ${input.command}`;
|
|
79
|
+
|
|
80
|
+
this.input.value = `${input.command}`;
|
|
81
|
+
this.input.focus();
|
|
82
|
+
|
|
83
|
+
if (input.run) {
|
|
84
|
+
this.input.dispatchEvent(this.enterEvent);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// prevent background scroll
|
|
88
|
+
this._prevOverflow = document.documentElement.style.overflow;
|
|
89
|
+
document.documentElement.style.overflow = "hidden";
|
|
90
|
+
}
|
|
91
|
+
|
|
47
92
|
close() {
|
|
48
93
|
if (!this._active) return;
|
|
49
94
|
this._active = false;
|
|
@@ -102,7 +147,7 @@ class Terminal {
|
|
|
102
147
|
method: normalized.method,
|
|
103
148
|
headers: {
|
|
104
149
|
...normalized.headers,
|
|
105
|
-
"X-N42-
|
|
150
|
+
"X-N42-Client-Version": `v${this.opts.pkgVersion}`,
|
|
106
151
|
},
|
|
107
152
|
body: normalized.body,
|
|
108
153
|
signal,
|
|
@@ -119,6 +164,8 @@ class Terminal {
|
|
|
119
164
|
if (normalized.body) this._printLine(`> (body ${this._byteLen(normalized.body)} bytes)`);
|
|
120
165
|
this._printLine("");
|
|
121
166
|
|
|
167
|
+
this.title.textContent = `Terminal [${normalized.method}]: curl`;
|
|
168
|
+
|
|
122
169
|
const res = await fetch(normalized.url, fetchInit);
|
|
123
170
|
|
|
124
171
|
const dt = (performance.now() - t0);
|
|
@@ -193,6 +240,40 @@ class Terminal {
|
|
|
193
240
|
this._historyIndex = this._history.length;
|
|
194
241
|
}
|
|
195
242
|
|
|
243
|
+
_jsonHighlight(json) {
|
|
244
|
+
if (typeof json !== "string") {
|
|
245
|
+
json = JSON.stringify(json, null, 2);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const esc = json
|
|
249
|
+
.replace(/&/g, "&")
|
|
250
|
+
.replace(/</g, "<")
|
|
251
|
+
.replace(/>/g, ">");
|
|
252
|
+
|
|
253
|
+
return esc.replace(
|
|
254
|
+
/"(step)"(\s*:\s*)"([^"]+)"|("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d+)?)/g,
|
|
255
|
+
(match, stepKey, colon, stepValue) => {
|
|
256
|
+
|
|
257
|
+
// Special case: only color the VALUE of step
|
|
258
|
+
if (stepKey) {
|
|
259
|
+
return `<span class="cm-json-key">"${stepKey}"</span>${colon}<span class="cm-json-step">"${stepValue}"</span>`;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
let cls = "number";
|
|
263
|
+
|
|
264
|
+
if (/^"/.test(match)) {
|
|
265
|
+
cls = /:$/.test(match) ? "key" : "string";
|
|
266
|
+
} else if (/true|false/.test(match)) {
|
|
267
|
+
cls = "boolean";
|
|
268
|
+
} else if (/null/.test(match)) {
|
|
269
|
+
cls = "null";
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
return `<span class="cm-json-${cls}">${match}</span>`;
|
|
273
|
+
}
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
|
|
196
277
|
_handleCommand(cmd) {
|
|
197
278
|
this._printLine(`$ ${cmd}`);
|
|
198
279
|
|
|
@@ -226,7 +307,7 @@ class Terminal {
|
|
|
226
307
|
|
|
227
308
|
if (discoveryTrace) {
|
|
228
309
|
this._resetTerminal();
|
|
229
|
-
this.
|
|
310
|
+
this._printHtml(this._jsonHighlight(discoveryTrace));
|
|
230
311
|
} else {
|
|
231
312
|
this._printLine("[error]: Discovery trace missing");
|
|
232
313
|
}
|
|
@@ -245,140 +326,33 @@ class Terminal {
|
|
|
245
326
|
return img;
|
|
246
327
|
}
|
|
247
328
|
|
|
329
|
+
_toggleTheme() {
|
|
330
|
+
const themeLink = document.getElementById("terminal-style");
|
|
331
|
+
|
|
332
|
+
// Check current theme file
|
|
333
|
+
const isLight = themeLink.getAttribute("href").includes("terminal-light.css");
|
|
334
|
+
|
|
335
|
+
if (isLight) {
|
|
336
|
+
themeLink.setAttribute("href", "../../assets/terminal-dark.css");
|
|
337
|
+
|
|
338
|
+
// Invert all icons for dark background
|
|
339
|
+
//icons.forEach(icon => { icon.style.filter = "invert(100%) hue-rotate(180deg)"; });
|
|
340
|
+
}
|
|
341
|
+
else {
|
|
342
|
+
themeLink.setAttribute("href", "../../assets/terminal-light.css");
|
|
343
|
+
|
|
344
|
+
// Reset icon colors to normal
|
|
345
|
+
//icons.forEach(icon => { icon.style.filter = "none"; });
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
|
|
248
349
|
_ensureDom() {
|
|
249
350
|
if (this.overlay) return;
|
|
250
351
|
|
|
251
|
-
const
|
|
252
|
-
const
|
|
253
|
-
|
|
254
|
-
// Styles (namespaced)
|
|
255
|
-
const style = document.createElement("style");
|
|
256
|
-
style.id = "terminal-style";
|
|
257
|
-
style.textContent = `
|
|
258
|
-
.cm-overlay {
|
|
259
|
-
position: fixed; inset: 0;
|
|
260
|
-
background: rgba(0,0,0,.55);
|
|
261
|
-
display: flex;
|
|
262
|
-
align-items: center;
|
|
263
|
-
justify-content: center;
|
|
264
|
-
padding: 24px;
|
|
265
|
-
z-index: 2147483647;
|
|
266
|
-
}
|
|
267
|
-
.cm-overlay.hidden {
|
|
268
|
-
display: none;
|
|
269
|
-
}
|
|
270
|
-
.cm-dialog {
|
|
271
|
-
width: min(980px, 100%);
|
|
272
|
-
height: min(720px, 100%);
|
|
273
|
-
background: #0b0f14;
|
|
274
|
-
color: ${textColor};
|
|
275
|
-
border: 1px solid rgba(255,255,255,.12);
|
|
276
|
-
border-radius: 12px;
|
|
277
|
-
box-shadow: 0 18px 60px rgba(0,0,0,.55);
|
|
278
|
-
display: flex;
|
|
279
|
-
flex-direction: column;
|
|
280
|
-
overflow: hidden;
|
|
281
|
-
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
|
282
|
-
}
|
|
283
|
-
.cm-display.hidden {
|
|
284
|
-
display: none;
|
|
285
|
-
}
|
|
286
|
-
.cm-head {
|
|
287
|
-
display: flex; align-items: center; gap: 12px;
|
|
288
|
-
padding: 10px 11px 10px 14px;
|
|
289
|
-
border-bottom: 1px solid rgba(255,255,255,.10);
|
|
290
|
-
background: rgba(255,255,255,.03);
|
|
291
|
-
}
|
|
292
|
-
.cm-title {
|
|
293
|
-
font-weight: 600;
|
|
294
|
-
font-size: 14px;
|
|
295
|
-
opacity: .95;
|
|
296
|
-
}
|
|
297
|
-
.cm-spacer { flex: 1; }
|
|
298
|
-
.cm-btn {
|
|
299
|
-
appearance: none;
|
|
300
|
-
border: 1px solid rgba(255,255,255,.18);
|
|
301
|
-
background: transparent;
|
|
302
|
-
color: inherit;
|
|
303
|
-
padding: 2px 6px 0 6px;
|
|
304
|
-
border-radius: 6px;
|
|
305
|
-
font-size: 12px;
|
|
306
|
-
cursor: pointer;
|
|
307
|
-
}
|
|
308
|
-
.cm-btn img {
|
|
309
|
-
width: 17px;
|
|
310
|
-
}
|
|
311
|
-
.cm-btn:hover {
|
|
312
|
-
border: 1px solid rgba(255,255,255,.38);
|
|
313
|
-
}
|
|
314
|
-
.cm-btn:disabled { opacity: .55; cursor: not-allowed; }
|
|
315
|
-
.cm-body {
|
|
316
|
-
flex: 1;
|
|
317
|
-
overflow: auto;
|
|
318
|
-
padding: 12px;
|
|
319
|
-
|
|
320
|
-
scrollbar-color: #323232 #0b0f14;
|
|
321
|
-
scrollbar-width: thin;
|
|
322
|
-
}
|
|
323
|
-
.cm-body::-webkit-scrollbar {
|
|
324
|
-
width: 10px;
|
|
325
|
-
}
|
|
326
|
-
.cm-body::-webkit-scrollbar-track {
|
|
327
|
-
background: #0b0f14;
|
|
328
|
-
}
|
|
329
|
-
.cm-body::-webkit-scrollbar-thumb {
|
|
330
|
-
background: #323232;
|
|
331
|
-
border-radius: 6px;
|
|
332
|
-
}
|
|
333
|
-
.cm-body::-webkit-scrollbar-thumb:hover {
|
|
334
|
-
background: #656565;
|
|
335
|
-
}
|
|
336
|
-
.cm-term {
|
|
337
|
-
white-space: pre-wrap;
|
|
338
|
-
word-break: break-word;
|
|
339
|
-
color: ${terminalTextColor};
|
|
340
|
-
line-height: 1.35;
|
|
341
|
-
font-size: 12px;
|
|
342
|
-
}
|
|
343
|
-
.cm-foot {
|
|
344
|
-
padding: 10px 12px;
|
|
345
|
-
border-top: 1px solid rgba(255,255,255,.10);
|
|
346
|
-
display: flex; align-items: center; gap: 10px;
|
|
347
|
-
background: rgba(255,255,255,.02);
|
|
348
|
-
}
|
|
349
|
-
.cm-status { font-size: 12px; opacity: .85; }
|
|
350
|
-
.cm-kbd {
|
|
351
|
-
font-size: 11px; opacity: .7;
|
|
352
|
-
border: 1px solid rgba(255,255,255,.16);
|
|
353
|
-
padding: 3px 6px 2px 6px;
|
|
354
|
-
border-radius: 6px;
|
|
355
|
-
}
|
|
356
|
-
.cm-input-row {
|
|
357
|
-
display: flex;
|
|
358
|
-
align-items: center;
|
|
359
|
-
gap: 8px;
|
|
360
|
-
padding: 8px 12px;
|
|
361
|
-
border-top: 1px solid rgba(255,255,255,.10);
|
|
362
|
-
background: rgba(255,255,255,.02);
|
|
363
|
-
}
|
|
364
|
-
.cm-prompt {
|
|
365
|
-
opacity: .8;
|
|
366
|
-
font-size: 12px;
|
|
367
|
-
}
|
|
368
|
-
.cm-input {
|
|
369
|
-
flex: 1;
|
|
370
|
-
background: transparent;
|
|
371
|
-
color: ${terminalTextColor};
|
|
372
|
-
border: none;
|
|
373
|
-
outline: none;
|
|
374
|
-
font-family: inherit;
|
|
375
|
-
font-size: 12px;
|
|
376
|
-
}
|
|
377
|
-
`;
|
|
352
|
+
const theme = this.opts.theme;
|
|
353
|
+
const themeLink = document.getElementById("terminal-style");
|
|
378
354
|
|
|
379
|
-
|
|
380
|
-
//document.head.appendChild(style);
|
|
381
|
-
}
|
|
355
|
+
themeLink.setAttribute("href", `../../assets/terminal-${theme}.css`);
|
|
382
356
|
|
|
383
357
|
// Overlay
|
|
384
358
|
const overlay = document.createElement("div");
|
|
@@ -450,6 +424,7 @@ class Terminal {
|
|
|
450
424
|
head.className = "cm-head";
|
|
451
425
|
|
|
452
426
|
const title = document.createElement("div");
|
|
427
|
+
title.id = "terminal-title";
|
|
453
428
|
title.className = "cm-title";
|
|
454
429
|
title.textContent = this.opts.title;
|
|
455
430
|
|
|
@@ -461,7 +436,6 @@ class Terminal {
|
|
|
461
436
|
btnCopy.className = "cm-btn copy";
|
|
462
437
|
btnCopy.type = "button";
|
|
463
438
|
btnCopy.title = "Copy";
|
|
464
|
-
//btnCopy.textContent = "Copy";
|
|
465
439
|
btnCopy.prepend(copyImg);
|
|
466
440
|
btnCopy.addEventListener("click", () => this._copy());
|
|
467
441
|
|
|
@@ -470,7 +444,6 @@ class Terminal {
|
|
|
470
444
|
btnDownload.className = "cm-btn";
|
|
471
445
|
btnDownload.type = "button";
|
|
472
446
|
btnDownload.title = "Download";
|
|
473
|
-
//btnDownload.textContent = "Download";
|
|
474
447
|
btnDownload.prepend(downloadImg);
|
|
475
448
|
btnDownload.addEventListener("click", () => this._download());
|
|
476
449
|
|
|
@@ -479,19 +452,18 @@ class Terminal {
|
|
|
479
452
|
btnOpenExt.className = "cm-btn";
|
|
480
453
|
btnOpenExt.type = "button";
|
|
481
454
|
btnOpenExt.title = "Open";
|
|
482
|
-
//btnOpenExt.textContent = "Open";
|
|
483
455
|
btnOpenExt.prepend(openExtImg);
|
|
484
456
|
btnOpenExt.addEventListener("click", () => this._openExt());
|
|
485
457
|
|
|
486
|
-
|
|
487
|
-
const
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
458
|
+
const themeImg = this._createImgEl("../../assets/theme-light.svg", 24, "Theme");
|
|
459
|
+
const btnTheme = document.createElement("button");
|
|
460
|
+
btnTheme.className = "cm-btn";
|
|
461
|
+
btnTheme.type = "button";
|
|
462
|
+
btnTheme.title = "Theme";
|
|
463
|
+
btnTheme.prepend(themeImg);
|
|
464
|
+
btnTheme.addEventListener("click", () => this._toggleTheme());
|
|
493
465
|
|
|
494
|
-
head.append(title, spacer, btnCopy, btnDownload, btnOpenExt);
|
|
466
|
+
head.append(title, spacer, btnTheme, btnCopy, btnDownload, btnOpenExt);
|
|
495
467
|
|
|
496
468
|
// Body
|
|
497
469
|
const body = document.createElement("div");
|
|
@@ -534,6 +506,7 @@ class Terminal {
|
|
|
534
506
|
// Store refs
|
|
535
507
|
this.overlay = overlay;
|
|
536
508
|
this.dialog = dialog;
|
|
509
|
+
this.title = title;
|
|
537
510
|
this.input = input;
|
|
538
511
|
this.term = term;
|
|
539
512
|
this.statusEl = status;
|
|
@@ -541,7 +514,7 @@ class Terminal {
|
|
|
541
514
|
this.btnCopy = btnCopy;
|
|
542
515
|
this.btnDownload = btnDownload;
|
|
543
516
|
this.btnOpenExt = btnOpenExt;
|
|
544
|
-
|
|
517
|
+
this.btnTheme = btnTheme;
|
|
545
518
|
|
|
546
519
|
// Close when clicking outside (optional)
|
|
547
520
|
overlay.addEventListener("click", (e) => {
|
|
@@ -638,6 +611,11 @@ class Terminal {
|
|
|
638
611
|
this._scrollToBottom();
|
|
639
612
|
}
|
|
640
613
|
|
|
614
|
+
_printHtml(s) {
|
|
615
|
+
this.term.innerHTML = s;
|
|
616
|
+
this._scrollToBottom();
|
|
617
|
+
}
|
|
618
|
+
|
|
641
619
|
_printRaw(s) {
|
|
642
620
|
this.term.textContent += s;
|
|
643
621
|
if (!s.endsWith("\n")) this.term.textContent += "\n";
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
2
|
+
<svg
|
|
3
|
+
width="800px"
|
|
4
|
+
height="800px"
|
|
5
|
+
viewBox="0 0 24 24"
|
|
6
|
+
version="1.1"
|
|
7
|
+
id="svg9"
|
|
8
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
9
|
+
xmlns:svg="http://www.w3.org/2000/svg"
|
|
10
|
+
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
11
|
+
xmlns:cc="http://creativecommons.org/ns#"
|
|
12
|
+
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
|
13
|
+
<defs
|
|
14
|
+
id="defs13" />
|
|
15
|
+
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
16
|
+
<title
|
|
17
|
+
id="title2">ic_fluent_dark_theme_24_regular</title>
|
|
18
|
+
<desc
|
|
19
|
+
id="desc4">Created with Sketch.</desc>
|
|
20
|
+
<g
|
|
21
|
+
id="🔍-Product-Icons"
|
|
22
|
+
stroke="none"
|
|
23
|
+
stroke-width="1"
|
|
24
|
+
fill="none"
|
|
25
|
+
fill-rule="evenodd">
|
|
26
|
+
<g
|
|
27
|
+
id="ic_fluent_dark_theme_24_regular"
|
|
28
|
+
fill="#212121"
|
|
29
|
+
fill-rule="nonzero"
|
|
30
|
+
style="fill:#6b7280;fill-opacity:1">
|
|
31
|
+
<path
|
|
32
|
+
d="M12,22 C17.5228475,22 22,17.5228475 22,12 C22,6.4771525 17.5228475,2 12,2 C6.4771525,2 2,6.4771525 2,12 C2,17.5228475 6.4771525,22 12,22 Z M12,20.5 L12,3.5 C16.6944204,3.5 20.5,7.30557963 20.5,12 C20.5,16.6944204 16.6944204,20.5 12,20.5 Z"
|
|
33
|
+
id="🎨-Color"
|
|
34
|
+
style="fill:#6b7280;fill-opacity:1" />
|
|
35
|
+
</g>
|
|
36
|
+
</g>
|
|
37
|
+
<metadata
|
|
38
|
+
id="metadata890">
|
|
39
|
+
<rdf:RDF>
|
|
40
|
+
<cc:Work
|
|
41
|
+
rdf:about="">
|
|
42
|
+
<dc:title>ic_fluent_dark_theme_24_regular</dc:title>
|
|
43
|
+
</cc:Work>
|
|
44
|
+
</rdf:RDF>
|
|
45
|
+
</metadata>
|
|
46
|
+
</svg>
|