@mapbox/mapbox-gl-style-spec 14.0.0 → 14.1.0
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/diff.js +5 -4
- package/dist/index.cjs +567 -637
- package/dist/index.cjs.map +1 -1
- package/dist/index.es.js +567 -637
- package/dist/index.es.js.map +1 -1
- package/expression/compound_expression.js +20 -12
- package/expression/definitions/index.js +47 -2
- package/expression/evaluation_context.js +4 -4
- package/expression/index.js +5 -4
- package/expression/parsing_context.js +3 -2
- package/flow-typed/sinon.js +1 -0
- package/package.json +1 -1
- package/reference/v8.json +481 -621
- package/types.js +23 -4
- package/validate/validate_property.js +5 -2
- package/validate/validate_source.js +9 -3
- package/validate/validate_terrain.js +2 -0
|
@@ -21,17 +21,23 @@ class CompoundExpression implements Expression {
|
|
|
21
21
|
type: Type;
|
|
22
22
|
_evaluate: Evaluate;
|
|
23
23
|
args: Array<Expression>;
|
|
24
|
+
_overloadIndex: number;
|
|
24
25
|
|
|
25
26
|
static definitions: {[_: string]: Definition };
|
|
26
27
|
|
|
27
|
-
constructor(name: string, type: Type, evaluate: Evaluate, args: Array<Expression
|
|
28
|
+
constructor(name: string, type: Type, evaluate: Evaluate, args: Array<Expression>, overloadIndex: number) {
|
|
28
29
|
this.name = name;
|
|
29
30
|
this.type = type;
|
|
30
31
|
this._evaluate = evaluate;
|
|
31
32
|
this.args = args;
|
|
33
|
+
this._overloadIndex = overloadIndex;
|
|
32
34
|
}
|
|
33
35
|
|
|
34
36
|
evaluate(ctx: EvaluationContext): Value {
|
|
37
|
+
if (!this._evaluate) { // restore evaluate function after transfer between threads
|
|
38
|
+
const definition = CompoundExpression.definitions[this.name];
|
|
39
|
+
this._evaluate = Array.isArray(definition) ? definition[2] : definition.overloads[this._overloadIndex][1];
|
|
40
|
+
}
|
|
35
41
|
return this._evaluate(ctx, this.args);
|
|
36
42
|
}
|
|
37
43
|
|
|
@@ -62,14 +68,18 @@ class CompoundExpression implements Expression {
|
|
|
62
68
|
[[definition[1], definition[2]]] :
|
|
63
69
|
definition.overloads;
|
|
64
70
|
|
|
65
|
-
const
|
|
66
|
-
!Array.isArray(signature) || // varags
|
|
67
|
-
signature.length === args.length - 1 // correct param count
|
|
68
|
-
));
|
|
71
|
+
const overloadParams = [];
|
|
69
72
|
|
|
70
73
|
let signatureContext: ParsingContext = (null: any);
|
|
71
74
|
|
|
72
|
-
|
|
75
|
+
let overloadIndex = -1;
|
|
76
|
+
|
|
77
|
+
for (const [params, evaluate] of availableOverloads) {
|
|
78
|
+
if (Array.isArray(params) && params.length !== args.length - 1) continue; // param count doesn't match
|
|
79
|
+
|
|
80
|
+
overloadParams.push(params);
|
|
81
|
+
overloadIndex++;
|
|
82
|
+
|
|
73
83
|
// Use a fresh context for each attempted signature so that, if
|
|
74
84
|
// we eventually succeed, we haven't polluted `context.errors`.
|
|
75
85
|
signatureContext = new ParsingContext(context.registry, context.path, null, context.scope, undefined, context.options);
|
|
@@ -111,19 +121,17 @@ class CompoundExpression implements Expression {
|
|
|
111
121
|
}
|
|
112
122
|
|
|
113
123
|
if (signatureContext.errors.length === 0) {
|
|
114
|
-
return new CompoundExpression(op, type, evaluate, parsedArgs);
|
|
124
|
+
return new CompoundExpression(op, type, evaluate, parsedArgs, overloadIndex);
|
|
115
125
|
}
|
|
116
126
|
}
|
|
117
127
|
|
|
118
128
|
assert(!signatureContext || signatureContext.errors.length > 0);
|
|
119
129
|
|
|
120
|
-
if (
|
|
130
|
+
if (overloadParams.length === 1) {
|
|
121
131
|
context.errors.push(...signatureContext.errors);
|
|
122
132
|
} else {
|
|
123
|
-
const expected =
|
|
124
|
-
const signatures = expected
|
|
125
|
-
.map(([params]) => stringifySignature(params))
|
|
126
|
-
.join(' | ');
|
|
133
|
+
const expected = overloadParams.length ? overloadParams : availableOverloads.map(([params]) => params);
|
|
134
|
+
const signatures = expected.map(stringifySignature).join(' | ');
|
|
127
135
|
|
|
128
136
|
const actualTypes = [];
|
|
129
137
|
// For error message, re-parse arguments without trying to
|
|
@@ -145,12 +145,57 @@ function get(key: string, obj: {[string]: any}) {
|
|
|
145
145
|
return typeof v === 'undefined' ? null : v;
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
+
function coerceValue(type: 'string' | 'number' | 'boolean' | 'color', value: any): any {
|
|
149
|
+
switch (type) {
|
|
150
|
+
case 'string': return String(value);
|
|
151
|
+
case 'number': return +value;
|
|
152
|
+
case 'boolean': return !!value;
|
|
153
|
+
case 'color': return Color.parse(value);
|
|
154
|
+
}
|
|
155
|
+
return value;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function clampToAllowedNumber(value: number, min: number | void, max: number | void, step: number | void): number {
|
|
159
|
+
if (step !== undefined) {
|
|
160
|
+
value = step * Math.round(value / step);
|
|
161
|
+
}
|
|
162
|
+
if (min !== undefined && value < min) {
|
|
163
|
+
value = min;
|
|
164
|
+
}
|
|
165
|
+
if (max !== undefined && value > max) {
|
|
166
|
+
value = max;
|
|
167
|
+
}
|
|
168
|
+
return value;
|
|
169
|
+
}
|
|
170
|
+
|
|
148
171
|
function getConfig(ctx: EvaluationContext, key: string, scope: string) {
|
|
149
172
|
if (scope.length) {
|
|
150
173
|
key += `\u{1f}${scope}`;
|
|
151
174
|
}
|
|
152
|
-
const
|
|
153
|
-
|
|
175
|
+
const config = ctx.getConfig(key);
|
|
176
|
+
if (!config) return null;
|
|
177
|
+
|
|
178
|
+
const {type, value, values, minValue, maxValue, stepValue} = config;
|
|
179
|
+
|
|
180
|
+
const defaultValue = config.default.evaluate(ctx);
|
|
181
|
+
let result = value ? value.evaluate(ctx) : defaultValue;
|
|
182
|
+
|
|
183
|
+
if (type) result = coerceValue(type, result);
|
|
184
|
+
|
|
185
|
+
if (value !== undefined && result !== undefined && values && !values.includes(result)) {
|
|
186
|
+
result = defaultValue;
|
|
187
|
+
if (type) result = coerceValue(type, result);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (result !== undefined && (minValue !== undefined || maxValue !== undefined || stepValue !== undefined)) {
|
|
191
|
+
if (typeof result === 'number') {
|
|
192
|
+
result = clampToAllowedNumber(result, minValue, maxValue, stepValue);
|
|
193
|
+
} else if (Array.isArray(result)) {
|
|
194
|
+
result = result.map((item) => typeof item === 'number' ? clampToAllowedNumber(item, minValue, maxValue, stepValue) : item);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return result;
|
|
154
199
|
}
|
|
155
200
|
|
|
156
201
|
function binarySearch(v: any, a: {[number]: any}, i: number, j: number) {
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
// @flow
|
|
2
2
|
|
|
3
3
|
import {Color} from './values.js';
|
|
4
|
-
import type {Expression} from './expression.js';
|
|
5
4
|
|
|
6
5
|
import type Point from '@mapbox/point-geometry';
|
|
7
6
|
import type {FormattedSection} from './types/formatted.js';
|
|
8
7
|
import type {GlobalProperties, Feature, FeatureState} from './index.js';
|
|
9
8
|
import type {CanonicalTileID} from '../../source/tile_id.js';
|
|
10
9
|
import type {FeatureDistanceData} from '../feature_filter/index.js';
|
|
10
|
+
import type {ConfigOptions, ConfigOptionValue} from '../../style/properties.js';
|
|
11
11
|
|
|
12
12
|
const geometryTypes = ['Unknown', 'Point', 'LineString', 'Polygon'];
|
|
13
13
|
|
|
@@ -20,11 +20,11 @@ class EvaluationContext {
|
|
|
20
20
|
canonical: null | CanonicalTileID;
|
|
21
21
|
featureTileCoord: ?Point;
|
|
22
22
|
featureDistanceData: ?FeatureDistanceData;
|
|
23
|
-
options: ?
|
|
23
|
+
options: ?ConfigOptions;
|
|
24
24
|
|
|
25
25
|
_parseColorCache: {[_: string]: ?Color};
|
|
26
26
|
|
|
27
|
-
constructor(options?: ?
|
|
27
|
+
constructor(options?: ?ConfigOptions) {
|
|
28
28
|
this.globals = (null: any);
|
|
29
29
|
this.feature = null;
|
|
30
30
|
this.featureState = null;
|
|
@@ -92,7 +92,7 @@ class EvaluationContext {
|
|
|
92
92
|
return cached;
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
getConfig(id: string): ?
|
|
95
|
+
getConfig(id: string): ?ConfigOptionValue {
|
|
96
96
|
return this.options ? this.options.get(id) : null;
|
|
97
97
|
}
|
|
98
98
|
}
|
package/expression/index.js
CHANGED
|
@@ -33,6 +33,7 @@ import type {FormattedSection} from './types/formatted.js';
|
|
|
33
33
|
import type Point from '@mapbox/point-geometry';
|
|
34
34
|
import type {CanonicalTileID} from '../../source/tile_id.js';
|
|
35
35
|
import type {FeatureDistanceData} from '../feature_filter/index.js';
|
|
36
|
+
import type {ConfigOptions} from '../../style/properties.js';
|
|
36
37
|
|
|
37
38
|
export interface Feature {
|
|
38
39
|
+type: 1 | 2 | 3 | 'Unknown' | 'Point' | 'LineString' | 'Polygon';
|
|
@@ -64,7 +65,7 @@ export class StyleExpression {
|
|
|
64
65
|
_warningHistory: {[key: string]: boolean};
|
|
65
66
|
_enumValues: ?{[_: string]: any};
|
|
66
67
|
|
|
67
|
-
constructor(expression: Expression, propertySpec: ?StylePropertySpecification, options?: ?
|
|
68
|
+
constructor(expression: Expression, propertySpec: ?StylePropertySpecification, options?: ?ConfigOptions) {
|
|
68
69
|
this.expression = expression;
|
|
69
70
|
this._warningHistory = {};
|
|
70
71
|
this._evaluator = new EvaluationContext(options);
|
|
@@ -131,7 +132,7 @@ export function isExpression(expression: mixed): boolean {
|
|
|
131
132
|
*
|
|
132
133
|
* @private
|
|
133
134
|
*/
|
|
134
|
-
export function createExpression(expression: mixed, propertySpec: ?StylePropertySpecification, options?: ?
|
|
135
|
+
export function createExpression(expression: mixed, propertySpec: ?StylePropertySpecification, options?: ?ConfigOptions): Result<StyleExpression, Array<ParsingError>> {
|
|
135
136
|
const parser = new ParsingContext(definitions, [], propertySpec ? getExpectedType(propertySpec) : undefined, undefined, undefined, options);
|
|
136
137
|
|
|
137
138
|
// For string-valued properties, coerce to string at the top level rather than asserting.
|
|
@@ -248,7 +249,7 @@ export type StylePropertyExpression =
|
|
|
248
249
|
| CameraExpression
|
|
249
250
|
| CompositeExpression;
|
|
250
251
|
|
|
251
|
-
export function createPropertyExpression(expression: mixed, propertySpec: StylePropertySpecification, options?: ?
|
|
252
|
+
export function createPropertyExpression(expression: mixed, propertySpec: StylePropertySpecification, options?: ?ConfigOptions): Result<StylePropertyExpression, Array<ParsingError>> {
|
|
252
253
|
expression = createExpression(expression, propertySpec, options);
|
|
253
254
|
if (expression.result === 'error') {
|
|
254
255
|
return expression;
|
|
@@ -330,7 +331,7 @@ export class StylePropertyFunction<T> {
|
|
|
330
331
|
}
|
|
331
332
|
}
|
|
332
333
|
|
|
333
|
-
export function normalizePropertyExpression<T>(value: PropertyValueSpecification<T>, specification: StylePropertySpecification, options?: ?
|
|
334
|
+
export function normalizePropertyExpression<T>(value: PropertyValueSpecification<T>, specification: StylePropertySpecification, options?: ?ConfigOptions): StylePropertyExpression {
|
|
334
335
|
if (isFunction(value)) {
|
|
335
336
|
return (new StylePropertyFunction(value, specification): any);
|
|
336
337
|
|
|
@@ -16,6 +16,7 @@ import Var from './definitions/var.js';
|
|
|
16
16
|
|
|
17
17
|
import type {Expression, ExpressionRegistry} from './expression.js';
|
|
18
18
|
import type {Type} from './types.js';
|
|
19
|
+
import type {ConfigOptions} from '../../style/properties.js';
|
|
19
20
|
|
|
20
21
|
/**
|
|
21
22
|
* State associated parsing at a given point in an expression tree.
|
|
@@ -27,7 +28,7 @@ class ParsingContext {
|
|
|
27
28
|
key: string;
|
|
28
29
|
scope: Scope;
|
|
29
30
|
errors: Array<ParsingError>;
|
|
30
|
-
options: ?
|
|
31
|
+
options: ?ConfigOptions;
|
|
31
32
|
|
|
32
33
|
// The expected type of this expression. Provided only to allow Expression
|
|
33
34
|
// implementations to infer argument types: Expression#parse() need not
|
|
@@ -41,7 +42,7 @@ class ParsingContext {
|
|
|
41
42
|
expectedType: ?Type,
|
|
42
43
|
scope: Scope = new Scope(),
|
|
43
44
|
errors: Array<ParsingError> = [],
|
|
44
|
-
options?: ?
|
|
45
|
+
options?: ?ConfigOptions
|
|
45
46
|
) {
|
|
46
47
|
this.registry = registry;
|
|
47
48
|
this.path = path;
|
package/flow-typed/sinon.js
CHANGED