Updates to xterm

This commit is contained in:
Andy Dixon
2026-06-16 15:59:28 +01:00
parent 58e916ecf8
commit d5295772cb
15 changed files with 402 additions and 89 deletions
+38 -52
View File
@@ -10,11 +10,11 @@
"hasInstallScript": true,
"dependencies": {
"@novnc/novnc": "^1.5.0",
"xterm": "5.3.0",
"xterm-addon-fit": "0.8.0",
"xterm-addon-search": "0.13.0",
"xterm-addon-unicode11": "0.6.0",
"xterm-addon-web-links": "0.9.0"
"@xterm/addon-fit": "0.11.0",
"@xterm/addon-search": "0.16.0",
"@xterm/addon-unicode11": "0.9.0",
"@xterm/addon-web-links": "0.12.0",
"@xterm/xterm": "6.0.0"
},
"devDependencies": {
"esbuild": "^0.28.1"
@@ -468,6 +468,39 @@
"integrity": "sha512-ucEJOx4T2avIRCleodk7YobZj5O2Ga2AeLfQ69A/yjG9HHba2+PDgwSkN3FttrmG+70ZGx21sElNFouK13RzyA==",
"license": "MPL-2.0"
},
"node_modules/@xterm/addon-fit": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@xterm/addon-fit/-/addon-fit-0.11.0.tgz",
"integrity": "sha512-jYcgT6xtVYhnhgxh3QgYDnnNMYTcf8ElbxxFzX0IZo+vabQqSPAjC3c1wJrKB5E19VwQei89QCiZZP86DCPF7g==",
"license": "MIT"
},
"node_modules/@xterm/addon-search": {
"version": "0.16.0",
"resolved": "https://registry.npmjs.org/@xterm/addon-search/-/addon-search-0.16.0.tgz",
"integrity": "sha512-9OeuBFu0/uZJPu+9AHKY6g/w0Czyb/Ut0A5t79I4ULoU4IfU5BEpPFVGQxP4zTTMdfZEYkVIRYbHBX1xWwjeSA==",
"license": "MIT"
},
"node_modules/@xterm/addon-unicode11": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/@xterm/addon-unicode11/-/addon-unicode11-0.9.0.tgz",
"integrity": "sha512-FxDnYcyuXhNl+XSqGZL/t0U9eiNb/q3EWT5rYkQT/zuig8Gz/VagnQANKHdDWFM2lTMk9ly0EFQxxxtZUoRetw==",
"license": "MIT"
},
"node_modules/@xterm/addon-web-links": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/@xterm/addon-web-links/-/addon-web-links-0.12.0.tgz",
"integrity": "sha512-4Smom3RPyVp7ZMYOYDoC/9eGJJJqYhnPLGGqJ6wOBfB8VxPViJNSKdgRYb8NpaM6YSelEKbA2SStD7lGyqaobw==",
"license": "MIT"
},
"node_modules/@xterm/xterm": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/@xterm/xterm/-/xterm-6.0.0.tgz",
"integrity": "sha512-TQwDdQGtwwDt+2cgKDLn0IRaSxYu1tSUjgKarSDkUM0ZNiSRXFpjxEsvc/Zgc5kq5omJ+V0a8/kIM2WD3sMOYg==",
"license": "MIT",
"workspaces": [
"addons/*"
]
},
"node_modules/esbuild": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz",
@@ -509,53 +542,6 @@
"@esbuild/win32-ia32": "0.28.1",
"@esbuild/win32-x64": "0.28.1"
}
},
"node_modules/xterm": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/xterm/-/xterm-5.3.0.tgz",
"integrity": "sha512-8QqjlekLUFTrU6x7xck1MsPzPA571K5zNqWm0M0oroYEWVOptZ0+ubQSkQ3uxIEhcIHRujJy6emDWX4A7qyFzg==",
"deprecated": "This package is now deprecated. Move to @xterm/xterm instead.",
"license": "MIT"
},
"node_modules/xterm-addon-fit": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/xterm-addon-fit/-/xterm-addon-fit-0.8.0.tgz",
"integrity": "sha512-yj3Np7XlvxxhYF/EJ7p3KHaMt6OdwQ+HDu573Vx1lRXsVxOcnVJs51RgjZOouIZOczTsskaS+CpXspK81/DLqw==",
"deprecated": "This package is now deprecated. Move to @xterm/addon-fit instead.",
"license": "MIT",
"peerDependencies": {
"xterm": "^5.0.0"
}
},
"node_modules/xterm-addon-search": {
"version": "0.13.0",
"resolved": "https://registry.npmjs.org/xterm-addon-search/-/xterm-addon-search-0.13.0.tgz",
"integrity": "sha512-sDUwG4CnqxUjSEFh676DlS3gsh3XYCzAvBPSvJ5OPgF3MRL3iHLPfsb06doRicLC2xXNpeG2cWk8x1qpESWJMA==",
"deprecated": "This package is now deprecated. Move to @xterm/addon-search instead.",
"license": "MIT",
"peerDependencies": {
"xterm": "^5.0.0"
}
},
"node_modules/xterm-addon-unicode11": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/xterm-addon-unicode11/-/xterm-addon-unicode11-0.6.0.tgz",
"integrity": "sha512-5pkb8YoS/deRtNqQRw8t640mu+Ga8B2MG3RXGQu0bwgcfr8XiXIRI880TWM49ICAHhTmnOLPzIIBIjEnCq7k2A==",
"deprecated": "This package is now deprecated. Move to @xterm/addon-unicode11 instead.",
"license": "MIT",
"peerDependencies": {
"xterm": "^5.0.0"
}
},
"node_modules/xterm-addon-web-links": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/xterm-addon-web-links/-/xterm-addon-web-links-0.9.0.tgz",
"integrity": "sha512-LIzi4jBbPlrKMZF3ihoyqayWyTXAwGfu4yprz1aK2p71e9UKXN6RRzVONR0L+Zd+Ik5tPVI9bwp9e8fDTQh49Q==",
"deprecated": "This package is now deprecated. Move to @xterm/addon-web-links instead.",
"license": "MIT",
"peerDependencies": {
"xterm": "^5.0.0"
}
}
}
}
+5 -5
View File
@@ -13,11 +13,11 @@
},
"dependencies": {
"@novnc/novnc": "^1.5.0",
"xterm": "5.3.0",
"xterm-addon-fit": "0.8.0",
"xterm-addon-search": "0.13.0",
"xterm-addon-unicode11": "0.6.0",
"xterm-addon-web-links": "0.9.0"
"@xterm/addon-fit": "0.11.0",
"@xterm/addon-search": "0.16.0",
"@xterm/addon-unicode11": "0.9.0",
"@xterm/addon-web-links": "0.12.0",
"@xterm/xterm": "6.0.0"
},
"devDependencies": {
"esbuild": "^0.28.1"
+1 -1
View File
@@ -1 +1 @@
0726a81c633cf310d2b07f5c7e100225
2f3e27ceb2ed8494c242e0b06d9f4da3
+6 -6
View File
@@ -14,27 +14,27 @@ const frontendDir = path.resolve(__dirname, "..");
// Mapping: source (relative to node_modules) → destination (relative to frontend/)
const assets = [
{
src: "xterm/css/xterm.css",
src: "@xterm/xterm/css/xterm.css",
dest: "src/css/lib/xterm.css",
},
{
src: "xterm/lib/xterm.js",
src: "@xterm/xterm/lib/xterm.js",
dest: "src/js/lib/xterm.min.js",
},
{
src: "xterm-addon-fit/lib/xterm-addon-fit.js",
src: "@xterm/addon-fit/lib/addon-fit.js",
dest: "src/js/lib/xterm-addon-fit.min.js",
},
{
src: "xterm-addon-search/lib/xterm-addon-search.js",
src: "@xterm/addon-search/lib/addon-search.js",
dest: "src/js/lib/xterm-addon-search.min.js",
},
{
src: "xterm-addon-unicode11/lib/xterm-addon-unicode11.js",
src: "@xterm/addon-unicode11/lib/addon-unicode11.js",
dest: "src/js/lib/xterm-addon-unicode11.min.js",
},
{
src: "xterm-addon-web-links/lib/xterm-addon-web-links.js",
src: "@xterm/addon-web-links/lib/addon-web-links.js",
dest: "src/js/lib/xterm-addon-web-links.min.js",
},
];
+70
View File
@@ -129,6 +129,21 @@ assertContains(
"margin-left: auto;",
"Leviathan mode label must sit on the right side of the sidebar header",
);
assertContains(
"frontend/src/css/tokens.css",
"--tab-bar-height: 44px;",
"tab bar row must match the sidebar header height",
);
assertContains(
"frontend/src/css/sidebar.css",
"height: var(--tab-bar-height);",
"sidebar header must use the shared tab bar height",
);
assertContains(
"frontend/src/css/layout.css",
"height: var(--tab-bar-height);",
"tab bar must use the shared sidebar header height",
);
assertContains(
"frontend/src/js/leviathan.js",
"Hex Editor",
@@ -139,6 +154,21 @@ assertContains(
"LeviathanSetByte",
"Leviathan hex view must support byte editing",
);
assertContains(
"frontend/src/js/leviathan.js",
"_handleHexByteInput",
"Leviathan hex byte edits must update while typing",
);
assertContains(
"frontend/src/js/leviathan.js",
"_updateHexAsciiCell",
"Leviathan hex byte edits must update the ASCII preview immediately",
);
assertContains(
"frontend/src/js/leviathan.js",
"_focusHexByte(cell, 1)",
"Leviathan hex byte edits must advance to the next byte after entry",
);
assertContains(
"frontend/src/js/leviathan.js",
"spectrogram-encode",
@@ -214,6 +244,46 @@ assertContains(
"window.go?.api?.Service",
"Wails service bridge must use the normal named Wails API",
);
assertContains(
"frontend/package.json",
'"@xterm/xterm":',
"frontend dependencies must use the maintained scoped xterm package",
);
assertContains(
"frontend/package.json",
'"@xterm/addon-fit":',
"frontend dependencies must use the maintained scoped xterm addons",
);
assertContains(
"frontend/scripts/copy-assets.js",
"@xterm/xterm/lib/xterm.js",
"xterm browser assets must be copied from the maintained scoped package",
);
assertContains(
"frontend/scripts/copy-assets.js",
"@xterm/addon-fit/lib/addon-fit.js",
"xterm addon browser assets must be copied from the maintained scoped packages",
);
assertNotContains(
"frontend/package.json",
'"xterm":',
"deprecated unscoped xterm dependency must not be restored",
);
assertNotContains(
"frontend/package.json",
'"xterm-addon-',
"deprecated unscoped xterm addon dependencies must not be restored",
);
assertNotContains(
"frontend/package-lock.json",
'"node_modules/xterm"',
"package lock must not contain the deprecated unscoped xterm package",
);
assertNotContains(
"frontend/package-lock.json",
'"node_modules/xterm-addon-',
"package lock must not contain deprecated unscoped xterm addon packages",
);
assertContains(
"frontend/scripts/build.js",
"sourceMappingURL",
+1
View File
@@ -44,6 +44,7 @@
border-bottom: 1px solid var(--border-subtle);
display: flex;
align-items: center;
height: var(--tab-bar-height);
min-height: var(--tab-bar-height);
overflow: hidden;
}
+8
View File
@@ -686,6 +686,14 @@
background: var(--bg-input);
}
.leviathan-byte.is-editing {
border-color: var(--warning);
}
.leviathan-byte.is-saving {
color: var(--accent);
}
.leviathan-byte.is-search-hit {
border-color: var(--warning);
color: var(--text-inverse);
+81 -5
View File
@@ -112,10 +112,6 @@
top: 0;
}
.xterm .xterm-scroll-area {
visibility: hidden;
}
.xterm-char-measure-element {
display: inline-block;
visibility: hidden;
@@ -140,7 +136,7 @@
cursor: crosshair;
}
.xterm .xterm-accessibility,
.xterm .xterm-accessibility:not(.debug),
.xterm .xterm-message {
position: absolute;
left: 0;
@@ -152,6 +148,21 @@
pointer-events: none;
}
.xterm .xterm-accessibility-tree:not(.debug) *::selection {
color: transparent;
}
.xterm .xterm-accessibility-tree {
font-family: monospace;
user-select: text;
white-space: pre;
}
.xterm .xterm-accessibility-tree > div {
transform-origin: left;
width: fit-content;
}
.xterm .live-region {
position: absolute;
left: -9999px;
@@ -207,3 +218,68 @@
z-index: 2;
position: relative;
}
/* Derived from vs/base/browser/ui/scrollbar/media/scrollbar.css */
/* xterm.js customization: Override xterm's cursor style */
.xterm .xterm-scrollable-element > .scrollbar {
cursor: default;
}
/* Arrows */
.xterm .xterm-scrollable-element > .scrollbar > .scra {
cursor: pointer;
font-size: 11px !important;
}
.xterm .xterm-scrollable-element > .visible {
opacity: 1;
/* Background rule added for IE9 - to allow clicks on dom node */
background:rgba(0,0,0,0);
transition: opacity 100ms linear;
/* In front of peek view */
z-index: 11;
}
.xterm .xterm-scrollable-element > .invisible {
opacity: 0;
pointer-events: none;
}
.xterm .xterm-scrollable-element > .invisible.fade {
transition: opacity 800ms linear;
}
/* Scrollable Content Inset Shadow */
.xterm .xterm-scrollable-element > .shadow {
position: absolute;
display: none;
}
.xterm .xterm-scrollable-element > .shadow.top {
display: block;
top: 0;
left: 3px;
height: 3px;
width: 100%;
box-shadow: var(--vscode-scrollbar-shadow, #000) 0 6px 6px -6px inset;
}
.xterm .xterm-scrollable-element > .shadow.left {
display: block;
top: 3px;
left: 0;
height: 100%;
width: 3px;
box-shadow: var(--vscode-scrollbar-shadow, #000) 6px 0 6px -6px inset;
}
.xterm .xterm-scrollable-element > .shadow.top-left-corner {
display: block;
top: 0;
left: 0;
height: 3px;
width: 3px;
}
.xterm .xterm-scrollable-element > .shadow.top.left {
box-shadow: var(--vscode-scrollbar-shadow, #000) 6px 0 6px -6px inset;
}
+1
View File
@@ -10,6 +10,7 @@
display: flex;
align-items: center;
padding: var(--space-3) var(--space-4);
height: var(--tab-bar-height);
min-height: var(--tab-bar-height);
border-bottom: 1px solid var(--border-subtle);
flex-shrink: 0;
+1 -1
View File
@@ -139,7 +139,7 @@
----------------------------------------------------------------------- */
--sidebar-width: 260px;
--sidebar-width-collapsed: 48px;
--tab-bar-height: 36px;
--tab-bar-height: 44px;
--toolbar-height: 40px;
--status-bar-height: 24px;
}
+183 -12
View File
@@ -572,34 +572,205 @@
line.appendChild(createElement("span", "leviathan-offset", { textContent: this._hexOffset(row.offset) }));
const bytes = createElement("span", "leviathan-byte-cells");
const cells = row.bytes || String(row.hex || "").split(/\s+/).filter(Boolean);
const ascii = createElement("span", "leviathan-ascii", { textContent: row.ascii || "" });
cells.forEach((value, idx) => {
const cellOffset = (row.offset || 0) + idx;
const hexValue = this._normaliseHexByte(value) || "00";
const cell = createElement("input", "leviathan-byte", {
value,
value: hexValue,
maxlength: "2",
inputmode: "text",
autocomplete: "off",
spellcheck: "false",
"aria-label": `Byte ${this._hexOffset(cellOffset)}`,
dataset: {
offset: String(cellOffset),
committedHex: hexValue,
},
});
if (activeHit && cellOffset >= activeHit.offset && cellOffset < activeHit.offset + activeHit.length) {
cell.classList.add("is-search-hit");
}
cell.addEventListener("change", async () => {
try {
await window.NexusTerminal.wailsService.LeviathanSetByte(cellOffset, cell.value);
cell.value = cell.value.trim().padStart(2, "0").slice(-2).toLowerCase();
status.textContent = "Edited " + this._hexOffset(cellOffset);
} catch (err) {
status.textContent = String(err);
cell.value = value;
}
});
this._wireHexByteCell(cell, bytes, ascii, idx, status);
bytes.appendChild(cell);
});
line.appendChild(bytes);
line.appendChild(createElement("span", "leviathan-ascii", { textContent: row.ascii || "" }));
line.appendChild(ascii);
grid.appendChild(line);
}
}
_wireHexByteCell(cell, rowCells, ascii, asciiIndex, status) {
cell.addEventListener("focus", () => {
cell.select();
});
cell.addEventListener("keydown", (event) => {
if (event.key === "ArrowRight") {
event.preventDefault();
this._focusHexByte(cell, 1);
} else if (event.key === "ArrowLeft") {
event.preventDefault();
this._focusHexByte(cell, -1);
} else if (event.key === "Enter" || event.key === " ") {
event.preventDefault();
this._finaliseHexByte(cell, rowCells, ascii, asciiIndex, status, { advance: 1 });
} else if (event.key === "Backspace" && cell.value.length === 0) {
event.preventDefault();
this._focusHexByte(cell, -1);
}
});
cell.addEventListener("input", () => {
this._handleHexByteInput(cell, rowCells, ascii, asciiIndex, status);
});
cell.addEventListener("paste", (event) => {
this._pasteHexBytes(event, cell, rowCells, ascii, asciiIndex, status);
});
cell.addEventListener("blur", () => {
this._finaliseHexByte(cell, rowCells, ascii, asciiIndex, status, { advance: 0 });
});
}
_handleHexByteInput(cell, rowCells, ascii, asciiIndex, status) {
const clean = this._normaliseHexByte(cell.value);
if (cell.value !== clean) cell.value = clean;
cell.classList.toggle("is-editing", clean.length === 1);
if (clean.length === 0) {
this._updateHexAsciiCell(ascii, asciiIndex, cell.dataset.committedHex || "00");
rowCells.classList.toggle("is-editing", Boolean(rowCells.querySelector(".leviathan-byte.is-editing")));
return;
}
if (clean.length === 2) {
this._updateHexAsciiCell(ascii, asciiIndex, clean);
this._commitHexByte(cell, ascii, asciiIndex, status);
this._focusHexByte(cell, 1);
}
rowCells.classList.toggle("is-editing", Boolean(rowCells.querySelector(".leviathan-byte.is-editing")));
}
_finaliseHexByte(cell, rowCells, ascii, asciiIndex, status, options = {}) {
let clean = this._normaliseHexByte(cell.value);
if (clean.length === 0) {
clean = cell.dataset.committedHex || "00";
} else if (clean.length === 1) {
clean = clean.padStart(2, "0");
}
cell.value = clean;
cell.classList.remove("is-editing");
rowCells.classList.toggle("is-editing", Boolean(rowCells.querySelector(".leviathan-byte.is-editing")));
this._updateHexAsciiCell(ascii, asciiIndex, clean);
this._commitHexByte(cell, ascii, asciiIndex, status);
if (options.advance) this._focusHexByte(cell, options.advance);
}
_pasteHexBytes(event, cell, rowCells, ascii, asciiIndex, status) {
const text = event.clipboardData?.getData("text/plain") || "";
const pasted = this._hexByteList(text);
if (!pasted.length) return;
event.preventDefault();
const scope = cell.closest(".leviathan-hex-grid") || rowCells;
const cells = Array.from(scope.querySelectorAll(".leviathan-byte"));
const startIndex = cells.indexOf(cell);
if (startIndex < 0) return;
pasted.forEach((hex, idx) => {
const target = cells[startIndex + idx];
if (!target) return;
const context = this._hexCellContext(target);
if (!context) return;
target.value = hex;
target.classList.remove("is-editing");
this._updateHexAsciiCell(context.ascii, context.index, hex);
this._commitHexByte(target, context.ascii, context.index, status);
});
const next = cells[Math.min(startIndex + pasted.length, cells.length - 1)];
if (next) {
next.focus();
next.select();
}
}
_commitHexByte(cell, ascii, asciiIndex, status) {
const hex = this._normaliseHexByte(cell.value);
if (hex.length !== 2) return;
if (hex === cell.dataset.committedHex || hex === cell.dataset.pendingHex) return;
const previous = cell.dataset.committedHex || "00";
const offset = Number(cell.dataset.offset || 0);
cell.dataset.pendingHex = hex;
cell.classList.add("is-saving");
window.NexusTerminal.wailsService
.LeviathanSetByte(offset, hex)
.then((payload) => {
if (cell.dataset.pendingHex === hex) {
delete cell.dataset.pendingHex;
cell.dataset.committedHex = hex;
cell.classList.remove("is-saving");
status.textContent = "Edited " + this._hexOffset(offset);
this.applyState(payload);
}
})
.catch((err) => {
if (cell.dataset.pendingHex === hex) {
delete cell.dataset.pendingHex;
cell.classList.remove("is-saving");
cell.value = previous;
this._updateHexAsciiCell(ascii, asciiIndex, previous);
status.textContent = String(err);
}
});
}
_focusHexByte(cell, direction) {
const scope = cell.closest(".leviathan-hex-grid") || cell.closest(".leviathan-byte-cells");
if (!scope) return;
const cells = Array.from(scope.querySelectorAll(".leviathan-byte"));
const index = cells.indexOf(cell);
const next = cells[index + direction];
if (!next) return;
next.focus();
next.select();
}
_hexCellContext(cell) {
const row = cell.closest(".leviathan-hex-row");
if (!row) return null;
const ascii = row.querySelector(".leviathan-ascii");
const rowCells = Array.from(row.querySelectorAll(".leviathan-byte"));
const index = rowCells.indexOf(cell);
if (!ascii || index < 0) return null;
return { ascii, index };
}
_updateHexAsciiCell(ascii, index, hex) {
const chars = Array.from(ascii.textContent || "");
while (chars.length <= index) chars.push(" ");
chars[index] = this._hexByteToAscii(hex);
ascii.textContent = chars.join("");
}
_hexByteToAscii(hex) {
const value = Number.parseInt(hex, 16);
if (!Number.isFinite(value)) return ".";
return value >= 32 && value < 127 ? String.fromCharCode(value) : ".";
}
_normaliseHexByte(value) {
return String(value || "")
.replace(/[^0-9a-f]/gi, "")
.slice(0, 2)
.toLowerCase();
}
_hexByteList(value) {
const clean = String(value || "")
.replace(/0x/gi, "")
.replace(/[^0-9a-f]/gi, "")
.toLowerCase();
const bytes = [];
for (let i = 0; i + 1 < clean.length; i += 2) {
bytes.push(clean.slice(i, i + 2));
}
return bytes;
}
_renderParams(toolId, container) {
container.innerHTML = "";
const cfg = defaults[toolId] || {};
+2 -2
View File
@@ -1,2 +1,2 @@
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.FitAddon=t():e.FitAddon=t()}(self,(()=>(()=>{"use strict";var e={};return(()=>{var t=e;Object.defineProperty(t,"__esModule",{value:!0}),t.FitAddon=void 0,t.FitAddon=class{activate(e){this._terminal=e}dispose(){}fit(){const e=this.proposeDimensions();if(!e||!this._terminal||isNaN(e.cols)||isNaN(e.rows))return;const t=this._terminal._core;this._terminal.rows===e.rows&&this._terminal.cols===e.cols||(t._renderService.clear(),this._terminal.resize(e.cols,e.rows))}proposeDimensions(){if(!this._terminal)return;if(!this._terminal.element||!this._terminal.element.parentElement)return;const e=this._terminal._core,t=e._renderService.dimensions;if(0===t.css.cell.width||0===t.css.cell.height)return;const r=0===this._terminal.options.scrollback?0:e.viewport.scrollBarWidth,i=window.getComputedStyle(this._terminal.element.parentElement),o=parseInt(i.getPropertyValue("height")),s=Math.max(0,parseInt(i.getPropertyValue("width"))),n=window.getComputedStyle(this._terminal.element),l=o-(parseInt(n.getPropertyValue("padding-top"))+parseInt(n.getPropertyValue("padding-bottom"))),a=s-(parseInt(n.getPropertyValue("padding-right"))+parseInt(n.getPropertyValue("padding-left")))-r;return{cols:Math.max(2,Math.floor(a/t.css.cell.width)),rows:Math.max(1,Math.floor(l/t.css.cell.height))}}}})(),e})()));
//# sourceMappingURL=xterm-addon-fit.js.map
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.FitAddon=t():e.FitAddon=t()}(globalThis,(()=>(()=>{"use strict";var e={};return(()=>{var t=e;Object.defineProperty(t,"__esModule",{value:!0}),t.FitAddon=void 0,t.FitAddon=class{activate(e){this._terminal=e}dispose(){}fit(){const e=this.proposeDimensions();if(!e||!this._terminal||isNaN(e.cols)||isNaN(e.rows))return;const t=this._terminal._core;this._terminal.rows===e.rows&&this._terminal.cols===e.cols||(t._renderService.clear(),this._terminal.resize(e.cols,e.rows))}proposeDimensions(){if(!this._terminal)return;if(!this._terminal.element||!this._terminal.element.parentElement)return;const e=this._terminal._core._renderService.dimensions;if(0===e.css.cell.width||0===e.css.cell.height)return;const t=0===this._terminal.options.scrollback?0:this._terminal.options.overviewRuler?.width||14,r=window.getComputedStyle(this._terminal.element.parentElement),i=parseInt(r.getPropertyValue("height")),o=Math.max(0,parseInt(r.getPropertyValue("width"))),s=window.getComputedStyle(this._terminal.element),n=i-(parseInt(s.getPropertyValue("padding-top"))+parseInt(s.getPropertyValue("padding-bottom"))),l=o-(parseInt(s.getPropertyValue("padding-right"))+parseInt(s.getPropertyValue("padding-left")))-t;return{cols:Math.max(2,Math.floor(l/e.css.cell.width)),rows:Math.max(1,Math.floor(n/e.css.cell.height))}}}})(),e})()));
//# sourceMappingURL=addon-fit.js.map
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -1,2 +1,2 @@
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.WebLinksAddon=t():e.WebLinksAddon=t()}(self,(()=>(()=>{"use strict";var e={6:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.LinkComputer=t.WebLinkProvider=void 0,t.WebLinkProvider=class{constructor(e,t,n,i={}){this._terminal=e,this._regex=t,this._handler=n,this._options=i}provideLinks(e,t){const i=n.computeLink(e,this._regex,this._terminal,this._handler);t(this._addCallbacks(i))}_addCallbacks(e){return e.map((e=>(e.leave=this._options.leave,e.hover=(t,n)=>{if(this._options.hover){const{range:i}=e;this._options.hover(t,n,i)}},e)))}};class n{static computeLink(e,t,i,r){const o=new RegExp(t.source,(t.flags||"")+"g"),[s,a]=n._getWindowedLineStrings(e-1,i),c=s.join("");let d;const l=[];for(;d=o.exec(c);){const e=d[0];try{const t=new URL(e),n=decodeURI(t.toString());if(e!==n&&e+"/"!==n)continue}catch(e){continue}const[t,o]=n._mapStrIdx(i,a,0,d.index),[s,c]=n._mapStrIdx(i,t,o,e.length);if(-1===t||-1===o||-1===s||-1===c)continue;const p={start:{x:o+1,y:t+1},end:{x:c,y:s+1}};l.push({range:p,text:e,activate:r})}return l}static _getWindowedLineStrings(e,t){let n,i=e,r=e,o=0,s="";const a=[];if(n=t.buffer.active.getLine(e)){const e=n.translateToString(!0);if(n.isWrapped&&" "!==e[0]){for(o=0;(n=t.buffer.active.getLine(--i))&&o<2048&&(s=n.translateToString(!0),o+=s.length,a.push(s),n.isWrapped&&-1===s.indexOf(" ")););a.reverse()}for(a.push(e),o=0;(n=t.buffer.active.getLine(++r))&&n.isWrapped&&o<2048&&(s=n.translateToString(!0),o+=s.length,a.push(s),-1===s.indexOf(" ")););}return[a,i]}static _mapStrIdx(e,t,n,i){const r=e.buffer.active,o=r.getNullCell();let s=n;for(;i;){const e=r.getLine(t);if(!e)return[-1,-1];for(let n=s;n<e.length;++n){e.getCell(n,o);const s=o.getChars();if(o.getWidth()&&(i-=s.length||1,n===e.length-1&&""===s)){const e=r.getLine(t+1);e&&e.isWrapped&&(e.getCell(0,o),2===o.getWidth()&&(i+=1))}if(i<0)return[t,n]}t++,s=0}return[t,s]}}t.LinkComputer=n}},t={};function n(i){var r=t[i];if(void 0!==r)return r.exports;var o=t[i]={exports:{}};return e[i](o,o.exports,n),o.exports}var i={};return(()=>{var e=i;Object.defineProperty(e,"__esModule",{value:!0}),e.WebLinksAddon=void 0;const t=n(6),r=/https?:[/]{2}[^\s"'!*(){}|\\\^<>`]*[^\s"':,.!?{}|\\\^~\[\]`()<>]/;function o(e,t){const n=window.open();if(n){try{n.opener=null}catch(e){}n.location.href=t}else console.warn("Opening link blocked as opener could not be cleared")}e.WebLinksAddon=class{constructor(e=o,t={}){this._handler=e,this._options=t}activate(e){this._terminal=e;const n=this._options,i=n.urlRegex||r;this._linkProvider=this._terminal.registerLinkProvider(new t.WebLinkProvider(this._terminal,i,this._handler,n))}dispose(){var e;null===(e=this._linkProvider)||void 0===e||e.dispose()}}})(),i})()));
//# sourceMappingURL=xterm-addon-web-links.js.map
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.WebLinksAddon=t():e.WebLinksAddon=t()}(globalThis,(()=>(()=>{"use strict";var e={490:(e,t)=>{function n(e){try{const t=new URL(e),n=t.password&&t.username?`${t.protocol}//${t.username}:${t.password}@${t.host}`:t.username?`${t.protocol}//${t.username}@${t.host}`:`${t.protocol}//${t.host}`;return e.toLocaleLowerCase().startsWith(n.toLocaleLowerCase())}catch(e){return!1}}Object.defineProperty(t,"__esModule",{value:!0}),t.LinkComputer=t.WebLinkProvider=void 0,t.WebLinkProvider=class{constructor(e,t,n,o={}){this._terminal=e,this._regex=t,this._handler=n,this._options=o}provideLinks(e,t){const n=o.computeLink(e,this._regex,this._terminal,this._handler);t(this._addCallbacks(n))}_addCallbacks(e){return e.map((e=>(e.leave=this._options.leave,e.hover=(t,n)=>{if(this._options.hover){const{range:o}=e;this._options.hover(t,n,o)}},e)))}};class o{static computeLink(e,t,r,i){const s=new RegExp(t.source,(t.flags||"")+"g"),[a,c]=o._getWindowedLineStrings(e-1,r),l=a.join("");let d;const p=[];for(;d=s.exec(l);){const e=d[0];if(!n(e))continue;const[t,s]=o._mapStrIdx(r,c,0,d.index),[a,l]=o._mapStrIdx(r,t,s,e.length);if(-1===t||-1===s||-1===a||-1===l)continue;const h={start:{x:s+1,y:t+1},end:{x:l,y:a+1}};p.push({range:h,text:e,activate:i})}return p}static _getWindowedLineStrings(e,t){let n,o=e,r=e,i=0,s="";const a=[];if(n=t.buffer.active.getLine(e)){const e=n.translateToString(!0);if(n.isWrapped&&" "!==e[0]){for(i=0;(n=t.buffer.active.getLine(--o))&&i<2048&&(s=n.translateToString(!0),i+=s.length,a.push(s),n.isWrapped&&-1===s.indexOf(" ")););a.reverse()}for(a.push(e),i=0;(n=t.buffer.active.getLine(++r))&&n.isWrapped&&i<2048&&(s=n.translateToString(!0),i+=s.length,a.push(s),-1===s.indexOf(" ")););}return[a,o]}static _mapStrIdx(e,t,n,o){const r=e.buffer.active,i=r.getNullCell();let s=n;for(;o;){const e=r.getLine(t);if(!e)return[-1,-1];for(let n=s;n<e.length;++n){e.getCell(n,i);const s=i.getChars();if(i.getWidth()&&(o-=s.length||1,n===e.length-1&&""===s)){const e=r.getLine(t+1);e&&e.isWrapped&&(e.getCell(0,i),2===i.getWidth()&&(o+=1))}if(o<0)return[t,n]}t++,s=0}return[t,s]}}t.LinkComputer=o}},t={};function n(o){var r=t[o];if(void 0!==r)return r.exports;var i=t[o]={exports:{}};return e[o](i,i.exports,n),i.exports}var o={};return(()=>{var e=o;Object.defineProperty(e,"__esModule",{value:!0}),e.WebLinksAddon=void 0;const t=n(490),r=/(https?|HTTPS?):[/]{2}[^\s"'!*(){}|\\\^<>`]*[^\s"':,.!?{}|\\\^~\[\]`()<>]/;function i(e,t){const n=window.open();if(n){try{n.opener=null}catch{}n.location.href=t}else console.warn("Opening link blocked as opener could not be cleared")}e.WebLinksAddon=class{constructor(e=i,t={}){this._handler=e,this._options=t}activate(e){this._terminal=e;const n=this._options,o=n.urlRegex||r;this._linkProvider=this._terminal.registerLinkProvider(new t.WebLinkProvider(this._terminal,o,this._handler,n))}dispose(){this._linkProvider?.dispose()}}})(),o})()));
//# sourceMappingURL=addon-web-links.js.map
+1 -1
View File
File diff suppressed because one or more lines are too long