@mapbox/mapbox-gl-style-spec 14.23.0 → 14.24.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/composite.ts +5 -3
- package/diff.ts +37 -80
- package/dist/index.cjs +159 -113
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.es.js +159 -113
- package/dist/index.es.js.map +1 -1
- package/error/parsing_error.ts +3 -1
- package/expression/compound_expression.ts +11 -4
- package/expression/definitions/assertion.ts +2 -3
- package/expression/definitions/case.ts +1 -1
- package/expression/definitions/coercion.ts +4 -4
- package/expression/definitions/format.ts +1 -1
- package/expression/definitions/image.ts +2 -2
- package/expression/definitions/in.ts +1 -1
- package/expression/definitions/index.ts +7 -8
- package/expression/definitions/interpolate.ts +1 -1
- package/expression/definitions/let.ts +4 -2
- package/expression/definitions/match.ts +1 -1
- package/expression/definitions/step.ts +1 -1
- package/expression/is_constant.ts +2 -2
- package/expression/parsing_context.ts +18 -4
- package/expression/stops.ts +2 -1
- package/expression/types/image_variant.ts +5 -3
- package/feature_filter/index.ts +7 -30
- package/function/index.ts +7 -6
- package/migrate/v9.ts +1 -1
- package/package.json +1 -1
- package/reference/v8.json +20 -0
- package/types.ts +5 -1
- package/util/color.ts +2 -7
- package/util/geometry_util.ts +3 -8
- package/util/interpolate.ts +2 -3
- package/util/lerp.ts +3 -0
- package/util/properties.ts +4 -1
- package/validate/validate_enum.ts +2 -2
- package/validate/validate_fog.ts +3 -2
- package/validate/validate_function.ts +2 -2
- package/validate/validate_glyphs_url.ts +2 -2
- package/validate/validate_layer.ts +6 -5
- package/validate/validate_light.ts +3 -2
- package/validate/validate_lights.ts +3 -2
- package/validate/validate_model.ts +1 -1
- package/validate/validate_object.ts +1 -3
- package/validate/validate_property.ts +7 -5
- package/validate/validate_rain.ts +2 -1
- package/validate/validate_snow.ts +2 -1
- package/validate/validate_style.ts +1 -0
- package/validate/validate_terrain.ts +3 -2
- package/validate_mapbox_api_supported.ts +9 -8
package/error/parsing_error.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
// Note: Do not inherit from Error. It breaks when transpiling to ES5.
|
|
2
2
|
|
|
3
|
+
const LINE_NUMBER_RE = /line (\d+)/;
|
|
4
|
+
|
|
3
5
|
export default class ParsingError {
|
|
4
6
|
message: string;
|
|
5
7
|
error: Error;
|
|
@@ -8,7 +10,7 @@ export default class ParsingError {
|
|
|
8
10
|
constructor(error: Error) {
|
|
9
11
|
this.error = error;
|
|
10
12
|
this.message = error.message;
|
|
11
|
-
const match = error.message.match(
|
|
13
|
+
const match = error.message.match(LINE_NUMBER_RE);
|
|
12
14
|
this.line = match ? parseInt(match[1], 10) : 0;
|
|
13
15
|
}
|
|
14
16
|
}
|
|
@@ -83,9 +83,16 @@ class CompoundExpression implements Expression {
|
|
|
83
83
|
overloadParams.push(params);
|
|
84
84
|
overloadIndex++;
|
|
85
85
|
|
|
86
|
-
// Use a fresh context for each attempted signature so
|
|
87
|
-
// we eventually succeed, we haven't polluted
|
|
88
|
-
|
|
86
|
+
// Use a fresh-looking context for each attempted signature so
|
|
87
|
+
// that, if we eventually succeed, we haven't polluted
|
|
88
|
+
// `context.errors`. We allocate the context once and reset its
|
|
89
|
+
// errors between overload attempts; the other fields are
|
|
90
|
+
// identical across attempts.
|
|
91
|
+
if (signatureContext === null) {
|
|
92
|
+
signatureContext = new ParsingContext(context.registry, context.path, null, context.scope, [], context._scope, context.options, context.iconImageUseTheme);
|
|
93
|
+
} else {
|
|
94
|
+
signatureContext.errors.length = 0;
|
|
95
|
+
}
|
|
89
96
|
|
|
90
97
|
// First parse all the args, potentially coercing to the
|
|
91
98
|
// types expected by this overload.
|
|
@@ -120,7 +127,7 @@ class CompoundExpression implements Expression {
|
|
|
120
127
|
for (let i = 0; i < parsedArgs.length; i++) {
|
|
121
128
|
const expected = Array.isArray(params) ? params[i] : params.type;
|
|
122
129
|
const arg = parsedArgs[i];
|
|
123
|
-
signatureContext.
|
|
130
|
+
signatureContext.checkSubtype(expected, arg.type, i + 1);
|
|
124
131
|
}
|
|
125
132
|
|
|
126
133
|
if (signatureContext.errors.length === 0) {
|
|
@@ -38,11 +38,11 @@ class Assertion implements Expression {
|
|
|
38
38
|
return context.error(`Expected at least one argument.`);
|
|
39
39
|
|
|
40
40
|
let i = 1;
|
|
41
|
-
let type;
|
|
41
|
+
let type: Type;
|
|
42
42
|
|
|
43
43
|
const name = args[0] as string;
|
|
44
44
|
if (name === 'array') {
|
|
45
|
-
let itemType;
|
|
45
|
+
let itemType: Type;
|
|
46
46
|
if (args.length > 2) {
|
|
47
47
|
const type = args[1];
|
|
48
48
|
if (typeof type !== 'string' || !(type in types) || type === 'object')
|
|
@@ -67,7 +67,6 @@ class Assertion implements Expression {
|
|
|
67
67
|
i++;
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
71
70
|
type = array(itemType, N);
|
|
72
71
|
} else {
|
|
73
72
|
assert(types[name], name);
|
|
@@ -48,7 +48,7 @@ class Case implements Expression {
|
|
|
48
48
|
outputType = outputType || result.type;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
const otherwise = context.parse(args
|
|
51
|
+
const otherwise = context.parse(args.at(-1), args.length - 1, outputType);
|
|
52
52
|
if (!otherwise) return null;
|
|
53
53
|
|
|
54
54
|
assert(outputType);
|
|
@@ -65,7 +65,7 @@ class Coercion implements Expression {
|
|
|
65
65
|
for (let i = 0; i < arrayLength; i++) {
|
|
66
66
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
67
67
|
const member = args[1][i];
|
|
68
|
-
let parsedMember;
|
|
68
|
+
let parsedMember: Expression | null | void;
|
|
69
69
|
if (Array.isArray(member)) {
|
|
70
70
|
parsedMember = context.parse(member, undefined, type.itemType);
|
|
71
71
|
} else {
|
|
@@ -103,8 +103,9 @@ class Coercion implements Expression {
|
|
|
103
103
|
if (this.type.kind === 'boolean') {
|
|
104
104
|
return Boolean(this.args[0].evaluate(ctx));
|
|
105
105
|
} else if (this.type.kind === 'color') {
|
|
106
|
-
|
|
107
|
-
let
|
|
106
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
107
|
+
let input: any;
|
|
108
|
+
let error: string | null;
|
|
108
109
|
for (const arg of this.args) {
|
|
109
110
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
110
111
|
input = arg.evaluate(ctx);
|
|
@@ -126,7 +127,6 @@ class Coercion implements Expression {
|
|
|
126
127
|
}
|
|
127
128
|
}
|
|
128
129
|
}
|
|
129
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
130
130
|
throw new RuntimeError(error || `Could not parse color from value '${typeof input === 'string' ? input : String(JSON.stringify(input))}'`);
|
|
131
131
|
} else if (this.type.kind === 'number') {
|
|
132
132
|
let value = null;
|
|
@@ -70,7 +70,7 @@ export default class FormatExpression implements Expression {
|
|
|
70
70
|
if (!textColor) return null;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
const lastExpression = sections
|
|
73
|
+
const lastExpression = sections.at(-1);
|
|
74
74
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
75
75
|
lastExpression.scale = scale;
|
|
76
76
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
@@ -121,7 +121,7 @@ export default class ImageExpression implements Expression {
|
|
|
121
121
|
parsedParams[key] = value;
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
-
imageExpression
|
|
124
|
+
imageExpression.at(-1).options.params = parsedParams;
|
|
125
125
|
}
|
|
126
126
|
|
|
127
127
|
// Validate the iconset image options
|
|
@@ -136,7 +136,7 @@ export default class ImageExpression implements Expression {
|
|
|
136
136
|
return false;
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
-
imageExpression
|
|
139
|
+
imageExpression.at(-1).options.iconset = iconset;
|
|
140
140
|
}
|
|
141
141
|
|
|
142
142
|
nextArgId++;
|
|
@@ -66,7 +66,7 @@ class In implements Expression {
|
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
// Type assertions safe due to isValidNativeType checks above
|
|
69
|
-
return (haystack as string | unknown[]).
|
|
69
|
+
return (haystack as string | unknown[]).includes(needle as string);
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
eachChild(fn: (_: Expression) => void) {
|
|
@@ -617,21 +617,21 @@ CompoundExpression.register(expressions, {
|
|
|
617
617
|
'filter-type-in': [
|
|
618
618
|
BooleanType,
|
|
619
619
|
[array(StringType)],
|
|
620
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
621
|
-
(ctx, [v]) => (v).value.
|
|
620
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-return
|
|
621
|
+
(ctx, [v]) => (v).value.includes(ctx.geometryType())
|
|
622
622
|
],
|
|
623
623
|
'filter-id-in': [
|
|
624
624
|
BooleanType,
|
|
625
625
|
[array(ValueType)],
|
|
626
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
627
|
-
(ctx, [v]) => (v).value.
|
|
626
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-return
|
|
627
|
+
(ctx, [v]) => (v).value.includes(ctx.id())
|
|
628
628
|
],
|
|
629
629
|
'filter-in-small': [
|
|
630
630
|
BooleanType,
|
|
631
631
|
[StringType, array(ValueType)],
|
|
632
632
|
// assumes v is an array literal
|
|
633
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
634
|
-
(ctx, [k, v]) => (v).value.
|
|
633
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-return
|
|
634
|
+
(ctx, [k, v]) => (v).value.includes(ctx.properties()[(k).value])
|
|
635
635
|
],
|
|
636
636
|
'filter-in-large': [
|
|
637
637
|
BooleanType,
|
|
@@ -736,7 +736,7 @@ CompoundExpression.register(expressions, {
|
|
|
736
736
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
737
737
|
return min;
|
|
738
738
|
}
|
|
739
|
-
let seedVal;
|
|
739
|
+
let seedVal: number;
|
|
740
740
|
if (typeof seed === 'string') {
|
|
741
741
|
seedVal = hashString(seed);
|
|
742
742
|
} else if (typeof seed === 'number') {
|
|
@@ -744,7 +744,6 @@ CompoundExpression.register(expressions, {
|
|
|
744
744
|
} else {
|
|
745
745
|
throw new RuntimeError(`Invalid seed input: ${seed}`);
|
|
746
746
|
}
|
|
747
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
748
747
|
const random = mulberry32(seedVal)();
|
|
749
748
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
750
749
|
return min + random * (max - min);
|
|
@@ -129,7 +129,7 @@ class Interpolate implements Expression {
|
|
|
129
129
|
return context.error('Input/output pairs for "interpolate" expressions must be defined using literal numeric values (not computed expressions) for the input values.', labelKey);
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
-
if (stops.length && stops
|
|
132
|
+
if (stops.length && stops.at(-1)[0] >= label) {
|
|
133
133
|
return context.error('Input/output pairs for "interpolate" expressions must be arranged with input values in strictly ascending order.', labelKey);
|
|
134
134
|
}
|
|
135
135
|
|
|
@@ -3,6 +3,8 @@ import type {Expression, SerializedExpression} from '../expression';
|
|
|
3
3
|
import type ParsingContext from '../parsing_context';
|
|
4
4
|
import type EvaluationContext from '../evaluation_context';
|
|
5
5
|
|
|
6
|
+
const INVALID_VAR_CHAR_RE = /[^a-zA-Z0-9_]/;
|
|
7
|
+
|
|
6
8
|
class Let implements Expression {
|
|
7
9
|
type: Type;
|
|
8
10
|
bindings: Array<[string, Expression]>;
|
|
@@ -39,7 +41,7 @@ class Let implements Expression {
|
|
|
39
41
|
return context.error(`Expected string, but found ${typeof name} instead.`, i);
|
|
40
42
|
}
|
|
41
43
|
|
|
42
|
-
if (
|
|
44
|
+
if (INVALID_VAR_CHAR_RE.test(name)) {
|
|
43
45
|
return context.error(`Variable names must contain only alphanumeric characters or '_'.`, i);
|
|
44
46
|
}
|
|
45
47
|
|
|
@@ -49,7 +51,7 @@ class Let implements Expression {
|
|
|
49
51
|
bindings.push([name, value]);
|
|
50
52
|
}
|
|
51
53
|
|
|
52
|
-
const result = context.parse(args
|
|
54
|
+
const result = context.parse(args.at(-1), args.length - 1, context.expectedType, bindings);
|
|
53
55
|
if (!result) return null;
|
|
54
56
|
|
|
55
57
|
return new Let(bindings, result);
|
|
@@ -86,7 +86,7 @@ class Match implements Expression {
|
|
|
86
86
|
const input = context.parse(args[1], 1, ValueType);
|
|
87
87
|
if (!input) return null;
|
|
88
88
|
|
|
89
|
-
const otherwise = context.parse(args
|
|
89
|
+
const otherwise = context.parse(args.at(-1), args.length - 1, outputType);
|
|
90
90
|
if (!otherwise) return null;
|
|
91
91
|
|
|
92
92
|
assert(inputType && outputType);
|
|
@@ -56,7 +56,7 @@ class Step implements Expression {
|
|
|
56
56
|
return context.error('Input/output pairs for "step" expressions must be defined using literal numeric values (not computed expressions) for the input values.', labelKey);
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
if (stops.length && stops
|
|
59
|
+
if (stops.length && stops.at(-1)[0] >= label) {
|
|
60
60
|
return context.error('Input/output pairs for "step" expressions must be arranged with input values in strictly ascending order.', labelKey);
|
|
61
61
|
}
|
|
62
62
|
|
|
@@ -19,7 +19,7 @@ function isFeatureConstant(e: Expression): boolean {
|
|
|
19
19
|
e.name === 'id'
|
|
20
20
|
) {
|
|
21
21
|
return false;
|
|
22
|
-
} else if (
|
|
22
|
+
} else if (e.name.startsWith('filter-')) {
|
|
23
23
|
return false;
|
|
24
24
|
}
|
|
25
25
|
}
|
|
@@ -57,7 +57,7 @@ function isStateConstant(e: Expression): boolean {
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
function isGlobalPropertyConstant(e: Expression, properties: Array<string>): boolean {
|
|
60
|
-
if (e instanceof CompoundExpression && properties.
|
|
60
|
+
if (e instanceof CompoundExpression && properties.includes(e.name)) { return false; }
|
|
61
61
|
let result = true;
|
|
62
62
|
e.eachChild((arg) => {
|
|
63
63
|
if (result && !isGlobalPropertyConstant(arg, properties)) { result = false; }
|
|
@@ -24,7 +24,6 @@ import type {ConfigOptions} from '../types/config_options';
|
|
|
24
24
|
class ParsingContext {
|
|
25
25
|
registry: ExpressionRegistry;
|
|
26
26
|
path: Array<number | string>;
|
|
27
|
-
key: string;
|
|
28
27
|
scope: Scope;
|
|
29
28
|
errors: Array<ParsingError>;
|
|
30
29
|
_scope: string | null | undefined;
|
|
@@ -37,6 +36,9 @@ class ParsingContext {
|
|
|
37
36
|
// `expectedType`.
|
|
38
37
|
expectedType: Type | null | undefined;
|
|
39
38
|
|
|
39
|
+
// `key` is only consulted on the error path, so compute it lazily.
|
|
40
|
+
private _key: string | undefined;
|
|
41
|
+
|
|
40
42
|
constructor(
|
|
41
43
|
registry: ExpressionRegistry,
|
|
42
44
|
path: Array<number | string> = [],
|
|
@@ -49,7 +51,6 @@ class ParsingContext {
|
|
|
49
51
|
) {
|
|
50
52
|
this.registry = registry;
|
|
51
53
|
this.path = path;
|
|
52
|
-
this.key = path.map(part => { if (typeof part === 'string') { return `['${part}']`; } return `[${part}]`; }).join('');
|
|
53
54
|
this.scope = scope;
|
|
54
55
|
this.errors = errors;
|
|
55
56
|
this.expectedType = expectedType;
|
|
@@ -58,6 +59,19 @@ class ParsingContext {
|
|
|
58
59
|
this.iconImageUseTheme = iconImageUseTheme;
|
|
59
60
|
}
|
|
60
61
|
|
|
62
|
+
get key(): string {
|
|
63
|
+
if (this._key === undefined) {
|
|
64
|
+
const path = this.path;
|
|
65
|
+
let key = '';
|
|
66
|
+
for (let i = 0; i < path.length; i++) {
|
|
67
|
+
const part = path[i];
|
|
68
|
+
key += typeof part === 'string' ? `['${part}']` : `[${part}]`;
|
|
69
|
+
}
|
|
70
|
+
this._key = key;
|
|
71
|
+
}
|
|
72
|
+
return this._key;
|
|
73
|
+
}
|
|
74
|
+
|
|
61
75
|
/**
|
|
62
76
|
* @param expr the JSON expression to parse
|
|
63
77
|
* @param index the optional argument index if this expression is an argument of a parent expression that's being parsed
|
|
@@ -226,9 +240,9 @@ class ParsingContext {
|
|
|
226
240
|
* Returns null if `t` is a subtype of `expected`; otherwise returns an
|
|
227
241
|
* error message and also pushes it to `this.errors`.
|
|
228
242
|
*/
|
|
229
|
-
checkSubtype(expected: Type, t: Type): string | null | undefined {
|
|
243
|
+
checkSubtype(expected: Type, t: Type, index?: number): string | null | undefined {
|
|
230
244
|
const error = checkSubtype(expected, t);
|
|
231
|
-
if (error) this.error(error);
|
|
245
|
+
if (error) this.error(error, ...(typeof index === 'number' ? [index] : []));
|
|
232
246
|
return error;
|
|
233
247
|
}
|
|
234
248
|
}
|
package/expression/stops.ts
CHANGED
|
@@ -13,7 +13,8 @@ export function findStopLessThanOrEqualTo(stops: Array<number>, input: number):
|
|
|
13
13
|
let lowerIndex = 0;
|
|
14
14
|
let upperIndex = lastIndex;
|
|
15
15
|
let currentIndex = 0;
|
|
16
|
-
let currentValue
|
|
16
|
+
let currentValue: number;
|
|
17
|
+
let nextValue: number;
|
|
17
18
|
|
|
18
19
|
while (lowerIndex <= upperIndex) {
|
|
19
20
|
currentIndex = Math.floor((lowerIndex + upperIndex) / 2);
|
|
@@ -47,7 +47,10 @@ export class ImageVariant implements RasterizationOptions {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
static parse(str: StringifiedImageVariant): ImageVariant | null {
|
|
50
|
-
let id
|
|
50
|
+
let id: ImageIdSpec | undefined;
|
|
51
|
+
let params: Record<string, Color> | undefined;
|
|
52
|
+
let sx: number | undefined;
|
|
53
|
+
let sy: number | undefined;
|
|
51
54
|
|
|
52
55
|
try {
|
|
53
56
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
@@ -58,8 +61,7 @@ export class ImageVariant implements RasterizationOptions {
|
|
|
58
61
|
|
|
59
62
|
if (!id) return null;
|
|
60
63
|
|
|
61
|
-
|
|
62
|
-
return new ImageVariant(id as ImageIdSpec, {params, sx, sy});
|
|
64
|
+
return new ImageVariant(id, {params, sx, sy});
|
|
63
65
|
}
|
|
64
66
|
|
|
65
67
|
scaleSelf(factor: number, yFactor: number = factor): this {
|
package/feature_filter/index.ts
CHANGED
|
@@ -160,7 +160,7 @@ ${JSON.stringify(filterExp, null, 2)}
|
|
|
160
160
|
}
|
|
161
161
|
|
|
162
162
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
163
|
-
function extractStaticFilter(filter:
|
|
163
|
+
function extractStaticFilter(filter: unknown | unknown[]): any {
|
|
164
164
|
if (!isDynamicFilter(filter)) {
|
|
165
165
|
return filter;
|
|
166
166
|
}
|
|
@@ -169,7 +169,7 @@ function extractStaticFilter(filter: any): any {
|
|
|
169
169
|
let result = deepUnbundle(filter);
|
|
170
170
|
|
|
171
171
|
// 1. Union branches
|
|
172
|
-
unionDynamicBranches(result);
|
|
172
|
+
unionDynamicBranches(result as unknown[]);
|
|
173
173
|
|
|
174
174
|
// 2. Collapse dynamic conditions to `true`
|
|
175
175
|
result = collapseDynamicBooleanExpressions(result);
|
|
@@ -202,59 +202,36 @@ function collapseDynamicBooleanExpressions(expression: any): any {
|
|
|
202
202
|
*
|
|
203
203
|
* @param {Array<any>} filter the filter expression mutated in-place.
|
|
204
204
|
*/
|
|
205
|
-
|
|
206
|
-
function unionDynamicBranches(filter: any) {
|
|
205
|
+
function unionDynamicBranches(filter: unknown[]) {
|
|
207
206
|
let isBranchingDynamically = false;
|
|
208
|
-
const branches = [];
|
|
209
|
-
|
|
210
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
207
|
+
const branches: unknown[] = [];
|
|
211
208
|
if (filter[0] === 'case') {
|
|
212
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
213
209
|
for (let i = 1; i < filter.length - 1; i += 2) {
|
|
214
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
215
210
|
isBranchingDynamically = isBranchingDynamically || isDynamicFilter(filter[i]);
|
|
216
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
217
211
|
branches.push(filter[i + 1]);
|
|
218
212
|
}
|
|
219
|
-
|
|
220
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
221
|
-
branches.push(filter[filter.length - 1]);
|
|
222
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
213
|
+
branches.push(filter.at(-1));
|
|
223
214
|
} else if (filter[0] === 'match') {
|
|
224
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
225
215
|
isBranchingDynamically = isBranchingDynamically || isDynamicFilter(filter[1]);
|
|
226
|
-
|
|
227
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
228
216
|
for (let i = 2; i < filter.length - 1; i += 2) {
|
|
229
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
230
217
|
branches.push(filter[i + 1]);
|
|
231
218
|
}
|
|
232
|
-
|
|
233
|
-
branches.push(filter[filter.length - 1]);
|
|
234
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
219
|
+
branches.push(filter.at(-1));
|
|
235
220
|
} else if (filter[0] === 'step') {
|
|
236
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
237
221
|
isBranchingDynamically = isBranchingDynamically || isDynamicFilter(filter[1]);
|
|
238
|
-
|
|
239
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
240
222
|
for (let i = 1; i < filter.length - 1; i += 2) {
|
|
241
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
242
223
|
branches.push(filter[i + 1]);
|
|
243
224
|
}
|
|
244
225
|
}
|
|
245
226
|
|
|
246
227
|
if (isBranchingDynamically) {
|
|
247
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
248
228
|
filter.length = 0;
|
|
249
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
250
229
|
filter.push('any', ...branches);
|
|
251
230
|
}
|
|
252
231
|
|
|
253
232
|
// traverse and recurse into children
|
|
254
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
255
233
|
for (let i = 1; i < filter.length; i++) {
|
|
256
|
-
|
|
257
|
-
unionDynamicBranches(filter[i]);
|
|
234
|
+
unionDynamicBranches(filter[i] as unknown[]);
|
|
258
235
|
}
|
|
259
236
|
}
|
|
260
237
|
|
package/function/index.ts
CHANGED
|
@@ -60,9 +60,10 @@ export function createFunction(parameters, propertySpec) {
|
|
|
60
60
|
throw new Error(`Unknown color space: ${parameters.colorSpace}`);
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
|
|
64
|
-
let hashedStops;
|
|
65
|
-
let
|
|
63
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
64
|
+
let innerFun: ((parameters: any, propertySpec: any, input: any, hashedStops?: any, categoricalKeyType?: any) => any) | undefined;
|
|
65
|
+
let hashedStops: Record<string | number, unknown> | undefined;
|
|
66
|
+
let categoricalKeyType: string | undefined;
|
|
66
67
|
if (type === 'exponential') {
|
|
67
68
|
innerFun = evaluateExponentialFunction;
|
|
68
69
|
} else if (type === 'interval') {
|
|
@@ -75,7 +76,7 @@ export function createFunction(parameters, propertySpec) {
|
|
|
75
76
|
hashedStops = Object.create(null);
|
|
76
77
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
77
78
|
for (const stop of parameters.stops) {
|
|
78
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-
|
|
79
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
79
80
|
hashedStops[stop[0]] = stop[1];
|
|
80
81
|
}
|
|
81
82
|
|
|
@@ -154,7 +155,7 @@ export function createFunction(parameters, propertySpec) {
|
|
|
154
155
|
interpolationFactor: Interpolate.interpolationFactor.bind(undefined, interpolationType),
|
|
155
156
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
156
157
|
zoomStops: parameters.stops.map(s => s[0]),
|
|
157
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
158
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
158
159
|
evaluate: ({zoom}) => innerFun(parameters, propertySpec, zoom, hashedStops, categoricalKeyType)
|
|
159
160
|
};
|
|
160
161
|
} else {
|
|
@@ -167,7 +168,7 @@ export function createFunction(parameters, propertySpec) {
|
|
|
167
168
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access
|
|
168
169
|
return coalesce(parameters.default, propertySpec.default);
|
|
169
170
|
}
|
|
170
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
171
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
171
172
|
return innerFun(parameters, propertySpec, value, hashedStops, categoricalKeyType);
|
|
172
173
|
}
|
|
173
174
|
};
|
package/migrate/v9.ts
CHANGED
|
@@ -21,7 +21,7 @@ export default function (style) {
|
|
|
21
21
|
// remove class-specific paint properties
|
|
22
22
|
eachLayer(style, (layer) => {
|
|
23
23
|
for (const k in layer) {
|
|
24
|
-
if (
|
|
24
|
+
if (k.includes('paint.')) {
|
|
25
25
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
26
26
|
delete layer[k];
|
|
27
27
|
}
|
package/package.json
CHANGED
package/reference/v8.json
CHANGED
|
@@ -8982,6 +8982,26 @@
|
|
|
8982
8982
|
]
|
|
8983
8983
|
},
|
|
8984
8984
|
"property-type": "data-constant"
|
|
8985
|
+
},
|
|
8986
|
+
"line-blend-additive-clamp": {
|
|
8987
|
+
"type": "number",
|
|
8988
|
+
"default": 0,
|
|
8989
|
+
"minimum": 0,
|
|
8990
|
+
"doc": "Controls the brightness of lines in additive blend mode. When set to 0 (the default), brightness is adjusted automatically based on the density of lines visible on screen. Increase this value if the lines appear too bright, or decrease it if they appear too faint.",
|
|
8991
|
+
"experimental": true,
|
|
8992
|
+
"private": true,
|
|
8993
|
+
"sdk-support": {
|
|
8994
|
+
"basic functionality": {
|
|
8995
|
+
"js": "3.21.0"
|
|
8996
|
+
}
|
|
8997
|
+
},
|
|
8998
|
+
"expression": {
|
|
8999
|
+
"interpolated": true,
|
|
9000
|
+
"parameters": [
|
|
9001
|
+
"zoom"
|
|
9002
|
+
]
|
|
9003
|
+
},
|
|
9004
|
+
"property-type": "data-constant"
|
|
8985
9005
|
}
|
|
8986
9006
|
},
|
|
8987
9007
|
"paint_circle": {
|
package/types.ts
CHANGED
|
@@ -759,7 +759,11 @@ export type LineLayerSpecification = {
|
|
|
759
759
|
/**
|
|
760
760
|
* @experimental This property is experimental and subject to change in future versions.
|
|
761
761
|
*/
|
|
762
|
-
"line-blend-mode"?: PropertyValueSpecification<"default" | "multiply" | "additive"
|
|
762
|
+
"line-blend-mode"?: PropertyValueSpecification<"default" | "multiply" | "additive">,
|
|
763
|
+
/**
|
|
764
|
+
* @experimental This property is experimental and subject to change in future versions.
|
|
765
|
+
*/
|
|
766
|
+
"line-blend-additive-clamp"?: PropertyValueSpecification<number>
|
|
763
767
|
},
|
|
764
768
|
/**
|
|
765
769
|
* @experimental This property is experimental and subject to change in future versions.
|
package/util/color.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {parseCSSColor} from 'csscolorparser';
|
|
2
|
-
import {number as lerp} from './
|
|
2
|
+
import {number as lerp} from './lerp';
|
|
3
3
|
|
|
4
4
|
import type {LUT} from '../types/lut';
|
|
5
5
|
|
|
@@ -74,12 +74,7 @@ class Color {
|
|
|
74
74
|
* translucentGreen.toString(); // = "rgba(26,207,26,0.73)"
|
|
75
75
|
*/
|
|
76
76
|
toString(): string {
|
|
77
|
-
const
|
|
78
|
-
this.r,
|
|
79
|
-
this.g,
|
|
80
|
-
this.b,
|
|
81
|
-
this.a
|
|
82
|
-
];
|
|
77
|
+
const {r, g, b, a} = this;
|
|
83
78
|
return `rgba(${Math.round(r * 255)},${Math.round(g * 255)},${Math.round(b * 255)},${a})`;
|
|
84
79
|
}
|
|
85
80
|
|
package/util/geometry_util.ts
CHANGED
|
@@ -13,10 +13,9 @@ export type BBox = [number, number, number, number];
|
|
|
13
13
|
*/
|
|
14
14
|
function calculateSignedArea(ring: Ring): number {
|
|
15
15
|
let sum = 0;
|
|
16
|
-
for (let i = 0, len = ring.length, j = len - 1, p1, p2; i < len; j = i++) {
|
|
16
|
+
for (let i = 0, len = ring.length, j = len - 1, p1: Point, p2: Point; i < len; j = i++) {
|
|
17
17
|
p1 = ring[i];
|
|
18
18
|
p2 = ring[j];
|
|
19
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
20
19
|
sum += (p2.x - p1.x) * (p1.y + p2.y);
|
|
21
20
|
}
|
|
22
21
|
return sum;
|
|
@@ -33,8 +32,8 @@ export function classifyRings(rings: Array<Ring>, maxRings: number): Array<Array
|
|
|
33
32
|
if (len <= 1) return [rings];
|
|
34
33
|
|
|
35
34
|
const polygons: Array<Array<Ring>> = [];
|
|
36
|
-
let polygon
|
|
37
|
-
ccw;
|
|
35
|
+
let polygon: Array<Ring>,
|
|
36
|
+
ccw: boolean;
|
|
38
37
|
|
|
39
38
|
for (let i = 0; i < len; i++) {
|
|
40
39
|
const area = calculateSignedArea(rings[i]);
|
|
@@ -45,16 +44,12 @@ export function classifyRings(rings: Array<Ring>, maxRings: number): Array<Array
|
|
|
45
44
|
if (ccw === undefined) ccw = area < 0;
|
|
46
45
|
|
|
47
46
|
if (ccw === area < 0) {
|
|
48
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
49
47
|
if (polygon) polygons.push(polygon);
|
|
50
48
|
polygon = [rings[i]];
|
|
51
|
-
|
|
52
49
|
} else {
|
|
53
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
54
50
|
(polygon).push(rings[i]);
|
|
55
51
|
}
|
|
56
52
|
}
|
|
57
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
58
53
|
if (polygon) polygons.push(polygon);
|
|
59
54
|
|
|
60
55
|
// Earcut performance degrades with the # of rings in a polygon. For this
|
package/util/interpolate.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import Color from './color';
|
|
2
|
+
import {number} from './lerp';
|
|
2
3
|
|
|
3
|
-
export
|
|
4
|
-
return (a * (1 - t)) + (b * t);
|
|
5
|
-
}
|
|
4
|
+
export {number};
|
|
6
5
|
|
|
7
6
|
export function color(from: Color, to: Color, t: number): Color {
|
|
8
7
|
return new Color(
|
package/util/lerp.ts
ADDED
package/util/properties.ts
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import type {PropertyExpressionSpecification, StylePropertySpecification} from '../style-spec';
|
|
2
2
|
|
|
3
|
+
export const TRANSITION_KEY_RE = /^(.*)-transition$/;
|
|
4
|
+
export const USE_THEME_KEY_RE = /^(.*)-use-theme$/;
|
|
5
|
+
|
|
3
6
|
type ExpressionParameter = PropertyExpressionSpecification['parameters'][number];
|
|
4
7
|
|
|
5
8
|
function expressionHasParameter(
|
|
6
9
|
expression: PropertyExpressionSpecification | null | undefined,
|
|
7
10
|
parameter: ExpressionParameter,
|
|
8
11
|
): boolean {
|
|
9
|
-
return !!expression && !!expression.parameters && expression.parameters.
|
|
12
|
+
return !!expression && !!expression.parameters && expression.parameters.includes(parameter);
|
|
10
13
|
}
|
|
11
14
|
|
|
12
15
|
export function supportsPropertyExpression(spec: StylePropertySpecification): boolean {
|