leaflet-html 0.3.4 → 0.3.6

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 (51) hide show
  1. package/package.json +5 -1
  2. package/.github/workflows/master.yml +0 -15
  3. package/.github/workflows/npm-publish.yml +0 -37
  4. package/.prettierignore +0 -2
  5. package/.prettierrc +0 -1
  6. package/docs/config.toml +0 -16
  7. package/docs/content/_index.md +0 -89
  8. package/docs/content/articles/_index.md +0 -5
  9. package/docs/content/articles/basic.md +0 -110
  10. package/docs/content/articles/htmx.md +0 -84
  11. package/docs/content/articles/icons.md +0 -47
  12. package/docs/content/articles/style.md +0 -14
  13. package/docs/public/icons/leaf-green.png +0 -0
  14. package/docs/public/icons/leaf-orange.png +0 -0
  15. package/docs/public/icons/leaf-red.png +0 -0
  16. package/docs/public/icons/leaf-shadow.png +0 -0
  17. package/docs/static/htmx/clicked.html +0 -1
  18. package/docs/static/htmx/marker.html +0 -3
  19. package/docs/static/htmx/tile-esri.html +0 -3
  20. package/docs/static/htmx/tile-osm.html +0 -4
  21. package/docs/static/htmx/tile-voyager.html +0 -4
  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/static/style.css +0 -48
  27. package/docs/templates/article-page.html +0 -8
  28. package/docs/templates/article.html +0 -12
  29. package/docs/templates/base.html +0 -43
  30. package/docs/templates/index.html +0 -6
  31. package/docs/templates/shortcodes/url.html +0 -1
  32. package/example/geojson/index.html +0 -44
  33. package/example/index.html +0 -113
  34. package/example/overlays/index.html +0 -78
  35. package/src/events.js +0 -3
  36. package/src/index.js +0 -33
  37. package/src/l-base-layers.js +0 -16
  38. package/src/l-control-layers.js +0 -39
  39. package/src/l-geojson.js +0 -27
  40. package/src/l-icon.js +0 -124
  41. package/src/l-image-overlay.js +0 -54
  42. package/src/l-lat-lng-bounds.js +0 -21
  43. package/src/l-layer-group.js +0 -51
  44. package/src/l-layer.js +0 -8
  45. package/src/l-map.js +0 -56
  46. package/src/l-marker.js +0 -95
  47. package/src/l-overlay-layers.js +0 -16
  48. package/src/l-popup.js +0 -22
  49. package/src/l-tile-layer.js +0 -32
  50. package/src/l-video-overlay.js +0 -34
  51. package/vite.config.js +0 -7
@@ -1,113 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <title>Leaflet HTML</title>
5
- <meta charset="utf-8" />
6
- <link
7
- rel="stylesheet"
8
- href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
9
- integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
10
- crossorigin=""
11
- />
12
- <script type="importmap">
13
- {
14
- "imports": {
15
- "leaflet": "https://unpkg.com/leaflet@1.9.4/dist/leaflet-src.esm.js"
16
- }
17
- }
18
- </script>
19
- <script
20
- src="/src/index.js"
21
- type="module"
22
- defer
23
- ></script>
24
- <style>
25
- * {
26
- margin: 0;
27
- }
28
-
29
- l-map {
30
- block-size: 100vh;
31
- isolation: isolate;
32
- z-index: 1;
33
- }
34
-
35
- .btn-group {
36
- z-index: 2;
37
- position: absolute;
38
- bottom: 0;
39
- left: 0;
40
- margin: 1rem;
41
- }
42
-
43
- button {
44
- padding: 1rem;
45
- background-color: #337;
46
- color: white;
47
- border-radius: 0.25rem;
48
- cursor: pointer;
49
- font-size: 1.2rem;
50
- }
51
-
52
- body {
53
- display: grid;
54
- grid-template-columns: 1fr 1fr;
55
- }
56
- </style>
57
- </head>
58
- <body>
59
- <l-map center="[39.61, -105.02]" zoom="10">
60
- <l-control-layers>
61
- <l-base-layers>
62
- <l-tile-layer
63
- name="OpenStreetMap"
64
- url-template="https://tile.openstreetmap.org/{z}/{x}/{y}.png"
65
- attribution='&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
66
- max-zoom="12"
67
- ></l-tile-layer>
68
- <l-tile-layer
69
- name="CartoDB_Voyager"
70
- url-template="https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png"
71
- attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors &copy; <a href="https://carto.com/attributions">CARTO</a>'
72
- max-zoom="20"
73
- subdomains="abcd"
74
- ></l-tile-layer>
75
- </l-base-layers>
76
- <l-overlay-layers>
77
- <l-layer-group name="Cities">
78
- <l-marker lat-lng="[39.61, -105.02]">
79
- <l-popup content="This is Littleton, CO."></l-popup>
80
- </l-marker>
81
- <l-marker lat-lng="[39.74, -104.99]">
82
- <l-popup content="This is Denver, CO."></l-popup>
83
- </l-marker>
84
- <l-marker lat-lng="[39.73, -104.8]" opacity="0.7">
85
- <l-popup content="This is Aurora, CO."></l-popup>
86
- </l-marker>
87
- <l-marker lat-lng="[39.77, -105.23]">
88
- <l-popup content="This is Golden, CO."></l-popup>
89
- </l-marker>
90
- </l-layer-group>
91
- </l-overlay-layers>
92
- </l-control-layers>
93
- </l-map>
94
- <div class="btn-group">
95
- <button id="btn-move">Move Denver</button>
96
- <button id="btn-remove">Remove Denver</button>
97
- </div>
98
- <script type="module">
99
- // Manual tests
100
- document.getElementById("btn-remove").addEventListener("click", () => {
101
- // Remove Denver
102
- let el = document.querySelector('[lat-lng="[39.74, -104.99]"]');
103
- el.remove();
104
- });
105
- document.getElementById("btn-move").addEventListener("click", () => {
106
- // Move Denver
107
- let el = document.querySelector('[lat-lng="[39.74, -104.99]"]');
108
- el.setAttribute("lat-lng", "[39.74, -104.89]");
109
- el.setAttribute("opacity", "0.5");
110
- });
111
- </script>
112
- </body>
113
- </html>
@@ -1,78 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head lang="en">
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1" />
6
- <title>Leaflet HTML imageOverlay</title>
7
- <link
8
- rel="stylesheet"
9
- href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
10
- integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
11
- crossorigin=""
12
- />
13
- <script type="importmap">
14
- {
15
- "imports": {
16
- "leaflet": "https://unpkg.com/leaflet@1.9.4/dist/leaflet-src.esm.js"
17
- }
18
- }
19
- </script>
20
- <script type="module" src="/src/index.js"></script>
21
- <style>
22
- * {
23
- margin: 0;
24
- }
25
-
26
- l-map {
27
- display: block;
28
- block-size: 100vh;
29
- outline: 1px solid hotpink;
30
- isolation: isolate;
31
- z-index: 1;
32
- }
33
- </style>
34
- </head>
35
- <body>
36
- <l-map center="[37.8, -96]" zoom="4">
37
- <l-lat-lng-bounds
38
- bounds="[[40.799311, -74.118464], [40.68202047785919, -74.33]]"
39
- ></l-lat-lng-bounds>
40
- <l-tile-layer
41
- name="OpenStreetMap"
42
- url-template="https://tile.openstreetmap.org/{z}/{x}/{y}.png"
43
- attribution=""
44
- ></l-tile-layer>
45
- <!-- Newark -->
46
- <l-image-overlay
47
- url="https://maps.lib.utexas.edu/maps/historical/newark_nj_1922.jpg"
48
- bounds="[[40.799311, -74.118464], [40.68202047785919, -74.33]]"
49
- opacity="0.8"
50
- interactive="true"
51
- error-overlay-url="https://cdn-icons-png.flaticon.com/512/110/110686.png"
52
- alt="Image of Newark, N.J. in 1922. Source: The University of Texas at Austin, UT Libraries Map Collection."
53
- ></l-image-overlay>
54
- <!-- Hurricane Patricia -->
55
- <l-video-overlay
56
- url='["https://www.mapbox.com/bites/00188/patricia_nasa.webm", "https://www.mapbox.com/bites/00188/patricia_nasa.mp4"]'
57
- error-overlay-url="https://cdn-icons-png.flaticon.com/512/110/110686.png"
58
- bounds="[[32, -130], [13, -100]]"
59
- ></l-video-overlay>
60
- </l-map>
61
-
62
- <script>
63
- el = document.querySelector("l-lat-lng-bounds")
64
- let counter = 0
65
- document.body.addEventListener("click", () => {
66
- el.setAttribute("method", "flyToBounds")
67
- if (counter === 0) {
68
- const bounds = document.querySelector("l-video-overlay").getAttribute("bounds")
69
- el.setAttribute("bounds", bounds)
70
- } else {
71
- const bounds = document.querySelector("l-image-overlay").getAttribute("bounds")
72
- el.setAttribute("bounds", bounds)
73
- }
74
- counter += 1
75
- })
76
- </script>
77
- </body>
78
- </html>
package/src/events.js DELETED
@@ -1,3 +0,0 @@
1
- export const mapAddTo = "map:addTo";
2
- export const popupAdd = "popup:add";
3
- export const layerRemove = "layer:remove";
package/src/index.js DELETED
@@ -1,33 +0,0 @@
1
- // @ts-check
2
- import LBaseLayers from "./l-base-layers.js";
3
- import LControlLayers from "./l-control-layers.js";
4
- import LLayerGroup from "./l-layer-group.js";
5
- import LMap from "./l-map.js";
6
- import LMarker from "./l-marker.js";
7
- import LOverlayLayers from "./l-overlay-layers.js";
8
- import LPopup from "./l-popup.js";
9
- import LTileLayer from "./l-tile-layer.js";
10
- import LLatLngBounds from "./l-lat-lng-bounds.js";
11
- import LImageOverlay from "./l-image-overlay.js";
12
- import LVideoOverlay from "./l-video-overlay.js";
13
- import LGeoJSON from "./l-geojson.js";
14
- import LIcon from "./l-icon.js";
15
-
16
- const init = (() => {
17
- // Custom elements (order of definition is important)
18
- customElements.define("l-map", LMap);
19
- customElements.define("l-control-layers", LControlLayers);
20
- customElements.define("l-base-layers", LBaseLayers);
21
- customElements.define("l-overlay-layers", LOverlayLayers);
22
- customElements.define("l-layer-group", LLayerGroup);
23
- customElements.define("l-tile-layer", LTileLayer);
24
- customElements.define("l-marker", LMarker);
25
- customElements.define("l-popup", LPopup);
26
- customElements.define("l-lat-lng-bounds", LLatLngBounds);
27
- customElements.define("l-image-overlay", LImageOverlay);
28
- customElements.define("l-video-overlay", LVideoOverlay);
29
- customElements.define("l-geojson", LGeoJSON);
30
- customElements.define("l-icon", LIcon);
31
- })();
32
-
33
- export default init;
@@ -1,16 +0,0 @@
1
- // @ts-check
2
- import { mapAddTo } from "./events.js";
3
-
4
- class LBaseLayers extends HTMLElement {
5
- constructor() {
6
- super();
7
- }
8
-
9
- connectedCallback() {
10
- this.addEventListener(mapAddTo, (ev) => {
11
- ev.detail["type"] = "base";
12
- });
13
- }
14
- }
15
-
16
- export default LBaseLayers;
@@ -1,39 +0,0 @@
1
- // @ts-check
2
- /** @typedef {import("leaflet").Layer} Layer */
3
- import { control } from "leaflet";
4
- import { mapAddTo } from "./events.js";
5
-
6
- class LControlLayers extends HTMLElement {
7
- constructor() {
8
- super();
9
- }
10
-
11
- connectedCallback() {
12
- /** @type {{ [key: string]: Layer }} */
13
- const base = {};
14
- /** @type {{ [key: string]: Layer }} */
15
- const overlay = {};
16
- const controlLayers = control.layers(base, overlay);
17
-
18
- this.addEventListener(mapAddTo, (ev) => {
19
- const { type, name, layer } = ev.detail;
20
- if (type === "overlay") {
21
- controlLayers.addOverlay(layer, name);
22
- } else if (type === "base") {
23
- controlLayers.addBaseLayer(layer, name);
24
- }
25
- ev.preventDefault();
26
- });
27
-
28
- const event = new CustomEvent(mapAddTo, {
29
- cancelable: true,
30
- bubbles: true,
31
- detail: {
32
- layer: controlLayers,
33
- },
34
- });
35
- this.dispatchEvent(event);
36
- }
37
- }
38
-
39
- export default LControlLayers;
package/src/l-geojson.js DELETED
@@ -1,27 +0,0 @@
1
- // @ts-check
2
- import { geoJSON } from "leaflet";
3
- import { mapAddTo } from "./events.js";
4
-
5
- class LGeoJSON extends HTMLElement {
6
- constructor() {
7
- super();
8
- }
9
-
10
- connectedCallback() {
11
- const value = this.getAttribute("geojson");
12
- if (value !== null) {
13
- const layer = geoJSON(JSON.parse(value));
14
- this.dispatchEvent(
15
- new CustomEvent(mapAddTo, {
16
- bubbles: true,
17
- cancelable: true,
18
- detail: {
19
- layer,
20
- },
21
- }),
22
- );
23
- }
24
- }
25
- }
26
-
27
- export default LGeoJSON;
package/src/l-icon.js DELETED
@@ -1,124 +0,0 @@
1
- // @vitest-environment happy-dom
2
- import * as L from "leaflet";
3
-
4
- const camelCase = (kebab) => kebab.replace(/-./g, (x) => x[1].toUpperCase());
5
-
6
- class LIcon extends HTMLElement {
7
- constructor() {
8
- super();
9
- this.icon = null;
10
- }
11
-
12
- connectedCallback() {
13
- const options = {};
14
-
15
- // Strings
16
- let keys = [
17
- "icon-url",
18
- "icon-retina-url",
19
- "shadow-url",
20
- "shadow-retina-url",
21
- "class-name",
22
- ];
23
- keys.forEach((key) => {
24
- if (this.hasAttribute(key)) {
25
- options[camelCase(key)] = this.getAttribute(key);
26
- }
27
- });
28
-
29
- // Points
30
- let points = [
31
- "icon-anchor",
32
- "icon-size",
33
- "shadow-anchor",
34
- "shadow-size",
35
- "tooltip-anchor",
36
- "popup-anchor",
37
- ];
38
- points.forEach((key) => {
39
- if (this.hasAttribute(key)) {
40
- options[camelCase(key)] = JSON.parse(this.getAttribute(key));
41
- }
42
- });
43
-
44
- if (this.hasAttribute("cross-origin")) {
45
- options.crossOrigin = this.getAttribute("cross-origin") === "true";
46
- }
47
- this.icon = L.icon(options);
48
-
49
- const event = new CustomEvent("icon:add", {
50
- cancelable: true,
51
- bubbles: true,
52
- detail: {
53
- icon: this.icon,
54
- },
55
- });
56
- this.dispatchEvent(event);
57
- }
58
- }
59
-
60
- if (import.meta.vitest) {
61
- const { it, expect, beforeAll } = import.meta.vitest;
62
-
63
- beforeAll(() => {
64
- customElements.define("l-icon", LIcon);
65
- });
66
-
67
- it("default", () => {
68
- const el = document.createElement("l-icon");
69
- document.body.appendChild(el);
70
-
71
- let actual = el.icon;
72
- let expected = L.icon();
73
- expect(actual).toEqual(expected);
74
- });
75
-
76
- it("emits icon:add event", async () => {
77
- const el = document.createElement("l-icon");
78
- let promise = new Promise((resolve) => {
79
- el.addEventListener("icon:add", (ev) => {
80
- resolve(ev.detail.icon);
81
- });
82
- });
83
- document.body.appendChild(el);
84
- let actual = await promise;
85
- let expected = L.icon();
86
- expect(actual).toEqual(expected);
87
- });
88
-
89
- it("options", () => {
90
- const el = document.createElement("l-icon");
91
- el.setAttribute("icon-url", "url.png");
92
- el.setAttribute("icon-retina-url", "retina.png");
93
- el.setAttribute("icon-size", "[0, 0]");
94
- el.setAttribute("icon-anchor", "[0, 0]");
95
- el.setAttribute("popup-anchor", "[0, 0]");
96
- el.setAttribute("tooltip-anchor", "[0, 0]");
97
- el.setAttribute("shadow-url", "urlShadow.png");
98
- el.setAttribute("shadow-retina-url", "retinaShadow.png");
99
- el.setAttribute("shadow-size", "[0, 0]");
100
- el.setAttribute("shadow-anchor", "[0, 0]");
101
- el.setAttribute("class-name", "foo");
102
- el.setAttribute("cross-origin", "true");
103
- document.body.appendChild(el);
104
-
105
- let actual = el.icon;
106
- let expected = L.icon({
107
- iconUrl: "url.png",
108
- iconRetinaUrl: "retina.png",
109
- iconSize: [0, 0],
110
- iconAnchor: [0, 0],
111
- popupAnchor: [0, 0],
112
- tooltipAnchor: [0, 0],
113
- shadowUrl: "urlShadow.png",
114
- shadowRetinaUrl: "retinaShadow.png",
115
- shadowSize: [0, 0],
116
- shadowAnchor: [0, 0],
117
- className: "foo",
118
- crossOrigin: true,
119
- });
120
- expect(actual).toEqual(expected);
121
- });
122
- }
123
-
124
- export default LIcon;
@@ -1,54 +0,0 @@
1
- // @ts-check
2
- import { imageOverlay } from "leaflet";
3
- import { mapAddTo } from "./events.js";
4
- import LLayer from "./l-layer.js";
5
-
6
- class LImageOverlay extends LLayer {
7
- static observedAttributes = ["url", "bounds", "opacity"];
8
-
9
- constructor() {
10
- super();
11
- this.layer = null;
12
- }
13
-
14
- connectedCallback() {
15
- const url = this.getAttribute("url");
16
- if (url === null) {
17
- console.warn("attribute 'url' not set");
18
- return;
19
- }
20
- let bounds = this.getAttribute("bounds");
21
- if (bounds === null) {
22
- console.warn("attribute 'bounds' not set");
23
- return;
24
- }
25
- const options = {
26
- opacity: parseFloat(this.getAttribute("opacity") || "1.0"),
27
- alt: this.getAttribute("alt") || "",
28
- };
29
- this.layer = imageOverlay(url, JSON.parse(bounds), options);
30
- this.dispatchEvent(
31
- new CustomEvent(mapAddTo, {
32
- cancelable: true,
33
- bubbles: true,
34
- detail: {
35
- layer: this.layer,
36
- },
37
- }),
38
- );
39
- }
40
-
41
- attributeChangedCallback(name, _oldValue, newValue) {
42
- if (this.layer !== null) {
43
- if (name === "url") {
44
- this.layer.setUrl(newValue);
45
- } else if (name === "bounds") {
46
- this.layer.setBounds(JSON.parse(newValue));
47
- } else if (name === "opacity") {
48
- this.layer.setOpacity(parseFloat(newValue));
49
- }
50
- }
51
- }
52
- }
53
-
54
- export default LImageOverlay;
@@ -1,21 +0,0 @@
1
- // @ts-check
2
- class LLatLngBounds extends HTMLElement {
3
- static observedAttributes = ["bounds"];
4
-
5
- constructor() {
6
- super();
7
- }
8
-
9
- attributeChangedCallback(_name, _oldValue, newValue) {
10
- const event = new CustomEvent("map:bounds", {
11
- bubbles: true,
12
- detail: {
13
- bounds: JSON.parse(newValue),
14
- method: this.getAttribute("method") || "fitBounds",
15
- },
16
- });
17
- this.dispatchEvent(event);
18
- }
19
- }
20
-
21
- export default LLatLngBounds;
@@ -1,51 +0,0 @@
1
- // @ts-check
2
- import { layerGroup } from "leaflet";
3
- import { mapAddTo } from "./events.js";
4
- import LLayer from "./l-layer.js";
5
-
6
- class LLayerGroup extends LLayer {
7
- constructor() {
8
- super();
9
- this.layer = null;
10
- }
11
-
12
- connectedCallback() {
13
- const name = this.getAttribute("name");
14
- const group = layerGroup();
15
- this.layer = group;
16
-
17
- const event = new CustomEvent(mapAddTo, {
18
- cancelable: true,
19
- bubbles: true,
20
- detail: {
21
- layer: group,
22
- name,
23
- },
24
- });
25
- this.dispatchEvent(event);
26
-
27
- this.addEventListener(mapAddTo, (ev) => {
28
- ev.stopPropagation();
29
- group.addLayer(ev.detail.layer);
30
- });
31
-
32
- const observer = new MutationObserver(function (mutations) {
33
- mutations.forEach((mutation) => {
34
- mutation.removedNodes.forEach((node) => {
35
- if (node instanceof HTMLElement) {
36
- const leafletId = node.getAttribute("leaflet-id");
37
- if (leafletId !== null) {
38
- const layer = group.getLayer(parseInt(leafletId));
39
- if (typeof layer !== "undefined") {
40
- group.removeLayer(layer);
41
- }
42
- }
43
- }
44
- });
45
- });
46
- });
47
- observer.observe(this, { childList: true });
48
- }
49
- }
50
-
51
- export default LLayerGroup;
package/src/l-layer.js DELETED
@@ -1,8 +0,0 @@
1
- class LLayer extends HTMLElement {
2
- constructor() {
3
- super()
4
- this.layer = null
5
- }
6
- }
7
-
8
- export default LLayer
package/src/l-map.js DELETED
@@ -1,56 +0,0 @@
1
- // @ts-check
2
- import * as L from "leaflet";
3
- import { layerRemove, mapAddTo } from "./events.js";
4
- import LLayer from "./l-layer.js";
5
-
6
- class LMap extends HTMLElement {
7
- constructor() {
8
- super();
9
-
10
- this.map = null;
11
- this.addEventListener("map:bounds", (ev) => {
12
- const { bounds, method } = ev.detail;
13
- if (this.map !== null) {
14
- this.map[method](bounds);
15
- }
16
- });
17
-
18
- // Observe removed l-tile-layers
19
- const observer = new MutationObserver(function(mutations) {
20
- mutations.forEach((mutation) => {
21
- if (mutation.target instanceof LMap) {
22
- const el = mutation.target
23
- mutation.removedNodes.forEach((node) => {
24
- if (node instanceof LLayer) {
25
- if ((el.map !== null) && (node.layer !== null)) {
26
- el.map.removeLayer(node.layer)
27
- }
28
- }
29
- })
30
- }
31
- })
32
- })
33
- observer.observe(this, { childList: true })
34
- }
35
-
36
- connectedCallback() {
37
- this.map = L.map(this);
38
- const center = this.getAttribute("center");
39
- const zoom = this.getAttribute("zoom");
40
- if (center !== null && zoom !== null) {
41
- this.map.setView(JSON.parse(center), parseInt(zoom));
42
- }
43
- this.addEventListener(mapAddTo, (ev) => {
44
- const layer = ev.detail.layer;
45
- layer.addTo(this.map);
46
- });
47
-
48
- this.addEventListener(layerRemove, (ev) => {
49
- if (this.map !== null) {
50
- this.map.removeLayer(ev.detail.layer);
51
- }
52
- });
53
- }
54
- }
55
-
56
- export default LMap;