@sakuzu/maplibre-gl-draw 1.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (541) hide show
  1. package/CHANGELOG.md +1109 -2
  2. package/README.ja.md +83 -50
  3. package/README.md +89 -53
  4. package/THIRD_PARTY_NOTICES.md +29 -0
  5. package/dist/api/datasets.d.ts +263 -0
  6. package/dist/api/document.d.ts +66 -0
  7. package/dist/api/draw.d.ts +137 -0
  8. package/dist/api/draw.js +20 -0
  9. package/dist/api/drawing.d.ts +87 -0
  10. package/dist/api/errors.d.ts +35 -0
  11. package/dist/api/errors.js +35 -0
  12. package/dist/api/events.d.ts +316 -0
  13. package/dist/api/extension/context.d.ts +247 -0
  14. package/dist/api/extension/feature-type.d.ts +129 -0
  15. package/dist/api/extension/mode.d.ts +123 -0
  16. package/dist/api/extension/plugin.d.ts +51 -0
  17. package/dist/api/extension/plugin.js +3 -0
  18. package/dist/api/extension/provider.d.ts +119 -0
  19. package/dist/api/extension/provider.js +3 -0
  20. package/dist/api/extension/render.d.ts +176 -0
  21. package/dist/api/extension/render.js +3 -0
  22. package/dist/api/extension/store.d.ts +190 -0
  23. package/dist/api/extension/store.js +3 -0
  24. package/dist/api/extensions.d.ts +306 -0
  25. package/dist/api/extensions.js +3 -0
  26. package/dist/api/features.d.ts +188 -0
  27. package/dist/api/features.js +3 -0
  28. package/dist/api/groups.d.ts +111 -0
  29. package/dist/api/groups.js +3 -0
  30. package/dist/api/hidden.d.ts +45 -0
  31. package/dist/api/hidden.js +3 -0
  32. package/dist/api/impl/adapters.js +463 -0
  33. package/dist/api/impl/contexts.js +466 -0
  34. package/dist/api/impl/create-draw.js +124 -0
  35. package/dist/api/impl/datasets.js +405 -0
  36. package/dist/api/impl/destroy-guard.js +74 -0
  37. package/dist/api/impl/document.js +280 -0
  38. package/dist/api/impl/drawing.js +180 -0
  39. package/dist/api/impl/engine-context.d.ts +7 -0
  40. package/dist/api/{context.js → impl/engine-context.js} +49 -38
  41. package/dist/{maplibre-gl-draw.js → api/impl/engine.js} +145 -177
  42. package/dist/api/impl/events.js +423 -0
  43. package/dist/api/impl/extension-host.js +364 -0
  44. package/dist/api/impl/extensions.js +229 -0
  45. package/dist/api/impl/features.js +445 -0
  46. package/dist/api/impl/geometry/apply.d.ts +32 -0
  47. package/dist/api/{geometry → impl/geometry}/apply.js +10 -27
  48. package/dist/api/{geometry → impl/geometry}/buffer.d.ts +4 -3
  49. package/dist/api/{geometry → impl/geometry}/buffer.js +12 -23
  50. package/dist/api/{geometry → impl/geometry}/split.d.ts +4 -3
  51. package/dist/api/{geometry → impl/geometry}/split.js +10 -21
  52. package/dist/api/{geometry → impl/geometry}/targets.d.ts +2 -20
  53. package/dist/api/{geometry → impl/geometry}/targets.js +8 -35
  54. package/dist/api/impl/geometry/types.js +3 -0
  55. package/dist/api/impl/groups.d.ts +3 -0
  56. package/dist/api/impl/groups.js +268 -0
  57. package/dist/api/impl/hidden.js +60 -0
  58. package/dist/api/impl/import-export/constants.d.ts +22 -0
  59. package/dist/api/impl/import-export/constants.js +24 -0
  60. package/dist/api/{import-export → impl/import-export}/embedded-file.js +2 -2
  61. package/dist/api/{import-export → impl/import-export}/format-detection.d.ts +1 -1
  62. package/dist/api/{import-export → impl/import-export}/format-detection.js +2 -1
  63. package/dist/api/impl/import-export/geojson-export.d.ts +19 -0
  64. package/dist/api/{import-export → impl/import-export}/geojson-export.js +71 -104
  65. package/dist/api/{import-export → impl/import-export}/geojson-import.d.ts +11 -7
  66. package/dist/api/{import-export → impl/import-export}/geojson-import.js +139 -97
  67. package/dist/api/{import-export → impl/import-export}/geometry-validation.d.ts +14 -0
  68. package/dist/api/{import-export → impl/import-export}/geometry-validation.js +45 -0
  69. package/dist/api/impl/import-export/image-import.d.ts +16 -0
  70. package/dist/api/impl/import-export/image-import.js +73 -0
  71. package/dist/api/impl/import-export/legacy-image-style.d.ts +16 -0
  72. package/dist/api/impl/import-export/legacy-image-style.js +49 -0
  73. package/dist/api/impl/import-export/native-format.d.ts +14 -0
  74. package/dist/api/{import-export → impl/import-export}/native-format.js +32 -22
  75. package/dist/api/impl/import-export/native-upgrade.d.ts +8 -0
  76. package/dist/api/impl/import-export/native-upgrade.js +139 -0
  77. package/dist/api/{import-export → impl/import-export}/native-validation.d.ts +1 -1
  78. package/dist/api/{import-export → impl/import-export}/native-validation.js +15 -14
  79. package/dist/api/impl/import-export/style-validation.d.ts +24 -0
  80. package/dist/api/impl/import-export/style-validation.js +86 -0
  81. package/dist/api/impl/import-export/types.d.ts +52 -0
  82. package/dist/api/impl/import-export/types.js +3 -0
  83. package/dist/api/impl/input.js +180 -0
  84. package/dist/api/impl/layers.js +307 -0
  85. package/dist/api/impl/metadata.d.ts +1 -0
  86. package/dist/api/impl/metadata.js +22 -0
  87. package/dist/api/impl/options.d.ts +1 -0
  88. package/dist/api/impl/options.js +851 -0
  89. package/dist/api/impl/placement.d.ts +1 -0
  90. package/dist/api/impl/placement.js +138 -0
  91. package/dist/api/impl/render-context.d.ts +13 -0
  92. package/dist/api/impl/render-context.js +272 -0
  93. package/dist/api/impl/rows.d.ts +1 -0
  94. package/dist/api/impl/rows.js +46 -0
  95. package/dist/api/impl/selection.d.ts +1 -0
  96. package/dist/api/impl/selection.js +186 -0
  97. package/dist/api/impl/shared.d.ts +64 -0
  98. package/dist/api/impl/shared.js +178 -0
  99. package/dist/api/impl/validate-extension.d.ts +1 -0
  100. package/dist/api/impl/validate-extension.js +159 -0
  101. package/dist/api/layers.d.ts +130 -0
  102. package/dist/api/layers.js +3 -0
  103. package/dist/api/metadata.d.ts +18 -0
  104. package/dist/api/metadata.js +3 -0
  105. package/dist/api/model.d.ts +487 -0
  106. package/dist/api/model.js +47 -0
  107. package/dist/api/options.d.ts +466 -0
  108. package/dist/api/options.js +3 -0
  109. package/dist/api/selection.d.ts +94 -0
  110. package/dist/api/selection.js +3 -0
  111. package/dist/api/state.d.ts +155 -0
  112. package/dist/api/state.js +12 -0
  113. package/dist/{display → dataset}/chunk.d.ts +1 -1
  114. package/dist/{display → dataset}/chunk.js +4 -3
  115. package/dist/{display → dataset}/dataset.js +21 -21
  116. package/dist/dataset/interaction.d.ts +1 -0
  117. package/dist/{display → dataset}/interaction.js +18 -6
  118. package/dist/dataset/manager.d.ts +1 -0
  119. package/dist/dataset/provider.d.ts +1 -0
  120. package/dist/{display → dataset}/retained.d.ts +1 -1
  121. package/dist/{display → dataset}/retained.js +8 -7
  122. package/dist/dataset/source.d.ts +1 -0
  123. package/dist/{display → dataset}/source.js +17 -4
  124. package/dist/dataset/spatial.d.ts +1 -0
  125. package/dist/{display → dataset}/spatial.js +1 -1
  126. package/dist/dataset/style.d.ts +1 -0
  127. package/dist/{display → dataset}/style.js +1 -1
  128. package/dist/dataset/table-source.d.ts +1 -0
  129. package/dist/{display/columnar/source.js → dataset/table-source.js} +53 -25
  130. package/dist/{display → dataset}/thinning.d.ts +0 -10
  131. package/dist/{display → dataset}/thinning.js +3 -2
  132. package/dist/dataset/triangulation.d.ts +1 -0
  133. package/dist/{display → dataset}/triangulation.js +0 -0
  134. package/dist/{display → dataset}/types.d.ts +84 -121
  135. package/dist/dataset/types.js +61 -0
  136. package/dist/dispatcher/hit-test/box-strategies.js +13 -13
  137. package/dist/dispatcher/hit-test/box-strategy.d.ts +2 -15
  138. package/dist/dispatcher/hit-test/globe-shape.js +5 -4
  139. package/dist/dispatcher/hit-test/service.d.ts +17 -0
  140. package/dist/dispatcher/hit-test/service.js +80 -16
  141. package/dist/dispatcher/hit-test/strategies/base.d.ts +13 -19
  142. package/dist/dispatcher/hit-test/strategies/circle.js +3 -2
  143. package/dist/dispatcher/hit-test/strategies/image.js +6 -18
  144. package/dist/dispatcher/hit-test/strategies/line.d.ts +0 -6
  145. package/dist/dispatcher/hit-test/strategies/line.js +9 -2
  146. package/dist/dispatcher/hit-test/strategies/multi.d.ts +0 -8
  147. package/dist/dispatcher/hit-test/strategies/multi.js +17 -8
  148. package/dist/dispatcher/hit-test/strategies/point.d.ts +9 -7
  149. package/dist/dispatcher/hit-test/strategies/point.js +8 -4
  150. package/dist/dispatcher/hit-test/strategies/polygon.d.ts +0 -7
  151. package/dist/dispatcher/hit-test/strategies/polygon.js +11 -3
  152. package/dist/dispatcher/hit-test/topmost.d.ts +1 -1
  153. package/dist/dispatcher/input-router.js +154 -70
  154. package/dist/dispatcher/normalizer.js +25 -4
  155. package/dist/dispatcher/types.d.ts +6 -1
  156. package/dist/extension/feature-handler.d.ts +1 -182
  157. package/dist/extension/index.d.ts +4 -7
  158. package/dist/extension/renderers.d.ts +1 -208
  159. package/dist/geometry/angle.d.ts +0 -8
  160. package/dist/geometry/angle.js +0 -8
  161. package/dist/geometry/bbox.d.ts +4 -12
  162. package/dist/geometry/bbox.js +4 -12
  163. package/dist/geometry/boolean.d.ts +0 -51
  164. package/dist/geometry/boolean.js +0 -51
  165. package/dist/geometry/buffer.d.ts +0 -26
  166. package/dist/geometry/buffer.js +0 -26
  167. package/dist/geometry/circle.d.ts +0 -9
  168. package/dist/geometry/circle.js +0 -9
  169. package/dist/geometry/coords.d.ts +0 -16
  170. package/dist/geometry/coords.js +0 -16
  171. package/dist/geometry/distance.d.ts +0 -24
  172. package/dist/geometry/distance.js +0 -24
  173. package/dist/geometry/errors.d.ts +21 -36
  174. package/dist/geometry/errors.js +49 -29
  175. package/dist/geometry/geojson.d.ts +85 -0
  176. package/dist/geometry/geojson.js +173 -0
  177. package/dist/geometry/index.d.ts +38 -23
  178. package/dist/geometry/index.js +43 -31
  179. package/dist/geometry/measure.d.ts +0 -27
  180. package/dist/geometry/measure.js +0 -27
  181. package/dist/geometry/predicates.d.ts +0 -9
  182. package/dist/geometry/predicates.js +0 -9
  183. package/dist/geometry/public-bounds.d.ts +26 -0
  184. package/dist/geometry/public-bounds.js +30 -0
  185. package/dist/geometry/public-combine.d.ts +78 -0
  186. package/dist/geometry/public-combine.js +82 -0
  187. package/dist/geometry/public-create.d.ts +54 -0
  188. package/dist/geometry/public-create.js +70 -0
  189. package/dist/geometry/public-measure.d.ts +170 -0
  190. package/dist/geometry/public-measure.js +283 -0
  191. package/dist/geometry/public-predicates.d.ts +54 -0
  192. package/dist/geometry/public-predicates.js +144 -0
  193. package/dist/geometry/public-repair.d.ts +75 -0
  194. package/dist/geometry/public-repair.js +77 -0
  195. package/dist/geometry/simplify.d.ts +0 -7
  196. package/dist/geometry/simplify.js +0 -7
  197. package/dist/geometry/split.d.ts +0 -20
  198. package/dist/geometry/split.js +0 -20
  199. package/dist/geometry/units.d.ts +20 -12
  200. package/dist/geometry/units.js +20 -12
  201. package/dist/index.d.ts +66 -66
  202. package/dist/index.js +6 -18
  203. package/dist/messages.d.ts +7 -7
  204. package/dist/modes/draw/circle.js +83 -207
  205. package/dist/modes/draw/commit-layer.d.ts +5 -16
  206. package/dist/modes/draw/commit-layer.js +2 -13
  207. package/dist/modes/draw/freehand.js +108 -246
  208. package/dist/modes/draw/image.js +4 -2
  209. package/dist/modes/draw/index.d.ts +5 -5
  210. package/dist/modes/draw/index.js +5 -5
  211. package/dist/modes/draw/line.js +18 -354
  212. package/dist/modes/draw/point.js +29 -78
  213. package/dist/modes/draw/polygon.js +23 -368
  214. package/dist/modes/draw/trace-support.d.ts +43 -36
  215. package/dist/modes/draw/trace-support.js +95 -98
  216. package/dist/modes/draw/vertex-drawing.d.ts +1 -0
  217. package/dist/modes/draw/vertex-drawing.js +176 -0
  218. package/dist/modes/handler.d.ts +1 -285
  219. package/dist/modes/manager.d.ts +2 -2
  220. package/dist/modes/manager.js +3 -0
  221. package/dist/modes/select/box-selection.d.ts +3 -3
  222. package/dist/modes/select/box-selection.js +2 -1
  223. package/dist/modes/select/click-handler.d.ts +5 -5
  224. package/dist/modes/select/click-handler.js +22 -20
  225. package/dist/modes/select/cursor-handler.d.ts +2 -2
  226. package/dist/modes/select/drag/intermediate-writes.js +1 -1
  227. package/dist/modes/select/drag/move.js +3 -3
  228. package/dist/modes/select/drag/operation.d.ts +3 -3
  229. package/dist/modes/select/drag/radius.js +5 -4
  230. package/dist/modes/select/drag/transform.d.ts +2 -2
  231. package/dist/modes/select/drag/transform.js +11 -5
  232. package/dist/modes/select/drag/vertex.d.ts +2 -2
  233. package/dist/modes/select/drag/vertex.js +13 -8
  234. package/dist/modes/select/drag-handler.js +44 -25
  235. package/dist/modes/select/mode.js +17 -17
  236. package/dist/modes/select/shortcut-handler.d.ts +8 -8
  237. package/dist/modes/select/shortcut-handler.js +9 -7
  238. package/dist/operations/layer-operations.js +29 -168
  239. package/dist/operations/resize.d.ts +2 -2
  240. package/dist/operations/resize.js +5 -5
  241. package/dist/operations/rotate.js +5 -5
  242. package/dist/operations/selection-operations.d.ts +16 -1
  243. package/dist/operations/selection-operations.js +28 -13
  244. package/dist/operations/shared-vertex.js +4 -2
  245. package/dist/operations/trace-graph.d.ts +0 -18
  246. package/dist/operations/trace-graph.js +0 -18
  247. package/dist/operations/vertex.js +36 -35
  248. package/dist/shared/color.d.ts +1 -0
  249. package/dist/shared/color.js +245 -0
  250. package/dist/shared/config/constants.d.ts +1 -54
  251. package/dist/shared/config/constants.js +1 -58
  252. package/dist/shared/config/feature-style.d.ts +16 -13
  253. package/dist/shared/config/feature-style.js +9 -0
  254. package/dist/shared/config/rendering.d.ts +3 -3
  255. package/dist/shared/config/selection-highlight.d.ts +0 -15
  256. package/dist/shared/config/selection-highlight.js +4 -7
  257. package/dist/shared/config/selection.d.ts +2 -32
  258. package/dist/shared/config/selection.js +0 -18
  259. package/dist/shared/config/topology.d.ts +2 -2
  260. package/dist/shared/config/trace.d.ts +4 -4
  261. package/dist/shared/math/angle.d.ts +1 -1
  262. package/dist/shared/math/angle.js +1 -1
  263. package/dist/shared/math/circle.d.ts +1 -1
  264. package/dist/shared/math/circle.js +1 -1
  265. package/dist/shared/math/distance.d.ts +2 -1
  266. package/dist/shared/math/distance.js +3 -2
  267. package/dist/shared/math/index.d.ts +1 -1
  268. package/dist/shared/math/index.js +1 -1
  269. package/dist/shared/math/transform.d.ts +23 -0
  270. package/dist/shared/math/transform.js +47 -28
  271. package/dist/shared/properties.d.ts +18 -0
  272. package/dist/shared/properties.js +129 -0
  273. package/dist/shared/types/events.d.ts +15 -7
  274. package/dist/shared/types/model.d.ts +109 -159
  275. package/dist/shared/types/style.d.ts +1 -1
  276. package/dist/shared/utils/color.d.ts +2 -36
  277. package/dist/shared/utils/color.js +13 -70
  278. package/dist/shared/utils/coordinates.d.ts +30 -4
  279. package/dist/shared/utils/coordinates.js +56 -10
  280. package/dist/shared/utils/event-emitter.d.ts +1 -262
  281. package/dist/shared/utils/event-emitter.js +4 -3
  282. package/dist/shared/utils/feature-bbox.js +8 -7
  283. package/dist/shared/utils/feature-segments.js +5 -4
  284. package/dist/shared/utils/image.d.ts +0 -4
  285. package/dist/shared/utils/image.js +0 -6
  286. package/dist/shared/utils/name-generator.d.ts +14 -20
  287. package/dist/shared/utils/name-generator.js +20 -3
  288. package/dist/shared/utils/pixel-ratio.d.ts +9 -3
  289. package/dist/shared/utils/pixel-ratio.js +13 -4
  290. package/dist/shared/utils/property.d.ts +7 -50
  291. package/dist/shared/utils/property.js +22 -87
  292. package/dist/snapping/custom-targets.js +21 -4
  293. package/dist/snapping/indicator.js +20 -11
  294. package/dist/snapping/providers/display.d.ts +6 -1
  295. package/dist/snapping/providers/display.js +2 -1
  296. package/dist/snapping/providers/guide.d.ts +3 -43
  297. package/dist/snapping/providers/guide.js +1 -44
  298. package/dist/snapping/providers/intersection.js +1 -1
  299. package/dist/snapping/providers/store.js +3 -3
  300. package/dist/snapping/service.js +18 -7
  301. package/dist/snapping/types.d.ts +9 -35
  302. package/dist/store/draw-store.js +233 -142
  303. package/dist/store/local-visibility.d.ts +11 -6
  304. package/dist/store/local-visibility.js +38 -7
  305. package/dist/store/lock.d.ts +0 -6
  306. package/dist/store/lock.js +0 -6
  307. package/dist/store/memory/change-bus.d.ts +3 -3
  308. package/dist/store/memory/change-bus.js +12 -0
  309. package/dist/store/memory/file-store.d.ts +2 -2
  310. package/dist/store/memory/ui-state.d.ts +1 -51
  311. package/dist/store/memory/ui-state.js +122 -134
  312. package/dist/store/memory.d.ts +1 -8
  313. package/dist/store/memory.js +249 -45
  314. package/dist/store/ordering.d.ts +9 -0
  315. package/dist/store/ordering.js +17 -0
  316. package/dist/store/spatial/spatial-index.d.ts +1 -1
  317. package/dist/store/spatial/spatial-index.js +1 -1
  318. package/dist/store/spatial/store-spatial-index.d.ts +3 -1
  319. package/dist/store/spatial/store-spatial-index.js +9 -3
  320. package/dist/store/store.d.ts +66 -107
  321. package/dist/store/types.d.ts +1 -1
  322. package/dist/store/writable-layer.d.ts +1 -1
  323. package/dist/store/writable-layer.js +2 -2
  324. package/dist/table/builder.d.ts +83 -0
  325. package/dist/table/builder.js +381 -0
  326. package/dist/table/index.d.ts +37 -0
  327. package/dist/table/index.js +5 -0
  328. package/dist/table/packed-rtree.d.ts +1 -0
  329. package/dist/{display → table}/packed-rtree.js +1 -1
  330. package/dist/table/partition.d.ts +1 -0
  331. package/dist/{display → table}/partition.js +3 -3
  332. package/dist/table/prepare.d.ts +44 -0
  333. package/dist/table/prepare.js +136 -0
  334. package/dist/table/table.d.ts +1 -0
  335. package/dist/{display/columnar → table}/table.js +29 -25
  336. package/dist/{display/columnar → table}/types.d.ts +68 -72
  337. package/dist/table/types.js +3 -0
  338. package/dist/view/coordinator.js +4 -3
  339. package/dist/view/feature-companion.d.ts +13 -7
  340. package/dist/view/feature-companion.js +11 -3
  341. package/dist/view/globe-subdivision.js +3 -3
  342. package/dist/view/layer/attach.d.ts +12 -6
  343. package/dist/view/layer/attach.js +86 -10
  344. package/dist/view/layer/custom-layer.js +40 -11
  345. package/dist/view/layer/display-list.js +2 -1
  346. package/dist/view/layer/drape-planner.d.ts +2 -2
  347. package/dist/view/layer/frame-render.d.ts +3 -3
  348. package/dist/view/layer/frame-render.js +7 -2
  349. package/dist/view/layer/frame-state.d.ts +6 -6
  350. package/dist/view/layer/index.d.ts +2 -2
  351. package/dist/view/layer/index.js +1 -1
  352. package/dist/view/layer/render.d.ts +4 -4
  353. package/dist/view/layer/render.js +3 -8
  354. package/dist/view/layer/renderers.d.ts +2 -2
  355. package/dist/view/layer/renderers.js +1 -1
  356. package/dist/view/layer/slot-manager.d.ts +2 -2
  357. package/dist/view/layer/slot-manager.js +4 -4
  358. package/dist/view/layer/slots.d.ts +2 -2
  359. package/dist/view/layer/slots.js +1 -1
  360. package/dist/view/layer/store-retained-bbox.js +3 -2
  361. package/dist/view/layer/store-retained-classify.d.ts +5 -7
  362. package/dist/view/layer/store-retained-classify.js +19 -7
  363. package/dist/view/layer/store-retained-collect.js +8 -7
  364. package/dist/view/layer/store-retained-coord-patch.d.ts +0 -8
  365. package/dist/view/layer/store-retained-coord-patch.js +13 -4
  366. package/dist/view/layer/store-retained-immediate.d.ts +3 -3
  367. package/dist/view/layer/store-retained-immediate.js +3 -8
  368. package/dist/view/layer/store-retained-invalidation.d.ts +2 -2
  369. package/dist/view/layer/store-retained.d.ts +2 -2
  370. package/dist/view/layer/store-retained.js +1 -1
  371. package/dist/view/renderers/batch-manager.js +8 -7
  372. package/dist/view/renderers/drawer.js +21 -15
  373. package/dist/view/renderers/image.js +13 -39
  374. package/dist/view/renderers/line/line-types.d.ts +3 -3
  375. package/dist/view/renderers/line/sdf-line.js +3 -1
  376. package/dist/view/renderers/point/billboard-depth.js +1 -1
  377. package/dist/view/renderers/point/point-instance.js +1 -1
  378. package/dist/view/renderers/point/point-shape.js +2 -2
  379. package/dist/view/renderers/point/point-style.js +48 -4
  380. package/dist/view/renderers/polygon/batch.js +1 -2
  381. package/dist/view/renderers/polygon/fill.js +3 -1
  382. package/dist/view/renderers/polygon/sdf-polygon.js +2 -3
  383. package/dist/view/renderers/polygon/triangulator.d.ts +1 -1
  384. package/dist/view/renderers/stroke.js +3 -1
  385. package/dist/view/shaders/helpers.d.ts +2 -42
  386. package/dist/view/shaders/helpers.js +0 -6
  387. package/dist/view/shaders/projection.d.ts +15 -7
  388. package/dist/view/shaders/projection.js +23 -6
  389. package/dist/view/shaders/quad.d.ts +16 -12
  390. package/dist/view/shaders/quad.js +34 -13
  391. package/dist/view/style-rule.d.ts +5 -42
  392. package/dist/view/style-rule.js +20 -44
  393. package/dist/view/terrain/binding.d.ts +1 -0
  394. package/dist/view/terrain/binding.js +29 -0
  395. package/dist/view/terrain/context.d.ts +3 -4
  396. package/dist/view/terrain/context.js +4 -5
  397. package/dist/view/terrain/drape/geometry.js +1 -1
  398. package/dist/view/terrain/drape/pass.d.ts +1 -1
  399. package/dist/view/terrain/drape/pass.js +8 -7
  400. package/dist/view/terrain/polygon.d.ts +9 -5
  401. package/dist/view/terrain/polygon.js +16 -2
  402. package/dist/view/terrain/state.d.ts +1 -1
  403. package/dist/view/terrain/state.js +1 -1
  404. package/dist/view/terrain/tessellation.d.ts +2 -2
  405. package/dist/view/terrain/tessellation.js +1 -1
  406. package/dist/view/ui/auxiliary-handles.d.ts +6 -29
  407. package/dist/view/ui/bounds.js +8 -12
  408. package/dist/view/ui/handle-test.js +2 -2
  409. package/dist/view/ui/handle-thinning.js +17 -17
  410. package/dist/view/ui/handles.js +21 -13
  411. package/dist/view/ui/helper.d.ts +1 -1
  412. package/dist/view/ui/helper.js +1 -1
  413. package/dist/view/ui/index.d.ts +1 -1
  414. package/dist/view/ui/selection-scope.js +4 -2
  415. package/dist/view/ui/selection-ui/bounding-box.js +6 -6
  416. package/dist/view/ui/selection-ui/extension-registry.d.ts +31 -20
  417. package/dist/view/ui/selection-ui/extension-registry.js +70 -7
  418. package/dist/view/ui/selection-ui/index.d.ts +2 -2
  419. package/dist/view/ui/selection-ui/index.js +1 -1
  420. package/dist/view/ui/selection-ui/renderer.js +15 -38
  421. package/dist/view/ui/selection-ui/types.d.ts +17 -2
  422. package/dist/view/ui/selection-ui-drawer.d.ts +8 -0
  423. package/dist/view/ui/selection-ui-drawer.js +63 -2
  424. package/dist/view/ui/tentative.js +1 -1
  425. package/dist/webgl/index.d.ts +65 -0
  426. package/dist/webgl/index.js +62 -0
  427. package/package.json +38 -15
  428. package/dist/api/api.d.ts +0 -1259
  429. package/dist/api/api.js +0 -86
  430. package/dist/api/context.d.ts +0 -173
  431. package/dist/api/display-api.js +0 -23
  432. package/dist/api/event-api.d.ts +0 -13
  433. package/dist/api/event-api.js +0 -17
  434. package/dist/api/extension-api.d.ts +0 -46
  435. package/dist/api/extension-api.js +0 -85
  436. package/dist/api/feature-api.d.ts +0 -11
  437. package/dist/api/feature-api.js +0 -101
  438. package/dist/api/geometry/apply.d.ts +0 -51
  439. package/dist/api/geometry/boolean.d.ts +0 -28
  440. package/dist/api/geometry/boolean.js +0 -65
  441. package/dist/api/geometry/types.d.ts +0 -31
  442. package/dist/api/geometry-operations.d.ts +0 -162
  443. package/dist/api/geometry-operations.js +0 -94
  444. package/dist/api/group-api.d.ts +0 -10
  445. package/dist/api/group-api.js +0 -78
  446. package/dist/api/import-export/constants.d.ts +0 -29
  447. package/dist/api/import-export/constants.js +0 -40
  448. package/dist/api/import-export/file-name.d.ts +0 -10
  449. package/dist/api/import-export/file-name.js +0 -20
  450. package/dist/api/import-export/geojson-export.d.ts +0 -19
  451. package/dist/api/import-export/image-import.d.ts +0 -12
  452. package/dist/api/import-export/image-import.js +0 -53
  453. package/dist/api/import-export/index.d.ts +0 -9
  454. package/dist/api/import-export/index.js +0 -107
  455. package/dist/api/import-export/native-format.d.ts +0 -15
  456. package/dist/api/import-export/style-validation.d.ts +0 -27
  457. package/dist/api/import-export/style-validation.js +0 -49
  458. package/dist/api/import-export/types.d.ts +0 -26
  459. package/dist/api/index.d.ts +0 -15
  460. package/dist/api/index.js +0 -3
  461. package/dist/api/input-api.d.ts +0 -158
  462. package/dist/api/input-api.js +0 -144
  463. package/dist/api/instance-api.d.ts +0 -38
  464. package/dist/api/instance-api.js +0 -136
  465. package/dist/api/layer-api.d.ts +0 -12
  466. package/dist/api/layer-api.js +0 -62
  467. package/dist/api/selection-api.d.ts +0 -7
  468. package/dist/api/selection-api.js +0 -78
  469. package/dist/api/snapping-api.d.ts +0 -125
  470. package/dist/api/snapping-api.js +0 -50
  471. package/dist/api/topology-api.d.ts +0 -30
  472. package/dist/api/topology-api.js +0 -16
  473. package/dist/api/tracing-api.d.ts +0 -31
  474. package/dist/api/tracing-api.js +0 -16
  475. package/dist/dispatcher/hit-test/index.d.ts +0 -14
  476. package/dist/dispatcher/hit-test/index.js +0 -9
  477. package/dist/dispatcher/index.d.ts +0 -15
  478. package/dist/dispatcher/index.js +0 -3
  479. package/dist/display/columnar/index.d.ts +0 -12
  480. package/dist/display/columnar/index.js +0 -13
  481. package/dist/display/columnar/prepare.d.ts +0 -42
  482. package/dist/display/columnar/prepare.js +0 -116
  483. package/dist/display/index.d.ts +0 -13
  484. package/dist/display/types.js +0 -43
  485. package/dist/maplibre-gl-draw.d.ts +0 -47
  486. package/dist/modes/cursor.js +0 -72
  487. package/dist/modes/index.d.ts +0 -7
  488. package/dist/operations/index.d.ts +0 -9
  489. package/dist/operations/index.js +0 -3
  490. package/dist/plugins/index.d.ts +0 -10
  491. package/dist/plugins/mutation-hooks.d.ts +0 -28
  492. package/dist/plugins/mutation-hooks.js +0 -84
  493. package/dist/plugins/plugin-context.js +0 -367
  494. package/dist/plugins/plugin-manager.d.ts +0 -103
  495. package/dist/plugins/plugin-manager.js +0 -316
  496. package/dist/plugins/plugin.d.ts +0 -529
  497. package/dist/shared/config/index.d.ts +0 -17
  498. package/dist/shared/config/index.js +0 -8
  499. package/dist/shared/utils/index.d.ts +0 -15
  500. package/dist/shared/utils/index.js +0 -24
  501. package/dist/snapping/index.d.ts +0 -14
  502. package/dist/snapping/index.js +0 -4
  503. package/dist/store/change-merger.js +0 -102
  504. package/dist/store/event-bridge.js +0 -161
  505. package/dist/store/index.d.ts +0 -12
  506. package/dist/store/index.js +0 -4
  507. package/dist/view/index.d.ts +0 -47
  508. package/dist/view/index.js +0 -20
  509. /package/dist/api/{geometry/types.js → datasets.js} +0 -0
  510. /package/dist/api/{import-export/types.js → document.js} +0 -0
  511. /package/dist/{display/columnar/types.js → api/drawing.js} +0 -0
  512. /package/dist/{display/index.js → api/events.js} +0 -0
  513. /package/dist/{modes/index.js → api/extension/context.js} +0 -0
  514. /package/dist/{plugins/index.js → api/extension/feature-type.js} +0 -0
  515. /package/dist/{plugins/plugin.js → api/extension/mode.js} +0 -0
  516. /package/dist/api/{display-api.d.ts → impl/adapters.d.ts} +0 -0
  517. /package/dist/{display/columnar/source.d.ts → api/impl/contexts.d.ts} +0 -0
  518. /package/dist/{display/columnar/table.d.ts → api/impl/create-draw.d.ts} +0 -0
  519. /package/dist/{display/interaction.d.ts → api/impl/datasets.d.ts} +0 -0
  520. /package/dist/{display/manager.d.ts → api/impl/destroy-guard.d.ts} +0 -0
  521. /package/dist/{display/packed-rtree.d.ts → api/impl/document.d.ts} +0 -0
  522. /package/dist/{display/partition.d.ts → api/impl/drawing.d.ts} +0 -0
  523. /package/dist/{display/provider.d.ts → api/impl/engine.d.ts} +0 -0
  524. /package/dist/{display/source.d.ts → api/impl/events.d.ts} +0 -0
  525. /package/dist/{display/spatial.d.ts → api/impl/extension-host.d.ts} +0 -0
  526. /package/dist/{display/style.d.ts → api/impl/extensions.d.ts} +0 -0
  527. /package/dist/{display/triangulation.d.ts → api/impl/features.d.ts} +0 -0
  528. /package/dist/{modes/cursor.d.ts → api/impl/geometry/types.d.ts} +0 -0
  529. /package/dist/{plugins/plugin-context.d.ts → api/impl/hidden.d.ts} +0 -0
  530. /package/dist/api/{import-export → impl/import-export}/embedded-file.d.ts +0 -0
  531. /package/dist/api/{import-export → impl/import-export}/own-property.d.ts +0 -0
  532. /package/dist/api/{import-export → impl/import-export}/own-property.js +0 -0
  533. /package/dist/{store/change-merger.d.ts → api/impl/input.d.ts} +0 -0
  534. /package/dist/{store/event-bridge.d.ts → api/impl/layers.d.ts} +0 -0
  535. /package/dist/{display → dataset}/chunk-set.d.ts +0 -0
  536. /package/dist/{display → dataset}/chunk-set.js +0 -0
  537. /package/dist/{display → dataset}/dataset.d.ts +0 -0
  538. /package/dist/{display → dataset}/manager.js +0 -0
  539. /package/dist/{display → dataset}/provider.js +0 -0
  540. /package/dist/{display → dataset}/selection.d.ts +0 -0
  541. /package/dist/{display → dataset}/selection.js +0 -0
@@ -4,17 +4,19 @@
4
4
  * Hit testing strategy for Point features.
5
5
  * Distances are measured in the local frame of hit testing (local-frame.ts).
6
6
  */
7
- import type { Coordinate, Feature, FeatureType } from '../../../store/types.js';
8
- import type { HitTestStrategy } from './base.js';
7
+ import type { Feature, FeatureType } from '../../../api/model.js';
9
8
  /**
10
9
  * The built-in hit test of `Point` features: hit within the tolerance of the position.
11
10
  *
12
- * The distance is measured in the local frame of the click (see {@link HitTestStrategy}).
13
- * A custom type drawn as a point can reuse it, or extend it to widen the hit area.
11
+ * The distance is measured in a local frame around the click, where a degree of longitude is
12
+ * scaled by the cosine of the latitude. A feature type drawn as a point can reuse it, or
13
+ * extend it to widen the hit area. The engine uses it as the hit test of its points.
14
14
  */
15
- export declare class PointHitTestStrategy implements HitTestStrategy {
15
+ export declare class PointHitTestStrategy {
16
16
  /** The feature type, `'Point'` */
17
17
  readonly geometryType: FeatureType;
18
- test(feature: Feature, coordinate: Coordinate, toleranceLngLat: number): boolean;
19
- distance(feature: Feature, coordinate: Coordinate): number;
18
+ /** Whether the feature is within `toleranceLngLat` degrees of the coordinate */
19
+ test(feature: Feature, coordinate: [number, number], toleranceLngLat: number): boolean;
20
+ /** The distance from the coordinate to the feature, in degrees of the local frame */
21
+ distance(feature: Feature, coordinate: [number, number]): number;
20
22
  }
@@ -1,11 +1,13 @@
1
1
  // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
2
  // SPDX-License-Identifier: AGPL-3.0-only
3
+ import { coordinatesOf } from '../../../shared/utils/coordinates.js';
3
4
  import { latitudeScale, localDistance } from '../local-frame.js';
4
5
  /**
5
6
  * The built-in hit test of `Point` features: hit within the tolerance of the position.
6
7
  *
7
- * The distance is measured in the local frame of the click (see {@link HitTestStrategy}).
8
- * A custom type drawn as a point can reuse it, or extend it to widen the hit area.
8
+ * The distance is measured in a local frame around the click, where a degree of longitude is
9
+ * scaled by the cosine of the latitude. A feature type drawn as a point can reuse it, or
10
+ * extend it to widen the hit area. The engine uses it as the hit test of its points.
9
11
  */
10
12
  export class PointHitTestStrategy {
11
13
  constructor() {
@@ -17,13 +19,15 @@ export class PointHitTestStrategy {
17
19
  value: 'Point'
18
20
  });
19
21
  }
22
+ /** Whether the feature is within `toleranceLngLat` degrees of the coordinate */
20
23
  test(feature, coordinate, toleranceLngLat) {
21
- const pointCoord = feature.coordinates;
24
+ const pointCoord = coordinatesOf(feature);
22
25
  const dist = localDistance(coordinate, pointCoord, latitudeScale(coordinate[1]));
23
26
  return dist <= toleranceLngLat;
24
27
  }
28
+ /** The distance from the coordinate to the feature, in degrees of the local frame */
25
29
  distance(feature, coordinate) {
26
- const pointCoord = feature.coordinates;
30
+ const pointCoord = coordinatesOf(feature);
27
31
  return localDistance(coordinate, pointCoord, latitudeScale(coordinate[1]));
28
32
  }
29
33
  }
@@ -1,10 +1,3 @@
1
- /**
2
- * PolygonHitTestStrategy
3
- *
4
- * Hit testing strategy for Polygon features.
5
- * Distances to the edges are measured in the local frame of hit testing (local-frame.ts).
6
- * The inside test is unaffected by that frame (it only scales the latitude axis).
7
- */
8
1
  import type { Coordinate, Feature, FeatureType } from '../../../store/types.js';
9
2
  import type { HitTestStrategy } from './base.js';
10
3
  /**
@@ -1,5 +1,13 @@
1
1
  // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
2
  // SPDX-License-Identifier: AGPL-3.0-only
3
+ /**
4
+ * PolygonHitTestStrategy
5
+ *
6
+ * Hit testing strategy for Polygon features.
7
+ * Distances to the edges are measured in the local frame of hit testing (local-frame.ts).
8
+ * The inside test is unaffected by that frame (it only scales the latitude axis).
9
+ */
10
+ import { coordinatesOf } from '../../../shared/utils/coordinates.js';
3
11
  import { latitudeScale, localPointToSegmentDistance } from '../local-frame.js';
4
12
  import { polylineDistanceWithin } from '../segment-grid.js';
5
13
  /**
@@ -15,15 +23,15 @@ export class PolygonHitTestStrategy {
15
23
  });
16
24
  }
17
25
  test(feature, coordinate, toleranceLngLat) {
18
- const rings = feature.coordinates;
26
+ const rings = coordinatesOf(feature);
19
27
  return this.testRings(rings, coordinate, toleranceLngLat);
20
28
  }
21
29
  distance(feature, coordinate) {
22
- const rings = feature.coordinates;
30
+ const rings = coordinatesOf(feature);
23
31
  return this.distanceToRings(rings, coordinate);
24
32
  }
25
33
  testDistance(feature, coordinate, toleranceLngLat) {
26
- const rings = feature.coordinates;
34
+ const rings = coordinatesOf(feature);
27
35
  return this.testDistanceRings(rings, coordinate, toleranceLngLat);
28
36
  }
29
37
  /**
@@ -1,4 +1,4 @@
1
- import type { Dataset } from '../../display/types.js';
1
+ import type { Dataset } from '../../dataset/types.js';
2
2
  import type { ScreenPoint } from '../../shared/math/index.js';
3
3
  import type { Feature } from '../../store/types.js';
4
4
  import type { FeatureCompanionHitResult } from '../../view/feature-companion.js';
@@ -39,7 +39,8 @@ function firstTentativeCoordinate(tentative) {
39
39
  * little beyond ±180; the rendering and the export deal with that
40
40
  * - A drag moves every coordinate of its events by the one shift decided from where it started
41
41
  * (`dragStartLngLat`), so the distance dragged never jumps by 360 degrees when the pointer
42
- * crosses the antimeridian during the drag
42
+ * crosses the antimeridian during the drag. The normalizer gives the positions of a press
43
+ * continuously (the globe's jump from 180 to -180 included), so one shift keeps them so
43
44
  *
44
45
  * Away from the antimeridian, on the main copy of the world, nothing changes and the event is
45
46
  * returned as it is.
@@ -67,7 +68,7 @@ function toStoredCopy(event, reference) {
67
68
  * @internal
68
69
  */
69
70
  export function createInputRouter(deps) {
70
- const { normalizer, modeManager, context, map, pluginManager, displayInteractions, notifyMapClick, snapService, } = deps;
71
+ const { normalizer, modeManager, context, map, displayInteractions, notifyMapClick, trackClick, snapService, extensionInput, } = deps;
71
72
  let boundHandleEvent = null;
72
73
  /**
73
74
  * Whether input originating from the pointer is currently held
@@ -126,68 +127,140 @@ export function createInputRouter(deps) {
126
127
  */
127
128
  function applySnap(event, inputType) {
128
129
  if (!snapService || event.snap === false)
129
- return event;
130
- if (modeManager.getHandler()?.isSnapEnabledFor?.(inputType) === false)
131
- return event;
130
+ return { event, result: null };
131
+ if (modeManager.getHandler()?.isSnapEnabledFor?.(inputType) === false) {
132
+ return { event, result: null };
133
+ }
132
134
  const result = snapService.resolve(event.lngLat, event.point, buildSnapContext(event.modifiers));
133
135
  if (result.lngLat.lng === event.lngLat.lng && result.lngLat.lat === event.lngLat.lat) {
134
- return event;
136
+ return { event, result: result.target ? result : null };
137
+ }
138
+ return {
139
+ event: { ...event, lngLat: { lng: result.lngLat.lng, lat: result.lngLat.lat } },
140
+ result,
141
+ };
142
+ }
143
+ /**
144
+ * What a consumed event stops besides the receivers after it: a consumed press does not
145
+ * reach the map (no pan starts) and a consumed double click does not zoom it
146
+ */
147
+ function stopConsumed(event) {
148
+ if (event.type === 'mousedown') {
149
+ const original = event.originalEvent;
150
+ original.stopPropagation();
151
+ if (!('touches' in original))
152
+ original.preventDefault();
153
+ }
154
+ else if (event.type === 'dblclick') {
155
+ event.originalEvent.preventDefault();
156
+ }
157
+ }
158
+ /**
159
+ * Hands the event to the plugins of the extensions, then to a mode written to the extension
160
+ * contract
161
+ *
162
+ * @returns 'consumed' when the event goes no further, 'mode' when a mode of the contract
163
+ * received it, 'engine' when the mode is a mode of the engine the router calls
164
+ */
165
+ function toExtensions(handler, event, snapped, snap) {
166
+ if (!extensionInput)
167
+ return 'engine';
168
+ if (extensionInput.toPlugins(event, snapped, snap)) {
169
+ stopConsumed(event);
170
+ return 'consumed';
171
+ }
172
+ const consumed = extensionInput.toMode(handler, event, snapped, snap);
173
+ if (consumed === undefined)
174
+ return 'engine';
175
+ if (consumed) {
176
+ stopConsumed(event);
177
+ return 'consumed';
178
+ }
179
+ return 'mode';
180
+ }
181
+ /**
182
+ * A click: to the extensions, the mode, the datasets and the map.clicked notification
183
+ *
184
+ * @returns Whether a receiver took it
185
+ */
186
+ function handleClickEvent(handler, event) {
187
+ // Deliver to the mode with the snapped coordinates (if nothing snapped,
188
+ // the original event is used unchanged)
189
+ const { event: snapped, result } = applySnap(event, 'click');
190
+ const route = toExtensions(handler, event, snapped, result);
191
+ if (route === 'consumed')
192
+ return true;
193
+ if (route === 'engine')
194
+ handleClick(handler, snapped);
195
+ // Delivery to datasets happens only in select mode. A click
196
+ // in a drawing mode places a vertex, and delivering that same click as a
197
+ // click on the data as well would make the host application's "click to
198
+ // select" fire by mistake while drawing (for example, starting to draw a
199
+ // circle on top of a huge polygon of data would cover the whole screen with
200
+ // the selection highlight). The rule that a hit in the Store always wins is
201
+ // decided on the interception side, so the selection behavior of the mode
202
+ // during select is unaffected.
203
+ if (handler.modeName === 'select')
204
+ displayInteractions?.handleClick(snapped);
205
+ // Emit the click of select mode as a single stream regardless of whether
206
+ // anything was hit (draw.map.click). display.click is designed not to fire
207
+ // when a feature in the Store is hit, so a host application that needs "a
208
+ // click anywhere on the map" (placing a comment pin, for instance) watches
209
+ // this one. The coordinates are copied from the raw event before snapping.
210
+ if (handler.modeName === 'select') {
211
+ notifyMapClick?.({
212
+ lngLat: [event.lngLat.lng, event.lngLat.lat],
213
+ point: { x: event.point.x, y: event.point.y },
214
+ });
135
215
  }
136
- return { ...event, lngLat: { lng: result.lngLat.lng, lat: result.lngLat.lat } };
216
+ return route === 'engine' && handler.onClick !== undefined;
137
217
  }
218
+ /**
219
+ * Hands an event to the extensions and the mode
220
+ *
221
+ * @returns Whether a receiver took it: a plugin or a mode of the contract consumed it, or
222
+ * the mode of the engine has a receiver for it
223
+ */
138
224
  function handleEvent(input, options = {}) {
139
225
  // Only input originating from the real pointer is stopped while held.
140
226
  // Synthetic input (dispatch) is let through
141
227
  if (pointerHeld && !options.synthetic && HELD_EVENT_TYPES.has(input.type))
142
- return;
228
+ return false;
143
229
  const handler = modeManager.getHandler();
144
230
  if (!handler)
145
- return;
231
+ return false;
146
232
  // The single place where the longitude of the input is decided (see toStoredCopy)
147
233
  const event = toStoredCopy(input, firstTentativeCoordinate(context.store.getTentative()));
148
234
  switch (event.type) {
149
- case 'click': {
150
- // Deliver to the mode with the snapped coordinates (if nothing snapped,
151
- // the original event is used unchanged)
152
- const snapped = applySnap(event, 'click');
153
- handleClick(handler, snapped);
154
- // Delivery to datasets happens only in select mode. A click
155
- // in a drawing mode places a vertex, and delivering that same click as a
156
- // click on the data as well would make the host application's "click to
157
- // select" fire by mistake while drawing (for example, starting to draw a
158
- // circle on top of a huge polygon of data would cover the whole screen with
159
- // the selection highlight). The rule that a hit in the Store always wins is
160
- // decided on the interception side, so the selection behavior of the mode
161
- // during select is unaffected.
162
- if (handler.modeName === 'select')
163
- displayInteractions?.handleClick(snapped);
164
- // Emit the click of select mode as a single stream regardless of whether
165
- // anything was hit (draw.map.click). display.click is designed not to fire
166
- // when a feature in the Store is hit, so a host application that needs "a
167
- // click anywhere on the map" (placing a comment pin, for instance) watches
168
- // this one. The coordinates are copied from the raw event before snapping.
169
- if (handler.modeName === 'select') {
170
- notifyMapClick?.({
171
- lngLat: [event.lngLat.lng, event.lngLat.lat],
172
- point: { x: event.point.x, y: event.point.y },
173
- });
235
+ case 'click':
236
+ trackClick?.([event.lngLat.lng, event.lngLat.lat]);
237
+ try {
238
+ return handleClickEvent(handler, event);
174
239
  }
175
- break;
240
+ finally {
241
+ trackClick?.(null);
242
+ }
243
+ case 'dblclick': {
244
+ const taken = engineOr(toExtensions(handler, event, event, null), handler.onDoubleClick, () => handler.onDoubleClick?.(event));
245
+ // A double click never zooms the map while a drawing mode is active, whether or not
246
+ // anything took it: its clicks were meant for the drawing
247
+ if (handler.writesFeatures === true)
248
+ event.originalEvent.preventDefault();
249
+ return taken;
176
250
  }
177
- case 'dblclick':
178
- handler.onDoubleClick?.(event);
179
- break;
180
251
  case 'mousedown':
181
- handleMouseDown(handler, event);
182
- break;
252
+ return engineOr(toExtensions(handler, event, event, null), handler.onMouseDown, () => handleMouseDown(handler, event));
183
253
  case 'mouseup':
184
- handler.onMouseUp?.(event);
185
- break;
254
+ return engineOr(toExtensions(handler, event, event, null), handler.onMouseUp, () => handler.onMouseUp?.(event));
186
255
  case 'mousemove': {
187
- const snapped = applySnap(event, 'mousemove');
188
- // Call the onMouseMove of the plugins (they do not consume it)
189
- pluginManager?.handleMouseMove(snapped);
190
- handler.onMouseMove?.(snapped);
256
+ const { event: snapped, result } = applySnap(event, 'mousemove');
257
+ if (extensionInput?.toPlugins(event, snapped, result))
258
+ return true;
259
+ const consumed = extensionInput?.toMode(handler, event, snapped, result);
260
+ if (consumed === true)
261
+ return true;
262
+ if (consumed === undefined)
263
+ handler.onMouseMove?.(snapped);
191
264
  // The hover of datasets is likewise limited to select mode,
192
265
  // by the same rule as click. When switching to a drawing mode, a hover that
193
266
  // is still held is discarded (so that it does not fire on the stale target
@@ -198,53 +271,64 @@ export function createInputRouter(deps) {
198
271
  else {
199
272
  displayInteractions?.reset();
200
273
  }
201
- break;
274
+ return consumed === undefined && handler.onMouseMove !== undefined;
202
275
  }
203
276
  case 'contextmenu':
204
277
  // contextmenu currently has no special handling
205
- break;
278
+ return false;
206
279
  // The start and end of a drag also go through snapping. This is to keep
207
280
  // "start drawing exactly at a corner of a boundary and end at a corner" for
208
281
  // drag-driven drawing (freehand). The drag operations of select mode use
209
282
  // dragStartLngLat (the press position from before the threshold was exceeded)
210
283
  // as their start position, so they are unaffected by the replacement here.
211
284
  case 'dragstart': {
212
- const snapped = applySnap(event, 'dragstart');
213
- handler.onDragStart?.(snapped);
214
- break;
285
+ const { event: snapped, result } = applySnap(event, 'dragstart');
286
+ return engineOr(toExtensions(handler, event, snapped, result), handler.onDragStart, () => handler.onDragStart?.(snapped));
215
287
  }
216
288
  case 'dragmove': {
217
- const snapped = applySnap(event, 'dragmove');
218
- // Call the onDragMove of the plugins (they do not consume it; the
219
- // counterpart of onMouseMove)
220
- pluginManager?.handleDragMove(snapped);
289
+ const { event: snapped, result } = applySnap(event, 'dragmove');
290
+ if (extensionInput?.toPlugins(event, snapped, result))
291
+ return true;
292
+ const consumed = extensionInput?.toMode(handler, event, snapped, result);
293
+ if (consumed !== undefined)
294
+ return consumed;
221
295
  handler.onDragMove?.(snapped);
222
- break;
296
+ return handler.onDragMove !== undefined;
223
297
  }
224
298
  case 'dragend': {
225
- const snapped = applySnap(event, 'dragend');
226
- handler.onDragEnd?.(snapped);
227
- break;
299
+ const { event: snapped, result } = applySnap(event, 'dragend');
300
+ return engineOr(toExtensions(handler, event, snapped, result), handler.onDragEnd, () => handler.onDragEnd?.(snapped));
228
301
  }
229
302
  // A press ended without a release (a second finger, or the browser cancelled the
230
303
  // touch). No coordinates are decided, so it does not go through snapping, and it
231
304
  // is never held: the mode must always get the chance to abort the press.
232
305
  case 'dragcancel':
233
- handler.onDragCancel?.(event);
234
- break;
235
- case 'keydown':
236
- // Call the onKeyDown of the plugins first
237
- if (pluginManager?.handleKeyDown(event)) {
238
- // Handled by a plugin
239
- break;
240
- }
306
+ return engineOr(toExtensions(handler, event, event, null), handler.onDragCancel, () => handler.onDragCancel?.(event));
307
+ case 'keydown': {
308
+ if (extensionInput?.toPlugins(event, event, null))
309
+ return true;
310
+ const consumed = extensionInput?.toMode(handler, event, event, null);
311
+ if (consumed !== undefined)
312
+ return consumed;
241
313
  handler.onKeyDown?.(event);
242
- break;
314
+ return handler.onKeyDown !== undefined;
315
+ }
243
316
  case 'keyup':
244
- handler.onKeyUp?.(event);
245
- break;
317
+ return engineOr(toExtensions(handler, event, event, null), handler.onKeyUp, () => handler.onKeyUp?.(event));
246
318
  }
247
319
  }
320
+ /**
321
+ * Runs the receiver of the mode of the engine when the route leads to it
322
+ *
323
+ * @param receiver - The receiver of the mode of the engine, to tell whether it has one
324
+ * @returns Whether a receiver took the event
325
+ */
326
+ function engineOr(route, receiver, run) {
327
+ if (route !== 'engine')
328
+ return route === 'consumed';
329
+ run();
330
+ return receiver !== undefined;
331
+ }
248
332
  function handleClick(handler, event) {
249
333
  handler.onClick?.(event);
250
334
  }
@@ -1,5 +1,6 @@
1
1
  // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
2
  // SPDX-License-Identifier: AGPL-3.0-only
3
+ import { nearestLongitude } from '../shared/math/longitude.js';
3
4
  import { getModifiers } from './types.js';
4
5
  const DEFAULT_OPTIONS = {
5
6
  dragThreshold: 3,
@@ -51,6 +52,20 @@ function createProfiles(opts) {
51
52
  },
52
53
  };
53
54
  }
55
+ /**
56
+ * The position of the pointer, on the copy of the world nearest to where it was last
57
+ *
58
+ * The flat map gives the pointer unwrapped longitudes, which run on past 180 as it crosses the
59
+ * antimeridian. The globe gives them in [-180, 180], so they jump by 360 degrees there: a
60
+ * freehand stroke drawn from them went once round the world along the parallel, and the shift
61
+ * of a feature dragged across jumped by a turn. Within a press each position is therefore
62
+ * taken on the copy nearest to the last one, so the pointer moves on continuously, as on the
63
+ * flat map. A position within 180 degrees of the last one is returned unchanged.
64
+ */
65
+ function continuing(lngLat, last) {
66
+ const lng = nearestLongitude(lngLat.lng, last.lng);
67
+ return lng === lngLat.lng ? lngLat : { lng, lat: lngLat.lat };
68
+ }
54
69
  /**
55
70
  * Whether a mouse event is the compatibility event a browser emits for a touch
56
71
  */
@@ -77,7 +92,7 @@ export function createInputNormalizer(map, options = {}) {
77
92
  const canvas = map.getCanvas();
78
93
  const listeners = new Set();
79
94
  const opts = { ...DEFAULT_OPTIONS, ...options };
80
- const profiles = createProfiles(opts);
95
+ let profiles = createProfiles(opts);
81
96
  // State management
82
97
  let press = null;
83
98
  /**
@@ -184,7 +199,8 @@ export function createInputNormalizer(map, options = {}) {
184
199
  *
185
200
  * Once the press has become a drag it stays one until it is released.
186
201
  */
187
- function movePress(current, point, lngLat, originalEvent) {
202
+ function movePress(current, point, rawLngLat, originalEvent) {
203
+ const lngLat = continuing(rawLngLat, current.lastLngLat);
188
204
  current.lastPoint = point;
189
205
  current.lastLngLat = lngLat;
190
206
  current.lastEvent = originalEvent;
@@ -204,7 +220,8 @@ export function createInputNormalizer(map, options = {}) {
204
220
  * Releases the press: dragend (when dragging) and mouseup. Returns whether the release
205
221
  * is a click candidate.
206
222
  */
207
- function releasePress(current, point, lngLat, originalEvent) {
223
+ function releasePress(current, point, rawLngLat, originalEvent) {
224
+ const lngLat = continuing(rawLngLat, current.lastLngLat);
208
225
  clearLongPress(current);
209
226
  press = null;
210
227
  if (current.dragging) {
@@ -509,5 +526,9 @@ export function createInputNormalizer(map, options = {}) {
509
526
  function off(handler) {
510
527
  listeners.delete(handler);
511
528
  }
512
- return { attach, detach, on, off };
529
+ const setDragThreshold = (px) => {
530
+ opts.dragThreshold = px;
531
+ profiles = createProfiles(opts);
532
+ };
533
+ return { attach, detach, on, off, setDragThreshold };
513
534
  }
@@ -22,7 +22,7 @@ export interface ModifierKeys {
22
22
  * `'touch'` is one finger of a touch screen, `'pen'` a stylus (reported either through
23
23
  * the touch events, as on iPadOS, or through the mouse events the browser emits for
24
24
  * it), and `'mouse'` everything else. Input with no `pointerType` (synthetic input
25
- * through `draw.input`, for example) is treated as `'mouse'`.
25
+ * of the tests, for example) is treated as `'mouse'`.
26
26
  */
27
27
  export type PointerType = 'mouse' | 'touch' | 'pen';
28
28
  /**
@@ -68,6 +68,11 @@ export interface MouseNormalizedEvent {
68
68
  * which synthetic input chooses whether to go through snapping.
69
69
  */
70
70
  snap?: boolean;
71
+ /**
72
+ * Whether the event was made from code (`draw.drawing`) at an exact position, not by the
73
+ * pointer; the modes apply no click tolerance to it (`DrawPointerEvent.programmatic`)
74
+ */
75
+ programmatic?: boolean;
71
76
  }
72
77
  /**
73
78
  * A normalized drag event: the start, each move, the end or the cancellation of a press