mirror of
https://github.com/tabler/tabler.git
synced 2026-10-12 05:06:55 +04:00
Move to MapLibre GL 6, loaded as an ES module
- 5.x has a critical XSS advisory (GHSA-jrc7-96c5-q579), fixed only in 6.4.1+
This commit is contained in:
1 parent
c60ea8e5da
commit
b135a40064
8 files changed
+73
-52
No files matched your search
+3
-2
@@ -57,8 +57,9 @@
|
||||
},
|
||||
"maplibre-gl": {
|
||||
"npm": "maplibre-gl",
|
||||
"js": ["dist/maplibre-gl.js"],
|
||||
"css": ["dist/maplibre-gl.css"]
|
||||
"module": { "file": "dist/maplibre-gl.mjs", "global": "maplibregl" },
|
||||
"css": ["dist/maplibre-gl.css"],
|
||||
"extra": ["dist/maplibre-gl.mjs", "dist/maplibre-gl-shared.mjs", "dist/maplibre-gl-worker.mjs"]
|
||||
},
|
||||
"jsvectormap": {
|
||||
"npm": "jsvectormap",
|
||||
|
||||
+1
-1
@@ -276,7 +276,7 @@
|
||||
"jsvectormap": "^1.7.0",
|
||||
"list.js": "^2.3.1",
|
||||
"litepicker": "^2.0.12",
|
||||
"maplibre-gl": "^5.24.0",
|
||||
"maplibre-gl": "^6.11.2",
|
||||
"nouislider": "^15.8.1",
|
||||
"playwright": "1.62.1",
|
||||
"plyr": "^3.8.4",
|
||||
|
||||
@@ -48,20 +48,38 @@ The demos load their map tiles from [OpenFreeMap](https://openfreemap.org/). It
|
||||
|
||||
## Installation
|
||||
|
||||
Install MapLibre GL JS with npm. Tabler uses version 5, the last one that ships a classic script file:
|
||||
|
||||
```bash
|
||||
npm install maplibre-gl@5
|
||||
```
|
||||
|
||||
Or include it from a CDN. You need two files: the stylesheet and the library.
|
||||
MapLibre GL JS is published as an ES module. Tabler uses version 6. Load the stylesheet, then import the library in a module script:
|
||||
|
||||
<Code
|
||||
lang="html"
|
||||
code={`<link rel="stylesheet" href="${site.cdnUrl}/dist/libs/maplibre-gl/dist/maplibre-gl.css" />
|
||||
<script src="${site.cdnUrl}/dist/libs/maplibre-gl/dist/maplibre-gl.js"></script>`}
|
||||
<script type="module">
|
||||
import * as maplibregl from '${site.cdnUrl}/dist/libs/maplibre-gl/dist/maplibre-gl.mjs'
|
||||
|
||||
// Makes the library available to the other scripts on the page
|
||||
window.maplibregl = maplibregl
|
||||
</script>`}
|
||||
/>
|
||||
|
||||
A module script runs before the `DOMContentLoaded` event, so the code examples on this page can use the `maplibregl` global. The library loads two more files from the same folder, `maplibre-gl-shared.mjs` and `maplibre-gl-worker.mjs`, so keep the three together when you host them yourself.
|
||||
|
||||
With a bundler, install the package and import it in your code:
|
||||
|
||||
```bash
|
||||
npm install maplibre-gl
|
||||
```
|
||||
|
||||
```js
|
||||
import * as maplibregl from 'maplibre-gl'
|
||||
import 'maplibre-gl/dist/maplibre-gl.css'
|
||||
```
|
||||
|
||||
<Danger title="Use version 6.4.1 or newer">
|
||||
Older versions, including all of version 5, have a known security issue in the code that cleans the attribution text.
|
||||
</Danger>
|
||||
|
||||
Browsers do not load ES modules from a page opened straight from the disk. Use a local server to see the maps while you work.
|
||||
|
||||
Tabler styles the map controls, popups and attribution to match the interface, in light and dark mode. These styles are in `tabler-vendors.css`, so load it after the MapLibre stylesheet:
|
||||
|
||||
<Code
|
||||
|
||||
@@ -142,7 +142,7 @@ const editFilePath =
|
||||
|
||||
// docs-libs for this page. In dev, file names stay unchanged
|
||||
// (e.g. dist/plyr.min.js keeps .min).
|
||||
type Lib = { npm?: string; js?: string[]; css?: string[] };
|
||||
type Lib = { npm?: string; js?: string[]; css?: string[]; module?: { file: string; global: string } };
|
||||
const libEntries = Object.entries(libs as Record<string, Lib>);
|
||||
const libUrl = (lib: Lib, file: string) =>
|
||||
isExternal(file)
|
||||
@@ -151,6 +151,9 @@ const libUrl = (lib: Lib, file: string) =>
|
||||
const docsLibCss = libEntries
|
||||
.filter(([name]) => docsLibs.includes(name))
|
||||
.flatMap(([, lib]) => (lib.css ?? []).map((file) => libUrl(lib, file)));
|
||||
const docsLibModules = libEntries
|
||||
.filter(([name]) => docsLibs.includes(name))
|
||||
.flatMap(([, lib]) => (lib.module ? [`import * as lib from '${libUrl(lib, lib.module.file)}'; window.${lib.module.global} = lib`] : []));
|
||||
const docsLibJs = libEntries
|
||||
.filter(([name]) => docsLibs.includes(name))
|
||||
.flatMap(([, lib]) => (lib.js ?? []).map((file) => libUrl(lib, file)));
|
||||
@@ -517,6 +520,7 @@ const relatedPages = await Promise.all(
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
{docsLibModules.map((code) => <Fragment set:html={`<script type="module">${code}</script>`} />)}
|
||||
|
||||
|
||||
<!-- BEGIN GLOBAL MANDATORY SCRIPTS -->
|
||||
|
||||
Generated
+24
-37
@@ -199,8 +199,8 @@ importers:
|
||||
specifier: ^2.0.12
|
||||
version: 2.0.12
|
||||
maplibre-gl:
|
||||
specifier: ^5.24.0
|
||||
version: 5.24.0
|
||||
specifier: ^6.11.2
|
||||
version: 6.11.2
|
||||
nouislider:
|
||||
specifier: ^15.8.1
|
||||
version: 15.8.1
|
||||
@@ -1289,24 +1289,17 @@ packages:
|
||||
'@mapbox/tiny-sdf@2.2.0':
|
||||
resolution: {integrity: sha512-LVL4wgI9YAum5V+LNVQO6QgFBPw7/MIIY4XJPNsPDMrjEwcE+JfKk1LuIl8GnF197ejVdC9QdPaxrx5gfgdGXg==}
|
||||
|
||||
'@mapbox/unitbezier@0.0.1':
|
||||
resolution: {integrity: sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw==}
|
||||
|
||||
'@mapbox/unitbezier@1.0.0':
|
||||
resolution: {integrity: sha512-fqd515fjBmANKGGsQ286E2Wvj/XvDFpGzwJxq4CI6jMQue6Oy04uCKp+JWKF00xRTmk6cEu1jPJ9p3xqH8YWqQ==}
|
||||
|
||||
'@mapbox/vector-tile@2.0.5':
|
||||
resolution: {integrity: sha512-pXj8m7KTsqZt+1jsE0xIpGvqTSbblfkuEJL/NJmNePMtEwxO8V3XMDo9WMSfDeqHvCtBI9Lmt4mGcGR10zecmw==}
|
||||
|
||||
'@mapbox/whoots-js@3.1.0':
|
||||
resolution: {integrity: sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
'@mapbox/vector-tile@3.0.0':
|
||||
resolution: {integrity: sha512-Qf10S1uIHMk20ri/IVBnpS+esUEkVaR5Hftmz88jTInrpmWgPGJfPe3LVjjlE77trLx8tH6qjTG7uWH9hIq/0Q==}
|
||||
|
||||
'@maplibre/geojson-vt@6.1.1':
|
||||
resolution: {integrity: sha512-FVMOcmSP/yqol45t7StApEyTL5/vmqBCuFhH9n+fFuINenhaX+YgHHIt1yJ86S8kln3uJLcMvmEU2cfn6E2eCQ==}
|
||||
|
||||
'@maplibre/maplibre-gl-style-spec@24.10.0':
|
||||
resolution: {integrity: sha512-lichxSiagMEBBrqHF0trtMQH9RKh+9jUlIJl0qW0QHvt2H/tbvUWdE+ZzI2Jd0/pT7j/iavLonlPu7EQ/ixTOw==}
|
||||
'@maplibre/maplibre-gl-style-spec@26.4.4':
|
||||
resolution: {integrity: sha512-hG4RZR4PBd/+6A3ODdZ3AnQRF106ZQk1y3bhwDg8bH/A4Oz2tnRUJVVWs9BZa6gXZ1d3UKe89C+Mm+olGBELvA==}
|
||||
hasBin: true
|
||||
|
||||
'@maplibre/mlt@1.3.0':
|
||||
@@ -2210,6 +2203,9 @@ packages:
|
||||
engines: {node: '>=6.0.0'}
|
||||
hasBin: true
|
||||
|
||||
bidi-js@1.1.0:
|
||||
resolution: {integrity: sha512-fX1Onk0tdVPC7obPWB5EbJ1z7NVhLq4m2xZLq2YXBkxzMXIGRpNMU88n0EPgWseKl12J7zXs7qrDxPK4sRs2fg==}
|
||||
|
||||
binary-extensions@2.3.0:
|
||||
resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -3498,8 +3494,8 @@ packages:
|
||||
make-synchronized@0.8.0:
|
||||
resolution: {integrity: sha512-DZu4lwc0ffoFz581BSQa/BJl+1ZqIkoRQ+VejMlH0VrP4E86StAODnZujZ4sepumQj8rcP7wUnUBGM8Gu+zKUA==}
|
||||
|
||||
maplibre-gl@5.24.0:
|
||||
resolution: {integrity: sha512-ALyFxgtd5R+65UqZ/++lOqwWcC0SNho9c27fYSyLmG7AfnAul2o46F05aDJGPbFU57wos9dgcIySHs0Xe6ia3A==}
|
||||
maplibre-gl@6.11.2:
|
||||
resolution: {integrity: sha512-Xh06pxoipjX/Ad1sUPGhiNh9go9naCNGZZ1IJm3sIeqK1kYGuMaMDSTIGDQ2igOLfVyukJU7kvEOA089VO7Z7g==}
|
||||
engines: {node: '>=16.14.0', npm: '>=8.1.0'}
|
||||
|
||||
markdown-extensions@2.0.0:
|
||||
@@ -3964,10 +3960,6 @@ packages:
|
||||
pathe@2.0.3:
|
||||
resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
|
||||
|
||||
pbf@4.0.2:
|
||||
resolution: {integrity: sha512-J0ajxARhZfpUEebxYs1vhMGMuLSXtBe1e+fFPDrf2uA2hgo+UshKfNUWOz92HJNz6/NFEXseQPddnHkTreWRqg==}
|
||||
hasBin: true
|
||||
|
||||
pbf@5.1.2:
|
||||
resolution: {integrity: sha512-mnvGdvOrIvJOBGUEdGkrVXjN8E/VkIJCkf2eS1DH2yv82ORUlLttmDt0rWY38yYZmVwciZwBUvHM20qxBZf40w==}
|
||||
hasBin: true
|
||||
@@ -6153,23 +6145,19 @@ snapshots:
|
||||
|
||||
'@mapbox/tiny-sdf@2.2.0': {}
|
||||
|
||||
'@mapbox/unitbezier@0.0.1': {}
|
||||
|
||||
'@mapbox/unitbezier@1.0.0': {}
|
||||
|
||||
'@mapbox/vector-tile@2.0.5':
|
||||
'@mapbox/vector-tile@3.0.0':
|
||||
dependencies:
|
||||
'@mapbox/point-geometry': 1.1.0
|
||||
'@types/geojson': 7946.0.16
|
||||
pbf: 4.0.2
|
||||
|
||||
'@mapbox/whoots-js@3.1.0': {}
|
||||
pbf: 5.1.2
|
||||
|
||||
'@maplibre/geojson-vt@6.1.1':
|
||||
dependencies:
|
||||
kdbush: 4.1.0
|
||||
|
||||
'@maplibre/maplibre-gl-style-spec@24.10.0':
|
||||
'@maplibre/maplibre-gl-style-spec@26.4.4':
|
||||
dependencies:
|
||||
'@mapbox/jsonlint-lines-primitives': 2.0.3
|
||||
'@mapbox/unitbezier': 1.0.0
|
||||
@@ -7133,6 +7121,10 @@ snapshots:
|
||||
|
||||
baseline-browser-mapping@2.11.6: {}
|
||||
|
||||
bidi-js@1.1.0:
|
||||
dependencies:
|
||||
require-from-string: 2.0.2
|
||||
|
||||
binary-extensions@2.3.0: {}
|
||||
|
||||
bindings@1.5.0:
|
||||
@@ -8455,24 +8447,23 @@ snapshots:
|
||||
|
||||
make-synchronized@0.8.0: {}
|
||||
|
||||
maplibre-gl@5.24.0:
|
||||
maplibre-gl@6.11.2:
|
||||
dependencies:
|
||||
'@mapbox/jsonlint-lines-primitives': 2.0.3
|
||||
'@mapbox/point-geometry': 1.1.0
|
||||
'@mapbox/tiny-sdf': 2.2.0
|
||||
'@mapbox/unitbezier': 0.0.1
|
||||
'@mapbox/vector-tile': 2.0.5
|
||||
'@mapbox/whoots-js': 3.1.0
|
||||
'@mapbox/unitbezier': 1.0.0
|
||||
'@mapbox/vector-tile': 3.0.0
|
||||
'@maplibre/geojson-vt': 6.1.1
|
||||
'@maplibre/maplibre-gl-style-spec': 24.10.0
|
||||
'@maplibre/maplibre-gl-style-spec': 26.4.4
|
||||
'@maplibre/mlt': 1.3.0
|
||||
'@maplibre/vt-pbf': 4.3.2
|
||||
'@types/geojson': 7946.0.16
|
||||
bidi-js: 1.1.0
|
||||
earcut: 3.2.4
|
||||
gl-matrix: 3.4.4
|
||||
kdbush: 4.1.0
|
||||
murmurhash-js: 1.0.0
|
||||
pbf: 4.0.2
|
||||
pbf: 5.1.2
|
||||
potpack: 2.1.0
|
||||
quickselect: 3.0.0
|
||||
tinyqueue: 3.0.0
|
||||
@@ -9227,10 +9218,6 @@ snapshots:
|
||||
|
||||
pathe@2.0.3: {}
|
||||
|
||||
pbf@4.0.2:
|
||||
dependencies:
|
||||
resolve-protobuf-schema: 2.1.0
|
||||
|
||||
pbf@5.1.2:
|
||||
dependencies:
|
||||
resolve-protobuf-schema: 2.1.0
|
||||
|
||||
@@ -73,11 +73,13 @@ const themeAttributes = themeDataAttributes({ ...theme, 'navbar-position': navba
|
||||
// whatever core's own watcher last emitted, which is unminified.
|
||||
const min = import.meta.env.DEV ? '' : '.min'
|
||||
|
||||
type Lib = { npm?: string; js?: string[]; css?: string[] }
|
||||
type Lib = { npm?: string; js?: string[]; css?: string[]; module?: { file: string; global: string } }
|
||||
const pageLibEntries = Object.entries(libs as Record<string, Lib>).filter(([name]) => pageLibs.includes(name))
|
||||
const libHref = (lib: Lib, file: string) => `/dist/libs/${lib.npm}/${file}`
|
||||
const libCssFiles = pageLibEntries.flatMap(([, lib]) => (lib.css ?? []).map((file) => libHref(lib, file)))
|
||||
const libJsFiles = pageLibEntries.flatMap(([, lib]) => (lib.js ?? []).map((file) => libHref(lib, file)))
|
||||
// ES-module-only libraries: imported in a module script and exposed as a global (see BaseLayout)
|
||||
const libModules = pageLibEntries.flatMap(([, lib]) => (lib.module ? [`import * as lib from '${libHref(lib, lib.module.file)}'; window.${lib.module.global} = lib`] : []))
|
||||
---
|
||||
|
||||
<!doctype html>
|
||||
@@ -177,6 +179,7 @@ const libJsFiles = pageLibEntries.flatMap(([, lib]) => (lib.js ?? []).map((file)
|
||||
</nav>
|
||||
|
||||
{libJsFiles.map((src) => <script is:inline src={src} defer />)}
|
||||
{libModules.map((code) => <Fragment set:html={`<script type="module">${code}</script>`} />)}
|
||||
<script is:inline src={`/dist/js/tabler${min}.js`} defer></script>
|
||||
|
||||
<PageScripts />
|
||||
|
||||
@@ -45,11 +45,13 @@ const rtlSuffix = rtl ? '.rtl' : ''
|
||||
// build instead of hardcoding one variant.
|
||||
const min = import.meta.env.DEV ? '' : '.min'
|
||||
|
||||
type Lib = { npm?: string; js?: string[]; css?: string[] }
|
||||
type Lib = { npm?: string; js?: string[]; css?: string[]; module?: { file: string; global: string } }
|
||||
const pageLibEntries = Object.entries(libs as Record<string, Lib>).filter(([name]) => pageLibs.includes(name))
|
||||
const libHref = (lib: Lib, file: string) => `/dist/libs/${lib.npm}/${file}`
|
||||
const libCssFiles = pageLibEntries.flatMap(([, lib]) => (lib.css ?? []).map((file) => libHref(lib, file)))
|
||||
const libJsFiles = pageLibEntries.flatMap(([, lib]) => (lib.js ?? []).map((file) => libHref(lib, file)))
|
||||
// ES-module-only libraries: imported in a module script and exposed as a global (see BaseLayout)
|
||||
const libModules = pageLibEntries.flatMap(([, lib]) => (lib.module ? [`import * as lib from '${libHref(lib, lib.module.file)}'; window.${lib.module.global} = lib`] : []))
|
||||
---
|
||||
|
||||
<!doctype html>
|
||||
@@ -168,6 +170,7 @@ const libJsFiles = pageLibEntries.flatMap(([, lib]) => (lib.js ?? []).map((file)
|
||||
</div>
|
||||
|
||||
{libJsFiles.map((src) => <script is:inline src={src} defer />)}
|
||||
{libModules.map((code) => <Fragment set:html={`<script type="module">${code}</script>`} />)}
|
||||
<script is:inline src={`/dist/js/tabler${min}.js`} defer></script>
|
||||
|
||||
<!-- components that render via CaptureScript (e.g. Chart) queue their init script
|
||||
|
||||
@@ -39,7 +39,7 @@ const isProduction = process.env.VERCEL_ENV === 'production'
|
||||
// RTL swaps tabler/plugin stylesheets for their .rtl.css variants (demo stays LTR)
|
||||
const rtlSuffix = rtl ? '.rtl' : ''
|
||||
|
||||
type Lib = { npm?: string; js?: string[]; css?: string[]; head?: boolean }
|
||||
type Lib = { npm?: string; js?: string[]; css?: string[]; head?: boolean; module?: { file: string; global: string } }
|
||||
const unknownLibs = pageLibs.filter((name) => !(name in libs))
|
||||
if (unknownLibs.length > 0) {
|
||||
throw new Error(`BaseLayout: unknown pageLibs ${unknownLibs.map((name) => `"${name}"`).join(', ')} — use a key from core/libs.json`)
|
||||
@@ -48,6 +48,10 @@ const pageLibEntries = Object.entries(libs as Record<string, Lib>).filter(([name
|
||||
// External URLs (http/https) are emitted verbatim; local files as ./dist/libs/{npm}/{file}.
|
||||
const libHref = (lib: Lib, file: string) => (/^https?:\/\//.test(file) ? file : `${base}/dist/libs/${lib.npm}/${file}`)
|
||||
const libCssFiles = pageLibEntries.flatMap(([, lib]) => (lib.css ?? []).map((file) => libHref(lib, file)))
|
||||
// Libraries published as ES modules only: imported in a module script and
|
||||
// handed to the classic page scripts as a global. Module scripts are deferred,
|
||||
// so the global is set before DOMContentLoaded.
|
||||
const libModules = pageLibEntries.flatMap(([, lib]) => (lib.module ? [`import * as lib from '${libHref(lib, lib.module.file)}'\n window.${lib.module.global} = lib`] : []))
|
||||
const libJsFiles = (head: boolean) => pageLibEntries.filter(([, lib]) => Boolean(lib.head) === head).flatMap(([, lib]) => (lib.js ?? []).map((file) => libHref(lib, file)))
|
||||
---
|
||||
|
||||
@@ -129,6 +133,7 @@ const libJsFiles = (head: boolean) => pageLibEntries.filter(([, lib]) => Boolean
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
{libModules.map((code) => <Fragment set:html={`<script type="module">\n ${code}\n </script>`} />)}
|
||||
|
||||
<!-- BEGIN GLOBAL MANDATORY SCRIPTS -->
|
||||
<script is:inline src={`${base}/dist/js/tabler${min}.js`} defer></script>
|
||||
|
||||
Reference in new issue
Block a user