@scoova/mgl 1.0.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 (565) hide show
  1. package/LICENSE.txt +116 -0
  2. package/README.md +174 -0
  3. package/build/banner.ts +12 -0
  4. package/build/bump-version-changelog.js +26 -0
  5. package/build/check-bundle-size.js +77 -0
  6. package/build/generate-dist-package.js +26 -0
  7. package/build/generate-doc-images.ts +78 -0
  8. package/build/generate-docs.ts +190 -0
  9. package/build/generate-shaders.ts +68 -0
  10. package/build/generate-struct-arrays.ts +438 -0
  11. package/build/generate-style-code.ts +283 -0
  12. package/build/readme.md +56 -0
  13. package/build/release-notes.js +45 -0
  14. package/build/rollup/bundle_prelude.js +29 -0
  15. package/build/rollup/maplibregl.js +22 -0
  16. package/build/rollup_plugins.ts +58 -0
  17. package/dist/LICENSE.txt +116 -0
  18. package/dist/maplibre-gl.css +1 -0
  19. package/dist/maplibre-gl.d.ts +13304 -0
  20. package/dist/maplibre-gl.js +59 -0
  21. package/dist/maplibre-gl.js.map +1 -0
  22. package/dist/package.json +1 -0
  23. package/package.json +192 -0
  24. package/src/css/maplibre-gl.css +854 -0
  25. package/src/css/svg/maplibregl-ctrl-attrib.svg +3 -0
  26. package/src/css/svg/maplibregl-ctrl-compass.svg +4 -0
  27. package/src/css/svg/maplibregl-ctrl-fullscreen.svg +3 -0
  28. package/src/css/svg/maplibregl-ctrl-geolocate.svg +5 -0
  29. package/src/css/svg/maplibregl-ctrl-logo.svg +11 -0
  30. package/src/css/svg/maplibregl-ctrl-shrink.svg +3 -0
  31. package/src/css/svg/maplibregl-ctrl-terrain.svg +3 -0
  32. package/src/css/svg/maplibregl-ctrl-zoom-in.svg +3 -0
  33. package/src/css/svg/maplibregl-ctrl-zoom-out.svg +3 -0
  34. package/src/data/array_types.g.ts +1130 -0
  35. package/src/data/bucket/circle_attributes.ts +8 -0
  36. package/src/data/bucket/circle_bucket.ts +197 -0
  37. package/src/data/bucket/fill_attributes.ts +8 -0
  38. package/src/data/bucket/fill_bucket.test.ts +95 -0
  39. package/src/data/bucket/fill_bucket.ts +228 -0
  40. package/src/data/bucket/fill_extrusion_attributes.ts +13 -0
  41. package/src/data/bucket/fill_extrusion_bucket.ts +305 -0
  42. package/src/data/bucket/heatmap_bucket.ts +12 -0
  43. package/src/data/bucket/line_attributes.ts +8 -0
  44. package/src/data/bucket/line_attributes_ext.ts +8 -0
  45. package/src/data/bucket/line_bucket.test.ts +142 -0
  46. package/src/data/bucket/line_bucket.ts +592 -0
  47. package/src/data/bucket/pattern_attributes.ts +9 -0
  48. package/src/data/bucket/pattern_bucket_features.ts +57 -0
  49. package/src/data/bucket/symbol_attributes.ts +122 -0
  50. package/src/data/bucket/symbol_bucket.test.ts +243 -0
  51. package/src/data/bucket/symbol_bucket.ts +975 -0
  52. package/src/data/bucket.ts +123 -0
  53. package/src/data/dem_data.test.ts +237 -0
  54. package/src/data/dem_data.ts +171 -0
  55. package/src/data/evaluation_feature.ts +18 -0
  56. package/src/data/extent.ts +13 -0
  57. package/src/data/feature_index.ts +337 -0
  58. package/src/data/feature_position_map.test.ts +33 -0
  59. package/src/data/feature_position_map.ts +126 -0
  60. package/src/data/index_array_type.ts +9 -0
  61. package/src/data/load_geometry.test.ts +49 -0
  62. package/src/data/load_geometry.ts +44 -0
  63. package/src/data/pos3d_attributes.ts +5 -0
  64. package/src/data/pos_attributes.ts +5 -0
  65. package/src/data/program_configuration.ts +735 -0
  66. package/src/data/raster_bounds_attributes.ts +6 -0
  67. package/src/data/segment.ts +89 -0
  68. package/src/geo/edge_insets.test.ts +83 -0
  69. package/src/geo/edge_insets.ts +146 -0
  70. package/src/geo/lng_lat.test.ts +65 -0
  71. package/src/geo/lng_lat.ts +169 -0
  72. package/src/geo/lng_lat_bounds.test.ts +357 -0
  73. package/src/geo/lng_lat_bounds.ts +356 -0
  74. package/src/geo/mercator_coordinate.test.ts +34 -0
  75. package/src/geo/mercator_coordinate.ts +157 -0
  76. package/src/geo/projection/projection.ts +72 -0
  77. package/src/geo/transform.test.ts +509 -0
  78. package/src/geo/transform.ts +1072 -0
  79. package/src/gl/color_mode.ts +31 -0
  80. package/src/gl/context.ts +321 -0
  81. package/src/gl/cull_face_mode.ts +22 -0
  82. package/src/gl/depth_mode.ts +26 -0
  83. package/src/gl/framebuffer.ts +48 -0
  84. package/src/gl/index_buffer.ts +55 -0
  85. package/src/gl/render_pool.test.ts +69 -0
  86. package/src/gl/render_pool.ts +93 -0
  87. package/src/gl/state.test.ts +125 -0
  88. package/src/gl/stencil_mode.ts +27 -0
  89. package/src/gl/types.ts +59 -0
  90. package/src/gl/value.ts +534 -0
  91. package/src/gl/vertex_buffer.test.ts +57 -0
  92. package/src/gl/vertex_buffer.ts +111 -0
  93. package/src/gl/webgl2.ts +12 -0
  94. package/src/index.test.ts +121 -0
  95. package/src/index.ts +250 -0
  96. package/src/render/draw_background.ts +53 -0
  97. package/src/render/draw_circle.ts +113 -0
  98. package/src/render/draw_collision_debug.ts +168 -0
  99. package/src/render/draw_custom.test.ts +73 -0
  100. package/src/render/draw_custom.ts +45 -0
  101. package/src/render/draw_debug.test.ts +122 -0
  102. package/src/render/draw_debug.ts +148 -0
  103. package/src/render/draw_fill.test.ts +137 -0
  104. package/src/render/draw_fill.ts +128 -0
  105. package/src/render/draw_fill_extrusion.ts +97 -0
  106. package/src/render/draw_heatmap.ts +228 -0
  107. package/src/render/draw_hillshade.ts +119 -0
  108. package/src/render/draw_line.ts +125 -0
  109. package/src/render/draw_raster.ts +133 -0
  110. package/src/render/draw_sky.ts +44 -0
  111. package/src/render/draw_symbol.test.ts +223 -0
  112. package/src/render/draw_symbol.ts +499 -0
  113. package/src/render/draw_terrain.ts +99 -0
  114. package/src/render/glyph_atlas.ts +83 -0
  115. package/src/render/glyph_manager.test.ts +147 -0
  116. package/src/render/glyph_manager.ts +198 -0
  117. package/src/render/image_atlas.ts +159 -0
  118. package/src/render/image_manager.ts +337 -0
  119. package/src/render/line_atlas.test.ts +38 -0
  120. package/src/render/line_atlas.ts +214 -0
  121. package/src/render/mesh.ts +25 -0
  122. package/src/render/painter.test.ts +51 -0
  123. package/src/render/painter.ts +666 -0
  124. package/src/render/program/background_program.ts +100 -0
  125. package/src/render/program/circle_program.ts +61 -0
  126. package/src/render/program/clipping_mask_program.ts +19 -0
  127. package/src/render/program/collision_program.ts +47 -0
  128. package/src/render/program/debug_program.ts +29 -0
  129. package/src/render/program/fill_extrusion_program.ts +120 -0
  130. package/src/render/program/fill_program.ts +121 -0
  131. package/src/render/program/heatmap_program.ts +76 -0
  132. package/src/render/program/hillshade_program.ts +116 -0
  133. package/src/render/program/line_program.ts +207 -0
  134. package/src/render/program/pattern.ts +102 -0
  135. package/src/render/program/program_uniforms.ts +46 -0
  136. package/src/render/program/raster_program.ts +88 -0
  137. package/src/render/program/sky_program.ts +28 -0
  138. package/src/render/program/symbol_program.ts +266 -0
  139. package/src/render/program/terrain_program.ts +116 -0
  140. package/src/render/program.ts +233 -0
  141. package/src/render/render_to_texture.test.ts +151 -0
  142. package/src/render/render_to_texture.ts +197 -0
  143. package/src/render/terrain.test.ts +322 -0
  144. package/src/render/terrain.ts +464 -0
  145. package/src/render/texture.ts +114 -0
  146. package/src/render/uniform_binding.test.ts +122 -0
  147. package/src/render/uniform_binding.ts +157 -0
  148. package/src/render/update_pattern_positions_in_program.test.ts +74 -0
  149. package/src/render/update_pattern_positions_in_program.ts +50 -0
  150. package/src/render/vertex_array_object.ts +163 -0
  151. package/src/shaders/README.md +42 -0
  152. package/src/shaders/_prelude.fragment.glsl +19 -0
  153. package/src/shaders/_prelude.fragment.glsl.g.ts +2 -0
  154. package/src/shaders/_prelude.vertex.glsl +148 -0
  155. package/src/shaders/_prelude.vertex.glsl.g.ts +2 -0
  156. package/src/shaders/background.fragment.glsl +10 -0
  157. package/src/shaders/background.fragment.glsl.g.ts +2 -0
  158. package/src/shaders/background.vertex.glsl +7 -0
  159. package/src/shaders/background.vertex.glsl.g.ts +2 -0
  160. package/src/shaders/background_pattern.fragment.glsl +28 -0
  161. package/src/shaders/background_pattern.fragment.glsl.g.ts +2 -0
  162. package/src/shaders/background_pattern.vertex.glsl +19 -0
  163. package/src/shaders/background_pattern.vertex.glsl.g.ts +2 -0
  164. package/src/shaders/circle.fragment.glsl +34 -0
  165. package/src/shaders/circle.fragment.glsl.g.ts +2 -0
  166. package/src/shaders/circle.vertex.glsl +68 -0
  167. package/src/shaders/circle.vertex.glsl.g.ts +2 -0
  168. package/src/shaders/clipping_mask.fragment.glsl +3 -0
  169. package/src/shaders/clipping_mask.fragment.glsl.g.ts +2 -0
  170. package/src/shaders/clipping_mask.vertex.glsl +7 -0
  171. package/src/shaders/clipping_mask.vertex.glsl.g.ts +2 -0
  172. package/src/shaders/collision_box.fragment.glsl +20 -0
  173. package/src/shaders/collision_box.fragment.glsl.g.ts +2 -0
  174. package/src/shaders/collision_box.vertex.glsl +27 -0
  175. package/src/shaders/collision_box.vertex.glsl.g.ts +2 -0
  176. package/src/shaders/collision_circle.fragment.glsl +17 -0
  177. package/src/shaders/collision_circle.fragment.glsl.g.ts +2 -0
  178. package/src/shaders/collision_circle.vertex.glsl +59 -0
  179. package/src/shaders/collision_circle.vertex.glsl.g.ts +2 -0
  180. package/src/shaders/debug.fragment.glsl +9 -0
  181. package/src/shaders/debug.fragment.glsl.g.ts +2 -0
  182. package/src/shaders/debug.vertex.glsl +12 -0
  183. package/src/shaders/debug.vertex.glsl.g.ts +2 -0
  184. package/src/shaders/encode_attribute.test.ts +11 -0
  185. package/src/shaders/encode_attribute.ts +13 -0
  186. package/src/shaders/fill.fragment.glsl +13 -0
  187. package/src/shaders/fill.fragment.glsl.g.ts +2 -0
  188. package/src/shaders/fill.vertex.glsl +13 -0
  189. package/src/shaders/fill.vertex.glsl.g.ts +2 -0
  190. package/src/shaders/fill_extrusion.fragment.glsl +9 -0
  191. package/src/shaders/fill_extrusion.fragment.glsl.g.ts +2 -0
  192. package/src/shaders/fill_extrusion.vertex.glsl +84 -0
  193. package/src/shaders/fill_extrusion.vertex.glsl.g.ts +2 -0
  194. package/src/shaders/fill_extrusion_pattern.fragment.glsl +47 -0
  195. package/src/shaders/fill_extrusion_pattern.fragment.glsl.g.ts +2 -0
  196. package/src/shaders/fill_extrusion_pattern.vertex.glsl +96 -0
  197. package/src/shaders/fill_extrusion_pattern.vertex.glsl.g.ts +2 -0
  198. package/src/shaders/fill_outline.fragment.glsl +17 -0
  199. package/src/shaders/fill_outline.fragment.glsl.g.ts +2 -0
  200. package/src/shaders/fill_outline.vertex.glsl +17 -0
  201. package/src/shaders/fill_outline.vertex.glsl.g.ts +2 -0
  202. package/src/shaders/fill_outline_pattern.fragment.glsl +43 -0
  203. package/src/shaders/fill_outline_pattern.fragment.glsl.g.ts +2 -0
  204. package/src/shaders/fill_outline_pattern.vertex.glsl +44 -0
  205. package/src/shaders/fill_outline_pattern.vertex.glsl.g.ts +2 -0
  206. package/src/shaders/fill_pattern.fragment.glsl +39 -0
  207. package/src/shaders/fill_pattern.fragment.glsl.g.ts +2 -0
  208. package/src/shaders/fill_pattern.vertex.glsl +39 -0
  209. package/src/shaders/fill_pattern.vertex.glsl.g.ts +2 -0
  210. package/src/shaders/heatmap.fragment.glsl +22 -0
  211. package/src/shaders/heatmap.fragment.glsl.g.ts +2 -0
  212. package/src/shaders/heatmap.vertex.glsl +54 -0
  213. package/src/shaders/heatmap.vertex.glsl.g.ts +2 -0
  214. package/src/shaders/heatmap_texture.fragment.glsl +15 -0
  215. package/src/shaders/heatmap_texture.fragment.glsl.g.ts +2 -0
  216. package/src/shaders/heatmap_texture.vertex.glsl +11 -0
  217. package/src/shaders/heatmap_texture.vertex.glsl.g.ts +2 -0
  218. package/src/shaders/hillshade.fragment.glsl +52 -0
  219. package/src/shaders/hillshade.fragment.glsl.g.ts +2 -0
  220. package/src/shaders/hillshade.vertex.glsl +11 -0
  221. package/src/shaders/hillshade.vertex.glsl.g.ts +2 -0
  222. package/src/shaders/hillshade_prepare.fragment.glsl +77 -0
  223. package/src/shaders/hillshade_prepare.fragment.glsl.g.ts +2 -0
  224. package/src/shaders/hillshade_prepare.vertex.glsl +15 -0
  225. package/src/shaders/hillshade_prepare.vertex.glsl.g.ts +2 -0
  226. package/src/shaders/line.fragment.glsl +30 -0
  227. package/src/shaders/line.fragment.glsl.g.ts +2 -0
  228. package/src/shaders/line.vertex.glsl +89 -0
  229. package/src/shaders/line.vertex.glsl.g.ts +2 -0
  230. package/src/shaders/line_gradient.fragment.glsl +34 -0
  231. package/src/shaders/line_gradient.fragment.glsl.g.ts +2 -0
  232. package/src/shaders/line_gradient.vertex.glsl +92 -0
  233. package/src/shaders/line_gradient.vertex.glsl.g.ts +2 -0
  234. package/src/shaders/line_pattern.fragment.glsl +77 -0
  235. package/src/shaders/line_pattern.fragment.glsl.g.ts +2 -0
  236. package/src/shaders/line_pattern.vertex.glsl +103 -0
  237. package/src/shaders/line_pattern.vertex.glsl.g.ts +2 -0
  238. package/src/shaders/line_sdf.fragment.glsl +45 -0
  239. package/src/shaders/line_sdf.fragment.glsl.g.ts +2 -0
  240. package/src/shaders/line_sdf.vertex.glsl +101 -0
  241. package/src/shaders/line_sdf.vertex.glsl.g.ts +2 -0
  242. package/src/shaders/raster.fragment.glsl +53 -0
  243. package/src/shaders/raster.fragment.glsl.g.ts +2 -0
  244. package/src/shaders/raster.vertex.glsl +21 -0
  245. package/src/shaders/raster.vertex.glsl.g.ts +2 -0
  246. package/src/shaders/shaders.ts +197 -0
  247. package/src/shaders/sky.fragment.glsl +17 -0
  248. package/src/shaders/sky.fragment.glsl.g.ts +2 -0
  249. package/src/shaders/sky.vertex.glsl +5 -0
  250. package/src/shaders/sky.vertex.glsl.g.ts +2 -0
  251. package/src/shaders/symbol_icon.fragment.glsl +17 -0
  252. package/src/shaders/symbol_icon.fragment.glsl.g.ts +2 -0
  253. package/src/shaders/symbol_icon.vertex.glsl +117 -0
  254. package/src/shaders/symbol_icon.vertex.glsl.g.ts +2 -0
  255. package/src/shaders/symbol_sdf.fragment.glsl +58 -0
  256. package/src/shaders/symbol_sdf.fragment.glsl.g.ts +2 -0
  257. package/src/shaders/symbol_sdf.vertex.glsl +142 -0
  258. package/src/shaders/symbol_sdf.vertex.glsl.g.ts +2 -0
  259. package/src/shaders/symbol_text_and_icon.fragment.glsl +68 -0
  260. package/src/shaders/symbol_text_and_icon.fragment.glsl.g.ts +2 -0
  261. package/src/shaders/symbol_text_and_icon.vertex.glsl +140 -0
  262. package/src/shaders/symbol_text_and_icon.vertex.glsl.g.ts +2 -0
  263. package/src/shaders/terrain.fragment.glsl +32 -0
  264. package/src/shaders/terrain.fragment.glsl.g.ts +2 -0
  265. package/src/shaders/terrain.vertex.glsl +17 -0
  266. package/src/shaders/terrain.vertex.glsl.g.ts +2 -0
  267. package/src/shaders/terrain_coords.fragment.glsl +11 -0
  268. package/src/shaders/terrain_coords.fragment.glsl.g.ts +2 -0
  269. package/src/shaders/terrain_coords.vertex.glsl +13 -0
  270. package/src/shaders/terrain_coords.vertex.glsl.g.ts +2 -0
  271. package/src/shaders/terrain_depth.fragment.glsl +15 -0
  272. package/src/shaders/terrain_depth.fragment.glsl.g.ts +2 -0
  273. package/src/shaders/terrain_depth.vertex.glsl +13 -0
  274. package/src/shaders/terrain_depth.vertex.glsl.g.ts +2 -0
  275. package/src/source/canvas_source.test.ts +210 -0
  276. package/src/source/canvas_source.ts +227 -0
  277. package/src/source/geojson_source.test.ts +492 -0
  278. package/src/source/geojson_source.ts +431 -0
  279. package/src/source/geojson_source_diff.test.ts +364 -0
  280. package/src/source/geojson_source_diff.ts +172 -0
  281. package/src/source/geojson_worker_source.test.ts +399 -0
  282. package/src/source/geojson_worker_source.ts +303 -0
  283. package/src/source/geojson_wrapper.test.ts +32 -0
  284. package/src/source/geojson_wrapper.ts +81 -0
  285. package/src/source/image_source.test.ts +235 -0
  286. package/src/source/image_source.ts +338 -0
  287. package/src/source/load_tilejson.ts +47 -0
  288. package/src/source/pixels_to_tile_units.ts +25 -0
  289. package/src/source/protocol_crud.ts +48 -0
  290. package/src/source/query_features.test.ts +31 -0
  291. package/src/source/query_features.ts +252 -0
  292. package/src/source/raster_dem_tile_source.test.ts +158 -0
  293. package/src/source/raster_dem_tile_source.ts +166 -0
  294. package/src/source/raster_dem_tile_worker_source.test.ts +36 -0
  295. package/src/source/raster_dem_tile_worker_source.ts +38 -0
  296. package/src/source/raster_tile_source.test.ts +206 -0
  297. package/src/source/raster_tile_source.ts +227 -0
  298. package/src/source/rtl_text_plugin_main_thread.test.ts +170 -0
  299. package/src/source/rtl_text_plugin_main_thread.ts +89 -0
  300. package/src/source/rtl_text_plugin_status.ts +33 -0
  301. package/src/source/rtl_text_plugin_worker.ts +49 -0
  302. package/src/source/source.test.ts +41 -0
  303. package/src/source/source.ts +186 -0
  304. package/src/source/source_cache.test.ts +2069 -0
  305. package/src/source/source_cache.ts +1102 -0
  306. package/src/source/source_state.ts +157 -0
  307. package/src/source/terrain_source_cache.test.ts +105 -0
  308. package/src/source/terrain_source_cache.ts +204 -0
  309. package/src/source/tile.test.ts +290 -0
  310. package/src/source/tile.ts +478 -0
  311. package/src/source/tile_bounds.ts +34 -0
  312. package/src/source/tile_cache.test.ts +130 -0
  313. package/src/source/tile_cache.ts +208 -0
  314. package/src/source/tile_id.test.ts +112 -0
  315. package/src/source/tile_id.ts +221 -0
  316. package/src/source/vector_tile_source.test.ts +401 -0
  317. package/src/source/vector_tile_source.ts +283 -0
  318. package/src/source/vector_tile_worker_source.test.ts +396 -0
  319. package/src/source/vector_tile_worker_source.ts +199 -0
  320. package/src/source/video_source.test.ts +124 -0
  321. package/src/source/video_source.ts +204 -0
  322. package/src/source/worker.test.ts +233 -0
  323. package/src/source/worker.ts +301 -0
  324. package/src/source/worker_source.ts +117 -0
  325. package/src/source/worker_tile.test.ts +226 -0
  326. package/src/source/worker_tile.ts +208 -0
  327. package/src/style/create_style_layer.ts +39 -0
  328. package/src/style/evaluation_parameters.ts +62 -0
  329. package/src/style/format_section_override.test.ts +62 -0
  330. package/src/style/format_section_override.ts +50 -0
  331. package/src/style/light.test.ts +86 -0
  332. package/src/style/light.ts +135 -0
  333. package/src/style/load_glyph_range.test.ts +40 -0
  334. package/src/style/load_glyph_range.ts +32 -0
  335. package/src/style/load_sprite.test.ts +227 -0
  336. package/src/style/load_sprite.ts +71 -0
  337. package/src/style/parse_glyph_pbf.ts +42 -0
  338. package/src/style/pauseable_placement.ts +138 -0
  339. package/src/style/properties.ts +726 -0
  340. package/src/style/query_utils.test.ts +107 -0
  341. package/src/style/query_utils.ts +70 -0
  342. package/src/style/sky.ts +127 -0
  343. package/src/style/style.test.ts +2654 -0
  344. package/src/style/style.ts +1814 -0
  345. package/src/style/style_glyph.ts +25 -0
  346. package/src/style/style_image.ts +188 -0
  347. package/src/style/style_layer/background_style_layer.ts +17 -0
  348. package/src/style/style_layer/background_style_layer_properties.g.ts +40 -0
  349. package/src/style/style_layer/circle_style_layer.ts +98 -0
  350. package/src/style/style_layer/circle_style_layer_properties.g.ts +76 -0
  351. package/src/style/style_layer/custom_style_layer.ts +233 -0
  352. package/src/style/style_layer/fill_extrusion_style_layer.ts +224 -0
  353. package/src/style/style_layer/fill_extrusion_style_layer_properties.g.ts +55 -0
  354. package/src/style/style_layer/fill_style_layer.test.ts +37 -0
  355. package/src/style/style_layer/fill_style_layer.ts +65 -0
  356. package/src/style/style_layer/fill_style_layer_properties.g.ts +64 -0
  357. package/src/style/style_layer/heatmap_style_layer.ts +74 -0
  358. package/src/style/style_layer/heatmap_style_layer_properties.g.ts +46 -0
  359. package/src/style/style_layer/hillshade_style_layer.ts +21 -0
  360. package/src/style/style_layer/hillshade_style_layer_properties.g.ts +49 -0
  361. package/src/style/style_layer/line_style_layer.test.ts +50 -0
  362. package/src/style/style_layer/line_style_layer.ts +131 -0
  363. package/src/style/style_layer/line_style_layer_properties.g.ts +88 -0
  364. package/src/style/style_layer/overlap_mode.test.ts +57 -0
  365. package/src/style/style_layer/overlap_mode.ts +25 -0
  366. package/src/style/style_layer/raster_style_layer.ts +17 -0
  367. package/src/style/style_layer/raster_style_layer_properties.g.ts +55 -0
  368. package/src/style/style_layer/symbol_style_layer.ts +195 -0
  369. package/src/style/style_layer/symbol_style_layer_properties.g.ts +218 -0
  370. package/src/style/style_layer/typed_style_layer.ts +9 -0
  371. package/src/style/style_layer/variable_text_anchor.test.ts +117 -0
  372. package/src/style/style_layer/variable_text_anchor.ts +163 -0
  373. package/src/style/style_layer.test.ts +372 -0
  374. package/src/style/style_layer.ts +287 -0
  375. package/src/style/style_layer_index.test.ts +99 -0
  376. package/src/style/style_layer_index.ts +78 -0
  377. package/src/style/validate_style.ts +53 -0
  378. package/src/style/zoom_history.ts +40 -0
  379. package/src/symbol/anchor.test.ts +14 -0
  380. package/src/symbol/anchor.ts +22 -0
  381. package/src/symbol/check_max_angle.test.ts +54 -0
  382. package/src/symbol/check_max_angle.ts +76 -0
  383. package/src/symbol/clip_line.test.ts +154 -0
  384. package/src/symbol/clip_line.ts +66 -0
  385. package/src/symbol/collision_feature.test.ts +98 -0
  386. package/src/symbol/collision_feature.ts +114 -0
  387. package/src/symbol/collision_index.test.ts +19 -0
  388. package/src/symbol/collision_index.ts +618 -0
  389. package/src/symbol/cross_tile_symbol_index.test.ts +260 -0
  390. package/src/symbol/cross_tile_symbol_index.ts +367 -0
  391. package/src/symbol/get_anchors.test.ts +113 -0
  392. package/src/symbol/get_anchors.ts +167 -0
  393. package/src/symbol/grid_index.test.ts +75 -0
  394. package/src/symbol/grid_index.ts +414 -0
  395. package/src/symbol/merge_lines.test.ts +30 -0
  396. package/src/symbol/merge_lines.ts +80 -0
  397. package/src/symbol/one_em.ts +3 -0
  398. package/src/symbol/opacity_state.ts +23 -0
  399. package/src/symbol/path_interpolator.test.ts +134 -0
  400. package/src/symbol/path_interpolator.ts +55 -0
  401. package/src/symbol/placement.ts +1371 -0
  402. package/src/symbol/projection.test.ts +171 -0
  403. package/src/symbol/projection.ts +833 -0
  404. package/src/symbol/quads.test.ts +157 -0
  405. package/src/symbol/quads.ts +349 -0
  406. package/src/symbol/shaping.test.ts +360 -0
  407. package/src/symbol/shaping.ts +911 -0
  408. package/src/symbol/symbol_layout.ts +739 -0
  409. package/src/symbol/symbol_size.ts +129 -0
  410. package/src/symbol/symbol_style_layer.test.ts +103 -0
  411. package/src/symbol/transform_text.ts +27 -0
  412. package/src/ui/anchor.ts +27 -0
  413. package/src/ui/camera.test.ts +2301 -0
  414. package/src/ui/camera.ts +1520 -0
  415. package/src/ui/control/attribution_control.test.ts +543 -0
  416. package/src/ui/control/attribution_control.ts +209 -0
  417. package/src/ui/control/control.ts +67 -0
  418. package/src/ui/control/fullscreen_control.test.ts +114 -0
  419. package/src/ui/control/fullscreen_control.ts +189 -0
  420. package/src/ui/control/geolocate_control.test.ts +619 -0
  421. package/src/ui/control/geolocate_control.ts +725 -0
  422. package/src/ui/control/logo_control.test.ts +88 -0
  423. package/src/ui/control/logo_control.ts +86 -0
  424. package/src/ui/control/navigation_control.test.ts +238 -0
  425. package/src/ui/control/navigation_control.ts +294 -0
  426. package/src/ui/control/scale_control.test.ts +52 -0
  427. package/src/ui/control/scale_control.ts +152 -0
  428. package/src/ui/control/terrain_control.test.ts +58 -0
  429. package/src/ui/control/terrain_control.ts +74 -0
  430. package/src/ui/default_locale.ts +25 -0
  431. package/src/ui/events.ts +758 -0
  432. package/src/ui/handler/box_zoom.test.ts +163 -0
  433. package/src/ui/handler/box_zoom.ts +171 -0
  434. package/src/ui/handler/click_zoom.ts +55 -0
  435. package/src/ui/handler/cooperative_gestures.test.ts +338 -0
  436. package/src/ui/handler/cooperative_gestures.ts +111 -0
  437. package/src/ui/handler/dblclick_zoom.test.ts +151 -0
  438. package/src/ui/handler/drag_handler.ts +174 -0
  439. package/src/ui/handler/drag_move_state_manager.ts +115 -0
  440. package/src/ui/handler/drag_pan.test.ts +487 -0
  441. package/src/ui/handler/drag_rotate.test.ts +859 -0
  442. package/src/ui/handler/handler_util.ts +10 -0
  443. package/src/ui/handler/keyboard.test.ts +235 -0
  444. package/src/ui/handler/keyboard.ts +212 -0
  445. package/src/ui/handler/map_event.test.ts +158 -0
  446. package/src/ui/handler/map_event.ts +161 -0
  447. package/src/ui/handler/mouse.ts +92 -0
  448. package/src/ui/handler/mouse_handler_interface.test.ts +111 -0
  449. package/src/ui/handler/mouse_rotate.test.ts +62 -0
  450. package/src/ui/handler/one_finger_touch_drag.ts +45 -0
  451. package/src/ui/handler/one_finger_touch_drag_handler_interface.test.ts +77 -0
  452. package/src/ui/handler/scroll_zoom.test.ts +382 -0
  453. package/src/ui/handler/scroll_zoom.ts +379 -0
  454. package/src/ui/handler/shim/dblclick_zoom.ts +64 -0
  455. package/src/ui/handler/shim/drag_pan.ts +104 -0
  456. package/src/ui/handler/shim/drag_rotate.ts +76 -0
  457. package/src/ui/handler/shim/two_fingers_touch.ts +112 -0
  458. package/src/ui/handler/tap_drag_zoom.test.ts +113 -0
  459. package/src/ui/handler/tap_drag_zoom.ts +112 -0
  460. package/src/ui/handler/tap_recognizer.ts +138 -0
  461. package/src/ui/handler/tap_zoom.ts +98 -0
  462. package/src/ui/handler/touch_pan.ts +115 -0
  463. package/src/ui/handler/transform-provider.ts +44 -0
  464. package/src/ui/handler/two_fingers_touch.test.ts +283 -0
  465. package/src/ui/handler/two_fingers_touch.ts +336 -0
  466. package/src/ui/handler_inertia.ts +157 -0
  467. package/src/ui/handler_manager.ts +637 -0
  468. package/src/ui/hash.test.ts +404 -0
  469. package/src/ui/hash.ts +153 -0
  470. package/src/ui/map.ts +3393 -0
  471. package/src/ui/map_tests/map_animation.test.ts +61 -0
  472. package/src/ui/map_tests/map_basic.test.ts +223 -0
  473. package/src/ui/map_tests/map_bounds.test.ts +123 -0
  474. package/src/ui/map_tests/map_calculate_camera_options.test.ts +113 -0
  475. package/src/ui/map_tests/map_canvas.test.ts +59 -0
  476. package/src/ui/map_tests/map_control.test.ts +61 -0
  477. package/src/ui/map_tests/map_disable_handlers.test.ts +38 -0
  478. package/src/ui/map_tests/map_events.test.ts +1001 -0
  479. package/src/ui/map_tests/map_feature_state.test.ts +421 -0
  480. package/src/ui/map_tests/map_images.test.ts +175 -0
  481. package/src/ui/map_tests/map_is_moving.test.ts +164 -0
  482. package/src/ui/map_tests/map_is_rotating.test.ts +62 -0
  483. package/src/ui/map_tests/map_is_zooming.test.ts +86 -0
  484. package/src/ui/map_tests/map_layer.test.ts +457 -0
  485. package/src/ui/map_tests/map_options.test.ts +64 -0
  486. package/src/ui/map_tests/map_pitch.test.ts +90 -0
  487. package/src/ui/map_tests/map_pixel_ratio.test.ts +75 -0
  488. package/src/ui/map_tests/map_query_rendered_features.test.ts +93 -0
  489. package/src/ui/map_tests/map_render.test.ts +90 -0
  490. package/src/ui/map_tests/map_request_render_frame.test.ts +51 -0
  491. package/src/ui/map_tests/map_resize.test.ts +120 -0
  492. package/src/ui/map_tests/map_style.test.ts +541 -0
  493. package/src/ui/map_tests/map_terrian.test.ts +104 -0
  494. package/src/ui/map_tests/map_webgl.test.ts +72 -0
  495. package/src/ui/map_tests/map_world_copies.test.ts +103 -0
  496. package/src/ui/map_tests/map_zoom.test.ts +95 -0
  497. package/src/ui/marker.test.ts +1149 -0
  498. package/src/ui/marker.ts +880 -0
  499. package/src/ui/popup.test.ts +827 -0
  500. package/src/ui/popup.ts +717 -0
  501. package/src/util/abort_error.ts +21 -0
  502. package/src/util/actor.test.ts +218 -0
  503. package/src/util/actor.ts +241 -0
  504. package/src/util/actor_messages.ts +149 -0
  505. package/src/util/ajax.test.ts +237 -0
  506. package/src/util/ajax.ts +297 -0
  507. package/src/util/browser.test.ts +23 -0
  508. package/src/util/browser.ts +63 -0
  509. package/src/util/color_ramp.test.ts +105 -0
  510. package/src/util/color_ramp.ts +56 -0
  511. package/src/util/config.ts +29 -0
  512. package/src/util/dictionary_coder.ts +23 -0
  513. package/src/util/dispatcher.test.ts +76 -0
  514. package/src/util/dispatcher.ts +78 -0
  515. package/src/util/dom.ts +135 -0
  516. package/src/util/evented.test.ts +231 -0
  517. package/src/util/evented.ts +178 -0
  518. package/src/util/find_pole_of_inaccessibility.test.ts +21 -0
  519. package/src/util/find_pole_of_inaccessibility.ts +130 -0
  520. package/src/util/geolocation_support.test.ts +43 -0
  521. package/src/util/geolocation_support.ts +23 -0
  522. package/src/util/global_worker_pool.ts +65 -0
  523. package/src/util/image.ts +150 -0
  524. package/src/util/image_request.test.ts +408 -0
  525. package/src/util/image_request.ts +246 -0
  526. package/src/util/intersection_tests.ts +206 -0
  527. package/src/util/is_char_in_unicode_block.test.ts +15 -0
  528. package/src/util/is_char_in_unicode_block.ts +345 -0
  529. package/src/util/offscreen_canvas_distorted.test.ts +13 -0
  530. package/src/util/offscreen_canvas_distorted.ts +39 -0
  531. package/src/util/offscreen_canvas_supported.ts +11 -0
  532. package/src/util/performance.ts +117 -0
  533. package/src/util/primitives.test.ts +140 -0
  534. package/src/util/primitives.ts +143 -0
  535. package/src/util/request_manager.ts +42 -0
  536. package/src/util/resolve_tokens.test.ts +45 -0
  537. package/src/util/resolve_tokens.ts +17 -0
  538. package/src/util/script_detection.test.ts +138 -0
  539. package/src/util/script_detection.ts +376 -0
  540. package/src/util/smart_wrap.test.ts +97 -0
  541. package/src/util/smart_wrap.ts +58 -0
  542. package/src/util/struct_array.test.ts +101 -0
  543. package/src/util/struct_array.ts +246 -0
  544. package/src/util/style.test.ts +34 -0
  545. package/src/util/style.ts +28 -0
  546. package/src/util/task_queue.test.ts +114 -0
  547. package/src/util/task_queue.ts +64 -0
  548. package/src/util/test/util.ts +185 -0
  549. package/src/util/throttle.test.ts +42 -0
  550. package/src/util/throttle.ts +28 -0
  551. package/src/util/throttled_invoker.ts +41 -0
  552. package/src/util/transferable_grid_index.test.ts +56 -0
  553. package/src/util/transferable_grid_index.ts +214 -0
  554. package/src/util/util.test.ts +414 -0
  555. package/src/util/util.ts +724 -0
  556. package/src/util/vectortile_to_geojson.ts +72 -0
  557. package/src/util/verticalize_punctuation.ts +110 -0
  558. package/src/util/web_worker.ts +16 -0
  559. package/src/util/web_worker_transfer.test.ts +153 -0
  560. package/src/util/web_worker_transfer.ts +254 -0
  561. package/src/util/webp_supported.ts +63 -0
  562. package/src/util/worker_pool.test.ts +43 -0
  563. package/src/util/worker_pool.ts +58 -0
  564. package/src/util/world_bounds.test.ts +59 -0
  565. package/src/util/world_bounds.ts +46 -0
@@ -0,0 +1,827 @@
1
+ import {createMap as globalCreateMap, beforeMapTest} from '../util/test/util';
2
+ import {Popup, Offset} from './popup';
3
+ import {LngLat} from '../geo/lng_lat';
4
+ import Point from '@mapbox/point-geometry';
5
+ import simulate from '../../test/unit/lib/simulate_interaction';
6
+ import {PositionAnchor} from './anchor';
7
+
8
+ const containerWidth = 512;
9
+ const containerHeight = 512;
10
+
11
+ function createMap(options?) {
12
+ options = options || {};
13
+ const container = window.document.createElement('div');
14
+ window.document.body.appendChild(container);
15
+ Object.defineProperty(container, 'clientWidth', {value: options.width || containerWidth});
16
+ Object.defineProperty(container, 'clientHeight', {value: options.height || containerHeight});
17
+ return globalCreateMap({...options, container});
18
+ }
19
+
20
+ beforeEach(() => {
21
+ beforeMapTest();
22
+ });
23
+
24
+ describe('popup', () => {
25
+
26
+ test('Popup#getElement returns a .maplibregl-popup element', () => {
27
+ const map = createMap();
28
+ const popup = new Popup()
29
+ .setText('Test')
30
+ .setLngLat([0, 0])
31
+ .addTo(map);
32
+
33
+ expect(popup.isOpen()).toBeTruthy();
34
+ expect(popup.getElement().classList.contains('maplibregl-popup')).toBeTruthy();
35
+ });
36
+
37
+ test('Popup#addTo adds a .maplibregl-popup element', () => {
38
+ const map = createMap();
39
+ const popup = new Popup()
40
+ .setText('Test')
41
+ .setLngLat([0, 0])
42
+ .addTo(map);
43
+
44
+ expect(popup.isOpen()).toBeTruthy();
45
+ expect(map.getContainer().querySelectorAll('.maplibregl-popup')).toHaveLength(1);
46
+ });
47
+
48
+ test('Popup closes on map click events by default', () => {
49
+ const map = createMap();
50
+ const popup = new Popup()
51
+ .setText('Test')
52
+ .setLngLat([0, 0])
53
+ .addTo(map);
54
+
55
+ simulate.click(map.getCanvas());
56
+
57
+ expect(!popup.isOpen()).toBeTruthy();
58
+ });
59
+
60
+ test('Popup does not close on map click events when the closeOnClick option is false', () => {
61
+ const map = createMap();
62
+ const popup = new Popup({closeOnClick: false})
63
+ .setText('Test')
64
+ .setLngLat([0, 0])
65
+ .addTo(map);
66
+
67
+ simulate.click(map.getCanvas());
68
+
69
+ expect(popup.isOpen()).toBeTruthy();
70
+ });
71
+
72
+ test('Popup closes on close button click events', () => {
73
+ const map = createMap();
74
+ const popup = new Popup()
75
+ .setText('Test')
76
+ .setLngLat([0, 0])
77
+ .addTo(map);
78
+
79
+ simulate.click(map.getContainer().querySelector('.maplibregl-popup-close-button'));
80
+
81
+ expect(!popup.isOpen()).toBeTruthy();
82
+ });
83
+
84
+ test('Popup has no close button if closeButton option is false', () => {
85
+ const map = createMap();
86
+
87
+ const popup = new Popup({closeButton: false})
88
+ .setText('Test')
89
+ .setLngLat([0, 0])
90
+ .addTo(map);
91
+
92
+ expect(
93
+ popup.getElement().querySelectorAll('.maplibregl-popup-close-button')
94
+ ).toHaveLength(0);
95
+ });
96
+
97
+ test('Popup does not close on map move events when the closeOnMove option is false', () => {
98
+ const map = createMap();
99
+ const popup = new Popup({closeOnMove: false})
100
+ .setText('Test')
101
+ .setLngLat([0, 0])
102
+ .addTo(map);
103
+
104
+ map.setCenter([-10, 0]); // longitude bounds: [-370, 350]
105
+
106
+ expect(popup.isOpen()).toBeTruthy();
107
+ });
108
+
109
+ test('Popup closes on map move events when the closeOnMove option is true', () => {
110
+ const map = createMap();
111
+ const popup = new Popup({closeOnMove: true})
112
+ .setText('Test')
113
+ .setLngLat([0, 0])
114
+ .addTo(map);
115
+
116
+ map.setCenter([-10, 0]); // longitude bounds: [-370, 350]
117
+
118
+ expect(!popup.isOpen()).toBeTruthy();
119
+ });
120
+
121
+ test('Popup fires close event when removed', () => {
122
+ const map = createMap();
123
+ const onClose = jest.fn();
124
+
125
+ new Popup()
126
+ .setText('Test')
127
+ .setLngLat([0, 0])
128
+ .on('close', onClose)
129
+ .addTo(map)
130
+ .remove();
131
+
132
+ expect(onClose).toHaveBeenCalled();
133
+ });
134
+
135
+ test('Popup does not fire close event when removed if it is not on the map', () => {
136
+ const onClose = jest.fn();
137
+
138
+ new Popup()
139
+ .setText('Test')
140
+ .setLngLat([0, 0])
141
+ .on('close', onClose)
142
+ .remove();
143
+
144
+ expect(onClose).not.toHaveBeenCalled();
145
+ });
146
+
147
+ test('Popup fires open event when added', () => {
148
+ const map = createMap();
149
+ const onOpen = jest.fn();
150
+
151
+ new Popup()
152
+ .setText('Test')
153
+ .setLngLat([0, 0])
154
+ .on('open', onOpen)
155
+ .addTo(map);
156
+
157
+ expect(onOpen).toHaveBeenCalled();
158
+ });
159
+
160
+ test('Popup content can be set via setText', () => {
161
+ const map = createMap();
162
+
163
+ const popup = new Popup({closeButton: false})
164
+ .setLngLat([0, 0])
165
+ .addTo(map)
166
+ .setText('Test');
167
+
168
+ expect(popup.getElement().textContent).toBe('Test');
169
+ });
170
+
171
+ test('Popup content can be set via setHTML', () => {
172
+ const map = createMap();
173
+
174
+ const popup = new Popup({closeButton: false})
175
+ .setLngLat([0, 0])
176
+ .addTo(map)
177
+ .setHTML('<span>Test</span>');
178
+
179
+ expect(popup.getElement().querySelector('.maplibregl-popup-content').innerHTML).toBe('<span>Test</span>');
180
+ });
181
+
182
+ test('Popup width maximum defaults to 240px', () => {
183
+ const map = createMap();
184
+
185
+ const popup = new Popup({closeButton: false})
186
+ .setLngLat([0, 0])
187
+ .addTo(map)
188
+ .setHTML('<span>Test</span>');
189
+
190
+ expect(popup.getMaxWidth()).toBe('240px');
191
+ });
192
+
193
+ test('Popup width maximum can be set via using maxWidth option', () => {
194
+ const map = createMap();
195
+
196
+ const popup = new Popup({closeButton: false, maxWidth: '5px'})
197
+ .setLngLat([0, 0])
198
+ .addTo(map)
199
+ .setHTML('<span>Test</span>');
200
+
201
+ expect(popup.getMaxWidth()).toBe('5px');
202
+ });
203
+
204
+ test('Popup width maximum can be set via maxWidth', () => {
205
+ const map = createMap();
206
+
207
+ const popup = new Popup({closeButton: false})
208
+ .setLngLat([0, 0])
209
+ .setHTML('<span>Test</span>')
210
+ .setMaxWidth('5px')
211
+ .addTo(map);
212
+
213
+ expect(popup.getMaxWidth()).toBe('5px');
214
+ });
215
+
216
+ test('Popup content can be set via setDOMContent', () => {
217
+ const map = createMap();
218
+ const content = window.document.createElement('span');
219
+
220
+ const popup = new Popup({closeButton: false})
221
+ .setLngLat([0, 0])
222
+ .addTo(map)
223
+ .setDOMContent(content);
224
+
225
+ expect(popup.getElement().querySelector('.maplibregl-popup-content').firstChild).toBe(content);
226
+ });
227
+
228
+ test('Popup#setText protects against XSS', () => {
229
+ const map = createMap();
230
+
231
+ const popup = new Popup({closeButton: false})
232
+ .setLngLat([0, 0])
233
+ .addTo(map)
234
+ .setText('<script>alert(\'XSS\')</script>');
235
+
236
+ expect(popup.getElement().textContent).toBe('<script>alert(\'XSS\')</script>');
237
+ });
238
+
239
+ test('Popup content setters overwrite previous content', () => {
240
+ const map = createMap();
241
+
242
+ const popup = new Popup({closeButton: false})
243
+ .setLngLat([0, 0])
244
+ .addTo(map);
245
+
246
+ popup.setText('Test 1');
247
+ expect(popup.getElement().textContent).toBe('Test 1');
248
+
249
+ popup.setHTML('Test 2');
250
+ expect(popup.getElement().textContent).toBe('Test 2');
251
+
252
+ popup.setDOMContent(window.document.createTextNode('Test 3'));
253
+ expect(popup.getElement().textContent).toBe('Test 3');
254
+
255
+ });
256
+
257
+ test('Popup provides LngLat accessors', () => {
258
+ expect(new Popup().getLngLat()).toBeUndefined();
259
+
260
+ expect(new Popup().setLngLat([1, 2]).getLngLat() instanceof LngLat).toBeTruthy();
261
+ expect(new Popup().setLngLat([1, 2]).getLngLat()).toEqual(new LngLat(1, 2));
262
+
263
+ expect(new Popup().setLngLat(new LngLat(1, 2)).getLngLat() instanceof LngLat).toBeTruthy();
264
+ expect(new Popup().setLngLat(new LngLat(1, 2)).getLngLat()).toEqual(new LngLat(1, 2));
265
+
266
+ });
267
+
268
+ test('Popup is positioned at the specified LngLat in a world copy', () => {
269
+ const map = createMap({width: 1024}); // longitude bounds: [-360, 360]
270
+
271
+ const popup = new Popup()
272
+ .setLngLat([270, 0])
273
+ .setText('Test')
274
+ .addTo(map);
275
+
276
+ expect(popup._pos).toEqual(map.project([270, 0]));
277
+ });
278
+
279
+ test('Popup preserves object constancy of position after map move', () => {
280
+ const map = createMap({width: 1024}); // longitude bounds: [-360, 360]
281
+
282
+ const popup = new Popup()
283
+ .setLngLat([270, 0])
284
+ .setText('Test')
285
+ .addTo(map);
286
+
287
+ map.setCenter([-10, 0]); // longitude bounds: [-370, 350]
288
+ expect(popup._pos).toEqual(map.project([270, 0]));
289
+
290
+ map.setCenter([-20, 0]); // longitude bounds: [-380, 340]
291
+ expect(popup._pos).toEqual(map.project([270, 0]));
292
+
293
+ });
294
+
295
+ test('Popup preserves object constancy of position after auto-wrapping center (left)', () => {
296
+ const map = createMap({width: 1024});
297
+ map.setCenter([-175, 0]); // longitude bounds: [-535, 185]
298
+
299
+ const popup = new Popup()
300
+ .setLngLat([0, 0])
301
+ .setText('Test')
302
+ .addTo(map);
303
+
304
+ map.setCenter([175, 0]); // longitude bounds: [-185, 535]
305
+ expect(popup._pos).toEqual(map.project([360, 0]));
306
+
307
+ });
308
+
309
+ test('Popup preserves object constancy of position after auto-wrapping center (right)', () => {
310
+ const map = createMap({width: 1024});
311
+ map.setCenter([175, 0]); // longitude bounds: [-185, 535]
312
+
313
+ const popup = new Popup()
314
+ .setLngLat([0, 0])
315
+ .setText('Test')
316
+ .addTo(map);
317
+
318
+ map.setCenter([-175, 0]); // longitude bounds: [-185, 535]
319
+ expect(popup._pos).toEqual(map.project([-360, 0]));
320
+
321
+ });
322
+
323
+ test('Popup wraps position after map move if it would otherwise go offscreen (right)', () => {
324
+ const map = createMap({width: 1024}); // longitude bounds: [-360, 360]
325
+
326
+ const popup = new Popup()
327
+ .setLngLat([-355, 0])
328
+ .setText('Test')
329
+ .addTo(map);
330
+
331
+ map.setCenter([10, 0]); // longitude bounds: [-350, 370]
332
+ expect(popup._pos).toEqual(map.project([5, 0]));
333
+ });
334
+
335
+ test('Popup wraps position after map move if it would otherwise go offscreen (right)', () => {
336
+ const map = createMap({width: 1024}); // longitude bounds: [-360, 360]
337
+
338
+ const popup = new Popup()
339
+ .setLngLat([355, 0])
340
+ .setText('Test')
341
+ .addTo(map);
342
+
343
+ map.setCenter([-10, 0]); // longitude bounds: [-370, 350]
344
+ expect(popup._pos).toEqual(map.project([-5, 0]));
345
+ });
346
+
347
+ test('Popup is repositioned at the specified LngLat', () => {
348
+ const map = createMap({width: 1024}); // longitude bounds: [-360, 360]
349
+ map.terrain = {
350
+ getElevationForLngLatZoom: () => 0
351
+ } as any;
352
+ const popup = new Popup()
353
+ .setLngLat([70, 0])
354
+ .setText('Test')
355
+ .addTo(map)
356
+ .setLngLat([0, 0]);
357
+
358
+ expect(popup._pos).toEqual(map.project([0, 0]));
359
+ });
360
+
361
+ test('Popup anchors as specified by the anchor option', () => {
362
+ const map = createMap();
363
+ const popup = new Popup({anchor: 'top-left'})
364
+ .setLngLat([0, 0])
365
+ .setText('Test')
366
+ .addTo(map);
367
+
368
+ expect(popup.getElement().classList.contains('maplibregl-popup-anchor-top-left')).toBeTruthy();
369
+ });
370
+
371
+ ([
372
+ ['top-left', new Point(10, 10), 'translate(0,0) translate(7px,7px)'],
373
+ ['top', new Point(containerWidth / 2, 10), 'translate(-50%,0) translate(0px,10px)'],
374
+ ['top-right', new Point(containerWidth - 10, 10), 'translate(-100%,0) translate(-7px,7px)'],
375
+ ['right', new Point(containerWidth - 10, containerHeight / 2), 'translate(-100%,-50%) translate(-10px,0px)'],
376
+ ['bottom-right', new Point(containerWidth - 10, containerHeight - 10), 'translate(-100%,-100%) translate(-7px,-7px)'],
377
+ ['bottom', new Point(containerWidth / 2, containerHeight - 10), 'translate(-50%,-100%) translate(0px,-10px)'],
378
+ ['bottom-left', new Point(10, containerHeight - 10), 'translate(0,-100%) translate(7px,-7px)'],
379
+ ['left', new Point(10, containerHeight / 2), 'translate(0,-50%) translate(10px,0px)'],
380
+ ['bottom', new Point(containerWidth / 2, containerHeight / 2), 'translate(-50%,-100%) translate(0px,-10px)']
381
+ ] as [PositionAnchor, Point, string][]).forEach((args) => {
382
+ const anchor = args[0];
383
+ const point = args[1];
384
+ const transform = args[2];
385
+
386
+ test(`Popup automatically anchors to ${anchor}`, () => {
387
+ const map = createMap();
388
+ const popup = new Popup()
389
+ .setLngLat([0, 0])
390
+ .setText('Test')
391
+ .addTo(map);
392
+
393
+ Object.defineProperty(popup.getElement(), 'offsetWidth', {value: 100});
394
+ Object.defineProperty(popup.getElement(), 'offsetHeight', {value: 100});
395
+
396
+ jest.spyOn(map, 'project').mockReturnValue(point);
397
+ popup.setLngLat([0, 0]);
398
+
399
+ expect(popup.getElement().classList.contains(`maplibregl-popup-anchor-${anchor}`)).toBeTruthy();
400
+ });
401
+
402
+ test(`Popup translation reflects offset and ${anchor} anchor`, () => {
403
+ const map = createMap();
404
+ jest.spyOn(map, 'project').mockReturnValue(new Point(0, 0));
405
+
406
+ const popup = new Popup({anchor, offset: 10})
407
+ .setLngLat([0, 0])
408
+ .setText('Test')
409
+ .addTo(map);
410
+
411
+ expect(popup.getElement().style.transform).toBe(transform);
412
+ });
413
+ });
414
+
415
+ test('Popup automatically anchors to top if its bottom offset would push it off-screen', () => {
416
+ const map = createMap();
417
+ const point = new Point(containerWidth / 2, containerHeight / 2);
418
+ const options = {offset: {
419
+ 'bottom': [0, -25],
420
+ 'top': [0, 0]
421
+ } as Offset};
422
+ const popup = new Popup(options)
423
+ .setLngLat([0, 0])
424
+ .setText('Test')
425
+ .addTo(map);
426
+
427
+ Object.defineProperty(popup.getElement(), 'offsetWidth', {value: containerWidth / 2});
428
+ Object.defineProperty(popup.getElement(), 'offsetHeight', {value: containerHeight / 2});
429
+
430
+ jest.spyOn(map, 'project').mockReturnValue(point);
431
+ popup.setLngLat([0, 0]);
432
+
433
+ expect(popup.getElement().classList.contains('maplibregl-popup-anchor-top')).toBeTruthy();
434
+ });
435
+
436
+ test('Popup is offset via a PointLike offset option', () => {
437
+ const map = createMap();
438
+ jest.spyOn(map, 'project').mockReturnValue(new Point(0, 0));
439
+
440
+ const popup = new Popup({anchor: 'top-left', offset: [5, 10]})
441
+ .setLngLat([0, 0])
442
+ .setText('Test')
443
+ .addTo(map);
444
+
445
+ expect(popup.getElement().style.transform).toBe('translate(0,0) translate(5px,10px)');
446
+ });
447
+
448
+ test('Popup is offset via an object offset option', () => {
449
+ const map = createMap();
450
+ jest.spyOn(map, 'project').mockReturnValue(new Point(0, 0));
451
+
452
+ const popup = new Popup({anchor: 'top-left', offset: {'top-left': [5, 10]} as Offset})
453
+ .setLngLat([0, 0])
454
+ .setText('Test')
455
+ .addTo(map);
456
+
457
+ expect(popup.getElement().style.transform).toBe('translate(0,0) translate(5px,10px)');
458
+ });
459
+
460
+ test('Popup is offset via an incomplete object offset option', () => {
461
+ const map = createMap();
462
+ jest.spyOn(map, 'project').mockReturnValue(new Point(0, 0));
463
+
464
+ const popup = new Popup({anchor: 'top-right', offset: {'top-left': [5, 10]} as Offset})
465
+ .setLngLat([0, 0])
466
+ .setText('Test')
467
+ .addTo(map);
468
+
469
+ expect(popup.getElement().style.transform).toBe('translate(-100%,0) translate(0px,0px)');
470
+ });
471
+
472
+ test('Popup offset can be set via setOffset', () => {
473
+ const map = createMap();
474
+
475
+ const popup = new Popup({offset: 5})
476
+ .setLngLat([0, 0])
477
+ .setText('Test')
478
+ .addTo(map);
479
+
480
+ expect(popup.options.offset).toBe(5);
481
+
482
+ popup.setOffset(10);
483
+
484
+ expect(popup.options.offset).toBe(10);
485
+ });
486
+
487
+ test('Popup can be removed and added again (#1477)', () => {
488
+ const map = createMap();
489
+
490
+ new Popup()
491
+ .setText('Test')
492
+ .setLngLat([0, 0])
493
+ .addTo(map)
494
+ .remove()
495
+ .addTo(map);
496
+
497
+ expect(map.getContainer().querySelectorAll('.maplibregl-popup')).toHaveLength(1);
498
+ });
499
+
500
+ test('Popup#addTo is idempotent (#1811)', () => {
501
+ const map = createMap();
502
+
503
+ const popup = new Popup({closeButton: false})
504
+ .setText('Test')
505
+ .setLngLat([0, 0])
506
+ .addTo(map)
507
+ .addTo(map);
508
+
509
+ expect(popup.getElement().querySelector('.maplibregl-popup-content').textContent).toBe('Test');
510
+ });
511
+
512
+ test('Popup#remove is idempotent (#2395)', () => {
513
+ const map = createMap();
514
+
515
+ new Popup({closeButton: false})
516
+ .setText('Test')
517
+ .setLngLat([0, 0])
518
+ .addTo(map)
519
+ .remove()
520
+ .remove();
521
+
522
+ expect(map.getContainer().querySelectorAll('.maplibregl-popup')).toHaveLength(0);
523
+ });
524
+
525
+ test('Popup adds classes from className option, methods for class manipulations works properly', () => {
526
+ const map = createMap();
527
+ const popup = new Popup({className: 'some classes'})
528
+ .setText('Test')
529
+ .setLngLat([0, 0])
530
+ .addTo(map);
531
+
532
+ const popupContainer = popup.getElement();
533
+ expect(popupContainer.classList.contains('some')).toBeTruthy();
534
+ expect(popupContainer.classList.contains('classes')).toBeTruthy();
535
+
536
+ const addClassNameMethodPopupInstance = popup.addClassName('addedClass');
537
+ expect(popupContainer.classList.contains('addedClass')).toBeTruthy();
538
+ expect(addClassNameMethodPopupInstance).toBeInstanceOf(Popup);
539
+
540
+ const removeClassNameMethodPopupInstance = popup.removeClassName('addedClass');
541
+ expect(!popupContainer.classList.contains('addedClass')).toBeTruthy();
542
+ expect(removeClassNameMethodPopupInstance).toBeInstanceOf(Popup);
543
+
544
+ popup.toggleClassName('toggle');
545
+ expect(popupContainer.classList.contains('toggle')).toBeTruthy();
546
+
547
+ popup.toggleClassName('toggle');
548
+ expect(!popupContainer.classList.contains('toggle')).toBeTruthy();
549
+
550
+ expect(() => popup.addClassName('should throw exception')).toThrow(window.DOMException);
551
+ expect(() => popup.removeClassName('should throw exception')).toThrow(window.DOMException);
552
+ expect(() => popup.toggleClassName('should throw exception')).toThrow(window.DOMException);
553
+
554
+ expect(() => popup.addClassName('')).toThrow(window.DOMException);
555
+ expect(() => popup.removeClassName('')).toThrow(window.DOMException);
556
+ expect(() => popup.toggleClassName('')).toThrow(window.DOMException);
557
+
558
+ });
559
+
560
+ test('Cursor-tracked popup disappears on mouseout', () => {
561
+ const map = createMap();
562
+
563
+ const popup = new Popup()
564
+ .setText('Test')
565
+ .trackPointer()
566
+ .addTo(map);
567
+
568
+ expect(popup._trackPointer).toBe(true);
569
+ });
570
+
571
+ test('Pointer-tracked popup is tagged with right class', () => {
572
+ const map = createMap();
573
+ const popup = new Popup()
574
+ .setText('Test')
575
+ .trackPointer()
576
+ .addTo(map);
577
+
578
+ expect(
579
+ popup._container.classList.value
580
+ ).toContain('maplibregl-popup-track-pointer');
581
+ });
582
+
583
+ test('Pointer-tracked popup with content set later is tagged with right class ', () => {
584
+ const map = createMap();
585
+ const popup = new Popup()
586
+ .trackPointer()
587
+ .addTo(map);
588
+
589
+ popup.setText('Test');
590
+
591
+ expect(
592
+ popup._container.classList.value
593
+ ).toContain('maplibregl-popup-track-pointer');
594
+ });
595
+
596
+ test('Pointer-tracked popup that is set afterwards is tagged with right class ', () => {
597
+ const map = createMap();
598
+ const popup = new Popup()
599
+ .addTo(map);
600
+
601
+ popup.setText('Test');
602
+ popup.trackPointer();
603
+
604
+ expect(
605
+ popup._container.classList.value
606
+ ).toContain('maplibregl-popup-track-pointer');
607
+ });
608
+
609
+ test('Pointer-tracked popup can be repositioned with setLngLat', () => {
610
+ const map = createMap();
611
+ const popup = new Popup()
612
+ .setText('Test')
613
+ .trackPointer()
614
+ .setLngLat([0, 0])
615
+ .addTo(map);
616
+
617
+ expect(popup._pos).toEqual(map.project([0, 0]));
618
+ expect(
619
+ popup._container.classList.value
620
+ ).not.toContain('maplibregl-popup-track-pointer');
621
+ expect(
622
+ map._canvasContainer.classList.value
623
+ ).not.toContain('maplibregl-track-pointer');
624
+ });
625
+
626
+ test('Pointer-tracked popup calling Popup#remove removes track-pointer class from map (#3434)', () => {
627
+ const map = createMap();
628
+ new Popup()
629
+ .setText('Test')
630
+ .trackPointer()
631
+ .addTo(map)
632
+ .remove();
633
+
634
+ expect(
635
+ map._canvasContainer.classList.value
636
+ ).not.toContain('maplibregl-track-pointer');
637
+ });
638
+
639
+ test('Positioned popup lacks pointer-tracking class', () => {
640
+ const map = createMap();
641
+ const popup = new Popup()
642
+ .setText('Test')
643
+ .setLngLat([0, 0])
644
+ .addTo(map);
645
+
646
+ expect(
647
+ popup._container.classList.value
648
+ ).not.toContain('maplibregl-popup-track-pointer');
649
+ });
650
+
651
+ test('Positioned popup can be set to track pointer', () => {
652
+ const map = createMap();
653
+ const popup = new Popup()
654
+ .setText('Test')
655
+ .setLngLat([0, 0])
656
+ .trackPointer()
657
+ .addTo(map);
658
+
659
+ simulate.mousemove(map.getCanvas(), {screenX: 0, screenY: 0});
660
+ expect(popup._pos).toEqual({x: 0, y: 0});
661
+ });
662
+
663
+ test('Popup closes on Map#remove', () => {
664
+ const map = createMap();
665
+ const popup = new Popup()
666
+ .setText('Test')
667
+ .setLngLat([0, 0])
668
+ .addTo(map);
669
+
670
+ map.remove();
671
+
672
+ expect(!popup.isOpen()).toBeTruthy();
673
+ });
674
+
675
+ test('Adding popup with no focusable content (Popup#setText) does not change the active element', () => {
676
+ const dummyFocusedEl = window.document.createElement('button');
677
+ window.document.body.appendChild(dummyFocusedEl);
678
+ dummyFocusedEl.focus();
679
+
680
+ new Popup({closeButton: false})
681
+ .setText('Test')
682
+ .setLngLat([0, 0])
683
+ .addTo(createMap());
684
+
685
+ expect(window.document.activeElement).toBe(dummyFocusedEl);
686
+ });
687
+
688
+ test('Adding popup with no focusable content (Popup#setHTML) does not change the active element', () => {
689
+ const dummyFocusedEl = window.document.createElement('button');
690
+ window.document.body.appendChild(dummyFocusedEl);
691
+ dummyFocusedEl.focus();
692
+
693
+ new Popup({closeButton: false})
694
+ .setHTML('<span>Test</span>')
695
+ .setLngLat([0, 0])
696
+ .addTo(createMap());
697
+
698
+ expect(window.document.activeElement).toBe(dummyFocusedEl);
699
+ });
700
+
701
+ test('Close button is focused if it is the only focusable element', () => {
702
+ const dummyFocusedEl = window.document.createElement('button');
703
+ window.document.body.appendChild(dummyFocusedEl);
704
+ dummyFocusedEl.focus();
705
+
706
+ const popup = new Popup({closeButton: true})
707
+ .setHTML('<span>Test</span>')
708
+ .setLngLat([0, 0])
709
+ .addTo(createMap({
710
+ locale: {
711
+ 'Popup.Close': 'Alt close label'
712
+ }
713
+ }));
714
+
715
+ // Suboptimal because the string matching is case-sensitive
716
+ const closeButton = popup._container.querySelector('[aria-label^=\'Alt close label\']');
717
+
718
+ expect(window.document.activeElement).toBe(closeButton);
719
+ });
720
+
721
+ test('If popup content contains a focusable element it is focused', () => {
722
+ const popup = new Popup({closeButton: true})
723
+ .setHTML('<span tabindex="0" data-testid="abc">Test</span>')
724
+ .setLngLat([0, 0])
725
+ .addTo(createMap());
726
+
727
+ const focusableEl = popup._container.querySelector('[data-testid=\'abc\']');
728
+
729
+ expect(window.document.activeElement).toBe(focusableEl);
730
+ });
731
+
732
+ test('Element with tabindex="-1" is not focused', () => {
733
+ const popup = new Popup({closeButton: true})
734
+ .setHTML('<span tabindex="-1" data-testid="abc">Test</span>')
735
+ .setLngLat([0, 0])
736
+ .addTo(createMap());
737
+
738
+ const nonFocusableEl = popup._container.querySelector('[data-testid=\'abc\']');
739
+ const closeButton = popup._container.querySelector('button[aria-label=\'Close popup\']');
740
+
741
+ expect(window.document.activeElement).not.toBe(nonFocusableEl);
742
+ expect(window.document.activeElement).toBe(closeButton);
743
+ });
744
+
745
+ test('If popup contains a disabled button and a focusable element then the latter is focused', () => {
746
+ const popup = new Popup({closeButton: true})
747
+ .setHTML(`
748
+ <button disabled>No focus here</button>
749
+ <select data-testid="abc">
750
+ <option value="1">1</option>
751
+ <option value="2">2</option>
752
+ </select>
753
+ `)
754
+ .setLngLat([0, 0])
755
+ .addTo(createMap());
756
+
757
+ const focusableEl = popup._container.querySelector('[data-testid=\'abc\']');
758
+
759
+ expect(window.document.activeElement).toBe(focusableEl);
760
+ });
761
+
762
+ test('Popup with disabled focusing does not change the active element', () => {
763
+ const dummyFocusedEl = window.document.createElement('button');
764
+ window.document.body.appendChild(dummyFocusedEl);
765
+ dummyFocusedEl.focus();
766
+
767
+ new Popup({closeButton: false, focusAfterOpen: false})
768
+ .setHTML('<span tabindex="0" data-testid="abc">Test</span>')
769
+ .setLngLat([0, 0])
770
+ .addTo(createMap());
771
+
772
+ expect(window.document.activeElement).toBe(dummyFocusedEl);
773
+ });
774
+
775
+ test('Popup is positioned on rounded whole-number pixel coordinates by default when offset is a decimal', () => {
776
+ const map = createMap();
777
+ jest.spyOn(map, 'project').mockReturnValue(new Point(0, 0));
778
+
779
+ const popup = new Popup({offset: [-0.1, 0.9]})
780
+ .setLngLat([0, 0])
781
+ .setText('foobar')
782
+ .addTo(map);
783
+
784
+ expect(popup.getElement().style.transform).toBe('translate(-50%,-100%) translate(0px,1px)');
785
+ });
786
+
787
+ test('Popup position is not rounded when subpixel positioning is enabled', () => {
788
+ const map = createMap();
789
+ jest.spyOn(map, 'project').mockReturnValue(new Point(0, 0));
790
+
791
+ const popup = new Popup({offset: [-0.1, 0.9], subpixelPositioning: true})
792
+ .setLngLat([0, 0])
793
+ .setText('foobar')
794
+ .addTo(map);
795
+
796
+ expect(popup.getElement().style.transform).toBe('translate(-50%,-100%) translate(-0.1px,0.9px)');
797
+ });
798
+
799
+ test('Popup subpixel positioning can be enabled with Popup#setSubpixelPositioning', () => {
800
+ const map = createMap();
801
+ jest.spyOn(map, 'project').mockReturnValue(new Point(0, 0));
802
+
803
+ const popup = new Popup({offset: [0, 0]})
804
+ .setLngLat([0, 0])
805
+ .setText('foobar')
806
+ .addTo(map);
807
+
808
+ popup.setSubpixelPositioning(true);
809
+ popup.setOffset([-0.1, 0.9]);
810
+
811
+ expect(popup.getElement().style.transform).toBe('translate(-50%,-100%) translate(-0.1px,0.9px)');
812
+ });
813
+ test('Popup subpixel positioning can be disabled with Popup#setSubpixelPositioning', () => {
814
+ const map = createMap();
815
+ jest.spyOn(map, 'project').mockReturnValue(new Point(0, 0));
816
+
817
+ const popup = new Popup({offset: [0, 0], subpixelPositioning: true})
818
+ .setLngLat([0, 0])
819
+ .setText('foobar')
820
+ .addTo(map);
821
+
822
+ popup.setSubpixelPositioning(false);
823
+ popup.setOffset([-0.1, 0.9]);
824
+
825
+ expect(popup.getElement().style.transform).toBe('translate(-50%,-100%) translate(0px,1px)');
826
+ });
827
+ });