Add an Alt+click debug inspector, NPMap4-infobox style
NPMap4 has infoboxControl: a generic "click anything, show every raw property" debug view, kept separate from a dataset's own curated popup. Not portable code (Leaflet), but the concept is: Alt+click anywhere now opens a popup listing every rendered feature at that point via map.queryRenderedFeatures — base map OSM tags included, not just this app's own GPX/FIT/radar layers — with a raw key/value table per feature. No dedicated UI for it on purpose: a keyboard-modified click needs no button, toggle state, or cursor change of its own, and it's fine for it to coexist with a layer's own click handler firing on the same click (e.g. a GPX waypoint's normal popup) since this is a power-user/debugging affordance, not a replacement for those. Feature properties can come from an uploaded GPX/FIT file (untrusted input) via this app's own layers, so every value is escaped the same way gpx.js's popups already are.
This commit is contained in:
1 parent
d58580f4d9
commit
8fa3391c6b
4 files changed
+99
-1
No files matched your search
@@ -2,6 +2,7 @@ import {
|
||||
Map as MaplibreMap,
|
||||
NavigationControl,
|
||||
GeolocateControl,
|
||||
Popup,
|
||||
addProtocol,
|
||||
} from "/vendor/maplibre-gl/maplibre-gl.mjs";
|
||||
import { RadarControl } from "/js/radar.js";
|
||||
@@ -263,3 +264,40 @@ fetch("/api/offline-tiles")
|
||||
// is rather than guessing — this is the same-origin request itself
|
||||
// failing, not evidence offline tiles are actually unavailable.
|
||||
});
|
||||
|
||||
// Alt+click anywhere shows every rendered feature at that point — base map
|
||||
// (OSM tags via OpenFreeMap/protomaps), GPX/FIT layers, radar, all of it —
|
||||
// with its raw properties, inspired by NPMap4's infoboxControl (a generic
|
||||
// "show me everything here" debug view, kept separate from the curated
|
||||
// popups those same features already have via their own layer-specific
|
||||
// click handlers, e.g. gpx.js's waypoint popups — both can fire on the same
|
||||
// click, which is fine, this is a power-user/debugging affordance, not
|
||||
// something replacing the normal popups). No dedicated UI for this
|
||||
// deliberately — a keyboard-modified click needs no button, state, or
|
||||
// cursor change of its own.
|
||||
map.on("click", (event) => {
|
||||
if (!event.originalEvent.altKey) return;
|
||||
|
||||
const features = map.queryRenderedFeatures(event.point);
|
||||
if (features.length === 0) return;
|
||||
|
||||
const html = features
|
||||
.map((feature) => {
|
||||
const rows = Object.entries(feature.properties)
|
||||
.map(([key, value]) => `<tr><th>${escapeHtml(key)}</th><td>${escapeHtml(String(value))}</td></tr>`)
|
||||
.join("");
|
||||
return `<div class="debug-popup__feature"><strong>${escapeHtml(feature.layer.id)}</strong><table>${rows || "<tr><td>(no properties)</td></tr>"}</table></div>`;
|
||||
})
|
||||
.join("");
|
||||
|
||||
new Popup({ maxWidth: "320px", className: "debug-popup" }).setLngLat(event.lngLat).setHTML(html).addTo(map);
|
||||
});
|
||||
|
||||
// Feature properties can come straight from an uploaded GPX/FIT file (an
|
||||
// untrusted source) via this app's own layers, not just the base map, so
|
||||
// every value is escaped the same way gpx.js's popups already do.
|
||||
function escapeHtml(text) {
|
||||
const div = document.createElement("div");
|
||||
div.textContent = text;
|
||||
return div.innerHTML;
|
||||
}
|
||||
Reference in new issue
Block a user