leaflet-html 0.1.7 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. package/.github/workflows/npm-publish.yml +27 -27
  2. package/.prettierignore +2 -0
  3. package/.prettierrc +1 -0
  4. package/README.md +63 -36
  5. package/dist/leaflet-html.cjs +1 -1
  6. package/dist/leaflet-html.cjs.map +1 -1
  7. package/dist/leaflet-html.esm.js +1 -1
  8. package/dist/leaflet-html.esm.js.map +1 -1
  9. package/dist/leaflet-html.js +1 -1
  10. package/dist/leaflet-html.js.map +1 -1
  11. package/dist/leaflet-html.umd.js +1 -1
  12. package/dist/leaflet-html.umd.js.map +1 -1
  13. package/docs/content/_index.md +66 -63
  14. package/docs/content/articles/_index.md +5 -0
  15. package/docs/content/articles/basic.md +105 -0
  16. package/docs/content/articles/icons.md +35 -0
  17. package/docs/content/articles/style.md +14 -0
  18. package/docs/public/icons/leaf-green.png +0 -0
  19. package/docs/public/icons/leaf-orange.png +0 -0
  20. package/docs/public/icons/leaf-red.png +0 -0
  21. package/docs/public/icons/leaf-shadow.png +0 -0
  22. package/docs/static/icons/leaf-green.png +0 -0
  23. package/docs/static/icons/leaf-orange.png +0 -0
  24. package/docs/static/icons/leaf-red.png +0 -0
  25. package/docs/static/icons/leaf-shadow.png +0 -0
  26. package/docs/templates/article-page.html +8 -0
  27. package/docs/templates/article.html +12 -0
  28. package/docs/templates/base.html +59 -0
  29. package/docs/templates/index.html +5 -52
  30. package/example/geojson/index.html +42 -0
  31. package/example/index.html +58 -50
  32. package/example/overlays/index.html +34 -35
  33. package/package.json +12 -5
  34. package/src/events.js +3 -0
  35. package/src/index.js +27 -185
  36. package/src/l-base-layers.js +15 -0
  37. package/src/l-control-layers.js +34 -0
  38. package/src/l-geojson.js +22 -0
  39. package/src/l-icon.js +124 -0
  40. package/src/l-image-overlay.js +43 -0
  41. package/src/l-lat-lng-bounds.js +20 -0
  42. package/src/l-layer-group.js +39 -0
  43. package/src/l-map.js +33 -0
  44. package/src/l-marker.js +94 -0
  45. package/src/l-overlay-layers.js +15 -0
  46. package/src/l-popup.js +21 -0
  47. package/src/l-tile-layer.js +22 -0
  48. package/src/l-video-overlay.js +31 -0
  49. package/vite.config.js +7 -0
@@ -1 +1 @@
1
- {"version":3,"file":"leaflet-html.js","sources":["../src/index.js"],"sourcesContent":["// @ts-check\n\n// Helpers\nconst selector = (noun) => `[data-${noun}]`;\n\n/**\n * Parse L.tileLayer args from element attributes\n */\nconst parseTileLayer = (el) => {\n const { urlTemplate } = el.dataset;\n const {\n attribution = null,\n maxZoom = \"18\",\n minZoom = \"0\",\n subdomains = \"abc\",\n } = el.dataset;\n const options = { attribution, maxZoom, minZoom, subdomains };\n return [urlTemplate, options];\n};\n\n/**\n * Parse L.imageOverlay args from element attributes\n */\nconst parseImageOverlay = (el) => {\n let { url, bounds } = el.dataset;\n bounds = JSON.parse(bounds);\n const { opacity } = el.dataset;\n const options = { opacity: parseFloat(opacity) };\n return [url, bounds, options];\n};\n\n/**\n * Parse L.imageOverlay args from element attributes\n */\nconst parseVideoOverlay = (el) => {\n let { url, bounds } = el.dataset;\n url = JSON.parse(url);\n bounds = JSON.parse(bounds);\n const {\n opacity,\n errorOverlayUrl,\n autoplay = true,\n muted = true,\n playsInline = true,\n } = el.dataset;\n const options = {\n opacity: parseFloat(opacity),\n errorOverlayUrl,\n autoplay,\n muted,\n playsInline,\n };\n return [url, bounds, options];\n};\n\n/**\n * @param {HTMLElement} el\n */\nconst parseLatLngBounds = (el) => {\n let { bounds } = el.dataset;\n if (typeof bounds === \"undefined\") {\n throw Error(\"data-bounds not specified\")\n }\n return [JSON.parse(bounds)];\n}\n\nconst render = () => {\n // Render Leaflet API calls\n document.querySelectorAll(selector(\"leaflet-html\")).forEach((el) => {\n const { center, zoom } = el.dataset;\n const map = L.map(el).setView(JSON.parse(center), parseInt(zoom));\n\n // L.latLngBounds\n el.querySelectorAll(selector(\"lat-lng-bounds\")).forEach((el) => {\n const bounds = L.latLngBounds(...parseLatLngBounds(el))\n // TODO: encapsulate this design pattern\n const observer = new MutationObserver(function (mutations) {\n mutations.forEach((mutation) => {\n let [bounds] = parseLatLngBounds(mutation.target)\n map.flyToBounds(bounds); // TODO: Use HTML attrs for fly/fit bounds\n });\n });\n observer.observe(el, {\n attributes: true,\n attributeFilter: [\"data-bounds\"],\n });\n map.fitBounds(bounds)\n })\n\n // L.tileLayers\n el.querySelectorAll(selector(\"tile-layer\")).forEach((el) => {\n L.tileLayer(...parseTileLayer(el)).addTo(map);\n });\n\n el.querySelectorAll(selector(\"image-overlay\")).forEach((el) => {\n L.imageOverlay(...parseImageOverlay(el)).addTo(map);\n });\n\n el.querySelectorAll(selector(\"video-overlay\")).forEach((el) => {\n L.videoOverlay(...parseVideoOverlay(el)).addTo(map);\n });\n\n // L.control.layers\n el.querySelectorAll(selector(\"control-layers\")).forEach((el) => {\n const baseMaps = {};\n\n // L.tileLayers\n el.querySelectorAll(selector(\"tile-layer\")).forEach((el) => {\n const { name, show } = el.dataset;\n baseMaps[name] = L.tileLayer(...parseTileLayer(el));\n if (show != null) {\n baseMaps[name].addTo(map);\n }\n });\n\n const overlayMaps = {};\n // L.layerGroup\n el.querySelectorAll(selector(\"layer-group\")).forEach((el) => {\n const { name } = el.dataset;\n const layers = [];\n\n const observer = new MutationObserver(function (mutations) {\n const group = overlayMaps[name];\n\n mutations.forEach((mutation) => {\n mutation.addedNodes.forEach((node) => {\n const { latLng } = node.dataset; // MutationObserver needed\n const layer = L.marker(JSON.parse(latLng));\n group.addLayer(layer);\n map.addLayer(layer);\n });\n\n mutation.removedNodes.forEach((node) => {\n const { _leafletId } = node.dataset;\n const layer = group.getLayer(_leafletId);\n group.removeLayer(layer);\n\n map.removeLayer(layer);\n });\n });\n });\n observer.observe(el, { childList: true });\n\n // L.marker\n el.querySelectorAll(selector(\"marker\")).forEach((el) => {\n const { latLng } = el.dataset;\n const { opacity = \"1.0\" } = el.dataset;\n const options = { opacity: parseFloat(opacity) };\n const marker = L.marker(JSON.parse(latLng), options).addTo(map);\n el.dataset._leafletId = L.stamp(marker); // Save ID for later\n\n const observer = new MutationObserver(function (mutations) {\n mutations.forEach((mutation) => {\n const { latLng } = mutation.target.dataset;\n marker.setLatLng(JSON.parse(latLng));\n });\n });\n observer.observe(el, {\n attributes: true,\n attributeFilter: [\"data-lat-lng\"],\n });\n\n // marker.bindPopup\n el.querySelectorAll(selector(\"popup\")).forEach((el) => {\n const { content } = el.dataset;\n marker.bindPopup(content);\n const observer = new MutationObserver(function () {\n marker.getPopup().setContent(el.dataset.content);\n });\n observer.observe(el, {\n attributes: true,\n attributeFilter: [\"data-content\"],\n });\n });\n\n layers.push(marker);\n });\n\n overlayMaps[name] = L.layerGroup(layers);\n });\n\n L.control.layers(baseMaps, overlayMaps).addTo(map);\n });\n });\n};\n\nconst init = (() => {\n document.addEventListener(\"DOMContentLoaded\", render);\n})();\n\nexport default init;\n"],"names":["selector","noun","parseTileLayer","el","urlTemplate","dataset","attribution","maxZoom","minZoom","subdomains","parseLatLngBounds","bounds","Error","JSON","parse","init","document","addEventListener","render","querySelectorAll","forEach","center","zoom","map","L","setView","parseInt","latLngBounds","observer","MutationObserver","mutations","mutation","target","flyToBounds","observe","attributes","attributeFilter","fitBounds","tileLayer","addTo","imageOverlay","url","opacity","parseFloat","parseImageOverlay","videoOverlay","errorOverlayUrl","autoplay","muted","playsInline","parseVideoOverlay","baseMaps","name","show","overlayMaps","layers","group","addedNodes","node","latLng","layer","marker","addLayer","removedNodes","_leafletId","getLayer","removeLayer","childList","options","stamp","setLatLng","content","bindPopup","getPopup","setContent","push","layerGroup","control"],"mappings":"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"}
1
+ {"version":3,"file":"leaflet-html.js","sources":["../src/events.js","../src/l-base-layers.js","../src/l-control-layers.js","../src/l-layer-group.js","../src/l-map.js","../src/l-marker.js","../src/l-overlay-layers.js","../src/l-popup.js","../src/l-tile-layer.js","../src/l-lat-lng-bounds.js","../src/l-image-overlay.js","../src/l-video-overlay.js","../src/l-geojson.js","../src/l-icon.js","../src/index.js"],"sourcesContent":["export const mapAddTo = \"map:addTo\";\nexport const popupAdd = \"popup:add\";\nexport const layerRemove = \"layer:remove\";\n","import { mapAddTo } from \"./events.js\";\n\nclass LBaseLayers extends HTMLElement {\n constructor() {\n super();\n }\n\n connectedCallback() {\n this.addEventListener(mapAddTo, (ev) => {\n ev.detail[\"type\"] = \"base\";\n });\n }\n}\n\nexport default LBaseLayers;\n","import { mapAddTo } from \"./events.js\";\n\nclass LControlLayers extends HTMLElement {\n constructor() {\n super();\n }\n\n connectedCallback() {\n const base = {};\n const overlay = {};\n const control = L.control.layers(base, overlay);\n\n this.addEventListener(mapAddTo, (ev) => {\n const { type, name, layer } = ev.detail;\n if (type === \"overlay\") {\n control.addOverlay(layer, name);\n } else if (type === \"base\") {\n control.addBaseLayer(layer, name);\n }\n ev.preventDefault();\n });\n\n const event = new CustomEvent(mapAddTo, {\n cancelable: true,\n bubbles: true,\n detail: {\n layer: control,\n },\n });\n this.dispatchEvent(event);\n }\n}\n\nexport default LControlLayers;\n","import { mapAddTo } from \"./events.js\";\n\nclass LLayerGroup extends HTMLElement {\n constructor() {\n super();\n }\n\n connectedCallback() {\n const name = this.getAttribute(\"name\");\n const group = L.layerGroup();\n const event = new CustomEvent(mapAddTo, {\n cancelable: true,\n bubbles: true,\n detail: {\n layer: group,\n name,\n },\n });\n this.dispatchEvent(event);\n\n this.addEventListener(mapAddTo, (ev) => {\n ev.stopPropagation();\n group.addLayer(ev.detail.layer);\n });\n\n const observer = new MutationObserver(function (mutations) {\n mutations.forEach((mutation) => {\n mutation.removedNodes.forEach((node) => {\n const leafletId = node.getAttribute(\"leaflet-id\");\n const layer = group.getLayer(leafletId);\n group.removeLayer(layer);\n });\n });\n });\n observer.observe(this, { childList: true });\n }\n}\n\nexport default LLayerGroup;\n","// @ts-check\nimport { layerRemove, mapAddTo } from \"./events.js\";\n\nclass LMap extends HTMLElement {\n constructor() {\n super();\n\n this.map = null;\n this.addEventListener(\"map:bounds\", (ev) => {\n const { bounds, method } = ev.detail;\n this.map[method](bounds);\n });\n }\n\n connectedCallback() {\n this.map = L.map(this);\n const center = this.getAttribute(\"center\");\n const zoom = this.getAttribute(\"zoom\");\n if (center !== null && zoom !== null) {\n this.map.setView(JSON.parse(center), parseInt(zoom));\n }\n this.addEventListener(mapAddTo, (ev) => {\n const layer = ev.detail.layer;\n layer.addTo(this.map);\n });\n\n this.addEventListener(layerRemove, (ev) => {\n this.map.remove(ev.detail.layer);\n });\n }\n}\n\nexport default LMap;\n","// @vitest-environment happy-dom\nimport * as L from \"leaflet\";\nimport { mapAddTo, popupAdd } from \"./events.js\";\n\nclass LMarker extends HTMLElement {\n static observedAttributes = [\"lat-lng\", \"opacity\", \"icon\"];\n\n constructor() {\n super();\n this.layer = null;\n this.addEventListener(\"icon:add\", (ev) => {\n ev.stopPropagation();\n this.layer.setIcon(ev.detail.icon);\n })\n }\n\n connectedCallback() {\n const latLng = JSON.parse(this.getAttribute(\"lat-lng\"));\n const opacity = parseFloat(this.getAttribute(\"opacity\") || \"1.0\");\n this.layer = L.marker(latLng, { opacity });\n if (this.hasAttribute(\"icon\")) {\n const icon = L.icon(JSON.parse(this.getAttribute(\"icon\")));\n this.layer.setIcon(icon);\n }\n\n this.setAttribute(\"leaflet-id\", L.stamp(this.layer));\n\n this.addEventListener(popupAdd, (ev) => {\n const { content } = ev.detail;\n this.layer.bindPopup(content);\n });\n\n const event = new CustomEvent(mapAddTo, {\n cancelable: true,\n bubbles: true,\n detail: {\n layer: this.layer,\n },\n });\n this.dispatchEvent(event);\n }\n\n attributeChangedCallback(name, _oldValue, newValue) {\n if (this.layer !== null) {\n if (name === \"lat-lng\") {\n this.layer.setLatLng(JSON.parse(newValue));\n }\n if (name === \"opacity\") {\n this.layer.setOpacity(parseFloat(newValue));\n }\n if (name === \"icon\") {\n this.layer.setIcon(L.icon(JSON.parse(newValue)));\n }\n }\n }\n}\n\nif (import.meta.vitest) {\n const { it, expect, beforeAll } = import.meta.vitest;\n\n beforeAll(() => {\n customElements.define(\"l-marker\", LMarker);\n });\n\n it(\"default icon\", () => {\n const el = document.createElement(\"l-marker\");\n document.body.appendChild(el);\n let actual = el.layer.getIcon();\n let expected = new L.Icon.Default();\n expect(actual).toEqual(expected);\n });\n\n it(\"adds an icon\", () => {\n const el = document.createElement(\"l-marker\");\n // Set attribute before appendChild\n el.setAttribute(\"icon\", JSON.stringify({ iconUrl: \"foo.png\" }));\n document.body.appendChild(el);\n let actual = el.layer.getIcon();\n let expected = L.icon({ iconUrl: \"foo.png\" });\n expect(actual).toEqual(expected);\n });\n\n it(\"changes an icon\", () => {\n const el = document.createElement(\"l-marker\");\n // Set attribute after appendChild\n document.body.appendChild(el);\n el.setAttribute(\"icon\", JSON.stringify({ iconUrl: \"bar.png\" }));\n let actual = el.layer.getIcon();\n let expected = L.icon({ iconUrl: \"bar.png\" });\n expect(actual).toEqual(expected);\n });\n}\n\nexport default LMarker;\n","import { mapAddTo } from \"./events.js\";\n\nclass LOverlayLayers extends HTMLElement {\n constructor() {\n super();\n }\n\n connectedCallback() {\n this.addEventListener(mapAddTo, (ev) => {\n ev.detail[\"type\"] = \"overlay\";\n });\n }\n}\n\nexport default LOverlayLayers;\n","import { popupAdd } from \"./events.js\";\n\nclass LPopup extends HTMLElement {\n constructor() {\n super();\n }\n\n connectedCallback() {\n const content = this.getAttribute(\"content\");\n const event = new CustomEvent(popupAdd, {\n cancelable: true,\n bubbles: true,\n detail: {\n content,\n },\n });\n this.dispatchEvent(event);\n }\n}\n\nexport default LPopup;\n","import { mapAddTo } from \"./events.js\";\n\nclass LTileLayer extends HTMLElement {\n constructor() {\n super();\n }\n\n connectedCallback() {\n const name = this.getAttribute(\"name\");\n const urlTemplate = this.getAttribute(\"url-template\");\n const attribution = this.getAttribute(\"attribution\");\n const options = { attribution };\n const layer = L.tileLayer(urlTemplate, options);\n const event = new CustomEvent(mapAddTo, {\n detail: { name, layer },\n bubbles: true,\n });\n this.dispatchEvent(event);\n }\n}\n\nexport default LTileLayer;\n","class LLatLngBounds extends HTMLElement {\n static observedAttributes = [\"bounds\"];\n\n constructor() {\n super();\n }\n\n attributeChangedCallback(_name, _oldValue, newValue) {\n const event = new CustomEvent(\"map:bounds\", {\n bubbles: true,\n detail: {\n bounds: JSON.parse(newValue),\n method: this.getAttribute(\"method\") || \"fitBounds\",\n },\n });\n this.dispatchEvent(event);\n }\n}\n\nexport default LLatLngBounds;\n","import { mapAddTo } from \"./events.js\";\n\nclass LImageOverlay extends HTMLElement {\n static observedAttributes = [\"url\", \"bounds\", \"opacity\"];\n\n constructor() {\n super();\n this.layer = null;\n }\n\n connectedCallback() {\n const url = this.getAttribute(\"url\");\n const bounds = JSON.parse(this.getAttribute(\"bounds\"));\n const options = {\n opacity: parseFloat(this.getAttribute(\"opacity\") || \"1.0\"),\n alt: this.getAttribute(\"alt\") || \"\",\n };\n this.layer = L.imageOverlay(url, bounds, options);\n this.dispatchEvent(\n new CustomEvent(mapAddTo, {\n cancelable: true,\n bubbles: true,\n detail: {\n layer: this.layer,\n },\n }),\n );\n }\n\n attributeChangedCallback(name, _oldValue, newValue) {\n if (this.layer !== null) {\n if (name === \"url\") {\n this.layer.setUrl(newValue);\n } else if (name === \"bounds\") {\n this.layer.setBounds(JSON.parse(newValue));\n } else if (name === \"opacity\") {\n this.layer.setOpacity(parseFloat(newValue));\n }\n }\n }\n}\n\nexport default LImageOverlay;\n","import { mapAddTo } from \"./events.js\";\n\nclass LVideoOverlay extends HTMLElement {\n constructor() {\n super();\n }\n\n connectedCallback() {\n const url = JSON.parse(this.getAttribute(\"url\"));\n const bounds = JSON.parse(this.getAttribute(\"bounds\"));\n const options = {\n opacity: parseFloat(this.getAttribute(\"opacity\") || \"1.0\"),\n alt: this.getAttribute(\"alt\") || \"\",\n autoplay: true,\n muted: true,\n playsInline: true,\n };\n const layer = L.videoOverlay(url, bounds, options);\n this.dispatchEvent(\n new CustomEvent(mapAddTo, {\n cancelable: true,\n bubbles: true,\n detail: {\n layer,\n },\n }),\n );\n }\n}\n\nexport default LVideoOverlay;\n","import { mapAddTo } from \"./events.js\";\n\nclass LGeoJSON extends HTMLElement {\n constructor() {\n super();\n }\n\n connectedCallback() {\n const layer = L.geoJSON(JSON.parse(this.getAttribute(\"geojson\")));\n this.dispatchEvent(\n new CustomEvent(mapAddTo, {\n bubbles: true,\n cancelable: true,\n detail: {\n layer,\n },\n }),\n );\n }\n}\n\nexport default LGeoJSON;\n","// @vitest-environment happy-dom\nimport * as L from \"leaflet\";\n\nconst camelCase = (kebab) => kebab.replace(/-./g, (x) => x[1].toUpperCase());\n\nclass LIcon extends HTMLElement {\n constructor() {\n super();\n this.icon = null;\n }\n\n connectedCallback() {\n const options = {};\n\n // Strings\n let keys = [\n \"icon-url\",\n \"icon-retina-url\",\n \"shadow-url\",\n \"shadow-retina-url\",\n \"class-name\",\n ];\n keys.forEach((key) => {\n if (this.hasAttribute(key)) {\n options[camelCase(key)] = this.getAttribute(key);\n }\n });\n\n // Points\n let points = [\n \"icon-anchor\",\n \"icon-size\",\n \"shadow-anchor\",\n \"shadow-size\",\n \"tooltip-anchor\",\n \"popup-anchor\",\n ];\n points.forEach((key) => {\n if (this.hasAttribute(key)) {\n options[camelCase(key)] = JSON.parse(this.getAttribute(key));\n }\n });\n\n if (this.hasAttribute(\"cross-origin\")) {\n options.crossOrigin = this.getAttribute(\"cross-origin\") === \"true\";\n }\n this.icon = L.icon(options);\n\n const event = new CustomEvent(\"icon:add\", {\n cancelable: true,\n bubbles: true,\n detail: {\n icon: this.icon,\n },\n });\n this.dispatchEvent(event);\n }\n}\n\nif (import.meta.vitest) {\n const { it, expect, beforeAll } = import.meta.vitest;\n\n beforeAll(() => {\n customElements.define(\"l-icon\", LIcon);\n });\n\n it(\"default\", () => {\n const el = document.createElement(\"l-icon\");\n document.body.appendChild(el);\n\n let actual = el.icon;\n let expected = L.icon();\n expect(actual).toEqual(expected);\n });\n\n it(\"emits icon:add event\", async () => {\n const el = document.createElement(\"l-icon\");\n let promise = new Promise((resolve) => {\n el.addEventListener(\"icon:add\", (ev) => {\n resolve(ev.detail.icon);\n });\n });\n document.body.appendChild(el);\n let actual = await promise;\n let expected = L.icon();\n expect(actual).toEqual(expected);\n });\n\n it(\"options\", () => {\n const el = document.createElement(\"l-icon\");\n el.setAttribute(\"icon-url\", \"url.png\");\n el.setAttribute(\"icon-retina-url\", \"retina.png\");\n el.setAttribute(\"icon-size\", \"[0, 0]\");\n el.setAttribute(\"icon-anchor\", \"[0, 0]\");\n el.setAttribute(\"popup-anchor\", \"[0, 0]\");\n el.setAttribute(\"tooltip-anchor\", \"[0, 0]\");\n el.setAttribute(\"shadow-url\", \"urlShadow.png\");\n el.setAttribute(\"shadow-retina-url\", \"retinaShadow.png\");\n el.setAttribute(\"shadow-size\", \"[0, 0]\");\n el.setAttribute(\"shadow-anchor\", \"[0, 0]\");\n el.setAttribute(\"class-name\", \"foo\");\n el.setAttribute(\"cross-origin\", \"true\");\n document.body.appendChild(el);\n\n let actual = el.icon;\n let expected = L.icon({\n iconUrl: \"url.png\",\n iconRetinaUrl: \"retina.png\",\n iconSize: [0, 0],\n iconAnchor: [0, 0],\n popupAnchor: [0, 0],\n tooltipAnchor: [0, 0],\n shadowUrl: \"urlShadow.png\",\n shadowRetinaUrl: \"retinaShadow.png\",\n shadowSize: [0, 0],\n shadowAnchor: [0, 0],\n className: \"foo\",\n crossOrigin: true,\n });\n expect(actual).toEqual(expected);\n });\n}\n\nexport default LIcon;\n","// @ts-check\nimport LBaseLayers from \"./l-base-layers.js\";\nimport LControlLayers from \"./l-control-layers.js\";\nimport LLayerGroup from \"./l-layer-group.js\";\nimport LMap from \"./l-map.js\";\nimport LMarker from \"./l-marker.js\";\nimport LOverlayLayers from \"./l-overlay-layers.js\";\nimport LPopup from \"./l-popup.js\";\nimport LTileLayer from \"./l-tile-layer.js\";\nimport LLatLngBounds from \"./l-lat-lng-bounds.js\";\nimport LImageOverlay from \"./l-image-overlay.js\";\nimport LVideoOverlay from \"./l-video-overlay.js\";\nimport LGeoJSON from \"./l-geojson.js\";\nimport LIcon from \"./l-icon.js\";\n\nconst init = (() => {\n // Custom elements (order of definition is important)\n customElements.define(\"l-map\", LMap);\n customElements.define(\"l-control-layers\", LControlLayers);\n customElements.define(\"l-base-layers\", LBaseLayers);\n customElements.define(\"l-overlay-layers\", LOverlayLayers);\n customElements.define(\"l-layer-group\", LLayerGroup);\n customElements.define(\"l-tile-layer\", LTileLayer);\n customElements.define(\"l-marker\", LMarker);\n customElements.define(\"l-popup\", LPopup);\n customElements.define(\"l-lat-lng-bounds\", LLatLngBounds);\n customElements.define(\"l-image-overlay\", LImageOverlay);\n customElements.define(\"l-video-overlay\", LVideoOverlay);\n customElements.define(\"l-geojson\", LGeoJSON);\n customElements.define(\"l-icon\", LIcon);\n})();\n\nexport default init;\n"],"names":["mapAddTo","popupAdd","LBaseLayers","HTMLElement","constructor","super","connectedCallback","this","addEventListener","ev","detail","LControlLayers","control","L","layers","type","name","layer","addOverlay","addBaseLayer","preventDefault","event","CustomEvent","cancelable","bubbles","dispatchEvent","LLayerGroup","getAttribute","group","layerGroup","stopPropagation","addLayer","MutationObserver","mutations","forEach","mutation","removedNodes","node","leafletId","getLayer","removeLayer","observe","childList","LMap","map","bounds","method","center","zoom","setView","JSON","parse","parseInt","addTo","remove","LMarker","setIcon","icon","latLng","opacity","parseFloat","marker","hasAttribute","setAttribute","stamp","content","bindPopup","attributeChangedCallback","_oldValue","newValue","setLatLng","setOpacity","observedAttributes","vitest","it","expect","beforeAll","customElements","define","el","document","createElement","body","appendChild","actual","getIcon","expected","Icon","Default","toEqual","stringify","iconUrl","LOverlayLayers","LPopup","LTileLayer","urlTemplate","attribution","tileLayer","LLatLngBounds","_name","LImageOverlay","url","options","alt","imageOverlay","setUrl","setBounds","LVideoOverlay","autoplay","muted","playsInline","videoOverlay","LGeoJSON","geoJSON","camelCase","kebab","replace","x","toUpperCase","LIcon","key","crossOrigin","async","promise","Promise","resolve","iconRetinaUrl","iconSize","iconAnchor","popupAnchor","tooltipAnchor","shadowUrl","shadowRetinaUrl","shadowSize","shadowAnchor","className","init"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e||self).leafletHtml=t()}(this,function(){var e=function(e){return"[data-"+e+"]"},t=function(e){var t=e.dataset,a=t.attribution,o=t.maxZoom,r=t.minZoom,n=t.subdomains;return[e.dataset.urlTemplate,{attribution:void 0===a?null:a,maxZoom:void 0===o?"18":o,minZoom:void 0===r?"0":r,subdomains:void 0===n?"abc":n}]},a=function(e){var t=e.dataset.bounds;if(void 0===t)throw Error("data-bounds not specified");return[JSON.parse(t)]};document.addEventListener("DOMContentLoaded",function(){document.querySelectorAll(e("leaflet-html")).forEach(function(o){var r=o.dataset,n=r.center,l=r.zoom,i=L.map(o).setView(JSON.parse(n),parseInt(l));o.querySelectorAll(e("lat-lng-bounds")).forEach(function(e){var t,o=(t=L).latLngBounds.apply(t,a(e));new MutationObserver(function(e){e.forEach(function(e){var t=a(e.target);i.flyToBounds(t[0])})}).observe(e,{attributes:!0,attributeFilter:["data-bounds"]}),i.fitBounds(o)}),o.querySelectorAll(e("tile-layer")).forEach(function(e){var a;(a=L).tileLayer.apply(a,t(e)).addTo(i)}),o.querySelectorAll(e("image-overlay")).forEach(function(e){var t;(t=L).imageOverlay.apply(t,function(e){var t=e.dataset,a=t.bounds;return[t.url,a=JSON.parse(a),{opacity:parseFloat(e.dataset.opacity)}]}(e)).addTo(i)}),o.querySelectorAll(e("video-overlay")).forEach(function(e){var t;(t=L).videoOverlay.apply(t,function(e){var t=e.dataset,a=t.url,o=t.bounds;a=JSON.parse(a),o=JSON.parse(o);var r=e.dataset,n=r.errorOverlayUrl,l=r.autoplay,i=void 0===l||l,d=r.muted,u=void 0===d||d,s=r.playsInline,c=void 0===s||s;return[a,o,{opacity:parseFloat(r.opacity),errorOverlayUrl:n,autoplay:i,muted:u,playsInline:c}]}(e)).addTo(i)}),o.querySelectorAll(e("control-layers")).forEach(function(a){var o={};a.querySelectorAll(e("tile-layer")).forEach(function(e){var a,r=e.dataset,n=r.name,l=r.show;o[n]=(a=L).tileLayer.apply(a,t(e)),null!=l&&o[n].addTo(i)});var r={};a.querySelectorAll(e("layer-group")).forEach(function(t){var a=t.dataset.name,o=[];new MutationObserver(function(e){var t=r[a];e.forEach(function(e){e.addedNodes.forEach(function(e){var a=L.marker(JSON.parse(e.dataset.latLng));t.addLayer(a),i.addLayer(a)}),e.removedNodes.forEach(function(e){var a=t.getLayer(e.dataset._leafletId);t.removeLayer(a),i.removeLayer(a)})})}).observe(t,{childList:!0}),t.querySelectorAll(e("marker")).forEach(function(t){var a=t.dataset.latLng,r=t.dataset.opacity,n={opacity:parseFloat(void 0===r?"1.0":r)},l=L.marker(JSON.parse(a),n).addTo(i);t.dataset._leafletId=L.stamp(l),new MutationObserver(function(e){e.forEach(function(e){l.setLatLng(JSON.parse(e.target.dataset.latLng))})}).observe(t,{attributes:!0,attributeFilter:["data-lat-lng"]}),t.querySelectorAll(e("popup")).forEach(function(e){l.bindPopup(e.dataset.content),new MutationObserver(function(){l.getPopup().setContent(e.dataset.content)}).observe(e,{attributes:!0,attributeFilter:["data-content"]})}),o.push(l)}),r[a]=L.layerGroup(o)}),L.control.layers(o,r).addTo(i)})})})});
1
+ !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(require("leaflet")):"function"==typeof define&&define.amd?define(["leaflet"],e):(t||self).leafletHtml=e(t.leaflet)}(this,function(t){function e(t){if(t&&t.__esModule)return t;var e=Object.create(null);return t&&Object.keys(t).forEach(function(n){if("default"!==n){var r=Object.getOwnPropertyDescriptor(t,n);Object.defineProperty(e,n,r.get?r:{enumerable:!0,get:function(){return t[n]}})}}),e.default=t,e}var n=/*#__PURE__*/e(t);function r(){try{var t=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch(t){}return(r=function(){return!!t})()}function i(t,e){t.prototype=Object.create(e.prototype),t.prototype.constructor=t,o(t,e)}function a(t){return a=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(t){return t.__proto__||Object.getPrototypeOf(t)},a(t)}function o(t,e){return o=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(t,e){return t.__proto__=e,t},o(t,e)}function l(t){var e="function"==typeof Map?new Map:void 0;return l=function(t){if(null===t||!function(t){try{return-1!==Function.toString.call(t).indexOf("[native code]")}catch(e){return"function"==typeof t}}(t))return t;if("function"!=typeof t)throw new TypeError("Super expression must either be null or a function");if(void 0!==e){if(e.has(t))return e.get(t);e.set(t,n)}function n(){return function(t,e,n){if(r())return Reflect.construct.apply(null,arguments);var i=[null];i.push.apply(i,e);var a=new(t.bind.apply(t,i));return n&&o(a,n.prototype),a}(t,arguments,a(this).constructor)}return n.prototype=Object.create(t.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),o(n,t)},l(t)}var u="map:addTo",c="popup:add",s=/*#__PURE__*/function(t){function e(){return t.call(this)||this}return i(e,t),e.prototype.connectedCallback=function(){this.addEventListener(u,function(t){t.detail.type="base"})},e}(/*#__PURE__*/l(HTMLElement)),p=/*#__PURE__*/function(t){function e(){return t.call(this)||this}return i(e,t),e.prototype.connectedCallback=function(){var t=L.control.layers({},{});this.addEventListener(u,function(e){var n=e.detail,r=n.type,i=n.name,a=n.layer;"overlay"===r?t.addOverlay(a,i):"base"===r&&t.addBaseLayer(a,i),e.preventDefault()});var e=new CustomEvent(u,{cancelable:!0,bubbles:!0,detail:{layer:t}});this.dispatchEvent(e)},e}(/*#__PURE__*/l(HTMLElement)),d=/*#__PURE__*/function(t){function e(){return t.call(this)||this}return i(e,t),e.prototype.connectedCallback=function(){var t=this.getAttribute("name"),e=L.layerGroup(),n=new CustomEvent(u,{cancelable:!0,bubbles:!0,detail:{layer:e,name:t}});this.dispatchEvent(n),this.addEventListener(u,function(t){t.stopPropagation(),e.addLayer(t.detail.layer)}),new MutationObserver(function(t){t.forEach(function(t){t.removedNodes.forEach(function(t){var n=t.getAttribute("leaflet-id"),r=e.getLayer(n);e.removeLayer(r)})})}).observe(this,{childList:!0})},e}(/*#__PURE__*/l(HTMLElement)),f=/*#__PURE__*/function(t){function e(){var e;return(e=t.call(this)||this).map=null,e.addEventListener("map:bounds",function(t){var n=t.detail;e.map[n.method](n.bounds)}),e}return i(e,t),e.prototype.connectedCallback=function(){var t=this;this.map=L.map(this);var e=this.getAttribute("center"),n=this.getAttribute("zoom");null!==e&&null!==n&&this.map.setView(JSON.parse(e),parseInt(n)),this.addEventListener(u,function(e){e.detail.layer.addTo(t.map)}),this.addEventListener("layer:remove",function(e){t.map.remove(e.detail.layer)})},e}(/*#__PURE__*/l(HTMLElement)),h=/*#__PURE__*/function(t){function e(){var e;return(e=t.call(this)||this).layer=null,e.addEventListener("icon:add",function(t){t.stopPropagation(),e.layer.setIcon(t.detail.icon)}),e}i(e,t);var r=e.prototype;return r.connectedCallback=function(){var t=this,e=JSON.parse(this.getAttribute("lat-lng")),r=parseFloat(this.getAttribute("opacity")||"1.0");if(this.layer=n.marker(e,{opacity:r}),this.hasAttribute("icon")){var i=n.icon(JSON.parse(this.getAttribute("icon")));this.layer.setIcon(i)}this.setAttribute("leaflet-id",n.stamp(this.layer)),this.addEventListener(c,function(e){t.layer.bindPopup(e.detail.content)});var a=new CustomEvent(u,{cancelable:!0,bubbles:!0,detail:{layer:this.layer}});this.dispatchEvent(a)},r.attributeChangedCallback=function(t,e,r){null!==this.layer&&("lat-lng"===t&&this.layer.setLatLng(JSON.parse(r)),"opacity"===t&&this.layer.setOpacity(parseFloat(r)),"icon"===t&&this.layer.setIcon(n.icon(JSON.parse(r))))},e}(/*#__PURE__*/l(HTMLElement));h.observedAttributes=["lat-lng","opacity","icon"];var b=/*#__PURE__*/function(t){function e(){return t.call(this)||this}return i(e,t),e.prototype.connectedCallback=function(){this.addEventListener(u,function(t){t.detail.type="overlay"})},e}(/*#__PURE__*/l(HTMLElement)),y=/*#__PURE__*/function(t){function e(){return t.call(this)||this}return i(e,t),e.prototype.connectedCallback=function(){var t=this.getAttribute("content"),e=new CustomEvent(c,{cancelable:!0,bubbles:!0,detail:{content:t}});this.dispatchEvent(e)},e}(/*#__PURE__*/l(HTMLElement)),v=/*#__PURE__*/function(t){function e(){return t.call(this)||this}return i(e,t),e.prototype.connectedCallback=function(){var t=this.getAttribute("name"),e=this.getAttribute("url-template"),n=this.getAttribute("attribution"),r=L.tileLayer(e,{attribution:n}),i=new CustomEvent(u,{detail:{name:t,layer:r},bubbles:!0});this.dispatchEvent(i)},e}(/*#__PURE__*/l(HTMLElement)),m=/*#__PURE__*/function(t){function e(){return t.call(this)||this}return i(e,t),e.prototype.attributeChangedCallback=function(t,e,n){var r=new CustomEvent("map:bounds",{bubbles:!0,detail:{bounds:JSON.parse(n),method:this.getAttribute("method")||"fitBounds"}});this.dispatchEvent(r)},e}(/*#__PURE__*/l(HTMLElement));m.observedAttributes=["bounds"];var E=/*#__PURE__*/function(t){function e(){var e;return(e=t.call(this)||this).layer=null,e}i(e,t);var n=e.prototype;return n.connectedCallback=function(){var t=this.getAttribute("url"),e=JSON.parse(this.getAttribute("bounds")),n={opacity:parseFloat(this.getAttribute("opacity")||"1.0"),alt:this.getAttribute("alt")||""};this.layer=L.imageOverlay(t,e,n),this.dispatchEvent(new CustomEvent(u,{cancelable:!0,bubbles:!0,detail:{layer:this.layer}}))},n.attributeChangedCallback=function(t,e,n){null!==this.layer&&("url"===t?this.layer.setUrl(n):"bounds"===t?this.layer.setBounds(JSON.parse(n)):"opacity"===t&&this.layer.setOpacity(parseFloat(n)))},e}(/*#__PURE__*/l(HTMLElement));E.observedAttributes=["url","bounds","opacity"];var g=/*#__PURE__*/function(t){function e(){return t.call(this)||this}return i(e,t),e.prototype.connectedCallback=function(){var t=JSON.parse(this.getAttribute("url")),e=JSON.parse(this.getAttribute("bounds")),n={opacity:parseFloat(this.getAttribute("opacity")||"1.0"),alt:this.getAttribute("alt")||"",autoplay:!0,muted:!0,playsInline:!0},r=L.videoOverlay(t,e,n);this.dispatchEvent(new CustomEvent(u,{cancelable:!0,bubbles:!0,detail:{layer:r}}))},e}(/*#__PURE__*/l(HTMLElement)),O=/*#__PURE__*/function(t){function e(){return t.call(this)||this}return i(e,t),e.prototype.connectedCallback=function(){var t=L.geoJSON(JSON.parse(this.getAttribute("geojson")));this.dispatchEvent(new CustomEvent(u,{bubbles:!0,cancelable:!0,detail:{layer:t}}))},e}(/*#__PURE__*/l(HTMLElement)),A=function(t){return t.replace(/-./g,function(t){return t[1].toUpperCase()})},C=/*#__PURE__*/function(t){function e(){var e;return(e=t.call(this)||this).icon=null,e}return i(e,t),e.prototype.connectedCallback=function(){var t=this,e={};["icon-url","icon-retina-url","shadow-url","shadow-retina-url","class-name"].forEach(function(n){t.hasAttribute(n)&&(e[A(n)]=t.getAttribute(n))}),["icon-anchor","icon-size","shadow-anchor","shadow-size","tooltip-anchor","popup-anchor"].forEach(function(n){t.hasAttribute(n)&&(e[A(n)]=JSON.parse(t.getAttribute(n)))}),this.hasAttribute("cross-origin")&&(e.crossOrigin="true"===this.getAttribute("cross-origin")),this.icon=n.icon(e);var r=new CustomEvent("icon:add",{cancelable:!0,bubbles:!0,detail:{icon:this.icon}});this.dispatchEvent(r)},e}(/*#__PURE__*/l(HTMLElement));return customElements.define("l-map",f),customElements.define("l-control-layers",p),customElements.define("l-base-layers",s),customElements.define("l-overlay-layers",b),customElements.define("l-layer-group",d),customElements.define("l-tile-layer",v),customElements.define("l-marker",h),customElements.define("l-popup",y),customElements.define("l-lat-lng-bounds",m),customElements.define("l-image-overlay",E),customElements.define("l-video-overlay",g),customElements.define("l-geojson",O),void customElements.define("l-icon",C)});
2
2
  //# sourceMappingURL=leaflet-html.umd.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"leaflet-html.umd.js","sources":["../src/index.js"],"sourcesContent":["// @ts-check\n\n// Helpers\nconst selector = (noun) => `[data-${noun}]`;\n\n/**\n * Parse L.tileLayer args from element attributes\n */\nconst parseTileLayer = (el) => {\n const { urlTemplate } = el.dataset;\n const {\n attribution = null,\n maxZoom = \"18\",\n minZoom = \"0\",\n subdomains = \"abc\",\n } = el.dataset;\n const options = { attribution, maxZoom, minZoom, subdomains };\n return [urlTemplate, options];\n};\n\n/**\n * Parse L.imageOverlay args from element attributes\n */\nconst parseImageOverlay = (el) => {\n let { url, bounds } = el.dataset;\n bounds = JSON.parse(bounds);\n const { opacity } = el.dataset;\n const options = { opacity: parseFloat(opacity) };\n return [url, bounds, options];\n};\n\n/**\n * Parse L.imageOverlay args from element attributes\n */\nconst parseVideoOverlay = (el) => {\n let { url, bounds } = el.dataset;\n url = JSON.parse(url);\n bounds = JSON.parse(bounds);\n const {\n opacity,\n errorOverlayUrl,\n autoplay = true,\n muted = true,\n playsInline = true,\n } = el.dataset;\n const options = {\n opacity: parseFloat(opacity),\n errorOverlayUrl,\n autoplay,\n muted,\n playsInline,\n };\n return [url, bounds, options];\n};\n\n/**\n * @param {HTMLElement} el\n */\nconst parseLatLngBounds = (el) => {\n let { bounds } = el.dataset;\n if (typeof bounds === \"undefined\") {\n throw Error(\"data-bounds not specified\")\n }\n return [JSON.parse(bounds)];\n}\n\nconst render = () => {\n // Render Leaflet API calls\n document.querySelectorAll(selector(\"leaflet-html\")).forEach((el) => {\n const { center, zoom } = el.dataset;\n const map = L.map(el).setView(JSON.parse(center), parseInt(zoom));\n\n // L.latLngBounds\n el.querySelectorAll(selector(\"lat-lng-bounds\")).forEach((el) => {\n const bounds = L.latLngBounds(...parseLatLngBounds(el))\n // TODO: encapsulate this design pattern\n const observer = new MutationObserver(function (mutations) {\n mutations.forEach((mutation) => {\n let [bounds] = parseLatLngBounds(mutation.target)\n map.flyToBounds(bounds); // TODO: Use HTML attrs for fly/fit bounds\n });\n });\n observer.observe(el, {\n attributes: true,\n attributeFilter: [\"data-bounds\"],\n });\n map.fitBounds(bounds)\n })\n\n // L.tileLayers\n el.querySelectorAll(selector(\"tile-layer\")).forEach((el) => {\n L.tileLayer(...parseTileLayer(el)).addTo(map);\n });\n\n el.querySelectorAll(selector(\"image-overlay\")).forEach((el) => {\n L.imageOverlay(...parseImageOverlay(el)).addTo(map);\n });\n\n el.querySelectorAll(selector(\"video-overlay\")).forEach((el) => {\n L.videoOverlay(...parseVideoOverlay(el)).addTo(map);\n });\n\n // L.control.layers\n el.querySelectorAll(selector(\"control-layers\")).forEach((el) => {\n const baseMaps = {};\n\n // L.tileLayers\n el.querySelectorAll(selector(\"tile-layer\")).forEach((el) => {\n const { name, show } = el.dataset;\n baseMaps[name] = L.tileLayer(...parseTileLayer(el));\n if (show != null) {\n baseMaps[name].addTo(map);\n }\n });\n\n const overlayMaps = {};\n // L.layerGroup\n el.querySelectorAll(selector(\"layer-group\")).forEach((el) => {\n const { name } = el.dataset;\n const layers = [];\n\n const observer = new MutationObserver(function (mutations) {\n const group = overlayMaps[name];\n\n mutations.forEach((mutation) => {\n mutation.addedNodes.forEach((node) => {\n const { latLng } = node.dataset; // MutationObserver needed\n const layer = L.marker(JSON.parse(latLng));\n group.addLayer(layer);\n map.addLayer(layer);\n });\n\n mutation.removedNodes.forEach((node) => {\n const { _leafletId } = node.dataset;\n const layer = group.getLayer(_leafletId);\n group.removeLayer(layer);\n\n map.removeLayer(layer);\n });\n });\n });\n observer.observe(el, { childList: true });\n\n // L.marker\n el.querySelectorAll(selector(\"marker\")).forEach((el) => {\n const { latLng } = el.dataset;\n const { opacity = \"1.0\" } = el.dataset;\n const options = { opacity: parseFloat(opacity) };\n const marker = L.marker(JSON.parse(latLng), options).addTo(map);\n el.dataset._leafletId = L.stamp(marker); // Save ID for later\n\n const observer = new MutationObserver(function (mutations) {\n mutations.forEach((mutation) => {\n const { latLng } = mutation.target.dataset;\n marker.setLatLng(JSON.parse(latLng));\n });\n });\n observer.observe(el, {\n attributes: true,\n attributeFilter: [\"data-lat-lng\"],\n });\n\n // marker.bindPopup\n el.querySelectorAll(selector(\"popup\")).forEach((el) => {\n const { content } = el.dataset;\n marker.bindPopup(content);\n const observer = new MutationObserver(function () {\n marker.getPopup().setContent(el.dataset.content);\n });\n observer.observe(el, {\n attributes: true,\n attributeFilter: [\"data-content\"],\n });\n });\n\n layers.push(marker);\n });\n\n overlayMaps[name] = L.layerGroup(layers);\n });\n\n L.control.layers(baseMaps, overlayMaps).addTo(map);\n });\n });\n};\n\nconst init = (() => {\n document.addEventListener(\"DOMContentLoaded\", render);\n})();\n\nexport default init;\n"],"names":["selector","noun","parseTileLayer","el","_el$dataset","dataset","_el$dataset$attributi","attribution","_el$dataset$maxZoom","maxZoom","_el$dataset$minZoom","minZoom","_el$dataset$subdomain","subdomains","urlTemplate","parseLatLngBounds","bounds","Error","JSON","parse","document","addEventListener","querySelectorAll","forEach","_el$dataset5","center","zoom","map","L","setView","parseInt","_L","latLngBounds","apply","MutationObserver","mutations","mutation","_parseLatLngBounds","target","flyToBounds","observe","attributes","attributeFilter","fitBounds","_L2","tileLayer","addTo","_L3","imageOverlay","_el$dataset2","url","opacity","parseFloat","parseImageOverlay","_L4","videoOverlay","_el$dataset3","_el$dataset4","errorOverlayUrl","_el$dataset4$autoplay","autoplay","_el$dataset4$muted","muted","_el$dataset4$playsInl","playsInline","parseVideoOverlay","baseMaps","_L5","_el$dataset6","name","show","overlayMaps","layers","group","addedNodes","node","layer","marker","latLng","addLayer","removedNodes","getLayer","_leafletId","removeLayer","childList","_el$dataset$opacity","options","stamp","setLatLng","bindPopup","content","getPopup","setContent","push","layerGroup","control"],"mappings":"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"}
1
+ {"version":3,"file":"leaflet-html.umd.js","sources":["../src/events.js","../src/l-base-layers.js","../src/l-control-layers.js","../src/l-layer-group.js","../src/l-map.js","../src/l-marker.js","../src/l-overlay-layers.js","../src/l-popup.js","../src/l-tile-layer.js","../src/l-lat-lng-bounds.js","../src/l-image-overlay.js","../src/l-video-overlay.js","../src/l-geojson.js","../src/l-icon.js","../src/index.js"],"sourcesContent":["export const mapAddTo = \"map:addTo\";\nexport const popupAdd = \"popup:add\";\nexport const layerRemove = \"layer:remove\";\n","import { mapAddTo } from \"./events.js\";\n\nclass LBaseLayers extends HTMLElement {\n constructor() {\n super();\n }\n\n connectedCallback() {\n this.addEventListener(mapAddTo, (ev) => {\n ev.detail[\"type\"] = \"base\";\n });\n }\n}\n\nexport default LBaseLayers;\n","import { mapAddTo } from \"./events.js\";\n\nclass LControlLayers extends HTMLElement {\n constructor() {\n super();\n }\n\n connectedCallback() {\n const base = {};\n const overlay = {};\n const control = L.control.layers(base, overlay);\n\n this.addEventListener(mapAddTo, (ev) => {\n const { type, name, layer } = ev.detail;\n if (type === \"overlay\") {\n control.addOverlay(layer, name);\n } else if (type === \"base\") {\n control.addBaseLayer(layer, name);\n }\n ev.preventDefault();\n });\n\n const event = new CustomEvent(mapAddTo, {\n cancelable: true,\n bubbles: true,\n detail: {\n layer: control,\n },\n });\n this.dispatchEvent(event);\n }\n}\n\nexport default LControlLayers;\n","import { mapAddTo } from \"./events.js\";\n\nclass LLayerGroup extends HTMLElement {\n constructor() {\n super();\n }\n\n connectedCallback() {\n const name = this.getAttribute(\"name\");\n const group = L.layerGroup();\n const event = new CustomEvent(mapAddTo, {\n cancelable: true,\n bubbles: true,\n detail: {\n layer: group,\n name,\n },\n });\n this.dispatchEvent(event);\n\n this.addEventListener(mapAddTo, (ev) => {\n ev.stopPropagation();\n group.addLayer(ev.detail.layer);\n });\n\n const observer = new MutationObserver(function (mutations) {\n mutations.forEach((mutation) => {\n mutation.removedNodes.forEach((node) => {\n const leafletId = node.getAttribute(\"leaflet-id\");\n const layer = group.getLayer(leafletId);\n group.removeLayer(layer);\n });\n });\n });\n observer.observe(this, { childList: true });\n }\n}\n\nexport default LLayerGroup;\n","// @ts-check\nimport { layerRemove, mapAddTo } from \"./events.js\";\n\nclass LMap extends HTMLElement {\n constructor() {\n super();\n\n this.map = null;\n this.addEventListener(\"map:bounds\", (ev) => {\n const { bounds, method } = ev.detail;\n this.map[method](bounds);\n });\n }\n\n connectedCallback() {\n this.map = L.map(this);\n const center = this.getAttribute(\"center\");\n const zoom = this.getAttribute(\"zoom\");\n if (center !== null && zoom !== null) {\n this.map.setView(JSON.parse(center), parseInt(zoom));\n }\n this.addEventListener(mapAddTo, (ev) => {\n const layer = ev.detail.layer;\n layer.addTo(this.map);\n });\n\n this.addEventListener(layerRemove, (ev) => {\n this.map.remove(ev.detail.layer);\n });\n }\n}\n\nexport default LMap;\n","// @vitest-environment happy-dom\nimport * as L from \"leaflet\";\nimport { mapAddTo, popupAdd } from \"./events.js\";\n\nclass LMarker extends HTMLElement {\n static observedAttributes = [\"lat-lng\", \"opacity\", \"icon\"];\n\n constructor() {\n super();\n this.layer = null;\n this.addEventListener(\"icon:add\", (ev) => {\n ev.stopPropagation();\n this.layer.setIcon(ev.detail.icon);\n })\n }\n\n connectedCallback() {\n const latLng = JSON.parse(this.getAttribute(\"lat-lng\"));\n const opacity = parseFloat(this.getAttribute(\"opacity\") || \"1.0\");\n this.layer = L.marker(latLng, { opacity });\n if (this.hasAttribute(\"icon\")) {\n const icon = L.icon(JSON.parse(this.getAttribute(\"icon\")));\n this.layer.setIcon(icon);\n }\n\n this.setAttribute(\"leaflet-id\", L.stamp(this.layer));\n\n this.addEventListener(popupAdd, (ev) => {\n const { content } = ev.detail;\n this.layer.bindPopup(content);\n });\n\n const event = new CustomEvent(mapAddTo, {\n cancelable: true,\n bubbles: true,\n detail: {\n layer: this.layer,\n },\n });\n this.dispatchEvent(event);\n }\n\n attributeChangedCallback(name, _oldValue, newValue) {\n if (this.layer !== null) {\n if (name === \"lat-lng\") {\n this.layer.setLatLng(JSON.parse(newValue));\n }\n if (name === \"opacity\") {\n this.layer.setOpacity(parseFloat(newValue));\n }\n if (name === \"icon\") {\n this.layer.setIcon(L.icon(JSON.parse(newValue)));\n }\n }\n }\n}\n\nif (import.meta.vitest) {\n const { it, expect, beforeAll } = import.meta.vitest;\n\n beforeAll(() => {\n customElements.define(\"l-marker\", LMarker);\n });\n\n it(\"default icon\", () => {\n const el = document.createElement(\"l-marker\");\n document.body.appendChild(el);\n let actual = el.layer.getIcon();\n let expected = new L.Icon.Default();\n expect(actual).toEqual(expected);\n });\n\n it(\"adds an icon\", () => {\n const el = document.createElement(\"l-marker\");\n // Set attribute before appendChild\n el.setAttribute(\"icon\", JSON.stringify({ iconUrl: \"foo.png\" }));\n document.body.appendChild(el);\n let actual = el.layer.getIcon();\n let expected = L.icon({ iconUrl: \"foo.png\" });\n expect(actual).toEqual(expected);\n });\n\n it(\"changes an icon\", () => {\n const el = document.createElement(\"l-marker\");\n // Set attribute after appendChild\n document.body.appendChild(el);\n el.setAttribute(\"icon\", JSON.stringify({ iconUrl: \"bar.png\" }));\n let actual = el.layer.getIcon();\n let expected = L.icon({ iconUrl: \"bar.png\" });\n expect(actual).toEqual(expected);\n });\n}\n\nexport default LMarker;\n","import { mapAddTo } from \"./events.js\";\n\nclass LOverlayLayers extends HTMLElement {\n constructor() {\n super();\n }\n\n connectedCallback() {\n this.addEventListener(mapAddTo, (ev) => {\n ev.detail[\"type\"] = \"overlay\";\n });\n }\n}\n\nexport default LOverlayLayers;\n","import { popupAdd } from \"./events.js\";\n\nclass LPopup extends HTMLElement {\n constructor() {\n super();\n }\n\n connectedCallback() {\n const content = this.getAttribute(\"content\");\n const event = new CustomEvent(popupAdd, {\n cancelable: true,\n bubbles: true,\n detail: {\n content,\n },\n });\n this.dispatchEvent(event);\n }\n}\n\nexport default LPopup;\n","import { mapAddTo } from \"./events.js\";\n\nclass LTileLayer extends HTMLElement {\n constructor() {\n super();\n }\n\n connectedCallback() {\n const name = this.getAttribute(\"name\");\n const urlTemplate = this.getAttribute(\"url-template\");\n const attribution = this.getAttribute(\"attribution\");\n const options = { attribution };\n const layer = L.tileLayer(urlTemplate, options);\n const event = new CustomEvent(mapAddTo, {\n detail: { name, layer },\n bubbles: true,\n });\n this.dispatchEvent(event);\n }\n}\n\nexport default LTileLayer;\n","class LLatLngBounds extends HTMLElement {\n static observedAttributes = [\"bounds\"];\n\n constructor() {\n super();\n }\n\n attributeChangedCallback(_name, _oldValue, newValue) {\n const event = new CustomEvent(\"map:bounds\", {\n bubbles: true,\n detail: {\n bounds: JSON.parse(newValue),\n method: this.getAttribute(\"method\") || \"fitBounds\",\n },\n });\n this.dispatchEvent(event);\n }\n}\n\nexport default LLatLngBounds;\n","import { mapAddTo } from \"./events.js\";\n\nclass LImageOverlay extends HTMLElement {\n static observedAttributes = [\"url\", \"bounds\", \"opacity\"];\n\n constructor() {\n super();\n this.layer = null;\n }\n\n connectedCallback() {\n const url = this.getAttribute(\"url\");\n const bounds = JSON.parse(this.getAttribute(\"bounds\"));\n const options = {\n opacity: parseFloat(this.getAttribute(\"opacity\") || \"1.0\"),\n alt: this.getAttribute(\"alt\") || \"\",\n };\n this.layer = L.imageOverlay(url, bounds, options);\n this.dispatchEvent(\n new CustomEvent(mapAddTo, {\n cancelable: true,\n bubbles: true,\n detail: {\n layer: this.layer,\n },\n }),\n );\n }\n\n attributeChangedCallback(name, _oldValue, newValue) {\n if (this.layer !== null) {\n if (name === \"url\") {\n this.layer.setUrl(newValue);\n } else if (name === \"bounds\") {\n this.layer.setBounds(JSON.parse(newValue));\n } else if (name === \"opacity\") {\n this.layer.setOpacity(parseFloat(newValue));\n }\n }\n }\n}\n\nexport default LImageOverlay;\n","import { mapAddTo } from \"./events.js\";\n\nclass LVideoOverlay extends HTMLElement {\n constructor() {\n super();\n }\n\n connectedCallback() {\n const url = JSON.parse(this.getAttribute(\"url\"));\n const bounds = JSON.parse(this.getAttribute(\"bounds\"));\n const options = {\n opacity: parseFloat(this.getAttribute(\"opacity\") || \"1.0\"),\n alt: this.getAttribute(\"alt\") || \"\",\n autoplay: true,\n muted: true,\n playsInline: true,\n };\n const layer = L.videoOverlay(url, bounds, options);\n this.dispatchEvent(\n new CustomEvent(mapAddTo, {\n cancelable: true,\n bubbles: true,\n detail: {\n layer,\n },\n }),\n );\n }\n}\n\nexport default LVideoOverlay;\n","import { mapAddTo } from \"./events.js\";\n\nclass LGeoJSON extends HTMLElement {\n constructor() {\n super();\n }\n\n connectedCallback() {\n const layer = L.geoJSON(JSON.parse(this.getAttribute(\"geojson\")));\n this.dispatchEvent(\n new CustomEvent(mapAddTo, {\n bubbles: true,\n cancelable: true,\n detail: {\n layer,\n },\n }),\n );\n }\n}\n\nexport default LGeoJSON;\n","// @vitest-environment happy-dom\nimport * as L from \"leaflet\";\n\nconst camelCase = (kebab) => kebab.replace(/-./g, (x) => x[1].toUpperCase());\n\nclass LIcon extends HTMLElement {\n constructor() {\n super();\n this.icon = null;\n }\n\n connectedCallback() {\n const options = {};\n\n // Strings\n let keys = [\n \"icon-url\",\n \"icon-retina-url\",\n \"shadow-url\",\n \"shadow-retina-url\",\n \"class-name\",\n ];\n keys.forEach((key) => {\n if (this.hasAttribute(key)) {\n options[camelCase(key)] = this.getAttribute(key);\n }\n });\n\n // Points\n let points = [\n \"icon-anchor\",\n \"icon-size\",\n \"shadow-anchor\",\n \"shadow-size\",\n \"tooltip-anchor\",\n \"popup-anchor\",\n ];\n points.forEach((key) => {\n if (this.hasAttribute(key)) {\n options[camelCase(key)] = JSON.parse(this.getAttribute(key));\n }\n });\n\n if (this.hasAttribute(\"cross-origin\")) {\n options.crossOrigin = this.getAttribute(\"cross-origin\") === \"true\";\n }\n this.icon = L.icon(options);\n\n const event = new CustomEvent(\"icon:add\", {\n cancelable: true,\n bubbles: true,\n detail: {\n icon: this.icon,\n },\n });\n this.dispatchEvent(event);\n }\n}\n\nif (import.meta.vitest) {\n const { it, expect, beforeAll } = import.meta.vitest;\n\n beforeAll(() => {\n customElements.define(\"l-icon\", LIcon);\n });\n\n it(\"default\", () => {\n const el = document.createElement(\"l-icon\");\n document.body.appendChild(el);\n\n let actual = el.icon;\n let expected = L.icon();\n expect(actual).toEqual(expected);\n });\n\n it(\"emits icon:add event\", async () => {\n const el = document.createElement(\"l-icon\");\n let promise = new Promise((resolve) => {\n el.addEventListener(\"icon:add\", (ev) => {\n resolve(ev.detail.icon);\n });\n });\n document.body.appendChild(el);\n let actual = await promise;\n let expected = L.icon();\n expect(actual).toEqual(expected);\n });\n\n it(\"options\", () => {\n const el = document.createElement(\"l-icon\");\n el.setAttribute(\"icon-url\", \"url.png\");\n el.setAttribute(\"icon-retina-url\", \"retina.png\");\n el.setAttribute(\"icon-size\", \"[0, 0]\");\n el.setAttribute(\"icon-anchor\", \"[0, 0]\");\n el.setAttribute(\"popup-anchor\", \"[0, 0]\");\n el.setAttribute(\"tooltip-anchor\", \"[0, 0]\");\n el.setAttribute(\"shadow-url\", \"urlShadow.png\");\n el.setAttribute(\"shadow-retina-url\", \"retinaShadow.png\");\n el.setAttribute(\"shadow-size\", \"[0, 0]\");\n el.setAttribute(\"shadow-anchor\", \"[0, 0]\");\n el.setAttribute(\"class-name\", \"foo\");\n el.setAttribute(\"cross-origin\", \"true\");\n document.body.appendChild(el);\n\n let actual = el.icon;\n let expected = L.icon({\n iconUrl: \"url.png\",\n iconRetinaUrl: \"retina.png\",\n iconSize: [0, 0],\n iconAnchor: [0, 0],\n popupAnchor: [0, 0],\n tooltipAnchor: [0, 0],\n shadowUrl: \"urlShadow.png\",\n shadowRetinaUrl: \"retinaShadow.png\",\n shadowSize: [0, 0],\n shadowAnchor: [0, 0],\n className: \"foo\",\n crossOrigin: true,\n });\n expect(actual).toEqual(expected);\n });\n}\n\nexport default LIcon;\n","// @ts-check\nimport LBaseLayers from \"./l-base-layers.js\";\nimport LControlLayers from \"./l-control-layers.js\";\nimport LLayerGroup from \"./l-layer-group.js\";\nimport LMap from \"./l-map.js\";\nimport LMarker from \"./l-marker.js\";\nimport LOverlayLayers from \"./l-overlay-layers.js\";\nimport LPopup from \"./l-popup.js\";\nimport LTileLayer from \"./l-tile-layer.js\";\nimport LLatLngBounds from \"./l-lat-lng-bounds.js\";\nimport LImageOverlay from \"./l-image-overlay.js\";\nimport LVideoOverlay from \"./l-video-overlay.js\";\nimport LGeoJSON from \"./l-geojson.js\";\nimport LIcon from \"./l-icon.js\";\n\nconst init = (() => {\n // Custom elements (order of definition is important)\n customElements.define(\"l-map\", LMap);\n customElements.define(\"l-control-layers\", LControlLayers);\n customElements.define(\"l-base-layers\", LBaseLayers);\n customElements.define(\"l-overlay-layers\", LOverlayLayers);\n customElements.define(\"l-layer-group\", LLayerGroup);\n customElements.define(\"l-tile-layer\", LTileLayer);\n customElements.define(\"l-marker\", LMarker);\n customElements.define(\"l-popup\", LPopup);\n customElements.define(\"l-lat-lng-bounds\", LLatLngBounds);\n customElements.define(\"l-image-overlay\", LImageOverlay);\n customElements.define(\"l-video-overlay\", LVideoOverlay);\n customElements.define(\"l-geojson\", LGeoJSON);\n customElements.define(\"l-icon\", LIcon);\n})();\n\nexport default init;\n"],"names":["mapAddTo","popupAdd","LBaseLayers","_HTMLElement","call","this","_inheritsLoose","prototype","connectedCallback","addEventListener","ev","detail","_wrapNativeSuper","HTMLElement","LControlLayers","control","L","layers","_ev$detail","type","name","layer","addOverlay","addBaseLayer","preventDefault","event","CustomEvent","cancelable","bubbles","dispatchEvent","LLayerGroup","getAttribute","group","layerGroup","stopPropagation","addLayer","MutationObserver","mutations","forEach","mutation","removedNodes","node","leafletId","getLayer","removeLayer","observe","childList","LMap","_this","map","method","bounds","_this2","center","zoom","setView","JSON","parse","parseInt","addTo","remove","LMarker","setIcon","icon","_proto","latLng","opacity","parseFloat","marker","hasAttribute","setAttribute","stamp","bindPopup","content","attributeChangedCallback","_oldValue","newValue","setLatLng","setOpacity","observedAttributes","LOverlayLayers","LPopup","LTileLayer","urlTemplate","attribution","tileLayer","LLatLngBounds","_name","LImageOverlay","url","options","alt","imageOverlay","setUrl","setBounds","LVideoOverlay","autoplay","muted","playsInline","videoOverlay","LGeoJSON","geoJSON","camelCase","kebab","replace","x","toUpperCase","LIcon","key","crossOrigin","customElements","define"],"mappings":"guDAAaA,EAAW,YACXC,EAAW,YCClBC,eAAWC,SAAAA,GACf,SAAAD,IAAc,OACZC,EAAAC,KAAAC,OAAOA,IACT,CAMC,OANAC,EAAAJ,EAAAC,GAAAD,EAAAK,UAEDC,kBAAA,WACEH,KAAKI,iBAAiBT,EAAU,SAACU,GAC/BA,EAAGC,OAAa,KAAI,MACtB,EACF,EAACT,CAAA,CATcC,cASdS,EATuBC,cCApBC,wBAAcX,GAClB,SAAAW,WACEX,EAAAC,KAAAC,OACFA,IAAA,CAyBC,OAzBAC,EAAAQ,EAAAX,GAAAW,EAAAP,UAEDC,kBAAA,WACE,IAEMO,EAAUC,EAAED,QAAQE,OAFb,CAAA,EACG,CAAE,GAGlBZ,KAAKI,iBAAiBT,EAAU,SAACU,GAC/B,IAAAQ,EAA8BR,EAAGC,OAAzBQ,EAAID,EAAJC,KAAMC,EAAIF,EAAJE,KAAMC,EAAKH,EAALG,MACP,YAATF,EACFJ,EAAQO,WAAWD,EAAOD,GACR,SAATD,GACTJ,EAAQQ,aAAaF,EAAOD,GAE9BV,EAAGc,gBACL,GAEA,IAAMC,EAAQ,IAAIC,YAAY1B,EAAU,CACtC2B,YAAY,EACZC,SAAS,EACTjB,OAAQ,CACNU,MAAON,KAGXV,KAAKwB,cAAcJ,EACrB,EAACX,CAAA,eAAAF,EA5B0BC,cCAvBiB,eAAW3B,SAAAA,GACf,SAAA2B,IAAc,OACZ3B,EAAAC,YAAOC,IACT,CA8BCyB,OA9BAxB,EAAAwB,EAAA3B,GAAA2B,EAAAvB,UAEDC,kBAAA,WACE,IAAMY,EAAOf,KAAK0B,aAAa,QACzBC,EAAQhB,EAAEiB,aACVR,EAAQ,IAAIC,YAAY1B,EAAU,CACtC2B,YAAY,EACZC,SAAS,EACTjB,OAAQ,CACNU,MAAOW,EACPZ,KAAAA,KAGJf,KAAKwB,cAAcJ,GAEnBpB,KAAKI,iBAAiBT,EAAU,SAACU,GAC/BA,EAAGwB,kBACHF,EAAMG,SAASzB,EAAGC,OAAOU,MAC3B,GAEiB,IAAIe,iBAAiB,SAAUC,GAC9CA,EAAUC,QAAQ,SAACC,GACjBA,EAASC,aAAaF,QAAQ,SAACG,GAC7B,IAAMC,EAAYD,EAAKV,aAAa,cAC9BV,EAAQW,EAAMW,SAASD,GAC7BV,EAAMY,YAAYvB,EACpB,EACF,EACF,GACSwB,QAAQxC,KAAM,CAAEyC,WAAW,GACtC,EAAChB,CAAA,CAjCc3B,cAiCdS,EAjCuBC,cCCpBkC,eAAI,SAAA5C,GACR,SAAA4C,IAAcC,IAAAA,EAOT,OANHA,EAAA7C,EAAAC,KAAAC,OAAOA,MAEF4C,IAAM,KACXD,EAAKvC,iBAAiB,aAAc,SAACC,GACnC,IAAAQ,EAA2BR,EAAGC,OAC9BqC,EAAKC,IADiB/B,EAANgC,QAAFhC,EAANiC,OAEV,GAAGH,CACL,CAiBC,OAjBA1C,EAAAyC,EAAA5C,GAAA4C,EAAAxC,UAEDC,kBAAA,WAAoB4C,IAAAA,OAClB/C,KAAK4C,IAAMjC,EAAEiC,IAAI5C,MACjB,IAAMgD,EAAShD,KAAK0B,aAAa,UAC3BuB,EAAOjD,KAAK0B,aAAa,QAChB,OAAXsB,GAA4B,OAATC,GACrBjD,KAAK4C,IAAIM,QAAQC,KAAKC,MAAMJ,GAASK,SAASJ,IAEhDjD,KAAKI,iBAAiBT,EAAU,SAACU,GACjBA,EAAGC,OAAOU,MAClBsC,MAAMP,EAAKH,IACnB,GAEA5C,KAAKI,iBJxBkB,eIwBY,SAACC,GAClC0C,EAAKH,IAAIW,OAAOlD,EAAGC,OAAOU,MAC5B,EACF,EAAC0B,CAAA,CA1BO,cA0BPnC,EA1BgBC,cCCbgD,eAAO1D,SAAAA,GAGX,SAAA0D,IAAc,IAAAb,EAMVA,OALFA,EAAA7C,EAAAC,YAAOC,MACFgB,MAAQ,KACb2B,EAAKvC,iBAAiB,WAAY,SAACC,GACjCA,EAAGwB,kBACHc,EAAK3B,MAAMyC,QAAQpD,EAAGC,OAAOoD,KAC/B,GAAEf,CACJ,CAAC1C,EAAAuD,EAAA1D,OAAA6D,EAAAH,EAAAtD,UAwCAsD,OAxCAG,EAEDxD,kBAAA,WAAoB,IAAA4C,EAClB/C,KAAM4D,EAAST,KAAKC,MAAMpD,KAAK0B,aAAa,YACtCmC,EAAUC,WAAW9D,KAAK0B,aAAa,YAAc,OAE3D,GADA1B,KAAKgB,MAAQL,EAAEoD,OAAOH,EAAQ,CAAEC,QAAAA,IAC5B7D,KAAKgE,aAAa,QAAS,CAC7B,IAAMN,EAAO/C,EAAE+C,KAAKP,KAAKC,MAAMpD,KAAK0B,aAAa,UACjD1B,KAAKgB,MAAMyC,QAAQC,EACrB,CAEA1D,KAAKiE,aAAa,aAActD,EAAEuD,MAAMlE,KAAKgB,QAE7ChB,KAAKI,iBAAiBR,EAAU,SAACS,GAE/B0C,EAAK/B,MAAMmD,UADS9D,EAAGC,OAAf8D,QAEV,GAEA,IAAMhD,EAAQ,IAAIC,YAAY1B,EAAU,CACtC2B,YAAY,EACZC,SAAS,EACTjB,OAAQ,CACNU,MAAOhB,KAAKgB,SAGhBhB,KAAKwB,cAAcJ,EACrB,EAACuC,EAEDU,yBAAA,SAAyBtD,EAAMuD,EAAWC,GACrB,OAAfvE,KAAKgB,QACM,YAATD,GACFf,KAAKgB,MAAMwD,UAAUrB,KAAKC,MAAMmB,IAErB,YAATxD,GACFf,KAAKgB,MAAMyD,WAAWX,WAAWS,IAEtB,SAATxD,GACFf,KAAKgB,MAAMyC,QAAQ9C,EAAE+C,KAAKP,KAAKC,MAAMmB,KAG3C,EAACf,CAAA,CAlDU1D,cAkDVS,EAlDmBC,cAAhBgD,EACGkB,mBAAqB,CAAC,UAAW,UAAW,QCLd,IAEjCC,eAAc7E,SAAAA,GAClB,SAAA6E,IAAc,OACZ7E,EAAAC,KAAAC,OAAOA,IACT,CAMC,OANAC,EAAA0E,EAAA7E,GAAA6E,EAAAzE,UAEDC,kBAAA,WACEH,KAAKI,iBAAiBT,EAAU,SAACU,GAC/BA,EAAGC,OAAa,KAAI,SACtB,EACF,EAACqE,CAAA,CATiB7E,cASjBS,EAT0BC,cCAvBoE,wBAAM9E,GACV,SAAA8E,WACE9E,EAAAC,KAAAC,OAAOA,IACT,CAYC,OAZAC,EAAA2E,EAAA9E,GAAA8E,EAAA1E,UAEDC,kBAAA,WACE,IAAMiE,EAAUpE,KAAK0B,aAAa,WAC5BN,EAAQ,IAAIC,YAAYzB,EAAU,CACtC0B,YAAY,EACZC,SAAS,EACTjB,OAAQ,CACN8D,QAAAA,KAGJpE,KAAKwB,cAAcJ,EACrB,EAACwD,CAAA,eAAArE,EAfkBC,cCAfqE,eAAU/E,SAAAA,GACd,SAAA+E,WACE/E,EAAAC,KAAMC,OACRA,IAAA,CAaC,OAbAC,EAAA4E,EAAA/E,GAAA+E,EAAA3E,UAEDC,kBAAA,WACE,IAAMY,EAAOf,KAAK0B,aAAa,QACzBoD,EAAc9E,KAAK0B,aAAa,gBAChCqD,EAAc/E,KAAK0B,aAAa,eAEhCV,EAAQL,EAAEqE,UAAUF,EADV,CAAEC,YAAAA,IAEZ3D,EAAQ,IAAIC,YAAY1B,EAAU,CACtCW,OAAQ,CAAES,KAAAA,EAAMC,MAAAA,GAChBO,SAAS,IAEXvB,KAAKwB,cAAcJ,EACrB,EAACyD,CAAA,CAhBa/E,cAgBbS,EAhBsBC,cCFnByE,wBAAanF,GAGjB,SAAAmF,IACE,OAAAnF,EAAAC,KAAMC,OACRA,IAAA,CAWC,OAXAC,EAAAgF,EAAAnF,GAAAmF,EAAA/E,UAEDmE,yBAAA,SAAyBa,EAAOZ,EAAWC,GACzC,IAAMnD,EAAQ,IAAIC,YAAY,aAAc,CAC1CE,SAAS,EACTjB,OAAQ,CACNwC,OAAQK,KAAKC,MAAMmB,GACnB1B,OAAQ7C,KAAK0B,aAAa,WAAa,eAG3C1B,KAAKwB,cAAcJ,EACrB,EAAC6D,CAAA,eAAA1E,EAhByBC,cAAtByE,EACGP,mBAAqB,CAAC,UCDQ,IAEjCS,eAAa,SAAArF,GAGjB,SAAAqF,IAAc,IAAAxC,EAEM,OADlBA,EAAA7C,EAAAC,KAAAC,OAAOA,MACFgB,MAAQ,KAAK2B,CACpB,CAAC1C,EAAAkF,EAAArF,GAAA6D,IAAAA,EAAAwB,EAAAjF,UA+BAiF,OA/BAxB,EAEDxD,kBAAA,WACE,IAAMiF,EAAMpF,KAAK0B,aAAa,OACxBoB,EAASK,KAAKC,MAAMpD,KAAK0B,aAAa,WACtC2D,EAAU,CACdxB,QAASC,WAAW9D,KAAK0B,aAAa,YAAc,OACpD4D,IAAKtF,KAAK0B,aAAa,QAAU,IAEnC1B,KAAKgB,MAAQL,EAAE4E,aAAaH,EAAKtC,EAAQuC,GACzCrF,KAAKwB,cACH,IAAIH,YAAY1B,EAAU,CACxB2B,YAAY,EACZC,SAAS,EACTjB,OAAQ,CACNU,MAAOhB,KAAKgB,SAIpB,EAAC2C,EAEDU,yBAAA,SAAyBtD,EAAMuD,EAAWC,GACrB,OAAfvE,KAAKgB,QACM,QAATD,EACFf,KAAKgB,MAAMwE,OAAOjB,GACA,WAATxD,EACTf,KAAKgB,MAAMyE,UAAUtC,KAAKC,MAAMmB,IACd,YAATxD,GACTf,KAAKgB,MAAMyD,WAAWX,WAAWS,IAGvC,EAACY,CAAA,CArCgB,cAqChB5E,EArCyBC,cAAtB2E,EACGT,mBAAqB,CAAC,MAAO,SAAU,WCHT,IAEjCgB,eAAa,SAAA5F,GACjB,SAAA4F,WACE5F,EAAAC,KAAAC,OAAOA,IACT,CAsBC0F,OAtBAzF,EAAAyF,EAAA5F,GAAA4F,EAAAxF,UAEDC,kBAAA,WACE,IAAMiF,EAAMjC,KAAKC,MAAMpD,KAAK0B,aAAa,QACnCoB,EAASK,KAAKC,MAAMpD,KAAK0B,aAAa,WACtC2D,EAAU,CACdxB,QAASC,WAAW9D,KAAK0B,aAAa,YAAc,OACpD4D,IAAKtF,KAAK0B,aAAa,QAAU,GACjCiE,UAAU,EACVC,OAAO,EACPC,aAAa,GAET7E,EAAQL,EAAEmF,aAAaV,EAAKtC,EAAQuC,GAC1CrF,KAAKwB,cACH,IAAIH,YAAY1B,EAAU,CACxB2B,YAAY,EACZC,SAAS,EACTjB,OAAQ,CACNU,MAAAA,KAIR,EAAC0E,CAAA,CAzBgB,cAyBhBnF,EAzByBC,cCAtBuF,eAAQjG,SAAAA,GACZ,SAAAiG,IAAc,OACZjG,EAAAC,KAAMC,OACRA,IAAA,CAaC+F,OAbA9F,EAAA8F,EAAAjG,GAAAiG,EAAA7F,UAEDC,kBAAA,WACE,IAAMa,EAAQL,EAAEqF,QAAQ7C,KAAKC,MAAMpD,KAAK0B,aAAa,aACrD1B,KAAKwB,cACH,IAAIH,YAAY1B,EAAU,CACxB4B,SAAS,EACTD,YAAY,EACZhB,OAAQ,CACNU,MAAAA,KAIR,EAAC+E,CAAA,CAhBWjG,cAgBXS,EAhBoBC,cCCjByF,EAAY,SAACC,GAAU,OAAAA,EAAMC,QAAQ,MAAO,SAACC,UAAMA,EAAE,GAAGC,aAAa,EAAC,EAEtEC,wBAAKxG,GACT,SAAAwG,IAAc3D,IAAAA,EAEK,OADjBA,EAAA7C,EAAAC,YAAOC,MACF0D,KAAO,KAAKf,CACnB,CA+CC2D,OA/CArG,EAAAqG,EAAAxG,GAAAwG,EAAApG,UAEDC,kBAAA,WAAoB,IAAA4C,EAClB/C,KAAMqF,EAAU,CAAA,EAGL,CACT,WACA,kBACA,aACA,oBACA,cAEGpD,QAAQ,SAACsE,GACRxD,EAAKiB,aAAauC,KACpBlB,EAAQY,EAAUM,IAAQxD,EAAKrB,aAAa6E,GAEhD,GAGa,CACX,cACA,YACA,gBACA,cACA,iBACA,gBAEKtE,QAAQ,SAACsE,GACVxD,EAAKiB,aAAauC,KACpBlB,EAAQY,EAAUM,IAAQpD,KAAKC,MAAML,EAAKrB,aAAa6E,IAE3D,GAEIvG,KAAKgE,aAAa,kBACpBqB,EAAQmB,YAAoD,SAAtCxG,KAAK0B,aAAa,iBAE1C1B,KAAK0D,KAAO/C,EAAE+C,KAAK2B,GAEnB,IAAMjE,EAAQ,IAAIC,YAAY,WAAY,CACxCC,YAAY,EACZC,SAAS,EACTjB,OAAQ,CACNoD,KAAM1D,KAAK0D,QAGf1D,KAAKwB,cAAcJ,EACrB,EAACkF,CAAA,eAAA/F,EAnDiBC,qBCYlBiG,eAAeC,OAAO,QAAShE,GAC/B+D,eAAeC,OAAO,mBAAoBjG,GAC1CgG,eAAeC,OAAO,gBAAiB7G,GACvC4G,eAAeC,OAAO,mBAAoB/B,GAC1C8B,eAAeC,OAAO,gBAAiBjF,GACvCgF,eAAeC,OAAO,eAAgB7B,GACtC4B,eAAeC,OAAO,WAAYlD,GAClCiD,eAAeC,OAAO,UAAW9B,GACjC6B,eAAeC,OAAO,mBAAoBzB,GAC1CwB,eAAeC,OAAO,kBAAmBvB,GACzCsB,eAAeC,OAAO,kBAAmBhB,GACzCe,eAAeC,OAAO,YAAaX,QACnCU,eAAeC,OAAO,SAAUJ"}
@@ -5,6 +5,11 @@
5
5
  [LeafletJS](https://leafletjs.com/) is a library geared towards map based visualisations.
6
6
  Leaflet HTML expresses that JavaScript API in HTML.
7
7
 
8
+ ## How-to guides
9
+
10
+ [Articles](@/articles/_index.md) have been written to make adopting Leaflet HTML simpler.
11
+ These articles follow the Leaflet tutorials closely and add a few `leaflet-html` specific
12
+ tips and tricks.
8
13
 
9
14
  ## Design principles
10
15
 
@@ -16,71 +21,69 @@ The hierarchy in the JS API is replicated by nesting HTML elements.
16
21
 
17
22
  The following is a live running example of Leaflet HTML.
18
23
 
19
- <div data-leaflet-html data-center="[39.61, -105.02]" data-zoom="10">
20
- <div data-control-layers>
21
- <div data-base-maps>
22
- <div
23
- data-tile-layer
24
- data-name="CartoDB_Voyager"
25
- data-url-template="https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png"
26
- data-attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors &copy; <a href="https://carto.com/attributions">CARTO</a>'
27
- data-max-zoom="20"
28
- data-subdomains="abcd"
29
- data-show
30
- ></div>
31
- </div>
32
- <div data-overlay-maps>
33
- <div data-layer-group data-name="Cities">
34
- <div data-marker data-lat-lng="[39.61, -105.02]">
35
- <div data-popup data-content="This is Littleton, CO."></div>
36
- </div>
37
- <div data-marker data-lat-lng="[39.74, -104.99]">
38
- <div data-popup data-content="This is Denver, CO."></div>
39
- </div>
40
- <div data-marker data-lat-lng="[39.73, -104.8]">
41
- <div data-popup data-content="This is Aurora, CO."></div>
42
- </div>
43
- <div data-marker data-lat-lng="[39.77, -105.23]">
44
- <div data-popup data-content="This is Golden, CO."></div>
45
- </div>
46
- </div>
47
- </div>
48
- </div>
49
- </div>
24
+ <l-map center="[39.61, -105.02]" zoom="10">
25
+ <l-control-layers>
26
+ <l-base-layers>
27
+ <l-tile-layer
28
+ name="CartoDB_Voyager"
29
+ url-template="https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png"
30
+ attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors &copy; <a href="https://carto.com/attributions">CARTO</a>'
31
+ max-zoom="20"
32
+ subdomains="abcd"
33
+ show
34
+ ></l-tile-layer>
35
+ </l-base-layers>
36
+ <l-overlay-layers>
37
+ <l-layer-group name="Cities">
38
+ <l-marker lat-lng="[39.61, -105.02]">
39
+ <l-popup content="This is Littleton, CO."></l-popup>
40
+ </l-marker>
41
+ <l-marker lat-lng="[39.74, -104.99]">
42
+ <l-popup content="This is Denver, CO."></l-popup>
43
+ </l-marker>
44
+ <l-marker lat-lng="[39.73, -104.8]">
45
+ <l-popup content="This is Aurora, CO."></l-popup>
46
+ </l-marker>
47
+ <l-marker lat-lng="[39.77, -105.23]">
48
+ <l-popup content="This is Golden, CO."></l-popup>
49
+ </l-marker>
50
+ </l-layer-group>
51
+ </l-overlay-layers>
52
+ </l-control-layers>
53
+ </l-map>
50
54
 
55
+ The above application is represented in HTML using the following syntax.
51
56
 
52
57
  ```html
53
- <!-- Example -->
54
- <div data-leaflet-html data-center="[39.61, -105.02]" data-zoom="10">
55
- <div data-control-layers>
56
- <div data-base-maps>
57
- <div
58
- data-tile-layer
59
- data-name="CartoDB_Voyager"
60
- data-url-template="https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png"
61
- data-attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors &copy; <a href="https://carto.com/attributions">CARTO</a>'
62
- data-max-zoom="20"
63
- data-subdomains="abcd"
64
- data-show
65
- ></div>
66
- </div>
67
- <div data-overlay-maps>
68
- <div data-layer-group data-name="Cities">
69
- <div data-marker data-lat-lng="[39.61, -105.02]">
70
- <div data-popup data-content="This is Littleton, CO."></div>
71
- </div>
72
- <div data-marker data-lat-lng="[39.74, -104.99]">
73
- <div data-popup data-content="This is Denver, CO."></div>
74
- </div>
75
- <div data-marker data-lat-lng="[39.73, -104.8]">
76
- <div data-popup data-content="This is Aurora, CO."></div>
77
- </div>
78
- <div data-marker data-lat-lng="[39.77, -105.23]">
79
- <div data-popup data-content="This is Golden, CO."></div>
80
- </div>
81
- </div>
82
- </div>
83
- </div>
84
- </div>
58
+ <l-map center="[39.61, -105.02]" zoom="10">
59
+ <l-control-layers>
60
+ <l-base-layers>
61
+ <l-tile-layer
62
+ name="CartoDB_Voyager"
63
+ url-template="https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png"
64
+ attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors &copy; <a href="https://carto.com/attributions">CARTO</a>'
65
+ max-zoom="20"
66
+ subdomains="abcd"
67
+ ></l-tile-layer>
68
+ </l-base-layers>
69
+ <l-overlay-layers>
70
+ <l-layer-group name="Cities">
71
+ <l-marker lat-lng="[39.61, -105.02]">
72
+ <l-popup content="This is Littleton, CO."></l-popup>
73
+ </l-marker>
74
+ <l-marker lat-lng="[39.74, -104.99]">
75
+ <l-popup content="This is Denver, CO."></l-popup>
76
+ </l-marker>
77
+ <l-marker lat-lng="[39.73, -104.8]">
78
+ <l-popup content="This is Aurora, CO."></l-popup>
79
+ </l-marker>
80
+ <l-marker lat-lng="[39.77, -105.23]">
81
+ <l-popup content="This is Golden, CO."></l-popup>
82
+ </l-marker>
83
+ </l-layer-group>
84
+ </l-overlay-layers>
85
+ </l-control-layers>
86
+ </l-map>
85
87
  ```
86
88
 
89
+ The above example is a taste of the syntax and capabilities of wrapping Leaflet in HTML tags.
@@ -0,0 +1,5 @@
1
+ +++
2
+ title = "Leaflet HTML articles"
3
+ template = "article.html"
4
+ page_template = "article-page.html"
5
+ +++
@@ -0,0 +1,105 @@
1
+ +++
2
+ title = "Basic usage"
3
+ +++
4
+
5
+ The minimal `leaflet-html` app is a basemap centered and zoomed on a location.
6
+
7
+ ```html
8
+ <l-map center="[53, 0]" zoom="4">
9
+ <l-tile-layer
10
+ url-template="https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png"
11
+ ></l-tile-layer>
12
+ </l-map>
13
+ ```
14
+
15
+ <l-map center="[53, 0]" zoom="4">
16
+ <l-tile-layer
17
+ url-template="https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png"
18
+ ></l-tile-layer>
19
+ </l-map>
20
+
21
+ To add the above widget to a HTML document both JS and CSS tags need to be included in the `<head>` of the page.
22
+
23
+ ## Assets
24
+
25
+ Basic HTML recommended settings, e.g. `charset`, `lang`, and `viewport` to help with cross device support.
26
+ Can be placed in the `<head>` tag, along with CSS and JS assets.
27
+
28
+ ```html
29
+ <head lang="en">
30
+ <meta charset="utf-8" />
31
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
32
+ </head>
33
+ ```
34
+
35
+ ### Leaflet
36
+
37
+ Leaflet is an external dependency of `leaflet-html`, as such,
38
+ the standard Leaflet assets should be included.
39
+
40
+ ```html
41
+ <head>
42
+ ...
43
+ <link
44
+ rel="stylesheet"
45
+ href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
46
+ integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
47
+ crossorigin=""
48
+ />
49
+ <script
50
+ src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
51
+ integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
52
+ crossorigin=""
53
+ ></script>
54
+ ...
55
+ </head>
56
+ ```
57
+
58
+ ### Leaflet-HTML
59
+
60
+ Leaflet-HTML is available via **npm** and **unpkg**.
61
+ To get started quickly, use the CDN version available on **unpkg**.
62
+
63
+ ```html
64
+ <script
65
+ type="module"
66
+ src="https://unpkg.com/leaflet-html@latest/dist/leaflet-html.js"
67
+ ></script>
68
+ ```
69
+
70
+ The `@latest` keyword should keep your site up to date during development.
71
+
72
+ ## Minimal style
73
+
74
+ By default Custom elements are `display: inline`,
75
+ meaning they are unaffected by `height`.
76
+ Add the following ruleset to your stylesheet to enable map size.
77
+
78
+ ```css
79
+ l-map {
80
+ display: block;
81
+ }
82
+ ```
83
+
84
+ It's not always necessary to set `block` directly on an `l-map` tag.
85
+ For example, a parent with `display: grid`, will size the `l-map` tag appropriately.
86
+
87
+ ### Z-index
88
+
89
+ Leaflet has fairly strong `z-index` settings that are not easy to override.
90
+ The easiest way to get around them is to start a new stacking context using `isolation: isolate`.
91
+
92
+ ### Sensible defaults
93
+
94
+ Without knowing anything specific about your application the following settings should be a good starting place.
95
+
96
+ ```css
97
+ l-map {
98
+ display: block;
99
+ block-size: 40ch;
100
+ isolation: isolate;
101
+ z-index: 1;
102
+ }
103
+ ```
104
+
105
+ This allows overlaying your own UI elements and gives full control over size and position of each map on the page.
@@ -0,0 +1,35 @@
1
+ +++
2
+ title = "Custom icons"
3
+ +++
4
+
5
+ There are two ways to add an icon to a marker.
6
+ One is to specify a `icon` attribute containing a JSON string of `L.Icon` options.
7
+
8
+ ```html
9
+ <l-marker
10
+ lat-lng="[51.5, -0.09]"
11
+ icon='{"iconUrl": "icons/leaf-green.png"}'
12
+ ></l-marker>
13
+ ```
14
+
15
+ The other way is to create a separate HTML tag to configure the icon.
16
+ This is a more HTML centered approach.
17
+ The above JSON approach may be suitable in cases where the icon data is available in a data structure.
18
+
19
+ ```html
20
+ <l-marker lat-lng="[51.5, -0.09]">
21
+ <l-icon icon-url="icons/leaf-green.png"></l-icon>
22
+ </l-marker>
23
+ ```
24
+
25
+ Both are supported, choose whichever is most convenient.
26
+
27
+ <l-map center="[51.5, -0.09]" zoom="12">
28
+ <l-tile-layer
29
+ url-template="https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png"
30
+ ></l-tile-layer>
31
+ <l-marker
32
+ lat-lng="[51.5, -0.09]"
33
+ icon='{"iconUrl": "icons/leaf-green.png"}'
34
+ ></l-marker>
35
+ </l-map>
@@ -0,0 +1,14 @@
1
+ +++
2
+ title = "Styling leaflet objects"
3
+ +++
4
+
5
+ ## Naming convention
6
+ Leaflet styles objects using the `style` keyword option.
7
+ Leaflet HTML, on the other hand, needs to support inline style and leaflet style.
8
+ Therefore, the keyword `l-style` is used to style the underlying leaflet objects.
9
+
10
+ ## Example
11
+
12
+ ```html
13
+ <l-marker l-style='{"color": "hotpink"}'></l-marker>
14
+ ```
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,8 @@
1
+ {% extends "base.html" %}
2
+
3
+ {% block content %}
4
+ <main>
5
+ <h1>{{ page.title }}</h1>
6
+ {{ page.content | safe }}
7
+ </main>
8
+ {% endblock %}
@@ -0,0 +1,12 @@
1
+ {% extends "base.html" %}
2
+
3
+ {% block content %}
4
+ <main>
5
+ <h1>{{section.title}}</h1>
6
+ <ul>
7
+ {% for page in section.pages %}
8
+ <li><a href="{{ page.permalink | safe }}">{{ page.title }}</a></li>
9
+ {% endfor %}
10
+ </ul>
11
+ </main>
12
+ {% endblock content %}