@defra/interactive-map 0.0.26-alpha → 0.0.28-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.
Files changed (105) hide show
  1. package/dist/css/index.css +1 -1
  2. package/dist/esm/im-core.js +1 -1
  3. package/dist/esm/im-shell.js +1 -1
  4. package/dist/umd/im-core.js +1 -1
  5. package/dist/umd/index.js +1 -1
  6. package/docs/assets/css/docusaurus.scss +4 -0
  7. package/package.json +1 -1
  8. package/plugins/beta/draw-ml/dist/esm/im-draw-ml-plugin.js +1 -1
  9. package/plugins/beta/draw-ml/dist/umd/im-draw-ml-plugin.js +1 -1
  10. package/plugins/beta/draw-ml/src/defaults.js +14 -14
  11. package/plugins/beta/draw-ml/src/mapboxDraw.js +5 -0
  12. package/plugins/beta/draw-ml/src/mapboxSnap.js +1 -1
  13. package/plugins/beta/draw-ml/src/modes/editVertex/touchHandlers.js +10 -2
  14. package/plugins/beta/draw-ml/src/modes/editVertexMode.js +2 -0
  15. package/plugins/beta/draw-ml/src/reducer.js +4 -1
  16. package/plugins/beta/draw-ml/src/styles.js +42 -39
  17. package/plugins/beta/draw-ol/dist/css/index.css +13 -0
  18. package/plugins/beta/draw-ol/dist/esm/DrawMode.js +1 -0
  19. package/plugins/beta/draw-ol/dist/esm/EditMode.js +1 -0
  20. package/plugins/beta/draw-ol/dist/esm/geometryHelpers.js +1 -0
  21. package/plugins/beta/draw-ol/dist/esm/im-draw-ol-plugin.js +1 -0
  22. package/plugins/beta/draw-ol/dist/esm/index.js +1 -0
  23. package/plugins/beta/draw-ol/src/DrawInit.jsx +67 -0
  24. package/plugins/beta/draw-ol/src/api/addFeature.js +29 -0
  25. package/plugins/beta/draw-ol/src/api/deleteFeature.js +11 -0
  26. package/plugins/beta/draw-ol/src/api/editFeature.js +50 -0
  27. package/plugins/beta/draw-ol/src/api/newLine.js +44 -0
  28. package/plugins/beta/draw-ol/src/api/newPolygon.js +44 -0
  29. package/plugins/beta/draw-ol/src/core/OLDrawManager.js +150 -0
  30. package/plugins/beta/draw-ol/src/core/featureStore.js +65 -0
  31. package/plugins/beta/draw-ol/src/core/styles.js +98 -0
  32. package/plugins/beta/draw-ol/src/core/undoStack.js +31 -0
  33. package/plugins/beta/draw-ol/src/defaults.js +16 -0
  34. package/plugins/beta/draw-ol/src/draw/DrawMode.js +113 -0
  35. package/plugins/beta/draw-ol/src/draw/drawInput.js +199 -0
  36. package/plugins/beta/draw-ol/src/draw.scss +17 -0
  37. package/plugins/beta/draw-ol/src/edit/EditMode.js +424 -0
  38. package/plugins/beta/draw-ol/src/edit/keyboardHandler.js +227 -0
  39. package/plugins/beta/draw-ol/src/edit/midpointLayer.js +57 -0
  40. package/plugins/beta/draw-ol/src/edit/touchHandler.js +171 -0
  41. package/plugins/beta/draw-ol/src/edit/undoOps.js +95 -0
  42. package/plugins/beta/draw-ol/src/edit/vertexHitTest.js +72 -0
  43. package/plugins/beta/draw-ol/src/edit/vertexLayer.js +49 -0
  44. package/plugins/beta/draw-ol/src/edit/vertexOps.js +99 -0
  45. package/plugins/beta/draw-ol/src/events.js +114 -0
  46. package/plugins/beta/draw-ol/src/index.js +12 -0
  47. package/plugins/beta/draw-ol/src/manifest.js +121 -0
  48. package/plugins/beta/draw-ol/src/olDraw.js +38 -0
  49. package/plugins/beta/draw-ol/src/reducer.js +41 -0
  50. package/plugins/beta/draw-ol/src/snap/snapEngine.js +109 -0
  51. package/plugins/beta/draw-ol/src/snap/snapGeometry.js +200 -0
  52. package/plugins/beta/draw-ol/src/snap/snapIndicator.js +81 -0
  53. package/plugins/beta/draw-ol/src/snap/snapInteraction.js +56 -0
  54. package/plugins/beta/draw-ol/src/snap/snapManager.js +90 -0
  55. package/plugins/beta/draw-ol/src/utils/flattenStyleProperties.js +47 -0
  56. package/plugins/beta/draw-ol/src/utils/geometryHelpers.js +97 -0
  57. package/plugins/beta/draw-ol/src/utils/olCoords.js +35 -0
  58. package/plugins/beta/draw-ol/src/utils/resolveColors.js +39 -0
  59. package/plugins/beta/draw-ol/src/utils/spatial.js +28 -0
  60. package/plugins/beta/draw-ol/src/utils/touchTarget.js +61 -0
  61. package/plugins/beta/map-styles/dist/esm/im-map-styles-plugin.js +1 -1
  62. package/plugins/beta/map-styles/dist/umd/im-map-styles-plugin.js +1 -1
  63. package/plugins/interact/dist/esm/im-interact-plugin.js +1 -1
  64. package/plugins/interact/dist/umd/im-interact-plugin.js +1 -1
  65. package/plugins/interact/src/defaults.js +1 -0
  66. package/plugins/interact/src/hooks/useInteractionHandlers.js +150 -43
  67. package/plugins/interact/src/hooks/useInteractionHandlers.test.js +240 -8
  68. package/plugins/interact/src/reducer.js +7 -0
  69. package/plugins/interact/src/reducer.test.js +16 -0
  70. package/providers/beta/openlayers/dist/esm/im-openlayers-provider.js +1 -1
  71. package/providers/beta/openlayers/dist/umd/im-openlayers-provider.js +1 -1
  72. package/providers/beta/openlayers/dist/umd/index.js +1 -1
  73. package/providers/beta/openlayers/src/appEvents.js +9 -13
  74. package/providers/beta/openlayers/src/appEvents.test.js +25 -17
  75. package/providers/beta/openlayers/src/mapEvents.js +32 -16
  76. package/providers/beta/openlayers/src/mapEvents.test.js +43 -10
  77. package/providers/beta/openlayers/src/openlayersProvider.js +45 -26
  78. package/providers/beta/openlayers/src/openlayersProvider.test.js +12 -34
  79. package/providers/beta/openlayers/src/utils/highlightFeatures.js +245 -0
  80. package/providers/beta/openlayers/src/utils/hoverCursor.js +65 -0
  81. package/providers/beta/openlayers/src/utils/hoverCursor.test.js +235 -0
  82. package/providers/beta/openlayers/src/utils/openLayersFixes.js +11 -0
  83. package/providers/beta/openlayers/src/utils/openLayersFixes.test.js +53 -0
  84. package/providers/beta/openlayers/src/utils/queryFeatures.js +77 -0
  85. package/providers/beta/openlayers/src/utils/queryFeatures.test.js +181 -0
  86. package/providers/beta/openlayers/src/utils/tileLayers.js +19 -1
  87. package/providers/beta/openlayers/src/utils/tileLayers.test.js +74 -3
  88. package/providers/beta/openlayers/src/utils/vtTileFragments.js +86 -0
  89. package/rollup.esm.mjs +6 -0
  90. package/src/App/components/Hints/Hints.test.jsx +2 -2
  91. package/src/App/components/PopupMenu/PopupMenu.module.scss +6 -0
  92. package/src/App/controls/keyboardActions.js +2 -2
  93. package/src/App/controls/keyboardMappings.js +1 -2
  94. package/src/App/controls/keyboardShortcuts.js +5 -3
  95. package/src/App/controls/keyboardShortcuts.test.js +24 -0
  96. package/src/InteractiveMap/InteractiveMap.js +38 -10
  97. package/src/InteractiveMap/InteractiveMap.test.js +282 -356
  98. package/src/InteractiveMap/deviceChecker.js +3 -2
  99. package/src/InteractiveMap/deviceChecker.test.js +7 -10
  100. package/src/InteractiveMap/historyManager.js +7 -0
  101. package/src/InteractiveMap/historyManager.test.js +11 -0
  102. package/src/config/defaults.js +1 -1
  103. package/src/utils/htmlToPlainText.js +11 -0
  104. package/src/utils/htmlToPlainText.test.js +5 -0
  105. package/webpack.dev.mjs +3 -1
@@ -1,5 +1,6 @@
1
1
  import { renderError } from './renderError.js'
2
2
  import { removeLoadingState } from './domStateManager.js'
3
+ import { logger } from '../services/logger.js'
3
4
 
4
5
  /**
5
6
  * Checks if the current device is supported by the map provider.
@@ -18,14 +19,14 @@ export function checkDeviceSupport (rootEl, config) {
18
19
  const device = mapProvider?.checkDeviceCapabilities()
19
20
 
20
21
  if (!mapProvider) {
21
- console.log('No map provider')
22
+ logger.warn('No map provider')
22
23
  return false
23
24
  }
24
25
 
25
26
  if (!device?.isSupported) {
26
27
  renderError(rootEl, deviceNotSupportedText)
27
28
  removeLoadingState()
28
- console.log(device?.error)
29
+ logger.warn(device?.error)
29
30
  return false
30
31
  }
31
32
  return true
@@ -1,23 +1,20 @@
1
1
  import { checkDeviceSupport } from './deviceChecker.js'
2
2
  import { renderError } from './renderError.js'
3
3
  import { removeLoadingState } from './domStateManager.js'
4
+ import { logger } from '../services/logger.js'
4
5
 
5
6
  jest.mock('./renderError.js')
6
7
  jest.mock('./domStateManager.js')
8
+ jest.mock('../services/logger.js', () => ({ logger: { warn: jest.fn() } }))
7
9
 
8
10
  describe('checkDeviceSupport', () => {
9
- let rootEl, config, consoleLogSpy
11
+ let rootEl, config
10
12
 
11
13
  beforeEach(() => {
12
14
  rootEl = document.createElement('div')
13
- consoleLogSpy = jest.spyOn(console, 'log').mockImplementation()
14
15
  jest.clearAllMocks()
15
16
  })
16
17
 
17
- afterEach(() => {
18
- consoleLogSpy.mockRestore()
19
- })
20
-
21
18
  it('returns true when device is supported', () => {
22
19
  config = {
23
20
  mapProvider: {
@@ -29,7 +26,7 @@ describe('checkDeviceSupport', () => {
29
26
  expect(checkDeviceSupport(rootEl, config)).toBe(true)
30
27
  expect(renderError).not.toHaveBeenCalled()
31
28
  expect(removeLoadingState).not.toHaveBeenCalled()
32
- expect(console.log).not.toHaveBeenCalled()
29
+ expect(logger.warn).not.toHaveBeenCalled()
33
30
  })
34
31
 
35
32
  it('returns false and shows error when device is not supported', () => {
@@ -46,7 +43,7 @@ describe('checkDeviceSupport', () => {
46
43
  expect(checkDeviceSupport(rootEl, config)).toBe(false)
47
44
  expect(renderError).toHaveBeenCalledWith(rootEl, 'Device not supported')
48
45
  expect(removeLoadingState).toHaveBeenCalled()
49
- expect(console.log).toHaveBeenCalledWith('WebGL not available')
46
+ expect(logger.warn).toHaveBeenCalledWith('WebGL not available')
50
47
  })
51
48
 
52
49
  it('logs "No map provider" and returns false if mapProvider is missing', () => {
@@ -56,7 +53,7 @@ describe('checkDeviceSupport', () => {
56
53
  }
57
54
 
58
55
  expect(checkDeviceSupport(rootEl, config)).toBe(false)
59
- expect(console.log).toHaveBeenCalledWith('No map provider')
56
+ expect(logger.warn).toHaveBeenCalledWith('No map provider')
60
57
  expect(renderError).not.toHaveBeenCalled()
61
58
  expect(removeLoadingState).not.toHaveBeenCalled()
62
59
  })
@@ -72,6 +69,6 @@ describe('checkDeviceSupport', () => {
72
69
  expect(checkDeviceSupport(rootEl, config)).toBe(false)
73
70
  expect(renderError).toHaveBeenCalledWith(rootEl, 'Device not supported')
74
71
  expect(removeLoadingState).toHaveBeenCalled()
75
- expect(console.log).toHaveBeenCalledWith(undefined)
72
+ expect(logger.warn).toHaveBeenCalledWith(undefined)
76
73
  })
77
74
  })
@@ -51,6 +51,8 @@ function syncMapInstance (mapInstance, viewId) {
51
51
  return
52
52
  }
53
53
 
54
+ mapInstance._isClosingViaBack = false
55
+
54
56
  const shouldBeOpen = mapInstance.id === viewId
55
57
  const isHybridVisible = mapInstance.config.behaviour === 'hybrid' && !isHybridFullscreen(mapInstance.config)
56
58
  const isOpen = mapInstance.rootEl?.children.length
@@ -134,6 +136,11 @@ function register (component) {
134
136
  */
135
137
  function unregister (component) {
136
138
  components.delete(component.id)
139
+
140
+ if (components.size === 0) {
141
+ globalThis.removeEventListener('popstate', handlePopstate)
142
+ initialized = false
143
+ }
137
144
  }
138
145
 
139
146
  // -----------------------------------------------------------------------------
@@ -168,4 +168,15 @@ describe('historyManager', () => {
168
168
 
169
169
  expect(component1.loadApp).not.toHaveBeenCalled()
170
170
  })
171
+
172
+ it('removes popstate listener and resets initialized when last component is unregistered', () => {
173
+ const removeListenerSpy = jest.spyOn(window, 'removeEventListener')
174
+ jest.isolateModules(() => {
175
+ const freshManager = require('./historyManager.js').default
176
+ freshManager.register(component1)
177
+ freshManager.unregister(component1)
178
+ expect(removeListenerSpy).toHaveBeenCalledWith('popstate', expect.any(Function))
179
+ })
180
+ removeListenerSpy.mockRestore()
181
+ })
171
182
  })
@@ -20,7 +20,7 @@ const defaults = {
20
20
  genericErrorText: 'There was a problem loading the map. Please try again later.',
21
21
  hasExitButton: false,
22
22
  hybridWidth: null, // Defaults to maxMobileWidth if not set
23
- keyboardHintText: '<span class="im-u-visually-hidden">Press </span><kbd>Alt</kbd> + <kbd>K</kbd> <span class="im-u-visually-hidden">to view </span>keyboard shortcuts',
23
+ keyboardHintText: '<span class="im-u-visually-hidden">Press </span><kbd>Shift</kbd> + <kbd>?</kbd> <span class="im-u-visually-hidden">to view </span>keyboard shortcuts',
24
24
  mapLabel: 'Interactive map application',
25
25
  mapProvider: null,
26
26
  mapSize: 'small',
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Strips HTML tags from a string and returns plain text.
3
+ * Collapses runs of two or more whitespace characters into a single space,
4
+ * while preserving intentional single spaces between words.
5
+ * @param {string} htmlString - A string containing HTML markup.
6
+ * @returns {string} The extracted text content with normalised whitespace.
7
+ */
8
+ export const htmlToPlainText = (htmlString) => {
9
+ const doc = new DOMParser().parseFromString(htmlString, 'text/html')
10
+ return doc.body.textContent.replace(/\s{2,}/g, ' ').trim()
11
+ }
@@ -0,0 +1,5 @@
1
+ import { htmlToPlainText } from './htmlToPlainText'
2
+
3
+ it('strips HTML and normalises whitespace', () => {
4
+ expect(htmlToPlainText('<p> Hello <strong>world</strong> </p>')).toBe('Hello world')
5
+ })
package/webpack.dev.mjs CHANGED
@@ -19,10 +19,12 @@ export default {
19
19
  entry: {
20
20
  index: path.join(__dirname, 'demo/js/index.js'),
21
21
  draw: path.join(__dirname, 'demo/js/draw.js'),
22
+ 'draw-ol': path.join(__dirname, 'demo/js/draw-ol.js'),
22
23
  farming: path.join(__dirname, 'demo/js/farming.js'),
23
24
  planning: path.join(__dirname, 'demo/js/planning.js'),
24
25
  'planning-ol': path.join(__dirname, 'demo/js/planning-ol.js'),
25
- gep: path.join(__dirname, 'demo/js/gep.js')
26
+ gep: path.join(__dirname, 'demo/js/gep.js'),
27
+ multimap: path.join(__dirname, 'demo/js/multimap.js')
26
28
  },
27
29
  output: {
28
30
  path: path.resolve(__dirname, 'public'),