@defra/interactive-map 0.0.39-alpha → 0.0.41-alpha
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/css/index.css +1 -1
- package/dist/esm/im-core.js +1 -1
- package/dist/esm/im-shell.js +1 -1
- package/dist/umd/im-core.js +1 -1
- package/dist/umd/index.js +1 -1
- package/docs/api/control-definition.md +9 -1
- package/docs/api/slots.md +26 -5
- package/docs/api.md +4 -4
- package/docs/assets/images/slot-map.svg +61 -262
- package/docs/examples/draw-tools.mdx +3 -3
- package/docs/plugins/draw.md +80 -17
- package/docs/plugins/search.md +1 -1
- package/govuk-prototype-kit.config.json +2 -0
- package/jest.setup.js +5 -0
- package/package.json +9 -1
- package/plugins/beta/draw-es/dist/esm/im-draw-es-plugin.js +1 -1
- package/plugins/beta/draw-ml/dist/esm/im-draw-ml-plugin.js +1 -1
- package/plugins/beta/draw-ml/dist/umd/im-draw-ml-plugin.js +1 -1
- package/plugins/beta/draw-ol/dist/esm/im-draw-ol-plugin.js +1 -1
- package/plugins/beta/map-styles/dist/esm/im-map-styles-plugin.js +1 -1
- package/plugins/beta/map-styles/dist/umd/im-map-styles-plugin.js +1 -1
- package/plugins/beta/map-styles/dist/umd/index.js +1 -1
- package/plugins/datasets/dist/css/index.css +1 -1
- package/plugins/datasets/dist/esm/esriLayerAdapter.js +1 -1
- package/plugins/datasets/dist/esm/im-datasets-ml-adapter.js +1 -1
- package/plugins/datasets/dist/esm/im-datasets-plugin.js +1 -1
- package/plugins/datasets/dist/umd/im-datasets-esri-adapter.js +1 -1
- package/plugins/datasets/dist/umd/im-datasets-ml-adapter.js +1 -1
- package/plugins/datasets/dist/umd/im-datasets-plugin.js +1 -1
- package/plugins/datasets/dist/umd/index.js +1 -1
- package/plugins/datasets/src/adapters/esri/esriLayerAdapter.js +2 -3
- package/plugins/datasets/src/adapters/esri/esriLayerAdapter.test.js +175 -0
- package/plugins/datasets/src/adapters/esri/registry/esriDataset.js +1 -1
- package/plugins/datasets/src/adapters/esri/registry/esriDataset.test.js +55 -0
- package/plugins/datasets/src/adapters/loadLayerAdapter.js +1 -1
- package/plugins/datasets/src/adapters/loadLayerAdapter.test.js +61 -0
- package/plugins/datasets/src/adapters/maplibre/maplibreLayerAdapter.js +1 -3
- package/plugins/datasets/src/adapters/maplibre/maplibreLayerAdapter.test.js +17 -3
- package/plugins/datasets/src/api/setOpacity.test.js +9 -0
- package/plugins/datasets/src/components/LayersMenu/LayersMenu.jsx +10 -25
- package/plugins/datasets/src/components/LayersMenu/LayersMenu.test.jsx +0 -42
- package/plugins/datasets/src/datasets.scss +0 -1
- package/plugins/datasets/src/fetch/createDynamicSource.js +135 -129
- package/plugins/datasets/src/fetch/createDynamicSource.test.js +318 -0
- package/plugins/datasets/src/fetch/fetchGeoJSON.test.js +83 -0
- package/plugins/datasets/src/index.test.js +36 -0
- package/plugins/datasets/src/initialise/DatasetsInit.jsx +17 -7
- package/plugins/datasets/src/initialise/DatasetsInit.test.jsx +262 -0
- package/plugins/datasets/src/initialise/initialiseDatasets.js +16 -5
- package/plugins/datasets/src/initialise/initialiseDatasets.test.js +42 -0
- package/plugins/datasets/src/manifest.js +0 -38
- package/plugins/datasets/src/manifest.test.js +49 -0
- package/plugins/datasets/src/reducers/datasetsToMenu.test.js +54 -1
- package/plugins/datasets/src/reducers/pluginState.js +3 -16
- package/plugins/datasets/src/reducers/pluginState.test.js +23 -0
- package/plugins/datasets/src/registry/dataset.js +15 -4
- package/plugins/datasets/src/registry/dataset.test.js +61 -0
- package/plugins/datasets/src/registry/datasetRegistry.js +12 -9
- package/plugins/datasets/src/registry/datasetRegistry.test.js +17 -5
- package/plugins/datasets/src/registry/globalDataset.js +0 -3
- package/plugins/datasets/src/registry/isVisibleWhen.js +6 -3
- package/plugins/datasets/src/registry/isVisibleWhen.test.js +11 -1
- package/plugins/datasets/src/utils/bbox.test.js +125 -0
- package/plugins/draw/dist/esm/im-draw-ml-adapter.js +1 -1
- package/plugins/draw/dist/esm/im-draw-ol-adapter.js +1 -1
- package/plugins/draw/dist/esm/im-draw-plugin.js +1 -1
- package/plugins/draw/dist/esm/index.js +1 -1
- package/plugins/draw/dist/umd/im-draw-ml-adapter.js +2 -1
- package/plugins/draw/dist/umd/im-draw-ml-adapter.js.LICENSE.txt +1 -0
- package/plugins/draw/dist/umd/im-draw-ol-adapter.js +1 -1
- package/plugins/draw/dist/umd/im-draw-plugin.js +1 -1
- package/plugins/draw/dist/umd/index.js +1 -1
- package/plugins/draw/src/DrawInit.jsx +12 -4
- package/plugins/draw/src/DrawInit.test.jsx +51 -10
- package/plugins/draw/src/adapters/maplibre/MaplibreDrawAdapter.js +92 -12
- package/plugins/draw/src/adapters/maplibre/MaplibreDrawAdapter.test.js +246 -4
- package/plugins/draw/src/adapters/maplibre/mapboxDraw.js +109 -14
- package/plugins/draw/src/adapters/maplibre/mapboxDraw.test.js +174 -11
- package/plugins/draw/src/adapters/maplibre/modes/drawMode/clickHandlers.test.js +12 -0
- package/plugins/draw/src/adapters/maplibre/modes/drawMode/lifecycle.js +9 -1
- package/plugins/draw/src/adapters/maplibre/modes/drawMode/lifecycle.test.js +24 -3
- package/plugins/draw/src/adapters/maplibre/modes/drawMode/pointerHandlers.js +1 -1
- package/plugins/draw/src/adapters/maplibre/modes/drawMode/pointerHandlers.test.js +1 -1
- package/plugins/draw/src/adapters/maplibre/modes/drawPointMode.js +194 -0
- package/plugins/draw/src/adapters/maplibre/modes/drawPointMode.test.js +457 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/__helpers__/harness.js +102 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/keyboardHandlers.js +82 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/keyboardHandlers.test.js +83 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/pointOperations.js +55 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/pointOperations.test.js +62 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/pointerHandlers.js +138 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/pointerHandlers.test.js +197 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/touchHandlers.js +92 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/touchHandlers.test.js +101 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/undoHandlers.js +46 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/undoHandlers.test.js +42 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode.js +151 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode.test.js +156 -0
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/keyboardHandlers.js +5 -28
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/keyboardHandlers.test.js +24 -39
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/pointerHandlers.js +4 -5
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/touchHandlers.js +20 -23
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/touchHandlers.test.js +25 -5
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/undoHandlers.js +6 -36
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/undoHandlers.test.js +7 -49
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/vertexOperations.js +4 -54
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/vertexOperations.test.js +8 -33
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode.js +29 -72
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode.test.js +11 -4
- package/plugins/draw/src/adapters/maplibre/pointSymbolImages.js +158 -0
- package/plugins/draw/src/adapters/maplibre/pointSymbolImages.test.js +314 -0
- package/plugins/draw/src/adapters/maplibre/snap/prototypePatches.js +6 -1
- package/plugins/draw/src/adapters/maplibre/snap/prototypePatches.test.js +21 -0
- package/plugins/draw/src/adapters/maplibre/snap/snapInstance.js +6 -2
- package/plugins/draw/src/adapters/maplibre/snap/snapInstance.test.js +12 -0
- package/plugins/draw/src/adapters/maplibre/styles.js +38 -11
- package/plugins/draw/src/adapters/maplibre/styles.test.js +39 -0
- package/plugins/draw/src/adapters/maplibre/utils/editModeEvents.js +79 -0
- package/plugins/draw/src/adapters/maplibre/utils/editModeEvents.test.js +135 -0
- package/plugins/draw/src/adapters/maplibre/utils/geometryValidation.js +42 -0
- package/plugins/draw/src/adapters/maplibre/utils/geometryValidation.test.js +85 -0
- package/plugins/draw/src/adapters/maplibre/utils/keyboardShortcuts.js +34 -0
- package/plugins/draw/src/adapters/maplibre/utils/keyboardShortcuts.test.js +78 -0
- package/plugins/draw/src/adapters/maplibre/utils/snapHelpers.js +16 -3
- package/plugins/draw/src/adapters/maplibre/utils/snapHelpers.test.js +21 -3
- package/plugins/draw/src/adapters/maplibre/utils/snapMovement.js +59 -0
- package/plugins/draw/src/adapters/maplibre/utils/snapMovement.test.js +73 -0
- package/plugins/draw/src/adapters/maplibre/utils/touchDragMath.js +33 -0
- package/plugins/draw/src/adapters/maplibre/utils/touchDragMath.test.js +70 -0
- package/plugins/draw/src/adapters/openlayers/OLDrawAdapter.js +27 -2
- package/plugins/draw/src/adapters/openlayers/OLDrawAdapter.test.js +93 -0
- package/plugins/draw/src/adapters/openlayers/__helpers__/harness.js +9 -0
- package/plugins/draw/src/adapters/openlayers/core/OLDrawManager.js +19 -1
- package/plugins/draw/src/adapters/openlayers/core/OLDrawManager.test.js +34 -1
- package/plugins/draw/src/adapters/openlayers/core/styles.js +73 -1
- package/plugins/draw/src/adapters/openlayers/core/styles.test.js +122 -3
- package/plugins/draw/src/adapters/openlayers/draw/DrawMode.js +1 -0
- package/plugins/draw/src/adapters/openlayers/draw/DrawMode.test.js +27 -1
- package/plugins/draw/src/adapters/openlayers/draw/drawInput.js +24 -4
- package/plugins/draw/src/adapters/openlayers/draw/drawInput.test.js +47 -3
- package/plugins/draw/src/adapters/openlayers/edit/EditMode.js +1 -1
- package/plugins/draw/src/adapters/openlayers/edit/EditMode.test.js +32 -1
- package/plugins/draw/src/adapters/openlayers/edit/keyboardHandler.js +9 -5
- package/plugins/draw/src/adapters/openlayers/edit/keyboardHandler.test.js +34 -1
- package/plugins/draw/src/adapters/openlayers/edit/modifyInteraction.js +5 -3
- package/plugins/draw/src/adapters/openlayers/edit/modifyInteraction.test.js +11 -0
- package/plugins/draw/src/adapters/openlayers/edit/nudge.js +12 -5
- package/plugins/draw/src/adapters/openlayers/edit/nudge.test.js +26 -3
- package/plugins/draw/src/adapters/openlayers/edit/touchHandler.js +18 -13
- package/plugins/draw/src/adapters/openlayers/edit/touchHandler.test.js +46 -1
- package/plugins/draw/src/adapters/openlayers/olDraw.js +11 -4
- package/plugins/draw/src/adapters/openlayers/olDraw.test.js +48 -6
- package/plugins/draw/src/adapters/openlayers/point/drawPointMode.js +156 -0
- package/plugins/draw/src/adapters/openlayers/point/drawPointMode.test.js +246 -0
- package/plugins/draw/src/adapters/openlayers/point/editPointMode.js +267 -0
- package/plugins/draw/src/adapters/openlayers/point/editPointMode.test.js +327 -0
- package/plugins/draw/src/adapters/openlayers/point/pointDragInteraction.js +71 -0
- package/plugins/draw/src/adapters/openlayers/point/pointOps.js +34 -0
- package/plugins/draw/src/adapters/openlayers/point/pointOps.test.js +32 -0
- package/plugins/draw/src/adapters/openlayers/point/pointSelectionState.js +82 -0
- package/plugins/draw/src/adapters/openlayers/point/pointSelectionState.test.js +107 -0
- package/plugins/draw/src/adapters/openlayers/point/pointSymbolImages.js +83 -0
- package/plugins/draw/src/adapters/openlayers/point/pointSymbolImages.test.js +214 -0
- package/plugins/draw/src/adapters/openlayers/snap/snapIndicator.js +3 -1
- package/plugins/draw/src/adapters/openlayers/snap/snapInteraction.js +6 -9
- package/plugins/draw/src/adapters/openlayers/snap/snapInteraction.test.js +15 -4
- package/plugins/draw/src/adapters/openlayers/utils/olCoords.js +1 -1
- package/plugins/draw/src/api/addFeature.js +16 -1
- package/plugins/draw/src/api/addFeature.test.js +62 -5
- package/plugins/draw/src/api/editFeature.js +7 -4
- package/plugins/draw/src/api/editFeature.test.js +16 -0
- package/plugins/draw/src/api/newPoint.js +42 -0
- package/plugins/draw/src/api/newPoint.test.js +117 -0
- package/plugins/draw/src/api/setStyle.js +43 -0
- package/plugins/draw/src/api/setStyle.test.js +75 -0
- package/plugins/draw/src/events.js +21 -14
- package/plugins/draw/src/events.test.js +15 -1
- package/plugins/draw/src/manifest.js +18 -6
- package/plugins/draw/src/manifest.test.js +32 -1
- package/plugins/draw/src/reducer.test.js +7 -0
- package/plugins/draw/src/utils/stripInternalProperties.js +19 -0
- package/plugins/draw/src/utils/stripInternalProperties.test.js +50 -0
- package/plugins/draw/src/utils/symbolKeys.js +5 -0
- package/plugins/draw/src/validation/liveDrawChecks.test.js +54 -0
- package/plugins/draw/src/validation/liveStroke.test.js +64 -1
- package/plugins/interact/dist/esm/im-interact-plugin.js +1 -1
- package/plugins/interact/dist/umd/im-interact-plugin.js +1 -1
- package/plugins/interact/dist/umd/index.js +1 -1
- package/plugins/interact/src/hooks/useCrossHairVisibility.js +12 -4
- package/plugins/interact/src/hooks/useCrossHairVisibility.test.js +88 -1
- package/plugins/interact/src/hooks/useHighlightSync.js +33 -12
- package/plugins/interact/src/hooks/useHighlightSync.test.js +96 -25
- package/plugins/interact/src/utils/featureQueries.js +18 -0
- package/plugins/interact/src/utils/featureQueries.test.js +15 -0
- package/plugins/interact/src/utils/spatial.js +9 -3
- package/plugins/interact/src/utils/spatial.test.js +12 -1
- package/plugins/map-key/dist/css/index.css +62 -0
- package/plugins/map-key/dist/esm/im-map-key-plugin.js +1 -0
- package/plugins/map-key/dist/esm/index.js +1 -0
- package/plugins/map-key/dist/umd/im-map-key-plugin.js +2 -0
- package/plugins/map-key/dist/umd/im-map-key-plugin.js.LICENSE.txt +1 -0
- package/plugins/map-key/dist/umd/index.js +2 -0
- package/plugins/map-key/dist/umd/index.js.LICENSE.txt +1 -0
- package/plugins/map-key/package.json +28 -0
- package/plugins/map-key/src/components/Key/EmptyKey.jsx +7 -0
- package/plugins/{datasets → map-key}/src/components/Key/EmptyKey.test.jsx +2 -2
- package/plugins/map-key/src/components/Key/Key.jsx +41 -0
- package/plugins/{datasets → map-key}/src/components/Key/Key.module.scss +15 -14
- package/plugins/map-key/src/components/Key/Key.test.jsx +73 -0
- package/plugins/map-key/src/components/Key/KeyGroupItem.jsx +16 -0
- package/plugins/map-key/src/components/Key/KeyGroupItem.test.jsx +53 -0
- package/plugins/map-key/src/components/Key/KeyItem.jsx +29 -0
- package/plugins/map-key/src/components/Key/KeyItem.test.jsx +67 -0
- package/plugins/map-key/src/components/Key/KeySvg.jsx +42 -0
- package/plugins/{datasets → map-key}/src/components/Key/KeySvg.test.jsx +14 -12
- package/plugins/map-key/src/components/Key/KeySvgLine.jsx +28 -0
- package/plugins/{datasets → map-key}/src/components/Key/KeySvgLine.test.jsx +1 -1
- package/plugins/map-key/src/components/Key/KeySvgPattern.jsx +23 -0
- package/plugins/{datasets → map-key}/src/components/Key/KeySvgPattern.test.jsx +2 -2
- package/plugins/map-key/src/components/Key/KeySvgRect.jsx +33 -0
- package/plugins/{datasets → map-key}/src/components/Key/KeySvgRect.test.jsx +1 -1
- package/plugins/map-key/src/components/Key/KeySvgSymbol.jsx +27 -0
- package/plugins/{datasets → map-key}/src/components/Key/KeySvgSymbol.test.jsx +5 -6
- package/plugins/map-key/src/components/Key/MapKey.jsx +50 -0
- package/plugins/map-key/src/components/Key/MapKey.test.jsx +130 -0
- package/plugins/{datasets → map-key}/src/components/Key/svgProperties.js +2 -2
- package/plugins/{datasets → map-key}/src/components/Key/svgProperties.test.js +2 -2
- package/plugins/map-key/src/index.js +13 -0
- package/plugins/map-key/src/index.test.js +31 -0
- package/plugins/map-key/src/initialise/MapKeyInit.jsx +15 -0
- package/plugins/map-key/src/initialise/MapKeyInit.test.jsx +39 -0
- package/plugins/map-key/src/manifest.js +30 -0
- package/plugins/map-key/src/manifest.test.js +63 -0
- package/plugins/map-key/src/mapKey.scss +4 -0
- package/plugins/map-key/src/registry/getDatasetRegistry.js +6 -0
- package/plugins/map-key/src/registry/getDatasetRegistry.test.js +23 -0
- package/plugins/map-key/src/registry/index.js +3 -0
- package/plugins/map-key/src/registry/index.test.js +15 -0
- package/plugins/menu/dist/css/index.css +80 -0
- package/plugins/menu/dist/esm/im-menu-plugin.js +1 -0
- package/plugins/menu/dist/esm/index.js +1 -0
- package/plugins/menu/dist/umd/im-menu-plugin.js +1 -0
- package/plugins/menu/dist/umd/index.js +2 -0
- package/plugins/menu/dist/umd/index.js.LICENSE.txt +1 -0
- package/plugins/menu/package.json +28 -0
- package/plugins/menu/src/components/Menu/CheckboxGroupWrapper.jsx +21 -0
- package/plugins/menu/src/components/Menu/GroupLegend.jsx +17 -0
- package/plugins/menu/src/components/Menu/GroupLegend.test.jsx +68 -0
- package/plugins/menu/src/components/Menu/Menu.jsx +19 -0
- package/plugins/menu/src/components/Menu/Menu.module.scss +90 -0
- package/plugins/menu/src/components/Menu/Menu.test.jsx +161 -0
- package/plugins/menu/src/components/Menu/MenuCheckbox.jsx +35 -0
- package/plugins/menu/src/components/Menu/MenuCheckbox.test.jsx +93 -0
- package/plugins/menu/src/components/Menu/MenuGroup.jsx +11 -0
- package/plugins/{datasets/src/components/LayersMenu/LayersMenuRadio.jsx → menu/src/components/Menu/MenuRadio.jsx} +6 -4
- package/plugins/{datasets/src/components/LayersMenu/LayersMenuRadio.test.jsx → menu/src/components/Menu/MenuRadio.test.jsx} +18 -18
- package/plugins/menu/src/components/Menu/RadioGroupWrapper.jsx +32 -0
- package/plugins/{datasets/src/components/LayersMenu/LayersRadioGroupWrapper.test.jsx → menu/src/components/Menu/RadioGroupWrapper.test.jsx} +21 -21
- package/plugins/menu/src/components/Menu/useIdPrefix.jsx +4 -0
- package/plugins/menu/src/index.js +13 -0
- package/plugins/menu/src/index.test.js +31 -0
- package/plugins/menu/src/initialise/MenuInit.jsx +24 -0
- package/plugins/menu/src/initialise/MenuInit.test.jsx +50 -0
- package/plugins/menu/src/initialise/createMenu.js +10 -0
- package/plugins/menu/src/initialise/createMenu.test.js +37 -0
- package/plugins/menu/src/manifest.js +35 -0
- package/plugins/menu/src/manifest.test.js +63 -0
- package/plugins/menu/src/menu.scss +4 -0
- package/plugins/menu/src/reducers/menuStateReducer.test.js +38 -0
- package/plugins/menu/src/reducers/pluginState.js +35 -0
- package/plugins/menu/src/reducers/pluginState.test.js +57 -0
- package/plugins/menu/src/registry/getDatasetRegistry.js +9 -0
- package/plugins/menu/src/registry/getDatasetRegistry.test.js +23 -0
- package/plugins/menu/src/registry/index.js +3 -0
- package/plugins/menu/src/registry/index.test.js +15 -0
- package/plugins/menu/src/registry/isVisibleWhen.js +43 -0
- package/plugins/menu/src/registry/isVisibleWhen.test.js +48 -0
- package/plugins/search/dist/css/index.css +1 -1
- package/plugins/search/dist/esm/im-search-plugin.js +1 -1
- package/plugins/search/dist/esm/index.js +1 -1
- package/plugins/search/dist/umd/im-search-plugin.js +1 -1
- package/plugins/search/dist/umd/index.js +1 -1
- package/plugins/search/src/Search.jsx +7 -5
- package/plugins/search/src/components/Form/Form.module.scss +9 -20
- package/plugins/search/src/index.js +0 -1
- package/plugins/search/src/index.test.js +2 -4
- package/plugins/search/src/manifest.js +1 -1
- package/plugins/search/src/search.scss +17 -16
- package/providers/beta/openlayers/dist/esm/im-openlayers-provider.js +1 -1
- package/providers/beta/openlayers/dist/umd/im-openlayers-provider.js +1 -1
- package/providers/beta/openlayers/dist/umd/index.js +1 -1
- package/providers/beta/openlayers/src/openlayersProvider.js +4 -1
- package/providers/beta/openlayers/src/openlayersProvider.test.js +18 -0
- package/providers/beta/openlayers/src/utils/highlightFeatures.js +52 -5
- package/providers/beta/openlayers/src/utils/highlightFeatures.test.js +176 -0
- package/providers/beta/openlayers/src/utils/symbolImages.js +40 -0
- package/providers/beta/openlayers/src/utils/symbolImages.test.js +58 -0
- package/providers/maplibre/dist/esm/im-maplibre-provider.js +1 -1
- package/providers/maplibre/dist/umd/im-maplibre-provider.js +1 -1
- package/providers/maplibre/dist/umd/index.js +1 -1
- package/providers/maplibre/src/utils/drawLayerBuckets.js +14 -0
- package/providers/maplibre/src/utils/drawLayerBuckets.test.js +18 -0
- package/providers/maplibre/src/utils/highlightFeatures.js +80 -55
- package/providers/maplibre/src/utils/highlightFeatures.test.js +156 -17
- package/providers/maplibre/src/utils/hoverCursor.js +30 -14
- package/providers/maplibre/src/utils/hoverCursor.test.js +35 -0
- package/providers/maplibre/src/utils/patternImages.js +1 -1
- package/providers/maplibre/src/utils/symbolImages.js +41 -3
- package/providers/maplibre/src/utils/symbolImages.test.js +40 -6
- package/rollup.esm.mjs +11 -1
- package/sonar-project.properties +7 -1
- package/src/App/components/Actions/Actions.test.jsx +47 -0
- package/src/App/components/Attributions/Attributions.module.scss +10 -0
- package/src/App/components/Hints/Hints.jsx +7 -2
- package/src/App/components/Hints/Hints.test.jsx +13 -0
- package/src/App/components/KeyboardHelp/KeyboardHelp.jsx +2 -3
- package/src/App/components/KeyboardHelp/KeyboardHelp.test.jsx +3 -6
- package/src/App/components/{MoveControl/MoveControl.jsx → MoveControls/MoveControls.jsx} +10 -10
- package/src/App/components/{MoveControl/MoveControl.module.scss → MoveControls/MoveControls.module.scss} +60 -29
- package/src/App/components/{MoveControl/MoveControl.test.jsx → MoveControls/MoveControls.test.jsx} +48 -48
- package/src/App/components/Panel/Panel.jsx +18 -3
- package/src/App/components/Panel/Panel.module.scss +18 -8
- package/src/App/components/Panel/Panel.test.jsx +34 -0
- package/src/App/components/Tooltip/Tooltip.test.jsx +12 -14
- package/src/App/components/Viewport/Viewport.jsx +9 -1
- package/src/App/components/Viewport/Viewport.test.jsx +11 -0
- package/src/App/hooks/useFeatureItems.js +16 -7
- package/src/App/hooks/useFeatureItems.test.js +57 -0
- package/src/App/hooks/useLayoutMeasurements.js +95 -84
- package/src/App/hooks/useLayoutMeasurements.test.js +61 -1
- package/src/App/initialiseApp.js +11 -8
- package/src/App/initialiseApp.test.js +15 -3
- package/src/App/layout/Layout.jsx +12 -11
- package/src/App/layout/Layout.test.jsx +2 -0
- package/src/App/layout/layout.module.scss +31 -17
- package/src/App/registry/keyboardShortcutRegistry.js +25 -13
- package/src/App/registry/keyboardShortcutRegistry.test.js +49 -32
- package/src/App/registry/pluginRegistry.js +2 -3
- package/src/App/registry/pluginRegistry.test.js +16 -3
- package/src/App/renderer/HtmlElementHost.jsx +18 -5
- package/src/App/renderer/HtmlElementHost.test.jsx +54 -0
- package/src/App/renderer/mapButtons.js +28 -12
- package/src/App/renderer/mapButtons.test.js +17 -4
- package/src/App/renderer/mapControls.js +3 -1
- package/src/App/renderer/mapControls.test.js +16 -0
- package/src/App/renderer/mapPanels.js +44 -9
- package/src/App/renderer/mapPanels.test.js +51 -2
- package/src/App/renderer/orderItems.js +28 -0
- package/src/App/renderer/orderItems.test.js +50 -0
- package/src/App/renderer/slotAggregator.js +2 -18
- package/src/App/renderer/slotHelpers.js +3 -1
- package/src/App/renderer/slotHelpers.test.js +5 -0
- package/src/App/renderer/slots.js +3 -0
- package/src/App/store/AppProvider.jsx +4 -2
- package/src/App/store/appDispatchMiddleware.js +1 -1
- package/src/App/store/appDispatchMiddleware.test.js +8 -0
- package/src/InteractiveMap/InteractiveMap.js +8 -2
- package/src/InteractiveMap/InteractiveMap.test.js +20 -3
- package/src/config/appConfig.js +17 -15
- package/src/config/appConfig.test.js +22 -22
- package/src/config/defaults.js +3 -1
- package/src/config/events.js +2 -0
- package/src/config/mergeConfig.js +7 -0
- package/src/config/mergeConfig.test.js +20 -0
- package/src/scss/main.scss +1 -1
- package/src/scss/settings/_colors.scss +1 -0
- package/src/scss/settings/_dimensions.scss +2 -3
- package/src/scss/settings/_transition.scss +1 -1
- package/src/services/eventBus.js +44 -0
- package/src/services/eventBus.test.js +83 -0
- package/src/services/symbolRegistry.js +1 -1
- package/src/test-utils.js +5 -0
- package/src/types.js +25 -7
- package/webpack.umd.mjs +2 -0
- package/plugins/datasets/src/components/Key/EmptyKey.jsx +0 -7
- package/plugins/datasets/src/components/Key/Key.jsx +0 -50
- package/plugins/datasets/src/components/Key/KeyGroupItem.jsx +0 -18
- package/plugins/datasets/src/components/Key/KeyItem.jsx +0 -23
- package/plugins/datasets/src/components/Key/KeySvg.jsx +0 -22
- package/plugins/datasets/src/components/Key/KeySvgLine.jsx +0 -19
- package/plugins/datasets/src/components/Key/KeySvgPattern.jsx +0 -13
- package/plugins/datasets/src/components/Key/KeySvgRect.jsx +0 -22
- package/plugins/datasets/src/components/Key/KeySvgSymbol.jsx +0 -16
- package/plugins/datasets/src/components/LayersMenu/LayersRadioGroupWrapper.jsx +0 -41
- /package/plugins/{datasets → menu}/src/reducers/menuStateReducer.js +0 -0
- /package/{providers/maplibre/src → src}/utils/rasteriseToImageData.js +0 -0
- /package/{providers/maplibre/src → src}/utils/rasteriseToImageData.test.js +0 -0
|
@@ -77,4 +77,15 @@ describe('createModifyInteraction', () => {
|
|
|
77
77
|
modify.destroy()
|
|
78
78
|
expect(map.removeInteraction).toHaveBeenCalledWith(interaction)
|
|
79
79
|
})
|
|
80
|
+
|
|
81
|
+
// point/editPointMode.js injects its own condition (built around map.forEachFeatureAtPixel)
|
|
82
|
+
// in place of buildModifyCondition's fixed-radius hit-test, since a symbol icon can render
|
|
83
|
+
// far bigger than PIXEL_TOLERANCE covers.
|
|
84
|
+
test('an injected condition overrides buildModifyCondition\'s own default', () => {
|
|
85
|
+
const map = createFakeMap()
|
|
86
|
+
const state = { interfaceType: 'mouse', vertices: [[0, 0]], midpoints: [] }
|
|
87
|
+
const customCondition = jest.fn(() => true)
|
|
88
|
+
createModifyInteraction({ map, olFeature: polygonFeature(RING), getState: () => state, onModifyEnd: jest.fn(), condition: customCondition })
|
|
89
|
+
expect(map.interactions[0].condition_).toBe(customCondition)
|
|
90
|
+
})
|
|
80
91
|
})
|
|
@@ -30,9 +30,12 @@ export const resolveSnappedCoord = (snap, map, current, nudgedCoord, snappedCoor
|
|
|
30
30
|
* `keyMove` tracks the coordinate at the start of a nudge sequence so a single
|
|
31
31
|
* move_vertex undo op can be pushed on keyup (see keyboardHandler).
|
|
32
32
|
*
|
|
33
|
+
* @param {(olFeature, index: number, coord: number[]) => void} [options.moveCoord] - coordinate
|
|
34
|
+
* writer, defaulting to moveVertex; point/editPointMode.js injects point/pointOps.js's
|
|
35
|
+
* movePoint instead, since a Point has no ring index to address.
|
|
33
36
|
* @returns {{ nudge: (e: KeyboardEvent) => void, keyMove: { start, index }, nudgeByDelta: (dx: number, dy: number, isLargeStep: boolean) => void }}
|
|
34
37
|
*/
|
|
35
|
-
export const wireNudge = ({ map, snap, getState, setState, onInserted, onVertexMoved }) => {
|
|
38
|
+
export const wireNudge = ({ map, snap, getState, setState, onInserted, onVertexMoved, moveCoord = moveVertex }) => {
|
|
36
39
|
const keyMove = { start: null, index: null }
|
|
37
40
|
|
|
38
41
|
// Shared core: moves the selected vertex by an already pixel-scaled delta,
|
|
@@ -46,9 +49,13 @@ export const wireNudge = ({ map, snap, getState, setState, onInserted, onVertexM
|
|
|
46
49
|
const current = vertices[selectedVertexIndex]
|
|
47
50
|
const nudgedCoord = nudgeCoord(map, current, dx, dy)
|
|
48
51
|
const snappedCoord = snap ? snap.apply(nudgedCoord) : nudgedCoord
|
|
49
|
-
snap?.hideIndicator()
|
|
50
52
|
const newCoord = resolveSnappedCoord(snap, map, current, nudgedCoord, snappedCoord, dx, dy)
|
|
51
|
-
|
|
53
|
+
// resolveSnappedCoord can override snappedCoord with an escape jump clear of the snap
|
|
54
|
+
// radius — when it does, the indicator snap.apply() just showed is now stale, so correct it.
|
|
55
|
+
if (snap && newCoord !== snappedCoord) {
|
|
56
|
+
snap.hideIndicator()
|
|
57
|
+
}
|
|
58
|
+
moveCoord(olFeature, selectedVertexIndex, newCoord)
|
|
52
59
|
setState({ vertices: vertices.map((c, i) => i === selectedVertexIndex ? newCoord : c) })
|
|
53
60
|
return { previousCoord: current, vertexIndex: selectedVertexIndex }
|
|
54
61
|
}
|
|
@@ -99,12 +106,12 @@ export const wireNudge = ({ map, snap, getState, setState, onInserted, onVertexM
|
|
|
99
106
|
moveSelectedVertexBy(dx, dy)
|
|
100
107
|
}
|
|
101
108
|
|
|
102
|
-
// Explicit-delta counterpart to nudge(e) — the entry point for
|
|
109
|
+
// Explicit-delta counterpart to nudge(e) — the entry point for MoveControls'
|
|
103
110
|
// D-pad (see mapProvider.activeMoveTarget in events.js). Unlike nudge(e)'s
|
|
104
111
|
// held-key sequencing (undo pushed on keyup via keyMove, so repeated keydowns
|
|
105
112
|
// while held batch into one undo step), each call here is one complete,
|
|
106
113
|
// undoable action — a button click has no "held" state to batch. Midpoints
|
|
107
|
-
// aren't handled here:
|
|
114
|
+
// aren't handled here: MoveControls only claims the D-pad once a real vertex is
|
|
108
115
|
// selected (see buildVertexMoveTarget in events.js).
|
|
109
116
|
const nudgeByDelta = (dx, dy, isLargeStep) => {
|
|
110
117
|
const step = isLargeStep ? KEYBOARD.stepAmount : KEYBOARD.nudgeAmount
|
|
@@ -53,7 +53,7 @@ describe('nudging a vertex', () => {
|
|
|
53
53
|
})
|
|
54
54
|
})
|
|
55
55
|
|
|
56
|
-
describe('nudgeByDelta (
|
|
56
|
+
describe('nudgeByDelta (MoveControls D-pad)', () => {
|
|
57
57
|
test('moves the selected vertex by an explicit direction, scaled by isLargeStep, and reports the move for undo', () => {
|
|
58
58
|
const { state, nudgeByDelta, olFeature, onVertexMoved } = setup()
|
|
59
59
|
Object.assign(state, { selectedVertexIndex: 1, selectedVertexType: 'vertex' })
|
|
@@ -79,7 +79,7 @@ describe('nudgeByDelta (MoveControl D-pad)', () => {
|
|
|
79
79
|
const { state, nudgeByDelta, onVertexMoved } = setup()
|
|
80
80
|
nudgeByDelta(1, 0, true) // nothing selected
|
|
81
81
|
Object.assign(state, { selectedVertexIndex: 4, selectedVertexType: 'midpoint' })
|
|
82
|
-
nudgeByDelta(1, 0, true) // midpoint selected —
|
|
82
|
+
nudgeByDelta(1, 0, true) // midpoint selected — MoveControls only claims a real vertex
|
|
83
83
|
state.olFeature = null
|
|
84
84
|
Object.assign(state, { selectedVertexIndex: 1, selectedVertexType: 'vertex' })
|
|
85
85
|
nudgeByDelta(1, 0, true)
|
|
@@ -134,7 +134,17 @@ describe('snapping while nudging', () => {
|
|
|
134
134
|
Object.assign(state, { selectedVertexIndex: 1, selectedVertexType: 'vertex' })
|
|
135
135
|
nudge({ key: 'ArrowRight' })
|
|
136
136
|
expect(ring(olFeature)[1]).toEqual([16, 0])
|
|
137
|
-
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
// Regression: a stray hideIndicator() right after snap.apply() undid its own show on every
|
|
140
|
+
// single nudge, so the indicator could never actually be seen. keyboardHandler.js's own keyup
|
|
141
|
+
// no longer hides it either — see its own comment — so once shown here, it stays shown.
|
|
142
|
+
test('does not hide the indicator mid-sequence — snap.apply() already shows/hides it', () => {
|
|
143
|
+
const snap = snapReturning((c) => [c[0] + 1, c[1]])
|
|
144
|
+
const { state, nudge } = setup({ snap })
|
|
145
|
+
Object.assign(state, { selectedVertexIndex: 1, selectedVertexType: 'vertex' })
|
|
146
|
+
nudge({ key: 'ArrowRight' })
|
|
147
|
+
expect(snap.hideIndicator).not.toHaveBeenCalled()
|
|
138
148
|
})
|
|
139
149
|
|
|
140
150
|
test('escapes the snap radius when snapping blocks the nudge', () => {
|
|
@@ -144,6 +154,19 @@ describe('snapping while nudging', () => {
|
|
|
144
154
|
nudge({ key: 'ArrowRight' })
|
|
145
155
|
expect(ring(olFeature)[1]).toEqual([23, 0]) // snapRadius + 1 past the original position
|
|
146
156
|
})
|
|
157
|
+
|
|
158
|
+
// Regression: nudging away from a target you're sitting on escapes the snap radius (above),
|
|
159
|
+
// but snap.apply() had already shown the indicator at the target it's about to flee — left
|
|
160
|
+
// uncorrected, the indicator stayed pinned there for one extra press even though the vertex
|
|
161
|
+
// had already jumped clear, only catching up on the next press once querying from the
|
|
162
|
+
// escaped position genuinely found nothing.
|
|
163
|
+
test('hides the indicator when a nudge escapes the snap radius', () => {
|
|
164
|
+
const snap = snapReturning(() => [10, 0]) // snap holds the vertex in place
|
|
165
|
+
const { state, nudge } = setup({ snap })
|
|
166
|
+
Object.assign(state, { selectedVertexIndex: 1, selectedVertexType: 'vertex' })
|
|
167
|
+
nudge({ key: 'ArrowRight' })
|
|
168
|
+
expect(snap.hideIndicator).toHaveBeenCalled()
|
|
169
|
+
})
|
|
147
170
|
})
|
|
148
171
|
|
|
149
172
|
describe('resolveSnappedCoord', () => {
|
|
@@ -30,21 +30,22 @@ const handleTouchStart = (e, { map, targetEl, cssToOl, getState, drag }) => {
|
|
|
30
30
|
e.preventDefault()
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
const handleTouchMove = (e, { map, targetEl, olToCSS, getState, setState, snap, drag }) => {
|
|
33
|
+
const handleTouchMove = (e, { map, targetEl, olToCSS, getState, setState, snap, drag, moveCoord }) => {
|
|
34
34
|
if (!isOnTouchTarget(e.target) || drag.dragStartIndex == null) {
|
|
35
35
|
return
|
|
36
36
|
}
|
|
37
37
|
e.preventDefault()
|
|
38
38
|
const tOl = map.getEventPixel({ clientX: e.touches[0].clientX, clientY: e.touches[0].clientY })
|
|
39
39
|
const rawCoord = pixelToCoord(map, { x: tOl[0] - drag.vertexTouchDelta.x, y: tOl[1] - drag.vertexTouchDelta.y })
|
|
40
|
+
// snap.apply() already shows/hides the indicator based on whether a candidate was found.
|
|
40
41
|
const newCoord = snap ? snap.apply(rawCoord) : rawCoord
|
|
41
|
-
snap?.hideIndicator()
|
|
42
42
|
const { olFeature, vertices } = getState()
|
|
43
43
|
if (!olFeature) {
|
|
44
44
|
return
|
|
45
45
|
}
|
|
46
|
-
|
|
46
|
+
moveCoord(olFeature, drag.dragStartIndex, newCoord)
|
|
47
47
|
setState({ vertices: vertices.map((c, i) => i === drag.dragStartIndex ? newCoord : c) })
|
|
48
|
+
// Tracks the raw touch point, not newCoord — the vertex is what jumps to the snap candidate.
|
|
48
49
|
showTouchTarget(targetEl, olToCSS({ x: tOl[0] - drag.targetTouchDelta.x, y: tOl[1] - drag.targetTouchDelta.y }))
|
|
49
50
|
}
|
|
50
51
|
|
|
@@ -63,7 +64,7 @@ const handleTap = (e, { map, getState, onTap, drag }) => {
|
|
|
63
64
|
}
|
|
64
65
|
|
|
65
66
|
const handleTouchEnd = (e, ctx) => {
|
|
66
|
-
const { getState, onVertexMoved,
|
|
67
|
+
const { getState, onVertexMoved, drag, updateTargetPosition } = ctx
|
|
67
68
|
if (drag.dragStartIndex == null) {
|
|
68
69
|
handleTap(e, ctx)
|
|
69
70
|
drag.tapStart = null
|
|
@@ -74,8 +75,9 @@ const handleTouchEnd = (e, ctx) => {
|
|
|
74
75
|
if (vertices[drag.dragStartIndex] && drag.dragStartCoord) {
|
|
75
76
|
onVertexMoved({ vertexIndex: drag.dragStartIndex, previousCoord: drag.dragStartCoord })
|
|
76
77
|
}
|
|
77
|
-
|
|
78
|
+
// Not hiding the indicator here — it should stay showing after the drag ends.
|
|
78
79
|
drag.dragStartCoord = null; drag.dragStartIndex = null; drag.vertexTouchDelta = null; drag.targetTouchDelta = null
|
|
80
|
+
updateTargetPosition() // re-sync the target to the vertex's final position
|
|
79
81
|
e.preventDefault()
|
|
80
82
|
}
|
|
81
83
|
|
|
@@ -97,6 +99,8 @@ const wireTouchEvents = (deps) => {
|
|
|
97
99
|
container.addEventListener('touchstart', onTouchstart, { passive: false })
|
|
98
100
|
container.addEventListener('touchmove', onTouchmove, { passive: false })
|
|
99
101
|
container.addEventListener('touchend', onTouchend, { passive: false })
|
|
102
|
+
// touchcancel fires instead of touchend when the browser itself interrupts the gesture.
|
|
103
|
+
container.addEventListener('touchcancel', onTouchend, { passive: false })
|
|
100
104
|
|
|
101
105
|
return {
|
|
102
106
|
isDragging: () => drag.dragStartIndex != null,
|
|
@@ -104,6 +108,7 @@ const wireTouchEvents = (deps) => {
|
|
|
104
108
|
container.removeEventListener('touchstart', onTouchstart)
|
|
105
109
|
container.removeEventListener('touchmove', onTouchmove)
|
|
106
110
|
container.removeEventListener('touchend', onTouchend)
|
|
111
|
+
container.removeEventListener('touchcancel', onTouchend)
|
|
107
112
|
}
|
|
108
113
|
}
|
|
109
114
|
}
|
|
@@ -114,15 +119,16 @@ const wireTouchEvents = (deps) => {
|
|
|
114
119
|
* without finger occlusion. Tap on a vertex or midpoint selects it via onTap.
|
|
115
120
|
*
|
|
116
121
|
* @param {{ map, container, getState, setState, onVertexMoved, onTap, colors }} options
|
|
122
|
+
* @param {(olFeature, index: number, coord: number[]) => void} [options.moveCoord] - coordinate
|
|
123
|
+
* writer, defaulting to moveVertex; point/editPointMode.js injects point/pointOps.js's
|
|
124
|
+
* movePoint instead, since a Point has no ring index to address.
|
|
117
125
|
* @returns {{ updateTargetPosition, updateColors, hide, destroy }}
|
|
118
126
|
*/
|
|
119
|
-
export const createTouchHandler = ({ map, container, getState, setState, onVertexMoved, onTap, colors, snap }) => {
|
|
127
|
+
export const createTouchHandler = ({ map, container, getState, setState, onVertexMoved, onTap, colors, snap, moveCoord = moveVertex }) => {
|
|
120
128
|
const targetEl = createTouchTarget(container)
|
|
121
129
|
applyTouchTargetColors(targetEl, colors)
|
|
122
130
|
|
|
123
|
-
// OL pixel space
|
|
124
|
-
// Container CSS space is larger when a CSS transform scales up ol-viewport
|
|
125
|
-
// (e.g. scale(1.5) at medium map size makes OL pixels 1.5× smaller than CSS pixels).
|
|
131
|
+
// Converts between OL pixel space and CSS space, which differ when a CSS transform scales up ol-viewport.
|
|
126
132
|
const cssTx = { scale: 1, ox: 0, oy: 0 }
|
|
127
133
|
const olToCSS = (p) => ({ x: p.x * cssTx.scale + cssTx.ox, y: p.y * cssTx.scale + cssTx.oy })
|
|
128
134
|
const cssToOl = (p) => ({ x: (p.x - cssTx.ox) / cssTx.scale, y: (p.y - cssTx.oy) / cssTx.scale })
|
|
@@ -140,8 +146,6 @@ export const createTouchHandler = ({ map, container, getState, setState, onVerte
|
|
|
140
146
|
})
|
|
141
147
|
}
|
|
142
148
|
|
|
143
|
-
const touchEvents = wireTouchEvents({ container, map, targetEl, olToCSS, cssToOl, getState, setState, onVertexMoved, onTap, snap })
|
|
144
|
-
|
|
145
149
|
const updateTargetPosition = () => {
|
|
146
150
|
const { selectedVertexIndex, vertices, interfaceType } = getState()
|
|
147
151
|
if (selectedVertexIndex < 0 || !vertices[selectedVertexIndex] || interfaceType !== 'touch') {
|
|
@@ -156,8 +160,9 @@ export const createTouchHandler = ({ map, container, getState, setState, onVerte
|
|
|
156
160
|
showTouchTarget(targetEl, olToCSS(px))
|
|
157
161
|
}
|
|
158
162
|
|
|
159
|
-
|
|
160
|
-
|
|
163
|
+
const touchEvents = wireTouchEvents({ container, map, targetEl, olToCSS, cssToOl, getState, setState, onVertexMoved, onTap, snap, moveCoord, updateTargetPosition })
|
|
164
|
+
|
|
165
|
+
// Reposition on every render (skipped mid-drag, which handles position directly) to stay anchored during pinch-zoom and pan.
|
|
161
166
|
const onPostrender = () => {
|
|
162
167
|
const { selectedVertexIndex, interfaceType } = getState()
|
|
163
168
|
if (selectedVertexIndex >= 0 && !touchEvents.isDragging() && interfaceType === 'touch') {
|
|
@@ -70,6 +70,42 @@ test('the offset target hides when its vertex cannot be projected', () => {
|
|
|
70
70
|
handler.destroy()
|
|
71
71
|
})
|
|
72
72
|
|
|
73
|
+
// The offset target is the drag handle under your finger and must track it exactly, even
|
|
74
|
+
// while snap pulls the vertex itself elsewhere (mirrors the ML adapter) — the vertex is what
|
|
75
|
+
// visibly "jumps" to the snap candidate, not the target. Once the drag actually ends, the
|
|
76
|
+
// target re-syncs to the vertex's own final (possibly snapped) position, collapsing the gap.
|
|
77
|
+
test('the offset target tracks the raw touch point while dragging, then snaps to the vertex on release', () => {
|
|
78
|
+
const snap = { apply: jest.fn((c) => [c[0] + 5, c[1]]), hideIndicator: jest.fn() }
|
|
79
|
+
const { container, handler, touch } = setup({}, { snap })
|
|
80
|
+
handler.updateTargetPosition()
|
|
81
|
+
touch('touchstart', 100, 0)
|
|
82
|
+
touch('touchmove', 120, 10) // raw touch → [120,10]; vertex snaps to [125,10]
|
|
83
|
+
const target = container.querySelector('[data-im-draw-touch-target]')
|
|
84
|
+
expect(target.style.left).toBe('120px') // tracks the finger…
|
|
85
|
+
expect(target.style.left).not.toBe('125px') // …not the snapped vertex, while still dragging
|
|
86
|
+
|
|
87
|
+
touch('touchend', 120, 10)
|
|
88
|
+
expect(target.style.left).toBe('125px') // re-synced to the vertex's actual final position
|
|
89
|
+
handler.destroy()
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
// touchcancel (the browser interrupting a gesture itself — a scroll takeover, app switch,
|
|
93
|
+
// etc.) must resync the target exactly like touchend does — without this listener a
|
|
94
|
+
// cancelled drag left the target stuck wherever the last touchmove put it.
|
|
95
|
+
test('touchcancel resyncs the target the same way touchend does', () => {
|
|
96
|
+
const snap = { apply: jest.fn((c) => [c[0] + 5, c[1]]), hideIndicator: jest.fn() }
|
|
97
|
+
const { container, handler, touch, grip } = setup({}, { snap })
|
|
98
|
+
handler.updateTargetPosition()
|
|
99
|
+
touch('touchstart', 100, 0)
|
|
100
|
+
touch('touchmove', 120, 10) // raw touch → [120,10]; vertex snaps to [125,10]
|
|
101
|
+
const target = container.querySelector('[data-im-draw-touch-target]')
|
|
102
|
+
expect(target.style.left).toBe('120px') // tracking the finger mid-drag
|
|
103
|
+
|
|
104
|
+
grip.dispatchEvent(domEvent('touchcancel', { touches: [{ clientX: 120, clientY: 10 }], changedTouches: [{ clientX: 120, clientY: 10 }] }))
|
|
105
|
+
expect(target.style.left).toBe('125px') // re-synced to the vertex's actual final position
|
|
106
|
+
handler.destroy()
|
|
107
|
+
})
|
|
108
|
+
|
|
73
109
|
test('a drag applies snapping to the moved coordinate when a snap manager is active', () => {
|
|
74
110
|
const snap = { apply: jest.fn((c) => [c[0] + 5, c[1]]), hideIndicator: jest.fn() }
|
|
75
111
|
const { state, handler, touch } = setup({}, { snap })
|
|
@@ -77,8 +113,17 @@ test('a drag applies snapping to the moved coordinate when a snap manager is act
|
|
|
77
113
|
touch('touchstart', 100, 0)
|
|
78
114
|
touch('touchmove', 120, 10)
|
|
79
115
|
expect(snap.apply).toHaveBeenCalled()
|
|
80
|
-
expect(snap.hideIndicator).toHaveBeenCalled()
|
|
81
116
|
expect(state.vertices[1]).toEqual([125, 10]) // dragged to [120,10] then snapped +5 on x
|
|
117
|
+
|
|
118
|
+
// Regression: a stray hideIndicator() right after snap.apply() on every touchmove undid its
|
|
119
|
+
// own show, so the indicator could never actually be seen mid-drag — it's only meant to
|
|
120
|
+
// clear for real once the drag actually finishes.
|
|
121
|
+
expect(snap.hideIndicator).not.toHaveBeenCalled()
|
|
122
|
+
// And it must stay showing after the drag ends too — snap.apply()'s own last call already
|
|
123
|
+
// left it correctly reflecting the snapped position (mirrors the ML adapter, which never
|
|
124
|
+
// hides its own indicator on release either).
|
|
125
|
+
touch('touchend', 120, 10)
|
|
126
|
+
expect(snap.hideIndicator).not.toHaveBeenCalled()
|
|
82
127
|
handler.destroy()
|
|
83
128
|
})
|
|
84
129
|
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { OLDrawManager } from './core/OLDrawManager.js'
|
|
2
2
|
import { MAP_SIZE_SCALES } from './defaults.js'
|
|
3
|
+
import { refreshAllPointSymbols } from './point/pointSymbolImages.js'
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
|
-
* Creates the OLDrawManager, attaches it to mapProvider, and wires
|
|
6
|
-
* app-level events (MAP_SET_SIZE for scale-aware touch targets,
|
|
7
|
-
* MAP_SET_STYLE for dynamic color updates).
|
|
8
|
-
*
|
|
6
|
+
* Creates the OLDrawManager, attaches it to mapProvider, and wires app-level size/style events.
|
|
9
7
|
* @returns {{ manager: OLDrawManager, remove: () => void }}
|
|
10
8
|
*/
|
|
11
9
|
export const createOLDraw = ({ mapProvider, events, eventBus, pluginConfig = {}, mapStyle = null }) => {
|
|
@@ -18,13 +16,22 @@ export const createOLDraw = ({ mapProvider, events, eventBus, pluginConfig = {},
|
|
|
18
16
|
|
|
19
17
|
mapProvider.draw = manager
|
|
20
18
|
|
|
19
|
+
// Seed drawScale from the provider's own starting size — MAP_SET_SIZE only fires on a later runtime change, not the initial one.
|
|
20
|
+
mapProvider.drawScale = MAP_SIZE_SCALES[mapProvider.mapSize] ?? 1
|
|
21
|
+
|
|
22
|
+
// Nudges useHighlightSync to re-apply the highlight overlay — OL's own MAP_DATA_CHANGE is driven purely by basemap 'tileloadend', unrelated to the draw source.
|
|
23
|
+
const notifyPointSymbolsRefreshed = () => eventBus.emit(events.MAP_DATA_CHANGE)
|
|
24
|
+
|
|
21
25
|
const handleSetMapSize = (size) => {
|
|
22
26
|
mapProvider.drawScale = MAP_SIZE_SCALES[size] ?? 1
|
|
27
|
+
refreshAllPointSymbols({ manager, mapProvider }).then(notifyPointSymbolsRefreshed)
|
|
23
28
|
}
|
|
24
29
|
eventBus.on(events.MAP_SET_SIZE, handleSetMapSize)
|
|
25
30
|
|
|
26
31
|
const handleSetMapStyle = (newMapStyle) => {
|
|
27
32
|
manager.setMapStyle(newMapStyle)
|
|
33
|
+
// Rasterised point symbol images are style-scoped (colours resolve per map style).
|
|
34
|
+
refreshAllPointSymbols({ manager, mapProvider }).then(notifyPointSymbolsRefreshed)
|
|
28
35
|
}
|
|
29
36
|
eventBus.on(events.MAP_SET_STYLE, handleSetMapStyle)
|
|
30
37
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createOLDraw } from './olDraw.js'
|
|
2
2
|
import { OLDrawManager } from './core/OLDrawManager.js'
|
|
3
|
+
import { refreshAllPointSymbols } from './point/pointSymbolImages.js'
|
|
3
4
|
import { MAP_SIZE_SCALES } from './defaults.js'
|
|
4
5
|
|
|
5
6
|
jest.mock('./core/OLDrawManager.js', () => ({
|
|
@@ -8,15 +9,16 @@ jest.mock('./core/OLDrawManager.js', () => ({
|
|
|
8
9
|
this.remove = jest.fn()
|
|
9
10
|
})
|
|
10
11
|
}))
|
|
12
|
+
jest.mock('./point/pointSymbolImages.js', () => ({ refreshAllPointSymbols: jest.fn(() => Promise.resolve()) }))
|
|
11
13
|
|
|
12
|
-
const events = { MAP_SET_SIZE: 'app:size', MAP_SET_STYLE: 'app:style' }
|
|
14
|
+
const events = { MAP_SET_SIZE: 'app:size', MAP_SET_STYLE: 'app:style', MAP_DATA_CHANGE: 'app:datachange' }
|
|
13
15
|
|
|
14
16
|
const setup = (mapStyle = null) => {
|
|
15
17
|
const listeners = {}
|
|
16
18
|
const eventBus = {
|
|
17
19
|
on: jest.fn((type, handler) => { listeners[type] = handler }),
|
|
18
20
|
off: jest.fn(),
|
|
19
|
-
emit: (type, payload) => listeners[type]?.(payload)
|
|
21
|
+
emit: jest.fn((type, payload) => listeners[type]?.(payload))
|
|
20
22
|
}
|
|
21
23
|
const mapProvider = { map: { id: 'ol-map' } }
|
|
22
24
|
const olDraw = createOLDraw({ mapProvider, events, eventBus, pluginConfig: { snapRadius: 5 }, mapStyle })
|
|
@@ -35,14 +37,46 @@ test('creates the manager for the map, exposes it as mapProvider.draw and applie
|
|
|
35
37
|
expect(setup().manager.setMapStyle).not.toHaveBeenCalled() // no initial style
|
|
36
38
|
})
|
|
37
39
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
+
// Regression: MAP_SET_SIZE only ever fires from the map-size UI control being clicked at
|
|
41
|
+
// runtime, so a map that loads directly at medium/large left drawScale unset (defaulting to 1,
|
|
42
|
+
// i.e. small) until the user happened to change size — rasterising the first symbol placed at
|
|
43
|
+
// the wrong resolution. mapProvider.mapSize already holds the size the map actually loaded at.
|
|
44
|
+
test('seeds drawScale from the provider\'s own starting map size, before any size-change event', () => {
|
|
45
|
+
const eventBus = { on: jest.fn(), off: jest.fn() }
|
|
46
|
+
const mapProvider = { map: { id: 'ol-map' }, mapSize: 'large' }
|
|
47
|
+
createOLDraw({ mapProvider, events, eventBus })
|
|
48
|
+
expect(mapProvider.drawScale).toBe(MAP_SIZE_SCALES.large)
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
test('defaults the seeded drawScale to 1 when the provider has no starting map size', () => {
|
|
52
|
+
const eventBus = { on: jest.fn(), off: jest.fn() }
|
|
53
|
+
const mapProvider = { map: { id: 'ol-map' } }
|
|
54
|
+
createOLDraw({ mapProvider, events, eventBus })
|
|
55
|
+
expect(mapProvider.drawScale).toBe(1)
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
test('map size changes update the draw UI scale, defaulting to 1 for unknown sizes, and re-resolve point symbols', async () => {
|
|
59
|
+
const { eventBus, mapProvider, manager } = setup()
|
|
40
60
|
eventBus.emit(events.MAP_SET_SIZE, 'large')
|
|
41
61
|
expect(mapProvider.drawScale).toBe(MAP_SIZE_SCALES.large)
|
|
62
|
+
expect(refreshAllPointSymbols).toHaveBeenCalledWith({ manager, mapProvider })
|
|
42
63
|
eventBus.emit(events.MAP_SET_SIZE, 'enormous')
|
|
43
64
|
expect(mapProvider.drawScale).toBe(1)
|
|
44
65
|
})
|
|
45
66
|
|
|
67
|
+
// A selected point's highlight overlay only re-applies on MAP_DATA_CHANGE, and (unlike
|
|
68
|
+
// MapLibre) OL's own MAP_DATA_CHANGE is driven purely by basemap 'tileloadend' — nothing
|
|
69
|
+
// ties it to the draw VectorSource, so without this explicit nudge a resize/style change
|
|
70
|
+
// with no tiles loading would never re-trigger the highlight refresh at all, leaving an
|
|
71
|
+
// already-selected point's ring stuck on its old (now wrong-resolution) icon.
|
|
72
|
+
test('emits MAP_DATA_CHANGE once point symbols have actually finished re-resolving after a size change', async () => {
|
|
73
|
+
const { eventBus, manager, mapProvider } = setup()
|
|
74
|
+
eventBus.emit(events.MAP_SET_SIZE, 'large')
|
|
75
|
+
await Promise.resolve() // flush the refreshAllPointSymbols().then(...) microtask
|
|
76
|
+
expect(refreshAllPointSymbols).toHaveBeenCalledWith({ manager, mapProvider })
|
|
77
|
+
expect(eventBus.emit).toHaveBeenCalledWith(events.MAP_DATA_CHANGE)
|
|
78
|
+
})
|
|
79
|
+
|
|
46
80
|
test('pluginConfig and mapStyle are optional, defaulting to {} and no initial style', () => {
|
|
47
81
|
const eventBus = { on: jest.fn(), off: jest.fn() }
|
|
48
82
|
const mapProvider = { map: { id: 'ol-map' } }
|
|
@@ -54,10 +88,18 @@ test('pluginConfig and mapStyle are optional, defaulting to {} and no initial st
|
|
|
54
88
|
olDraw.remove()
|
|
55
89
|
})
|
|
56
90
|
|
|
57
|
-
test('map style changes are forwarded to the manager', () => {
|
|
58
|
-
const { eventBus, manager } = setup()
|
|
91
|
+
test('map style changes are forwarded to the manager and re-resolve point symbols', () => {
|
|
92
|
+
const { eventBus, manager, mapProvider } = setup()
|
|
59
93
|
eventBus.emit(events.MAP_SET_STYLE, { id: 'dark' })
|
|
60
94
|
expect(manager.setMapStyle).toHaveBeenCalledWith({ id: 'dark' })
|
|
95
|
+
expect(refreshAllPointSymbols).toHaveBeenCalledWith({ manager, mapProvider })
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
test('emits MAP_DATA_CHANGE once point symbols have actually finished re-resolving after a style change', async () => {
|
|
99
|
+
const { eventBus } = setup()
|
|
100
|
+
eventBus.emit(events.MAP_SET_STYLE, { id: 'dark' })
|
|
101
|
+
await Promise.resolve()
|
|
102
|
+
expect(eventBus.emit).toHaveBeenCalledWith(events.MAP_DATA_CHANGE)
|
|
61
103
|
})
|
|
62
104
|
|
|
63
105
|
test('remove unsubscribes, destroys the manager and clears mapProvider.draw', () => {
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import Draw from 'ol/interaction/Draw.js'
|
|
2
|
+
import { noModifierKeys } from 'ol/events/condition.js'
|
|
3
|
+
import { wireInputEvents, applyCrossHairVisibility } from '../draw/drawInput.js'
|
|
4
|
+
import { ADAPTER_EVENTS } from '../../../adapterEvents.js'
|
|
5
|
+
import { validatePlacement } from '../../../validation/validateGeometry.js'
|
|
6
|
+
import { TOLERANCES } from '../defaults.js'
|
|
7
|
+
|
|
8
|
+
const MODE = 'draw_point'
|
|
9
|
+
|
|
10
|
+
// A point has no ring/rubber-band to build a candidate from — just the coordinate about to
|
|
11
|
+
// be placed. Mirrors validateGeometry.js's attemptPlacement, but that helper hardcodes
|
|
12
|
+
// Polygon/LineString via MODE_BY_GEOMETRY, so a Point candidate is built and validated
|
|
13
|
+
// directly (same approach as the MapLibre adapter's drawPointMode.js).
|
|
14
|
+
const canPlaceVertex = (manager) => (coordinate) => {
|
|
15
|
+
const candidate = { type: 'Feature', geometry: { type: 'Point', coordinates: coordinate }, properties: {} }
|
|
16
|
+
const { valid, reason } = validatePlacement(
|
|
17
|
+
candidate,
|
|
18
|
+
{ mode: MODE, vertexIndex: 0 },
|
|
19
|
+
{ onGeometryChange: manager._geometryValidator }
|
|
20
|
+
)
|
|
21
|
+
if (!valid) {
|
|
22
|
+
manager.emit(ADAPTER_EVENTS.PLACEMENT_BLOCKED, { feature: candidate, reason: reason ?? null, phase: 'place', mode: MODE, vertexIndex: 0 })
|
|
23
|
+
}
|
|
24
|
+
return valid
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Commit a finished point to the store under the requested id and emit CREATE — mirrors
|
|
28
|
+
// draw/DrawMode.js's finalizeDrawnFeature (identical shape, kept separate rather than
|
|
29
|
+
// imported since draw/DrawMode.js isn't otherwise a shared dependency of this mode).
|
|
30
|
+
// Symbol resolution runs after the feature is in the store (not before), matching the
|
|
31
|
+
// MapLibre adapter's own ordering. The resolver itself is injected by OLDrawManager via
|
|
32
|
+
// changeMode's options (mirrors the ML adapter's state.resolvePointSymbol convention — see
|
|
33
|
+
// MaplibreDrawAdapter.js's changeMode) so this mode has no direct dependency on
|
|
34
|
+
// symbolRegistry/mapProvider/pointSymbolImages.js.
|
|
35
|
+
const finalizeDrawnFeature = (manager, resolvePointSymbol, olFeature, featureId, properties) => {
|
|
36
|
+
olFeature.setId(String(featureId))
|
|
37
|
+
olFeature.setProperties(properties)
|
|
38
|
+
manager.store.source.addFeature(olFeature)
|
|
39
|
+
manager.emit(ADAPTER_EVENTS.CREATE, manager.store.toGeoJSON(olFeature))
|
|
40
|
+
resolvePointSymbol?.(olFeature)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Touch/keyboard/"Add point" input for draw_point — the same concerns as
|
|
45
|
+
* draw/drawInput.js (crosshair, interface-type tracking, add-vertex-button/Enter), reused
|
|
46
|
+
* directly, but with a much smaller placement step: a point has no rubber band to update
|
|
47
|
+
* while positioning (the crosshair itself already shows where it'll land) and nothing to
|
|
48
|
+
* undo before a single-click commit, so those callbacks are no-ops here.
|
|
49
|
+
*/
|
|
50
|
+
const buildPointInput = ({ drawInteraction, options, canPlace }) => {
|
|
51
|
+
const { container, addVertexButtonId, mapProvider, snap, crossHair } = options
|
|
52
|
+
let interfaceType = options.interfaceType ?? 'mouse'
|
|
53
|
+
const getInterfaceType = () => interfaceType
|
|
54
|
+
|
|
55
|
+
// appendCoordinates() only builds up LineString/Polygon rings — for a Point-type Draw
|
|
56
|
+
// interaction it does nothing beyond starting the sketch (confirmed by reading OL's own
|
|
57
|
+
// source), so finishDrawing() has to be called explicitly right after to actually commit.
|
|
58
|
+
const placePoint = () => {
|
|
59
|
+
const raw = mapProvider.getCenter()
|
|
60
|
+
const coord = (getInterfaceType() !== 'mouse' && snap) ? snap.apply(raw) : raw
|
|
61
|
+
snap?.hideIndicator()
|
|
62
|
+
if (!canPlace(coord)) { return }
|
|
63
|
+
drawInteraction.appendCoordinates([coord])
|
|
64
|
+
drawInteraction.finishDrawing()
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Keeps the snap indicator visible at the crosshair while positioning via touch/keyboard
|
|
68
|
+
// (mouse hover is handled by the separate OL snap interaction already attached by
|
|
69
|
+
// OLDrawManager) — the closest point-shaped equivalent of updateRubberbanding.
|
|
70
|
+
const updateSnapIndicator = () => {
|
|
71
|
+
if (getInterfaceType() !== 'mouse' && snap) { snap.apply(mapProvider.getCenter()) }
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Mirrors draw/drawInput.js's createDrawInput: an interface-type switch to touch/keyboard
|
|
75
|
+
// must refresh the snap indicator immediately at the crosshair, not wait for the next
|
|
76
|
+
// pointermove/change:center — otherwise it stays hidden until the user first pans or drags
|
|
77
|
+
// after entering the mode (the same gap the MapLibre adapter's onInterfaceTypeChange already
|
|
78
|
+
// guards against by calling onMove(state) right after _setInterface).
|
|
79
|
+
const applyInterfaceType = (type) => {
|
|
80
|
+
interfaceType = type
|
|
81
|
+
applyCrossHairVisibility(crossHair, type)
|
|
82
|
+
updateSnapIndicator()
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const events = wireInputEvents({
|
|
86
|
+
container,
|
|
87
|
+
addVertexButtonId,
|
|
88
|
+
olView: drawInteraction.getMap()?.getView(),
|
|
89
|
+
onUndo: null,
|
|
90
|
+
getInterfaceType,
|
|
91
|
+
setInterfaceType: applyInterfaceType,
|
|
92
|
+
clearLastCoord: () => {},
|
|
93
|
+
updateRubberbanding: updateSnapIndicator,
|
|
94
|
+
placeVertex: placePoint
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
applyCrossHairVisibility(crossHair, interfaceType)
|
|
98
|
+
|
|
99
|
+
return {
|
|
100
|
+
getInterfaceType,
|
|
101
|
+
setInterfaceType: applyInterfaceType,
|
|
102
|
+
destroy () { events.destroy() }
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Draw mode for placing a single point: mouse click, or crosshair + Enter/"Add point"
|
|
108
|
+
* button for touch/keyboard. Commits immediately on the first placement — unlike
|
|
109
|
+
* draw_line/draw_polygon, there is no rubber band, no multi-vertex undo, and no "Done"
|
|
110
|
+
* step (mirrors the MapLibre adapter's drawPointMode.js decision).
|
|
111
|
+
*
|
|
112
|
+
* OL's own Draw({type:'Point'}) interaction already finishes a real mouse click
|
|
113
|
+
* immediately (confirmed by reading its handleUpEvent — mode 'Point' always attempts
|
|
114
|
+
* finishDrawing() on pointer-up, no second click needed), so the mouse path needs no
|
|
115
|
+
* extra wiring beyond the placement-veto condition every mode already has. Deliberately
|
|
116
|
+
* NOT built via draw/DrawMode.js's createDrawMode()/createVertexPlacement() — those are
|
|
117
|
+
* parametrised around a ring of placed vertices + a trailing rubber-band coordinate,
|
|
118
|
+
* which a single-click commit doesn't have (mirrors the same decision already made for
|
|
119
|
+
* the MapLibre adapter, and the OL EditMode/DrawMode split noted in
|
|
120
|
+
* feedback_adapter_parity.md: don't force point through machinery shaped for lines/polygons
|
|
121
|
+
* just because they happen to share a file).
|
|
122
|
+
*/
|
|
123
|
+
export const createDrawPointMode = ({ map, manager, options }) => {
|
|
124
|
+
const { featureId, properties = {} } = options
|
|
125
|
+
const canPlace = canPlaceVertex(manager)
|
|
126
|
+
|
|
127
|
+
const drawInteraction = new Draw({
|
|
128
|
+
type: 'Point',
|
|
129
|
+
// Without an explicit style, OL renders its own default sketch style (a blue circle)
|
|
130
|
+
// following the cursor before commit — core/styles.js's createSketchStyle() already
|
|
131
|
+
// suppresses this same default for the "ghost" Point sketch OL renders alongside a
|
|
132
|
+
// Polygon/LineString sketch (see its own comment); a real Point sketch needs the same
|
|
133
|
+
// treatment, since it commits on the very first click with nothing meaningful to preview.
|
|
134
|
+
style: () => [],
|
|
135
|
+
snapTolerance: TOLERANCES.snapRadius,
|
|
136
|
+
condition: (e) => noModifierKeys(e) && canPlace(e.coordinate)
|
|
137
|
+
})
|
|
138
|
+
map.addInteraction(drawInteraction)
|
|
139
|
+
|
|
140
|
+
drawInteraction.on('drawend', (e) => finalizeDrawnFeature(manager, options.resolvePointSymbol, e.feature, featureId, properties))
|
|
141
|
+
drawInteraction.on('drawabort', () => { manager.emit(ADAPTER_EVENTS.CANCEL) })
|
|
142
|
+
|
|
143
|
+
const input = buildPointInput({ drawInteraction, options, canPlace })
|
|
144
|
+
|
|
145
|
+
return {
|
|
146
|
+
done () {}, // no-op: commit is immediate, there's no pending sketch to finish
|
|
147
|
+
cancel () { drawInteraction.abortDrawing() },
|
|
148
|
+
undo () {}, // no-op: nothing placed yet to undo before commit
|
|
149
|
+
setInterfaceType (type) { input.setInterfaceType(type) },
|
|
150
|
+
destroy () {
|
|
151
|
+
manager.emit(ADAPTER_EVENTS.INTERFACE_TYPE_CHANGE, { interfaceType: input.getInterfaceType() })
|
|
152
|
+
input.destroy()
|
|
153
|
+
map.removeInteraction(drawInteraction)
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|