@mapbox/mapbox-gl-style-spec 14.12.0 → 14.13.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.ts +3 -1
- package/dist/index.cjs +321 -237
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +26 -26
- package/dist/index.es.js +321 -237
- package/dist/index.es.js.map +1 -1
- package/expression/definitions/config.ts +30 -10
- package/expression/definitions/format.ts +2 -1
- package/expression/definitions/index.ts +8 -3
- package/expression/definitions/literal.ts +1 -1
- package/expression/definitions/match.ts +2 -2
- package/expression/index.ts +1 -0
- package/expression/is_constant.ts +4 -0
- package/expression/parsing_context.ts +1 -1
- package/expression/types/formatted.ts +1 -1
- package/expression/types.ts +8 -0
- package/expression/values.ts +1 -3
- package/group_by_layout.ts +1 -9
- package/package.json +1 -1
- package/reference/v8.json +102 -19
- package/types.ts +12 -4
- package/union-to-intersection.ts +1 -2
- package/util/color.ts +85 -69
- package/util/interpolate.ts +0 -4
- package/validate/validate_lights.ts +21 -21
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {ValueType} from '../types';
|
|
1
|
+
import {typeEquals, ValueType} from '../types';
|
|
2
2
|
import {Color, typeOf, toString as valueToString} from '../values';
|
|
3
3
|
import Formatted from '../types/formatted';
|
|
4
4
|
import ResolvedImage from '../types/resolved_image';
|
|
5
|
+
import * as isConstant from '../is_constant';
|
|
5
6
|
import Literal from './literal';
|
|
6
7
|
|
|
7
8
|
import type {Type} from '../types';
|
|
@@ -9,6 +10,12 @@ import type {Expression, SerializedExpression} from '../expression';
|
|
|
9
10
|
import type ParsingContext from '../parsing_context';
|
|
10
11
|
import type EvaluationContext from '../evaluation_context';
|
|
11
12
|
|
|
13
|
+
const FQIDSeparator = '\u001F';
|
|
14
|
+
|
|
15
|
+
function makeConfigFQID(id: string, ownScope?: string | null, contextScope?: string | null): string {
|
|
16
|
+
return [id, ownScope, contextScope].filter(Boolean).join(FQIDSeparator);
|
|
17
|
+
}
|
|
18
|
+
|
|
12
19
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
13
20
|
function coerceValue(type: string, value: any): any {
|
|
14
21
|
switch (type) {
|
|
@@ -43,11 +50,13 @@ class Config implements Expression {
|
|
|
43
50
|
type: Type;
|
|
44
51
|
key: string;
|
|
45
52
|
scope: string | null | undefined;
|
|
53
|
+
featureConstant: boolean;
|
|
46
54
|
|
|
47
|
-
constructor(type: Type, key: string, scope?: string) {
|
|
55
|
+
constructor(type: Type, key: string, scope?: string, featureConstant: boolean = false) {
|
|
48
56
|
this.type = type;
|
|
49
57
|
this.key = key;
|
|
50
58
|
this.scope = scope;
|
|
59
|
+
this.featureConstant = featureConstant;
|
|
51
60
|
}
|
|
52
61
|
|
|
53
62
|
static parse(args: ReadonlyArray<unknown>, context: ParsingContext): Config | null | void {
|
|
@@ -64,23 +73,34 @@ class Config implements Expression {
|
|
|
64
73
|
return context.error(`Key name of 'config' expression must be a string literal.`);
|
|
65
74
|
}
|
|
66
75
|
|
|
76
|
+
let featureConstant = true;
|
|
77
|
+
let configScopeValue: string | undefined;
|
|
78
|
+
const configKeyValue = valueToString(configKey.value);
|
|
79
|
+
|
|
67
80
|
if (args.length >= 3) {
|
|
68
81
|
const configScope = context.parse(args[2], 2);
|
|
69
82
|
if (!(configScope instanceof Literal)) {
|
|
70
83
|
return context.error(`Scope of 'config' expression must be a string literal.`);
|
|
71
84
|
}
|
|
72
|
-
|
|
85
|
+
|
|
86
|
+
configScopeValue = valueToString(configScope.value);
|
|
73
87
|
}
|
|
74
88
|
|
|
75
|
-
|
|
89
|
+
if (context.options) {
|
|
90
|
+
const fqid = makeConfigFQID(configKeyValue, configScopeValue, context._scope);
|
|
91
|
+
const config = context.options.get(fqid);
|
|
92
|
+
if (config) {
|
|
93
|
+
featureConstant = isConstant.isFeatureConstant(config.value || config.default);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return new Config(type, configKeyValue, configScopeValue, featureConstant);
|
|
76
98
|
}
|
|
77
99
|
|
|
78
100
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
79
101
|
evaluate(ctx: EvaluationContext): any {
|
|
80
|
-
const
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
const config = ctx.getConfig(configKey);
|
|
102
|
+
const fqid = makeConfigFQID(this.key, this.scope, ctx.scope);
|
|
103
|
+
const config = ctx.getConfig(fqid);
|
|
84
104
|
if (!config) return null;
|
|
85
105
|
|
|
86
106
|
const {type, value, values, minValue, maxValue, stepValue} = config;
|
|
@@ -117,7 +137,7 @@ class Config implements Expression {
|
|
|
117
137
|
}
|
|
118
138
|
|
|
119
139
|
// @ts-expect-error - TS2367 - This comparison appears to be unintentional because the types 'string' and 'Type' have no overlap.
|
|
120
|
-
if ((type && type !== this.type) || (result !== undefined && typeOf(result)
|
|
140
|
+
if ((type && type !== this.type) || (result !== undefined && !typeEquals(typeOf(result), this.type))) {
|
|
121
141
|
result = coerceValue(this.type.kind, result);
|
|
122
142
|
}
|
|
123
143
|
|
|
@@ -133,7 +153,7 @@ class Config implements Expression {
|
|
|
133
153
|
serialize(): SerializedExpression {
|
|
134
154
|
const res = ["config", this.key];
|
|
135
155
|
if (this.scope) {
|
|
136
|
-
res.concat(this.
|
|
156
|
+
res.concat(this.scope);
|
|
137
157
|
}
|
|
138
158
|
return res;
|
|
139
159
|
}
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
StringType,
|
|
7
7
|
ColorType,
|
|
8
8
|
ResolvedImageType,
|
|
9
|
+
typeEquals,
|
|
9
10
|
} from '../types';
|
|
10
11
|
import Formatted, {FormattedSection} from '../types/formatted';
|
|
11
12
|
import {toString, typeOf} from '../values';
|
|
@@ -92,7 +93,7 @@ export default class FormatExpression implements Expression {
|
|
|
92
93
|
evaluate(ctx: EvaluationContext): Formatted {
|
|
93
94
|
const evaluateSection = (section: FormattedSectionExpression) => {
|
|
94
95
|
const evaluatedContent = section.content.evaluate(ctx);
|
|
95
|
-
if (typeOf(evaluatedContent)
|
|
96
|
+
if (typeEquals(typeOf(evaluatedContent), ResolvedImageType)) {
|
|
96
97
|
return new FormattedSection('', evaluatedContent, null, null, null);
|
|
97
98
|
}
|
|
98
99
|
|
|
@@ -101,7 +101,7 @@ function rgba(ctx: EvaluationContext, [r, g, b, a]: Expression[]) {
|
|
|
101
101
|
const alpha = a ? a.evaluate(ctx) : 1;
|
|
102
102
|
const error = validateRGBA(r, g, b, alpha);
|
|
103
103
|
if (error) throw new RuntimeError(error);
|
|
104
|
-
return new Color(r as unknown as number / 255
|
|
104
|
+
return new Color(r as unknown as number / 255, g as unknown as number / 255, b as unknown as number / 255, alpha);
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
function hsla(ctx: EvaluationContext, [h, s, l, a]: Expression[]) {
|
|
@@ -187,7 +187,7 @@ CompoundExpression.register(expressions, {
|
|
|
187
187
|
[ColorType],
|
|
188
188
|
(ctx, [v]) => {
|
|
189
189
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
190
|
-
return v.evaluate(ctx).
|
|
190
|
+
return v.evaluate(ctx).toNonPremultipliedRenderColor(null).toArray();
|
|
191
191
|
}
|
|
192
192
|
],
|
|
193
193
|
'to-hsla': [
|
|
@@ -195,7 +195,7 @@ CompoundExpression.register(expressions, {
|
|
|
195
195
|
[ColorType],
|
|
196
196
|
(ctx, [v]) => {
|
|
197
197
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
198
|
-
return v.evaluate(ctx).
|
|
198
|
+
return v.evaluate(ctx).toNonPremultipliedRenderColor(null).toHslaArray();
|
|
199
199
|
}
|
|
200
200
|
],
|
|
201
201
|
'rgb': [
|
|
@@ -260,6 +260,11 @@ CompoundExpression.register(expressions, {
|
|
|
260
260
|
[],
|
|
261
261
|
(ctx) => ctx.geometryType()
|
|
262
262
|
],
|
|
263
|
+
'worldview': [
|
|
264
|
+
StringType,
|
|
265
|
+
[],
|
|
266
|
+
(ctx) => ctx.globals.worldview || ""
|
|
267
|
+
],
|
|
263
268
|
'id': [
|
|
264
269
|
ValueType,
|
|
265
270
|
[],
|
|
@@ -58,7 +58,7 @@ class Literal implements Expression {
|
|
|
58
58
|
// Constant-folding can generate Literal expressions that you
|
|
59
59
|
// couldn't actually generate with a "literal" expression,
|
|
60
60
|
// so we have to implement an equivalent serialization here
|
|
61
|
-
return ["rgba" as SerializedExpression].concat(this.value.
|
|
61
|
+
return ["rgba" as SerializedExpression].concat(this.value.toNonPremultipliedRenderColor(null).toArray());
|
|
62
62
|
} else if (this.value instanceof Formatted) {
|
|
63
63
|
// Same as Color
|
|
64
64
|
return this.value.serialize();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import assert from 'assert';
|
|
2
2
|
import {typeOf} from '../values';
|
|
3
|
-
import {ValueType} from '../types';
|
|
3
|
+
import {typeEquals, ValueType} from '../types';
|
|
4
4
|
|
|
5
5
|
import type {Type} from '../types';
|
|
6
6
|
import type {Expression, SerializedExpression} from '../expression';
|
|
@@ -101,7 +101,7 @@ class Match implements Expression {
|
|
|
101
101
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
102
102
|
evaluate(ctx: EvaluationContext): any {
|
|
103
103
|
const input = (this.input.evaluate(ctx));
|
|
104
|
-
const output = (typeOf(input)
|
|
104
|
+
const output = (typeEquals(typeOf(input), this.inputType) && this.outputs[this.cases[input]]) || this.otherwise;
|
|
105
105
|
return output.evaluate(ctx);
|
|
106
106
|
}
|
|
107
107
|
|
package/expression/index.ts
CHANGED
|
@@ -271,5 +271,5 @@ function isConstant(expression: Expression) {
|
|
|
271
271
|
}
|
|
272
272
|
|
|
273
273
|
return isFeatureConstant(expression) &&
|
|
274
|
-
isGlobalPropertyConstant(expression, ['zoom', 'heatmap-density', 'line-progress', 'raster-value', 'sky-radial-progress', 'accumulated', 'is-supported-script', 'pitch', 'distance-from-center', 'measure-light', 'raster-particle-speed']);
|
|
274
|
+
isGlobalPropertyConstant(expression, ['zoom', 'heatmap-density', 'worldview', 'line-progress', 'raster-value', 'sky-radial-progress', 'accumulated', 'is-supported-script', 'pitch', 'distance-from-center', 'measure-light', 'raster-particle-speed']);
|
|
275
275
|
}
|
|
@@ -70,7 +70,7 @@ export default class Formatted {
|
|
|
70
70
|
options["font-scale"] = section.scale;
|
|
71
71
|
}
|
|
72
72
|
if (section.textColor) {
|
|
73
|
-
options["text-color"] = (["rgba"] as Array<unknown>).concat(section.textColor.
|
|
73
|
+
options["text-color"] = (["rgba"] as Array<unknown>).concat(section.textColor.toNonPremultipliedRenderColor(null).toArray());
|
|
74
74
|
}
|
|
75
75
|
serialized.push(options);
|
|
76
76
|
}
|
package/expression/types.ts
CHANGED
|
@@ -134,3 +134,11 @@ export function isValidNativeType(provided: any, allowedTypes: Array<NativeType>
|
|
|
134
134
|
}
|
|
135
135
|
});
|
|
136
136
|
}
|
|
137
|
+
|
|
138
|
+
export function typeEquals(a: Type, b: Type): boolean {
|
|
139
|
+
if (a.kind === 'array' && b.kind === 'array') {
|
|
140
|
+
return a.N === b.N && typeEquals(a.itemType, b.itemType);
|
|
141
|
+
} else {
|
|
142
|
+
return a.kind === b.kind;
|
|
143
|
+
}
|
|
144
|
+
}
|
package/expression/values.ts
CHANGED
|
@@ -135,9 +135,7 @@ export function toString(value: Value): string {
|
|
|
135
135
|
return '';
|
|
136
136
|
} else if (type === 'string' || type === 'number' || type === 'boolean') {
|
|
137
137
|
return String(value as string | number | boolean);
|
|
138
|
-
} else if (value instanceof Color) {
|
|
139
|
-
return value.toStringPremultipliedAlpha();
|
|
140
|
-
} else if (value instanceof Formatted || value instanceof ResolvedImage) {
|
|
138
|
+
} else if (value instanceof Formatted || value instanceof ResolvedImage || value instanceof Color) {
|
|
141
139
|
return value.toString();
|
|
142
140
|
} else {
|
|
143
141
|
return JSON.stringify(value);
|
package/group_by_layout.ts
CHANGED
|
@@ -25,15 +25,7 @@ function stringify(obj: any) {
|
|
|
25
25
|
function getKey(layer: LayerSpecification) {
|
|
26
26
|
let key = '';
|
|
27
27
|
for (const k of refProperties) {
|
|
28
|
-
|
|
29
|
-
// referencing the same source (but with different zoom ranges) produce the same
|
|
30
|
-
// key. This ensures they get grouped into a single bucket, preventing a scenario
|
|
31
|
-
// where shared node data is serialized twice and triggers an assert in struct_array.ts.
|
|
32
|
-
if (layer.type === 'model' && (k === 'minzoom' || k === 'maxzoom')) {
|
|
33
|
-
continue;
|
|
34
|
-
} else {
|
|
35
|
-
key += `/${stringify(layer[k])}`;
|
|
36
|
-
}
|
|
28
|
+
key += `/${stringify(layer[k])}`;
|
|
37
29
|
}
|
|
38
30
|
return key;
|
|
39
31
|
}
|