mpetazzoni / leaflet-gpx

A GPX track plugin for Leaflet.js
http://mpetazzoni.github.io/leaflet-gpx
BSD 2-Clause "Simplified" License
545 stars 118 forks source link

Module version of the plugin? #153

Closed davidbgk closed 2 months ago

davidbgk commented 6 months ago

Since version 1.9.x of Leaflet, using a module and not relying on the global L object is encouraged.

Is there any plan to head toward that pattern?

mpetazzoni commented 6 months ago

@davidbgk Is there an example of another Leaflet plugin that follows the new pattern? Leaflet's release notes don't really show much information about what plugins are expected to do if they're not supposed to use the L global.

davidbgk commented 6 months ago

@mpetazzoni I'm not sure about other plugins, we had to do some hacks on the uMap side to go that way.

I experimented yesterday:

<script type="module">
  import * as L from 'leaflet.1.9.4.js'
  window.L = L
</script>

And then:

import GPX from 'gpx.1.7.0-custom.js'
new GPX(gpxUrl, {etc})

But I had to customize also the way leaflet-gpx works:

--- gpx.1.7.0.js    2024-03-26 11:54:49
+++ gpx.1.7.0-custom.js 2024-03-25 22:53:59
@@ -36,7 +36,8 @@
  * rendered on the Leaflet map.
  */

-var L = L || require('leaflet');
+var L = window.L
+var GPXTrackIcon

 var _MAX_POINT_INTERVAL_MS = 15000;
 var _SECOND_IN_MILLIS = 1000;
@@ -73,13 +74,13 @@
   joinTrackSegments: true
 };

-L.GPX = L.FeatureGroup.extend({
+const GPX = L.FeatureGroup.extend({
   initialize: function(gpx, options) {
     options.max_point_interval = options.max_point_interval || _MAX_POINT_INTERVAL_MS;
     options.marker_options = this._merge_objs(
       _DEFAULT_MARKER_OPTS,
       options.marker_options || {});
@@ -87,7 +88,7 @@
     L.Util.setOptions(this, options);

     // Base icon class for track pins.
-    L.GPXTrackIcon = L.Icon.extend({ options: options.marker_options });
+    GPXTrackIcon = L.Icon.extend({ options: options.marker_options });

     this._gpx = gpx;
     this._layers = {};
@@ -414,9 +419,9 @@
         } else if (wptIconsType && typeKey && wptIconsType[typeKey]) {
           symIcon = wptIconsType[typeKey];
         } else if (wptIconUrls && symKey && wptIconUrls[symKey]) {
-          symIcon = new L.GPXTrackIcon({iconUrl: wptIconUrls[symKey]});
+          symIcon = new GPXTrackIcon({iconUrl: wptIconUrls[symKey]});
         } else if (wptIconTypeUrls && typeKey && wptIconTypeUrls[typeKey]) {
-          symIcon = new L.GPXTrackIcon({iconUrl: wptIconTypeUrls[typeKey]});
+          symIcon = new GPXTrackIcon({iconUrl: wptIconTypeUrls[typeKey]});
         } else if (ptMatchers.length > 0) {
           for (var j = 0; j < ptMatchers.length; j++) {
             if (ptMatchers[j].regex.test(name)) {
@@ -427,7 +432,7 @@
         } else if (wptIcons && wptIcons['']) {
           symIcon = wptIcons[''];
         } else if (wptIconUrls && wptIconUrls['']) {
-          symIcon = new L.GPXTrackIcon({iconUrl: wptIconUrls['']});
+          symIcon = new GPXTrackIcon({iconUrl: wptIconUrls['']});
         }

         if (!symIcon) {
@@ -575,7 +580,7 @@
       // add start pin
       var marker = new L.Marker(coords[0], {
         clickable: options.marker_options.clickable,
-        icon: options.marker_options.startIcon || new L.GPXTrackIcon({iconUrl: options.marker_options.startIconUrl})
+        icon: options.marker_options.startIcon || new GPXTrackIcon({iconUrl: options.marker_options.startIconUrl})
       });
       this.fire('addpoint', { point: marker, point_type: 'start', element: el[0] });
       layers.push(marker);
@@ -585,7 +590,7 @@
       // add end pin
       var marker = new L.Marker(coords[coords.length-1], {
         clickable: options.marker_options.clickable,
-        icon: options.marker_options.endIcon || new L.GPXTrackIcon({iconUrl: options.marker_options.endIconUrl})
+        icon: options.marker_options.endIcon || new GPXTrackIcon({iconUrl: options.marker_options.endIconUrl})
       });
       this.fire('addpoint', { point: marker, point_type: 'end', element: el[el.length-1] });
       layers.push(marker);
@@ -653,8 +669,4 @@
   }
 });

-if (typeof module === 'object' && typeof module.exports === 'object') {
-  module.exports = L;
-} else if (typeof define === 'function' && define.amd) {
-  define(L);
-}
+export default GPX

This is really a draft/intention, not something that can merged as is but it gives a direction to make it work for my case.

Would it be useful to continue that work and plan a 1.9.x release that matches the Leaflet latest one?

davidbgk commented 6 months ago

There is a live example here.

raveman commented 5 months ago

@davidbgk worked this patch for me when using importmap in rails 7 project in Hotwire controller.

Thanx!

mpetazzoni commented 2 months ago

This should work out of the box now using ECMAScript modules standard techniques. I've updated the README with the recommended approaches for importing leaflet-gpx from both module and non-module contexts (with dynamic import). Let me know if you're experiencing any issues working with this latest 2.1.0 version!