diff --git a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/generated/app.js b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/generated/app.js index cb434840..6a9a2707 100644 --- a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/generated/app.js +++ b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/generated/app.js @@ -50,6 +50,28 @@ return `${field1}${field2}${square1}${square2}${sub1}${sub2}`; } + // src/core/dom.ts + function escapeHtml(input) { + return String(input).replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """); + } + + // src/core/settings.ts + var STORAGE_PREFIX2 = "trx_"; + function saveSetting(key, value) { + try { + localStorage.setItem(`${STORAGE_PREFIX2}${key}`, JSON.stringify(value)); + } catch { + } + } + function loadSetting(key, fallback) { + try { + const value = localStorage.getItem(`${STORAGE_PREFIX2}${key}`); + return value === null ? fallback : JSON.parse(value); + } catch { + return fallback; + } + } + // src/app.js var decoderRegistry = []; window.decoderRegistry = decoderRegistry; @@ -105,24 +127,6 @@ } }); } - var STORAGE_PREFIX = "trx_"; - function saveSetting(key, value) { - try { - localStorage.setItem(STORAGE_PREFIX + key, JSON.stringify(value)); - } catch (e) { - } - } - function loadSetting(key, fallback) { - try { - const v = localStorage.getItem(STORAGE_PREFIX + key); - return v !== null ? JSON.parse(v) : fallback; - } catch (e) { - return fallback; - } - } - function escapeMapHtml(input) { - return String(input).replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """); - } var authRole = null; var authEnabled = true; async function checkAuthStatus() { @@ -1891,7 +1895,7 @@ const mainClass = hasPs ? "rds-ps-main" : "rds-ps-fallback"; const metaText = hasPs ? `${formatOverlayPi(rds?.pi)} · ${formatOverlayPty(rds?.pty, rds?.pty_name)}` : rds?.pty_name ?? (rds?.pty != null ? String(rds.pty) : ""); const trafficFlags = `${overlayTrafficFlagHtml("TP", rds?.traffic_program)}${overlayTrafficFlagHtml("TA", rds?.traffic_announcement)}`; - return `${hasPs ? formatPsHtml(ps) : escapeMapHtml(mainText)}${escapeMapHtml(metaText)}${trafficFlags}`; + return `${hasPs ? formatPsHtml(ps) : escapeHtml(mainText)}${escapeHtml(metaText)}${trafficFlags}`; } function collectRdsOverlayEntries() { const entries = []; @@ -2901,7 +2905,7 @@ ${unsupportedBandSummary()}`; if (titleEl) { if (ownerWebsiteUrl) { const label = ownerWebsiteName || displayLabelFromUrl(ownerWebsiteUrl); - titleEl.innerHTML = `${escapeMapHtml(label)}`; + titleEl.innerHTML = `${escapeHtml(label)}`; } else { titleEl.textContent = serverVersion ? `trx-rs v${serverVersion}` : "trx-rs"; } @@ -2994,14 +2998,14 @@ ${unsupportedBandSummary()}`; } if (serverSubtitle && update.server_callsign) { const base = serverSubtitle.textContent.split(" hosted by")[0]; - const safeCallsign = escapeMapHtml(update.server_callsign); + const safeCallsign = escapeHtml(update.server_callsign); const encodedCallsign = encodeURIComponent(update.server_callsign); - serverSubtitle.innerHTML = `${escapeMapHtml(base)} hosted by ${safeCallsign}`; + serverSubtitle.innerHTML = `${escapeHtml(base)} hosted by ${safeCallsign}`; } updateRigSubtitle(lastActiveRigId); if (ownerSubtitle) { if (ownerCallsign) { - const safeOwner = escapeMapHtml(ownerCallsign); + const safeOwner = escapeHtml(ownerCallsign); const encodedOwner = encodeURIComponent(ownerCallsign); ownerSubtitle.innerHTML = `Owner: ${safeOwner}`; } else { @@ -4549,7 +4553,7 @@ ${unsupportedBandSummary()}`; saveSetting, loadSetting, showHint, - escapeMapHtml, + escapeMapHtml: escapeHtml, formatFreq, formatFreqForHumans, formatWavelength, @@ -5591,7 +5595,7 @@ ${unsupportedBandSummary()}`; for (const r of list) { const started = new Date(r.started_at * 1e3).toLocaleTimeString(); const fname = r.path.split("/").pop(); - html += `${escapeMapHtml(r.rig_id)}${r.vchan_id ? escapeMapHtml(r.vchan_id) : "-"}${escapeMapHtml(fname)}${started}`; + html += `${escapeHtml(r.rig_id)}${r.vchan_id ? escapeHtml(r.vchan_id) : "-"}${escapeHtml(fname)}${started}`; } html += ""; el.innerHTML = html; @@ -5665,7 +5669,7 @@ ${unsupportedBandSummary()}`; } let html = ''; for (const f of page) { - const safeName = escapeMapHtml(f.name); + const safeName = escapeHtml(f.name); const encodedName = encodeURIComponent(f.name); html += ''; } @@ -6643,7 +6647,7 @@ ${unsupportedBandSummary()}`; if (ch == null || ch === " ") { html += `_`; } else { - html += escapeMapHtml(ch); + html += escapeHtml(ch); } } return html; @@ -7165,7 +7169,7 @@ ${unsupportedBandSummary()}`; } span.title = buildBookmarkTooltipText(bm) || bm.name + " — " + freqStr + (bm.comment ? "\n" + bm.comment : ""); span.dataset.bmId = bm.id; - const labelHtml = options.sideStack ? `${escapeMapHtml(freqStr)}${escapeMapHtml(bm.name)}` : " " + escapeMapHtml(bm.name) + ""; + const labelHtml = options.sideStack ? `${escapeHtml(freqStr)}${escapeHtml(bm.name)}` : " " + escapeHtml(bm.name) + ""; span.innerHTML = labelHtml; const col = colorMap[bm.category || ""]; span.style.setProperty("--bm-cat-bg", col); diff --git a/src/trx-client/trx-frontend/trx-frontend-http/frontend/src/app.js b/src/trx-client/trx-frontend/trx-frontend-http/frontend/src/app.js index fc99a6ca..fb2b0a5e 100644 --- a/src/trx-client/trx-frontend/trx-frontend-http/frontend/src/app.js +++ b/src/trx-client/trx-frontend/trx-frontend-http/frontend/src/app.js @@ -9,6 +9,8 @@ import { latLonToMaidenhead, locatorToLatLon, } from "./core/geo.js"; +import { escapeHtml as escapeMapHtml } from "./core/dom.js"; +import { loadSetting, saveSetting } from "./core/settings.js"; // --- Decoder registry (fetched from /decoders on load) --- /** @type {Array<{id:string,label:string,activation:string,active_modes:string[],background_decode:boolean,bookmark_selectable:boolean}>} */ @@ -75,25 +77,6 @@ function hideUnsupportedDecoderTabs() { }); } -// --- Persistent settings (localStorage) --- -const STORAGE_PREFIX = "trx_"; -function saveSetting(key, value) { - try { localStorage.setItem(STORAGE_PREFIX + key, JSON.stringify(value)); } catch(e) {} -} -function loadSetting(key, fallback) { - try { - const v = localStorage.getItem(STORAGE_PREFIX + key); - return v !== null ? JSON.parse(v) : fallback; - } catch(e) { return fallback; } -} -function escapeMapHtml(input) { - return String(input) - .replaceAll("&", "&") - .replaceAll("<", "<") - .replaceAll(">", ">") - .replaceAll("\"", """); -} - // --- Authentication --- let authRole = null; // null (not authenticated), "rx" (read-only), or "control" (full access) let authEnabled = true; diff --git a/src/trx-client/trx-frontend/trx-frontend-http/frontend/src/core/dom.ts b/src/trx-client/trx-frontend/trx-frontend-http/frontend/src/core/dom.ts new file mode 100644 index 00000000..a4aaf9a7 --- /dev/null +++ b/src/trx-client/trx-frontend/trx-frontend-http/frontend/src/core/dom.ts @@ -0,0 +1,11 @@ +// SPDX-FileCopyrightText: 2026 Stan Grams +// +// SPDX-License-Identifier: GPL-2.0-or-later + +export function escapeHtml(input: unknown): string { + return String(input) + .replaceAll("&", "&") + .replaceAll("<", "<") + .replaceAll(">", ">") + .replaceAll("\"", """); +} diff --git a/src/trx-client/trx-frontend/trx-frontend-http/frontend/src/core/settings.ts b/src/trx-client/trx-frontend/trx-frontend-http/frontend/src/core/settings.ts new file mode 100644 index 00000000..2c116746 --- /dev/null +++ b/src/trx-client/trx-frontend/trx-frontend-http/frontend/src/core/settings.ts @@ -0,0 +1,22 @@ +// SPDX-FileCopyrightText: 2026 Stan Grams +// +// SPDX-License-Identifier: GPL-2.0-or-later + +const STORAGE_PREFIX = "trx_"; + +export function saveSetting(key: string, value: unknown): void { + try { + localStorage.setItem(`${STORAGE_PREFIX}${key}`, JSON.stringify(value)); + } catch { + // Storage can be unavailable in private browsing or under a strict policy. + } +} + +export function loadSetting(key: string, fallback: T): T { + try { + const value = localStorage.getItem(`${STORAGE_PREFIX}${key}`); + return value === null ? fallback : JSON.parse(value) as T; + } catch { + return fallback; + } +}
FileSizeActions
' + safeName + "" + recorderFormatSize(f.size) + '
Download