leaflet-rails 1.9.2 → 1.9.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ac76749c8be70ff74252db4223b8263e0f64d5ca9111fb0db57e5b449362cd28
4
- data.tar.gz: 0463cf0179d226f8dee59a59e43caaa8d2dd851657c151d841e3f1403799db23
3
+ metadata.gz: 5867f577c8fd013854bb4aa8c2f4a304edd494d9a4406f7932947f9068fa2e67
4
+ data.tar.gz: '0078d4469dd93ff397d70cdda32a29f7f52e16f5f2214ba78607f6b1ce8ac3b3'
5
5
  SHA512:
6
- metadata.gz: 98d3510d3a093e46688cce6969edc704b0f09e5665805c6d93aadf2340cb70ef39f2b26180fed4003680282c186bd6c82735f064c30c6c482dac2419b8667d73
7
- data.tar.gz: edb8f891b3b565ed45cef1d717d571dac9ee306b7a9ad58bdc605041e1a094270d5451281538caa5155538e705f611e570ba5a703276bb448ce19e4acb46e838
6
+ metadata.gz: 5a3c53b49914fdc57fef1f1de030e7441669e72cc155523bc9b7d137984bfbb4634ba81064f33292f2a8973cc4c26a28aec5b768754df6789aa94c320be8d3a9
7
+ data.tar.gz: ca44b6f4224e8dfc2fc5e5cbc0a7adb8691bd53424b5af1d34802151453ac70ed4da4bad530ba1789d21539ae83240babca01c8935107eb79f839b0ec261da8e
@@ -1,5 +1,5 @@
1
1
  module Leaflet
2
2
  module Rails
3
- VERSION = "1.9.2"
3
+ VERSION = "1.9.4"
4
4
  end
5
5
  end
@@ -1,6 +1,6 @@
1
1
  /* @preserve
2
- * Leaflet 1.9.2, a JS library for interactive maps. https://leafletjs.com
3
- * (c) 2010-2022 Vladimir Agafonkin, (c) 2010-2011 CloudMade
2
+ * Leaflet 1.9.4+v1.d15112c, a JS library for interactive maps. https://leafletjs.com
3
+ * (c) 2010-2023 Vladimir Agafonkin, (c) 2010-2011 CloudMade
4
4
  */
5
5
 
6
6
  (function (global, factory) {
@@ -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.9.2";
12
+ var version = "1.9.4";
13
13
 
14
14
  /*
15
15
  * @namespace Util
@@ -398,6 +398,7 @@
398
398
  };
399
399
 
400
400
  function checkDeprecatedMixinEvents(includes) {
401
+ /* global L: true */
401
402
  if (typeof L === 'undefined' || !L || !L.Mixin) { return; }
402
403
 
403
404
  includes = isArray(includes) ? includes : [includes];
@@ -2166,7 +2167,7 @@
2166
2167
  }
2167
2168
  if (!handle[type]) {
2168
2169
  console.warn('wrong event specified:', type);
2169
- return L.Util.falseFn;
2170
+ return falseFn;
2170
2171
  }
2171
2172
  handler = handle[type].bind(this, handler);
2172
2173
  obj.addEventListener(pEvent[type], handler, false);
@@ -2625,8 +2626,8 @@
2625
2626
  if (!element.style) { return; }
2626
2627
  restoreOutline();
2627
2628
  _outlineElement = element;
2628
- _outlineStyle = element.style.outline;
2629
- element.style.outline = 'none';
2629
+ _outlineStyle = element.style.outlineStyle;
2630
+ element.style.outlineStyle = 'none';
2630
2631
  on(window, 'keydown', restoreOutline);
2631
2632
  }
2632
2633
 
@@ -2634,7 +2635,7 @@
2634
2635
  // Cancels the effects of a previous [`L.DomUtil.preventOutline`]().
2635
2636
  function restoreOutline() {
2636
2637
  if (!_outlineElement) { return; }
2637
- _outlineElement.style.outline = _outlineStyle;
2638
+ _outlineElement.style.outlineStyle = _outlineStyle;
2638
2639
  _outlineElement = undefined;
2639
2640
  _outlineStyle = undefined;
2640
2641
  off(window, 'keydown', restoreOutline);
@@ -4224,7 +4225,7 @@
4224
4225
 
4225
4226
  var position = getStyle(container, 'position');
4226
4227
 
4227
- if (position !== 'absolute' && position !== 'relative' && position !== 'fixed') {
4228
+ if (position !== 'absolute' && position !== 'relative' && position !== 'fixed' && position !== 'sticky') {
4228
4229
  container.style.position = 'relative';
4229
4230
  }
4230
4231
 
@@ -4655,7 +4656,7 @@
4655
4656
  // If offset is less than a pixel, ignore.
4656
4657
  // This prevents unstable projections from getting into
4657
4658
  // an infinite loop of tiny offsets.
4658
- if (offset.round().equals([0, 0])) {
4659
+ if (Math.abs(offset.x) <= 1 && Math.abs(offset.y) <= 1) {
4659
4660
  return center;
4660
4661
  }
4661
4662
 
@@ -4787,7 +4788,7 @@
4787
4788
 
4788
4789
  requestAnimFrame(function () {
4789
4790
  this
4790
- ._moveStart(true, false)
4791
+ ._moveStart(true, options.noMoveStart || false)
4791
4792
  ._animateZoom(center, zoom, true);
4792
4793
  }, this);
4793
4794
 
@@ -5110,6 +5111,7 @@
5110
5111
  this._layers = [];
5111
5112
  this._lastZIndex = 0;
5112
5113
  this._handlingClick = false;
5114
+ this._preventClick = false;
5113
5115
 
5114
5116
  for (var i in baseLayers) {
5115
5117
  this._addLayer(baseLayers[i], i);
@@ -5214,13 +5216,7 @@
5214
5216
  this._map.on('click', this.collapse, this);
5215
5217
 
5216
5218
  on(container, {
5217
- mouseenter: function () {
5218
- on(section, 'click', preventDefault);
5219
- this.expand();
5220
- setTimeout(function () {
5221
- off(section, 'click', preventDefault);
5222
- });
5223
- },
5219
+ mouseenter: this._expandSafely,
5224
5220
  mouseleave: this.collapse
5225
5221
  }, this);
5226
5222
  }
@@ -5230,8 +5226,18 @@
5230
5226
  link.title = 'Layers';
5231
5227
  link.setAttribute('role', 'button');
5232
5228
 
5233
- on(link, 'click', preventDefault); // prevent link function
5234
- on(link, 'focus', this.expand, this);
5229
+ on(link, {
5230
+ keydown: function (e) {
5231
+ if (e.keyCode === 13) {
5232
+ this._expandSafely();
5233
+ }
5234
+ },
5235
+ // Certain screen readers intercept the key event and instead send a click event
5236
+ click: function (e) {
5237
+ preventDefault(e);
5238
+ this._expandSafely();
5239
+ }
5240
+ }, this);
5235
5241
 
5236
5242
  if (!collapsed) {
5237
5243
  this.expand();
@@ -5381,6 +5387,11 @@
5381
5387
  },
5382
5388
 
5383
5389
  _onInputClick: function () {
5390
+ // expanding the control on mobile with a click can cause adding a layer - we don't want this
5391
+ if (this._preventClick) {
5392
+ return;
5393
+ }
5394
+
5384
5395
  var inputs = this._layerControlInputs,
5385
5396
  input, layer;
5386
5397
  var addedLayers = [],
@@ -5436,6 +5447,18 @@
5436
5447
  this.expand();
5437
5448
  }
5438
5449
  return this;
5450
+ },
5451
+
5452
+ _expandSafely: function () {
5453
+ var section = this._section;
5454
+ this._preventClick = true;
5455
+ on(section, 'click', preventDefault);
5456
+ this.expand();
5457
+ var that = this;
5458
+ setTimeout(function () {
5459
+ off(section, 'click', preventDefault);
5460
+ that._preventClick = false;
5461
+ });
5439
5462
  }
5440
5463
 
5441
5464
  });
@@ -6123,8 +6146,12 @@
6123
6146
  enableImageDrag();
6124
6147
  enableTextSelection();
6125
6148
 
6126
- if (this._moved && this._moving) {
6149
+ var fireDragend = this._moved && this._moving;
6150
+
6151
+ this._moving = false;
6152
+ Draggable._dragging = false;
6127
6153
 
6154
+ if (fireDragend) {
6128
6155
  // @event dragend: DragEndEvent
6129
6156
  // Fired when the drag ends.
6130
6157
  this.fire('dragend', {
@@ -6132,13 +6159,143 @@
6132
6159
  distance: this._newPos.distanceTo(this._startPos)
6133
6160
  });
6134
6161
  }
6135
-
6136
- this._moving = false;
6137
- Draggable._dragging = false;
6138
6162
  }
6139
6163
 
6140
6164
  });
6141
6165
 
6166
+ /*
6167
+ * @namespace PolyUtil
6168
+ * Various utility functions for polygon geometries.
6169
+ */
6170
+
6171
+ /* @function clipPolygon(points: Point[], bounds: Bounds, round?: Boolean): Point[]
6172
+ * Clips the polygon geometry defined by the given `points` by the given bounds (using the [Sutherland-Hodgman algorithm](https://en.wikipedia.org/wiki/Sutherland%E2%80%93Hodgman_algorithm)).
6173
+ * Used by Leaflet to only show polygon points that are on the screen or near, increasing
6174
+ * performance. Note that polygon points needs different algorithm for clipping
6175
+ * than polyline, so there's a separate method for it.
6176
+ */
6177
+ function clipPolygon(points, bounds, round) {
6178
+ var clippedPoints,
6179
+ edges = [1, 4, 2, 8],
6180
+ i, j, k,
6181
+ a, b,
6182
+ len, edge, p;
6183
+
6184
+ for (i = 0, len = points.length; i < len; i++) {
6185
+ points[i]._code = _getBitCode(points[i], bounds);
6186
+ }
6187
+
6188
+ // for each edge (left, bottom, right, top)
6189
+ for (k = 0; k < 4; k++) {
6190
+ edge = edges[k];
6191
+ clippedPoints = [];
6192
+
6193
+ for (i = 0, len = points.length, j = len - 1; i < len; j = i++) {
6194
+ a = points[i];
6195
+ b = points[j];
6196
+
6197
+ // if a is inside the clip window
6198
+ if (!(a._code & edge)) {
6199
+ // if b is outside the clip window (a->b goes out of screen)
6200
+ if (b._code & edge) {
6201
+ p = _getEdgeIntersection(b, a, edge, bounds, round);
6202
+ p._code = _getBitCode(p, bounds);
6203
+ clippedPoints.push(p);
6204
+ }
6205
+ clippedPoints.push(a);
6206
+
6207
+ // else if b is inside the clip window (a->b enters the screen)
6208
+ } else if (!(b._code & edge)) {
6209
+ p = _getEdgeIntersection(b, a, edge, bounds, round);
6210
+ p._code = _getBitCode(p, bounds);
6211
+ clippedPoints.push(p);
6212
+ }
6213
+ }
6214
+ points = clippedPoints;
6215
+ }
6216
+
6217
+ return points;
6218
+ }
6219
+
6220
+ /* @function polygonCenter(latlngs: LatLng[], crs: CRS): LatLng
6221
+ * Returns the center ([centroid](http://en.wikipedia.org/wiki/Centroid)) of the passed LatLngs (first ring) from a polygon.
6222
+ */
6223
+ function polygonCenter(latlngs, crs) {
6224
+ var i, j, p1, p2, f, area, x, y, center;
6225
+
6226
+ if (!latlngs || latlngs.length === 0) {
6227
+ throw new Error('latlngs not passed');
6228
+ }
6229
+
6230
+ if (!isFlat(latlngs)) {
6231
+ console.warn('latlngs are not flat! Only the first ring will be used');
6232
+ latlngs = latlngs[0];
6233
+ }
6234
+
6235
+ var centroidLatLng = toLatLng([0, 0]);
6236
+
6237
+ var bounds = toLatLngBounds(latlngs);
6238
+ var areaBounds = bounds.getNorthWest().distanceTo(bounds.getSouthWest()) * bounds.getNorthEast().distanceTo(bounds.getNorthWest());
6239
+ // tests showed that below 1700 rounding errors are happening
6240
+ if (areaBounds < 1700) {
6241
+ // getting a inexact center, to move the latlngs near to [0, 0] to prevent rounding errors
6242
+ centroidLatLng = centroid(latlngs);
6243
+ }
6244
+
6245
+ var len = latlngs.length;
6246
+ var points = [];
6247
+ for (i = 0; i < len; i++) {
6248
+ var latlng = toLatLng(latlngs[i]);
6249
+ points.push(crs.project(toLatLng([latlng.lat - centroidLatLng.lat, latlng.lng - centroidLatLng.lng])));
6250
+ }
6251
+
6252
+ area = x = y = 0;
6253
+
6254
+ // polygon centroid algorithm;
6255
+ for (i = 0, j = len - 1; i < len; j = i++) {
6256
+ p1 = points[i];
6257
+ p2 = points[j];
6258
+
6259
+ f = p1.y * p2.x - p2.y * p1.x;
6260
+ x += (p1.x + p2.x) * f;
6261
+ y += (p1.y + p2.y) * f;
6262
+ area += f * 3;
6263
+ }
6264
+
6265
+ if (area === 0) {
6266
+ // Polygon is so small that all points are on same pixel.
6267
+ center = points[0];
6268
+ } else {
6269
+ center = [x / area, y / area];
6270
+ }
6271
+
6272
+ var latlngCenter = crs.unproject(toPoint(center));
6273
+ return toLatLng([latlngCenter.lat + centroidLatLng.lat, latlngCenter.lng + centroidLatLng.lng]);
6274
+ }
6275
+
6276
+ /* @function centroid(latlngs: LatLng[]): LatLng
6277
+ * Returns the 'center of mass' of the passed LatLngs.
6278
+ */
6279
+ function centroid(coords) {
6280
+ var latSum = 0;
6281
+ var lngSum = 0;
6282
+ var len = 0;
6283
+ for (var i = 0; i < coords.length; i++) {
6284
+ var latlng = toLatLng(coords[i]);
6285
+ latSum += latlng.lat;
6286
+ lngSum += latlng.lng;
6287
+ len++;
6288
+ }
6289
+ return toLatLng([latSum / len, lngSum / len]);
6290
+ }
6291
+
6292
+ var PolyUtil = {
6293
+ __proto__: null,
6294
+ clipPolygon: clipPolygon,
6295
+ polygonCenter: polygonCenter,
6296
+ centroid: centroid
6297
+ };
6298
+
6142
6299
  /*
6143
6300
  * @namespace LineUtil
6144
6301
  *
@@ -6393,12 +6550,22 @@
6393
6550
  latlngs = latlngs[0];
6394
6551
  }
6395
6552
 
6396
- var points = [];
6397
- for (var j in latlngs) {
6398
- points.push(crs.project(toLatLng(latlngs[j])));
6553
+ var centroidLatLng = toLatLng([0, 0]);
6554
+
6555
+ var bounds = toLatLngBounds(latlngs);
6556
+ var areaBounds = bounds.getNorthWest().distanceTo(bounds.getSouthWest()) * bounds.getNorthEast().distanceTo(bounds.getNorthWest());
6557
+ // tests showed that below 1700 rounding errors are happening
6558
+ if (areaBounds < 1700) {
6559
+ // getting a inexact center, to move the latlngs near to [0, 0] to prevent rounding errors
6560
+ centroidLatLng = centroid(latlngs);
6399
6561
  }
6400
6562
 
6401
- var len = points.length;
6563
+ var len = latlngs.length;
6564
+ var points = [];
6565
+ for (i = 0; i < len; i++) {
6566
+ var latlng = toLatLng(latlngs[i]);
6567
+ points.push(crs.project(toLatLng([latlng.lat - centroidLatLng.lat, latlng.lng - centroidLatLng.lng])));
6568
+ }
6402
6569
 
6403
6570
  for (i = 0, halfDist = 0; i < len - 1; i++) {
6404
6571
  halfDist += points[i].distanceTo(points[i + 1]) / 2;
@@ -6424,7 +6591,9 @@
6424
6591
  }
6425
6592
  }
6426
6593
  }
6427
- return crs.unproject(toPoint(center));
6594
+
6595
+ var latlngCenter = crs.unproject(toPoint(center));
6596
+ return toLatLng([latlngCenter.lat + centroidLatLng.lat, latlngCenter.lng + centroidLatLng.lng]);
6428
6597
  }
6429
6598
 
6430
6599
  var LineUtil = {
@@ -6441,109 +6610,6 @@
6441
6610
  polylineCenter: polylineCenter
6442
6611
  };
6443
6612
 
6444
- /*
6445
- * @namespace PolyUtil
6446
- * Various utility functions for polygon geometries.
6447
- */
6448
-
6449
- /* @function clipPolygon(points: Point[], bounds: Bounds, round?: Boolean): Point[]
6450
- * Clips the polygon geometry defined by the given `points` by the given bounds (using the [Sutherland-Hodgman algorithm](https://en.wikipedia.org/wiki/Sutherland%E2%80%93Hodgman_algorithm)).
6451
- * Used by Leaflet to only show polygon points that are on the screen or near, increasing
6452
- * performance. Note that polygon points needs different algorithm for clipping
6453
- * than polyline, so there's a separate method for it.
6454
- */
6455
- function clipPolygon(points, bounds, round) {
6456
- var clippedPoints,
6457
- edges = [1, 4, 2, 8],
6458
- i, j, k,
6459
- a, b,
6460
- len, edge, p;
6461
-
6462
- for (i = 0, len = points.length; i < len; i++) {
6463
- points[i]._code = _getBitCode(points[i], bounds);
6464
- }
6465
-
6466
- // for each edge (left, bottom, right, top)
6467
- for (k = 0; k < 4; k++) {
6468
- edge = edges[k];
6469
- clippedPoints = [];
6470
-
6471
- for (i = 0, len = points.length, j = len - 1; i < len; j = i++) {
6472
- a = points[i];
6473
- b = points[j];
6474
-
6475
- // if a is inside the clip window
6476
- if (!(a._code & edge)) {
6477
- // if b is outside the clip window (a->b goes out of screen)
6478
- if (b._code & edge) {
6479
- p = _getEdgeIntersection(b, a, edge, bounds, round);
6480
- p._code = _getBitCode(p, bounds);
6481
- clippedPoints.push(p);
6482
- }
6483
- clippedPoints.push(a);
6484
-
6485
- // else if b is inside the clip window (a->b enters the screen)
6486
- } else if (!(b._code & edge)) {
6487
- p = _getEdgeIntersection(b, a, edge, bounds, round);
6488
- p._code = _getBitCode(p, bounds);
6489
- clippedPoints.push(p);
6490
- }
6491
- }
6492
- points = clippedPoints;
6493
- }
6494
-
6495
- return points;
6496
- }
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
-
6541
- var PolyUtil = {
6542
- __proto__: null,
6543
- clipPolygon: clipPolygon,
6544
- polygonCenter: polygonCenter
6545
- };
6546
-
6547
6613
  /*
6548
6614
  * @namespace Projection
6549
6615
  * @section
@@ -9116,8 +9182,8 @@
9116
9182
  latLngToCoords(latlngs[i], precision));
9117
9183
  }
9118
9184
 
9119
- if (!levelsDeep && closed) {
9120
- coords.push(coords[0]);
9185
+ if (!levelsDeep && closed && coords.length > 0) {
9186
+ coords.push(coords[0].slice());
9121
9187
  }
9122
9188
 
9123
9189
  return coords;
@@ -9730,7 +9796,7 @@
9730
9796
  },
9731
9797
 
9732
9798
  initialize: function (options, source) {
9733
- if (options && (options instanceof L.LatLng || isArray(options))) {
9799
+ if (options && (options instanceof LatLng || isArray(options))) {
9734
9800
  this._latlng = toLatLng(options);
9735
9801
  setOptions(this, source);
9736
9802
  } else {
@@ -10283,10 +10349,17 @@
10283
10349
  setPosition(this._container, pos.add(anchor));
10284
10350
  },
10285
10351
 
10286
- _adjustPan: function (e) {
10352
+ _adjustPan: function () {
10287
10353
  if (!this.options.autoPan) { return; }
10288
10354
  if (this._map._panAnim) { this._map._panAnim.stop(); }
10289
10355
 
10356
+ // We can endlessly recurse if keepInView is set and the view resets.
10357
+ // Let's guard against that by exiting early if we're responding to our own autopan.
10358
+ if (this._autopanning) {
10359
+ this._autopanning = false;
10360
+ return;
10361
+ }
10362
+
10290
10363
  var map = this._map,
10291
10364
  marginBottom = parseInt(getStyle(this._container, 'marginBottom'), 10) || 0,
10292
10365
  containerHeight = this._container.offsetHeight + marginBottom,
@@ -10321,9 +10394,14 @@
10321
10394
  // @event autopanstart: Event
10322
10395
  // Fired when the map starts autopanning when opening a popup.
10323
10396
  if (dx || dy) {
10397
+ // Track that we're autopanning, as this function will be re-ran on moveend
10398
+ if (this.options.keepInView) {
10399
+ this._autopanning = true;
10400
+ }
10401
+
10324
10402
  map
10325
10403
  .fire('autopanstart')
10326
- .panBy([dx, dy], {animate: e && e.type === 'moveend'});
10404
+ .panBy([dx, dy]);
10327
10405
  }
10328
10406
  },
10329
10407
 
@@ -10437,10 +10515,14 @@
10437
10515
  // @method openPopup(latlng?: LatLng): this
10438
10516
  // Opens the bound popup at the specified `latlng` or at the default popup anchor if no `latlng` is passed.
10439
10517
  openPopup: function (latlng) {
10440
- if (this._popup && this._popup._prepareOpen(latlng || this._latlng)) {
10441
-
10442
- // open the popup on the map
10443
- this._popup.openOn(this._map);
10518
+ if (this._popup) {
10519
+ if (!(this instanceof FeatureGroup)) {
10520
+ this._popup._source = this;
10521
+ }
10522
+ if (this._popup._prepareOpen(latlng || this._latlng)) {
10523
+ // open the popup on the map
10524
+ this._popup.openOn(this._map);
10525
+ }
10444
10526
  }
10445
10527
  return this;
10446
10528
  },
@@ -10838,14 +10920,19 @@
10838
10920
  // @method openTooltip(latlng?: LatLng): this
10839
10921
  // Opens the bound tooltip at the specified `latlng` or at the default tooltip anchor if no `latlng` is passed.
10840
10922
  openTooltip: function (latlng) {
10841
- if (this._tooltip && this._tooltip._prepareOpen(latlng)) {
10842
- // open the tooltip on the map
10843
- this._tooltip.openOn(this._map);
10844
-
10845
- if (this.getElement) {
10846
- this._setAriaDescribedByOnLayer(this);
10847
- } else if (this.eachLayer) {
10848
- this.eachLayer(this._setAriaDescribedByOnLayer, this);
10923
+ if (this._tooltip) {
10924
+ if (!(this instanceof FeatureGroup)) {
10925
+ this._tooltip._source = this;
10926
+ }
10927
+ if (this._tooltip._prepareOpen(latlng)) {
10928
+ // open the tooltip on the map
10929
+ this._tooltip.openOn(this._map);
10930
+
10931
+ if (this.getElement) {
10932
+ this._setAriaDescribedByOnLayer(this);
10933
+ } else if (this.eachLayer) {
10934
+ this.eachLayer(this._setAriaDescribedByOnLayer, this);
10935
+ }
10849
10936
  }
10850
10937
  }
10851
10938
  return this;
@@ -10898,7 +10985,7 @@
10898
10985
  },
10899
10986
 
10900
10987
  _addFocusListenersOnLayer: function (layer) {
10901
- var el = layer.getElement();
10988
+ var el = typeof layer.getElement === 'function' && layer.getElement();
10902
10989
  if (el) {
10903
10990
  on(el, 'focus', function () {
10904
10991
  this._tooltip._source = layer;
@@ -10909,7 +10996,7 @@
10909
10996
  },
10910
10997
 
10911
10998
  _setAriaDescribedByOnLayer: function (layer) {
10912
- var el = layer.getElement();
10999
+ var el = typeof layer.getElement === 'function' && layer.getElement();
10913
11000
  if (el) {
10914
11001
  el.setAttribute('aria-describedby', this._tooltip._container.id);
10915
11002
  }
@@ -10917,9 +11004,21 @@
10917
11004
 
10918
11005
 
10919
11006
  _openTooltip: function (e) {
10920
- if (!this._tooltip || !this._map || (this._map.dragging && this._map.dragging.moving())) {
11007
+ if (!this._tooltip || !this._map) {
10921
11008
  return;
10922
11009
  }
11010
+
11011
+ // If the map is moving, we will show the tooltip after it's done.
11012
+ if (this._map.dragging && this._map.dragging.moving() && !this._openOnceFlag) {
11013
+ this._openOnceFlag = true;
11014
+ var that = this;
11015
+ this._map.once('moveend', function () {
11016
+ that._openOnceFlag = false;
11017
+ that._openTooltip(e);
11018
+ });
11019
+ return;
11020
+ }
11021
+
10923
11022
  this._tooltip._source = e.layer || e.target;
10924
11023
 
10925
11024
  this.openTooltip(this._tooltip.options.sticky ? e.latlng : undefined);
@@ -12384,9 +12483,8 @@
12384
12483
  if (!this._container) {
12385
12484
  this._initContainer(); // defined by renderer implementations
12386
12485
 
12387
- if (this._zoomAnimated) {
12388
- addClass(this._container, 'leaflet-zoom-animated');
12389
- }
12486
+ // always keep transform-origin as 0 0
12487
+ addClass(this._container, 'leaflet-zoom-animated');
12390
12488
  }
12391
12489
 
12392
12490
  this.getPane().appendChild(this._container);
@@ -13977,10 +14075,15 @@
13977
14075
  offset = toPoint(offset).multiplyBy(3);
13978
14076
  }
13979
14077
 
13980
- map.panBy(offset);
13981
-
13982
14078
  if (map.options.maxBounds) {
13983
- map.panInsideBounds(map.options.maxBounds);
14079
+ offset = map._limitOffset(toPoint(offset), map.options.maxBounds);
14080
+ }
14081
+
14082
+ if (map.options.worldCopyJump) {
14083
+ var newLatLng = map.wrapLatLng(map.unproject(map.project(map.getCenter()).add(offset)));
14084
+ map.panTo(newLatLng);
14085
+ } else {
14086
+ map.panBy(offset);
13984
14087
  }
13985
14088
  }
13986
14089
  } else if (key in this._zoomKeys) {