From 17a620a28a3739930f494157d808d6e6ff7d9e9e Mon Sep 17 00:00:00 2001 From: Andy Sellick Date: Thu, 10 Sep 2026 14:06:03 +0100 Subject: [PATCH 1/9] Install importmaps - should be automatically included in Rails 7+, but seems like it needs to be installed manually - ran command `bundle add importmap-rails` --- Gemfile | 1 + Gemfile.lock | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/Gemfile b/Gemfile index 9d14cb216f..6632aa3f84 100644 --- a/Gemfile +++ b/Gemfile @@ -15,6 +15,7 @@ gem "govuk_personalisation" gem "govuk_publishing_components" gem "govuk_web_banners" gem "htmlentities" +gem "importmap-rails", "~> 2.2" gem "plek" gem "rack-utf8_sanitizer" gem "rails-i18n" diff --git a/Gemfile.lock b/Gemfile.lock index 890bb9dbe4..6e2c989d94 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -247,6 +247,10 @@ GEM rainbow (>= 2.2.2, < 4.0) ruby-progressbar (~> 1.8, >= 1.8.1) terminal-table (>= 1.5.1) + importmap-rails (2.2.3) + actionpack (>= 6.0.0) + activesupport (>= 6.0.0) + railties (>= 6.0.0) io-console (0.9.2) irb (1.18.0) pp (>= 0.6.0) @@ -796,6 +800,7 @@ DEPENDENCIES govuk_web_banners htmlentities i18n-coverage + importmap-rails (~> 2.2) listen pact (~> 1.67) pact_broker-client From 3e167bc908cb019ae80c6dd20105db53397fbbb5 Mon Sep 17 00:00:00 2001 From: Andy Sellick Date: Thu, 10 Sep 2026 14:09:32 +0100 Subject: [PATCH 2/9] Install importmap - ran command `./bin/rails importmap:install` - the result is probably wrong for our config, but keeping this in a separate commit for clarity before reconfiguring - critically it failed to add anything to the application layout file, which we probably need to address in the layout component --- app/assets/config/manifest.js | 2 ++ app/javascript/application.js | 1 + bin/importmap | 4 ++++ config/importmap.rb | 3 +++ vendor/javascript/.keep | 0 5 files changed, 10 insertions(+) create mode 100644 app/javascript/application.js create mode 100755 bin/importmap create mode 100644 config/importmap.rb create mode 100644 vendor/javascript/.keep diff --git a/app/assets/config/manifest.js b/app/assets/config/manifest.js index bf7d828eb8..59d9da175e 100644 --- a/app/assets/config/manifest.js +++ b/app/assets/config/manifest.js @@ -13,3 +13,5 @@ //= link static-error-pages.js //= link_tree ../builds +//= link_tree ../../javascript .js +//= link_tree ../../../vendor/javascript .js diff --git a/app/javascript/application.js b/app/javascript/application.js new file mode 100644 index 0000000000..beff742ec3 --- /dev/null +++ b/app/javascript/application.js @@ -0,0 +1 @@ +// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails diff --git a/bin/importmap b/bin/importmap new file mode 100755 index 0000000000..36502ab16c --- /dev/null +++ b/bin/importmap @@ -0,0 +1,4 @@ +#!/usr/bin/env ruby + +require_relative "../config/application" +require "importmap/commands" diff --git a/config/importmap.rb b/config/importmap.rb new file mode 100644 index 0000000000..0086a327b8 --- /dev/null +++ b/config/importmap.rb @@ -0,0 +1,3 @@ +# Pin npm packages by running ./bin/importmap + +pin "application" diff --git a/vendor/javascript/.keep b/vendor/javascript/.keep new file mode 100644 index 0000000000..e69de29bb2 From 51f7828eef891219db7d07c1c66bd025aed46dd2 Mon Sep 17 00:00:00 2001 From: Andy Sellick Date: Fri, 11 Sep 2026 08:27:09 +0100 Subject: [PATCH 3/9] WIP --- app/assets/config/manifest.js | 6 ++++-- app/assets/javascripts/components/map.js | 7 +++++-- app/views/components/_map.html.erb | 3 +-- config/importmap.rb | 5 ++++- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/app/assets/config/manifest.js b/app/assets/config/manifest.js index 59d9da175e..91d628fe34 100644 --- a/app/assets/config/manifest.js +++ b/app/assets/config/manifest.js @@ -13,5 +13,7 @@ //= link static-error-pages.js //= link_tree ../builds -//= link_tree ../../javascript .js -//= link_tree ../../../vendor/javascript .js + +//= link @defra/interactive-map/dist/esm/index.js +//= link @defra/interactive-map/providers/maplibre/dist/esm/index.js +//= link @defra/interactive-map/plugins/interact/dist/esm/index.js diff --git a/app/assets/javascripts/components/map.js b/app/assets/javascripts/components/map.js index 44ad076924..fb2bc816f5 100644 --- a/app/assets/javascripts/components/map.js +++ b/app/assets/javascripts/components/map.js @@ -2,6 +2,9 @@ window.GOVUK = window.GOVUK || {} window.GOVUK.Modules = window.GOVUK.Modules || {}; +import InteractiveMap from '@defra/interactive-map' +import maplibreProvider from '@defra/interactive-map/providers/maplibre' + (function (Modules) { class Map { constructor ($module) { @@ -15,7 +18,7 @@ window.GOVUK.Modules = window.GOVUK.Modules || {}; }) const config = { - mapProvider: defra.maplibreProvider({ workerUrl: cspWorker }), + mapProvider: maplibreProvider({ workerUrl: cspWorker }), behaviour: 'inline', mapStyle: { url: window.GOVUK.mapComponentStyles, @@ -54,7 +57,7 @@ window.GOVUK.Modules = window.GOVUK.Modules || {}; this.map_element.setAttribute('id', id) this.map_element.classList.add('app-c-map--enabled') - this.map = new defra.InteractiveMap(this.map_id, this.config) + this.map = new InteractiveMap(this.map_id, this.config) /* istanbul ignore next */ this.map.on('map:ready', () => { diff --git a/app/views/components/_map.html.erb b/app/views/components/_map.html.erb index 0e3b1afc13..f95bfe03dc 100644 --- a/app/views/components/_map.html.erb +++ b/app/views/components/_map.html.erb @@ -37,6 +37,7 @@ @include_script ||= OpenStruct.new(script_included: false) %> <% if heading_text && ((map_config[:center] && map_config[:zoom]) || (markers || !geojson.nil?)) %> + <%= javascript_importmap_tags %> <%= render "govuk_publishing_components/components/heading", heading_obj %> <% if description %> <%= render "govuk_publishing_components/components/govspeak", {} do %> @@ -64,9 +65,7 @@ <% end %> <% unless @include_script[:script_included] %> - <%= javascript_include_tag "components/map/defra-map.js", integrity: false %> <%= javascript_include_tag "components/map.js", integrity: false, type: "module" %> - <%= javascript_include_tag "components/map/map-style-liberty.js", integrity: false %> <% @include_script[:script_included] = true %> <% end %> diff --git a/config/importmap.rb b/config/importmap.rb index 0086a327b8..e63002b226 100644 --- a/config/importmap.rb +++ b/config/importmap.rb @@ -1,3 +1,6 @@ # Pin npm packages by running ./bin/importmap -pin "application" +pin "@defra/interactive-map", to: "@defra/interactive-map/dist/esm/index.js" +pin "@defra/interactive-map/providers/maplibre", to: "@defra/interactive-map/providers/maplibre/dist/esm/index.js" +pin "@defra/interactive-map/plugins/interact", to: "@defra/interactive-map/plugins/interact/dist/esm/index.js" +pin "components/map", to: "components/map.js" From e0485e3a72b52f3263c196181a051644979692b9 Mon Sep 17 00:00:00 2001 From: Andy Sellick Date: Fri, 11 Sep 2026 08:42:47 +0100 Subject: [PATCH 4/9] WIP --- config/importmap.rb | 9 ++++++--- config/initializers/assets.rb | 3 +++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/config/importmap.rb b/config/importmap.rb index e63002b226..c1d13706be 100644 --- a/config/importmap.rb +++ b/config/importmap.rb @@ -1,6 +1,9 @@ # Pin npm packages by running ./bin/importmap -pin "@defra/interactive-map", to: "@defra/interactive-map/dist/esm/index.js" -pin "@defra/interactive-map/providers/maplibre", to: "@defra/interactive-map/providers/maplibre/dist/esm/index.js" -pin "@defra/interactive-map/plugins/interact", to: "@defra/interactive-map/plugins/interact/dist/esm/index.js" +# Pin the default entry point required by javascript_importmap_tags +pin "application", preload: true + +pin "@defra/interactive-map", to: "./node_modules/@defra/interactive-map/dist/esm/index.js" +pin "@defra/interactive-map/providers/maplibre", to: "./node_modules/@defra/interactive-map/providers/maplibre/dist/esm/index.js" +pin "@defra/interactive-map/plugins/interact", to: "./node_modules/@defra/interactive-map/plugins/interact/dist/esm/index.js" pin "components/map", to: "components/map.js" diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb index ded865c00f..269577447a 100644 --- a/config/initializers/assets.rb +++ b/config/initializers/assets.rb @@ -6,3 +6,6 @@ # Add additional assets to the asset load path. # Add Yarn node_modules folder to the asset load path. Rails.application.config.assets.paths << Rails.root.join("node_modules") + +# Precompile map.js independently so it can be fetched directly by the importmap +Rails.application.config.assets.precompile += %w( components/map.js ) From 1b493bc2b2c34c10e8b9493efaaf650b291e4d5d Mon Sep 17 00:00:00 2001 From: Andy Sellick Date: Fri, 11 Sep 2026 09:09:24 +0100 Subject: [PATCH 5/9] WIP --- app/javascript/components/map/defra.js | 5 +++++ app/javascript/components/map/maplibre.js | 2 ++ app/views/components/_map.html.erb | 1 - config/importmap.rb | 6 +++--- config/initializers/assets.rb | 2 ++ 5 files changed, 12 insertions(+), 4 deletions(-) create mode 100644 app/javascript/components/map/defra.js create mode 100644 app/javascript/components/map/maplibre.js diff --git a/app/javascript/components/map/defra.js b/app/javascript/components/map/defra.js new file mode 100644 index 0000000000..2be22dee28 --- /dev/null +++ b/app/javascript/components/map/defra.js @@ -0,0 +1,5 @@ +//= require @defra/interactive-map/dist/esm/index.js +// im-core.js +// im-shell.js + +// require @defra/interactive-map/dist/umd/index.js diff --git a/app/javascript/components/map/maplibre.js b/app/javascript/components/map/maplibre.js new file mode 100644 index 0000000000..54434292c8 --- /dev/null +++ b/app/javascript/components/map/maplibre.js @@ -0,0 +1,2 @@ +//= require @defra/interactive-map/providers/maplibre/dist/esm/index.js +// im-maplibre-provider.js diff --git a/app/views/components/_map.html.erb b/app/views/components/_map.html.erb index f95bfe03dc..a8eb0f0cf9 100644 --- a/app/views/components/_map.html.erb +++ b/app/views/components/_map.html.erb @@ -37,7 +37,6 @@ @include_script ||= OpenStruct.new(script_included: false) %> <% if heading_text && ((map_config[:center] && map_config[:zoom]) || (markers || !geojson.nil?)) %> - <%= javascript_importmap_tags %> <%= render "govuk_publishing_components/components/heading", heading_obj %> <% if description %> <%= render "govuk_publishing_components/components/govspeak", {} do %> diff --git a/config/importmap.rb b/config/importmap.rb index c1d13706be..d2a3b20abd 100644 --- a/config/importmap.rb +++ b/config/importmap.rb @@ -3,7 +3,7 @@ # Pin the default entry point required by javascript_importmap_tags pin "application", preload: true -pin "@defra/interactive-map", to: "./node_modules/@defra/interactive-map/dist/esm/index.js" -pin "@defra/interactive-map/providers/maplibre", to: "./node_modules/@defra/interactive-map/providers/maplibre/dist/esm/index.js" -pin "@defra/interactive-map/plugins/interact", to: "./node_modules/@defra/interactive-map/plugins/interact/dist/esm/index.js" +pin "@defra/interactive-map", to: "components/map/defra.js" +pin "@defra/interactive-map/providers/maplibre", to: "components/map/maplibre.js" +# pin "@defra/interactive-map/plugins/interact", to: "./node_modules/@defra/interactive-map/plugins/interact/dist/esm/index.js" pin "components/map", to: "components/map.js" diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb index 269577447a..7d988cc8bd 100644 --- a/config/initializers/assets.rb +++ b/config/initializers/assets.rb @@ -9,3 +9,5 @@ # Precompile map.js independently so it can be fetched directly by the importmap Rails.application.config.assets.precompile += %w( components/map.js ) +Rails.application.config.assets.precompile += %w( components/map/defra.js ) +Rails.application.config.assets.precompile += %w( components/map/maplibre.js ) From fa0f880400d5f0fb4185eddd6b122ad01cfb0163 Mon Sep 17 00:00:00 2001 From: Andy Sellick Date: Fri, 11 Sep 2026 09:40:59 +0100 Subject: [PATCH 6/9] WIP include all dependencies --- app/javascript/components/map/defra.js | 4 ++-- config/importmap.rb | 5 +++++ config/initializers/assets.rb | 3 +++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/app/javascript/components/map/defra.js b/app/javascript/components/map/defra.js index 2be22dee28..4c56e41794 100644 --- a/app/javascript/components/map/defra.js +++ b/app/javascript/components/map/defra.js @@ -1,5 +1,5 @@ //= require @defra/interactive-map/dist/esm/index.js -// im-core.js -// im-shell.js +//= require @defra/interactive-map/dist/esm/im-core.js +//= require @defra/interactive-map/dist/esm/im-shell.js // require @defra/interactive-map/dist/umd/index.js diff --git a/config/importmap.rb b/config/importmap.rb index d2a3b20abd..a702422fec 100644 --- a/config/importmap.rb +++ b/config/importmap.rb @@ -7,3 +7,8 @@ pin "@defra/interactive-map/providers/maplibre", to: "components/map/maplibre.js" # pin "@defra/interactive-map/plugins/interact", to: "./node_modules/@defra/interactive-map/plugins/interact/dist/esm/index.js" pin "components/map", to: "components/map.js" + +# try to avoid errors relating to babel, which is referenced by the defra ESM code +pin "@babel/runtime/helpers/asyncToGenerator", to: "@babel/runtime/helpers/asyncToGenerator.js" +pin "@babel/runtime/helpers/defineProperty", to: "@babel/runtime/helpers/defineProperty.js" +pin "@babel/runtime/helpers/objectWithoutProperties", to: "@babel/runtime/helpers/objectWithoutProperties.js" diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb index 7d988cc8bd..be94bf3c4b 100644 --- a/config/initializers/assets.rb +++ b/config/initializers/assets.rb @@ -11,3 +11,6 @@ Rails.application.config.assets.precompile += %w( components/map.js ) Rails.application.config.assets.precompile += %w( components/map/defra.js ) Rails.application.config.assets.precompile += %w( components/map/maplibre.js ) +Rails.application.config.assets.precompile += %w( @babel/runtime/helpers/asyncToGenerator.js ) +Rails.application.config.assets.precompile += %w( @babel/runtime/helpers/defineProperty.js ) +Rails.application.config.assets.precompile += %w( @babel/runtime/helpers/objectWithoutProperties.js ) From 915b74ec57368381a37e0871882e97a114e367ad Mon Sep 17 00:00:00 2001 From: Andy Sellick Date: Fri, 11 Sep 2026 10:14:31 +0100 Subject: [PATCH 7/9] WIP split out more JS due to namespace conflicts --- app/javascript/components/map/defra-im-core.js | 1 + app/javascript/components/map/defra-im-shell.js | 1 + app/javascript/components/map/defra-index.js | 1 + app/javascript/components/map/defra.js | 5 ----- 4 files changed, 3 insertions(+), 5 deletions(-) create mode 100644 app/javascript/components/map/defra-im-core.js create mode 100644 app/javascript/components/map/defra-im-shell.js create mode 100644 app/javascript/components/map/defra-index.js delete mode 100644 app/javascript/components/map/defra.js diff --git a/app/javascript/components/map/defra-im-core.js b/app/javascript/components/map/defra-im-core.js new file mode 100644 index 0000000000..ccb1043ad7 --- /dev/null +++ b/app/javascript/components/map/defra-im-core.js @@ -0,0 +1 @@ +//= require @defra/interactive-map/dist/esm/im-core.js diff --git a/app/javascript/components/map/defra-im-shell.js b/app/javascript/components/map/defra-im-shell.js new file mode 100644 index 0000000000..db9ad7afa8 --- /dev/null +++ b/app/javascript/components/map/defra-im-shell.js @@ -0,0 +1 @@ +//= require @defra/interactive-map/dist/esm/im-shell.js diff --git a/app/javascript/components/map/defra-index.js b/app/javascript/components/map/defra-index.js new file mode 100644 index 0000000000..085dc92e45 --- /dev/null +++ b/app/javascript/components/map/defra-index.js @@ -0,0 +1 @@ +//= require @defra/interactive-map/dist/esm/index.js diff --git a/app/javascript/components/map/defra.js b/app/javascript/components/map/defra.js deleted file mode 100644 index 4c56e41794..0000000000 --- a/app/javascript/components/map/defra.js +++ /dev/null @@ -1,5 +0,0 @@ -//= require @defra/interactive-map/dist/esm/index.js -//= require @defra/interactive-map/dist/esm/im-core.js -//= require @defra/interactive-map/dist/esm/im-shell.js - -// require @defra/interactive-map/dist/umd/index.js From fa98974d4160bb30d1cbca7f9057c79d8a2d228a Mon Sep 17 00:00:00 2001 From: Andy Sellick Date: Mon, 14 Sep 2026 15:23:29 +0100 Subject: [PATCH 8/9] WIP - some progress, sort of - specifically had to rename files to match their counterparts that they `require` - but still not working properly --- app/assets/config/manifest.js | 4 - .../components/map/asyncToGenerator.js | 1 + .../components/map/defineProperty.js | 1 + .../map/{defra-im-core.js => im-core.js} | 0 .../map/{defra-im-shell.js => im-shell.js} | 0 .../map/{defra-index.js => index.js} | 0 app/javascript/components/map/map.js | 196 ++++++++++++++++++ .../components/map/objectWithoutProperties.js | 1 + app/views/components/_map.html.erb | 3 +- config/importmap.rb | 18 +- config/initializers/assets.rb | 14 +- 11 files changed, 223 insertions(+), 15 deletions(-) create mode 100644 app/javascript/components/map/asyncToGenerator.js create mode 100644 app/javascript/components/map/defineProperty.js rename app/javascript/components/map/{defra-im-core.js => im-core.js} (100%) rename app/javascript/components/map/{defra-im-shell.js => im-shell.js} (100%) rename app/javascript/components/map/{defra-index.js => index.js} (100%) create mode 100644 app/javascript/components/map/map.js create mode 100644 app/javascript/components/map/objectWithoutProperties.js diff --git a/app/assets/config/manifest.js b/app/assets/config/manifest.js index 91d628fe34..bf7d828eb8 100644 --- a/app/assets/config/manifest.js +++ b/app/assets/config/manifest.js @@ -13,7 +13,3 @@ //= link static-error-pages.js //= link_tree ../builds - -//= link @defra/interactive-map/dist/esm/index.js -//= link @defra/interactive-map/providers/maplibre/dist/esm/index.js -//= link @defra/interactive-map/plugins/interact/dist/esm/index.js diff --git a/app/javascript/components/map/asyncToGenerator.js b/app/javascript/components/map/asyncToGenerator.js new file mode 100644 index 0000000000..7e8c963e6e --- /dev/null +++ b/app/javascript/components/map/asyncToGenerator.js @@ -0,0 +1 @@ +//= require @babel/runtime/helpers/asyncToGenerator.js \ No newline at end of file diff --git a/app/javascript/components/map/defineProperty.js b/app/javascript/components/map/defineProperty.js new file mode 100644 index 0000000000..b161eb8823 --- /dev/null +++ b/app/javascript/components/map/defineProperty.js @@ -0,0 +1 @@ +//= require @babel/runtime/helpers/defineProperty.js diff --git a/app/javascript/components/map/defra-im-core.js b/app/javascript/components/map/im-core.js similarity index 100% rename from app/javascript/components/map/defra-im-core.js rename to app/javascript/components/map/im-core.js diff --git a/app/javascript/components/map/defra-im-shell.js b/app/javascript/components/map/im-shell.js similarity index 100% rename from app/javascript/components/map/defra-im-shell.js rename to app/javascript/components/map/im-shell.js diff --git a/app/javascript/components/map/defra-index.js b/app/javascript/components/map/index.js similarity index 100% rename from app/javascript/components/map/defra-index.js rename to app/javascript/components/map/index.js diff --git a/app/javascript/components/map/map.js b/app/javascript/components/map/map.js new file mode 100644 index 0000000000..4fcd0d309c --- /dev/null +++ b/app/javascript/components/map/map.js @@ -0,0 +1,196 @@ +/* global defra */ +window.GOVUK = window.GOVUK || {} +window.GOVUK.Modules = window.GOVUK.Modules || {}; + +import InteractiveMap from '@defra/interactive-map' +import maplibreProvider from '@defra/interactive-map/providers/maplibre' + +(function (Modules) { + class Map { + constructor ($module) { + console.log('constructor') + this.$module = $module + this.map_element = this.$module.querySelector('.app-c-map') + this.map_id = this.$module.getAttribute('id') + const cspWorker = this.$module.getAttribute('data-csp-worker') + + this.interactPlugin = defra.interactPlugin({ + deselectOnClickOutside: true + }) + + const config = { + mapProvider: maplibreProvider({ workerUrl: cspWorker }), + behaviour: 'inline', + mapStyle: { + url: window.GOVUK.mapComponentStyles, + backgroundColor: '#f5f5f0' + }, + plugins: [this.interactPlugin], + urlPosition: 'none', + minZoom: 4, + maxZoom: 16, + center: [-0.09, 51.505], + containerHeight: '500px' + } + const passedConfig = JSON.parse(this.$module.getAttribute('data-config')) || {} + this.config = Object.assign(config, passedConfig) + + this.markers = JSON.parse(this.$module.getAttribute('data-markers')) || [] + this.geoJsonUrl = this.$module.getAttribute('data-geojson') + if (this.geoJsonUrl && !this.geoJsonUrl.startsWith('/')) { + console.error(`Error: external URLs for geoJSON are not allowed: ${this.geoJsonUrl}`) + this.geoJsonUrl = false + } + this.headingLevel = parseInt(this.$module.getAttribute('data-heading-level')) || 2 + + this.markerOptions = { + symbol: 'circle', + backgroundColor: '#1d70b8', + foregroundColor: '#FFFFFF', + haloWidth: 3, + selectedWidth: 8 + } + } + + init () { + const id = this.$module.getAttribute('id') + this.$module.setAttribute('id', '') + this.map_element.setAttribute('id', id) + this.map_element.classList.add('app-c-map--enabled') + + this.map = new InteractiveMap(this.map_id, this.config) + + /* istanbul ignore next */ + this.map.on('map:ready', () => { + this.addAllMarkers() + }) + + /* istanbul ignore next */ + this.map.on('interact:selectionchange', (e) => { + if (e.selectedMarkers.length > 0) { + let marker = parseInt(e.selectedMarkers[0].replace('marker-', '')) + marker = this.markers[marker] + this.map.addPanel('the-panel', { + focus: false, + label: marker.name, + html: this.createPopupContent(marker), + mobile: { slot: 'drawer', dismissible: true }, + tablet: { slot: 'left-top', dismissible: true, width: '280px' }, + desktop: { slot: 'left-top', dismissible: true, width: '280px' } + }) + } else { + this.map.hidePanel('the-panel') + } + }) + + /* istanbul ignore next */ + this.map.on('app:panelclosed', (e) => { + this.interactPlugin.clear() + }) + } + + createPopupContent (feature) { + const heading = `h${this.headingLevel}` + let popupContent = `<${heading} class="govuk-heading-s govuk-!-margin-bottom-2">${feature.properties.name}` + if (feature.properties.description) { + popupContent = `${popupContent} ${feature.properties.description}` + } + popupContent = this.removeScript(popupContent) + return popupContent + } + + removeScript (input) { + do { + input = input.replace(/<[\s]*script/g, '') + } while (input.includes(' { + const nameA = a.properties.name.toUpperCase() + const nameB = b.properties.name.toUpperCase() + if (nameA < nameB) { + return -1 + } + if (nameA > nameB) { + return 1 + } + return 0 // names are equal + }) + this.addMarkers() + + // only fit to bounds if there are more than one markers + if (this.markers.length > 0 && !this.config.bounds) { + this.map.fitToBounds({ + type: 'FeatureCollection', + features: this.markers + }) + } + if (this.markers.length > 0) { + this.interactPlugin.enable() + this.addPopupsList() + } + } + + addMarkers () { + const allowedColours = { + blue: '#1d70b8', + green: '#0f7a52', + orange: '#f47738', + red: '#ca3535' + } + const allowedSymbols = ['circle', 'pin', 'square'] + this.markers.forEach((marker, index) => { + if (marker.marker) { + const colour = marker.marker.colour || false + if (colour) { + if (allowedColours[colour]) { + marker.marker.backgroundColor = allowedColours[colour] + } + delete marker.marker.colour + } + const symbol = marker.marker.symbol || false + if (!(symbol && allowedSymbols.includes(symbol))) { + delete marker.marker.symbol + } + } + const options = Object.assign(Object.assign({}, this.markerOptions), marker.marker || {}) + this.map.addMarker(`marker-${index}`, marker.geometry.coordinates, options) + }) + } + + addPopupsList () { + const popupsListWrapper = this.$module.querySelector('.app-c-map__markers-list') + const popupsListEl = this.$module.querySelector('.js-list-markers ol') + + if (popupsListWrapper && popupsListEl) { + popupsListWrapper.classList.add('app-c-map__markers-list--visible') + const popupsList = [] + this.markers.forEach(marker => { + popupsList.push(this.createPopupContent(marker)) + }) + popupsList.forEach(popup => { + const listItem = document.createElement('li') + listItem.innerHTML = popup + popupsListEl.appendChild(listItem) + }) + } + } + } + Modules.Map = Map +})(window.GOVUK.Modules) diff --git a/app/javascript/components/map/objectWithoutProperties.js b/app/javascript/components/map/objectWithoutProperties.js new file mode 100644 index 0000000000..78139782f0 --- /dev/null +++ b/app/javascript/components/map/objectWithoutProperties.js @@ -0,0 +1 @@ +//= require @babel/runtime/helpers/objectWithoutProperties.js diff --git a/app/views/components/_map.html.erb b/app/views/components/_map.html.erb index a8eb0f0cf9..60d27a7d65 100644 --- a/app/views/components/_map.html.erb +++ b/app/views/components/_map.html.erb @@ -64,7 +64,8 @@ <% end %> <% unless @include_script[:script_included] %> - <%= javascript_include_tag "components/map.js", integrity: false, type: "module" %> + <%= javascript_importmap_tags %> + <%= javascript_import_module_tag "components/map/map" %> <% @include_script[:script_included] = true %> <% end %> diff --git a/config/importmap.rb b/config/importmap.rb index a702422fec..b779bb4255 100644 --- a/config/importmap.rb +++ b/config/importmap.rb @@ -2,13 +2,21 @@ # Pin the default entry point required by javascript_importmap_tags pin "application", preload: true +pin "components/map/map", preload: true +pin "components/map/index", preload: true +pin "components/map/im-core", preload: true +pin "components/map/im-shell", preload: true +pin "components/map/maplibre", preload: true -pin "@defra/interactive-map", to: "components/map/defra.js" +pin "@defra/interactive-map", to: "components/map/index.js" pin "@defra/interactive-map/providers/maplibre", to: "components/map/maplibre.js" # pin "@defra/interactive-map/plugins/interact", to: "./node_modules/@defra/interactive-map/plugins/interact/dist/esm/index.js" -pin "components/map", to: "components/map.js" + +pin "components/map/asyncToGenerator", preload: true +pin "components/map/defineProperty", preload: true +pin "components/map/objectWithoutProperties", preload: true # try to avoid errors relating to babel, which is referenced by the defra ESM code -pin "@babel/runtime/helpers/asyncToGenerator", to: "@babel/runtime/helpers/asyncToGenerator.js" -pin "@babel/runtime/helpers/defineProperty", to: "@babel/runtime/helpers/defineProperty.js" -pin "@babel/runtime/helpers/objectWithoutProperties", to: "@babel/runtime/helpers/objectWithoutProperties.js" +pin "@babel/runtime/helpers/asyncToGenerator", to: "components/map/asyncToGenerator.js" +pin "@babel/runtime/helpers/defineProperty", to: "components/map/defineProperty.js" +pin "@babel/runtime/helpers/objectWithoutProperties", to: "components/map/objectWithoutProperties.js" diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb index be94bf3c4b..4f4a787441 100644 --- a/config/initializers/assets.rb +++ b/config/initializers/assets.rb @@ -8,9 +8,13 @@ Rails.application.config.assets.paths << Rails.root.join("node_modules") # Precompile map.js independently so it can be fetched directly by the importmap -Rails.application.config.assets.precompile += %w( components/map.js ) -Rails.application.config.assets.precompile += %w( components/map/defra.js ) +Rails.application.config.assets.precompile += %w( components/map/map.js ) + +Rails.application.config.assets.precompile += %w( components/map/index.js ) +Rails.application.config.assets.precompile += %w( components/map/im-core.js ) +Rails.application.config.assets.precompile += %w( components/map/im-shell.js ) Rails.application.config.assets.precompile += %w( components/map/maplibre.js ) -Rails.application.config.assets.precompile += %w( @babel/runtime/helpers/asyncToGenerator.js ) -Rails.application.config.assets.precompile += %w( @babel/runtime/helpers/defineProperty.js ) -Rails.application.config.assets.precompile += %w( @babel/runtime/helpers/objectWithoutProperties.js ) + +Rails.application.config.assets.precompile += %w( components/map/asyncToGenerator.js ) +Rails.application.config.assets.precompile += %w( components/map/defineProperty.js ) +Rails.application.config.assets.precompile += %w( components/map/objectWithoutProperties.js ) From 2e6604a6fe3bdaf2b5d46cf59f35ec6e7588cd44 Mon Sep 17 00:00:00 2001 From: Andy Sellick Date: Mon, 14 Sep 2026 16:28:24 +0100 Subject: [PATCH 9/9] WIP babel - install the ES module version of babel - `yarn add @babel/runtime-corejs3` - and reference that instead of the UMD version - unfortunately it still doesn't work, due to a new import problem, but one more step --- .../components/map/asyncToGenerator.js | 2 +- package.json | 1 + yarn.lock | 17 +++++++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/app/javascript/components/map/asyncToGenerator.js b/app/javascript/components/map/asyncToGenerator.js index 7e8c963e6e..bce197e5ff 100644 --- a/app/javascript/components/map/asyncToGenerator.js +++ b/app/javascript/components/map/asyncToGenerator.js @@ -1 +1 @@ -//= require @babel/runtime/helpers/asyncToGenerator.js \ No newline at end of file +//= require @babel/runtime-corejs3/helpers/esm/asyncToGenerator.js diff --git a/package.json b/package.json index 86aea1d972..a980fcdf2d 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ }, "packageManager": "yarn@4.18.0", "dependencies": { + "@babel/runtime-corejs3": "^8.0.5", "@defra/interactive-map": "0.0.30-alpha", "leaflet": "^1.9.4", "maplibre-gl": "5.24.0" diff --git a/yarn.lock b/yarn.lock index 532c40027f..d8fbd48c07 100644 --- a/yarn.lock +++ b/yarn.lock @@ -169,6 +169,15 @@ __metadata: languageName: node linkType: hard +"@babel/runtime-corejs3@npm:^8.0.5": + version: 8.0.5 + resolution: "@babel/runtime-corejs3@npm:8.0.5" + dependencies: + core-js-pure: "npm:^3.48.0" + checksum: 10/5f8e90a52a45ce386a34af2b788aefd76ba34d12c5fa5e345c0ac3b71ab60d1d844b0a9634c38f7114a8530e15a096c133d633fbdd946e335bc9d775a51b9442 + languageName: node + linkType: hard + "@babel/runtime@npm:^7.28.6": version: 7.29.2 resolution: "@babel/runtime@npm:7.29.2" @@ -1643,6 +1652,13 @@ __metadata: languageName: node linkType: hard +"core-js-pure@npm:^3.48.0": + version: 3.50.0 + resolution: "core-js-pure@npm:3.50.0" + checksum: 10/4009d549c955dbd4274b58a6c36c7afce8a8f468a631bacb06708873bf503b1c91cbf5baa88c8605c2fff2ccc481fb337e9358c16c029c701d0fffa074e1706e + languageName: node + linkType: hard + "core-util-is@npm:~1.0.0": version: 1.0.3 resolution: "core-util-is@npm:1.0.3" @@ -2595,6 +2611,7 @@ __metadata: version: 0.0.0-use.local resolution: "frontend@workspace:." dependencies: + "@babel/runtime-corejs3": "npm:^8.0.5" "@defra/interactive-map": "npm:0.0.30-alpha" jasmine-browser-runner: "npm:^5.0.0" jasmine-core: "npm:^7.0.2"