From 56fab8fec96d769d26a83115bf890279f2fdb5c8 Mon Sep 17 00:00:00 2001
From: Nicolas DROUX <nicolas.droux@ecedi.fr>
Date: Wed, 19 Feb 2025 16:04:12 +0100
Subject: [PATCH 1/5] Ref #3507085 - Add gitlab ci file

---
 .gitlab-ci.yml | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)
 create mode 100644 .gitlab-ci.yml

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000..c6cd69a
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,29 @@
+################
+# GitLabCI template for Drupal projects.
+#
+# This template is designed to give any Contrib maintainer everything they need to test, without requiring modification.
+# It is also designed to keep up to date with Core Development automatically through the use of include files that can be centrally maintained.
+# As long as you include the project, ref and three files below, any future updates added by the Drupal Association will be used in your
+# pipelines automatically. However, you can modify this template if you have additional needs for your project.
+# The full documentation is on https://project.pages.drupalcode.org/gitlab_templates/
+################
+
+# For information on alternative values for 'ref' see https://project.pages.drupalcode.org/gitlab_templates/info/templates-version/
+# To test a Drupal 7 project, change the first include filename from .main.yml to .main-d7.yml
+include:
+  - project: $_GITLAB_TEMPLATES_REPO
+    ref: $_GITLAB_TEMPLATES_REF
+    file:
+      - '/includes/include.drupalci.main.yml'
+      - '/includes/include.drupalci.variables.yml'
+      - '/includes/include.drupalci.workflows.yml'
+#
+################
+# Pipeline configuration variables are defined with default values and descriptions in the file
+# https://git.drupalcode.org/project/gitlab_templates/-/blob/main/includes/include.drupalci.variables.yml
+# Uncomment the lines below if you want to override any of the variables. The following is just an example.
+################
+# variables:
+#   SKIP_ESLINT: '1'
+#   OPT_IN_TEST_NEXT_MAJOR: '1'
+#   _CURL_TEMPLATES_REF: 'main'
-- 
GitLab


From e9267c943e66af918fefef443bbcd18c9c507953 Mon Sep 17 00:00:00 2001
From: Nicolas DROUX <nicolas.droux@ecedi.fr>
Date: Wed, 19 Feb 2025 17:01:59 +0100
Subject: [PATCH 2/5] Ref #3507085 - Fix coding standards

---
 .eslintrc.json                            |   5 +
 .gitlab-ci.yml                            |   4 +-
 README.md                                 |   2 +-
 css/geomap_default_widget.css             |  20 +--
 geomap_field.info.yml                     |   2 +-
 js/geomap-default-formatter.js            |  36 +++---
 js/geomap-default-widget.js               | 149 +++++++++++-----------
 src/Plugin/Field/FieldType/GeomapItem.php |   6 +-
 8 files changed, 114 insertions(+), 110 deletions(-)
 create mode 100644 .eslintrc.json

diff --git a/.eslintrc.json b/.eslintrc.json
new file mode 100644
index 0000000..4fc0596
--- /dev/null
+++ b/.eslintrc.json
@@ -0,0 +1,5 @@
+{
+  "globals": {
+    "L": true
+  }
+}
\ No newline at end of file
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index c6cd69a..edece01 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -23,7 +23,9 @@ include:
 # https://git.drupalcode.org/project/gitlab_templates/-/blob/main/includes/include.drupalci.variables.yml
 # Uncomment the lines below if you want to override any of the variables. The following is just an example.
 ################
-# variables:
+variables:
+  _CSPELL_WORDS:
+    value: 'bano, geolocate, latlon, zipcode'
 #   SKIP_ESLINT: '1'
 #   OPT_IN_TEST_NEXT_MAJOR: '1'
 #   _CURL_TEMPLATES_REF: 'main'
diff --git a/README.md b/README.md
index 02c1362..bd73a61 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,3 @@
 # Geomap Field
 
-Provide a new field type to store address (using geolocation and map visualisation). Also provide a field formatter to display the field as a map.
\ No newline at end of file
+Provide a new field type to store address (using geolocation and map visualization). Also provide a field formatter to display the field as a map.
\ No newline at end of file
diff --git a/css/geomap_default_widget.css b/css/geomap_default_widget.css
index 290d26a..12a82c6 100644
--- a/css/geomap_default_widget.css
+++ b/css/geomap_default_widget.css
@@ -20,17 +20,17 @@
 }
 
 .geomap-widget-map {
-  height: 100%;
   width: 100%;
+  height: 100%;
 }
 
 .geolocation-suggestions-list {
+  position: absolute;
   margin: 0;
   padding: 0;
-  position: absolute;
-  left: 11px;
-  bottom: 11px;
   z-index: 1000;
+  bottom: 11px;
+  left: 11px;
 }
 
 .geolocation-suggestions-list-item {
@@ -38,17 +38,17 @@
 }
 
 .geolocation-suggestions-list-item button {
+  display: flex;
   padding: 8px 16px;
   background-color: #fff;
-  box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
   border: none;
-  display: flex;
+  box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
   align-items: center;
 }
 
-.geolocation-suggestions-list-item button:after {
-  content: url(../images/baseline-reply-24px.svg);
+.geolocation-suggestions-list-item button::after {
   padding-left: 8px;
+  content: url(../images/baseline-reply-24px.svg);
 }
 
 .geolocation-suggestions-list-item button:hover {
@@ -56,13 +56,13 @@
 }
 
 .geomap-loader {
+  position: absolute;
   width: 42px;
   height: 42px;
+  animation: geomap-loader-spin 1s linear infinite;
   border: 8px solid transparent;
   border-top: 8px solid #1f86c7;
   border-radius: 50%;
-  animation: geomap-loader-spin 1s linear infinite;
-  position: absolute;
   z-index: 1000;
   top: 16px;
   right: 16px;
diff --git a/geomap_field.info.yml b/geomap_field.info.yml
index ddafbca..0b5358a 100644
--- a/geomap_field.info.yml
+++ b/geomap_field.info.yml
@@ -1,6 +1,6 @@
 name: 'Geomap Field'
 type: module
-description: 'Provide a new field type to store address (using geolocation and map visualisation). Also provide a field formatter to display the field as a map.'
+description: 'Provide a new field type to store address (using geolocation and map visualization). Also provide a field formatter to display the field as a map.'
 core_version_requirement: ^8 || ^9 || ^10 || ^11
 package: 'Field types'
 dependencies:
diff --git a/js/geomap-default-formatter.js b/js/geomap-default-formatter.js
index 4ba19a1..8bec791 100644
--- a/js/geomap-default-formatter.js
+++ b/js/geomap-default-formatter.js
@@ -5,23 +5,21 @@
 
 
 (function ($, Drupal) {
-
-    Drupal.behaviors.geomapDefaultFormatter = {
-
-        attach: function (context) {
-            $(once('geomapDefaultFormatter', '.geomap-formatter-map', context))
-                .on('map:afterInit', function (event, map) {
-                    var mapSettings = $(event.target).data('map');
-                    if (mapSettings.center) {
-                        var marker = new L.marker([
-                            mapSettings.center[0],
-                            mapSettings.center[1]
-                        ], {draggable: 'false'});
-                        map.addLayer(marker);
-                    }
-                }.bind(this));
-        }
-
-    };
-
+  Drupal.behaviors.geomapDefaultFormatter = {
+    attach(context) {
+    $(once('geomapDefaultFormatter', '.geomap-formatter-map', context)).on(
+      'map:afterInit',
+      function (event, map) {
+        const mapSettings = $(event.target).data('map');
+        if (mapSettings.center) {
+          const marker = new L.marker(
+            [mapSettings.center[0], mapSettings.center[1]],
+            { draggable: 'false' },
+            );
+          map.addLayer(marker);
+          }
+        },
+      );
+    },
+  };
 })(jQuery, Drupal);
diff --git a/js/geomap-default-widget.js b/js/geomap-default-widget.js
index e0f48a4..7ba6e84 100644
--- a/js/geomap-default-widget.js
+++ b/js/geomap-default-widget.js
@@ -3,77 +3,78 @@
  * Geomap default widget custom behavior
  */
 
-
 (function ($, Drupal) {
-
   Drupal.behaviors.geomapDefaultWidget = {
+    attach(context) {
+      $(once('geomapDefaultWidget', '.geomap-widget-map', context)).on(
+        'map:afterInit',
+        function (event, map) {
+          const $map = $(event.target);
+          const geolocationPlugin = $map.data('geolocation-plugin');
+          const reverseUrl = `/geolocation_provider/reverse/${geolocationPlugin}`;
+          const geolocationUrl = `/geolocation_provider/geolocation/${geolocationPlugin}`;
+          const $widget = $map.parents('.geomap-widget-wrapper');
+          const $latlon = $widget.find('.latlon-wrapper');
+          const $latField = $latlon.find('.geomap-field-lat');
+          const $lonField = $latlon.find('.geomap-field-lon');
 
-    attach: function (context) {
-      $(once('geomapDefaultWidget','.geomap-widget-map', context))
-          .on('map:afterInit', function (event, map) {
-            var $map = $(event.target);
-            var geolocationPlugin = $map.data('geolocation-plugin');
-            var reverseUrl = '/geolocation_provider/reverse/' + geolocationPlugin;
-            var geolocationUrl = '/geolocation_provider/geolocation/' + geolocationPlugin;
-            var $widget = $map.parents('.geomap-widget-wrapper');
-            var $latlon = $widget.find('.latlon-wrapper');
-            var $latField = $latlon.find('.geomap-field-lat');
-            var $lonField = $latlon.find('.geomap-field-lon');
-
-            var marker = new L.marker([
-              $latField.val() || 51.505,
-              $lonField.val() || -0.09
-            ], {draggable: 'true'});
-            marker.on('dragend', function (event) {
-              var position = marker.getLatLng();
-              $latField.val(position.lat);
-              $lonField.val(position.lng);
-              this.updateLoader($widget, true);
-              $.get(reverseUrl + '/' + position.lat + '/' + position.lng, function (data) {
-                this.updateSuggestions($widget, data);
-                this.updateLoader($widget, false);
-                if (data.features && data.features.length > 0) {
-                  this.updateFeatureInput($widget, data.features[0]);
-                }
-              }.bind(this));
+          const marker = new L.marker(
+            [$latField.val() || 51.505, $lonField.val() || -0.09],
+            {draggable: 'true'}
+          );
+          marker.on('dragend', function (event) {
+            const position = marker.getLatLng();
+            $latField.val(position.lat);
+            $lonField.val(position.lng);
+            this.updateLoader($widget, true);
+            $.get(`${reverseUrl}/${position.lat}/${position.lng}`, function (data) {
+              this.updateSuggestions($widget, data);
+              this.updateLoader($widget, false);
+              if (data.features && data.features.length > 0) {
+                this.updateFeatureInput($widget, data.features[0]);
+              }
             }.bind(this));
-            map.addLayer(marker);
-            $widget.marker = marker;
+          }.bind(this));
+          map.addLayer(marker);
+          $widget.marker = marker;
 
-            // Listen Lat/Lon fields changes.
-            $latlon.find('input').on('input', Drupal.debounce(function (event) {
+          // Listen Lat/Lon fields changes.
+          $latlon.find('input').on(
+            'input',
+            Drupal.debounce(function (event) {
               this.updateMarker($widget, map);
-            }.bind(this), 200));
+            }.bind(this), 200)
+          );
 
-            // Geolocation behavior.
-            $widget.find('.geomap-geolocation-btn').on('click', function (event) {
-              var street = $widget.find('input[name$="][street]"]').val();
-              var zipcode = $widget.find('input[name$="][zipcode]"]').val();
-              var city = $widget.find('input[name$="][city]"]').val();
-              var country = $widget.find('input[name$="][country]"]').val();
-              var address = street + ', ' + zipcode + ' ' + city + ', ' + country;
-              this.updateLoader($widget, true);
-              $.get(geolocationUrl + '/' + address, function (data) {
-                this.updateLoader($widget, false);
-                if (data.features && data.features.length > 0) {
-                  var feature = data.features[0];
-                  $latField.val(feature.geometry.coordinates[1]);
-                  $lonField.val(feature.geometry.coordinates[0]);
-                  this.updateMarker($widget, map);
-                  this.updateFeatureInput($widget, feature);
-                }
-              }.bind(this));
-              event.preventDefault();
+          // Geolocation behavior.
+          $widget.find('.geomap-geolocation-btn').on('click', function (event) {
+            const street = $widget.find('input[name$="][street]"]').val();
+            const zipcode = $widget.find('input[name$="][zipcode]"]').val();
+            const city = $widget.find('input[name$="][city]"]').val();
+            const country = $widget.find('input[name$="][country]"]').val();
+            const address = `${street}, ${zipcode} ${city}, ${country}`;
+            this.updateLoader($widget, true);
+            $.get(`${geolocationUrl}/${address}`, function (data) {
+              this.updateLoader($widget, false);
+              if (data.features && data.features.length > 0) {
+                const feature = data.features[0];
+                $latField.val(feature.geometry.coordinates[1]);
+                $lonField.val(feature.geometry.coordinates[0]);
+                this.updateMarker($widget, map);
+                this.updateFeatureInput($widget, feature);
+              }
             }.bind(this));
-
+            event.preventDefault();
           }.bind(this));
+        }.bind(this)
+      );
     },
 
-    updateMarker: function ($widget, map) {
-      var lat = $widget.find('.geomap-field-lat').val();
-      var lon = $widget.find('.geomap-field-lon').val();
+    updateMarker($widget, map) {
+      const lat = $widget.find('.geomap-field-lat').val();
+      const lon = $widget.find('.geomap-field-lon').val();
       if (lat && lon) {
-        var latlon = new L.LatLng(lat, lon);
+        const latlon = new L.LatLng(lat, lon);
         if (latlon !== $widget.marker.getLatLng()) {
           $widget.marker.setLatLng(latlon);
           map.setView(latlon);
@@ -81,29 +82,29 @@
       }
     },
 
-    updateLoader: function ($widget, status) {
+    updateLoader($widget, status) {
       $widget.find('.geomap-loader').attr('aria-hidden', status ? 'false' : 'true');
     },
 
-    updateSuggestions: function ($widget, featureCollection) {
-      var $list = $widget.find('.geolocation-suggestions-list');
+    updateSuggestions($widget, featureCollection) {
+      const $list = $widget.find('.geolocation-suggestions-list');
       $list.empty();
-      var features = featureCollection.features || [];
+      const features = featureCollection.features || [];
       features.forEach(function (feature) {
-        var $item = $('<li>', {'class': 'geolocation-suggestions-list-item'});
-        var $btn = $('<button>');
+        const $item = $('<li>', {class: 'geolocation-suggestions-list-item'});
+        const $btn = $('<button>');
         $btn.data('feature', feature);
         $btn.on('click', this.onSuggestionClick.bind(this));
-        $btn.text(feature.properties.label)
+        $btn.text(feature.properties.label);
         $list.append($item.append($btn));
       }.bind(this));
     },
 
-    onSuggestionClick: function (event) {
-      var $suggestion = $(event.target);
-      var feature = $suggestion.data('feature');
+    onSuggestionClick(event) {
+      const $suggestion = $(event.target);
+      const feature = $suggestion.data('feature');
       // Update address input fields.
-      var $widget = $suggestion.parents('.geomap-widget-wrapper');
+      const $widget = $suggestion.parents('.geomap-widget-wrapper');
       $widget.find('input[name$="][street]"]').val(feature.properties.name);
       $widget.find('input[name$="][zipcode]"]').val(feature.properties.postcode);
       $widget.find('input[name$="][city]"]').val(feature.properties.city);
@@ -111,10 +112,8 @@
       event.preventDefault();
     },
 
-    updateFeatureInput: function ($widget, feature) {
+    updateFeatureInput($widget, feature) {
       $widget.find('input[name$="][feature]"]').val(JSON.stringify(feature));
-    }
-
+    },
   };
-
-})(jQuery, Drupal);
+})(jQuery, Drupal);
\ No newline at end of file
diff --git a/src/Plugin/Field/FieldType/GeomapItem.php b/src/Plugin/Field/FieldType/GeomapItem.php
index 38fb211..485def3 100644
--- a/src/Plugin/Field/FieldType/GeomapItem.php
+++ b/src/Plugin/Field/FieldType/GeomapItem.php
@@ -26,9 +26,9 @@ class GeomapItem extends FieldItemBase {
    */
   public static function defaultStorageSettings() {
     $default = [
-      //      'max_length' => 255,
-      //      'is_ascii' => FALSE,
-      //      'case_sensitive' => FALSE,
+      // 'max_length' => 255,
+      // 'is_ascii' => FALSE,
+      // 'case_sensitive' => FALSE,
     ];
     return $default + parent::defaultStorageSettings();
   }
-- 
GitLab


From 00e8c0eaf60bde8b7a1f0d0d813ac644b1f7f039 Mon Sep 17 00:00:00 2001
From: Nicolas DROUX <nicolas.droux@ecedi.fr>
Date: Fri, 21 Feb 2025 16:36:01 +0100
Subject: [PATCH 3/5] Ref #3507085 - Fix coding standards dependency injection

---
 geomap_field.services.yml                     |  8 +++
 .../Field/FieldFormatter/GeomapDefault.php    | 47 ++++++++++----
 .../Field/FieldWidget/GeomapDefault.php       | 65 ++++++++++++++-----
 3 files changed, 91 insertions(+), 29 deletions(-)
 create mode 100644 geomap_field.services.yml

diff --git a/geomap_field.services.yml b/geomap_field.services.yml
new file mode 100644
index 0000000..faeeefe
--- /dev/null
+++ b/geomap_field.services.yml
@@ -0,0 +1,8 @@
+services:
+  plugin.manager.map_provider:
+    class: 'Drupal\map_provider\Plugin\MapProviderManager'
+    arguments: []
+
+  plugin.manager.geolocation_provider_plugin:
+    class: 'Drupal\geolocation_provider\Plugin\GeolocationProviderPluginManager'
+    arguments: ['@container.namespaces', '@cache.default', '@module_handler']
diff --git a/src/Plugin/Field/FieldFormatter/GeomapDefault.php b/src/Plugin/Field/FieldFormatter/GeomapDefault.php
index e367038..d0f20d0 100644
--- a/src/Plugin/Field/FieldFormatter/GeomapDefault.php
+++ b/src/Plugin/Field/FieldFormatter/GeomapDefault.php
@@ -2,9 +2,12 @@
 
 namespace Drupal\geomap_field\Plugin\Field\FieldFormatter;
 
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\FieldItemListInterface;
 use Drupal\Core\Field\FormatterBase;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\map_provider\Plugin\MapProviderManager;
 
 /**
  * Plugin implementation of the 'geomap_default' formatter.
@@ -19,6 +22,36 @@ use Drupal\Core\Form\FormStateInterface;
  */
 class GeomapDefault extends FormatterBase {
 
+  /**
+   * Map manager service.
+   *
+   * @var \Drupal\map_provider\Plugin\MapProviderManager
+   */
+  protected MapProviderManager $mapManager;
+
+  public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, MapProviderManager $mapManager) {
+    parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings);
+    $this->mapManager = $mapManager;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+
+    $mapManager = $container->get('plugin.manager.map_provider');
+    return new static(
+      $plugin_id,
+      $plugin_definition,
+      $configuration['field_definition'],
+      $configuration['settings'],
+      $configuration['label'],
+      $configuration['view_mode'],
+      $configuration['third_party_settings'],
+      $mapManager
+    );
+  }
+
   /**
    * {@inheritdoc}
    */
@@ -36,11 +69,8 @@ class GeomapDefault extends FormatterBase {
    */
   public function settingsForm(array $form, FormStateInterface $form_state) {
     $elements = [];
-
-    /** @var \Drupal\map_provider\Plugin\MapProviderManager $map_manager */
-    $map_manager = \Drupal::service('plugin.manager.map_provider');
     $map_options = [];
-    foreach ($map_manager->getDefinitions() as $id => $definition) {
+    foreach ($this->mapManager->getDefinitions() as $id => $definition) {
       $map_options[$id] = $definition['label'];
     }
     $elements['map_provider'] = [
@@ -71,10 +101,7 @@ class GeomapDefault extends FormatterBase {
    */
   public function settingsSummary() {
     $summary = [];
-
-    /** @var \Drupal\map_provider\Plugin\MapProviderManager $map_manager */
-    $map_manager = \Drupal::service('plugin.manager.map_provider');
-    $map_plugin_label = $map_manager->getDefinition($this->getSetting('map_provider'))['label'] ?? '';
+    $map_plugin_label = $this->mapManager->getDefinition($this->getSetting('map_provider'))['label'] ?? '';
     $summary[] = $this->t('Map provider: @provider', ['@provider' => $map_plugin_label]);
 
     $summary[] = $this->t('Map height: @height', ['@height' => $this->getSetting('height')]);
@@ -88,8 +115,6 @@ class GeomapDefault extends FormatterBase {
    */
   public function viewElements(FieldItemListInterface $items, $langcode) {
     $elements = [];
-    /** @var \Drupal\map_provider\Plugin\MapProviderManager $map_manager */
-    $map_manager = \Drupal::service('plugin.manager.map_provider');
 
     foreach ($items as $delta => $item) {
       /** @var \Drupal\map_provider\Plugin\MapProviderInterface $map_provider */
@@ -97,7 +122,7 @@ class GeomapDefault extends FormatterBase {
       if (empty($plugin)) {
         $plugin = 'yaml_map_provider:osm';
       }
-      $map_provider = $map_manager->createInstance($plugin);
+      $map_provider = $this->mapManager->createInstance($plugin);
       $elements[$delta] = [
         '#type' => 'map',
         '#tile_url' => $map_provider->getUrl(),
diff --git a/src/Plugin/Field/FieldWidget/GeomapDefault.php b/src/Plugin/Field/FieldWidget/GeomapDefault.php
index 80867ad..3582beb 100644
--- a/src/Plugin/Field/FieldWidget/GeomapDefault.php
+++ b/src/Plugin/Field/FieldWidget/GeomapDefault.php
@@ -2,9 +2,13 @@
 
 namespace Drupal\geomap_field\Plugin\Field\FieldWidget;
 
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\FieldItemListInterface;
 use Drupal\Core\Field\WidgetBase;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\geolocation_provider\Plugin\GeolocationProviderPluginManager;
+use Drupal\map_provider\Plugin\MapProviderManager;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Plugin implementation of the 'geomap_default' widget.
@@ -19,6 +23,43 @@ use Drupal\Core\Form\FormStateInterface;
  */
 class GeomapDefault extends WidgetBase {
 
+  /**
+   * GeolocationProvider service.
+   *
+   * @var \Drupal\geolocation_provider\Plugin\GeolocationProviderPluginManager
+   */
+  protected GeolocationProviderPluginManager $geolocationManager;
+
+  /**
+   * Map manager service.
+   *
+   * @var \Drupal\map_provider\Plugin\MapProviderManager
+   */
+  protected MapProviderManager $mapManager;
+
+  public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, array $third_party_settings, GeolocationProviderPluginManager $geolocationManager, MapProviderManager $mapManager) {
+    parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $third_party_settings);
+    $this->geolocationManager = $geolocationManager;
+    $this->mapManager = $mapManager;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    $geolocationManager = $container->get('plugin.manager.geolocation.geolocation');
+    $mapManager = $container->get('plugin.manager.map_provider');
+    return new static(
+      $plugin_id,
+      $plugin_definition,
+      $configuration['field_definition'],
+      $configuration['settings'],
+      $configuration['third_party_settings'],
+      $geolocationManager,
+      $mapManager
+    );
+  }
+
   /**
    * {@inheritdoc}
    */
@@ -36,10 +77,9 @@ class GeomapDefault extends WidgetBase {
   public function settingsForm(array $form, FormStateInterface $form_state) {
     $elements = [];
 
-    /** @var \Drupal\geolocation_provider\Plugin\GeolocationProviderPluginManager $geolocation_manager */
-    $geolocation_manager = \Drupal::service('plugin.manager.geolocation_provider_plugin');
+
     $geo_options = [];
-    foreach ($geolocation_manager->getDefinitions() as $id => $definition) {
+    foreach ($this->geolocationManager->getDefinitions() as $id => $definition) {
       $geo_options[$id] = $definition['label'];
     }
     $elements['geolocation_provider'] = [
@@ -48,11 +88,8 @@ class GeomapDefault extends WidgetBase {
       '#options' => $geo_options,
       '#default_value' => $this->settings['geolocation_provider'],
     ];
-
-    /** @var \Drupal\map_provider\Plugin\MapProviderManager $map_manager */
-    $map_manager = \Drupal::service('plugin.manager.map_provider');
     $map_options = [];
-    foreach ($map_manager->getDefinitions() as $id => $definition) {
+    foreach ($this->mapManager->getDefinitions() as $id => $definition) {
       $map_options[$id] = $definition['label'];
     }
     $elements['map_provider'] = [
@@ -70,15 +107,9 @@ class GeomapDefault extends WidgetBase {
    */
   public function settingsSummary() {
     $summary = [];
-
-    /** @var \Drupal\geolocation_provider\Plugin\GeolocationProviderPluginManager $geolocation_manager */
-    $geolocation_manager = \Drupal::service('plugin.manager.geolocation_provider_plugin');
-    $geolocation_plugin_label = $geolocation_manager->getDefinition($this->getSetting('geolocation_provider'))['label'] ?? '';
+    $geolocation_plugin_label = $this->geolocationManager->getDefinition($this->getSetting('geolocation_provider'))['label'] ?? '';
     $summary[] = t('Geolocation provider: @provider', ['@provider' => $geolocation_plugin_label]);
-
-    /** @var \Drupal\map_provider\Plugin\MapProviderManager $map_manager */
-    $map_manager = \Drupal::service('plugin.manager.map_provider');
-    $map_plugin_label = $map_manager->getDefinition($this->getSetting('map_provider'))['label'] ?? '';
+    $map_plugin_label = $this->mapManager->getDefinition($this->getSetting('map_provider'))['label'] ?? '';
     $summary[] = t('Map provider: @provider', ['@provider' => $map_plugin_label]);
 
     return $summary;
@@ -90,10 +121,8 @@ class GeomapDefault extends WidgetBase {
   public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
     /** @var \Drupal\geomap_field\Plugin\Field\FieldType\GeomapItem $item */
     $item = $items[$delta];
-    /** @var \Drupal\map_provider\Plugin\MapProviderManager $map_manager */
-    $map_manager = \Drupal::service('plugin.manager.map_provider');
     /** @var \Drupal\map_provider\Plugin\MapProviderInterface $map_provider */
-    $map_provider = $map_manager->createInstance($this->getSetting('map_provider'));
+    $map_provider = $this->mapManager->createInstance($this->getSetting('map_provider'));
     $geomap_form = [
       '#type' => 'details',
       '#open' => TRUE,
-- 
GitLab


From b5e47868ba1a40ad9b0a9dcbc68e1bed918d3815 Mon Sep 17 00:00:00 2001
From: Nicolas DROUX <nicolas.droux@ecedi.fr>
Date: Fri, 21 Feb 2025 16:36:17 +0100
Subject: [PATCH 4/5] Ref #3507085 - Fix coding standards eslint & css

---
 css/geomap_default_widget.css                 |  8 ++---
 js/geomap-default-widget.js                   | 32 +++++++++----------
 .../Field/FieldWidget/GeomapDefault.php       |  2 +-
 3 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/css/geomap_default_widget.css b/css/geomap_default_widget.css
index 12a82c6..51b95c9 100644
--- a/css/geomap_default_widget.css
+++ b/css/geomap_default_widget.css
@@ -26,9 +26,9 @@
 
 .geolocation-suggestions-list {
   position: absolute;
+  z-index: 1000;
   margin: 0;
   padding: 0;
-  z-index: 1000;
   bottom: 11px;
   left: 11px;
 }
@@ -39,11 +39,11 @@
 
 .geolocation-suggestions-list-item button {
   display: flex;
+  align-items: center;
   padding: 8px 16px;
-  background-color: #fff;
   border: none;
+  background-color: #fff;
   box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
-  align-items: center;
 }
 
 .geolocation-suggestions-list-item button::after {
@@ -57,13 +57,13 @@
 
 .geomap-loader {
   position: absolute;
+  z-index: 1000;
   width: 42px;
   height: 42px;
   animation: geomap-loader-spin 1s linear infinite;
   border: 8px solid transparent;
   border-top: 8px solid #1f86c7;
   border-radius: 50%;
-  z-index: 1000;
   top: 16px;
   right: 16px;
 }
diff --git a/js/geomap-default-widget.js b/js/geomap-default-widget.js
index 7ba6e84..8b1f4c6 100644
--- a/js/geomap-default-widget.js
+++ b/js/geomap-default-widget.js
@@ -19,13 +19,13 @@
           const $lonField = $latlon.find('.geomap-field-lon');
 
           const marker = new L.marker(
-            [$latField.val() || 51.505, $lonField.val() || -0.09],
+            [$latField[0].value || 51.505, $lonField[0].value || -0.09],
             {draggable: 'true'}
           );
           marker.on('dragend', function (event) {
             const position = marker.getLatLng();
-            $latField.val(position.lat);
-            $lonField.val(position.lng);
+            $latField[0].value = position.lat;
+            $lonField[0].value = position.lng;
             this.updateLoader($widget, true);
             $.get(`${reverseUrl}/${position.lat}/${position.lng}`, function (data) {
               this.updateSuggestions($widget, data);
@@ -48,18 +48,18 @@
 
           // Geolocation behavior.
           $widget.find('.geomap-geolocation-btn').on('click', function (event) {
-            const street = $widget.find('input[name$="][street]"]').val();
-            const zipcode = $widget.find('input[name$="][zipcode]"]').val();
-            const city = $widget.find('input[name$="][city]"]').val();
-            const country = $widget.find('input[name$="][country]"]').val();
+            const street = $widget.find('input[name$="][street]"]')[0].value;
+            const zipcode = $widget.find('input[name$="][zipcode]"]')[0].value;
+            const city = $widget.find('input[name$="][city]"]')[0].value;
+            const country = $widget.find('input[name$="][country]"]')[0].value;
             const address = `${street}, ${zipcode} ${city}, ${country}`;
             this.updateLoader($widget, true);
             $.get(`${geolocationUrl}/${address}`, function (data) {
               this.updateLoader($widget, false);
               if (data.features && data.features.length > 0) {
                 const feature = data.features[0];
-                $latField.val(feature.geometry.coordinates[1]);
-                $lonField.val(feature.geometry.coordinates[0]);
+                $latField[0].value = feature.geometry.coordinates[1];
+                $lonField[0].value = feature.geometry.coordinates[0];
                 this.updateMarker($widget, map);
                 this.updateFeatureInput($widget, feature);
               }
@@ -71,8 +71,8 @@
     },
 
     updateMarker($widget, map) {
-      const lat = $widget.find('.geomap-field-lat').val();
-      const lon = $widget.find('.geomap-field-lon').val();
+      const lat = $widget.find('.geomap-field-lat')[0].value;
+      const lon = $widget.find('.geomap-field-lon')[0].value;
       if (lat && lon) {
         const latlon = new L.LatLng(lat, lon);
         if (latlon !== $widget.marker.getLatLng()) {
@@ -105,15 +105,15 @@
       const feature = $suggestion.data('feature');
       // Update address input fields.
       const $widget = $suggestion.parents('.geomap-widget-wrapper');
-      $widget.find('input[name$="][street]"]').val(feature.properties.name);
-      $widget.find('input[name$="][zipcode]"]').val(feature.properties.postcode);
-      $widget.find('input[name$="][city]"]').val(feature.properties.city);
+      $widget.find('input[name$="][street]"]')[0].value = feature.properties.name;
+      $widget.find('input[name$="][zipcode]"]')[0].value = feature.properties.postcode;
+      $widget.find('input[name$="][city]"]')[0].value = feature.properties.city;
       this.updateFeatureInput($widget, feature);
       event.preventDefault();
     },
 
     updateFeatureInput($widget, feature) {
-      $widget.find('input[name$="][feature]"]').val(JSON.stringify(feature));
+      $widget.find('input[name$="][feature]"]')[0].value = JSON.stringify(feature);
     },
   };
-})(jQuery, Drupal);
\ No newline at end of file
+})(jQuery, Drupal);
diff --git a/src/Plugin/Field/FieldWidget/GeomapDefault.php b/src/Plugin/Field/FieldWidget/GeomapDefault.php
index 3582beb..0991a9a 100644
--- a/src/Plugin/Field/FieldWidget/GeomapDefault.php
+++ b/src/Plugin/Field/FieldWidget/GeomapDefault.php
@@ -47,7 +47,7 @@ class GeomapDefault extends WidgetBase {
    * {@inheritdoc}
    */
   public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
-    $geolocationManager = $container->get('plugin.manager.geolocation.geolocation');
+    $geolocationManager = $container->get('plugin.manager.geolocation_provider_plugin');
     $mapManager = $container->get('plugin.manager.map_provider');
     return new static(
       $plugin_id,
-- 
GitLab


From ab82fc5c250882f35e8c103f319d3169ec840cc5 Mon Sep 17 00:00:00 2001
From: Nicolas DROUX <nicolas.droux@ecedi.fr>
Date: Fri, 21 Feb 2025 17:17:22 +0100
Subject: [PATCH 5/5] Ref #3507085 - Fix coding standards

---
 composer.json                                 |  17 +++
 css/geomap_default_widget.css                 |   8 +-
 js/geomap-default-formatter.js                |  19 ++-
 js/geomap-default-widget.js                   | 124 +++++++++++-------
 .../Field/FieldWidget/GeomapDefault.php       |   2 -
 5 files changed, 105 insertions(+), 65 deletions(-)
 create mode 100644 composer.json

diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..7013482
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,17 @@
+{
+  "name": "ecedi/geomap_field",
+  "description": "Provides geomap fields",
+  "type": "drupal-module",
+  "homepage": "https://www.drupal.org/project/geomap_field",
+  "authors": [
+    {
+      "name": "Marc-Antoine Marty (martygraphie)",
+      "role": "Maintainer"
+    }
+  ],
+  "license": "GPL-2.0-or-later",
+  "require": {
+    "drupal/geolocation_provider": "^1",
+    "drupal/map_provider" : "^1"
+  }
+}
\ No newline at end of file
diff --git a/css/geomap_default_widget.css b/css/geomap_default_widget.css
index 51b95c9..a738477 100644
--- a/css/geomap_default_widget.css
+++ b/css/geomap_default_widget.css
@@ -27,10 +27,10 @@
 .geolocation-suggestions-list {
   position: absolute;
   z-index: 1000;
-  margin: 0;
-  padding: 0;
   bottom: 11px;
   left: 11px;
+  margin: 0;
+  padding: 0;
 }
 
 .geolocation-suggestions-list-item {
@@ -58,14 +58,14 @@
 .geomap-loader {
   position: absolute;
   z-index: 1000;
+  top: 16px;
+  right: 16px;
   width: 42px;
   height: 42px;
   animation: geomap-loader-spin 1s linear infinite;
   border: 8px solid transparent;
   border-top: 8px solid #1f86c7;
   border-radius: 50%;
-  top: 16px;
-  right: 16px;
 }
 
 .geomap-loader[aria-hidden="true"] {
diff --git a/js/geomap-default-formatter.js b/js/geomap-default-formatter.js
index 8bec791..876a766 100644
--- a/js/geomap-default-formatter.js
+++ b/js/geomap-default-formatter.js
@@ -3,20 +3,19 @@
  * Geomap default widget custom behavior
  */
 
-
 (function ($, Drupal) {
   Drupal.behaviors.geomapDefaultFormatter = {
     attach(context) {
-    $(once('geomapDefaultFormatter', '.geomap-formatter-map', context)).on(
-      'map:afterInit',
-      function (event, map) {
-        const mapSettings = $(event.target).data('map');
-        if (mapSettings.center) {
-          const marker = new L.marker(
-            [mapSettings.center[0], mapSettings.center[1]],
-            { draggable: 'false' },
+      $(once('geomapDefaultFormatter', '.geomap-formatter-map', context)).on(
+        'map:afterInit',
+        function (event, map) {
+          const mapSettings = $(event.target).data('map');
+          if (mapSettings.center) {
+            const marker = new L.marker(
+              [mapSettings.center[0], mapSettings.center[1]],
+              { draggable: 'false' },
             );
-          map.addLayer(marker);
+            map.addLayer(marker);
           }
         },
       );
diff --git a/js/geomap-default-widget.js b/js/geomap-default-widget.js
index 8b1f4c6..806543f 100644
--- a/js/geomap-default-widget.js
+++ b/js/geomap-default-widget.js
@@ -20,53 +20,70 @@
 
           const marker = new L.marker(
             [$latField[0].value || 51.505, $lonField[0].value || -0.09],
-            {draggable: 'true'}
+            { draggable: 'true' },
+          );
+          marker.on(
+            'dragend',
+            function (event) {
+              const position = marker.getLatLng();
+              $latField[0].value = position.lat;
+              $lonField[0].value = position.lng;
+              this.updateLoader($widget, true);
+              $.get(
+                `${reverseUrl}/${position.lat}/${position.lng}`,
+                function (data) {
+                  this.updateSuggestions($widget, data);
+                  this.updateLoader($widget, false);
+                  if (data.features && data.features.length > 0) {
+                    this.updateFeatureInput($widget, data.features[0]);
+                  }
+                }.bind(this),
+              );
+            }.bind(this),
           );
-          marker.on('dragend', function (event) {
-            const position = marker.getLatLng();
-            $latField[0].value = position.lat;
-            $lonField[0].value = position.lng;
-            this.updateLoader($widget, true);
-            $.get(`${reverseUrl}/${position.lat}/${position.lng}`, function (data) {
-              this.updateSuggestions($widget, data);
-              this.updateLoader($widget, false);
-              if (data.features && data.features.length > 0) {
-                this.updateFeatureInput($widget, data.features[0]);
-              }
-            }.bind(this));
-          }.bind(this));
           map.addLayer(marker);
           $widget.marker = marker;
 
           // Listen Lat/Lon fields changes.
           $latlon.find('input').on(
             'input',
-            Drupal.debounce(function (event) {
-              this.updateMarker($widget, map);
-            }.bind(this), 200)
+            Drupal.debounce(
+              function (event) {
+                this.updateMarker($widget, map);
+              }.bind(this),
+              200,
+            ),
           );
 
           // Geolocation behavior.
-          $widget.find('.geomap-geolocation-btn').on('click', function (event) {
-            const street = $widget.find('input[name$="][street]"]')[0].value;
-            const zipcode = $widget.find('input[name$="][zipcode]"]')[0].value;
-            const city = $widget.find('input[name$="][city]"]')[0].value;
-            const country = $widget.find('input[name$="][country]"]')[0].value;
-            const address = `${street}, ${zipcode} ${city}, ${country}`;
-            this.updateLoader($widget, true);
-            $.get(`${geolocationUrl}/${address}`, function (data) {
-              this.updateLoader($widget, false);
-              if (data.features && data.features.length > 0) {
-                const feature = data.features[0];
-                $latField[0].value = feature.geometry.coordinates[1];
-                $lonField[0].value = feature.geometry.coordinates[0];
-                this.updateMarker($widget, map);
-                this.updateFeatureInput($widget, feature);
-              }
-            }.bind(this));
-            event.preventDefault();
-          }.bind(this));
-        }.bind(this)
+          $widget.find('.geomap-geolocation-btn').on(
+            'click',
+            function (event) {
+              const street = $widget.find('input[name$="][street]"]')[0].value;
+              const zipcode = $widget.find('input[name$="][zipcode]"]')[0]
+                .value;
+              const city = $widget.find('input[name$="][city]"]')[0].value;
+              const country = $widget.find('input[name$="][country]"]')[0]
+                .value;
+              const address = `${street}, ${zipcode} ${city}, ${country}`;
+              this.updateLoader($widget, true);
+              $.get(
+                `${geolocationUrl}/${address}`,
+                function (data) {
+                  this.updateLoader($widget, false);
+                  if (data.features && data.features.length > 0) {
+                    const feature = data.features[0];
+                    $latField[0].value = feature.geometry.coordinates[1];
+                    $lonField[0].value = feature.geometry.coordinates[0];
+                    this.updateMarker($widget, map);
+                    this.updateFeatureInput($widget, feature);
+                  }
+                }.bind(this),
+              );
+              event.preventDefault();
+            }.bind(this),
+          );
+        }.bind(this),
       );
     },
 
@@ -83,21 +100,27 @@
     },
 
     updateLoader($widget, status) {
-      $widget.find('.geomap-loader').attr('aria-hidden', status ? 'false' : 'true');
+      $widget
+        .find('.geomap-loader')
+        .attr('aria-hidden', status ? 'false' : 'true');
     },
 
     updateSuggestions($widget, featureCollection) {
       const $list = $widget.find('.geolocation-suggestions-list');
       $list.empty();
       const features = featureCollection.features || [];
-      features.forEach(function (feature) {
-        const $item = $('<li>', {class: 'geolocation-suggestions-list-item'});
-        const $btn = $('<button>');
-        $btn.data('feature', feature);
-        $btn.on('click', this.onSuggestionClick.bind(this));
-        $btn.text(feature.properties.label);
-        $list.append($item.append($btn));
-      }.bind(this));
+      features.forEach(
+        function (feature) {
+          const $item = $('<li>', {
+            class: 'geolocation-suggestions-list-item',
+          });
+          const $btn = $('<button>');
+          $btn.data('feature', feature);
+          $btn.on('click', this.onSuggestionClick.bind(this));
+          $btn.get(0).textContent = feature.properties.label;
+          $list.append($item.append($btn));
+        }.bind(this),
+      );
     },
 
     onSuggestionClick(event) {
@@ -105,15 +128,18 @@
       const feature = $suggestion.data('feature');
       // Update address input fields.
       const $widget = $suggestion.parents('.geomap-widget-wrapper');
-      $widget.find('input[name$="][street]"]')[0].value = feature.properties.name;
-      $widget.find('input[name$="][zipcode]"]')[0].value = feature.properties.postcode;
+      $widget.find('input[name$="][street]"]')[0].value =
+        feature.properties.name;
+      $widget.find('input[name$="][zipcode]"]')[0].value =
+        feature.properties.postcode;
       $widget.find('input[name$="][city]"]')[0].value = feature.properties.city;
       this.updateFeatureInput($widget, feature);
       event.preventDefault();
     },
 
     updateFeatureInput($widget, feature) {
-      $widget.find('input[name$="][feature]"]')[0].value = JSON.stringify(feature);
+      $widget.find('input[name$="][feature]"]')[0].value =
+        JSON.stringify(feature);
     },
   };
 })(jQuery, Drupal);
diff --git a/src/Plugin/Field/FieldWidget/GeomapDefault.php b/src/Plugin/Field/FieldWidget/GeomapDefault.php
index 0991a9a..9067cb4 100644
--- a/src/Plugin/Field/FieldWidget/GeomapDefault.php
+++ b/src/Plugin/Field/FieldWidget/GeomapDefault.php
@@ -76,8 +76,6 @@ class GeomapDefault extends WidgetBase {
    */
   public function settingsForm(array $form, FormStateInterface $form_state) {
     $elements = [];
-
-
     $geo_options = [];
     foreach ($this->geolocationManager->getDefinitions() as $id => $definition) {
       $geo_options[$id] = $definition['label'];
-- 
GitLab