maplibre-gl 3.5.2 → 3.6.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.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "maplibre-gl",
3
3
  "description": "BSD licensed community fork of mapbox-gl, a WebGL interactive maps library",
4
- "version": "3.5.2",
4
+ "version": "3.6.1",
5
5
  "main": "dist/maplibre-gl.js",
6
6
  "style": "dist/maplibre-gl.css",
7
7
  "license": "BSD-3-Clause",
@@ -21,11 +21,11 @@
21
21
  "@mapbox/vector-tile": "^1.3.1",
22
22
  "@mapbox/whoots-js": "^3.1.0",
23
23
  "@maplibre/maplibre-gl-style-spec": "^19.3.3",
24
- "@types/geojson": "^7946.0.12",
25
- "@types/mapbox__point-geometry": "^0.1.3",
24
+ "@types/geojson": "^7946.0.13",
25
+ "@types/mapbox__point-geometry": "^0.1.4",
26
26
  "@types/mapbox__vector-tile": "^1.3.3",
27
27
  "@types/pbf": "^3.0.4",
28
- "@types/supercluster": "^7.1.2",
28
+ "@types/supercluster": "^7.1.3",
29
29
  "earcut": "^2.2.4",
30
30
  "geojson-vt": "^3.2.1",
31
31
  "gl-matrix": "^3.4.3",
@@ -45,49 +45,49 @@
45
45
  "@rollup/plugin-commonjs": "^25.0.7",
46
46
  "@rollup/plugin-json": "^6.0.1",
47
47
  "@rollup/plugin-node-resolve": "^15.2.3",
48
- "@rollup/plugin-replace": "^5.0.4",
48
+ "@rollup/plugin-replace": "^5.0.5",
49
49
  "@rollup/plugin-strip": "^3.0.4",
50
50
  "@rollup/plugin-terser": "^0.4.4",
51
51
  "@rollup/plugin-typescript": "^11.1.5",
52
- "@types/benchmark": "^2.1.3",
52
+ "@types/benchmark": "^2.1.5",
53
53
  "@types/cssnano": "^5.0.0",
54
- "@types/d3": "^7.4.1",
55
- "@types/diff": "^5.0.7",
56
- "@types/earcut": "^2.1.3",
57
- "@types/eslint": "^8.44.6",
58
- "@types/geojson-vt": "3.2.3",
54
+ "@types/d3": "^7.4.2",
55
+ "@types/diff": "^5.0.8",
56
+ "@types/earcut": "^2.1.4",
57
+ "@types/eslint": "^8.44.7",
58
+ "@types/geojson-vt": "3.2.4",
59
59
  "@types/gl": "^6.0.4",
60
60
  "@types/glob": "^8.1.0",
61
61
  "@types/jest": "^29.5.3",
62
- "@types/jsdom": "^21.1.3",
63
- "@types/minimist": "^1.2.4",
62
+ "@types/jsdom": "^21.1.5",
63
+ "@types/minimist": "^1.2.5",
64
64
  "@types/murmurhash-js": "^1.0.5",
65
- "@types/nise": "^1.4.2",
65
+ "@types/nise": "^1.4.4",
66
66
  "@types/node": "^20.8.3",
67
- "@types/offscreencanvas": "^2019.7.2",
68
- "@types/pixelmatch": "^5.2.4",
69
- "@types/pngjs": "^6.0.3",
70
- "@types/react": "^18.2.31",
71
- "@types/react-dom": "^18.2.13",
72
- "@types/request": "^2.48.11",
73
- "@types/shuffle-seed": "^1.1.1",
74
- "@types/window-or-global": "^1.0.4",
75
- "@typescript-eslint/eslint-plugin": "^6.8.0",
76
- "@typescript-eslint/parser": "^6.8.0",
67
+ "@types/offscreencanvas": "^2019.7.3",
68
+ "@types/pixelmatch": "^5.2.5",
69
+ "@types/pngjs": "^6.0.4",
70
+ "@types/react": "^18.2.35",
71
+ "@types/react-dom": "^18.2.14",
72
+ "@types/request": "^2.48.12",
73
+ "@types/shuffle-seed": "^1.1.2",
74
+ "@types/window-or-global": "^1.0.6",
75
+ "@typescript-eslint/eslint-plugin": "^6.10.0",
76
+ "@typescript-eslint/parser": "^6.10.0",
77
77
  "address": "^2.0.1",
78
78
  "benchmark": "^2.1.4",
79
79
  "canvas": "^2.11.2",
80
80
  "cssnano": "^6.0.1",
81
81
  "d3": "^7.8.5",
82
82
  "d3-queue": "^3.0.7",
83
- "devtools-protocol": "^0.0.1212569",
83
+ "devtools-protocol": "^0.0.1219864",
84
84
  "diff": "^5.1.0",
85
- "dts-bundle-generator": "^8.0.1",
86
- "eslint": "^8.52.0",
85
+ "dts-bundle-generator": "^8.1.2",
86
+ "eslint": "^8.53.0",
87
87
  "eslint-config-mourner": "^3.0.0",
88
88
  "eslint-plugin-html": "^7.1.0",
89
- "eslint-plugin-import": "^2.28.1",
90
- "eslint-plugin-jest": "^27.4.3",
89
+ "eslint-plugin-import": "^2.29.0",
90
+ "eslint-plugin-jest": "^27.6.0",
91
91
  "eslint-plugin-react": "^7.33.2",
92
92
  "eslint-plugin-tsdoc": "0.2.17",
93
93
  "expect": "^29.7.0",
@@ -111,10 +111,10 @@
111
111
  "postcss-cli": "^10.1.0",
112
112
  "postcss-inline-svg": "^6.0.0",
113
113
  "pretty-bytes": "^6.1.1",
114
- "puppeteer": "^21.3.8",
114
+ "puppeteer": "^21.5.1",
115
115
  "react": "^18.2.0",
116
116
  "react-dom": "^18.2.0",
117
- "rollup": "^4.1.4",
117
+ "rollup": "^4.4.0",
118
118
  "rollup-plugin-sourcemaps": "^0.6.3",
119
119
  "rw": "^1.3.3",
120
120
  "semver": "^7.5.4",
@@ -126,8 +126,8 @@
126
126
  "ts-jest": "^29.1.1",
127
127
  "ts-node": "^10.9.1",
128
128
  "tslib": "^2.6.2",
129
- "typedoc": "^0.25.2",
130
- "typedoc-plugin-markdown": "^3.16.0",
129
+ "typedoc": "^0.25.3",
130
+ "typedoc-plugin-markdown": "^3.17.1",
131
131
  "typedoc-plugin-missing-exports": "^2.1.0",
132
132
  "typescript": "^5.2.2"
133
133
  },
@@ -2155,6 +2155,36 @@ describe('Style#setLayerZoomRange', () => {
2155
2155
  });
2156
2156
  });
2157
2157
 
2158
+ describe('Style#getLayersOrder', () => {
2159
+ test('returns ids of layers in the correct order', done => {
2160
+ const style = new Style(getStubMap());
2161
+ style.loadJSON({
2162
+ 'version': 8,
2163
+ 'sources': {
2164
+ 'raster': {
2165
+ type: 'raster',
2166
+ tiles: ['http://tiles.server']
2167
+ }
2168
+ },
2169
+ 'layers': [{
2170
+ 'id': 'raster',
2171
+ 'type': 'raster',
2172
+ 'source': 'raster'
2173
+ }]
2174
+ });
2175
+
2176
+ style.on('style.load', () => {
2177
+ style.addLayer({
2178
+ id: 'custom',
2179
+ type: 'custom',
2180
+ render() {}
2181
+ }, 'raster');
2182
+ expect(style.getLayersOrder()).toEqual(['custom', 'raster']);
2183
+ done();
2184
+ });
2185
+ });
2186
+ });
2187
+
2158
2188
  describe('Style#queryRenderedFeatures', () => {
2159
2189
 
2160
2190
  let style;
@@ -1008,7 +1008,16 @@ export class Style extends Evented {
1008
1008
  }
1009
1009
 
1010
1010
  /**
1011
- * checks if a specific layer is present within the style.
1011
+ * Return the ids of all layers currently in the style, including custom layers, in order.
1012
+ *
1013
+ * @returns ids of layers, in order
1014
+ */
1015
+ getLayersOrder(): string[] {
1016
+ return [...this._order];
1017
+ }
1018
+
1019
+ /**
1020
+ * Checks if a specific layer is present within the style.
1012
1021
  *
1013
1022
  * @param id - the id of the desired layer
1014
1023
  * @returns a boolean specifying if the given layer is present
@@ -7,6 +7,7 @@ import {setMatchMedia} from '../util/test/util';
7
7
  import {mercatorZfromAltitude} from '../geo/mercator_coordinate';
8
8
  import {Terrain} from '../render/terrain';
9
9
  import {LngLat, LngLatLike} from '../geo/lng_lat';
10
+ import {Event} from '../util/evented';
10
11
 
11
12
  beforeEach(() => {
12
13
  setMatchMedia();
@@ -974,6 +975,86 @@ describe('#easeTo', () => {
974
975
  assertTransitionTime(done, camera, 0, 10);
975
976
  camera.easeTo({center: [100, 0], zoom: 3.2, bearing: 90, duration: 1000});
976
977
  });
978
+
979
+ test('jumpTo on("move") during easeTo with zoom, pitch, etc', (done) => {
980
+ const camera = createCamera();
981
+
982
+ camera.on('moveend', (e: Event & {done?: true}) => {
983
+ if ('done' in e) {
984
+ setTimeout(() => {
985
+ done();
986
+ }, 50);
987
+ }
988
+ });
989
+
990
+ camera.easeTo({zoom: 20, bearing: 90, pitch: 60, duration: 500}, {done: true});
991
+ camera.once('move', () => {
992
+ camera.jumpTo({pitch: 40});
993
+ });
994
+
995
+ camera.simulateFrame();
996
+ camera.simulateFrame();
997
+ });
998
+
999
+ test('jumpTo on("zoom") during easeTo', (done) => {
1000
+ const camera = createCamera();
1001
+
1002
+ camera.on('moveend', (e: Event & {done?: true}) => {
1003
+ if ('done' in e) {
1004
+ setTimeout(() => {
1005
+ done();
1006
+ }, 50);
1007
+ }
1008
+ });
1009
+
1010
+ camera.easeTo({zoom: 20, duration: 500}, {done: true});
1011
+ camera.once('zoom', () => {
1012
+ camera.jumpTo({pitch: 40});
1013
+ });
1014
+
1015
+ camera.simulateFrame();
1016
+ camera.simulateFrame();
1017
+ });
1018
+
1019
+ test('jumpTo on("pitch") during easeTo', (done) => {
1020
+ const camera = createCamera();
1021
+
1022
+ camera.on('moveend', (e: Event & {done?: true}) => {
1023
+ if ('done' in e) {
1024
+ setTimeout(() => {
1025
+ done();
1026
+ }, 50);
1027
+ }
1028
+ });
1029
+
1030
+ camera.easeTo({pitch: 60, duration: 500}, {done: true});
1031
+ camera.once('pitch', () => {
1032
+ camera.jumpTo({pitch: 40});
1033
+ });
1034
+
1035
+ camera.simulateFrame();
1036
+ camera.simulateFrame();
1037
+ });
1038
+
1039
+ test('jumpTo on("rotate") during easeTo', (done) => {
1040
+ const camera = createCamera();
1041
+
1042
+ camera.on('moveend', (e: Event & {done?: true}) => {
1043
+ if ('done' in e) {
1044
+ setTimeout(() => {
1045
+ done();
1046
+ }, 50);
1047
+ }
1048
+ });
1049
+
1050
+ camera.easeTo({bearing: 90, duration: 500}, {done: true});
1051
+ camera.once('rotate', () => {
1052
+ camera.jumpTo({pitch: 40});
1053
+ });
1054
+
1055
+ camera.simulateFrame();
1056
+ camera.simulateFrame();
1057
+ });
977
1058
  });
978
1059
 
979
1060
  describe('#flyTo', () => {
package/src/ui/camera.ts CHANGED
@@ -1427,7 +1427,9 @@ export abstract class Camera extends Evented {
1427
1427
  _renderFrameCallback = () => {
1428
1428
  const t = Math.min((browser.now() - this._easeStart) / this._easeOptions.duration, 1);
1429
1429
  this._onEaseFrame(this._easeOptions.easing(t));
1430
- if (t < 1) {
1430
+
1431
+ // if _stop is called during _onEaseFrame from _fireMoveEvents we should avoid a new _requestRenderFrame, checking it by ensuring _easeFrameId was not deleted
1432
+ if (t < 1 && this._easeFrameId) {
1431
1433
  this._easeFrameId = this._requestRenderFrame(this._renderFrameCallback);
1432
1434
  } else {
1433
1435
  this.stop();
@@ -811,6 +811,36 @@ describe('Map', () => {
811
811
  expect(mapLayer.source).toBe(layer.source);
812
812
  });
813
813
 
814
+ describe('#getLayersOrder', () => {
815
+ test('returns ids of layers in the correct order', done => {
816
+ const map = createMap({
817
+ style: extend(createStyle(), {
818
+ 'sources': {
819
+ 'raster': {
820
+ type: 'raster',
821
+ tiles: ['http://tiles.server']
822
+ }
823
+ },
824
+ 'layers': [{
825
+ 'id': 'raster',
826
+ 'type': 'raster',
827
+ 'source': 'raster'
828
+ }]
829
+ })
830
+ });
831
+
832
+ map.on('style.load', () => {
833
+ map.addLayer({
834
+ id: 'custom',
835
+ type: 'custom',
836
+ render() {}
837
+ }, 'raster');
838
+ expect(map.getLayersOrder()).toEqual(['custom', 'raster']);
839
+ done();
840
+ });
841
+ });
842
+ });
843
+
814
844
  describe('#resize', () => {
815
845
  test('sets width and height from container clients', () => {
816
846
  const map = createMap(),
package/src/ui/map.ts CHANGED
@@ -2480,6 +2480,20 @@ export class Map extends Camera {
2480
2480
  return this.style.getLayer(id);
2481
2481
  }
2482
2482
 
2483
+ /**
2484
+ * Return the ids of all layers currently in the style, including custom layers, in order.
2485
+ *
2486
+ * @returns ids of layers, in order
2487
+ *
2488
+ * @example
2489
+ * ```ts
2490
+ * const orderedLayerIds = map.getLayersOrder();
2491
+ * ```
2492
+ */
2493
+ getLayersOrder(): string[] {
2494
+ return this.style.getLayersOrder();
2495
+ }
2496
+
2483
2497
  /**
2484
2498
  * Sets the zoom extent for the specified style layer. The zoom extent includes the
2485
2499
  * [minimum zoom level](https://maplibre.org/maplibre-style-spec/layers/#minzoom)
@@ -10,6 +10,10 @@ test('resolveToken', () => {
10
10
  expect(resolveTokens({name: 'Test'}, '{name}')).toBe('Test');
11
11
  expect(resolveTokens({name: 'Test'}, '{name}-suffix')).toBe('Test-suffix');
12
12
 
13
+ // No properties.
14
+ expect(resolveTokens(null, '{name}')).toBe('');
15
+ expect(resolveTokens(null, '{name}-suffix')).toBe('-suffix');
16
+
13
17
  // Undefined property.
14
18
  expect(resolveTokens({}, '{name}')).toBe('');
15
19
  expect(resolveTokens({}, '{name}-suffix')).toBe('-suffix');
@@ -8,10 +8,10 @@
8
8
  export function resolveTokens(
9
9
  properties: {
10
10
  readonly [x: string]: unknown;
11
- },
11
+ } | null,
12
12
  text: string
13
13
  ): string {
14
14
  return text.replace(/{([^{}]+)}/g, (match, key: string) => {
15
- return key in properties ? String(properties[key]) : '';
15
+ return properties && key in properties ? String(properties[key]) : '';
16
16
  });
17
17
  }