leaflet-html 0.1.7 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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":"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"}
@@ -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 %}