leaflet-rails 1.8.0 → 1.9.0

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.
@@ -1,5 +1,5 @@
1
1
  /* @preserve
2
- * Leaflet 1.8.0, a JS library for interactive maps. https://leafletjs.com
2
+ * Leaflet 1.9.0+main.a7e1bbc, a JS library for interactive maps. https://leafletjs.com
3
3
  * (c) 2010-2022 Vladimir Agafonkin, (c) 2010-2011 CloudMade
4
4
  */
5
5
 
@@ -9,7 +9,7 @@
9
9
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.leaflet = {}));
10
10
  })(this, (function (exports) { 'use strict';
11
11
 
12
- var version = "1.8.0";
12
+ var version = "1.9.0+main.a7e1bbcb";
13
13
 
14
14
  /*
15
15
  * @namespace Util
@@ -505,35 +505,30 @@
505
505
  },
506
506
 
507
507
  // attach listener (without syntactic sugar now)
508
- _on: function (type, fn, context) {
508
+ _on: function (type, fn, context, _once) {
509
509
  if (typeof fn !== 'function') {
510
510
  console.warn('wrong listener type: ' + typeof fn);
511
511
  return;
512
512
  }
513
- this._events = this._events || {};
514
513
 
515
- /* get/init listeners for type */
516
- var typeListeners = this._events[type];
517
- if (!typeListeners) {
518
- typeListeners = [];
519
- this._events[type] = typeListeners;
514
+ // check if fn already there
515
+ if (this._listens(type, fn, context) !== false) {
516
+ return;
520
517
  }
521
518
 
522
519
  if (context === this) {
523
520
  // Less memory footprint.
524
521
  context = undefined;
525
522
  }
526
- var newListener = {fn: fn, ctx: context},
527
- listeners = typeListeners;
528
523
 
529
- // check if fn already there
530
- for (var i = 0, len = listeners.length; i < len; i++) {
531
- if (listeners[i].fn === fn && listeners[i].ctx === context) {
532
- return;
533
- }
524
+ var newListener = {fn: fn, ctx: context};
525
+ if (_once) {
526
+ newListener.once = true;
534
527
  }
535
528
 
536
- listeners.push(newListener);
529
+ this._events = this._events || {};
530
+ this._events[type] = this._events[type] || [];
531
+ this._events[type].push(newListener);
537
532
  },
538
533
 
539
534
  _off: function (type, fn, context) {
@@ -541,10 +536,11 @@
541
536
  i,
542
537
  len;
543
538
 
544
- if (!this._events) { return; }
539
+ if (!this._events) {
540
+ return;
541
+ }
545
542
 
546
543
  listeners = this._events[type];
547
-
548
544
  if (!listeners) {
549
545
  return;
550
546
  }
@@ -562,32 +558,24 @@
562
558
  return;
563
559
  }
564
560
 
565
- if (context === this) {
566
- context = undefined;
567
- }
568
-
569
561
  if (typeof fn !== 'function') {
570
562
  console.warn('wrong listener type: ' + typeof fn);
571
563
  return;
572
564
  }
565
+
573
566
  // find fn and remove it
574
- for (i = 0, len = listeners.length; i < len; i++) {
575
- var l = listeners[i];
576
- if (l.ctx !== context) { continue; }
577
- if (l.fn === fn) {
578
- if (this._firingCount) {
579
- // set the removed listener to noop so that's not called if remove happens in fire
580
- l.fn = falseFn;
581
-
582
- /* copy array in case events are being fired */
583
- this._events[type] = listeners = listeners.slice();
584
- }
585
- listeners.splice(i, 1);
567
+ var index = this._listens(type, fn, context);
568
+ if (index !== false) {
569
+ var listener = listeners[index];
570
+ if (this._firingCount) {
571
+ // set the removed listener to noop so that's not called if remove happens in fire
572
+ listener.fn = falseFn;
586
573
 
587
- return;
574
+ /* copy array in case events are being fired */
575
+ this._events[type] = listeners = listeners.slice();
588
576
  }
577
+ listeners.splice(index, 1);
589
578
  }
590
- console.warn('listener not found');
591
579
  },
592
580
 
593
581
  // @method fire(type: String, data?: Object, propagate?: Boolean): this
@@ -605,12 +593,16 @@
605
593
 
606
594
  if (this._events) {
607
595
  var listeners = this._events[type];
608
-
609
596
  if (listeners) {
610
597
  this._firingCount = (this._firingCount + 1) || 1;
611
598
  for (var i = 0, len = listeners.length; i < len; i++) {
612
599
  var l = listeners[i];
613
- l.fn.call(l.ctx || this, event);
600
+ // off overwrites l.fn, so we need to copy fn to a var
601
+ var fn = l.fn;
602
+ if (l.once) {
603
+ this.off(type, fn, l.ctx);
604
+ }
605
+ fn.call(l.ctx || this, event);
614
606
  }
615
607
 
616
608
  this._firingCount--;
@@ -626,45 +618,83 @@
626
618
  },
627
619
 
628
620
  // @method listens(type: String, propagate?: Boolean): Boolean
621
+ // @method listens(type: String, fn: Function, context?: Object, propagate?: Boolean): Boolean
629
622
  // Returns `true` if a particular event type has any listeners attached to it.
630
623
  // The verification can optionally be propagated, it will return `true` if parents have the listener attached to it.
631
- listens: function (type, propagate) {
624
+ listens: function (type, fn, context, propagate) {
632
625
  if (typeof type !== 'string') {
633
626
  console.warn('"string" type argument expected');
634
627
  }
628
+
629
+ if (typeof fn !== 'function') {
630
+ propagate = !!fn;
631
+ fn = undefined;
632
+ context = undefined;
633
+ }
634
+
635
635
  var listeners = this._events && this._events[type];
636
- if (listeners && listeners.length) { return true; }
636
+ if (listeners && listeners.length) {
637
+ if (this._listens(type, fn, context) !== false) {
638
+ return true;
639
+ }
640
+ }
637
641
 
638
642
  if (propagate) {
639
643
  // also check parents for listeners if event propagates
640
644
  for (var id in this._eventParents) {
641
- if (this._eventParents[id].listens(type, propagate)) { return true; }
645
+ if (this._eventParents[id].listens(type, fn, context, propagate)) { return true; }
646
+ }
647
+ }
648
+ return false;
649
+ },
650
+
651
+ // returns the index (number) or false
652
+ _listens: function (type, fn, context) {
653
+ if (!this._events) {
654
+ return false;
655
+ }
656
+
657
+ var listeners = this._events[type] || [];
658
+ if (!fn) {
659
+ return !!listeners.length;
660
+ }
661
+
662
+ if (context === this) {
663
+ // Less memory footprint.
664
+ context = undefined;
665
+ }
666
+
667
+ for (var i = 0, len = listeners.length; i < len; i++) {
668
+ if (listeners[i].fn === fn && listeners[i].ctx === context) {
669
+ return i;
642
670
  }
643
671
  }
644
672
  return false;
673
+
645
674
  },
646
675
 
647
676
  // @method once(…): this
648
677
  // Behaves as [`on(…)`](#evented-on), except the listener will only get fired once and then removed.
649
678
  once: function (types, fn, context) {
650
679
 
680
+ // types can be a map of types/handlers
651
681
  if (typeof types === 'object') {
652
682
  for (var type in types) {
653
- this.once(type, types[type], fn);
683
+ // we don't process space-separated events here for performance;
684
+ // it's a hot path since Layer uses the on(obj) syntax
685
+ this._on(type, types[type], fn, true);
654
686
  }
655
- return this;
656
- }
657
687
 
658
- var handler = bind(function () {
659
- this
660
- .off(types, fn, context)
661
- .off(types, handler, context);
662
- }, this);
688
+ } else {
689
+ // types can be a string of space-separated words
690
+ types = splitWords(types);
691
+
692
+ for (var i = 0, len = types.length; i < len; i++) {
693
+ this._on(types[i], fn, context, true);
694
+ }
695
+ }
663
696
 
664
- // add a listener that's executed once and removed after that
665
- return this
666
- .on(types, fn, context)
667
- .on(types, handler, context);
697
+ return this;
668
698
  },
669
699
 
670
700
  // @method addEventParent(obj: Evented): this
@@ -980,21 +1010,36 @@
980
1010
  Bounds.prototype = {
981
1011
  // @method extend(point: Point): this
982
1012
  // Extends the bounds to contain the given point.
983
- extend: function (point) { // (Point)
984
- point = toPoint(point);
1013
+
1014
+ // @alternative
1015
+ // @method extend(otherBounds: Bounds): this
1016
+ // Extend the bounds to contain the given bounds
1017
+ extend: function (obj) {
1018
+ var min2, max2;
1019
+ if (!obj) { return this; }
1020
+
1021
+ if (obj instanceof Point || typeof obj[0] === 'number' || 'x' in obj) {
1022
+ min2 = max2 = toPoint(obj);
1023
+ } else {
1024
+ obj = toBounds(obj);
1025
+ min2 = obj.min;
1026
+ max2 = obj.max;
1027
+
1028
+ if (!min2 || !max2) { return this; }
1029
+ }
985
1030
 
986
1031
  // @property min: Point
987
1032
  // The top left corner of the rectangle.
988
1033
  // @property max: Point
989
1034
  // The bottom right corner of the rectangle.
990
1035
  if (!this.min && !this.max) {
991
- this.min = point.clone();
992
- this.max = point.clone();
1036
+ this.min = min2.clone();
1037
+ this.max = max2.clone();
993
1038
  } else {
994
- this.min.x = Math.min(point.x, this.min.x);
995
- this.max.x = Math.max(point.x, this.max.x);
996
- this.min.y = Math.min(point.y, this.min.y);
997
- this.max.y = Math.max(point.y, this.max.y);
1039
+ this.min.x = Math.min(min2.x, this.min.x);
1040
+ this.max.x = Math.max(max2.x, this.max.x);
1041
+ this.min.y = Math.min(min2.y, this.min.y);
1042
+ this.max.y = Math.max(max2.y, this.max.y);
998
1043
  }
999
1044
  return this;
1000
1045
  },
@@ -1002,7 +1047,7 @@
1002
1047
  // @method getCenter(round?: Boolean): Point
1003
1048
  // Returns the center point of the bounds.
1004
1049
  getCenter: function (round) {
1005
- return new Point(
1050
+ return toPoint(
1006
1051
  (this.min.x + this.max.x) / 2,
1007
1052
  (this.min.y + this.max.y) / 2, round);
1008
1053
  },
@@ -1010,13 +1055,13 @@
1010
1055
  // @method getBottomLeft(): Point
1011
1056
  // Returns the bottom-left point of the bounds.
1012
1057
  getBottomLeft: function () {
1013
- return new Point(this.min.x, this.max.y);
1058
+ return toPoint(this.min.x, this.max.y);
1014
1059
  },
1015
1060
 
1016
1061
  // @method getTopRight(): Point
1017
1062
  // Returns the top-right point of the bounds.
1018
1063
  getTopRight: function () { // -> Point
1019
- return new Point(this.max.x, this.min.y);
1064
+ return toPoint(this.max.x, this.min.y);
1020
1065
  },
1021
1066
 
1022
1067
  // @method getTopLeft(): Point
@@ -1096,9 +1141,40 @@
1096
1141
  return xOverlaps && yOverlaps;
1097
1142
  },
1098
1143
 
1144
+ // @method isValid(): Boolean
1145
+ // Returns `true` if the bounds are properly initialized.
1099
1146
  isValid: function () {
1100
1147
  return !!(this.min && this.max);
1101
- }
1148
+ },
1149
+
1150
+
1151
+ // @method pad(bufferRatio: Number): Bounds
1152
+ // Returns bounds created by extending or retracting the current bounds by a given ratio in each direction.
1153
+ // For example, a ratio of 0.5 extends the bounds by 50% in each direction.
1154
+ // Negative values will retract the bounds.
1155
+ pad: function (bufferRatio) {
1156
+ var min = this.min,
1157
+ max = this.max,
1158
+ heightBuffer = Math.abs(min.x - max.x) * bufferRatio,
1159
+ widthBuffer = Math.abs(min.y - max.y) * bufferRatio;
1160
+
1161
+
1162
+ return toBounds(
1163
+ toPoint(min.x - heightBuffer, min.y - widthBuffer),
1164
+ toPoint(max.x + heightBuffer, max.y + widthBuffer));
1165
+ },
1166
+
1167
+
1168
+ // @method equals(otherBounds: Bounds, maxMargin?: Number): Boolean
1169
+ // Returns `true` if the rectangle is equivalent (within a small margin of error) to the given bounds. The margin of error can be overridden by setting `maxMargin` to a small number.
1170
+ equals: function (bounds) {
1171
+ if (!bounds) { return false; }
1172
+
1173
+ bounds = toBounds(bounds);
1174
+
1175
+ return this.min.equals(bounds.getTopLeft()) &&
1176
+ this.max.equals(bounds.getBottomRight());
1177
+ },
1102
1178
  };
1103
1179
 
1104
1180
 
@@ -2006,6 +2082,13 @@
2006
2082
  }
2007
2083
  }());
2008
2084
 
2085
+
2086
+ // @property mac: Boolean; `true` when the browser is running in a Mac platform
2087
+ var mac = navigator.platform.indexOf('Mac') === 0;
2088
+
2089
+ // @property mac: Boolean; `true` when the browser is running in a Linux platform
2090
+ var linux = navigator.platform.indexOf('Linux') === 0;
2091
+
2009
2092
  function userAgentContains(str) {
2010
2093
  return navigator.userAgent.toLowerCase().indexOf(str) >= 0;
2011
2094
  }
@@ -2044,7 +2127,9 @@
2044
2127
  canvas: canvas$1,
2045
2128
  svg: svg$1,
2046
2129
  vml: vml,
2047
- inlineSvg: inlineSvg
2130
+ inlineSvg: inlineSvg,
2131
+ mac: mac,
2132
+ linux: linux
2048
2133
  };
2049
2134
 
2050
2135
  /*
@@ -2187,6 +2272,25 @@
2187
2272
  return;
2188
2273
  }
2189
2274
 
2275
+ // When clicking on an <input>, the browser generates a click on its
2276
+ // <label> (and vice versa) triggering two clicks in quick succession.
2277
+ // This ignores clicks on elements which are a label with a 'for'
2278
+ // attribute (or children of such a label), but not children of
2279
+ // a <input>.
2280
+ var path = getPropagationPath(e);
2281
+ if (path.some(function (el) {
2282
+ return el instanceof HTMLLabelElement && el.attributes.for;
2283
+ }) &&
2284
+ !path.some(function (el) {
2285
+ return (
2286
+ el instanceof HTMLInputElement ||
2287
+ el instanceof HTMLSelectElement
2288
+ );
2289
+ })
2290
+ ) {
2291
+ return;
2292
+ }
2293
+
2190
2294
  var now = Date.now();
2191
2295
  if (now - last <= delay) {
2192
2296
  detail++;
@@ -2808,6 +2912,26 @@
2808
2912
  return this;
2809
2913
  }
2810
2914
 
2915
+ // @function getPropagationPath(ev: DOMEvent): Array
2916
+ // Compatibility polyfill for [`Event.composedPath()`](https://developer.mozilla.org/en-US/docs/Web/API/Event/composedPath).
2917
+ // Returns an array containing the `HTMLElement`s that the given DOM event
2918
+ // should propagate to (if not stopped).
2919
+ function getPropagationPath(ev) {
2920
+ if (ev.composedPath) {
2921
+ return ev.composedPath();
2922
+ }
2923
+
2924
+ var path = [];
2925
+ var el = ev.target;
2926
+
2927
+ while (el) {
2928
+ path.push(el);
2929
+ el = el.parentNode;
2930
+ }
2931
+ return path;
2932
+ }
2933
+
2934
+
2811
2935
  // @function getMousePosition(ev: DOMEvent, container?: HTMLElement): Point
2812
2936
  // Gets normalized mouse position from a DOM event relative to the
2813
2937
  // `container` (border excluded) or to the whole page if not specified.
@@ -2827,12 +2951,15 @@
2827
2951
  );
2828
2952
  }
2829
2953
 
2830
- // Chrome on Win scrolls double the pixels as in other platforms (see #4538),
2831
- // and Firefox scrolls device pixels, not CSS pixels
2832
- var wheelPxFactor =
2833
- (Browser.win && Browser.chrome) ? 2 * window.devicePixelRatio :
2834
- Browser.gecko ? window.devicePixelRatio : 1;
2835
2954
 
2955
+ // except , Safari and
2956
+ // We need double the scroll pixels (see #7403 and #4538) for all Browsers
2957
+ // except OSX (Mac) -> 3x, Chrome running on Linux 1x
2958
+
2959
+ var wheelPxFactor =
2960
+ (Browser.linux && Browser.chrome) ? window.devicePixelRatio :
2961
+ Browser.mac ? window.devicePixelRatio * 3 :
2962
+ window.devicePixelRatio > 0 ? 2 * window.devicePixelRatio : 1;
2836
2963
  // @function getWheelDelta(ev: DOMEvent): Number
2837
2964
  // Gets normalized wheel delta from a wheel DOM event, in vertical
2838
2965
  // pixels scrolled (negative if scrolling down).
@@ -2876,6 +3003,7 @@
2876
3003
  disableClickPropagation: disableClickPropagation,
2877
3004
  preventDefault: preventDefault,
2878
3005
  stop: stop,
3006
+ getPropagationPath: getPropagationPath,
2879
3007
  getMousePosition: getMousePosition,
2880
3008
  getWheelDelta: getWheelDelta,
2881
3009
  isExternalTarget: isExternalTarget,
@@ -2891,8 +3019,21 @@
2891
3019
  *
2892
3020
  * @example
2893
3021
  * ```js
2894
- * var fx = new L.PosAnimation();
2895
- * fx.run(el, [300, 500], 0.5);
3022
+ * var myPositionMarker = L.marker([48.864716, 2.294694]).addTo(map);
3023
+ *
3024
+ * myPositionMarker.on("click", function() {
3025
+ * var pos = map.latLngToLayerPoint(myPositionMarker.getLatLng());
3026
+ * pos.y -= 25;
3027
+ * var fx = new L.PosAnimation();
3028
+ *
3029
+ * fx.once('end',function() {
3030
+ * pos.y += 25;
3031
+ * fx.run(myPositionMarker._icon, pos, 0.8);
3032
+ * });
3033
+ *
3034
+ * fx.run(myPositionMarker._icon, pos, 0.3);
3035
+ * });
3036
+ *
2896
3037
  * ```
2897
3038
  *
2898
3039
  * @constructor L.PosAnimation()
@@ -3172,7 +3313,7 @@
3172
3313
  }
3173
3314
 
3174
3315
  // animation didn't start, just reset the map view
3175
- this._resetView(center, zoom);
3316
+ this._resetView(center, zoom, options.pan && options.pan.noMoveStart);
3176
3317
 
3177
3318
  return this;
3178
3319
  },
@@ -3415,11 +3556,13 @@
3415
3556
  setMaxBounds: function (bounds) {
3416
3557
  bounds = toLatLngBounds(bounds);
3417
3558
 
3559
+ if (this.listens('moveend', this._panInsideMaxBounds)) {
3560
+ this.off('moveend', this._panInsideMaxBounds);
3561
+ }
3562
+
3418
3563
  if (!bounds.isValid()) {
3419
3564
  this.options.maxBounds = null;
3420
- return this.off('moveend', this._panInsideMaxBounds);
3421
- } else if (this.options.maxBounds) {
3422
- this.off('moveend', this._panInsideMaxBounds);
3565
+ return this;
3423
3566
  }
3424
3567
 
3425
3568
  this.options.maxBounds = bounds;
@@ -3789,7 +3932,7 @@
3789
3932
  this._checkIfLoaded();
3790
3933
 
3791
3934
  if (this._lastCenter && !this._moved()) {
3792
- return this._lastCenter;
3935
+ return this._lastCenter.clone();
3793
3936
  }
3794
3937
  return this.layerPointToLatLng(this._getCenterLayerPoint());
3795
3938
  },
@@ -4138,7 +4281,7 @@
4138
4281
  // private methods that modify map state
4139
4282
 
4140
4283
  // @section Map state change events
4141
- _resetView: function (center, zoom) {
4284
+ _resetView: function (center, zoom, noMoveStart) {
4142
4285
  setPosition(this._mapPane, new Point(0, 0));
4143
4286
 
4144
4287
  var loading = !this._loaded;
@@ -4149,7 +4292,7 @@
4149
4292
 
4150
4293
  var zoomChanged = this._zoom !== zoom;
4151
4294
  this
4152
- ._moveStart(zoomChanged, false)
4295
+ ._moveStart(zoomChanged, noMoveStart)
4153
4296
  ._move(center, zoom)
4154
4297
  ._moveEnd(zoomChanged);
4155
4298
 
@@ -4346,7 +4489,7 @@
4346
4489
  },
4347
4490
 
4348
4491
  _isClickDisabled: function (el) {
4349
- while (el !== this._container) {
4492
+ while (el && el !== this._container) {
4350
4493
  if (el['_leaflet_disable_click']) { return true; }
4351
4494
  el = el.parentNode;
4352
4495
  }
@@ -5572,7 +5715,7 @@
5572
5715
  return new Scale(options);
5573
5716
  };
5574
5717
 
5575
- var ukrainianFlag = '<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="12" height="8"><path fill="#4C7BE1" d="M0 0h12v4H0z"/><path fill="#FFD500" d="M0 4h12v3H0z"/><path fill="#E0BC00" d="M0 7h12v1H0z"/></svg>';
5718
+ var ukrainianFlag = '<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="12" height="8" viewBox="0 0 12 8" class="leaflet-attribution-flag"><path fill="#4C7BE1" d="M0 0h12v4H0z"/><path fill="#FFD500" d="M0 4h12v3H0z"/><path fill="#E0BC00" d="M0 7h12v1H0z"/></svg>';
5576
5719
 
5577
5720
 
5578
5721
  /*
@@ -5641,7 +5784,7 @@
5641
5784
  },
5642
5785
 
5643
5786
  // @method addAttribution(text: String): this
5644
- // Adds an attribution text (e.g. `'Vector data &copy; Mapbox'`).
5787
+ // Adds an attribution text (e.g. `'&copy; OpenStreetMap contributors'`).
5645
5788
  addAttribution: function (text) {
5646
5789
  if (!text) { return this; }
5647
5790
 
@@ -6233,6 +6376,55 @@
6233
6376
  return isFlat(latlngs);
6234
6377
  }
6235
6378
 
6379
+ /* @function polylineCenter(latlngs: LatLng[], crs: CRS): LatLng
6380
+ * Returns the center ([centroid](http://en.wikipedia.org/wiki/Centroid)) of the passed LatLngs (first ring) from a polyline.
6381
+ */
6382
+ function polylineCenter(latlngs, crs) {
6383
+ var i, halfDist, segDist, dist, p1, p2, ratio, center;
6384
+
6385
+ if (!latlngs || latlngs.length === 0) {
6386
+ throw new Error('latlngs not passed');
6387
+ }
6388
+
6389
+ if (!isFlat(latlngs)) {
6390
+ console.warn('latlngs are not flat! Only the first ring will be used');
6391
+ latlngs = latlngs[0];
6392
+ }
6393
+
6394
+ var points = [];
6395
+ for (var j in latlngs) {
6396
+ points.push(crs.project(toLatLng(latlngs[j])));
6397
+ }
6398
+
6399
+ var len = points.length;
6400
+
6401
+ for (i = 0, halfDist = 0; i < len - 1; i++) {
6402
+ halfDist += points[i].distanceTo(points[i + 1]) / 2;
6403
+ }
6404
+
6405
+ // The line is so small in the current view that all points are on the same pixel.
6406
+ if (halfDist === 0) {
6407
+ center = points[0];
6408
+ } else {
6409
+ for (i = 0, dist = 0; i < len - 1; i++) {
6410
+ p1 = points[i];
6411
+ p2 = points[i + 1];
6412
+ segDist = p1.distanceTo(p2);
6413
+ dist += segDist;
6414
+
6415
+ if (dist > halfDist) {
6416
+ ratio = (dist - halfDist) / segDist;
6417
+ center = [
6418
+ p2.x - ratio * (p2.x - p1.x),
6419
+ p2.y - ratio * (p2.y - p1.y)
6420
+ ];
6421
+ break;
6422
+ }
6423
+ }
6424
+ }
6425
+ return crs.unproject(toPoint(center));
6426
+ }
6427
+
6236
6428
  var LineUtil = {
6237
6429
  __proto__: null,
6238
6430
  simplify: simplify,
@@ -6243,7 +6435,8 @@
6243
6435
  _getBitCode: _getBitCode,
6244
6436
  _sqClosestPointOnSegment: _sqClosestPointOnSegment,
6245
6437
  isFlat: isFlat,
6246
- _flat: _flat
6438
+ _flat: _flat,
6439
+ polylineCenter: polylineCenter
6247
6440
  };
6248
6441
 
6249
6442
  /*
@@ -6300,9 +6493,53 @@
6300
6493
  return points;
6301
6494
  }
6302
6495
 
6496
+ /* @function polygonCenter(latlngs: LatLng[] crs: CRS): LatLng
6497
+ * Returns the center ([centroid](http://en.wikipedia.org/wiki/Centroid)) of the passed LatLngs (first ring) from a polygon.
6498
+ */
6499
+ function polygonCenter(latlngs, crs) {
6500
+ var i, j, p1, p2, f, area, x, y, center;
6501
+
6502
+ if (!latlngs || latlngs.length === 0) {
6503
+ throw new Error('latlngs not passed');
6504
+ }
6505
+
6506
+ if (!isFlat(latlngs)) {
6507
+ console.warn('latlngs are not flat! Only the first ring will be used');
6508
+ latlngs = latlngs[0];
6509
+ }
6510
+
6511
+ var points = [];
6512
+ for (var k in latlngs) {
6513
+ points.push(crs.project(toLatLng(latlngs[k])));
6514
+ }
6515
+
6516
+ var len = points.length;
6517
+ area = x = y = 0;
6518
+
6519
+ // polygon centroid algorithm;
6520
+ for (i = 0, j = len - 1; i < len; j = i++) {
6521
+ p1 = points[i];
6522
+ p2 = points[j];
6523
+
6524
+ f = p1.y * p2.x - p2.y * p1.x;
6525
+ x += (p1.x + p2.x) * f;
6526
+ y += (p1.y + p2.y) * f;
6527
+ area += f * 3;
6528
+ }
6529
+
6530
+ if (area === 0) {
6531
+ // Polygon is so small that all points are on same pixel.
6532
+ center = points[0];
6533
+ } else {
6534
+ center = [x / area, y / area];
6535
+ }
6536
+ return crs.unproject(toPoint(center));
6537
+ }
6538
+
6303
6539
  var PolyUtil = {
6304
6540
  __proto__: null,
6305
- clipPolygon: clipPolygon
6541
+ clipPolygon: clipPolygon,
6542
+ polygonCenter: polygonCenter
6306
6543
  };
6307
6544
 
6308
6545
  /*
@@ -8261,38 +8498,7 @@
8261
8498
  if (!this._map) {
8262
8499
  throw new Error('Must add layer to map before using getCenter()');
8263
8500
  }
8264
-
8265
- var i, halfDist, segDist, dist, p1, p2, ratio,
8266
- points = this._rings[0],
8267
- len = points.length;
8268
-
8269
- if (!len) { return null; }
8270
-
8271
- // polyline centroid algorithm; only uses the first ring if there are multiple
8272
-
8273
- for (i = 0, halfDist = 0; i < len - 1; i++) {
8274
- halfDist += points[i].distanceTo(points[i + 1]) / 2;
8275
- }
8276
-
8277
- // The line is so small in the current view that all points are on the same pixel.
8278
- if (halfDist === 0) {
8279
- return this._map.layerPointToLatLng(points[0]);
8280
- }
8281
-
8282
- for (i = 0, dist = 0; i < len - 1; i++) {
8283
- p1 = points[i];
8284
- p2 = points[i + 1];
8285
- segDist = p1.distanceTo(p2);
8286
- dist += segDist;
8287
-
8288
- if (dist > halfDist) {
8289
- ratio = (dist - halfDist) / segDist;
8290
- return this._map.layerPointToLatLng([
8291
- p2.x - ratio * (p2.x - p1.x),
8292
- p2.y - ratio * (p2.y - p1.y)
8293
- ]);
8294
- }
8295
- }
8501
+ return polylineCenter(this._defaultShape(), this._map.options.crs);
8296
8502
  },
8297
8503
 
8298
8504
  // @method getBounds(): LatLngBounds
@@ -8534,39 +8740,14 @@
8534
8740
  return !this._latlngs.length || !this._latlngs[0].length;
8535
8741
  },
8536
8742
 
8743
+ // @method getCenter(): LatLng
8744
+ // Returns the center ([centroid](http://en.wikipedia.org/wiki/Centroid)) of the Polygon.
8537
8745
  getCenter: function () {
8538
8746
  // throws error when not yet added to map as this center calculation requires projected coordinates
8539
8747
  if (!this._map) {
8540
8748
  throw new Error('Must add layer to map before using getCenter()');
8541
8749
  }
8542
-
8543
- var i, j, p1, p2, f, area, x, y, center,
8544
- points = this._rings[0],
8545
- len = points.length;
8546
-
8547
- if (!len) { return null; }
8548
-
8549
- // polygon centroid algorithm; only uses the first ring if there are multiple
8550
-
8551
- area = x = y = 0;
8552
-
8553
- for (i = 0, j = len - 1; i < len; j = i++) {
8554
- p1 = points[i];
8555
- p2 = points[j];
8556
-
8557
- f = p1.y * p2.x - p2.y * p1.x;
8558
- x += (p1.x + p2.x) * f;
8559
- y += (p1.y + p2.y) * f;
8560
- area += f * 3;
8561
- }
8562
-
8563
- if (area === 0) {
8564
- // Polygon is so small that all points are on same pixel.
8565
- center = points[0];
8566
- } else {
8567
- center = [x / area, y / area];
8568
- }
8569
- return this._map.layerPointToLatLng(center);
8750
+ return polygonCenter(this._defaultShape(), this._map.options.crs);
8570
8751
  },
8571
8752
 
8572
8753
  _convertLatLngs: function (latlngs) {
@@ -8851,14 +9032,24 @@
8851
9032
 
8852
9033
  case 'GeometryCollection':
8853
9034
  for (i = 0, len = geometry.geometries.length; i < len; i++) {
8854
- var layer = geometryToLayer({
9035
+ var geoLayer = geometryToLayer({
8855
9036
  geometry: geometry.geometries[i],
8856
9037
  type: 'Feature',
8857
9038
  properties: geojson.properties
8858
9039
  }, options);
8859
9040
 
8860
- if (layer) {
8861
- layers.push(layer);
9041
+ if (geoLayer) {
9042
+ layers.push(geoLayer);
9043
+ }
9044
+ }
9045
+ return new FeatureGroup(layers);
9046
+
9047
+ case 'FeatureCollection':
9048
+ for (i = 0, len = geometry.features.length; i < len; i++) {
9049
+ var featureLayer = geometryToLayer(geometry.features[i], options);
9050
+
9051
+ if (featureLayer) {
9052
+ layers.push(featureLayer);
8862
9053
  }
8863
9054
  }
8864
9055
  return new FeatureGroup(layers);
@@ -8917,8 +9108,9 @@
8917
9108
  var coords = [];
8918
9109
 
8919
9110
  for (var i = 0, len = latlngs.length; i < len; i++) {
9111
+ // Check for flat arrays required to ensure unbalanced arrays are correctly converted in recursion
8920
9112
  coords.push(levelsDeep ?
8921
- latLngsToCoords(latlngs[i], levelsDeep - 1, closed, precision) :
9113
+ latLngsToCoords(latlngs[i], isFlat(latlngs[i]) ? 0 : levelsDeep - 1, closed, precision) :
8922
9114
  latLngToCoords(latlngs[i], precision));
8923
9115
  }
8924
9116
 
@@ -9527,13 +9719,25 @@
9527
9719
 
9528
9720
  // @option pane: String = undefined
9529
9721
  // `Map pane` where the overlay will be added.
9530
- pane: undefined
9722
+ pane: undefined,
9723
+
9724
+ // @option content: String|HTMLElement|Function = ''
9725
+ // Sets the HTML content of the overlay while initializing. If a function is passed the source layer will be
9726
+ // passed to the function. The function should return a `String` or `HTMLElement` to be used in the overlay.
9727
+ content: ''
9531
9728
  },
9532
9729
 
9533
9730
  initialize: function (options, source) {
9534
- setOptions(this, options);
9535
-
9536
- this._source = source;
9731
+ if (options && (options instanceof L.LatLng || isArray(options))) {
9732
+ this._latlng = toLatLng(options);
9733
+ setOptions(this, source);
9734
+ } else {
9735
+ setOptions(this, options);
9736
+ this._source = source;
9737
+ }
9738
+ if (this.options.content) {
9739
+ this._content = this.options.content;
9740
+ }
9537
9741
  },
9538
9742
 
9539
9743
  // @method openOn(map: Map): this
@@ -9845,7 +10049,8 @@
9845
10049
  * marker.bindPopup(popupContent).openPopup();
9846
10050
  * ```
9847
10051
  * Path overlays like polylines also have a `bindPopup` method.
9848
- * Here's a more complicated way to open a popup on a map:
10052
+ *
10053
+ * A popup can be also standalone:
9849
10054
  *
9850
10055
  * ```js
9851
10056
  * var popup = L.popup()
@@ -9853,6 +10058,11 @@
9853
10058
  * .setContent('<p>Hello world!<br />This is a nice popup.</p>')
9854
10059
  * .openOn(map);
9855
10060
  * ```
10061
+ * or
10062
+ * ```js
10063
+ * var popup = L.popup(latlng, {content: '<p>Hello world!<br />This is a nice popup.</p>')
10064
+ * .openOn(map);
10065
+ * ```
9856
10066
  */
9857
10067
 
9858
10068
 
@@ -9881,6 +10091,8 @@
9881
10091
  // @option maxHeight: Number = null
9882
10092
  // If set, creates a scrollable container of the given height
9883
10093
  // inside a popup if its content exceeds it.
10094
+ // The scrollable container can be styled using the
10095
+ // `leaflet-popup-scrolled` CSS class selector.
9884
10096
  maxHeight: null,
9885
10097
 
9886
10098
  // @option autoPan: Boolean = true
@@ -10026,7 +10238,10 @@
10026
10238
  closeButton.href = '#close';
10027
10239
  closeButton.innerHTML = '<span aria-hidden="true">&#215;</span>';
10028
10240
 
10029
- on(closeButton, 'click', this.close, this);
10241
+ on(closeButton, 'click', function (ev) {
10242
+ preventDefault(ev);
10243
+ this.close();
10244
+ }, this);
10030
10245
  }
10031
10246
  },
10032
10247
 
@@ -10120,6 +10335,9 @@
10120
10335
  // @namespace Popup
10121
10336
  // @factory L.popup(options?: Popup options, source?: Layer)
10122
10337
  // Instantiates a `Popup` object given an optional `options` object that describes its appearance and location and an optional `source` object that is used to tag the popup with a reference to the Layer to which it refers.
10338
+ // @alternative
10339
+ // @factory L.popup(latlng: LatLng, options?: Popup options)
10340
+ // Instantiates a `Popup` object given `latlng` where the popup will open and an optional `options` object that describes its appearance and location.
10123
10341
  var popup = function (options, source) {
10124
10342
  return new Popup(options, source);
10125
10343
  };
@@ -10303,10 +10521,28 @@
10303
10521
  * Used to display small texts on top of map layers.
10304
10522
  *
10305
10523
  * @example
10524
+ * If you want to just bind a tooltip to marker:
10306
10525
  *
10307
10526
  * ```js
10308
10527
  * marker.bindTooltip("my tooltip text").openTooltip();
10309
10528
  * ```
10529
+ * Path overlays like polylines also have a `bindTooltip` method.
10530
+ *
10531
+ * A tooltip can be also standalone:
10532
+ *
10533
+ * ```js
10534
+ * var tooltip = L.tooltip()
10535
+ * .setLatLng(latlng)
10536
+ * .setContent('Hello world!<br />This is a nice tooltip.')
10537
+ * .addTo(map);
10538
+ * ```
10539
+ * or
10540
+ * ```js
10541
+ * var tooltip = L.tooltip(latlng, {content: 'Hello world!<br />This is a nice tooltip.'})
10542
+ * .addTo(map);
10543
+ * ```
10544
+ *
10545
+ *
10310
10546
  * Note about tooltip offset. Leaflet takes two options in consideration
10311
10547
  * for computing tooltip offsetting:
10312
10548
  * - the `offset` Tooltip option: it defaults to [0, 0], and it's specific to one tooltip.
@@ -10407,6 +10643,9 @@
10407
10643
  className = prefix + ' ' + (this.options.className || '') + ' leaflet-zoom-' + (this._zoomAnimated ? 'animated' : 'hide');
10408
10644
 
10409
10645
  this._contentNode = this._container = create$1('div', className);
10646
+
10647
+ this._container.setAttribute('role', 'tooltip');
10648
+ this._container.setAttribute('id', 'leaflet-tooltip-' + stamp(this));
10410
10649
  },
10411
10650
 
10412
10651
  _updateLayout: function () {},
@@ -10487,7 +10726,10 @@
10487
10726
 
10488
10727
  // @namespace Tooltip
10489
10728
  // @factory L.tooltip(options?: Tooltip options, source?: Layer)
10490
- // Instantiates a Tooltip object given an optional `options` object that describes its appearance and location and an optional `source` object that is used to tag the tooltip with a reference to the Layer to which it refers.
10729
+ // Instantiates a `Tooltip` object given an optional `options` object that describes its appearance and location and an optional `source` object that is used to tag the tooltip with a reference to the Layer to which it refers.
10730
+ // @alternative
10731
+ // @factory L.tooltip(latlng: LatLng, options?: Tooltip options)
10732
+ // Instantiates a `Tooltip` object given `latlng` where the tooltip will open and an optional `options` object that describes its appearance and location.
10491
10733
  var tooltip = function (options, source) {
10492
10734
  return new Tooltip(options, source);
10493
10735
  };
@@ -10575,6 +10817,11 @@
10575
10817
  events.mouseover = this._openTooltip;
10576
10818
  events.mouseout = this.closeTooltip;
10577
10819
  events.click = this._openTooltip;
10820
+ if (this._map) {
10821
+ this._addFocusListeners();
10822
+ } else {
10823
+ events.add = this._addFocusListeners;
10824
+ }
10578
10825
  } else {
10579
10826
  events.add = this._openTooltip;
10580
10827
  }
@@ -10591,6 +10838,12 @@
10591
10838
  if (this._tooltip && this._tooltip._prepareOpen(latlng)) {
10592
10839
  // open the tooltip on the map
10593
10840
  this._tooltip.openOn(this._map);
10841
+
10842
+ if (this.getElement) {
10843
+ this._setAriaDescribedByOnLayer(this);
10844
+ } else if (this.eachLayer) {
10845
+ this.eachLayer(this._setAriaDescribedByOnLayer, this);
10846
+ }
10594
10847
  }
10595
10848
  return this;
10596
10849
  },
@@ -10633,6 +10886,27 @@
10633
10886
  return this._tooltip;
10634
10887
  },
10635
10888
 
10889
+ _addFocusListeners: function () {
10890
+ if (this.getElement) {
10891
+ this._addFocusListenersOnLayer(this);
10892
+ } else if (this.eachLayer) {
10893
+ this.eachLayer(this._addFocusListenersOnLayer, this);
10894
+ }
10895
+ },
10896
+
10897
+ _addFocusListenersOnLayer: function (layer) {
10898
+ on(layer.getElement(), 'focus', function () {
10899
+ this._tooltip._source = layer;
10900
+ this.openTooltip();
10901
+ }, this);
10902
+ on(layer.getElement(), 'blur', this.closeTooltip, this);
10903
+ },
10904
+
10905
+ _setAriaDescribedByOnLayer: function (layer) {
10906
+ layer.getElement().setAttribute('aria-describedby', this._tooltip._container.id);
10907
+ },
10908
+
10909
+
10636
10910
  _openTooltip: function (e) {
10637
10911
  if (!this._tooltip || !this._map || (this._map.dragging && this._map.dragging.moving())) {
10638
10912
  return;
@@ -11651,7 +11925,7 @@
11651
11925
  * @example
11652
11926
  *
11653
11927
  * ```js
11654
- * L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png?{foo}', {foo: 'bar', attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'}).addTo(map);
11928
+ * L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png?{foo}', {foo: 'bar', attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'}).addTo(map);
11655
11929
  * ```
11656
11930
  *
11657
11931
  * @section URL template
@@ -11738,13 +12012,19 @@
11738
12012
 
11739
12013
  if (!options.zoomReverse) {
11740
12014
  options.zoomOffset++;
11741
- options.maxZoom--;
12015
+ options.maxZoom = Math.max(options.minZoom, options.maxZoom - 1);
11742
12016
  } else {
11743
12017
  options.zoomOffset--;
11744
- options.minZoom++;
12018
+ options.minZoom = Math.min(options.maxZoom, options.minZoom + 1);
11745
12019
  }
11746
12020
 
11747
12021
  options.minZoom = Math.max(0, options.minZoom);
12022
+ } else if (!options.zoomReverse) {
12023
+ // make sure maxZoom is gte minZoom
12024
+ options.maxZoom = Math.max(options.minZoom, options.maxZoom);
12025
+ } else {
12026
+ // make sure minZoom is lte maxZoom
12027
+ options.minZoom = Math.min(options.maxZoom, options.minZoom);
11748
12028
  }
11749
12029
 
11750
12030
  if (typeof options.subdomains === 'string') {
@@ -11791,18 +12071,12 @@
11791
12071
  tile.referrerPolicy = this.options.referrerPolicy;
11792
12072
  }
11793
12073
 
11794
- /*
11795
- Alt tag is set to empty string to keep screen readers from reading URL and for compliance reasons
11796
- https://www.w3.org/TR/WCAG20-TECHS/H67
11797
- */
12074
+ // The alt attribute is set to the empty string,
12075
+ // allowing screen readers to ignore the decorative image tiles.
12076
+ // https://www.w3.org/WAI/tutorials/images/decorative/
12077
+ // https://www.w3.org/TR/html-aria/#el-img-empty-alt
11798
12078
  tile.alt = '';
11799
12079
 
11800
- /*
11801
- Set role="presentation" to force screen readers to ignore this
11802
- https://www.w3.org/TR/wai-aria/roles#textalternativecomputation
11803
- */
11804
- tile.setAttribute('role', 'presentation');
11805
-
11806
12080
  tile.src = this.getTileUrl(coords);
11807
12081
 
11808
12082
  return tile;
@@ -13995,7 +14269,7 @@
13995
14269
 
13996
14270
  cancelAnimFrame(this._animRequest);
13997
14271
 
13998
- var moveFn = bind(map._move, map, this._center, this._zoom, {pinch: true, round: false});
14272
+ var moveFn = bind(map._move, map, this._center, this._zoom, {pinch: true, round: false}, undefined);
13999
14273
  this._animRequest = requestAnimFrame(moveFn, this, true);
14000
14274
 
14001
14275
  preventDefault(e);
@@ -14035,6 +14309,109 @@
14035
14309
  Map.TapHold = TapHold;
14036
14310
  Map.TouchZoom = TouchZoom;
14037
14311
 
14312
+ var L$1 = {
14313
+ __proto__: null,
14314
+ version: version,
14315
+ Control: Control,
14316
+ control: control,
14317
+ Class: Class,
14318
+ Handler: Handler,
14319
+ extend: extend,
14320
+ bind: bind,
14321
+ stamp: stamp,
14322
+ setOptions: setOptions,
14323
+ Browser: Browser,
14324
+ Evented: Evented,
14325
+ Mixin: Mixin,
14326
+ Util: Util,
14327
+ PosAnimation: PosAnimation,
14328
+ Draggable: Draggable,
14329
+ DomEvent: DomEvent,
14330
+ DomUtil: DomUtil,
14331
+ Point: Point,
14332
+ point: toPoint,
14333
+ Bounds: Bounds,
14334
+ bounds: toBounds,
14335
+ Transformation: Transformation,
14336
+ transformation: toTransformation,
14337
+ LineUtil: LineUtil,
14338
+ PolyUtil: PolyUtil,
14339
+ LatLng: LatLng,
14340
+ latLng: toLatLng,
14341
+ LatLngBounds: LatLngBounds,
14342
+ latLngBounds: toLatLngBounds,
14343
+ CRS: CRS,
14344
+ Projection: index,
14345
+ Layer: Layer,
14346
+ LayerGroup: LayerGroup,
14347
+ layerGroup: layerGroup,
14348
+ FeatureGroup: FeatureGroup,
14349
+ featureGroup: featureGroup,
14350
+ ImageOverlay: ImageOverlay,
14351
+ imageOverlay: imageOverlay,
14352
+ VideoOverlay: VideoOverlay,
14353
+ videoOverlay: videoOverlay,
14354
+ SVGOverlay: SVGOverlay,
14355
+ svgOverlay: svgOverlay,
14356
+ DivOverlay: DivOverlay,
14357
+ Popup: Popup,
14358
+ popup: popup,
14359
+ Tooltip: Tooltip,
14360
+ tooltip: tooltip,
14361
+ icon: icon,
14362
+ DivIcon: DivIcon,
14363
+ divIcon: divIcon,
14364
+ Marker: Marker,
14365
+ marker: marker,
14366
+ Icon: Icon,
14367
+ GridLayer: GridLayer,
14368
+ gridLayer: gridLayer,
14369
+ TileLayer: TileLayer,
14370
+ tileLayer: tileLayer,
14371
+ Renderer: Renderer,
14372
+ Canvas: Canvas,
14373
+ canvas: canvas,
14374
+ Path: Path,
14375
+ CircleMarker: CircleMarker,
14376
+ circleMarker: circleMarker,
14377
+ Circle: Circle,
14378
+ circle: circle,
14379
+ Polyline: Polyline,
14380
+ polyline: polyline,
14381
+ Polygon: Polygon,
14382
+ polygon: polygon,
14383
+ Rectangle: Rectangle,
14384
+ rectangle: rectangle,
14385
+ SVG: SVG,
14386
+ svg: svg,
14387
+ GeoJSON: GeoJSON,
14388
+ geoJSON: geoJSON,
14389
+ geoJson: geoJson,
14390
+ Map: Map,
14391
+ map: createMap
14392
+ };
14393
+
14394
+ var globalL = extend(L$1, {noConflict: noConflict});
14395
+
14396
+ var globalObject = getGlobalObject();
14397
+ var oldL = globalObject.L;
14398
+
14399
+ globalObject.L = globalL;
14400
+
14401
+ function noConflict() {
14402
+ globalObject.L = oldL;
14403
+ return globalL;
14404
+ }
14405
+
14406
+ function getGlobalObject() {
14407
+ if (typeof globalThis !== 'undefined') { return globalThis; }
14408
+ if (typeof self !== 'undefined') { return self; }
14409
+ if (typeof window !== 'undefined') { return window; }
14410
+ if (typeof global !== 'undefined') { return global; }
14411
+
14412
+ throw new Error('Unable to locate global object.');
14413
+ }
14414
+
14038
14415
  exports.Bounds = Bounds;
14039
14416
  exports.Browser = Browser;
14040
14417
  exports.CRS = CRS;
@@ -14086,6 +14463,7 @@
14086
14463
  exports.circle = circle;
14087
14464
  exports.circleMarker = circleMarker;
14088
14465
  exports.control = control;
14466
+ exports["default"] = globalL;
14089
14467
  exports.divIcon = divIcon;
14090
14468
  exports.extend = extend;
14091
14469
  exports.featureGroup = featureGroup;
@@ -14099,6 +14477,7 @@
14099
14477
  exports.layerGroup = layerGroup;
14100
14478
  exports.map = createMap;
14101
14479
  exports.marker = marker;
14480
+ exports.noConflict = noConflict;
14102
14481
  exports.point = toPoint;
14103
14482
  exports.polygon = polygon;
14104
14483
  exports.polyline = polyline;
@@ -14114,13 +14493,5 @@
14114
14493
  exports.version = version;
14115
14494
  exports.videoOverlay = videoOverlay;
14116
14495
 
14117
- var oldL = window.L;
14118
- exports.noConflict = function() {
14119
- window.L = oldL;
14120
- return this;
14121
- }
14122
- // Always export us to window global (see #2364)
14123
- window.L = exports;
14124
-
14125
14496
  }));
14126
14497
  //# sourceMappingURL=<%= asset_path 'leaflet-src.js.map' %>