leaflet-rails 1.8.0 → 1.9.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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.1, 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.1";
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,85 @@
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
+ // we don't overwrite the input `fn` value, because we need to use it for propagation
630
+ var _fn = fn;
631
+ if (typeof fn !== 'function') {
632
+ propagate = !!fn;
633
+ _fn = undefined;
634
+ context = undefined;
635
+ }
636
+
635
637
  var listeners = this._events && this._events[type];
636
- if (listeners && listeners.length) { return true; }
638
+ if (listeners && listeners.length) {
639
+ if (this._listens(type, _fn, context) !== false) {
640
+ return true;
641
+ }
642
+ }
637
643
 
638
644
  if (propagate) {
639
645
  // also check parents for listeners if event propagates
640
646
  for (var id in this._eventParents) {
641
- if (this._eventParents[id].listens(type, propagate)) { return true; }
647
+ if (this._eventParents[id].listens(type, fn, context, propagate)) { return true; }
648
+ }
649
+ }
650
+ return false;
651
+ },
652
+
653
+ // returns the index (number) or false
654
+ _listens: function (type, fn, context) {
655
+ if (!this._events) {
656
+ return false;
657
+ }
658
+
659
+ var listeners = this._events[type] || [];
660
+ if (!fn) {
661
+ return !!listeners.length;
662
+ }
663
+
664
+ if (context === this) {
665
+ // Less memory footprint.
666
+ context = undefined;
667
+ }
668
+
669
+ for (var i = 0, len = listeners.length; i < len; i++) {
670
+ if (listeners[i].fn === fn && listeners[i].ctx === context) {
671
+ return i;
642
672
  }
643
673
  }
644
674
  return false;
675
+
645
676
  },
646
677
 
647
678
  // @method once(…): this
648
679
  // Behaves as [`on(…)`](#evented-on), except the listener will only get fired once and then removed.
649
680
  once: function (types, fn, context) {
650
681
 
682
+ // types can be a map of types/handlers
651
683
  if (typeof types === 'object') {
652
684
  for (var type in types) {
653
- this.once(type, types[type], fn);
685
+ // we don't process space-separated events here for performance;
686
+ // it's a hot path since Layer uses the on(obj) syntax
687
+ this._on(type, types[type], fn, true);
654
688
  }
655
- return this;
656
- }
657
689
 
658
- var handler = bind(function () {
659
- this
660
- .off(types, fn, context)
661
- .off(types, handler, context);
662
- }, this);
690
+ } else {
691
+ // types can be a string of space-separated words
692
+ types = splitWords(types);
693
+
694
+ for (var i = 0, len = types.length; i < len; i++) {
695
+ this._on(types[i], fn, context, true);
696
+ }
697
+ }
663
698
 
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);
699
+ return this;
668
700
  },
669
701
 
670
702
  // @method addEventParent(obj: Evented): this
@@ -980,21 +1012,36 @@
980
1012
  Bounds.prototype = {
981
1013
  // @method extend(point: Point): this
982
1014
  // Extends the bounds to contain the given point.
983
- extend: function (point) { // (Point)
984
- point = toPoint(point);
1015
+
1016
+ // @alternative
1017
+ // @method extend(otherBounds: Bounds): this
1018
+ // Extend the bounds to contain the given bounds
1019
+ extend: function (obj) {
1020
+ var min2, max2;
1021
+ if (!obj) { return this; }
1022
+
1023
+ if (obj instanceof Point || typeof obj[0] === 'number' || 'x' in obj) {
1024
+ min2 = max2 = toPoint(obj);
1025
+ } else {
1026
+ obj = toBounds(obj);
1027
+ min2 = obj.min;
1028
+ max2 = obj.max;
1029
+
1030
+ if (!min2 || !max2) { return this; }
1031
+ }
985
1032
 
986
1033
  // @property min: Point
987
1034
  // The top left corner of the rectangle.
988
1035
  // @property max: Point
989
1036
  // The bottom right corner of the rectangle.
990
1037
  if (!this.min && !this.max) {
991
- this.min = point.clone();
992
- this.max = point.clone();
1038
+ this.min = min2.clone();
1039
+ this.max = max2.clone();
993
1040
  } 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);
1041
+ this.min.x = Math.min(min2.x, this.min.x);
1042
+ this.max.x = Math.max(max2.x, this.max.x);
1043
+ this.min.y = Math.min(min2.y, this.min.y);
1044
+ this.max.y = Math.max(max2.y, this.max.y);
998
1045
  }
999
1046
  return this;
1000
1047
  },
@@ -1002,7 +1049,7 @@
1002
1049
  // @method getCenter(round?: Boolean): Point
1003
1050
  // Returns the center point of the bounds.
1004
1051
  getCenter: function (round) {
1005
- return new Point(
1052
+ return toPoint(
1006
1053
  (this.min.x + this.max.x) / 2,
1007
1054
  (this.min.y + this.max.y) / 2, round);
1008
1055
  },
@@ -1010,13 +1057,13 @@
1010
1057
  // @method getBottomLeft(): Point
1011
1058
  // Returns the bottom-left point of the bounds.
1012
1059
  getBottomLeft: function () {
1013
- return new Point(this.min.x, this.max.y);
1060
+ return toPoint(this.min.x, this.max.y);
1014
1061
  },
1015
1062
 
1016
1063
  // @method getTopRight(): Point
1017
1064
  // Returns the top-right point of the bounds.
1018
1065
  getTopRight: function () { // -> Point
1019
- return new Point(this.max.x, this.min.y);
1066
+ return toPoint(this.max.x, this.min.y);
1020
1067
  },
1021
1068
 
1022
1069
  // @method getTopLeft(): Point
@@ -1096,9 +1143,40 @@
1096
1143
  return xOverlaps && yOverlaps;
1097
1144
  },
1098
1145
 
1146
+ // @method isValid(): Boolean
1147
+ // Returns `true` if the bounds are properly initialized.
1099
1148
  isValid: function () {
1100
1149
  return !!(this.min && this.max);
1101
- }
1150
+ },
1151
+
1152
+
1153
+ // @method pad(bufferRatio: Number): Bounds
1154
+ // Returns bounds created by extending or retracting the current bounds by a given ratio in each direction.
1155
+ // For example, a ratio of 0.5 extends the bounds by 50% in each direction.
1156
+ // Negative values will retract the bounds.
1157
+ pad: function (bufferRatio) {
1158
+ var min = this.min,
1159
+ max = this.max,
1160
+ heightBuffer = Math.abs(min.x - max.x) * bufferRatio,
1161
+ widthBuffer = Math.abs(min.y - max.y) * bufferRatio;
1162
+
1163
+
1164
+ return toBounds(
1165
+ toPoint(min.x - heightBuffer, min.y - widthBuffer),
1166
+ toPoint(max.x + heightBuffer, max.y + widthBuffer));
1167
+ },
1168
+
1169
+
1170
+ // @method equals(otherBounds: Bounds, maxMargin?: Number): Boolean
1171
+ // 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.
1172
+ equals: function (bounds) {
1173
+ if (!bounds) { return false; }
1174
+
1175
+ bounds = toBounds(bounds);
1176
+
1177
+ return this.min.equals(bounds.getTopLeft()) &&
1178
+ this.max.equals(bounds.getBottomRight());
1179
+ },
1102
1180
  };
1103
1181
 
1104
1182
 
@@ -2006,6 +2084,13 @@
2006
2084
  }
2007
2085
  }());
2008
2086
 
2087
+
2088
+ // @property mac: Boolean; `true` when the browser is running in a Mac platform
2089
+ var mac = navigator.platform.indexOf('Mac') === 0;
2090
+
2091
+ // @property mac: Boolean; `true` when the browser is running in a Linux platform
2092
+ var linux = navigator.platform.indexOf('Linux') === 0;
2093
+
2009
2094
  function userAgentContains(str) {
2010
2095
  return navigator.userAgent.toLowerCase().indexOf(str) >= 0;
2011
2096
  }
@@ -2044,7 +2129,9 @@
2044
2129
  canvas: canvas$1,
2045
2130
  svg: svg$1,
2046
2131
  vml: vml,
2047
- inlineSvg: inlineSvg
2132
+ inlineSvg: inlineSvg,
2133
+ mac: mac,
2134
+ linux: linux
2048
2135
  };
2049
2136
 
2050
2137
  /*
@@ -2187,6 +2274,25 @@
2187
2274
  return;
2188
2275
  }
2189
2276
 
2277
+ // When clicking on an <input>, the browser generates a click on its
2278
+ // <label> (and vice versa) triggering two clicks in quick succession.
2279
+ // This ignores clicks on elements which are a label with a 'for'
2280
+ // attribute (or children of such a label), but not children of
2281
+ // a <input>.
2282
+ var path = getPropagationPath(e);
2283
+ if (path.some(function (el) {
2284
+ return el instanceof HTMLLabelElement && el.attributes.for;
2285
+ }) &&
2286
+ !path.some(function (el) {
2287
+ return (
2288
+ el instanceof HTMLInputElement ||
2289
+ el instanceof HTMLSelectElement
2290
+ );
2291
+ })
2292
+ ) {
2293
+ return;
2294
+ }
2295
+
2190
2296
  var now = Date.now();
2191
2297
  if (now - last <= delay) {
2192
2298
  detail++;
@@ -2808,6 +2914,26 @@
2808
2914
  return this;
2809
2915
  }
2810
2916
 
2917
+ // @function getPropagationPath(ev: DOMEvent): Array
2918
+ // Compatibility polyfill for [`Event.composedPath()`](https://developer.mozilla.org/en-US/docs/Web/API/Event/composedPath).
2919
+ // Returns an array containing the `HTMLElement`s that the given DOM event
2920
+ // should propagate to (if not stopped).
2921
+ function getPropagationPath(ev) {
2922
+ if (ev.composedPath) {
2923
+ return ev.composedPath();
2924
+ }
2925
+
2926
+ var path = [];
2927
+ var el = ev.target;
2928
+
2929
+ while (el) {
2930
+ path.push(el);
2931
+ el = el.parentNode;
2932
+ }
2933
+ return path;
2934
+ }
2935
+
2936
+
2811
2937
  // @function getMousePosition(ev: DOMEvent, container?: HTMLElement): Point
2812
2938
  // Gets normalized mouse position from a DOM event relative to the
2813
2939
  // `container` (border excluded) or to the whole page if not specified.
@@ -2827,12 +2953,15 @@
2827
2953
  );
2828
2954
  }
2829
2955
 
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
2956
 
2957
+ // except , Safari and
2958
+ // We need double the scroll pixels (see #7403 and #4538) for all Browsers
2959
+ // except OSX (Mac) -> 3x, Chrome running on Linux 1x
2960
+
2961
+ var wheelPxFactor =
2962
+ (Browser.linux && Browser.chrome) ? window.devicePixelRatio :
2963
+ Browser.mac ? window.devicePixelRatio * 3 :
2964
+ window.devicePixelRatio > 0 ? 2 * window.devicePixelRatio : 1;
2836
2965
  // @function getWheelDelta(ev: DOMEvent): Number
2837
2966
  // Gets normalized wheel delta from a wheel DOM event, in vertical
2838
2967
  // pixels scrolled (negative if scrolling down).
@@ -2876,6 +3005,7 @@
2876
3005
  disableClickPropagation: disableClickPropagation,
2877
3006
  preventDefault: preventDefault,
2878
3007
  stop: stop,
3008
+ getPropagationPath: getPropagationPath,
2879
3009
  getMousePosition: getMousePosition,
2880
3010
  getWheelDelta: getWheelDelta,
2881
3011
  isExternalTarget: isExternalTarget,
@@ -2891,8 +3021,21 @@
2891
3021
  *
2892
3022
  * @example
2893
3023
  * ```js
2894
- * var fx = new L.PosAnimation();
2895
- * fx.run(el, [300, 500], 0.5);
3024
+ * var myPositionMarker = L.marker([48.864716, 2.294694]).addTo(map);
3025
+ *
3026
+ * myPositionMarker.on("click", function() {
3027
+ * var pos = map.latLngToLayerPoint(myPositionMarker.getLatLng());
3028
+ * pos.y -= 25;
3029
+ * var fx = new L.PosAnimation();
3030
+ *
3031
+ * fx.once('end',function() {
3032
+ * pos.y += 25;
3033
+ * fx.run(myPositionMarker._icon, pos, 0.8);
3034
+ * });
3035
+ *
3036
+ * fx.run(myPositionMarker._icon, pos, 0.3);
3037
+ * });
3038
+ *
2896
3039
  * ```
2897
3040
  *
2898
3041
  * @constructor L.PosAnimation()
@@ -3172,7 +3315,7 @@
3172
3315
  }
3173
3316
 
3174
3317
  // animation didn't start, just reset the map view
3175
- this._resetView(center, zoom);
3318
+ this._resetView(center, zoom, options.pan && options.pan.noMoveStart);
3176
3319
 
3177
3320
  return this;
3178
3321
  },
@@ -3415,11 +3558,13 @@
3415
3558
  setMaxBounds: function (bounds) {
3416
3559
  bounds = toLatLngBounds(bounds);
3417
3560
 
3561
+ if (this.listens('moveend', this._panInsideMaxBounds)) {
3562
+ this.off('moveend', this._panInsideMaxBounds);
3563
+ }
3564
+
3418
3565
  if (!bounds.isValid()) {
3419
3566
  this.options.maxBounds = null;
3420
- return this.off('moveend', this._panInsideMaxBounds);
3421
- } else if (this.options.maxBounds) {
3422
- this.off('moveend', this._panInsideMaxBounds);
3567
+ return this;
3423
3568
  }
3424
3569
 
3425
3570
  this.options.maxBounds = bounds;
@@ -3789,7 +3934,7 @@
3789
3934
  this._checkIfLoaded();
3790
3935
 
3791
3936
  if (this._lastCenter && !this._moved()) {
3792
- return this._lastCenter;
3937
+ return this._lastCenter.clone();
3793
3938
  }
3794
3939
  return this.layerPointToLatLng(this._getCenterLayerPoint());
3795
3940
  },
@@ -4138,7 +4283,7 @@
4138
4283
  // private methods that modify map state
4139
4284
 
4140
4285
  // @section Map state change events
4141
- _resetView: function (center, zoom) {
4286
+ _resetView: function (center, zoom, noMoveStart) {
4142
4287
  setPosition(this._mapPane, new Point(0, 0));
4143
4288
 
4144
4289
  var loading = !this._loaded;
@@ -4149,7 +4294,7 @@
4149
4294
 
4150
4295
  var zoomChanged = this._zoom !== zoom;
4151
4296
  this
4152
- ._moveStart(zoomChanged, false)
4297
+ ._moveStart(zoomChanged, noMoveStart)
4153
4298
  ._move(center, zoom)
4154
4299
  ._moveEnd(zoomChanged);
4155
4300
 
@@ -4346,7 +4491,7 @@
4346
4491
  },
4347
4492
 
4348
4493
  _isClickDisabled: function (el) {
4349
- while (el !== this._container) {
4494
+ while (el && el !== this._container) {
4350
4495
  if (el['_leaflet_disable_click']) { return true; }
4351
4496
  el = el.parentNode;
4352
4497
  }
@@ -5572,7 +5717,7 @@
5572
5717
  return new Scale(options);
5573
5718
  };
5574
5719
 
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>';
5720
+ 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
5721
 
5577
5722
 
5578
5723
  /*
@@ -5641,7 +5786,7 @@
5641
5786
  },
5642
5787
 
5643
5788
  // @method addAttribution(text: String): this
5644
- // Adds an attribution text (e.g. `'Vector data &copy; Mapbox'`).
5789
+ // Adds an attribution text (e.g. `'&copy; OpenStreetMap contributors'`).
5645
5790
  addAttribution: function (text) {
5646
5791
  if (!text) { return this; }
5647
5792
 
@@ -6233,6 +6378,55 @@
6233
6378
  return isFlat(latlngs);
6234
6379
  }
6235
6380
 
6381
+ /* @function polylineCenter(latlngs: LatLng[], crs: CRS): LatLng
6382
+ * Returns the center ([centroid](http://en.wikipedia.org/wiki/Centroid)) of the passed LatLngs (first ring) from a polyline.
6383
+ */
6384
+ function polylineCenter(latlngs, crs) {
6385
+ var i, halfDist, segDist, dist, p1, p2, ratio, center;
6386
+
6387
+ if (!latlngs || latlngs.length === 0) {
6388
+ throw new Error('latlngs not passed');
6389
+ }
6390
+
6391
+ if (!isFlat(latlngs)) {
6392
+ console.warn('latlngs are not flat! Only the first ring will be used');
6393
+ latlngs = latlngs[0];
6394
+ }
6395
+
6396
+ var points = [];
6397
+ for (var j in latlngs) {
6398
+ points.push(crs.project(toLatLng(latlngs[j])));
6399
+ }
6400
+
6401
+ var len = points.length;
6402
+
6403
+ for (i = 0, halfDist = 0; i < len - 1; i++) {
6404
+ halfDist += points[i].distanceTo(points[i + 1]) / 2;
6405
+ }
6406
+
6407
+ // The line is so small in the current view that all points are on the same pixel.
6408
+ if (halfDist === 0) {
6409
+ center = points[0];
6410
+ } else {
6411
+ for (i = 0, dist = 0; i < len - 1; i++) {
6412
+ p1 = points[i];
6413
+ p2 = points[i + 1];
6414
+ segDist = p1.distanceTo(p2);
6415
+ dist += segDist;
6416
+
6417
+ if (dist > halfDist) {
6418
+ ratio = (dist - halfDist) / segDist;
6419
+ center = [
6420
+ p2.x - ratio * (p2.x - p1.x),
6421
+ p2.y - ratio * (p2.y - p1.y)
6422
+ ];
6423
+ break;
6424
+ }
6425
+ }
6426
+ }
6427
+ return crs.unproject(toPoint(center));
6428
+ }
6429
+
6236
6430
  var LineUtil = {
6237
6431
  __proto__: null,
6238
6432
  simplify: simplify,
@@ -6243,7 +6437,8 @@
6243
6437
  _getBitCode: _getBitCode,
6244
6438
  _sqClosestPointOnSegment: _sqClosestPointOnSegment,
6245
6439
  isFlat: isFlat,
6246
- _flat: _flat
6440
+ _flat: _flat,
6441
+ polylineCenter: polylineCenter
6247
6442
  };
6248
6443
 
6249
6444
  /*
@@ -6300,9 +6495,53 @@
6300
6495
  return points;
6301
6496
  }
6302
6497
 
6498
+ /* @function polygonCenter(latlngs: LatLng[] crs: CRS): LatLng
6499
+ * Returns the center ([centroid](http://en.wikipedia.org/wiki/Centroid)) of the passed LatLngs (first ring) from a polygon.
6500
+ */
6501
+ function polygonCenter(latlngs, crs) {
6502
+ var i, j, p1, p2, f, area, x, y, center;
6503
+
6504
+ if (!latlngs || latlngs.length === 0) {
6505
+ throw new Error('latlngs not passed');
6506
+ }
6507
+
6508
+ if (!isFlat(latlngs)) {
6509
+ console.warn('latlngs are not flat! Only the first ring will be used');
6510
+ latlngs = latlngs[0];
6511
+ }
6512
+
6513
+ var points = [];
6514
+ for (var k in latlngs) {
6515
+ points.push(crs.project(toLatLng(latlngs[k])));
6516
+ }
6517
+
6518
+ var len = points.length;
6519
+ area = x = y = 0;
6520
+
6521
+ // polygon centroid algorithm;
6522
+ for (i = 0, j = len - 1; i < len; j = i++) {
6523
+ p1 = points[i];
6524
+ p2 = points[j];
6525
+
6526
+ f = p1.y * p2.x - p2.y * p1.x;
6527
+ x += (p1.x + p2.x) * f;
6528
+ y += (p1.y + p2.y) * f;
6529
+ area += f * 3;
6530
+ }
6531
+
6532
+ if (area === 0) {
6533
+ // Polygon is so small that all points are on same pixel.
6534
+ center = points[0];
6535
+ } else {
6536
+ center = [x / area, y / area];
6537
+ }
6538
+ return crs.unproject(toPoint(center));
6539
+ }
6540
+
6303
6541
  var PolyUtil = {
6304
6542
  __proto__: null,
6305
- clipPolygon: clipPolygon
6543
+ clipPolygon: clipPolygon,
6544
+ polygonCenter: polygonCenter
6306
6545
  };
6307
6546
 
6308
6547
  /*
@@ -8261,38 +8500,7 @@
8261
8500
  if (!this._map) {
8262
8501
  throw new Error('Must add layer to map before using getCenter()');
8263
8502
  }
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
- }
8503
+ return polylineCenter(this._defaultShape(), this._map.options.crs);
8296
8504
  },
8297
8505
 
8298
8506
  // @method getBounds(): LatLngBounds
@@ -8534,39 +8742,14 @@
8534
8742
  return !this._latlngs.length || !this._latlngs[0].length;
8535
8743
  },
8536
8744
 
8745
+ // @method getCenter(): LatLng
8746
+ // Returns the center ([centroid](http://en.wikipedia.org/wiki/Centroid)) of the Polygon.
8537
8747
  getCenter: function () {
8538
8748
  // throws error when not yet added to map as this center calculation requires projected coordinates
8539
8749
  if (!this._map) {
8540
8750
  throw new Error('Must add layer to map before using getCenter()');
8541
8751
  }
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);
8752
+ return polygonCenter(this._defaultShape(), this._map.options.crs);
8570
8753
  },
8571
8754
 
8572
8755
  _convertLatLngs: function (latlngs) {
@@ -8851,14 +9034,24 @@
8851
9034
 
8852
9035
  case 'GeometryCollection':
8853
9036
  for (i = 0, len = geometry.geometries.length; i < len; i++) {
8854
- var layer = geometryToLayer({
9037
+ var geoLayer = geometryToLayer({
8855
9038
  geometry: geometry.geometries[i],
8856
9039
  type: 'Feature',
8857
9040
  properties: geojson.properties
8858
9041
  }, options);
8859
9042
 
8860
- if (layer) {
8861
- layers.push(layer);
9043
+ if (geoLayer) {
9044
+ layers.push(geoLayer);
9045
+ }
9046
+ }
9047
+ return new FeatureGroup(layers);
9048
+
9049
+ case 'FeatureCollection':
9050
+ for (i = 0, len = geometry.features.length; i < len; i++) {
9051
+ var featureLayer = geometryToLayer(geometry.features[i], options);
9052
+
9053
+ if (featureLayer) {
9054
+ layers.push(featureLayer);
8862
9055
  }
8863
9056
  }
8864
9057
  return new FeatureGroup(layers);
@@ -8917,8 +9110,9 @@
8917
9110
  var coords = [];
8918
9111
 
8919
9112
  for (var i = 0, len = latlngs.length; i < len; i++) {
9113
+ // Check for flat arrays required to ensure unbalanced arrays are correctly converted in recursion
8920
9114
  coords.push(levelsDeep ?
8921
- latLngsToCoords(latlngs[i], levelsDeep - 1, closed, precision) :
9115
+ latLngsToCoords(latlngs[i], isFlat(latlngs[i]) ? 0 : levelsDeep - 1, closed, precision) :
8922
9116
  latLngToCoords(latlngs[i], precision));
8923
9117
  }
8924
9118
 
@@ -9527,13 +9721,25 @@
9527
9721
 
9528
9722
  // @option pane: String = undefined
9529
9723
  // `Map pane` where the overlay will be added.
9530
- pane: undefined
9724
+ pane: undefined,
9725
+
9726
+ // @option content: String|HTMLElement|Function = ''
9727
+ // Sets the HTML content of the overlay while initializing. If a function is passed the source layer will be
9728
+ // passed to the function. The function should return a `String` or `HTMLElement` to be used in the overlay.
9729
+ content: ''
9531
9730
  },
9532
9731
 
9533
9732
  initialize: function (options, source) {
9534
- setOptions(this, options);
9535
-
9536
- this._source = source;
9733
+ if (options && (options instanceof L.LatLng || isArray(options))) {
9734
+ this._latlng = toLatLng(options);
9735
+ setOptions(this, source);
9736
+ } else {
9737
+ setOptions(this, options);
9738
+ this._source = source;
9739
+ }
9740
+ if (this.options.content) {
9741
+ this._content = this.options.content;
9742
+ }
9537
9743
  },
9538
9744
 
9539
9745
  // @method openOn(map: Map): this
@@ -9845,7 +10051,8 @@
9845
10051
  * marker.bindPopup(popupContent).openPopup();
9846
10052
  * ```
9847
10053
  * Path overlays like polylines also have a `bindPopup` method.
9848
- * Here's a more complicated way to open a popup on a map:
10054
+ *
10055
+ * A popup can be also standalone:
9849
10056
  *
9850
10057
  * ```js
9851
10058
  * var popup = L.popup()
@@ -9853,6 +10060,11 @@
9853
10060
  * .setContent('<p>Hello world!<br />This is a nice popup.</p>')
9854
10061
  * .openOn(map);
9855
10062
  * ```
10063
+ * or
10064
+ * ```js
10065
+ * var popup = L.popup(latlng, {content: '<p>Hello world!<br />This is a nice popup.</p>')
10066
+ * .openOn(map);
10067
+ * ```
9856
10068
  */
9857
10069
 
9858
10070
 
@@ -9881,6 +10093,8 @@
9881
10093
  // @option maxHeight: Number = null
9882
10094
  // If set, creates a scrollable container of the given height
9883
10095
  // inside a popup if its content exceeds it.
10096
+ // The scrollable container can be styled using the
10097
+ // `leaflet-popup-scrolled` CSS class selector.
9884
10098
  maxHeight: null,
9885
10099
 
9886
10100
  // @option autoPan: Boolean = true
@@ -10026,7 +10240,10 @@
10026
10240
  closeButton.href = '#close';
10027
10241
  closeButton.innerHTML = '<span aria-hidden="true">&#215;</span>';
10028
10242
 
10029
- on(closeButton, 'click', this.close, this);
10243
+ on(closeButton, 'click', function (ev) {
10244
+ preventDefault(ev);
10245
+ this.close();
10246
+ }, this);
10030
10247
  }
10031
10248
  },
10032
10249
 
@@ -10120,6 +10337,9 @@
10120
10337
  // @namespace Popup
10121
10338
  // @factory L.popup(options?: Popup options, source?: Layer)
10122
10339
  // 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.
10340
+ // @alternative
10341
+ // @factory L.popup(latlng: LatLng, options?: Popup options)
10342
+ // Instantiates a `Popup` object given `latlng` where the popup will open and an optional `options` object that describes its appearance and location.
10123
10343
  var popup = function (options, source) {
10124
10344
  return new Popup(options, source);
10125
10345
  };
@@ -10303,10 +10523,28 @@
10303
10523
  * Used to display small texts on top of map layers.
10304
10524
  *
10305
10525
  * @example
10526
+ * If you want to just bind a tooltip to marker:
10306
10527
  *
10307
10528
  * ```js
10308
10529
  * marker.bindTooltip("my tooltip text").openTooltip();
10309
10530
  * ```
10531
+ * Path overlays like polylines also have a `bindTooltip` method.
10532
+ *
10533
+ * A tooltip can be also standalone:
10534
+ *
10535
+ * ```js
10536
+ * var tooltip = L.tooltip()
10537
+ * .setLatLng(latlng)
10538
+ * .setContent('Hello world!<br />This is a nice tooltip.')
10539
+ * .addTo(map);
10540
+ * ```
10541
+ * or
10542
+ * ```js
10543
+ * var tooltip = L.tooltip(latlng, {content: 'Hello world!<br />This is a nice tooltip.'})
10544
+ * .addTo(map);
10545
+ * ```
10546
+ *
10547
+ *
10310
10548
  * Note about tooltip offset. Leaflet takes two options in consideration
10311
10549
  * for computing tooltip offsetting:
10312
10550
  * - the `offset` Tooltip option: it defaults to [0, 0], and it's specific to one tooltip.
@@ -10407,6 +10645,9 @@
10407
10645
  className = prefix + ' ' + (this.options.className || '') + ' leaflet-zoom-' + (this._zoomAnimated ? 'animated' : 'hide');
10408
10646
 
10409
10647
  this._contentNode = this._container = create$1('div', className);
10648
+
10649
+ this._container.setAttribute('role', 'tooltip');
10650
+ this._container.setAttribute('id', 'leaflet-tooltip-' + stamp(this));
10410
10651
  },
10411
10652
 
10412
10653
  _updateLayout: function () {},
@@ -10487,7 +10728,10 @@
10487
10728
 
10488
10729
  // @namespace Tooltip
10489
10730
  // @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.
10731
+ // 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.
10732
+ // @alternative
10733
+ // @factory L.tooltip(latlng: LatLng, options?: Tooltip options)
10734
+ // Instantiates a `Tooltip` object given `latlng` where the tooltip will open and an optional `options` object that describes its appearance and location.
10491
10735
  var tooltip = function (options, source) {
10492
10736
  return new Tooltip(options, source);
10493
10737
  };
@@ -10575,6 +10819,11 @@
10575
10819
  events.mouseover = this._openTooltip;
10576
10820
  events.mouseout = this.closeTooltip;
10577
10821
  events.click = this._openTooltip;
10822
+ if (this._map) {
10823
+ this._addFocusListeners();
10824
+ } else {
10825
+ events.add = this._addFocusListeners;
10826
+ }
10578
10827
  } else {
10579
10828
  events.add = this._openTooltip;
10580
10829
  }
@@ -10591,6 +10840,12 @@
10591
10840
  if (this._tooltip && this._tooltip._prepareOpen(latlng)) {
10592
10841
  // open the tooltip on the map
10593
10842
  this._tooltip.openOn(this._map);
10843
+
10844
+ if (this.getElement) {
10845
+ this._setAriaDescribedByOnLayer(this);
10846
+ } else if (this.eachLayer) {
10847
+ this.eachLayer(this._setAriaDescribedByOnLayer, this);
10848
+ }
10594
10849
  }
10595
10850
  return this;
10596
10851
  },
@@ -10633,6 +10888,27 @@
10633
10888
  return this._tooltip;
10634
10889
  },
10635
10890
 
10891
+ _addFocusListeners: function () {
10892
+ if (this.getElement) {
10893
+ this._addFocusListenersOnLayer(this);
10894
+ } else if (this.eachLayer) {
10895
+ this.eachLayer(this._addFocusListenersOnLayer, this);
10896
+ }
10897
+ },
10898
+
10899
+ _addFocusListenersOnLayer: function (layer) {
10900
+ on(layer.getElement(), 'focus', function () {
10901
+ this._tooltip._source = layer;
10902
+ this.openTooltip();
10903
+ }, this);
10904
+ on(layer.getElement(), 'blur', this.closeTooltip, this);
10905
+ },
10906
+
10907
+ _setAriaDescribedByOnLayer: function (layer) {
10908
+ layer.getElement().setAttribute('aria-describedby', this._tooltip._container.id);
10909
+ },
10910
+
10911
+
10636
10912
  _openTooltip: function (e) {
10637
10913
  if (!this._tooltip || !this._map || (this._map.dragging && this._map.dragging.moving())) {
10638
10914
  return;
@@ -11651,7 +11927,7 @@
11651
11927
  * @example
11652
11928
  *
11653
11929
  * ```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);
11930
+ * 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
11931
  * ```
11656
11932
  *
11657
11933
  * @section URL template
@@ -11738,13 +12014,19 @@
11738
12014
 
11739
12015
  if (!options.zoomReverse) {
11740
12016
  options.zoomOffset++;
11741
- options.maxZoom--;
12017
+ options.maxZoom = Math.max(options.minZoom, options.maxZoom - 1);
11742
12018
  } else {
11743
12019
  options.zoomOffset--;
11744
- options.minZoom++;
12020
+ options.minZoom = Math.min(options.maxZoom, options.minZoom + 1);
11745
12021
  }
11746
12022
 
11747
12023
  options.minZoom = Math.max(0, options.minZoom);
12024
+ } else if (!options.zoomReverse) {
12025
+ // make sure maxZoom is gte minZoom
12026
+ options.maxZoom = Math.max(options.minZoom, options.maxZoom);
12027
+ } else {
12028
+ // make sure minZoom is lte maxZoom
12029
+ options.minZoom = Math.min(options.maxZoom, options.minZoom);
11748
12030
  }
11749
12031
 
11750
12032
  if (typeof options.subdomains === 'string') {
@@ -11791,18 +12073,12 @@
11791
12073
  tile.referrerPolicy = this.options.referrerPolicy;
11792
12074
  }
11793
12075
 
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
- */
12076
+ // The alt attribute is set to the empty string,
12077
+ // allowing screen readers to ignore the decorative image tiles.
12078
+ // https://www.w3.org/WAI/tutorials/images/decorative/
12079
+ // https://www.w3.org/TR/html-aria/#el-img-empty-alt
11798
12080
  tile.alt = '';
11799
12081
 
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
12082
  tile.src = this.getTileUrl(coords);
11807
12083
 
11808
12084
  return tile;
@@ -13995,7 +14271,7 @@
13995
14271
 
13996
14272
  cancelAnimFrame(this._animRequest);
13997
14273
 
13998
- var moveFn = bind(map._move, map, this._center, this._zoom, {pinch: true, round: false});
14274
+ var moveFn = bind(map._move, map, this._center, this._zoom, {pinch: true, round: false}, undefined);
13999
14275
  this._animRequest = requestAnimFrame(moveFn, this, true);
14000
14276
 
14001
14277
  preventDefault(e);
@@ -14035,6 +14311,109 @@
14035
14311
  Map.TapHold = TapHold;
14036
14312
  Map.TouchZoom = TouchZoom;
14037
14313
 
14314
+ var L$1 = {
14315
+ __proto__: null,
14316
+ version: version,
14317
+ Control: Control,
14318
+ control: control,
14319
+ Class: Class,
14320
+ Handler: Handler,
14321
+ extend: extend,
14322
+ bind: bind,
14323
+ stamp: stamp,
14324
+ setOptions: setOptions,
14325
+ Browser: Browser,
14326
+ Evented: Evented,
14327
+ Mixin: Mixin,
14328
+ Util: Util,
14329
+ PosAnimation: PosAnimation,
14330
+ Draggable: Draggable,
14331
+ DomEvent: DomEvent,
14332
+ DomUtil: DomUtil,
14333
+ Point: Point,
14334
+ point: toPoint,
14335
+ Bounds: Bounds,
14336
+ bounds: toBounds,
14337
+ Transformation: Transformation,
14338
+ transformation: toTransformation,
14339
+ LineUtil: LineUtil,
14340
+ PolyUtil: PolyUtil,
14341
+ LatLng: LatLng,
14342
+ latLng: toLatLng,
14343
+ LatLngBounds: LatLngBounds,
14344
+ latLngBounds: toLatLngBounds,
14345
+ CRS: CRS,
14346
+ Projection: index,
14347
+ Layer: Layer,
14348
+ LayerGroup: LayerGroup,
14349
+ layerGroup: layerGroup,
14350
+ FeatureGroup: FeatureGroup,
14351
+ featureGroup: featureGroup,
14352
+ ImageOverlay: ImageOverlay,
14353
+ imageOverlay: imageOverlay,
14354
+ VideoOverlay: VideoOverlay,
14355
+ videoOverlay: videoOverlay,
14356
+ SVGOverlay: SVGOverlay,
14357
+ svgOverlay: svgOverlay,
14358
+ DivOverlay: DivOverlay,
14359
+ Popup: Popup,
14360
+ popup: popup,
14361
+ Tooltip: Tooltip,
14362
+ tooltip: tooltip,
14363
+ icon: icon,
14364
+ DivIcon: DivIcon,
14365
+ divIcon: divIcon,
14366
+ Marker: Marker,
14367
+ marker: marker,
14368
+ Icon: Icon,
14369
+ GridLayer: GridLayer,
14370
+ gridLayer: gridLayer,
14371
+ TileLayer: TileLayer,
14372
+ tileLayer: tileLayer,
14373
+ Renderer: Renderer,
14374
+ Canvas: Canvas,
14375
+ canvas: canvas,
14376
+ Path: Path,
14377
+ CircleMarker: CircleMarker,
14378
+ circleMarker: circleMarker,
14379
+ Circle: Circle,
14380
+ circle: circle,
14381
+ Polyline: Polyline,
14382
+ polyline: polyline,
14383
+ Polygon: Polygon,
14384
+ polygon: polygon,
14385
+ Rectangle: Rectangle,
14386
+ rectangle: rectangle,
14387
+ SVG: SVG,
14388
+ svg: svg,
14389
+ GeoJSON: GeoJSON,
14390
+ geoJSON: geoJSON,
14391
+ geoJson: geoJson,
14392
+ Map: Map,
14393
+ map: createMap
14394
+ };
14395
+
14396
+ var globalL = extend(L$1, {noConflict: noConflict});
14397
+
14398
+ var globalObject = getGlobalObject();
14399
+ var oldL = globalObject.L;
14400
+
14401
+ globalObject.L = globalL;
14402
+
14403
+ function noConflict() {
14404
+ globalObject.L = oldL;
14405
+ return globalL;
14406
+ }
14407
+
14408
+ function getGlobalObject() {
14409
+ if (typeof globalThis !== 'undefined') { return globalThis; }
14410
+ if (typeof self !== 'undefined') { return self; }
14411
+ if (typeof window !== 'undefined') { return window; }
14412
+ if (typeof global !== 'undefined') { return global; }
14413
+
14414
+ throw new Error('Unable to locate global object.');
14415
+ }
14416
+
14038
14417
  exports.Bounds = Bounds;
14039
14418
  exports.Browser = Browser;
14040
14419
  exports.CRS = CRS;
@@ -14086,6 +14465,7 @@
14086
14465
  exports.circle = circle;
14087
14466
  exports.circleMarker = circleMarker;
14088
14467
  exports.control = control;
14468
+ exports["default"] = globalL;
14089
14469
  exports.divIcon = divIcon;
14090
14470
  exports.extend = extend;
14091
14471
  exports.featureGroup = featureGroup;
@@ -14099,6 +14479,7 @@
14099
14479
  exports.layerGroup = layerGroup;
14100
14480
  exports.map = createMap;
14101
14481
  exports.marker = marker;
14482
+ exports.noConflict = noConflict;
14102
14483
  exports.point = toPoint;
14103
14484
  exports.polygon = polygon;
14104
14485
  exports.polyline = polyline;
@@ -14114,13 +14495,5 @@
14114
14495
  exports.version = version;
14115
14496
  exports.videoOverlay = videoOverlay;
14116
14497
 
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
14498
  }));
14126
14499
  //# sourceMappingURL=<%= asset_path 'leaflet-src.js.map' %>