UNPKG

@trailstash/ultra

Version:

A web based tool for making MapLibre GL maps with data from sources such as Overpass, GeoJSON, GPX, KML, TCX, etc

73 lines (64 loc) 1.74 kB
import DOMPurify from "dompurify"; import { Liquid } from "liquidjs"; import { h, t } from "../lib/dom.js"; import { normalizeCSS } from "../lib/normalize.js"; const engine = new Liquid(); const style = new CSSStyleSheet(); style.replaceSync(` a { text-decoration: none; } h1,h2,h3,h4,h5,h6 { margin: .5em 0; } `); const defaultTemplate = ` <h3>Properties</h3> {%- for prop in properties %} <code>{{ prop[0] }} = {{ prop[1] }}</code> <br> {%- endfor %} `; const defaultContextBuilder = ({ properties, geometry }) => { const context = { properties: structuredClone(properties) }; if (geometry.type === "Point") context.geometry = geometry; return context; }; export class MapPopup extends HTMLElement { constructor() { super(); this.template = defaultTemplate; this.contextBuilder = defaultContextBuilder; } connectedCallback() { const shadow = this.attachShadow({ mode: "open" }); shadow.adoptedStyleSheets.push(normalizeCSS); shadow.adoptedStyleSheets.push(style); const div = h("div"); div.style.maxHeight = "1000px"; div.style.overflowY = "auto"; let first = true; for (const f of Object.values(this.features)) { if (first) { first = false; } else { div.appendChild(h("hr")); } const html = engine.parseAndRenderSync( this.template, this.contextBuilder(f), ); div.appendChild( h( "div", {}, DOMPurify.sanitize(html, { ALLOWED_URI_REGEXP: /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|geo):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i, }), ), ); } shadow.appendChild(div); } }