maplibre-gl 2.0.4 → 2.0.5

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": "2.0.4",
4
+ "version": "2.0.5",
5
5
  "main": "dist/maplibre-gl.js",
6
6
  "style": "dist/maplibre-gl.css",
7
7
  "license": "BSD-3-Clause",
@@ -9,9 +9,6 @@
9
9
  "type": "git",
10
10
  "url": "git://github.com/maplibre/maplibre-gl-js.git"
11
11
  },
12
- "engines": {
13
- "node": ">=16.0.0"
14
- },
15
12
  "types": "dist/maplibre-gl.d.ts",
16
13
  "type": "module",
17
14
  "dependencies": {
@@ -45,17 +42,18 @@
45
42
  "@mapbox/mapbox-gl-rtl-text": "^0.2.1",
46
43
  "@mapbox/mvt-fixtures": "^3.6.0",
47
44
  "@octokit/rest": "^18.10.0",
48
- "@rollup/plugin-commonjs": "^21.0.0",
45
+ "@rollup/plugin-buble": "^0.21.3",
46
+ "@rollup/plugin-commonjs": "^21.0.1",
49
47
  "@rollup/plugin-json": "^4.1.0",
50
- "@rollup/plugin-node-resolve": "^13.0.6",
51
- "@rollup/plugin-replace": "^3.0.0",
48
+ "@rollup/plugin-node-resolve": "^13.1.3",
49
+ "@rollup/plugin-replace": "^3.0.1",
52
50
  "@rollup/plugin-strip": "^2.1.0",
53
51
  "@rollup/plugin-typescript": "^8.3.0",
54
52
  "@types/babel__core": "^7.1.12",
55
53
  "@types/babelify": "^7.3.6",
56
54
  "@types/benchmark": "^2.1.0",
57
55
  "@types/browserify": "^12.0.36",
58
- "@types/cssnano": "^4.0.0",
56
+ "@types/cssnano": "^5.0.0",
59
57
  "@types/d3": "^4.13.12",
60
58
  "@types/diff": "^4.0.2",
61
59
  "@types/earcut": "^2.1.1",
@@ -99,7 +97,7 @@
99
97
  "cssnano": "^5.0.8",
100
98
  "d3": "^4.12.0",
101
99
  "diff": "^4.0.1",
102
- "documentation": "~12.1.1",
100
+ "documentation": "^12.3.0",
103
101
  "dts-bundle-generator": "^6.0.0",
104
102
  "ejs": "^3.1.6",
105
103
  "eslint": "^7.32.0",
@@ -146,10 +144,6 @@
146
144
  "replace-in-file": "^6.2.0",
147
145
  "request": "^2.88.0",
148
146
  "rollup": "^2.56.3",
149
- "rollup-plugin-buble": "^0.19.8",
150
- "rollup-plugin-commonjs": "^10.1.0",
151
- "rollup-plugin-node-resolve": "^5.2.0",
152
- "rollup-plugin-replace": "^2.2.0",
153
147
  "rollup-plugin-sourcemaps": "^0.6.3",
154
148
  "rollup-plugin-terser": "^7.0.2",
155
149
  "rollup-plugin-unassert": "^0.3.0",
@@ -169,7 +163,7 @@
169
163
  "tape-filter": "^1.0.4",
170
164
  "testem": "^3.5.0",
171
165
  "ts-jest": "^27.0.5",
172
- "ts-node": "^10.2.1",
166
+ "ts-node": "^10.4.0",
173
167
  "typescript": "^4.5.4"
174
168
  },
175
169
  "browser": {
@@ -0,0 +1,153 @@
1
+ import ImageSource from './image_source';
2
+ import {Evented} from '../util/evented';
3
+ import Transform from '../geo/transform';
4
+ import {extend} from '../util/util';
5
+ import {useFakeXMLHttpRequest} from 'sinon';
6
+ import {RequestManager} from '../util/request_manager';
7
+ import Dispatcher from '../util/dispatcher';
8
+ import {stubAjaxGetImage} from '../util/test/util';
9
+
10
+ function createSource(options) {
11
+ options = extend({
12
+ coordinates: [[0, 0], [1, 0], [1, 1], [0, 1]]
13
+ }, options);
14
+
15
+ const source = new ImageSource('id', options, {send() {}} as any as Dispatcher, options.eventedParent);
16
+ return source;
17
+ }
18
+
19
+ class StubMap extends Evented {
20
+ transform: Transform;
21
+ _requestManager: RequestManager;
22
+
23
+ constructor() {
24
+ super();
25
+ this.transform = new Transform();
26
+ this._requestManager = {
27
+ transformRequest: (url) => {
28
+ return {url};
29
+ }
30
+ } as any as RequestManager;
31
+ }
32
+ }
33
+
34
+ describe('ImageSource', () => {
35
+ const requests = [];
36
+ useFakeXMLHttpRequest().onCreate = (req) => { requests.push(req); };
37
+ stubAjaxGetImage(undefined);
38
+ beforeEach(() => {
39
+ global.fetch = null;
40
+ });
41
+
42
+ const respond = () => {
43
+ const req = requests.shift();
44
+ req.setStatus(200);
45
+ req.response = new ArrayBuffer(1);
46
+ req.onload();
47
+ };
48
+
49
+ test('constructor', () => {
50
+ const source = createSource({url : '/image.png'});
51
+
52
+ expect(source.minzoom).toBe(0);
53
+ expect(source.maxzoom).toBe(22);
54
+ expect(source.tileSize).toBe(512);
55
+ });
56
+
57
+ test('fires dataloading event', () => {
58
+ const source = createSource({url : '/image.png'});
59
+ source.on('dataloading', (e) => {
60
+ expect(e.dataType).toBe('source');
61
+ });
62
+ source.onAdd(new StubMap() as any);
63
+ respond();
64
+ expect(source.image).toBeTruthy();
65
+ });
66
+
67
+ test('transforms url request', () => {
68
+ const source = createSource({url : '/image.png'});
69
+ const map = new StubMap() as any;
70
+ const spy = jest.spyOn(map._requestManager, 'transformRequest');
71
+ source.onAdd(map);
72
+ respond();
73
+ expect(spy).toHaveBeenCalledTimes(1);
74
+ expect(spy.mock.calls[0][0]).toBe('/image.png');
75
+ expect(spy.mock.calls[0][1]).toBe('Image');
76
+ });
77
+
78
+ test('updates url from updateImage', () => {
79
+ const source = createSource({url : '/image.png'});
80
+ const map = new StubMap() as any;
81
+ const spy = jest.spyOn(map._requestManager, 'transformRequest');
82
+ source.onAdd(map);
83
+ respond();
84
+ expect(spy).toHaveBeenCalledTimes(1);
85
+ expect(spy.mock.calls[0][0]).toBe('/image.png');
86
+ expect(spy.mock.calls[0][1]).toBe('Image');
87
+ source.updateImage({url: '/image2.png'});
88
+ respond();
89
+ expect(spy).toHaveBeenCalledTimes(2);
90
+ expect(spy.mock.calls[1][0]).toBe('/image2.png');
91
+ expect(spy.mock.calls[1][1]).toBe('Image');
92
+ });
93
+
94
+ test('sets coordinates', () => {
95
+ const source = createSource({url : '/image.png'});
96
+ const map = new StubMap() as any;
97
+ source.onAdd(map);
98
+ respond();
99
+ const beforeSerialized = source.serialize();
100
+ expect(beforeSerialized.coordinates).toEqual([[0, 0], [1, 0], [1, 1], [0, 1]]);
101
+ source.setCoordinates([[0, 0], [-1, 0], [-1, -1], [0, -1]]);
102
+ const afterSerialized = source.serialize();
103
+ expect(afterSerialized.coordinates).toEqual([[0, 0], [-1, 0], [-1, -1], [0, -1]]);
104
+ });
105
+
106
+ test('sets coordinates via updateImage', () => {
107
+ const source = createSource({url : '/image.png'});
108
+ const map = new StubMap() as any;
109
+ source.onAdd(map);
110
+ respond();
111
+ const beforeSerialized = source.serialize();
112
+ expect(beforeSerialized.coordinates).toEqual([[0, 0], [1, 0], [1, 1], [0, 1]]);
113
+ source.updateImage({
114
+ url: '/image2.png',
115
+ coordinates: [[0, 0], [-1, 0], [-1, -1], [0, -1]]
116
+ });
117
+ respond();
118
+ const afterSerialized = source.serialize();
119
+ expect(afterSerialized.coordinates).toEqual([[0, 0], [-1, 0], [-1, -1], [0, -1]]);
120
+ });
121
+
122
+ test('fires data event when content is loaded', done => {
123
+ const source = createSource({url : '/image.png'});
124
+ source.on('data', (e) => {
125
+ if (e.dataType === 'source' && e.sourceDataType === 'content') {
126
+ expect(typeof source.tileID == 'object').toBeTruthy();
127
+ done();
128
+ }
129
+ });
130
+ source.onAdd(new StubMap() as any);
131
+ respond();
132
+ });
133
+
134
+ test('fires data event when metadata is loaded', done => {
135
+ const source = createSource({url : '/image.png'});
136
+ source.on('data', (e) => {
137
+ if (e.dataType === 'source' && e.sourceDataType === 'metadata') {
138
+ done();
139
+ }
140
+ });
141
+ source.onAdd(new StubMap() as any);
142
+ respond();
143
+ });
144
+
145
+ test('serialize url and coordinates', () => {
146
+ const source = createSource({url: '/image.png'});
147
+
148
+ const serialized = source.serialize();
149
+ expect(serialized.type).toBe('image');
150
+ expect(serialized.url).toBe('/image.png');
151
+ expect(serialized.coordinates).toEqual([[0, 0], [1, 0], [1, 1], [0, 1]]);
152
+ });
153
+ });
package/src/ui/camera.ts CHANGED
@@ -14,6 +14,14 @@ import type {LngLatBoundsLike} from '../geo/lng_lat_bounds';
14
14
  import type {TaskID} from '../util/task_queue';
15
15
  import type {PaddingOptions} from '../geo/edge_insets';
16
16
 
17
+ /**
18
+ * A [Point](https://github.com/mapbox/point-geometry) or an array of two numbers representing `x` and `y` screen coordinates in pixels.
19
+ *
20
+ * @typedef {(Point | [number, number])} PointLike
21
+ * @example
22
+ * var p1 = new Point(-77, 38); // a PointLike which is a Point
23
+ * var p2 = [-77, 38]; // a PointLike which is an array of two numbers
24
+ */
17
25
  export type PointLike = Point | [number, number];
18
26
 
19
27
  export type RequireAtLeastOne<T> = { [K in keyof T]-?: Required<Pick<T, K>> & Partial<Pick<T, Exclude<keyof T, K>>>; }[keyof T];
package/src/ui/map.ts CHANGED
@@ -828,11 +828,11 @@ class Map extends Camera {
828
828
  }
829
829
 
830
830
  /**
831
- * Returns a {@link Point} representing pixel coordinates, relative to the map's `container`,
831
+ * Returns a [Point](https://github.com/mapbox/point-geometry) representing pixel coordinates, relative to the map's `container`,
832
832
  * that correspond to the specified geographical location.
833
833
  *
834
834
  * @param {LngLatLike} lnglat The geographical location to project.
835
- * @returns {Point} The {@link Point} corresponding to `lnglat`, relative to the map's `container`.
835
+ * @returns {Point} The [Point](https://github.com/mapbox/point-geometry) corresponding to `lnglat`, relative to the map's `container`.
836
836
  * @example
837
837
  * var coordinate = [-122.420679, 37.772537];
838
838
  * var point = map.project(coordinate);
@@ -0,0 +1,206 @@
1
+ import {
2
+ getArrayBuffer,
3
+ getJSON,
4
+ postData,
5
+ getImage,
6
+ resetImageRequestQueue
7
+ } from './ajax';
8
+ import config from './config';
9
+ import webpSupported from './webp_supported';
10
+ import {fakeServer, SinonFakeServer} from 'sinon';
11
+ import {stubAjaxGetImage} from './test/util';
12
+
13
+ describe('ajax', () => {
14
+ let server: SinonFakeServer;
15
+ beforeEach(() => {
16
+ global.fetch = null;
17
+ server = fakeServer.create();
18
+ });
19
+ afterEach(() => {
20
+ server.restore();
21
+ });
22
+
23
+ test('getArrayBuffer, 404', done => {
24
+ server.respondWith(request => {
25
+ request.respond(404, undefined, undefined);
26
+ });
27
+ getArrayBuffer({url:''}, (error) => {
28
+ expect((error as any).status).toBe(404);
29
+ done();
30
+ });
31
+ server.respond();
32
+ });
33
+
34
+ test('getJSON', done => {
35
+ server.respondWith(request => {
36
+ request.respond(200, {'Content-Type': 'application/json'}, '{"foo": "bar"}');
37
+ });
38
+ getJSON({url:''}, (error, body) => {
39
+ expect(error).toBeFalsy();
40
+ expect(body).toEqual({foo: 'bar'});
41
+ done();
42
+ });
43
+ server.respond();
44
+ });
45
+
46
+ test('getJSON, invalid syntax', done => {
47
+ server.respondWith(request => {
48
+ request.respond(200, {'Content-Type': 'application/json'}, 'how do i even');
49
+ });
50
+ getJSON({url:''}, (error) => {
51
+ expect(error).toBeTruthy();
52
+ done();
53
+ });
54
+ server.respond();
55
+ });
56
+
57
+ test('getJSON, 404', done => {
58
+ server.respondWith(request => {
59
+ request.respond(404, undefined, undefined);
60
+ });
61
+ getJSON({url:''}, (error) => {
62
+ expect((error as any).status).toBe(404);
63
+ done();
64
+ });
65
+ server.respond();
66
+ });
67
+
68
+ test('getJSON, 401: non-Mapbox domain', done => {
69
+ server.respondWith(request => {
70
+ request.respond(401, undefined, undefined);
71
+ });
72
+ getJSON({url:''}, (error) => {
73
+ expect((error as any).status).toBe(401);
74
+ expect(error.message).toBe('Unauthorized');
75
+ done();
76
+ });
77
+ server.respond();
78
+ });
79
+
80
+ test('postData, 204(no content): no error', done => {
81
+ server.respondWith(request => {
82
+ request.respond(204, undefined, undefined);
83
+ });
84
+ postData({url:'api.mapbox.com'}, (error) => {
85
+ expect(error).toBeNull();
86
+ done();
87
+ });
88
+ server.respond();
89
+ });
90
+
91
+ test('getImage respects maxParallelImageRequests', done => {
92
+ server.respondWith(request => request.respond(200, {'Content-Type': 'image/png'}, ''));
93
+
94
+ const maxRequests = config.MAX_PARALLEL_IMAGE_REQUESTS;
95
+
96
+ function callback(err) {
97
+ if (err) return;
98
+ // last request is only added after we got a response from one of the previous ones
99
+ expect(server.requests).toHaveLength(maxRequests + 1);
100
+ done();
101
+ }
102
+
103
+ for (let i = 0; i < maxRequests + 1; i++) {
104
+ getImage({url: ''}, callback);
105
+ }
106
+ expect(server.requests).toHaveLength(maxRequests);
107
+
108
+ server.requests[0].respond(undefined, undefined, undefined);
109
+ });
110
+
111
+ test('getImage cancelling frees up request for maxParallelImageRequests', done => {
112
+ resetImageRequestQueue();
113
+
114
+ server.respondWith(request => request.respond(200, {'Content-Type': 'image/png'}, ''));
115
+
116
+ const maxRequests = config.MAX_PARALLEL_IMAGE_REQUESTS;
117
+
118
+ for (let i = 0; i < maxRequests + 1; i++) {
119
+ getImage({url: ''}, () => done('test failed: getImage callback was called')).cancel();
120
+ }
121
+ expect(server.requests).toHaveLength(maxRequests + 1);
122
+ done();
123
+ });
124
+
125
+ test('getImage requests that were once queued are still abortable', done => {
126
+ resetImageRequestQueue();
127
+
128
+ const maxRequests = config.MAX_PARALLEL_IMAGE_REQUESTS;
129
+
130
+ const requests = [];
131
+ for (let i = 0; i < maxRequests; i++) {
132
+ requests.push(getImage({url: ''}, () => {}));
133
+ }
134
+
135
+ // the limit of allowed requests is reached
136
+ expect(server.requests).toHaveLength(maxRequests);
137
+
138
+ const queuedURL = 'this-is-the-queued-request';
139
+ const queued = getImage({url: queuedURL}, () => done('test failed: getImage callback was called'));
140
+
141
+ // the new requests is queued because the limit is reached
142
+ expect(server.requests).toHaveLength(maxRequests);
143
+
144
+ // cancel the first request to let the queued request start
145
+ requests[0].cancel();
146
+ expect(server.requests).toHaveLength(maxRequests + 1);
147
+
148
+ // abort the previously queued request and confirm that it is aborted
149
+ const queuedRequest = server.requests[server.requests.length - 1];
150
+ expect(queuedRequest.url).toBe(queuedURL);
151
+ expect((queuedRequest as any).aborted).toBeUndefined();
152
+ queued.cancel();
153
+ expect((queuedRequest as any).aborted).toBe(true);
154
+
155
+ done();
156
+ });
157
+
158
+ test('getImage sends accept/webp when supported', done => {
159
+ resetImageRequestQueue();
160
+
161
+ server.respondWith((request) => {
162
+ expect(request.requestHeaders.accept.includes('image/webp')).toBeTruthy();
163
+ request.respond(200, {'Content-Type': 'image/webp'}, '');
164
+ });
165
+
166
+ // mock webp support
167
+ webpSupported.supported = true;
168
+
169
+ getImage({url: ''}, () => { done(); });
170
+
171
+ server.respond();
172
+ });
173
+
174
+ test('getImage uses ImageBitmap when supported', done => {
175
+ resetImageRequestQueue();
176
+
177
+ server.respondWith(request => request.respond(200, {'Content-Type': 'image/png'}, ''));
178
+
179
+ stubAjaxGetImage(() => Promise.resolve(new ImageBitmap()));
180
+
181
+ getImage({url: ''}, (err, img) => {
182
+ if (err) done(err);
183
+ expect(img).toBeInstanceOf(ImageBitmap);
184
+ done();
185
+ });
186
+
187
+ server.respond();
188
+ });
189
+
190
+ test('getImage uses HTMLImageElement when ImageBitmap is not supported', done => {
191
+ resetImageRequestQueue();
192
+
193
+ server.respondWith(request => request.respond(200, {'Content-Type': 'image/png'}, ''));
194
+
195
+ stubAjaxGetImage(undefined);
196
+
197
+ getImage({url: ''}, (err, img) => {
198
+ if (err) done(`get image failed with error ${err.message}`);
199
+ expect(img).toBeInstanceOf(HTMLImageElement);
200
+ done();
201
+ });
202
+
203
+ server.respond();
204
+ });
205
+
206
+ });
@@ -99,3 +99,17 @@ export function getMockDispatcher() {
99
99
 
100
100
  return mockDispatcher;
101
101
  }
102
+
103
+ export function stubAjaxGetImage(createImageBitmap) {
104
+ global.createImageBitmap = createImageBitmap;
105
+
106
+ global.URL.revokeObjectURL = () => {};
107
+ global.URL.createObjectURL = (_) => { return null; };
108
+
109
+ // eslint-disable-next-line accessor-pairs
110
+ Object.defineProperty(global.Image.prototype, 'src', {
111
+ set(_) {
112
+ this.onload();
113
+ }
114
+ });
115
+ }