Merge pull request #44 from Plastdroid/fix/popup-tooltip-html-escape

Escape HTML in node names
This commit is contained in:
Plastdroid
2026-06-07 04:20:26 +02:00
committed by GitHub
3 changed files with 35 additions and 8 deletions
+12 -3
View File
@@ -21,6 +21,15 @@ document.addEventListener("DOMContentLoaded", async function () {
nodesById: {},
};
function escapeHtml(s) {
return String(s)
.replaceAll('&', '&')
.replaceAll('<', '&lt;')
.replaceAll('>', '&gt;')
.replaceAll('"', '&quot;')
.replaceAll("'", '&#39;');
}
radioButtons.forEach(radio => {
radio.addEventListener("change", fetchMessages);
});
@@ -116,13 +125,13 @@ document.addEventListener("DOMContentLoaded", async function () {
<div class="p-2 flex">
<div class="d-flex rounded-circle shadow text-white justify-content-center align-items-center"
style="width: 48px; height: 48px; background-color: ${getNodeColour(message.from)}; color: #ffffff;">
${getNodeShortName(message.from)}
${escapeHtml(getNodeShortName(message.from))}
</div>
</div>
<div class="flex">
<div class="small">
<a target="_blank" href="https://map.sthlm-mesh.se/?node_id=${message.from}" style="color: grey; text-decoration: none;">${getNodeLongName(message.from)}</a>
${message.to !== "4294967295" ? ` → <a target="_blank" href="https://map.sthlm-mesh.se/?node_id=${message.to}" style="color: grey; text-decoration: none;">${getNodeLongName(message.to)}</a>` : ""}
<a target="_blank" href="https://map.sthlm-mesh.se/?node_id=${message.from}" style="color: grey; text-decoration: none;">${escapeHtml(getNodeLongName(message.from))}</a>
${message.to !== "4294967295" ? ` → <a target="_blank" href="https://map.sthlm-mesh.se/?node_id=${message.to}" style="color: grey; text-decoration: none;">${escapeHtml(getNodeLongName(message.to))}</a>` : ""}
</div>
<div class="px-2 py-1 pb-1 border rounded shadow-sm" style="background-color: #efefef">
<div class="">${escapeMessageText(message.text)}</div>
+11 -2
View File
@@ -1,3 +1,12 @@
function escapeHtml(s) {
return String(s)
.replaceAll('&', '&amp;')
.replaceAll('<', '&lt;')
.replaceAll('>', '&gt;')
.replaceAll('"', '&quot;')
.replaceAll("'", '&#39;');
}
// RSVP response patterns (order matters - check longer phrases first!)
const RESPONSE_PATTERNS = {
'no': ['kommer inte', 'no', 'nej', 'not attending', 'kan inte', 'cannot attend'],
@@ -88,13 +97,13 @@ function generateAttendeeList(attendees) {
<div class="d-flex align-items-center mb-2">
<div class="rounded-circle d-flex justify-content-center align-items-center me-2"
style="width: 32px; height: 32px; background-color: ${getNodeColour(attendee.nodeId)}; color: white; font-size: 12px;">
${attendee.shortName.substring(0, 4)}
${escapeHtml(attendee.shortName.substring(0, 4))}
</div>
<div>
<div class="small">
<a href="https://map.sthlm-mesh.se/?node_id=${attendee.nodeId}"
target="_blank" class="text-decoration-none">
${attendee.longName}
${escapeHtml(attendee.longName)}
</a>
</div>
<div class="small text-muted">
+12 -3
View File
@@ -1,3 +1,12 @@
function escapeHtml(s) {
return String(s)
.replaceAll('&', '&amp;')
.replaceAll('<', '&lt;')
.replaceAll('>', '&gt;')
.replaceAll('"', '&quot;')
.replaceAll("'", '&#39;');
}
async function channelUtilizationGauges() {
try {
await fetchNodes();
@@ -171,9 +180,9 @@ function showTop10NodesLegend(channelName, top10Nodes) {
<span class="badge me-2" style="background-color: ${utilizationColor}; color: white; font-size: 0.7rem; min-width: 45px;">
${node.utilizationValue.toFixed(1)}%
</span>
<span class="me-2" style="display:inline-block;width:7ch;font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace; font-size: 0.85rem; text-align:right; white-space:nowrap; overflow:hidden; text-overflow:clip;" title="${shortName}">[${shortName}]</span>
<span class="text-truncate" style="font-size: 0.85rem;" title="${longName || shortName}">
${longName}
<span class="me-2" style="display:inline-block;width:7ch;font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace; font-size: 0.85rem; text-align:right; white-space:nowrap; overflow:hidden; text-overflow:clip;" title="${escapeHtml(shortName)}">[${escapeHtml(shortName)}]</span>
<span class="text-truncate" style="font-size: 0.85rem;" title="${escapeHtml(longName || shortName)}">
${escapeHtml(longName)}
</span>
</li>
`;