@panoramax/web-viewer 4.4.0-develop-26884d68 → 4.4.0-develop-e873def3

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.
@@ -8,7 +8,7 @@ import PACKAGE_JSON from "../../../package.json" with { type: "json" };
8
8
  import BasicStyles from "./Basic.css" with { type: "css" };
9
9
  document.adoptedStyleSheets.push(BasicStyles);
10
10
 
11
- const __COMMIT_HASH__ = "26884d6";
11
+ const __COMMIT_HASH__ = "e873def";
12
12
 
13
13
  /**
14
14
  * Event for overlaying menu opening
@@ -1,7 +1,10 @@
1
1
  import { LitElement, css, html } from "lit";
2
+ import { svgToImg } from "../../utils/utils.js";
3
+ const SwitchBigSVG = await fetch(new URL("../../img/switch_big.svg", import.meta.url).href).then(res => res.text());
4
+ const SwitchMiniSVG = await fetch(new URL("../../img/switch_mini.svg", import.meta.url).href).then(res => res.text());
2
5
 
3
- const SwitchBig = new URL("../../img/switch_big.svg", import.meta.url).href;
4
- const SwitchMini = new URL("../../img/switch_mini.svg", import.meta.url).href;
6
+ const SwitchBig = svgToImg(SwitchBigSVG);
7
+ const SwitchMini = svgToImg(SwitchMiniSVG);
5
8
 
6
9
  /**
7
10
  * Mini layout allows to show a reduced or collapsed component in a corner of a main component.
@@ -98,7 +101,7 @@ export default class Mini extends LitElement {
98
101
  style="top: 0; right: 0"
99
102
  @click=${onExpand}
100
103
  >
101
- <img src=${SwitchBig} alt="" />
104
+ ${SwitchBig}
102
105
  ${this._parent?._t.pnx.expand}
103
106
  </pnx-button>
104
107
 
@@ -108,7 +111,7 @@ export default class Mini extends LitElement {
108
111
  style="bottom: 0; left: 0"
109
112
  @click=${() => this.collapsed = true}
110
113
  >
111
- <img src=${SwitchMini} alt="" />
114
+ ${SwitchMini}
112
115
  </pnx-button>
113
116
  `;
114
117
  }
@@ -1,8 +1,8 @@
1
1
  import { LitElement, css, html, nothing, unsafeCSS } from "lit";
2
2
  import { inRangeRandom } from "../../utils/utils.js";
3
3
 
4
- const LogoDead = new URL("../../img/logo_dead.svg", import.meta.url).href;
5
- const LoaderBg = new URL("../../img/loader_base.jpg", import.meta.url).href;
4
+ const LogoDead = await fetch(new URL("../../img/logo_dead.svg", import.meta.url).href).then(res => res.text());
5
+ const LoaderBg = await fetch(new URL("../../img/loader_base.jpg", import.meta.url).href).then(res => res.text());
6
6
 
7
7
  /**
8
8
  * Loader component display a full page covering for user waiting.
@@ -4,6 +4,7 @@ import {
4
4
  import SemanticsMapProtocol from "../../utils/SemanticsMapProtocol.js";
5
5
  import PanoraMapProtocol from "../../utils/PanoraMapProtocol.js";
6
6
  import { DISABLED_LEVEL, initIndoorEqualOnMap } from "../../utils/indoor.js";
7
+ import { svgToImg } from "../../utils/utils.js";
7
8
  import MapStyles from "./Map.css" with { type: "css" };
8
9
  document.adoptedStyleSheets.push(MapStyles);
9
10
 
@@ -19,8 +20,8 @@ maplibregl.addProtocol("panora", new PanoraMapProtocol().tile());
19
20
  // eslint-disable-next-line no-undef
20
21
  maplibregl.addProtocol("panoras", new PanoraMapProtocol().tile());
21
22
 
22
- const MarkerBaseSVG = new URL("../../img/marker.svg", import.meta.url).href;
23
- const MarkerSelectedSVG = new URL("../../img/marker_blue.svg", import.meta.url).href;
23
+ const MarkerBaseSVG = await fetch(new URL("../../img/marker.svg", import.meta.url).href).then(res => res.text());
24
+ const MarkerSelectedSVG = await fetch(new URL("../../img/marker_blue.svg", import.meta.url).href).then(res => res.text());
24
25
 
25
26
 
26
27
  /**
@@ -326,7 +327,7 @@ export default class Map extends maplibregl.Map {
326
327
  ].forEach(m => {
327
328
  const img = new Image(64, 64);
328
329
  img.onload = () => this.addImage(m.id, img);
329
- img.src = m.img;
330
+ svgToImg(m.img, img);
330
331
  });
331
332
  }
332
333
 
@@ -714,12 +715,9 @@ export default class Map extends maplibregl.Map {
714
715
  * @memberof Panoramax.components.ui.Map#
715
716
  */
716
717
  _getPictureMarker(selected = true) {
717
- const img = document.createElement("img");
718
- img.src = selected ? MarkerSelectedSVG : MarkerBaseSVG;
719
- img.alt = "";
720
718
  // eslint-disable-next-line no-undef
721
719
  return new maplibregl.Marker({
722
- element: img,
720
+ element: svgToImg(selected ? MarkerSelectedSVG : MarkerBaseSVG),
723
721
  picId: null
724
722
  })
725
723
  // Only picMarker could be draggable, don't for picMarkerPreview.
@@ -13,8 +13,8 @@ import PhotoAdapter from "../../utils/PhotoAdapter.js";
13
13
  import PhotoStyles from "./Photo.css" with { type: "css" };
14
14
  document.adoptedStyleSheets.push(PhotoStyles);
15
15
 
16
- const LogoDead = new URL("../../img/logo_dead.svg", import.meta.url).href;
17
- const LoaderImgBase = new URL("../../img/loader_base.jpg", import.meta.url).href;
16
+ const LogoDead = await fetch(new URL("../../img/logo_dead.svg", import.meta.url).href).then(res => res.text());
17
+ const LoaderImgBase = await fetch(new URL("../../img/loader_base.jpg", import.meta.url).href).then(res => res.text());
18
18
 
19
19
 
20
20
  // Default panorama (logo)
@@ -4,8 +4,8 @@ import { fa, onceParentAvailable } from "../../../utils/widgets.js";
4
4
  import { faInfoCircle } from "@fortawesome/free-solid-svg-icons";
5
5
  import { classMap } from "lit/directives/class-map.js";
6
6
  import { PanoramaxWebsiteURL } from "../../../utils/services.js";
7
-
8
- const PanoramaxImg = new URL("../../../img/panoramax.svg", import.meta.url).href;
7
+ import { svgToImg } from "../../../utils/utils.js";
8
+ const PanoramaxImg = await fetch(new URL("../../../img/panoramax.svg", import.meta.url).href).then(res => res.text());
9
9
 
10
10
  /**
11
11
  * Legend widget, handling switch between map and photo components.
@@ -137,12 +137,15 @@ export default class Legend extends LitElement {
137
137
  "pnx-legend-light": this.light,
138
138
  };
139
139
 
140
+ const logo = svgToImg(PanoramaxImg);
141
+ logo.classList.add("logo");
142
+
140
143
  return html`<div class=${classMap(classes)} part="panel">
141
144
  <div
142
145
  class="presentation"
143
146
  style=${!this.light && this.focus != "map" && this.picture ? "display: none": ""}
144
147
  >
145
- <img class="logo" src=${PanoramaxImg} alt="" />
148
+ ${logo}
146
149
 
147
150
  ${this.light ? html`
148
151
  &copy; <a
@@ -38,6 +38,13 @@
38
38
  "license": "MIT",
39
39
  "devDependencies": {
40
40
  "@eslint/js": "^9.39.4",
41
+ "@rollup/plugin-commonjs": "^29.0.2",
42
+ "@rollup/plugin-image": "^3.0.3",
43
+ "@rollup/plugin-json": "^6.1.0",
44
+ "@rollup/plugin-node-resolve": "^16.0.3",
45
+ "@rollup/plugin-replace": "^6.0.3",
46
+ "@rollup/plugin-terser": "^1.0.0",
47
+ "@rollup/plugin-url": "^8.0.2",
41
48
  "@web/dev-server": "^0.4.6",
42
49
  "@web/dev-server-rollup": "^0.6.4",
43
50
  "eslint": "^9.39.4",
@@ -50,6 +57,9 @@
50
57
  "jest-environment-jsdom": "^30.3.0",
51
58
  "jest-fixed-jsdom": "^0.0.11",
52
59
  "jsdoc-to-markdown": "^9.1.1",
60
+ "rollup": "^4.60.2",
61
+ "rollup-plugin-import-css": "^4.2.1",
62
+ "rollup-plugin-lit-css": "^6.0.1",
53
63
  "rollup-plugin-postcss": "^4.0.2",
54
64
  "whatwg-url": "^16.0.1"
55
65
  },
@@ -131,7 +141,9 @@
131
141
  "<rootDir>"
132
142
  ],
133
143
  "moduleNameMapper": {
134
- "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/config/jest/fileMock.js",
144
+ "\\.(eot|otf|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/config/jest/fileMock.js",
145
+ "\\.(jpg|jpeg|png|gif|webp)$": "<rootDir>/config/jest/imgMock.js",
146
+ "\\.svg$": "<rootDir>/config/jest/svgMock.js",
135
147
  "\\.css$": "identity-obj-proxy"
136
148
  },
137
149
  "setupFilesAfterEnv": [
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  COLORS, GPS_VALUES, QUALITYSCORE_GPS_VALUES,
3
3
  QUALITYSCORE_POND_GPS, QUALITYSCORE_POND_RES, QUALITYSCORE_RES_360_VALUES,
4
- QUALITYSCORE_RES_FLAT_VALUES, QUALITYSCORE_VALUES, isNullId
4
+ QUALITYSCORE_RES_FLAT_VALUES, QUALITYSCORE_VALUES, isNullId, svgToImg,
5
5
  } from "./utils.js";
6
6
 
7
- const LoaderImg = new URL("../img/marker.svg", import.meta.url).href;
7
+ const LoaderImg = await fetch(new URL("../img/marker.svg", import.meta.url).href).then(res => res.text());
8
8
 
9
9
  export const RASTER_LAYER_ID = "pnx-aerial";
10
10
 
@@ -217,7 +217,7 @@ export const MAP_THEMES_STYLES = {
217
217
  */
218
218
  export function getThumbGif(lang) {
219
219
  const thumbGif = document.createElement("img");
220
- thumbGif.src = LoaderImg;
220
+ svgToImg(LoaderImg, thumbGif);
221
221
  thumbGif.alt = lang.loading;
222
222
  thumbGif.title = lang.loading;
223
223
  thumbGif.classList.add("pnx-map-thumb", "pnx-map-thumb-loader");
@@ -1,5 +1,4 @@
1
1
  import { COLORS, getArrow, getDistance, getSimplifiedAngle, svgToPSVLink } from "./utils.js";
2
-
3
2
  const ArrowTriangleSVG = await fetch(new URL("../img/arrow_triangle.svg", import.meta.url).href).then(res => res.text());
4
3
  const ArrowTurnSVG = await fetch(new URL("../img/arrow_turn.svg", import.meta.url).href).then(res => res.text());
5
4
  const ArrowTriangle = svgToPSVLink(ArrowTriangleSVG, "white");
@@ -2,8 +2,8 @@ import { html } from "lit";
2
2
  import { OSMURL, OSMWikiURL, PanoramaxPresetsURL, WikidataAPIURL, WikidataURL } from "./services.js";
3
3
  import { getBestLabel } from "./i18n.js";
4
4
 
5
- const logoOsm = new URL("../img/osm.svg", import.meta.url).href;
6
- const logoWd = new URL("../img/wd.svg", import.meta.url).href;
5
+ const logoOsm = await fetch(new URL("../img/osm.svg", import.meta.url).href).then(res => res.text());
6
+ const logoWd = await fetch(new URL("../img/wd.svg", import.meta.url).href).then(res => res.text());
7
7
 
8
8
 
9
9
  // List of [ Overlay ID, API filter, Maplibre Style, Sprites ]
@@ -92,6 +92,26 @@ export function getDistance(from, to) {
92
92
  return Math.sqrt(dx*dx + dy*dy);
93
93
  }
94
94
 
95
+ export function svgToImg(svg, img = null) {
96
+ if(svg.constructor.name === "HTMLImageElement") {
97
+ if(img) {
98
+ svg.width = img.width;
99
+ svg.height = img.height;
100
+ svg.onload = img.onload;
101
+ }
102
+ return svg;
103
+ }
104
+ else if(typeof svg === "string") {
105
+ if(!img) {
106
+ img = new Image();
107
+ img.alt = "";
108
+ }
109
+ if(svg.startsWith("<?xml")) { svg = URL.createObjectURL(new Blob([svg], {type: 'image/svg+xml'})); }
110
+ img.src = svg;
111
+ return img;
112
+ }
113
+ }
114
+
95
115
  /**
96
116
  * Transforms a Base64 SVG string into a DOM img element.
97
117
  * @param {string} svg The SVG as Base64 string
@@ -100,6 +120,7 @@ export function getDistance(from, to) {
100
120
  */
101
121
  export function svgToPSVLink(svg, fillColor) {
102
122
  try {
123
+ if(svg.startsWith("data:image/svg+xml,")) { svg = decodeURIComponent(svg.replace("data:image/svg+xml,", "")); }
103
124
  if(!svg.startsWith("<svg")) { throw new Error(); }
104
125
  const svgXml = (new DOMParser()).parseFromString(svg, "image/svg+xml").childNodes[0];
105
126
  const btn = document.createElement("button");
@@ -110,10 +131,7 @@ export function svgToPSVLink(svg, fillColor) {
110
131
  }
111
132
 
112
133
  catch(e) {
113
- const img = document.createElement("img");
114
- img.src = svg;
115
- img.alt = "";
116
- return img;
134
+ return svgToImg(svg);
117
135
  }
118
136
  }
119
137
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@panoramax/web-viewer",
3
- "version": "4.4.0-develop-26884d68",
3
+ "version": "4.4.0-develop-e873def3",
4
4
  "description": "Panoramax web viewer for geolocated pictures",
5
5
  "main": "./build/index.js",
6
6
  "type": "module",
@@ -38,6 +38,13 @@
38
38
  "license": "MIT",
39
39
  "devDependencies": {
40
40
  "@eslint/js": "^9.39.4",
41
+ "@rollup/plugin-commonjs": "^29.0.2",
42
+ "@rollup/plugin-image": "^3.0.3",
43
+ "@rollup/plugin-json": "^6.1.0",
44
+ "@rollup/plugin-node-resolve": "^16.0.3",
45
+ "@rollup/plugin-replace": "^6.0.3",
46
+ "@rollup/plugin-terser": "^1.0.0",
47
+ "@rollup/plugin-url": "^8.0.2",
41
48
  "@web/dev-server": "^0.4.6",
42
49
  "@web/dev-server-rollup": "^0.6.4",
43
50
  "eslint": "^9.39.4",
@@ -50,6 +57,9 @@
50
57
  "jest-environment-jsdom": "^30.3.0",
51
58
  "jest-fixed-jsdom": "^0.0.11",
52
59
  "jsdoc-to-markdown": "^9.1.1",
60
+ "rollup": "^4.60.2",
61
+ "rollup-plugin-import-css": "^4.2.1",
62
+ "rollup-plugin-lit-css": "^6.0.1",
53
63
  "rollup-plugin-postcss": "^4.0.2",
54
64
  "whatwg-url": "^16.0.1"
55
65
  },
@@ -131,7 +141,9 @@
131
141
  "<rootDir>"
132
142
  ],
133
143
  "moduleNameMapper": {
134
- "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/config/jest/fileMock.js",
144
+ "\\.(eot|otf|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/config/jest/fileMock.js",
145
+ "\\.(jpg|jpeg|png|gif|webp)$": "<rootDir>/config/jest/imgMock.js",
146
+ "\\.svg$": "<rootDir>/config/jest/svgMock.js",
135
147
  "\\.css$": "identity-obj-proxy"
136
148
  },
137
149
  "setupFilesAfterEnv": [