maplibre-gl 2.2.0-pre.2 → 2.2.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.
Files changed (169) hide show
  1. package/README.md +73 -8
  2. package/build/generate-debug-index-file.ts +19 -0
  3. package/build/generate-style-code.ts +6 -1
  4. package/build/generate-style-spec.ts +151 -35
  5. package/build/rollup_plugins.ts +4 -1
  6. package/dist/maplibre-gl-csp-worker.js +1 -1
  7. package/dist/maplibre-gl-csp-worker.js.map +1 -1
  8. package/dist/maplibre-gl-csp.js +1 -1
  9. package/dist/maplibre-gl-csp.js.map +1 -1
  10. package/dist/maplibre-gl-dev.js +1317 -4304
  11. package/dist/maplibre-gl.css +1 -1
  12. package/dist/maplibre-gl.d.ts +443 -145
  13. package/dist/maplibre-gl.js +4 -4
  14. package/dist/maplibre-gl.js.map +1 -1
  15. package/package.json +70 -67
  16. package/src/css/maplibre-gl.css +48 -32
  17. package/src/data/bucket/fill_bucket.test.ts +1 -0
  18. package/src/data/bucket/symbol_bucket.test.ts +2 -0
  19. package/src/data/bucket/symbol_bucket.ts +1 -1
  20. package/src/data/evaluation_feature.ts +1 -1
  21. package/src/data/program_configuration.ts +2 -2
  22. package/src/geo/transform.test.ts +34 -1
  23. package/src/geo/transform.ts +25 -15
  24. package/src/gl/vertex_buffer.ts +4 -4
  25. package/src/index.ts +1 -1
  26. package/src/render/draw_debug.ts +1 -1
  27. package/src/render/draw_symbol.test.ts +2 -23
  28. package/src/render/draw_terrain.ts +1 -1
  29. package/src/render/image_atlas.ts +1 -0
  30. package/src/render/image_manager.ts +1 -0
  31. package/src/render/program/debug_program.ts +1 -1
  32. package/src/render/render_to_texture.ts +3 -0
  33. package/src/render/terrain.test.ts +119 -17
  34. package/src/render/terrain.ts +39 -21
  35. package/src/shaders/README.md +2 -2
  36. package/src/shaders/shaders.ts +3 -1
  37. package/src/source/geojson_worker_source.test.ts +2 -2
  38. package/src/source/geojson_wrapper.test.ts +1 -1
  39. package/src/source/image_source.test.ts +8 -8
  40. package/src/source/image_source.ts +1 -1
  41. package/src/source/load_tilejson.ts +6 -1
  42. package/src/source/pixels_to_tile_units.ts +1 -1
  43. package/src/source/raster_tile_source.test.ts +1 -1
  44. package/src/source/source_cache.test.ts +12 -12
  45. package/src/source/source_cache.ts +1 -1
  46. package/src/source/terrain_source_cache.test.ts +17 -2
  47. package/src/source/terrain_source_cache.ts +16 -12
  48. package/src/source/vector_tile_source.test.ts +1 -1
  49. package/src/source/vector_tile_worker_source.test.ts +1 -1
  50. package/src/source/video_source.test.ts +2 -2
  51. package/src/style/light.test.ts +1 -1
  52. package/src/style/load_sprite.ts +1 -1
  53. package/src/style/parse_glyph_pbf.ts +1 -1
  54. package/src/style/style.test.ts +3 -3
  55. package/src/style/style.ts +2 -2
  56. package/src/style/style_layer/background_style_layer_properties.g.ts +1 -0
  57. package/src/style/style_layer/circle_style_layer_properties.g.ts +1 -0
  58. package/src/style/style_layer/fill_extrusion_style_layer_properties.g.ts +1 -0
  59. package/src/style/style_layer/fill_style_layer_properties.g.ts +1 -0
  60. package/src/style/style_layer/heatmap_style_layer_properties.g.ts +1 -0
  61. package/src/style/style_layer/hillshade_style_layer_properties.g.ts +1 -0
  62. package/src/style/style_layer/line_style_layer_properties.g.ts +1 -0
  63. package/src/style/style_layer/raster_style_layer_properties.g.ts +1 -0
  64. package/src/style/style_layer/symbol_style_layer.ts +16 -1
  65. package/src/style/style_layer/symbol_style_layer_properties.g.ts +4 -3
  66. package/src/style-spec/CHANGELOG.md +5 -0
  67. package/src/style-spec/composite.test.ts +2 -0
  68. package/src/style-spec/composite.ts +3 -2
  69. package/src/style-spec/diff.test.ts +3 -3
  70. package/src/style-spec/empty.ts +3 -2
  71. package/src/style-spec/expression/compound_expression.ts +0 -4
  72. package/src/style-spec/expression/definitions/assertion.ts +0 -18
  73. package/src/style-spec/expression/definitions/at.ts +0 -4
  74. package/src/style-spec/expression/definitions/case.ts +0 -6
  75. package/src/style-spec/expression/definitions/coalesce.ts +0 -6
  76. package/src/style-spec/expression/definitions/coercion.ts +13 -18
  77. package/src/style-spec/expression/definitions/collator.ts +0 -10
  78. package/src/style-spec/expression/definitions/comparison.ts +0 -6
  79. package/src/style-spec/expression/definitions/format.ts +0 -19
  80. package/src/style-spec/expression/definitions/image.ts +0 -4
  81. package/src/style-spec/expression/definitions/in.ts +0 -4
  82. package/src/style-spec/expression/definitions/index_of.ts +0 -8
  83. package/src/style-spec/expression/definitions/interpolate.ts +1 -25
  84. package/src/style-spec/expression/definitions/length.ts +0 -6
  85. package/src/style-spec/expression/definitions/let.ts +0 -9
  86. package/src/style-spec/expression/definitions/literal.ts +1 -23
  87. package/src/style-spec/expression/definitions/match.ts +0 -41
  88. package/src/style-spec/expression/definitions/number_format.ts +0 -17
  89. package/src/style-spec/expression/definitions/slice.ts +0 -8
  90. package/src/style-spec/expression/definitions/step.ts +0 -11
  91. package/src/style-spec/expression/definitions/var.ts +0 -4
  92. package/src/style-spec/expression/definitions/within.ts +0 -5
  93. package/src/style-spec/expression/expression.test.ts +1 -1
  94. package/src/style-spec/expression/expression.ts +3 -3
  95. package/src/style-spec/expression/index.ts +8 -2
  96. package/src/style-spec/expression/parsing_context.ts +2 -0
  97. package/src/style-spec/expression/types/formatted.ts +0 -23
  98. package/src/style-spec/expression/types/resolved_image.ts +0 -4
  99. package/src/style-spec/expression/types.ts +6 -1
  100. package/src/style-spec/expression/values.ts +9 -4
  101. package/src/style-spec/feature_filter/convert.ts +65 -65
  102. package/src/style-spec/feature_filter/feature_filter.test.ts +45 -4
  103. package/src/style-spec/feature_filter/index.ts +2 -1
  104. package/src/style-spec/function/index.test.ts +117 -1
  105. package/src/style-spec/function/index.ts +24 -12
  106. package/src/style-spec/migrate/expressions.ts +2 -2
  107. package/src/style-spec/migrate/v8.test.ts +2 -0
  108. package/src/style-spec/migrate/v8.ts +8 -7
  109. package/src/style-spec/migrate/v9.test.ts +6 -4
  110. package/src/style-spec/migrate/v9.ts +3 -2
  111. package/src/style-spec/migrate.test.ts +3 -1
  112. package/src/style-spec/migrate.ts +5 -4
  113. package/src/style-spec/package.json +1 -1
  114. package/src/style-spec/read_style.ts +2 -1
  115. package/src/style-spec/reference/latest.ts +1 -1
  116. package/src/style-spec/reference/v8.json +9 -6
  117. package/src/style-spec/style-spec.test.ts +2 -1
  118. package/src/style-spec/style-spec.ts +8 -0
  119. package/src/style-spec/types.g.ts +152 -36
  120. package/src/style-spec/util/extend.ts +1 -1
  121. package/src/style-spec/util/interpolate.test.ts +5 -0
  122. package/src/style-spec/util/interpolate.ts +12 -0
  123. package/src/style-spec/util/padding.test.ts +27 -0
  124. package/src/style-spec/util/padding.ts +64 -0
  125. package/src/style-spec/util/ref_properties.ts +2 -1
  126. package/src/style-spec/validate/validate.ts +3 -1
  127. package/src/style-spec/validate/validate_expression.ts +2 -1
  128. package/src/style-spec/validate/validate_function.ts +2 -2
  129. package/src/style-spec/validate/validate_glyphs_url.ts +1 -1
  130. package/src/style-spec/validate/validate_object.ts +2 -2
  131. package/src/style-spec/validate/validate_padding.test.ts +82 -0
  132. package/src/style-spec/validate/validate_padding.ts +36 -0
  133. package/src/style-spec/validate_style.min.ts +4 -3
  134. package/src/style-spec/validate_style.ts +4 -3
  135. package/src/symbol/check_max_angle.test.ts +5 -5
  136. package/src/symbol/collision_feature.test.ts +22 -5
  137. package/src/symbol/collision_feature.ts +7 -5
  138. package/src/symbol/collision_index.ts +1 -1
  139. package/src/symbol/get_anchors.test.ts +4 -4
  140. package/src/symbol/{mergelines.test.ts → merge_lines.test.ts} +1 -1
  141. package/src/symbol/{mergelines.ts → merge_lines.ts} +1 -1
  142. package/src/symbol/projection.ts +1 -1
  143. package/src/symbol/quads.test.ts +1 -1
  144. package/src/symbol/shaping.ts +10 -10
  145. package/src/symbol/symbol_layout.ts +5 -4
  146. package/src/symbol/symbol_style_layer.test.ts +1 -1
  147. package/src/symbol/transform_text.ts +3 -3
  148. package/src/ui/camera.test.ts +11 -11
  149. package/src/ui/control/geolocate_control.ts +1 -1
  150. package/src/ui/control/terrain_control.ts +4 -4
  151. package/src/ui/handler/cooperative_gestures.test.ts +167 -0
  152. package/src/ui/handler/drag_pan.test.ts +2 -1
  153. package/src/ui/handler/scroll_zoom.ts +7 -0
  154. package/src/ui/handler/touch_pan.ts +22 -2
  155. package/src/ui/handler/touch_zoom_rotate.ts +18 -1
  156. package/src/ui/handler_manager.ts +2 -2
  157. package/src/ui/map.test.ts +17 -17
  158. package/src/ui/map.ts +76 -8
  159. package/src/ui/map_events.test.ts +33 -32
  160. package/src/ui/popup.test.ts +2 -2
  161. package/src/util/ajax.test.ts +5 -5
  162. package/src/util/ajax.ts +1 -1
  163. package/src/util/classify_rings.test.ts +27 -27
  164. package/src/util/find_pole_of_inaccessibility.ts +1 -1
  165. package/src/util/primitives.ts +4 -4
  166. package/src/util/resolve_tokens.test.ts +1 -1
  167. package/src/util/smart_wrap.ts +1 -1
  168. package/src/util/tile_request_cache.test.ts +5 -5
  169. package/src/util/util.test.ts +5 -5
@@ -3,42 +3,160 @@
3
3
 
4
4
  export type ColorSpecification = string;
5
5
 
6
+ export type PaddingSpecification = number | number[];
7
+
6
8
  export type FormattedSpecification = string;
7
9
 
8
10
  export type ResolvedImageSpecification = string;
9
11
 
10
12
  export type PromoteIdSpecification = {[_: string]: string} | string;
11
13
 
12
- export type FilterSpecificationInputType = string | number | boolean;
13
- export type FilterSpecification =
14
- // Lookup
15
- | ['at', number, (number |string)[]]
16
- | ['get', string, Record<string, unknown>?]
17
- | ['has', string, Record<string, unknown>?]
18
- | ['in', ...FilterSpecificationInputType[], FilterSpecificationInputType | FilterSpecificationInputType[]]
19
- | ['index-of', FilterSpecificationInputType, FilterSpecificationInputType | FilterSpecificationInputType[]]
20
- | ['length', string | string[]]
21
- | ['slice', string | string[], number]
14
+ export type ExpressionInputType = string | number | boolean;
15
+
16
+ export type CollatorExpressionSpecification =
17
+ ['collator', {
18
+ 'case-sensitive'?: boolean | ExpressionSpecification,
19
+ 'diacritic-sensitive'?: boolean | ExpressionSpecification,
20
+ locale?: string | ExpressionSpecification}
21
+ ]; // collator
22
+
23
+ export type InterpolationSpecification =
24
+ | ['linear']
25
+ | ['exponential', number | ExpressionSpecification]
26
+ | ['cubic-bezier', number | ExpressionSpecification, number | ExpressionSpecification, number | ExpressionSpecification, number | ExpressionSpecification]
27
+
28
+ export type ExpressionSpecification =
29
+ // types
30
+ | ['array', unknown | ExpressionSpecification] // array
31
+ | ['array', ExpressionInputType | ExpressionSpecification, unknown | ExpressionSpecification] // array
32
+ | ['array', ExpressionInputType | ExpressionSpecification, number | ExpressionSpecification, unknown | ExpressionSpecification] // array
33
+ | ['boolean', ...(unknown | ExpressionSpecification)[], unknown | ExpressionSpecification] // boolean
34
+ | CollatorExpressionSpecification
35
+ | ['format', ...(string | ['image', ExpressionSpecification] | ExpressionSpecification | {'font-scale'?: number | ExpressionSpecification, 'text-font'?: string[] | ExpressionSpecification, 'text-color': ColorSpecification | ExpressionSpecification})[]] // string
36
+ | ['image', unknown | ExpressionSpecification] // image
37
+ | ['literal', unknown]
38
+ | ['number', unknown | ExpressionSpecification, ...(unknown | ExpressionSpecification)[]] // number
39
+ | ['number-format', number | ExpressionSpecification, {'locale'?: string | ExpressionSpecification, 'currency'?: string | ExpressionSpecification, 'min-fraction-digits'?: number | ExpressionSpecification, 'max-fraction-digits'?: number | ExpressionSpecification}] // string
40
+ | ['object', unknown | ExpressionSpecification, ...(unknown | ExpressionSpecification)[]] // object
41
+ | ['string', unknown | ExpressionSpecification, ...(unknown | ExpressionSpecification)[]] // string
42
+ | ['to-boolean', unknown | ExpressionSpecification] // boolean
43
+ | ['to-color', unknown | ExpressionSpecification, ...(unknown | ExpressionSpecification)[]] // color
44
+ | ['to-number', unknown | ExpressionSpecification, ...(unknown | ExpressionSpecification)[]] // number
45
+ | ['to-string', unknown | ExpressionSpecification] // string
46
+ // feature data
47
+ | ['accumulated']
48
+ | ['feature-state', string]
49
+ | ['geometry-type'] // string
50
+ | ['id']
51
+ | ['line-progress'] // number
52
+ | ['properties'] // object
53
+ // lookup
54
+ | ['at', number | ExpressionSpecification, ExpressionSpecification]
55
+ | ['get', string | ExpressionSpecification, (Record<string, unknown> | ExpressionSpecification)?]
56
+ | ['has', string | ExpressionSpecification, (Record<string, unknown> | ExpressionSpecification)?]
57
+ | ['in', ExpressionInputType | ExpressionSpecification, ExpressionInputType | ExpressionSpecification]
58
+ | ['index-of', ExpressionInputType | ExpressionSpecification, ExpressionInputType | ExpressionSpecification] // number
59
+ | ['length', string | ExpressionSpecification]
60
+ | ['slice', string | ExpressionSpecification, number | ExpressionSpecification]
22
61
  // Decision
23
- | ['!', FilterSpecification]
24
- | ['!=', string | FilterSpecification, FilterSpecificationInputType]
25
- | ['<', string | FilterSpecification, FilterSpecificationInputType]
26
- | ['<=', string | FilterSpecification, FilterSpecificationInputType]
27
- | ['==', string | FilterSpecification, FilterSpecificationInputType]
28
- | ['>', string | FilterSpecification, FilterSpecificationInputType]
29
- | ['>=', string | FilterSpecification, FilterSpecificationInputType]
30
- | ["all", ...FilterSpecification[], FilterSpecificationInputType]
31
- | ["any", ...FilterSpecification[], FilterSpecificationInputType]
32
- | ["case", ...FilterSpecification[], FilterSpecificationInputType]
33
- | ["coalesce", ...FilterSpecification[], FilterSpecificationInputType]
34
- | ["match", ...FilterSpecification[], FilterSpecificationInputType]
35
- | ["within", ...FilterSpecification[], FilterSpecificationInputType]
36
- // Used in convert.ts
37
- | ["!in", ...FilterSpecification[], FilterSpecificationInputType]
38
- | ["!has", ...FilterSpecification[], FilterSpecificationInputType]
39
- | ["none", ...FilterSpecification[], FilterSpecificationInputType]
40
- // Fallbak for others
41
- | Array<string | FilterSpecification>
62
+ | ['!', boolean | ExpressionSpecification] // boolean
63
+ | ['!=', ExpressionInputType | ExpressionSpecification, ExpressionInputType | ExpressionSpecification, CollatorExpressionSpecification?] // boolean
64
+ | ['<', ExpressionInputType | ExpressionSpecification, ExpressionInputType | ExpressionSpecification, CollatorExpressionSpecification?] // boolean
65
+ | ['<=', ExpressionInputType | ExpressionSpecification, ExpressionInputType | ExpressionSpecification, CollatorExpressionSpecification?] // boolean
66
+ | ['==', ExpressionInputType | ExpressionSpecification, ExpressionInputType | ExpressionSpecification, CollatorExpressionSpecification?] // boolean
67
+ | ['>', ExpressionInputType | ExpressionSpecification, ExpressionInputType | ExpressionSpecification, CollatorExpressionSpecification?] // boolean
68
+ | ['>=', ExpressionInputType | ExpressionSpecification, ExpressionInputType | ExpressionSpecification, CollatorExpressionSpecification?] // boolean
69
+ | ['all', ...(boolean | ExpressionSpecification)[]] // boolean
70
+ | ['any', ...(boolean | ExpressionSpecification)[]] // boolean
71
+ | ['case', boolean | ExpressionSpecification, ExpressionInputType | ExpressionSpecification,
72
+ ...(boolean | ExpressionInputType | ExpressionSpecification)[], ExpressionInputType | ExpressionSpecification]
73
+ | ['coalesce', ExpressionInputType | ExpressionSpecification, ExpressionInputType | ExpressionSpecification,
74
+ ...(ExpressionInputType | ExpressionSpecification)[]]
75
+ | ['match', ExpressionInputType | ExpressionSpecification,
76
+ ExpressionInputType | ExpressionInputType[], ExpressionInputType | ExpressionSpecification,
77
+ ...(ExpressionInputType | ExpressionInputType[] | ExpressionSpecification)[], // repeated as above
78
+ ExpressionInputType]
79
+ | ['within', unknown | ExpressionSpecification]
80
+ // Ramps, scales, curves
81
+ | ['interpolate', InterpolationSpecification,
82
+ number | ExpressionSpecification, number | ExpressionSpecification, ExpressionInputType | ExpressionSpecification,
83
+ ...(number | ExpressionInputType | ExpressionSpecification)[]]
84
+ | ['interpolate-hcl', InterpolationSpecification,
85
+ number | ExpressionSpecification, number | ExpressionSpecification, ExpressionInputType | ExpressionSpecification,
86
+ ...(number | ColorSpecification | ExpressionSpecification)[]]
87
+ | ['interpolate-lab', InterpolationSpecification,
88
+ number | ExpressionSpecification, number | ExpressionSpecification, ExpressionInputType | ExpressionSpecification,
89
+ ...(number | ColorSpecification | ExpressionSpecification)[]]
90
+ | ['step', number | ExpressionSpecification, number | ExpressionSpecification, ExpressionInputType | ExpressionSpecification,
91
+ ...(number | ExpressionInputType | ExpressionSpecification)[]]
92
+ // Variable binding
93
+ | ['let', string, ExpressionInputType | ExpressionSpecification, ...(string | ExpressionInputType | ExpressionSpecification)[]]
94
+ | ['var', string]
95
+ // String
96
+ | ['concat', ExpressionInputType | ExpressionSpecification, ExpressionInputType | ExpressionSpecification,
97
+ ...(ExpressionInputType | ExpressionSpecification)[]] // string
98
+ | ['downcase', string | ExpressionSpecification] // string
99
+ | ['is-supported-script', string | ExpressionSpecification] // boolean
100
+ | ['resolved-locale', CollatorExpressionSpecification] // string
101
+ | ['upcase', string | ExpressionSpecification] // string
102
+ // Color
103
+ | ['rgb', number | ExpressionSpecification, number | ExpressionSpecification, number | ExpressionSpecification] // color
104
+ | ['rgba', number | ExpressionSpecification, number | ExpressionSpecification, number | ExpressionSpecification, number | ExpressionSpecification]
105
+ | ['to-rgba', ColorSpecification | ExpressionSpecification]
106
+ // Math
107
+ | ['-', number | ExpressionSpecification, (number | ExpressionSpecification)?] // number
108
+ | ['*', number | ExpressionSpecification, number | ExpressionSpecification, ...(number | ExpressionSpecification)[]] // number
109
+ | ['/', number | ExpressionSpecification, number | ExpressionSpecification] // number
110
+ | ['%', number | ExpressionSpecification, number | ExpressionSpecification] // number
111
+ | ['^', number | ExpressionSpecification, number | ExpressionSpecification] // number
112
+ | ['+', number | ExpressionSpecification, number | ExpressionSpecification, ...(number | ExpressionSpecification)[]] // number
113
+ | ['abs', number | ExpressionSpecification] // number
114
+ | ['acos', number | ExpressionSpecification] // number
115
+ | ['asin', number | ExpressionSpecification] // number
116
+ | ['atan', number | ExpressionSpecification] // number
117
+ | ['ceil', number | ExpressionSpecification] // number
118
+ | ['cos', number | ExpressionSpecification] // number
119
+ | ['distance', Record<string, unknown> | ExpressionSpecification] // number
120
+ | ['ExpressionSpecification'] // number
121
+ | ['floor', number | ExpressionSpecification] // number
122
+ | ['ln', number | ExpressionSpecification] // number
123
+ | ['ln2'] // number
124
+ | ['log10', number | ExpressionSpecification] // number
125
+ | ['log2', number | ExpressionSpecification] // number
126
+ | ['max', number | ExpressionSpecification, ...(number | ExpressionSpecification)[]] // number
127
+ | ['min', number | ExpressionSpecification, ...(number | ExpressionSpecification)[]] // number
128
+ | ['pi'] // number
129
+ | ['round', number | ExpressionSpecification] // number
130
+ | ['sin', number | ExpressionSpecification] // number
131
+ | ['sqrt', number | ExpressionSpecification] // number
132
+ | ['tan', number | ExpressionSpecification] // number
133
+ // Zoom
134
+ | ['zoom'] // number
135
+ // Heatmap
136
+ | ['heatmap-density'] // number
137
+
138
+ export type ExpressionFilterSpecification = boolean | ExpressionSpecification
139
+
140
+ export type LegacyFilterSpecification =
141
+ // Existential
142
+ | ['has', string]
143
+ | ['!has', string]
144
+ // Comparison
145
+ | ['==', string, string | number | boolean]
146
+ | ['!=', string, string | number | boolean]
147
+ | ['>', string, string | number | boolean]
148
+ | ['>=', string, string | number | boolean]
149
+ | ['<', string, string | number | boolean]
150
+ | ['<=', string, string | number | boolean]
151
+ // Set membership
152
+ | ['in', string, ...(string | number | boolean)[]]
153
+ | ['!in', string, ...(string | number | boolean)[]]
154
+ // Combining
155
+ | ['all', ...LegacyFilterSpecification[]]
156
+ | ['any', ...LegacyFilterSpecification[]]
157
+ | ['none', ...LegacyFilterSpecification[]]
158
+
159
+ export type FilterSpecification = ExpressionFilterSpecification | LegacyFilterSpecification
42
160
 
43
161
  export type TransitionSpecification = {
44
162
  duration?: number,
@@ -62,19 +180,17 @@ export type CompositeFunctionSpecification<T> =
62
180
  | { type: 'interval', stops: Array<[{zoom: number, value: number}, T]>, property: string, default?: T }
63
181
  | { type: 'categorical', stops: Array<[{zoom: number, value: string | number | boolean}, T]>, property: string, default?: T };
64
182
 
65
- export type ExpressionSpecificationArray = Array<unknown>;
66
-
67
183
  export type PropertyValueSpecification<T> =
68
184
  T
69
185
  | CameraFunctionSpecification<T>
70
- | ExpressionSpecificationArray;
186
+ | ExpressionSpecification;
71
187
 
72
188
  export type DataDrivenPropertyValueSpecification<T> =
73
189
  T
74
190
  | CameraFunctionSpecification<T>
75
191
  | SourceFunctionSpecification<T>
76
192
  | CompositeFunctionSpecification<T>
77
- | ExpressionSpecificationArray;
193
+ | ExpressionSpecification;
78
194
 
79
195
  export type StyleSpecification = {
80
196
  "version": 8,
@@ -235,7 +351,7 @@ export type LineLayerSpecification = {
235
351
  "line-blur"?: DataDrivenPropertyValueSpecification<number>,
236
352
  "line-dasharray"?: PropertyValueSpecification<Array<number>>,
237
353
  "line-pattern"?: DataDrivenPropertyValueSpecification<ResolvedImageSpecification>,
238
- "line-gradient"?: ExpressionSpecificationArray
354
+ "line-gradient"?: ExpressionSpecification
239
355
  }
240
356
  };
241
357
 
@@ -264,7 +380,7 @@ export type SymbolLayerSpecification = {
264
380
  "icon-text-fit-padding"?: PropertyValueSpecification<[number, number, number, number]>,
265
381
  "icon-image"?: DataDrivenPropertyValueSpecification<ResolvedImageSpecification>,
266
382
  "icon-rotate"?: DataDrivenPropertyValueSpecification<number>,
267
- "icon-padding"?: PropertyValueSpecification<number>,
383
+ "icon-padding"?: DataDrivenPropertyValueSpecification<PaddingSpecification>,
268
384
  "icon-keep-upright"?: PropertyValueSpecification<boolean>,
269
385
  "icon-offset"?: DataDrivenPropertyValueSpecification<[number, number]>,
270
386
  "icon-anchor"?: DataDrivenPropertyValueSpecification<"center" | "left" | "right" | "top" | "bottom" | "top-left" | "top-right" | "bottom-left" | "bottom-right">,
@@ -356,7 +472,7 @@ export type HeatmapLayerSpecification = {
356
472
  "heatmap-radius"?: DataDrivenPropertyValueSpecification<number>,
357
473
  "heatmap-weight"?: DataDrivenPropertyValueSpecification<number>,
358
474
  "heatmap-intensity"?: PropertyValueSpecification<number>,
359
- "heatmap-color"?: ExpressionSpecificationArray,
475
+ "heatmap-color"?: ExpressionSpecification,
360
476
  "heatmap-opacity"?: PropertyValueSpecification<number>
361
477
  }
362
478
  };
@@ -1,4 +1,4 @@
1
- export default function(output: any, ...inputs: Array<any>) {
1
+ export default function extendBy(output: any, ...inputs: Array<any>) {
2
2
  for (const input of inputs) {
3
3
  for (const k in input) {
4
4
  output[k] = input[k];
@@ -1,5 +1,6 @@
1
1
  import * as interpolate from './interpolate';
2
2
  import Color from './color';
3
+ import Padding from './padding';
3
4
 
4
5
  describe('interpolate', () => {
5
6
  test('interpolate.number', () => {
@@ -13,4 +14,8 @@ describe('interpolate', () => {
13
14
  test('interpolate.array', () => {
14
15
  expect(interpolate.array([0, 0, 0, 0], [1, 2, 3, 4], 0.5)).toEqual([0.5, 1, 3 / 2, 2]);
15
16
  });
17
+
18
+ test('interpolate.padding', () => {
19
+ expect(interpolate.padding(new Padding([0, 0, 0, 0]), new Padding([1, 2, 3, 4]), 0.5)).toEqual(new Padding([0.5, 1, 3 / 2, 2]));
20
+ });
16
21
  });
@@ -1,4 +1,5 @@
1
1
  import Color from './color';
2
+ import Padding from './padding';
2
3
 
3
4
  export function number(a: number, b: number, t: number) {
4
5
  return (a * (1 - t)) + (b * t);
@@ -18,3 +19,14 @@ export function array(from: Array<number>, to: Array<number>, t: number): Array<
18
19
  return number(d, to[i], t);
19
20
  });
20
21
  }
22
+
23
+ export function padding(from: Padding, to: Padding, t: number): Padding {
24
+ const fromVal = from.values;
25
+ const toVal = to.values;
26
+ return new Padding([
27
+ number(fromVal[0], toVal[0], t),
28
+ number(fromVal[1], toVal[1], t),
29
+ number(fromVal[2], toVal[2], t),
30
+ number(fromVal[3], toVal[3], t)
31
+ ]);
32
+ }
@@ -0,0 +1,27 @@
1
+ import Padding from './padding';
2
+
3
+ describe('Padding', () => {
4
+ test('Padding.parse', () => {
5
+ expect(Padding.parse()).toBeUndefined();
6
+ expect(Padding.parse(null)).toBeUndefined();
7
+ expect(Padding.parse(undefined)).toBeUndefined();
8
+ expect(Padding.parse('Dennis' as any)).toBeUndefined();
9
+ expect(Padding.parse('3' as any)).toBeUndefined();
10
+ expect(Padding.parse([])).toBeUndefined();
11
+ expect(Padding.parse([3, '4'] as any)).toBeUndefined();
12
+ expect(Padding.parse(5)).toEqual(new Padding([5, 5, 5, 5]));
13
+ expect(Padding.parse([1])).toEqual(new Padding([1, 1, 1, 1]));
14
+ expect(Padding.parse([1, 2])).toEqual(new Padding([1, 2, 1, 2]));
15
+ expect(Padding.parse([1, 2, 3])).toEqual(new Padding([1, 2, 3, 2]));
16
+ expect(Padding.parse([1, 2, 3, 4])).toEqual(new Padding([1, 2, 3, 4]));
17
+ expect(Padding.parse([1, 2, 3, 4, 5])).toBeUndefined();
18
+
19
+ const passThru = new Padding([1, 2, 3, 4]);
20
+ expect(Padding.parse(passThru)).toBe(passThru);
21
+ });
22
+
23
+ test('Padding#toString', () => {
24
+ const padding = new Padding([1, 2, 3, 4]);
25
+ expect(padding.toString()).toBe('[1,2,3,4]');
26
+ });
27
+ });
@@ -0,0 +1,64 @@
1
+ /**
2
+ * A set of four numbers representing padding around a box. Create instances from
3
+ * bare arrays or numeric values using the static method `Padding.parse`.
4
+ * @private
5
+ */
6
+ class Padding {
7
+ /** Padding values are in CSS order: top, right, bottom, left */
8
+ values: [number, number, number, number];
9
+
10
+ constructor(values: [number, number, number, number]) {
11
+ this.values = values.slice() as [number, number, number, number];
12
+ }
13
+
14
+ /**
15
+ * Numeric padding values
16
+ * @returns A `Padding` instance, or `undefined` if the input is not a valid padding value.
17
+ */
18
+ static parse(input?: number | number[] | Padding | null): Padding | void {
19
+ if (input instanceof Padding) {
20
+ return input;
21
+ }
22
+
23
+ // Backwards compatibility: bare number is treated the same as array with single value.
24
+ // Padding applies to all four sides.
25
+ if (typeof input === 'number') {
26
+ return new Padding([input, input, input, input]);
27
+ }
28
+
29
+ if (!Array.isArray(input)) {
30
+ return undefined;
31
+ }
32
+
33
+ if (input.length < 1 || input.length > 4) {
34
+ return undefined;
35
+ }
36
+
37
+ for (const val of input) {
38
+ if (typeof val !== 'number') {
39
+ return undefined;
40
+ }
41
+ }
42
+
43
+ // Expand shortcut properties into explicit 4-sided values
44
+ switch (input.length) {
45
+ case 1:
46
+ input = [input[0], input[0], input[0], input[0]];
47
+ break;
48
+ case 2:
49
+ input = [input[0], input[1], input[0], input[1]];
50
+ break;
51
+ case 3:
52
+ input = [input[0], input[1], input[2], input[1]];
53
+ break;
54
+ }
55
+
56
+ return new Padding(input as [number, number, number, number]);
57
+ }
58
+
59
+ toString(): string {
60
+ return JSON.stringify(this.values);
61
+ }
62
+ }
63
+
64
+ export default Padding;
@@ -1,2 +1,3 @@
1
1
 
2
- export default ['type', 'source', 'source-layer', 'minzoom', 'maxzoom', 'filter', 'layout'];
2
+ const refProperties = ['type', 'source', 'source-layer', 'minzoom', 'maxzoom', 'filter', 'layout'];
3
+ export default refProperties;
@@ -21,6 +21,7 @@ import validateTerrain from './validate_terrain';
21
21
  import validateString from './validate_string';
22
22
  import validateFormatted from './validate_formatted';
23
23
  import validateImage from './validate_image';
24
+ import validatePadding from './validate_padding';
24
25
 
25
26
  const VALIDATORS = {
26
27
  '*'() {
@@ -41,7 +42,8 @@ const VALIDATORS = {
41
42
  'terrain': validateTerrain,
42
43
  'string': validateString,
43
44
  'formatted': validateFormatted,
44
- 'resolvedImage': validateImage
45
+ 'resolvedImage': validateImage,
46
+ 'padding': validatePadding
45
47
  };
46
48
 
47
49
  // Main recursive validation function. Tracks:
@@ -3,6 +3,7 @@ import ValidationError from '../error/validation_error';
3
3
  import {createExpression, createPropertyExpression} from '../expression';
4
4
  import {deepUnbundle} from '../util/unbundle_jsonlint';
5
5
  import {isStateConstant, isGlobalPropertyConstant, isFeatureConstant} from '../expression/is_constant';
6
+ import {Expression} from '../expression/expression';
6
7
 
7
8
  export default function validateExpression(options: any): Array<ValidationError> {
8
9
  const expression = (options.expressionContext === 'property' ? createPropertyExpression : createExpression)(deepUnbundle(options.value), options.valueSpec);
@@ -12,7 +13,7 @@ export default function validateExpression(options: any): Array<ValidationError>
12
13
  });
13
14
  }
14
15
 
15
- const expressionObj = (expression.value as any).expression || (expression.value as any)._styleExpression.expression;
16
+ const expressionObj: Expression = (expression.value as any).expression || (expression.value as any)._styleExpression.expression;
16
17
 
17
18
  if (options.expressionContext === 'property' && (options.propertyKey === 'text-font') &&
18
19
  !expressionObj.outputDefined()) {
@@ -13,7 +13,7 @@ import {
13
13
  supportsInterpolation
14
14
  } from '../util/properties';
15
15
 
16
- export default function validateFunction(options) {
16
+ export default function validateFunction(options): Array<ValidationError> {
17
17
  const functionValueSpec = options.valueSpec;
18
18
  const functionType = unbundle(options.value.type);
19
19
  let stopKeyType;
@@ -195,7 +195,7 @@ export default function validateFunction(options) {
195
195
  return [];
196
196
  }
197
197
 
198
- function validateFunctionDefault(options) {
198
+ function validateFunctionDefault(options): Array<ValidationError> {
199
199
  return validate({
200
200
  key: options.key,
201
201
  value: options.value,
@@ -2,7 +2,7 @@
2
2
  import ValidationError from '../error/validation_error';
3
3
  import validateString from './validate_string';
4
4
 
5
- export default function(options) {
5
+ export default function validateGlyphsUrl(options) {
6
6
  const value = options.value;
7
7
  const key = options.key;
8
8
 
@@ -3,14 +3,14 @@ import ValidationError from '../error/validation_error';
3
3
  import getType from '../util/get_type';
4
4
  import validateSpec from './validate';
5
5
 
6
- export default function validateObject(options) {
6
+ export default function validateObject(options): Array<ValidationError> {
7
7
  const key = options.key;
8
8
  const object = options.value;
9
9
  const elementSpecs = options.valueSpec || {};
10
10
  const elementValidators = options.objectElementValidators || {};
11
11
  const style = options.style;
12
12
  const styleSpec = options.styleSpec;
13
- let errors = [];
13
+ let errors = [] as Array<ValidationError>;
14
14
 
15
15
  const type = getType(object);
16
16
  if (type !== 'object') {
@@ -0,0 +1,82 @@
1
+ import validatePadding from './validate_padding';
2
+
3
+ describe('Validate Padding', () => {
4
+ test('Should return error if type is not number or array', () => {
5
+ let errors = validatePadding({key: 'padding', value: '3'});
6
+ expect(errors).toHaveLength(1);
7
+ expect(errors[0].message).toBe('padding: number expected, string found');
8
+
9
+ errors = validatePadding({key: 'padding', value: true});
10
+ expect(errors).toHaveLength(1);
11
+ expect(errors[0].message).toBe('padding: number expected, boolean found');
12
+
13
+ errors = validatePadding({key: 'padding', value: null});
14
+ expect(errors).toHaveLength(1);
15
+ expect(errors[0].message).toBe('padding: number expected, null found');
16
+
17
+ errors = validatePadding({key: 'padding', value: {x: 1, y: 1}});
18
+ expect(errors).toHaveLength(1);
19
+ expect(errors[0].message).toBe('padding: number expected, object found');
20
+
21
+ errors = validatePadding({key: 'padding', value: NaN});
22
+ expect(errors).toHaveLength(1);
23
+ expect(errors[0].message).toBe('padding: number expected, NaN found');
24
+ });
25
+
26
+ test('Should pass if type is number', () => {
27
+ const errors = validatePadding({key: 'padding', value: 1});
28
+ expect(errors).toHaveLength(0);
29
+ });
30
+
31
+ test('Should return error if array length is invalid', () => {
32
+ let errors = validatePadding({key: 'padding', value: []});
33
+ expect(errors).toHaveLength(1);
34
+ expect(errors[0].message).toBe('padding: padding requires 1 to 4 values; 0 values found');
35
+
36
+ errors = validatePadding({key: 'padding', value: [1, 1, 1, 1, 1]});
37
+ expect(errors).toHaveLength(1);
38
+ expect(errors[0].message).toBe('padding: padding requires 1 to 4 values; 5 values found');
39
+
40
+ errors = validatePadding({key: 'padding', value: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]});
41
+ expect(errors).toHaveLength(1);
42
+ expect(errors[0].message).toBe('padding: padding requires 1 to 4 values; 12 values found');
43
+ });
44
+
45
+ test('Should return error if array contains non-numeric values', () => {
46
+ let errors = validatePadding({key: 'padding', value: ['1']});
47
+ expect(errors).toHaveLength(1);
48
+ expect(errors[0].message).toBe('padding[0]: number expected, string found');
49
+
50
+ errors = validatePadding({key: 'padding', value: [true]});
51
+ expect(errors).toHaveLength(1);
52
+ expect(errors[0].message).toBe('padding[0]: number expected, boolean found');
53
+
54
+ errors = validatePadding({key: 'padding', value: [NaN]});
55
+ expect(errors).toHaveLength(1);
56
+ expect(errors[0].message).toBe('padding[0]: number expected, NaN found');
57
+
58
+ errors = validatePadding({key: 'padding', value: [{x: 1}]});
59
+ expect(errors).toHaveLength(1);
60
+ expect(errors[0].message).toBe('padding[0]: number expected, object found');
61
+
62
+ errors = validatePadding({key: 'padding', value: [1, 3, false]});
63
+ expect(errors).toHaveLength(1);
64
+ expect(errors[0].message).toBe('padding[2]: number expected, boolean found');
65
+
66
+ errors = validatePadding({key: 'padding', value: ['1', 3, false]});
67
+ expect(errors).toHaveLength(2);
68
+ expect(errors[0].message).toBe('padding[0]: number expected, string found');
69
+ expect(errors[1].message).toBe('padding[2]: number expected, boolean found');
70
+ });
71
+
72
+ test('Should pass if type is numeric array', () => {
73
+ let errors = validatePadding({key: 'padding', value: [1]});
74
+ expect(errors).toHaveLength(0);
75
+ errors = validatePadding({key: 'padding', value: [1, 1]});
76
+ expect(errors).toHaveLength(0);
77
+ errors = validatePadding({key: 'padding', value: [1, 1, 1]});
78
+ expect(errors).toHaveLength(0);
79
+ errors = validatePadding({key: 'padding', value: [1, 1, 1, 1]});
80
+ expect(errors).toHaveLength(0);
81
+ });
82
+ });
@@ -0,0 +1,36 @@
1
+ import ValidationError from '../error/validation_error';
2
+ import getType from '../util/get_type';
3
+ import validate from './validate';
4
+ import validateNumber from './validate_number';
5
+
6
+ export default function validatePadding(options) {
7
+ const key = options.key;
8
+ const value = options.value;
9
+ const type = getType(value);
10
+
11
+ if (type === 'array') {
12
+ if (value.length < 1 || value.length > 4) {
13
+ return [new ValidationError(key, value, `padding requires 1 to 4 values; ${value.length} values found`)];
14
+ }
15
+
16
+ const arrayElementSpec = {
17
+ type: 'number'
18
+ };
19
+
20
+ let errors = [];
21
+ for (let i = 0; i < value.length; i++) {
22
+ errors = errors.concat(validate({
23
+ key: `${key}[${i}]`,
24
+ value: value[i],
25
+ valueSpec: arrayElementSpec
26
+ }));
27
+ }
28
+ return errors;
29
+ } else {
30
+ return validateNumber({
31
+ key,
32
+ value,
33
+ valueSpec: {}
34
+ });
35
+ }
36
+ }
@@ -11,6 +11,7 @@ import validateLayer from './validate/validate_layer';
11
11
  import validateFilter from './validate/validate_filter';
12
12
  import validatePaintProperty from './validate/validate_paint_property';
13
13
  import validateLayoutProperty from './validate/validate_layout_property';
14
+ import type {StyleSpecification} from './types.g';
14
15
 
15
16
  /**
16
17
  * Validate a MapLibre GL style against the style specification. This entrypoint,
@@ -27,7 +28,7 @@ import validateLayoutProperty from './validate/validate_layout_property';
27
28
  * var validate = require('maplibre-gl-style-spec/lib/validate_style.min');
28
29
  * var errors = validate(style);
29
30
  */
30
- function validateStyleMin(style, styleSpec = latestStyleSpec) {
31
+ function validateStyleMin(style: StyleSpecification, styleSpec = latestStyleSpec) {
31
32
 
32
33
  let errors = [];
33
34
 
@@ -45,10 +46,10 @@ function validateStyleMin(style, styleSpec = latestStyleSpec) {
45
46
  }
46
47
  }));
47
48
 
48
- if (style.constants) {
49
+ if (style['constants']) {
49
50
  errors = errors.concat(validateConstants({
50
51
  key: 'constants',
51
- value: style.constants,
52
+ value: style['constants'],
52
53
  style,
53
54
  styleSpec
54
55
  }));
@@ -1,14 +1,15 @@
1
1
 
2
2
  import validateStyleMin from './validate_style.min';
3
- import {v8} from './style-spec';
3
+ import {v8, ValidationError} from './style-spec';
4
4
  import readStyle from './read_style';
5
+ import type {StyleSpecification} from './types.g';
5
6
 
6
7
  /**
7
8
  * Validate a Mapbox GL style against the style specification.
8
9
  *
9
10
  * @private
10
11
  * @alias validate
11
- * @param {Object|String|Buffer} style The style to be validated. If a `String`
12
+ * @param {StyleSpecification|string|Buffer} style The style to be validated. If a `String`
12
13
  * or `Buffer` is provided, the returned errors will contain line numbers.
13
14
  * @param {Object} [styleSpec] The style specification to validate against.
14
15
  * If omitted, the spec version is inferred from the stylesheet.
@@ -19,7 +20,7 @@ import readStyle from './read_style';
19
20
  * var errors = validate(style);
20
21
  */
21
22
 
22
- export default function validateStyle(style, styleSpec = v8) {
23
+ export default function validateStyle(style: StyleSpecification | string | Buffer, styleSpec = v8): Array<ValidationError> {
23
24
  let s = style;
24
25
 
25
26
  try {