Socket
Socket
Sign inDemoInstall

maplibre-gl

Package Overview
Dependencies
Maintainers
5
Versions
105
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

maplibre-gl - npm Package Compare versions

Comparing version 2.0.0-pre.6 to 2.0.0

build/glsl_to_js.js

38

build/generate-style-spec.ts

@@ -128,12 +128,32 @@ import * as fs from 'fs';

export type FilterSpecificationInputType = string | number | boolean;
export type FilterSpecification =
['has', string]
| ['!has', string]
| ['==', string, string | number | boolean]
| ['!=', string, string | number | boolean]
| ['>', string, string | number | boolean]
| ['>=', string, string | number | boolean]
| ['<', string, string | number | boolean]
| ['<=', string, string | number | boolean]
| Array<string | FilterSpecification>; // Can't type in, !in, all, any, none -- https://github.com/facebook/flow/issues/2443
// Lookup
| ['at', number, (number |string)[]]
| ['get', string, Record<string, unknown>?]
| ['has', string, Record<string, unknown>?]
| ['in', ...FilterSpecificationInputType[], FilterSpecificationInputType | FilterSpecificationInputType[]]
| ['index-of', FilterSpecificationInputType, FilterSpecificationInputType | FilterSpecificationInputType[]]
| ['length', string | string[]]
| ['slice', string | string[], number]
// Decision
| ['!', FilterSpecification]
| ['!=', string | FilterSpecification, FilterSpecificationInputType]
| ['<', string | FilterSpecification, FilterSpecificationInputType]
| ['<=', string | FilterSpecification, FilterSpecificationInputType]
| ['==', string | FilterSpecification, FilterSpecificationInputType]
| ['>', string | FilterSpecification, FilterSpecificationInputType]
| ['>=', string | FilterSpecification, FilterSpecificationInputType]
| ["all", ...FilterSpecification[], FilterSpecificationInputType]
| ["any", ...FilterSpecification[], FilterSpecificationInputType]
| ["case", ...FilterSpecification[], FilterSpecificationInputType]
| ["coalesce", ...FilterSpecification[], FilterSpecificationInputType]
| ["match", ...FilterSpecification[], FilterSpecificationInputType]
| ["within", ...FilterSpecification[], FilterSpecificationInputType]
// Used in convert.ts
| ["!in", ...FilterSpecification[], FilterSpecificationInputType]
| ["!has", ...FilterSpecification[], FilterSpecificationInputType]
| ["none", ...FilterSpecification[], FilterSpecificationInputType]
// Fallbak for others
| Array<string | FilterSpecification>

@@ -140,0 +160,0 @@ export type TransitionSpecification = {

import fs from 'fs';
import glob from 'glob';
import child_process from 'child_process';
import glsl_to_js from './glsl_to_js.js';

@@ -22,13 +23,3 @@ let args = process.argv.slice(2);

let code = fs.readFileSync(file, 'utf8');
if (minify) {
code = code.trim() // strip whitespace at the start/end
.replace(/\s*\/\/[^\n]*\n/g, '\n') // strip double-slash comments
.replace(/\n+/g, '\n') // collapse multi line breaks
.replace(/\n\s+/g, '\n') // strip identation
.replace(/\s?([+-\/*=,])\s?/g, '$1') // strip whitespace around operators
.replace(/([;\(\),\{\}])\n(?=[^#])/g, '$1'); // strip more line breaks
}
let content = `export default ${JSON.stringify(code)};`
let content = glsl_to_js(code, minify);
let fileName = outputBaseDir + '/' + file.split('/').splice(-1) + ".js";

@@ -35,0 +26,0 @@ fs.writeFileSync(fileName, content);

#!/usr/bin/env node
const fs = require('fs');
const execSync = require('child_process').execSync;
const ejs = require('ejs');
const _ = require('lodash');
const semver = require('semver');
import * as fs from 'fs';
import {execSync} from 'child_process';
import * as ejs from 'ejs';
import _ from 'lodash';
import semver from 'semver';

@@ -39,2 +39,3 @@ const changelogPath = 'CHANGELOG.md';

let releaseNotes = [];
let match;
// eslint-disable-next-line no-cond-assign

@@ -41,0 +42,0 @@ while (match = regex.exec(changelog)) {

import typescript from '@rollup/plugin-typescript';
import resolve from '@rollup/plugin-node-resolve';

@@ -9,3 +10,5 @@ import replace from '@rollup/plugin-replace';

import minifyStyleSpec from './rollup_plugin_minify_style_spec.js';
import {createFilter} from 'rollup-pluginutils';
import strip from '@rollup/plugin-strip';
import glsl_to_js from './glsl_to_js.js';

@@ -15,3 +18,3 @@ // Common set of plugins/transformations shared across different rollup

export const plugins = (minified, production) => [
export const plugins = (minified, production, watch) => [
minifyStyleSpec(),

@@ -31,2 +34,3 @@ json(),

}) : false,
glsl('**/*.glsl', production),
minified ? terser({

@@ -38,3 +42,5 @@ compress: {

}) : false,
production ? unassert() : false,
production ? unassert({
include: ['**/*'], // by default, unassert only includes .js files
}) : false,
resolve({

@@ -44,2 +50,3 @@ browser: true,

}),
watch ? typescript() : false,
commonjs({

@@ -51,1 +58,16 @@ // global keyword handling causes Webpack compatibility issues, so we disabled it:

].filter(Boolean);
// Using this instead of rollup-plugin-string to add minification
function glsl(include, minify) {
const filter = createFilter(include);
return {
name: 'glsl',
transform(code, id) {
if (!filter(id)) return;
return {
code: glsl_to_js(code, minify),
map: {mappings: ''}
};
}
};
}
{
"name": "maplibre-gl",
"description": "BSD licensed community fork of mapbox-gl, a WebGL interactive maps library",
"version": "2.0.0-pre.6",
"version": "2.0.0",
"main": "dist/maplibre-gl.js",

@@ -25,3 +25,2 @@ "style": "dist/maplibre-gl.css",

"@mapbox/whoots-js": "^3.1.0",
"@types/offscreencanvas": "^2019.6.3",
"csscolorparser": "~1.0.3",

@@ -32,3 +31,2 @@ "earcut": "^2.2.2",

"grid-index": "^1.1.0",
"minimist": "^1.2.5",
"murmurhash-js": "^1.0.0",

@@ -38,4 +36,2 @@ "pbf": "^3.2.1",

"quickselect": "^2.0.0",
"rollup-plugin-buble": "^0.19.8",
"rw": "^1.3.3",
"supercluster": "^7.1.0",

@@ -56,2 +52,3 @@ "tinyqueue": "^2.0.3",

"@rollup/plugin-strip": "^2.1.0",
"@rollup/plugin-typescript": "^8.3.0",
"@types/babel__core": "^7.1.12",

@@ -66,3 +63,3 @@ "@types/babelify": "^7.3.6",

"@types/ejs": "^3.1.0",
"@types/eslint": "^7.28.2",
"@types/eslint": "^8.2.1",
"@types/geojson": "^7946.0.7",

@@ -79,2 +76,3 @@ "@types/gl": "^4.1.0",

"@types/npm-packlist": "^1.1.1",
"@types/offscreencanvas": "^2019.6.3",
"@types/pbf": "^3.0.2",

@@ -124,3 +122,3 @@ "@types/pixelmatch": "^5.2.2",

"jest-canvas-mock": "^2.3.1",
"jest-codemods": "^0.24.0",
"jest-codemods": "^0.25.0",
"jest-raw-loader": "^1.0.1",

@@ -135,2 +133,3 @@ "jscodeshift": "^0.13.0",

"mapbox-gl-styles": "^2.0.2",
"minimist": "^1.2.5",
"mock-geolocation": "^1.0.11",

@@ -150,3 +149,3 @@ "node-notifier": "^10.0.0",

"pretty-bytes": "^5.1.0",
"puppeteer": "^11.0.0",
"puppeteer": "^13.0.1",
"qrcode-terminal": "^0.12.0",

@@ -158,2 +157,3 @@ "react": "^17.0.2",

"rollup": "^2.56.3",
"rollup-plugin-buble": "^0.19.8",
"rollup-plugin-commonjs": "^10.1.0",

@@ -165,2 +165,4 @@ "rollup-plugin-node-resolve": "^5.2.0",

"rollup-plugin-unassert": "^0.3.0",
"rollup-pluginutils": "^2.8.2",
"rw": "^1.3.3",
"selenium-webdriver": "^4.0.0-rc-1",

@@ -189,6 +191,6 @@ "semver": "^7.3.5",

"build-post-ts-min": "node build/post-ts-build.js ./rollup/build/tsc/src/shaders true",
"build-tsc": "tsc && npm run build-post-ts",
"build-tsc-min": "tsc && npm run build-post-ts-min",
"build-tsc": "tsc --outDir rollup/build/tsc && npm run build-post-ts",
"build-tsc-min": "tsc --outDir rollup/build/tsc && npm run build-post-ts-min",
"build-dev": "npm run build-tsc && rollup -c --environment BUILD:dev",
"watch-dev": "npm run build-tsc && rollup -c --environment BUILD:dev --watch",
"watch-dev": "rollup -c --environment BUILD:dev --watch",
"build-prod": "npm run build-tsc && rollup -c --environment BUILD:production",

@@ -203,2 +205,3 @@ "build-prod-min": "npm run build-tsc-min && rollup -c --environment BUILD:production,MINIFY:true",

"build-benchmarks": "npm run build-dev && BENCHMARK_VERSION=${BENCHMARK_VERSION:-\"$(git rev-parse --abbrev-ref HEAD) $(git rev-parse --short=7 HEAD)\"} rollup -c bench/rollup_config_benchmarks.js",
"watch-benchmarks": "BENCHMARK_VERSION=${BENCHMARK_VERSION:-\"$(git rev-parse --abbrev-ref HEAD) $(git rev-parse --short=7 HEAD)\"} rollup -c bench/rollup_config_benchmarks.js --watch",
"start-server": "st --no-cache -H 0.0.0.0 --port 9966 --index index.html .",

@@ -208,3 +211,3 @@ "start": "run-p watch-css watch-query start-server",

"start-tests": "run-p watch-css watch-query start-server",
"start-bench": "run-s build-css build-dev build-benchmarks start-server",
"start-bench": "run-p watch-css watch-benchmarks start-server",
"lint": "eslint --ext \".ts,.js,.html\" --ignore-path .gitignore src build debug/*.html bench",

@@ -211,0 +214,0 @@ "lint-docs": "documentation lint src/index.ts",

@@ -20,2 +20,11 @@ # MapLibre GL

If you are OK with changes that integrate non-backward compatible features, install `maplibre-gl` version 2:
```diff
"dependencies": {
- "mapbox-gl": "^1.13.0"
+ "maplibre-gl": ">=2.0.0"
}
```
And replace `mapboxgl` with `maplibregl` in your JavaScript and optionally in your HTML/CSS code:

@@ -70,3 +79,3 @@

We'd like to acknowledge the amazing work Mapbox has contributed to open source. The open source community is sad to part ways with them, but we simultaneously feel grateful for everything they already contributed. `mapbox-gl-js` 1.x is an open source achievment which now lives on as `maplibre-gl`. We're proud to develop on the shoulders of giants, thank you Mapbox 🙇🏽‍♀️.
We'd like to acknowledge the amazing work Mapbox has contributed to open source. The open source community is sad to part ways with them, but we simultaneously feel grateful for everything they already contributed. `mapbox-gl-js` 1.x is an open source achievement which now lives on as `maplibre-gl`. We're proud to develop on the shoulders of giants, thank you Mapbox 🙇🏽‍♀️.

@@ -73,0 +82,0 @@ Please keep in mind: Unauthorized backports are the biggest threat to the MapLibre project. It is unacceptable to backport code from mapbox-gl-js, which is not covered by the former BSD-3 license. If you are unsure about this issue, [please ask](https://github.com/maplibre/maplibre-gl-js/discussions)!

@@ -15,6 +15,6 @@ import {wrap} from '../util/util';

*
* Mapbox GL uses longitude, latitude coordinate order (as opposed to latitude, longitude) to match the
* MapLibre GL uses longitude, latitude coordinate order (as opposed to latitude, longitude) to match the
* [GeoJSON specification](https://tools.ietf.org/html/rfc7946).
*
* Note that any Mapbox GL method that accepts a `LngLat` object as an argument or option
* Note that any MapLibre GL method that accepts a `LngLat` object as an argument or option
* can also accept an `Array` of two numbers and will perform an implicit conversion.

@@ -21,0 +21,0 @@ * This flexible type is documented as {@link LngLatLike}.

@@ -120,3 +120,3 @@ /// <reference path="./types/glsl.d.ts" />

/**
* Clears browser storage used by this library. Using this method flushes the Mapbox tile
* Clears browser storage used by this library. Using this method flushes the MapLibre tile
* cache that is managed by this library. Tiles may still be cached by the browser

@@ -193,3 +193,3 @@ * in some cases.

/**
* The version of Mapbox GL JS in use as specified in `package.json`,
* The version of MapLibre GL JS in use as specified in `package.json`,
* `CHANGELOG.md`, and the GitHub release.

@@ -201,3 +201,3 @@ *

/**
* Test whether the browser [supports Mapbox GL JS](https://www.mapbox.com/help/mapbox-browser-support/#mapbox-gl-js).
* Test whether the browser supports MapLibre GL JS.
*

@@ -207,9 +207,9 @@ * @function supported

* @param {boolean} [options.failIfMajorPerformanceCaveat=false] If `true`,
* the function will return `false` if the performance of Mapbox GL JS would
* the function will return `false` if the performance of MapLibre GL JS would
* be dramatically worse than expected (e.g. a software WebGL renderer would be used).
* @return {boolean}
* @example
* // Show an alert if the browser does not support Mapbox GL
* // Show an alert if the browser does not support MapLibre GL
* if (!maplibregl.supported()) {
* alert('Your browser does not support Mapbox GL');
* alert('Your browser does not support MapLibre GL');
* }

@@ -221,3 +221,3 @@ * @see [Check for browser support](https://maplibre.org/maplibre-gl-js-docs/example/check-for-support/)

* Sets the map's [RTL text plugin](https://www.mapbox.com/mapbox-gl-js/plugins/#mapbox-gl-rtl-text).
* Necessary for supporting the Arabic and Hebrew languages, which are written right-to-left. Mapbox Studio loads this plugin by default.
* Necessary for supporting the Arabic and Hebrew languages, which are written right-to-left.
*

@@ -224,0 +224,0 @@ * @function setRTLTextPlugin

@@ -106,3 +106,3 @@ import loadGlyphRange from '../style/load_glyph_range';

requests = entry.requests[range] = [];
GlyphManager.loadGlyphRange(stack, range, ((this.url as any)), this.requestManager,
GlyphManager.loadGlyphRange(stack, range, this.url as any, this.requestManager,
(err, response?: {

@@ -109,0 +109,0 @@ [_: number]: StyleGlyph | null;

@@ -15,6 +15,12 @@ import {Event, ErrorEvent, Evented} from '../util/evented';

import type {GeoJSONSourceSpecification, PromoteIdSpecification} from '../style-spec/types';
import type {MapSourceDataType} from '../ui/events';
export type GeoJSONSourceOptions = GeoJSONSourceSpecification & {
workerOptions?: any;
collectResourceTiming: boolean;
}
/**
* A source containing GeoJSON.
* (See the [Style Specification](https://www.mapbox.com/mapbox-gl-style-spec/#sources-geojson) for detailed documentation of options.)
* (See the [Style Specification](https://maplibre.org/maplibre-gl-js-docs/style-spec/#sources-geojson) for detailed documentation of options.)
*

@@ -79,5 +85,4 @@ * @example

actor: Actor;
_loaded: boolean;
_pendingLoads: number;
_collectResourceTiming: boolean;
_resourceTiming: Array<PerformanceResourceTiming>;
_removed: boolean;

@@ -88,6 +93,3 @@

*/
constructor(id: string, options: GeoJSONSourceSpecification & {
workerOptions?: any;
collectResourceTiming: boolean;
}, dispatcher: Dispatcher, eventedParent: Evented) {
constructor(id: string, options: GeoJSONSourceOptions, dispatcher: Dispatcher, eventedParent: Evented) {
super();

@@ -107,3 +109,3 @@

this._removed = false;
this._loaded = false;
this._pendingLoads = 0;

@@ -117,3 +119,2 @@ this.actor = dispatcher.getActor();

this._collectResourceTiming = options.collectResourceTiming;
this._resourceTiming = [];

@@ -158,19 +159,5 @@ if (options.maxzoom !== undefined) this.maxzoom = options.maxzoom;

load() {
this.fire(new Event('dataloading', {dataType: 'source'}));
this._updateWorkerData((err) => {
if (err) {
this.fire(new ErrorEvent(err));
return;
}
const data: any = {dataType: 'source', sourceDataType: 'metadata'};
if (this._collectResourceTiming && this._resourceTiming && (this._resourceTiming.length > 0)) {
data.resourceTiming = this._resourceTiming;
this._resourceTiming = [];
}
// although GeoJSON sources contain no metadata, we fire this event to let the SourceCache
// know its ok to start requesting tiles.
this.fire(new Event('data', data));
});
// although GeoJSON sources contain no metadata, we fire this event to let the SourceCache
// know its ok to start requesting tiles.
this._updateWorkerData('metadata');
}

@@ -191,17 +178,4 @@

this._data = data;
this.fire(new Event('dataloading', {dataType: 'source'}));
this._updateWorkerData((err) => {
if (err) {
this.fire(new ErrorEvent(err));
return;
}
this._updateWorkerData('content');
const data: any = {dataType: 'source', sourceDataType: 'content'};
if (this._collectResourceTiming && this._resourceTiming && (this._resourceTiming.length > 0)) {
data.resourceTiming = this._resourceTiming;
this._resourceTiming = [];
}
this.fire(new Event('data', data));
});
return this;

@@ -274,4 +248,3 @@ }

*/
_updateWorkerData(callback: Callback<void>) {
this._loaded = false;
_updateWorkerData(sourceDataType: MapSourceDataType) {
const options = extend({}, this.workerOptions);

@@ -286,2 +259,5 @@ const data = this._data;

this._pendingLoads++;
this.fire(new Event('dataloading', {dataType: 'source'}));
// target {this.type}.loadData rather than literally geojson.loadData,

@@ -291,2 +267,4 @@ // so that other geojson-like source types can easily reuse this

this.actor.send(`${this.type}.loadData`, options, (err, result) => {
this._pendingLoads--;
if (this._removed || (result && result.abandoned)) {

@@ -296,6 +274,5 @@ return;

this._loaded = true;
let resourceTiming = null;
if (result && result.resourceTiming && result.resourceTiming[this.id])
this._resourceTiming = result.resourceTiming[this.id].slice(0);
resourceTiming = result.resourceTiming[this.id].slice(0);
// Any `loadData` calls that piled up while we were processing

@@ -309,3 +286,13 @@ // this one will get coalesced into a single call when this

this.actor.send(`${this.type}.coalesce`, {source: options.source}, null);
callback(err);
if (err) {
this.fire(new ErrorEvent(err));
return;
}
const data: any = {dataType: 'source', sourceDataType};
if (this._collectResourceTiming && resourceTiming && resourceTiming.length > 0)
extend(data, {resourceTiming});
this.fire(new Event('data', data));
});

@@ -315,3 +302,3 @@ }

loaded(): boolean {
return this._loaded;
return this._pendingLoads === 0;
}

@@ -318,0 +305,0 @@

@@ -23,7 +23,7 @@ import {CanonicalTileID} from './tile_id';

type Coordinates = [[number, number], [number, number], [number, number], [number, number]];
export type Coordinates = [[number, number], [number, number], [number, number], [number, number]];
/**
* A data source containing an image.
* (See the [Style Specification](https://www.mapbox.com/mapbox-gl-style-spec/#sources-image) for detailed documentation of options.)
* (See the [Style Specification](https://maplibre.org/maplibre-gl-js-docs/style-spec/#sources-image) for detailed documentation of options.)
*

@@ -34,3 +34,3 @@ * @example

* type: 'image',
* url: 'https://www.mapbox.com/images/foo.png',
* url: 'https://www.maplibre.org/images/foo.png',
* coordinates: [

@@ -55,3 +55,3 @@ * [-76.54, 39.18],

* mySource.updateImage({
* url: 'https://www.mapbox.com/images/bar.png',
* url: 'https://www.maplibre.org/images/bar.png',
* coordinates: [

@@ -58,0 +58,0 @@ * [-76.54335737228394, 39.18579907229748],

@@ -104,3 +104,3 @@ import {bindAll} from '../util/util';

* @param {Object} source A source definition object compliant with
* [`mapbox-gl-style-spec`](https://www.mapbox.com/mapbox-gl-style-spec/#sources) or, for a third-party source type,
* [`maplibre-gl-style-spec`](https://maplibre.org/maplibre-gl-js-docs/style-spec/#sources) or, for a third-party source type,
* with that type's requirements.

@@ -107,0 +107,0 @@ * @param {Dispatcher} dispatcher

@@ -9,19 +9,7 @@ import {fakeServer, SinonFakeServer} from 'sinon';

import fixturesSource from '../../test/fixtures/source.json';
import Dispatcher from '../util/dispatcher';
import {getMockDispatcher, getWrapDispatcher} from '../util/test/util';
import Map from '../ui/map';
const wrapDispatcher = (dispatcher) => {
return {
getActor() {
return dispatcher;
}
} as any as Dispatcher;
};
const mockDispatcher = wrapDispatcher({
send () {}
});
function createSource(options, transformCallback?) {
const source = new VectorTileSource('id', options, mockDispatcher, options.eventedParent);
const source = new VectorTileSource('id', options, getMockDispatcher(), options.eventedParent);
source.onAdd({

@@ -119,3 +107,3 @@ transform: {showCollisionBoxes: false},

if (e.sourceDataType === 'metadata') {
if (!dataloadingFired) done.fail();
if (!dataloadingFired) done('test failed: dataloading not fired');
done();

@@ -163,3 +151,3 @@ }

source.dispatcher = wrapDispatcher({
source.dispatcher = getWrapDispatcher()({
send(type, params) {

@@ -211,3 +199,3 @@ expect(type).toBe('loadTile');

const events = [];
source.dispatcher = wrapDispatcher({
source.dispatcher = getWrapDispatcher()({
send(type, params, cb) {

@@ -302,3 +290,3 @@ events.push(type);

});
source.dispatcher = wrapDispatcher({
source.dispatcher = getWrapDispatcher()({
send(type, params, cb) {

@@ -310,3 +298,3 @@ expect(params.request.collectResourceTiming).toBeTruthy();

// do nothing for cache size check dispatch
source.dispatcher = mockDispatcher;
source.dispatcher = getMockDispatcher();

@@ -313,0 +301,0 @@ return 1;

@@ -20,3 +20,3 @@ import {Event, ErrorEvent, Evented} from '../util/evented';

* A source containing vector tiles in [Mapbox Vector Tile format](https://docs.mapbox.com/vector-tiles/reference/).
* (See the [Style Specification](https://docs.mapbox.com/mapbox-gl-js/style-spec/sources/#vector) for detailed documentation of options.)
* (See the [Style Specification](https://maplibre.org/maplibre-gl-js-docs/style-spec/) for detailed documentation of options.)
*

@@ -26,3 +26,3 @@ * @example

* type: 'vector',
* url: 'mapbox://mapbox.mapbox-streets-v6'
* url: 'https://demotiles.maplibre.org/tiles/tiles.json'
* });

@@ -39,3 +39,3 @@ *

* @example
* map.getSource('some id').setUrl("mapbox://mapbox.mapbox-streets-v6");
* map.getSource('some id').setUrl("https://demotiles.maplibre.org/tiles/tiles.json");
*

@@ -160,3 +160,3 @@ * @example

*
* @param {string} url A URL to a TileJSON resource. Supported protocols are `http:`, `https:`, and `mapbox://<Tileset ID>`.
* @param {string} url A URL to a TileJSON resource. Supported protocols are `http:` and `https:`.
* @returns {VectorTileSource} this

@@ -163,0 +163,0 @@ */

@@ -17,3 +17,3 @@ import {getVideo, ResourceType} from '../util/ajax';

* A data source containing video.
* (See the [Style Specification](https://www.mapbox.com/mapbox-gl-style-spec/#sources-video) for detailed documentation of options.)
* (See the [Style Specification](https://maplibre.org/maplibre-gl-js-docs/style-spec/#sources-video) for detailed documentation of options.)
*

@@ -20,0 +20,0 @@ * @example

@@ -0,1 +1,7 @@

## 15.0.0
### Breaking changes
* The migration to TypeScript [#209](https://github.com/maplibre/maplibre-gl-js/pull/209) removed support for the `mapbox://` protocol.
## 14.0.2

@@ -2,0 +8,0 @@

@@ -81,6 +81,6 @@ import {isExpressionFilter} from './index';

) {
const [, property, value] = (filter as any);
converted = convertComparisonOp(property, value, op, expectedTypes);
const [, property, value] = filter;
converted = convertComparisonOp(property as string, value, op, expectedTypes);
} else if (op === 'any') {
const children = (filter as any).slice(1).map(f => {
const children = (filter).slice(1).map((f: FilterSpecification) => {
const types = {};

@@ -91,16 +91,16 @@ const child = _convertFilter(f, types);

});
return ['any'].concat(children);
return ['any'].concat(children as string[]);
} else if (op === 'all') {
const children = (filter as any).slice(1).map(f => _convertFilter(f, expectedTypes));
return children.length > 1 ? ['all'].concat(children) : [].concat(...children);
const children = (filter).slice(1).map(f => _convertFilter(f as FilterSpecification, expectedTypes));
return children.length > 1 ? ['all'].concat(children as string[]) : [].concat(...children);
} else if (op === 'none') {
return ['!', _convertFilter(['any'].concat(filter.slice(1) as any), {})];
return ['!', _convertFilter(['any'].concat(filter.slice(1) as string[]) as string[], {})];
} else if (op === 'in') {
converted = convertInOp(filter[1] as any, filter.slice(2));
converted = convertInOp(filter[1] as string, filter.slice(2));
} else if (op === '!in') {
converted = convertInOp(filter[1] as any, filter.slice(2), true);
converted = convertInOp(filter[1] as string, filter.slice(2), true);
} else if (op === 'has') {
converted = convertHasOp(filter[1] as any);
converted = convertHasOp(filter[1] as string);
} else if (op === '!has') {
converted = ['!', convertHasOp(filter[1] as any)];
converted = ['!', convertHasOp(filter[1] as string)];
} else {

@@ -107,0 +107,0 @@ converted = true;

@@ -159,3 +159,3 @@ import {default as createFilter, isExpressionFilter} from '.';

test('flattens nested, single child all expressions', () => {
const filter = [
const filter: FilterSpecification = [
'all',

@@ -175,3 +175,3 @@ [

const expected = [
const expected: FilterSpecification = [
'all',

@@ -184,3 +184,3 @@ [

false
],
] as FilterSpecification,
[

@@ -192,3 +192,3 @@ 'match',

false
]
] as FilterSpecification
];

@@ -195,0 +195,0 @@

@@ -21,3 +21,3 @@

/**
* Format a Mapbox GL Style. Returns a stringified style with its keys
* Format a MapLibre GL Style. Returns a stringified style with its keys
* sorted in the same order as the reference style.

@@ -32,3 +32,3 @@ *

* @private
* @param {Object} style a Mapbox GL Style
* @param {Object} style a MapLibre GL Style
* @param {number} [space] space argument to pass to `JSON.stringify`

@@ -35,0 +35,0 @@ * @returns {string} stringified formatted JSON

{
"name": "@maplibre/maplibre-gl-style-spec",
"description": "a specification for maplibre gl styles",
"version": "14.0.2",
"version": "15.0.0",
"author": "MapLibre",

@@ -6,0 +6,0 @@ "keywords": [

@@ -12,12 +12,32 @@ // Generated code; do not edit. Edit build/generate-style-spec.ts instead.

export type FilterSpecificationInputType = string | number | boolean;
export type FilterSpecification =
['has', string]
| ['!has', string]
| ['==', string, string | number | boolean]
| ['!=', string, string | number | boolean]
| ['>', string, string | number | boolean]
| ['>=', string, string | number | boolean]
| ['<', string, string | number | boolean]
| ['<=', string, string | number | boolean]
| Array<string | FilterSpecification>; // Can't type in, !in, all, any, none -- https://github.com/facebook/flow/issues/2443
// Lookup
| ['at', number, (number |string)[]]
| ['get', string, Record<string, unknown>?]
| ['has', string, Record<string, unknown>?]
| ['in', ...FilterSpecificationInputType[], FilterSpecificationInputType | FilterSpecificationInputType[]]
| ['index-of', FilterSpecificationInputType, FilterSpecificationInputType | FilterSpecificationInputType[]]
| ['length', string | string[]]
| ['slice', string | string[], number]
// Decision
| ['!', FilterSpecification]
| ['!=', string | FilterSpecification, FilterSpecificationInputType]
| ['<', string | FilterSpecification, FilterSpecificationInputType]
| ['<=', string | FilterSpecification, FilterSpecificationInputType]
| ['==', string | FilterSpecification, FilterSpecificationInputType]
| ['>', string | FilterSpecification, FilterSpecificationInputType]
| ['>=', string | FilterSpecification, FilterSpecificationInputType]
| ["all", ...FilterSpecification[], FilterSpecificationInputType]
| ["any", ...FilterSpecification[], FilterSpecificationInputType]
| ["case", ...FilterSpecification[], FilterSpecificationInputType]
| ["coalesce", ...FilterSpecification[], FilterSpecificationInputType]
| ["match", ...FilterSpecification[], FilterSpecificationInputType]
| ["within", ...FilterSpecification[], FilterSpecificationInputType]
// Used in convert.ts
| ["!in", ...FilterSpecification[], FilterSpecificationInputType]
| ["!has", ...FilterSpecification[], FilterSpecificationInputType]
| ["none", ...FilterSpecification[], FilterSpecificationInputType]
// Fallbak for others
| Array<string | FilterSpecification>

@@ -24,0 +44,0 @@ export type TransitionSpecification = {

@@ -15,3 +15,3 @@

/**
* Validate a Mapbox GL style against the style specification. This entrypoint,
* Validate a MapLibre GL style against the style specification. This entrypoint,
* `maplibre-gl-style-spec/lib/validate_style.min`, is designed to produce as

@@ -18,0 +18,0 @@ * small a browserify bundle as possible by omitting unnecessary functionality

@@ -632,5 +632,5 @@ import assert from 'assert';

* @param {string} id id of the desired source
* @returns {Object} source
* @returns {Source | undefined} source
*/
getSource(id: string): Source {
getSource(id: string): Source | undefined {
return this.sourceCaches[id] && this.sourceCaches[id].getSource();

@@ -637,0 +637,0 @@ }

@@ -28,2 +28,8 @@ import Point from '../util/point';

export type FeatureKey = {
bucketInstanceId: number;
featureIndex: number;
collisionGroupID: number;
};
/**

@@ -42,4 +48,4 @@ * A collision index used to prevent symbols from overlapping. It keep tracks of

class CollisionIndex {
grid: GridIndex;
ignoredGrid: GridIndex;
grid: GridIndex<FeatureKey>;
ignoredGrid: GridIndex<FeatureKey>;
transform: Transform;

@@ -54,4 +60,4 @@ pitchfactor: number;

transform: Transform,
grid = new GridIndex(transform.width + 2 * viewportPadding, transform.height + 2 * viewportPadding, 25),
ignoredGrid = new GridIndex(transform.width + 2 * viewportPadding, transform.height + 2 * viewportPadding, 25)
grid = new GridIndex<FeatureKey>(transform.width + 2 * viewportPadding, transform.height + 2 * viewportPadding, 25),
ignoredGrid = new GridIndex<FeatureKey>(transform.width + 2 * viewportPadding, transform.height + 2 * viewportPadding, 25)
) {

@@ -75,3 +81,3 @@ this.transform = transform;

posMatrix: mat4,
collisionGroupPredicate?: any
collisionGroupPredicate?: (key: FeatureKey) => boolean
): {

@@ -113,3 +119,3 @@ box: Array<number>;

pitchWithMap: boolean,
collisionGroupPredicate: any,
collisionGroupPredicate: (key: FeatureKey) => boolean,
circlePixelDiameter: number,

@@ -116,0 +122,0 @@ textPixelPadding: number

@@ -6,3 +6,3 @@ import GridIndex from './grid_index';

test('indexes features', () => {
const grid = new GridIndex(100, 100, 10);
const grid = new GridIndex<number>(100, 100, 10);
grid.insert(0, 4, 10, 6, 30);

@@ -22,3 +22,3 @@ grid.insert(1, 4, 10, 30, 12);

test('returns multiple copies of a key if multiple boxes were inserted with the same key', () => {
const grid = new GridIndex(100, 100, 10);
const grid = new GridIndex<number>(100, 100, 10);
const key = 123;

@@ -32,3 +32,3 @@ grid.insert(key, 3, 3, 4, 4);

test('circle-circle intersection', () => {
const grid = new GridIndex(100, 100, 10);
const grid = new GridIndex<number>(100, 100, 10);
grid.insertCircle(0, 50, 50, 10);

@@ -45,3 +45,3 @@ grid.insertCircle(1, 60, 60, 15);

test('circle-rectangle intersection', () => {
const grid = new GridIndex(100, 100, 10);
const grid = new GridIndex<number>(100, 100, 10);
grid.insertCircle(0, 50, 50, 10);

@@ -48,0 +48,0 @@ grid.insertCircle(1, 60, 60, 15);

@@ -0,1 +1,26 @@

type QueryArgs = {
hitTest: boolean;
circle?: {
x: number;
y: number;
radius: number;
};
seenUids: {
box: {
[_: number]: boolean;
};
circle: {
[_: number]: boolean;
};
};
};
type QueryResult<T> = {
key: T;
x1: number;
y1: number;
x2: number;
y2: number;
};
/**

@@ -14,5 +39,5 @@ * GridIndex is a data structure for testing the intersection of

*/
class GridIndex {
circleKeys: Array<any>;
boxKeys: Array<any>;
class GridIndex<T> {
circleKeys: Array<T>;
boxKeys: Array<T>;
boxCells: Array<Array<number>>;

@@ -62,3 +87,3 @@ circleCells: Array<Array<number>>;

insert(key: any, x1: number, y1: number, x2: number, y2: number) {
insert(key: T, x1: number, y1: number, x2: number, y2: number) {
this._forEachCell(x1, y1, x2, y2, this._insertBoxCell, this.boxUid++);

@@ -72,3 +97,3 @@ this.boxKeys.push(key);

insertCircle(key: any, x: number, y: number, radius: number) {
insertCircle(key: T, x: number, y: number, radius: number) {
// Insert circle into grid for all cells in the circumscribing square

@@ -83,18 +108,25 @@ // It's more than necessary (by a factor of 4/PI), but fast to insert

_insertBoxCell(x1: number, y1: number, x2: number, y2: number, cellIndex: number, uid: number) {
private _insertBoxCell(x1: number, y1: number, x2: number, y2: number, cellIndex: number, uid: number) {
this.boxCells[cellIndex].push(uid);
}
_insertCircleCell(x1: number, y1: number, x2: number, y2: number, cellIndex: number, uid: number) {
private _insertCircleCell(x1: number, y1: number, x2: number, y2: number, cellIndex: number, uid: number) {
this.circleCells[cellIndex].push(uid);
}
_query(x1: number, y1: number, x2: number, y2: number, hitTest: boolean, predicate?: any) {
private _query(x1: number, y1: number, x2: number, y2: number, hitTest: boolean, predicate?: (key: T) => boolean): Array<QueryResult<T>> {
if (x2 < 0 || x1 > this.width || y2 < 0 || y1 > this.height) {
return hitTest ? false : [];
return [];
}
const result = [];
const result: Array<QueryResult<T>> = [];
if (x1 <= 0 && y1 <= 0 && this.width <= x2 && this.height <= y2) {
if (hitTest) {
return true;
// Covers the entire grid, so collides with everything
return [{
key: null,
x1,
y1,
x2,
y2
}];
}

@@ -122,5 +154,4 @@ for (let boxUid = 0; boxUid < this.boxKeys.length; boxUid++) {

}
return predicate ? result.filter(predicate) : result;
} else {
const queryArgs = {
const queryArgs: QueryArgs = {
hitTest,

@@ -130,7 +161,16 @@ seenUids: {box: {}, circle: {}}

this._forEachCell(x1, y1, x2, y2, this._queryCell, result, queryArgs, predicate);
return hitTest ? result.length > 0 : result;
}
return result;
}
_queryCircle(x: number, y: number, radius: number, hitTest: boolean, predicate?: any) {
query(x1: number, y1: number, x2: number, y2: number): Array<QueryResult<T>> {
return this._query(x1, y1, x2, y2, false, null);
}
hitTest(x1: number, y1: number, x2: number, y2: number, predicate?: (key: T) => boolean): boolean {
return this._query(x1, y1, x2, y2, true, predicate).length > 0;
}
hitTestCircle(x: number, y: number, radius: number, predicate?: (key: T) => boolean): boolean {
// Insert circle into grid for all cells in the circumscribing square

@@ -143,3 +183,3 @@ // It's more than necessary (by a factor of 4/PI), but fast to insert

if (x2 < 0 || x1 > this.width || y2 < 0 || y1 > this.height) {
return hitTest ? false : [];
return false;
}

@@ -150,5 +190,5 @@

// and the calculation is more expensive
const result = [];
const queryArgs = {
hitTest,
const result: boolean[] = [];
const queryArgs: QueryArgs = {
hitTest: true,
circle: {x, y, radius},

@@ -158,20 +198,9 @@ seenUids: {box: {}, circle: {}}

this._forEachCell(x1, y1, x2, y2, this._queryCellCircle, result, queryArgs, predicate);
return hitTest ? result.length > 0 : result;
return result.length > 0;
}
query(x1: number, y1: number, x2: number, y2: number, predicate?: any): Array<any> {
return this._query(x1, y1, x2, y2, false, predicate) as any;
}
private _queryCell(x1: number, y1: number, x2: number, y2: number, cellIndex: number, result: Array<QueryResult<T>>, queryArgs: QueryArgs, predicate?: (key: T) => boolean): boolean {
const {seenUids, hitTest} = queryArgs;
const boxCell = this.boxCells[cellIndex];
hitTest(x1: number, y1: number, x2: number, y2: number, predicate?: any): boolean {
return this._query(x1, y1, x2, y2, true, predicate) as any;
}
hitTestCircle(x: number, y: number, radius: number, predicate?: any): boolean {
return this._queryCircle(x, y, radius, true, predicate) as any;
}
_queryCell(x1: number, y1: number, x2: number, y2: number, cellIndex: number, result: any, queryArgs: any, predicate?: any) {
const seenUids = queryArgs.seenUids;
const boxCell = this.boxCells[cellIndex];
if (boxCell !== null) {

@@ -183,2 +212,4 @@ const bboxes = this.bboxes;

const offset = boxUid * 4;
const key = this.boxKeys[boxUid];
if ((x1 <= bboxes[offset + 2]) &&

@@ -188,14 +219,13 @@ (y1 <= bboxes[offset + 3]) &&

(y2 >= bboxes[offset + 1]) &&
(!predicate || predicate(this.boxKeys[boxUid]))) {
if (queryArgs.hitTest) {
result.push(true);
(!predicate || predicate(key))) {
result.push({
key,
x1: bboxes[offset],
y1: bboxes[offset + 1],
x2: bboxes[offset + 2],
y2: bboxes[offset + 3]
});
if (hitTest) {
// true return value stops the query after first match
return true;
} else {
result.push({
key: this.boxKeys[boxUid],
x1: bboxes[offset],
y1: bboxes[offset + 1],
x2: bboxes[offset + 2],
y2: bboxes[offset + 3]
});
}

@@ -213,2 +243,4 @@ }

const offset = circleUid * 3;
const key = this.circleKeys[circleUid];
if (this._circleAndRectCollide(

@@ -222,17 +254,16 @@ circles[offset],

y2) &&
(!predicate || predicate(this.circleKeys[circleUid]))) {
if (queryArgs.hitTest) {
result.push(true);
(!predicate || predicate(key))) {
const x = circles[offset];
const y = circles[offset + 1];
const radius = circles[offset + 2];
result.push({
key,
x1: x - radius,
y1: y - radius,
x2: x + radius,
y2: y + radius
});
if (hitTest) {
// true return value stops the query after first match
return true;
} else {
const x = circles[offset];
const y = circles[offset + 1];
const radius = circles[offset + 2];
result.push({
key: this.circleKeys[circleUid],
x1: x - radius,
y1: y - radius,
x2: x + radius,
y2: y + radius
});
}

@@ -243,8 +274,11 @@ }

}
// false return to continue query
return false;
}
_queryCellCircle(x1: number, y1: number, x2: number, y2: number, cellIndex: number, result: any, queryArgs: any, predicate?: any) {
const circle = queryArgs.circle;
const seenUids = queryArgs.seenUids;
private _queryCellCircle(x1: number, y1: number, x2: number, y2: number, cellIndex: number, result: Array<boolean>, queryArgs: QueryArgs, predicate?: (key:T) => boolean): boolean {
const {circle, seenUids} = queryArgs;
const boxCell = this.boxCells[cellIndex];
if (boxCell !== null) {

@@ -256,2 +290,3 @@ const bboxes = this.bboxes;

const offset = boxUid * 4;
const key = this.boxKeys[boxUid];
if (this._circleAndRectCollide(

@@ -265,3 +300,3 @@ circle.x,

bboxes[offset + 3]) &&
(!predicate || predicate(this.boxKeys[boxUid]))) {
(!predicate || predicate(key))) {
result.push(true);

@@ -281,2 +316,3 @@ return true;

const offset = circleUid * 3;
const key = this.circleKeys[circleUid];
if (this._circlesCollide(

@@ -289,3 +325,3 @@ circles[offset],

circle.radius) &&
(!predicate || predicate(this.circleKeys[circleUid]))) {
(!predicate || predicate(key))) {
result.push(true);

@@ -299,3 +335,11 @@ return true;

_forEachCell(x1: number, y1: number, x2: number, y2: number, fn: any, arg1: any, arg2?: any, predicate?: any) {
private _forEachCell<TArg>(
x1: number,
y1: number,
x2: number,
y2: number,
fn: (x1: number, y1: number, x2: number, y2: number, cellIndex: number, arg1: TArg, arg2?: QueryArgs, predicate?: (key: T) => boolean) => boolean | void,
arg1: TArg,
arg2?: QueryArgs,
predicate?: (key: T) => boolean) {
const cx1 = this._convertToXCellCoord(x1);

@@ -314,11 +358,11 @@ const cy1 = this._convertToYCellCoord(y1);

_convertToXCellCoord(x: number) {
private _convertToXCellCoord(x: number) {
return Math.max(0, Math.min(this.xCellCount - 1, Math.floor(x * this.xScale)));
}
_convertToYCellCoord(y: number) {
private _convertToYCellCoord(y: number) {
return Math.max(0, Math.min(this.yCellCount - 1, Math.floor(y * this.yScale)));
}
_circlesCollide(x1: number, y1: number, r1: number, x2: number, y2: number, r2: number): boolean {
private _circlesCollide(x1: number, y1: number, r1: number, x2: number, y2: number, r2: number): boolean {
const dx = x2 - x1;

@@ -330,3 +374,3 @@ const dy = y2 - y1;

_circleAndRectCollide(
private _circleAndRectCollide(
circleX: number,

@@ -333,0 +377,0 @@ circleY: number,

@@ -13,2 +13,4 @@ import CollisionIndex from './collision_index';

import type StyleLayer from '../style/style_layer';
import {PossiblyEvaluated} from '../style/properties';
import type {SymbolLayoutProps, SymbolLayoutPropsPossiblyEvaluated} from '../style/style_layer/symbol_style_layer_properties';

@@ -174,29 +176,32 @@ import type Tile from '../source/tile';

export type VariableOffset = {
textOffset: [number, number];
width: number;
height: number;
anchor: TextAnchor;
textBoxScale: number;
prevAnchor?: TextAnchor;
textOffset: [number, number];
width: number;
height: number;
anchor: TextAnchor;
textBoxScale: number;
prevAnchor?: TextAnchor;
};
type TileLayerParameters = {
bucket: SymbolBucket;
layout: any;
posMatrix: mat4;
textLabelPlaneMatrix: mat4;
labelToScreenMatrix: mat4;
scale: number;
textPixelRatio: number;
holdingForFade: boolean;
collisionBoxArray: CollisionBoxArray;
partiallyEvaluatedTextSize: any;
collisionGroup: any;
bucket: SymbolBucket;
layout: PossiblyEvaluated<SymbolLayoutProps, SymbolLayoutPropsPossiblyEvaluated>;
posMatrix: mat4;
textLabelPlaneMatrix: mat4;
labelToScreenMatrix: mat4;
scale: number;
textPixelRatio: number;
holdingForFade: boolean;
collisionBoxArray: CollisionBoxArray;
partiallyEvaluatedTextSize: {
uSize: number;
uSizeT: number;
};
collisionGroup: CollisionGroup;
};
export type BucketPart = {
sortKey?: number | void;
symbolInstanceStart: number;
symbolInstanceEnd: number;
parameters: TileLayerParameters;
sortKey?: number | void;
symbolInstanceStart: number;
symbolInstanceEnd: number;
parameters: TileLayerParameters;
};

@@ -258,3 +263,3 @@

getBucketParts(results: Array<BucketPart>, styleLayer: StyleLayer, tile: Tile, sortAcrossTiles: boolean) {
const symbolBucket = (tile.getBucket(styleLayer) as any as SymbolBucket);
const symbolBucket = (tile.getBucket(styleLayer) as SymbolBucket);
const bucketFeatureIndex = tile.latestFeatureIndex;

@@ -406,3 +411,3 @@ if (!symbolBucket || !bucketFeatureIndex || styleLayer.id !== symbolBucket.layerIds[0])

placeLayerBucketPart(bucketPart: any, seenCrossTileIDs: {
placeLayerBucketPart(bucketPart: BucketPart, seenCrossTileIDs: {
[k in string | number]: boolean;

@@ -889,3 +894,3 @@ }, showCollisionBoxes: boolean) {

for (const tile of tiles) {
const symbolBucket = (tile.getBucket(styleLayer) as any as SymbolBucket);
const symbolBucket = (tile.getBucket(styleLayer) as SymbolBucket);
if (symbolBucket && tile.latestFeatureIndex && styleLayer.id === symbolBucket.layerIds[0]) {

@@ -892,0 +897,0 @@ this.updateBucketOpacities(symbolBucket, seenCrossTileIDs, tile.collisionBoxArray);

@@ -83,3 +83,3 @@ import fs from 'fs';

// Prefer zero width spaces when breaking lines. Zero width spaces are used by Mapbox data sources as a hint that
// Prefer zero width spaces when breaking lines. Zero width spaces are used by MapLibre data sources as a hint that
// a position is ideal for breaking.

@@ -86,0 +86,0 @@ const expectedZeroWidthSpaceBreak = require('../../test/expected/text-shaping-zero-width-space.json');

@@ -56,2 +56,7 @@ import Anchor from './anchor';

type ShapedTextOrientations = {
vertical: Shaping | false;
horizontal: Record<TextJustify, Shaping>;
};
export type TextAnchor = 'center' | 'left' | 'right' | 'top' | 'bottom' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';

@@ -176,3 +181,10 @@

const sizes: {[k: string]: any} = {};
const sizes: Sizes = {
// Filled in below, if *SizeData.kind is 'composite'
// compositeIconSizes: undefined,
// compositeTextSizes: undefined,
layoutIconSize: unevaluatedLayoutValues['icon-size'].possiblyEvaluate(new EvaluationParameters(bucket.zoom + 1), canonical),
layoutTextSize: unevaluatedLayoutValues['text-size'].possiblyEvaluate(new EvaluationParameters(bucket.zoom + 1), canonical),
textMaxSize: unevaluatedLayoutValues['text-size'].possiblyEvaluate(new EvaluationParameters(18))
} as Sizes;

@@ -195,6 +207,2 @@ if (bucket.textSizeData.kind === 'composite') {

sizes.layoutTextSize = unevaluatedLayoutValues['text-size'].possiblyEvaluate(new EvaluationParameters(bucket.zoom + 1), canonical);
sizes.layoutIconSize = unevaluatedLayoutValues['icon-size'].possiblyEvaluate(new EvaluationParameters(bucket.zoom + 1), canonical);
sizes.textMaxSize = unevaluatedLayoutValues['text-size'].possiblyEvaluate(new EvaluationParameters(18));
const lineHeight = layout.get('text-line-height') * ONE_EM;

@@ -211,4 +219,4 @@ const textAlongLine = layout.get('text-rotation-alignment') === 'map' && layout.get('symbol-placement') !== 'point';

const shapedTextOrientations: {[k: string]: any} = {
horizontal: {},
const shapedTextOrientations: ShapedTextOrientations = {
horizontal: {} as Record<TextJustify, Shaping>,
vertical: undefined

@@ -235,3 +243,3 @@ };

} else {
textOffset = (layout.get('text-offset').evaluate(feature, {}, canonical).map(t => t * ONE_EM) as any);
textOffset = (layout.get('text-offset').evaluate(feature, {}, canonical).map(t => t * ONE_EM) as [number, number]);
}

@@ -334,3 +342,3 @@ }

if (shapedText || shapedIcon) {
addFeature(bucket, feature, shapedTextOrientations, shapedIcon, imageMap, sizes as Sizes, layoutTextSize, layoutIconSize, textOffset, isSDFIcon, canonical);
addFeature(bucket, feature, shapedTextOrientations, shapedIcon, imageMap, sizes, layoutTextSize, layoutIconSize, textOffset, isSDFIcon, canonical);
}

@@ -368,3 +376,3 @@ }

feature: SymbolFeature,
shapedTextOrientations: any,
shapedTextOrientations: ShapedTextOrientations,
shapedIcon: PositionedIcon,

@@ -557,5 +565,3 @@ imageMap: {[_: string]: StyleImage},

function getDefaultHorizontalShaping(
horizontalShaping: {
[_ in TextJustify]: Shaping;
}
horizontalShaping: Record<TextJustify, Shaping>
): Shaping | null {

@@ -578,3 +584,3 @@ // We don't care which shaping we get because this is used for collision purposes

line: Array<Point>,
shapedTextOrientations: any,
shapedTextOrientations: ShapedTextOrientations,
shapedIcon: PositionedIcon | void,

@@ -611,3 +617,3 @@ imageMap: {[_: string]: StyleImage},

let verticalPlacedIconSymbolIndex = -1;
const placedTextSymbolIndices: {[k: string]: any} = {};
const placedTextSymbolIndices: {[k: string]: number} = {};
let key = murmur3('');

@@ -618,3 +624,3 @@

if (layer._unevaluatedLayout.getValue('text-radial-offset') === undefined) {
[textOffset0, textOffset1] = (layer.layout.get('text-offset').evaluate(feature, {}, canonical).map(t => t * ONE_EM) as any);
[textOffset0, textOffset1] = (layer.layout.get('text-offset').evaluate(feature, {}, canonical).map(t => t * ONE_EM) as [number, number]);
} else {

@@ -706,3 +712,4 @@ textOffset0 = layer.layout.get('text-radial-offset').evaluate(feature, {}, canonical) * ONE_EM;

for (const justification in shapedTextOrientations.horizontal) {
const justifications = Object.keys(shapedTextOrientations.horizontal) as TextJustify[];
for (const justification of justifications) {
const shaping = shapedTextOrientations.horizontal[justification];

@@ -722,3 +729,3 @@

shapedTextOrientations.vertical ? WritingMode.horizontal : WritingMode.horizontalOnly,
singleLine ? (Object.keys(shapedTextOrientations.horizontal) as any) : [justification],
singleLine ? justifications : [justification],
placedTextSymbolIndices, placedIconSymbolIndex, sizes, canonical);

@@ -809,3 +816,3 @@

function anchorIsTooClose(bucket: any, text: string, repeatDistance: number, anchor: Point) {
function anchorIsTooClose(bucket: SymbolBucket, text: string, repeatDistance: number, anchor: Point) {
const compareText = bucket.compareText;

@@ -812,0 +819,0 @@ if (!(text in compareText)) {

@@ -39,3 +39,3 @@ import {bindAll, extend, warnOnce, clamp, wrap, ease as defaultEasing, pick} from '../util/util';

* container: 'map',
* style: 'mapbox://styles/mapbox/streets-v11',
* style: 'https://demotiles.maplibre.org/style.json',
* center: [-73.5804, 45.53483],

@@ -163,3 +163,2 @@ * pitch: 60,

* var {lng, lat} = map.getCenter();
* @see Tutorial: [Use Mapbox GL JS in a React app](https://docs.mapbox.com/help/tutorials/use-mapbox-gl-js-with-react/#store-the-new-coordinates)
*/

@@ -166,0 +165,0 @@ getCenter(): LngLat { return new LngLat(this.transform.center.lng, this.transform.center.lat); }

@@ -13,4 +13,4 @@ import AttributionControl from './attribution_control';

layers: [],
owner: 'mapbox',
id: 'streets-v10',
owner: 'mapblibre',
id: 'demotiles',
},

@@ -21,16 +21,16 @@ hash: true

describe('AttributionControl', () => {
let map;
let map;
beforeEach(() => {
setWebGlContext();
setPerformance();
setMatchMedia();
map = createMap();
});
beforeEach(() => {
setWebGlContext();
setPerformance();
setMatchMedia();
map = createMap();
});
afterEach(() => {
map.remove();
});
afterEach(() => {
map.remove();
});
describe('AttributionControl', () => {
test('appears in bottom-right by default', () => {

@@ -269,107 +269,183 @@ map.addControl(new AttributionControl());

test('details is set correct for compact view after map load. In particular, it should NOT contain the attribute open="".', () => {
const attributionControl = new AttributionControl({
compact: true
});
describe('AttributionControl test regarding the HTML elements details and summary', () => {
describe('Details is set correct for compact view', () => {
test('It should NOT contain the attribute open="" on first load.', () => {
const attributionControl = new AttributionControl({
compact: true
});
map.addControl(attributionControl);
expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')[0].getAttribute('open')).toBeNull();
});
map.addControl(attributionControl);
expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(`
NodeList [
<details
class="maplibregl-ctrl maplibregl-ctrl-attrib mapboxgl-ctrl mapboxgl-ctrl-attrib maplibregl-compact mapboxgl-compact maplibregl-attrib-empty mapboxgl-attrib-empty"
>
<summary
aria-label="Toggle attribution"
class="maplibregl-ctrl-attrib-button mapboxgl-ctrl-attrib-button"
title="Toggle attribution"
/>
<div
class="maplibregl-ctrl-attrib-inner mapboxgl-ctrl-attrib-inner"
/>
</details>,
]
`);
});
test('It SHOULD contain the attribute open="" after click on summary.', () => {
const attributionControl = new AttributionControl({
compact: true
});
map.addControl(attributionControl);
const container = map.getContainer();
const toggle = container.querySelector('.maplibregl-ctrl-attrib-button');
test('details is set correct for compact view after click on summary. In particular, it SHOULD contain the attribute open="".', () => {
const attributionControl = new AttributionControl({
compact: true
simulate.click(toggle);
expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')[0].getAttribute('open')).toBe('');
});
map.addControl(attributionControl);
const container = map.getContainer();
const toggle = container.querySelector('.maplibregl-ctrl-attrib-button');
simulate.click(toggle);
test('It should NOT contain the attribute open="" after two clicks on summary.', () => {
const attributionControl = new AttributionControl({
compact: true
});
map.addControl(attributionControl);
const container = map.getContainer();
const toggle = container.querySelector('.maplibregl-ctrl-attrib-button');
expect(container.querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(`
NodeList [
<details
class="maplibregl-ctrl maplibregl-ctrl-attrib mapboxgl-ctrl mapboxgl-ctrl-attrib maplibregl-compact mapboxgl-compact maplibregl-attrib-empty mapboxgl-attrib-empty maplibregl-compact-show mapboxgl-compact-show"
open=""
>
<summary
aria-label="Toggle attribution"
class="maplibregl-ctrl-attrib-button mapboxgl-ctrl-attrib-button"
title="Toggle attribution"
/>
<div
class="maplibregl-ctrl-attrib-inner mapboxgl-ctrl-attrib-inner"
/>
</details>,
]
`);
simulate.click(toggle);
expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')[0].getAttribute('open')).toBe('');
simulate.click(toggle);
expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')[0].getAttribute('open')).toBeNull();
});
});
test('details is set correct for compact view after two clicks on summary. In particular, it should NOT contain the attribute open="".', () => {
const attributionControl = new AttributionControl({
compact: true
describe('Details is set correct for default view (compact === undefined)', () => {
test('It should NOT contain the attribute open="" if offsetWidth <= 640.', () => {
Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 640, configurable: true});
const attributionControl = new AttributionControl({
});
map.addControl(attributionControl);
expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')[0].getAttribute('open')).toBeNull();
});
map.addControl(attributionControl);
const container = map.getContainer();
const toggle = container.querySelector('.maplibregl-ctrl-attrib-button');
simulate.click(toggle);
simulate.click(toggle);
test('It SHOULD contain the attribute open="" if offsetWidth > 640.', () => {
Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 641, configurable: true});
const attributionControl = new AttributionControl({
});
map.addControl(attributionControl);
expect(container.querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(`
NodeList [
<details
class="maplibregl-ctrl maplibregl-ctrl-attrib mapboxgl-ctrl mapboxgl-ctrl-attrib maplibregl-compact mapboxgl-compact maplibregl-attrib-empty mapboxgl-attrib-empty"
>
<summary
aria-label="Toggle attribution"
class="maplibregl-ctrl-attrib-button mapboxgl-ctrl-attrib-button"
title="Toggle attribution"
/>
<div
class="maplibregl-ctrl-attrib-inner mapboxgl-ctrl-attrib-inner"
/>
</details>,
]
`);
expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')[0].getAttribute('open')).toBe('');
});
test('The attribute open="" SHOULD change on resize from size > 640 to <= 640 and and vice versa.', () => {
Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 640, configurable: true});
const attributionControl = new AttributionControl({
});
map.addControl(attributionControl);
expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')[0].getAttribute('open')).toBeNull();
Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 641, configurable: true});
map.resize();
expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')[0].getAttribute('open')).toBe('');
Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 640, configurable: true});
map.resize();
expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')[0].getAttribute('open')).toBeNull();
});
test('The attribute open="" should NOT change on resize from > 640 to another > 640.', () => {
Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 641, configurable: true});
const attributionControl = new AttributionControl({
});
map.addControl(attributionControl);
expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')[0].getAttribute('open')).toBe('');
Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 650, configurable: true});
map.resize();
expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')[0].getAttribute('open')).toBe('');
Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 641, configurable: true});
map.resize();
expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')[0].getAttribute('open')).toBe('');
});
test('The attribute open="" should NOT change on resize from <= 640 to another <= 640 if it is closed.', () => {
Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 640, configurable: true});
const attributionControl = new AttributionControl({
});
map.addControl(attributionControl);
expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')[0].getAttribute('open')).toBeNull();
Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 630, configurable: true});
map.resize();
expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')[0].getAttribute('open')).toBeNull();
Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 640, configurable: true});
map.resize();
expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')[0].getAttribute('open')).toBeNull();
});
test('The attribute open="" should NOT change on resize from <= 640 to another <= 640 if it is open.', () => {
Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 640, configurable: true});
const attributionControl = new AttributionControl({
});
map.addControl(attributionControl);
const toggle = map.getContainer().querySelector('.maplibregl-ctrl-attrib-button');
simulate.click(toggle);
expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')[0].getAttribute('open')).toBe('');
Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 630, configurable: true});
map.resize();
expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')[0].getAttribute('open')).toBe('');
Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 640, configurable: true});
map.resize();
expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')[0].getAttribute('open')).toBe('');
});
});
test('details is set correct for default view. In particular, it SHOULD contain the attribute open="".', () => {
const attributionControl = new AttributionControl({
describe('Details is set correct for default view (compact === false)', () => {
test('It SHOULD contain the attribute open="" if offsetWidth <= 640.', () => {
Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 640, configurable: true});
const attributionControl = new AttributionControl({
compact: false
});
map.addControl(attributionControl);
expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')[0].getAttribute('open')).toBe('');
});
map.addControl(attributionControl);
expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')).toMatchInlineSnapshot(`
NodeList [
<details
class="maplibregl-ctrl maplibregl-ctrl-attrib mapboxgl-ctrl mapboxgl-ctrl-attrib maplibregl-attrib-empty mapboxgl-attrib-empty maplibregl-compact mapboxgl-compact"
open=""
>
<summary
aria-label="Toggle attribution"
class="maplibregl-ctrl-attrib-button mapboxgl-ctrl-attrib-button"
title="Toggle attribution"
/>
<div
class="maplibregl-ctrl-attrib-inner mapboxgl-ctrl-attrib-inner"
/>
</details>,
]
`);
test('It SHOULD contain the attribute open="" if offsetWidth > 640.', () => {
Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 641, configurable: true});
const attributionControl = new AttributionControl({
compact: false
});
map.addControl(attributionControl);
expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')[0].getAttribute('open')).toBe('');
});
test('The attribute open="" should NOT change on resize.', () => {
Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 640, configurable: true});
const attributionControl = new AttributionControl({
compact: false
});
map.addControl(attributionControl);
expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')[0].getAttribute('open')).toBe('');
Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 641, configurable: true});
map.resize();
expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')[0].getAttribute('open')).toBe('');
Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 640, configurable: true});
map.resize();
expect(map.getContainer().querySelectorAll('.maplibregl-ctrl-attrib')[0].getAttribute('open')).toBe('');
});
});
});

@@ -13,7 +13,7 @@ import DOM from '../../util/dom';

/**
* An `AttributionControl` control presents the map's [attribution information](https://docs.mapbox.com/help/how-mapbox-works/attribution/).
* An `AttributionControl` control presents the map's attribution information.
*
* @implements {IControl}
* @param {Object} [options]
* @param {boolean} [options.compact] If `true`, force a compact attribution that shows the full attribution on mouse hover. If `false`, force the full attribution control. The default is a responsive attribution that collapses when the map is less than 640 pixels wide. **Attribution should not be collapsed if it can comfortably fit on the map. `compact` should only be used to modify default attribution when map size makes it impossible to fit [default attribution](https://docs.mapbox.com/help/how-mapbox-works/attribution/) and when the automatic compact resizing for default settings are not sufficient.**
* @param {boolean} [options.compact] If `true`, force a compact attribution that shows the full attribution on mouse hover. If `false`, force the full attribution control. The default is a responsive attribution that collapses when the map is less than 640 pixels wide. **Attribution should not be collapsed if it can comfortably fit on the map. `compact` should only be used to modify default attribution when map size makes it impossible to fit default attribution and when the automatic compact resizing for default settings are not sufficient.**
* @param {string | Array<string>} [options.customAttribution] String or strings to show in addition to any other attributions.

@@ -52,4 +52,2 @@ * @example

onAdd(map: Map) {
const compact = this.options && this.options.compact;
this._map = map;

@@ -62,8 +60,3 @@ this._container = DOM.create('details', 'maplibregl-ctrl maplibregl-ctrl-attrib mapboxgl-ctrl mapboxgl-ctrl-attrib');

if (compact) {
this._container.classList.add('maplibregl-compact', 'mapboxgl-compact');
} else {
this._container.setAttribute('open', '');
}
this._updateCompact();
this._updateAttributions();

@@ -73,8 +66,4 @@

this._map.on('sourcedata', this._updateData);
this._map.on('resize', this._updateCompact);
if (compact === undefined) {
this._map.on('resize', this._updateCompact);
this._updateCompact();
}
return this._container;

@@ -174,6 +163,17 @@ }

_updateCompact() {
if (this._map.getCanvasContainer().offsetWidth <= 640) {
this._container.classList.add('maplibregl-compact', 'mapboxgl-compact');
const compact = this.options && this.options.compact;
if (this._map.getCanvasContainer().offsetWidth <= 640 || compact) {
if (compact === false) {
this._container.setAttribute('open', '');
} else {
if (!this._container.classList.contains('maplibregl-compact')) {
this._container.removeAttribute('open');
this._container.classList.add('maplibregl-compact', 'mapboxgl-compact');
}
}
} else {
this._container.classList.remove('maplibregl-compact', 'maplibregl-compact-show', 'mapboxgl-compact', 'mapboxgl-compact-show');
this._container.setAttribute('open', '');
if (this._container.classList.contains('maplibregl-compact')) {
this._container.classList.remove('maplibregl-compact', 'maplibregl-compact-show', 'mapboxgl-compact', 'mapboxgl-compact-show');
}
}

@@ -180,0 +180,0 @@ }

@@ -9,3 +9,3 @@ export type ControlPosition = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';

* Controls must implement `onAdd` and `onRemove`, and must own an
* element, which is often a `div` element. To use Mapbox GL JS's
* element, which is often a `div` element. To use MapLibre GL JS's
* default control styling, add the `maplibregl-ctrl` class to your control's

@@ -12,0 +12,0 @@ * node.

@@ -15,2 +15,4 @@ import {Event} from '../util/evented';

export type MapSourceDataType = 'content' | 'metadata';
export type MapLayerEventType = {

@@ -48,3 +50,3 @@ click: MapLayerMouseEvent;

sourceId: string;
sourceDataType: 'metadata' | 'content';
sourceDataType: MapSourceDataType;
tile: any;

@@ -286,3 +288,3 @@ }

* - `'source'`: The non-tile data associated with any source
* - `'style'`: The [style](https://www.mapbox.com/mapbox-gl-style-spec/) used by the map
* - `'style'`: The [style](https://maplibre.org/maplibre-gl-js-docs/style-spec/) used by the map
*

@@ -293,3 +295,3 @@ * @typedef {Object} MapDataEvent

* @property {boolean} [isSourceLoaded] True if the event has a `dataType` of `source` and the source has no outstanding network requests.
* @property {Object} [source] The [style spec representation of the source](https://www.mapbox.com/mapbox-gl-style-spec/#sources) if the event has a `dataType` of `source`.
* @property {Object} [source] The [style spec representation of the source](https://maplibre.org/maplibre-gl-js-docs/style-spec/#sources) if the event has a `dataType` of `source`.
* @property {string} [sourceDataType] Included if the event has a `dataType` of `source` and the event signals

@@ -299,3 +301,3 @@ * that internal data has been received or changed. Possible values are `metadata`, `content` and `visibility`.

* the event is related to loading of a tile.
* @property {Coordinate} [coord] The coordinate of the tile if the event has a `dataType` of `source` and
* @property {Coordinates} [coord] The coordinate of the tile if the event has a `dataType` of `source` and
* the event is related to loading of a tile.

@@ -314,2 +316,3 @@ * @example

dataType: string;
sourceDataType: MapSourceDataType;
};

@@ -322,2 +325,7 @@

export interface MapStyleImageMissingEvent extends MapLibreEvent {
type: 'styleimagemissing';
id: string;
}
/**

@@ -345,2 +353,3 @@ * MapEventType - a mapping between the event name and the event value

styledata: MapStyleDataEvent;
styleimagemissing: MapStyleImageMissingEvent;

@@ -1335,3 +1344,3 @@ boxzoomcancel: MapLibreZoomEvent;

* });
* @see [Generate and add a missing icon to the map](https://mapbox.com/mapbox-gl-js/example/add-image-missing-generated/)
* @see [Generate and add a missing icon to the map](https://maplibre.org/maplibre-gl-js-docs/example/add-image-missing-generated/)
*/ | 'styleimagemissing'

@@ -1338,0 +1347,0 @@

@@ -234,3 +234,3 @@ import DOM from '../util/dom';

* Attaches the `Marker` to a `Map` object.
* @param {Map} map The Mapbox GL JS map to add the marker to.
* @param {Map} map The MapLibre GL JS map to add the marker to.
* @returns {Marker} `this`

@@ -237,0 +237,0 @@ * @example

@@ -110,3 +110,3 @@ import {extend, bindAll} from '../util/util';

constructor(options: PopupOptions) {
constructor(options?: PopupOptions) {
super();

@@ -120,3 +120,3 @@ this.options = extend(Object.create(defaultOptions), options);

*
* @param {Map} map The Mapbox GL JS map to add the popup to.
* @param {Map} map The MapLibre GL JS map to add the popup to.
* @returns {Popup} `this`

@@ -123,0 +123,0 @@ * @example

@@ -6,3 +6,2 @@ import {extend, warnOnce, isWorker} from './util';

import webpSupported from './webp_supported';
import offscreenCanvasSupported from './offscreen_canvas_supported';

@@ -327,2 +326,11 @@ import type {Callback} from '../types/callback';

function arrayBufferToCanvasImageSource(data: ArrayBuffer, callback: (err?: Error | null, image?: CanvasImageSource | null) => void, cacheControl?: string | null, expires?: string | null) {
const imageBitmapSupported = typeof createImageBitmap === 'function';
if (imageBitmapSupported) {
arrayBufferToImageBitmap(data, callback);
} else {
arrayBufferToImage(data, callback, cacheControl, expires);
}
}
let imageQueue, numImageRequests;

@@ -383,7 +391,3 @@ export const resetImageRequestQueue = () => {

} else if (data) {
if (offscreenCanvasSupported()) {
arrayBufferToImageBitmap(data, callback);
} else {
arrayBufferToImage(data, callback, cacheControl, expires);
}
arrayBufferToCanvasImageSource(data, callback, cacheControl, expires);
}

@@ -390,0 +394,0 @@ });

@@ -17,3 +17,3 @@ import browser from './browser';

const frame = browser.frame(() => {
done.fail();
done('test failed: browser.frame callback was called');
});

@@ -20,0 +20,0 @@ frame.cancel();

@@ -102,3 +102,3 @@ import {extend} from './util';

fire(event: Event, properties?: any) {
fire(event: Event | string, properties?: any) {
// Compatibility with (type: string, properties: Object) signature from previous versions.

@@ -105,0 +105,0 @@ // See https://github.com/mapbox/mapbox-gl-js/issues/6522,

import Map from '../../ui/map';
import {extend} from '../../util/util';
import Dispatcher from '../../util/dispatcher';
import gl from 'gl';
export function createMap(options, callback) {
export function createMap(options?, callback?) {
const container = window.document.createElement('div');

@@ -41,3 +42,3 @@ const defaultOptions = {

// Add webgl context with the supplied GL
export function setWebGlContext () {
export function setWebGlContext() {
const originalGetContext = global.HTMLCanvasElement.prototype.getContext;

@@ -58,3 +59,3 @@

export function setPerformance () {
export function setPerformance() {
window.performance.mark = jest.fn();

@@ -65,3 +66,3 @@ window.performance.clearMeasures = jest.fn();

export function setMatchMedia () {
export function setMatchMedia() {
// https://jestjs.io/docs/manual-mocks#mocking-methods-which-are-not-implemented-in-jsdom

@@ -82,1 +83,23 @@ Object.defineProperty(window, 'matchMedia', {

}
export function getWrapDispatcher() {
const wrapDispatcher = (dispatcher) => {
return {
getActor() {
return dispatcher;
}
} as any as Dispatcher;
};
return wrapDispatcher;
}
export function getMockDispatcher() {
const wrapDispatcher = getWrapDispatcher();
const mockDispatcher = wrapDispatcher({
send() {}
});
return mockDispatcher;
}

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc