refactor: extract typed frontend core utilities
This commit is contained in:
@@ -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 = `<span class="rds-ps-flags">${overlayTrafficFlagHtml("TP", rds?.traffic_program)}${overlayTrafficFlagHtml("TA", rds?.traffic_announcement)}</span>`;
|
||||
return `<span class="${mainClass}">${hasPs ? formatPsHtml(ps) : escapeMapHtml(mainText)}</span><span class="rds-ps-meta"><span class="rds-ps-meta-text">${escapeMapHtml(metaText)}</span>${trafficFlags}</span>`;
|
||||
return `<span class="${mainClass}">${hasPs ? formatPsHtml(ps) : escapeHtml(mainText)}</span><span class="rds-ps-meta"><span class="rds-ps-meta-text">${escapeHtml(metaText)}</span>${trafficFlags}</span>`;
|
||||
}
|
||||
function collectRdsOverlayEntries() {
|
||||
const entries = [];
|
||||
@@ -2901,7 +2905,7 @@ ${unsupportedBandSummary()}`;
|
||||
if (titleEl) {
|
||||
if (ownerWebsiteUrl) {
|
||||
const label = ownerWebsiteName || displayLabelFromUrl(ownerWebsiteUrl);
|
||||
titleEl.innerHTML = `<a class="title-link" href="${escapeMapHtml(ownerWebsiteUrl)}" target="_blank" rel="noopener">${escapeMapHtml(label)}</a>`;
|
||||
titleEl.innerHTML = `<a class="title-link" href="${escapeHtml(ownerWebsiteUrl)}" target="_blank" rel="noopener">${escapeHtml(label)}</a>`;
|
||||
} 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 <a href="https://qrzcq.com/call/${encodedCallsign}" target="_blank" rel="noopener">${safeCallsign}</a>`;
|
||||
serverSubtitle.innerHTML = `${escapeHtml(base)} hosted by <a href="https://qrzcq.com/call/${encodedCallsign}" target="_blank" rel="noopener">${safeCallsign}</a>`;
|
||||
}
|
||||
updateRigSubtitle(lastActiveRigId);
|
||||
if (ownerSubtitle) {
|
||||
if (ownerCallsign) {
|
||||
const safeOwner = escapeMapHtml(ownerCallsign);
|
||||
const safeOwner = escapeHtml(ownerCallsign);
|
||||
const encodedOwner = encodeURIComponent(ownerCallsign);
|
||||
ownerSubtitle.innerHTML = `Owner: <a href="https://qrzcq.com/call/${encodedOwner}" target="_blank" rel="noopener">${safeOwner}</a>`;
|
||||
} 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 += `<tr><td>${escapeMapHtml(r.rig_id)}</td><td>${r.vchan_id ? escapeMapHtml(r.vchan_id) : "-"}</td><td>${escapeMapHtml(fname)}</td><td>${started}</td></tr>`;
|
||||
html += `<tr><td>${escapeHtml(r.rig_id)}</td><td>${r.vchan_id ? escapeHtml(r.vchan_id) : "-"}</td><td>${escapeHtml(fname)}</td><td>${started}</td></tr>`;
|
||||
}
|
||||
html += "</tbody></table>";
|
||||
el.innerHTML = html;
|
||||
@@ -5665,7 +5669,7 @@ ${unsupportedBandSummary()}`;
|
||||
}
|
||||
let html = '<table class="recorder-table"><thead><tr><th>File</th><th>Size</th><th>Actions</th></tr></thead><tbody>';
|
||||
for (const f of page) {
|
||||
const safeName = escapeMapHtml(f.name);
|
||||
const safeName = escapeHtml(f.name);
|
||||
const encodedName = encodeURIComponent(f.name);
|
||||
html += '<tr data-name="' + safeName + '"><td>' + safeName + "</td><td>" + recorderFormatSize(f.size) + '</td><td><div class="rec-file-actions"><button class="rec-file-btn rec-play-btn" data-name="' + safeName + '" data-url="/api/recorder/download/' + encodedName + '" type="button" aria-expanded="false">Play</button><a class="rec-file-btn" href="/api/recorder/download/' + encodedName + '" download="' + safeName + '">Download</a><button class="rec-file-btn rec-delete-btn" data-name="' + safeName + '" type="button">Remove</button></div></td></tr>';
|
||||
}
|
||||
@@ -6643,7 +6647,7 @@ ${unsupportedBandSummary()}`;
|
||||
if (ch == null || ch === " ") {
|
||||
html += `<span class="rds-ps-gap">_</span>`;
|
||||
} 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 ? `<span class="spectrum-bookmark-side-head"><svg class='bm-icon-svg' viewBox='0 0 8 12' width='8' height='12' aria-hidden='true'><path d='M0,0 h8 v10 l-4,2 l-4,-2 Z'/></svg><span class="spectrum-bookmark-freq">${escapeMapHtml(freqStr)}</span></span><span class="spectrum-bookmark-name">${escapeMapHtml(bm.name)}</span>` : "<svg class='bm-icon-svg' viewBox='0 0 8 12' width='8' height='12' aria-hidden='true'><path d='M0,0 h8 v10 l-4,2 l-4,-2 Z'/></svg> <span class='spectrum-bookmark-name'>" + escapeMapHtml(bm.name) + "</span>";
|
||||
const labelHtml = options.sideStack ? `<span class="spectrum-bookmark-side-head"><svg class='bm-icon-svg' viewBox='0 0 8 12' width='8' height='12' aria-hidden='true'><path d='M0,0 h8 v10 l-4,2 l-4,-2 Z'/></svg><span class="spectrum-bookmark-freq">${escapeHtml(freqStr)}</span></span><span class="spectrum-bookmark-name">${escapeHtml(bm.name)}</span>` : "<svg class='bm-icon-svg' viewBox='0 0 8 12' width='8' height='12' aria-hidden='true'><path d='M0,0 h8 v10 l-4,2 l-4,-2 Z'/></svg> <span class='spectrum-bookmark-name'>" + escapeHtml(bm.name) + "</span>";
|
||||
span.innerHTML = labelHtml;
|
||||
const col = colorMap[bm.category || ""];
|
||||
span.style.setProperty("--bm-cat-bg", col);
|
||||
|
||||
Reference in New Issue
Block a user