leaflet-rails 1.0.0.pre.rc3 → 1.0.0

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
  SHA1:
3
- metadata.gz: f0c97aec024487b391c9f35605d30b22b28fb123
4
- data.tar.gz: 75edc6def71d9c53f520a764f66256b90bd76b45
3
+ metadata.gz: cade19c6b53274eddf5f57dfd3bd9700910b7cfe
4
+ data.tar.gz: 41e1720f5574bc590503a3cec2c83aa193b3da2f
5
5
  SHA512:
6
- metadata.gz: e2f6a39b4d438316048c2383f3bc0639a5499aaa0af6da609a6ab2d6fed7ffed1f5b13d4714224e6b7bf9ece3f04a66efffed8a92d692cf2606b0a02e7e68c26
7
- data.tar.gz: 28a4594cd8aec615953f39adeb61f960e6fae645d6f571bb7253063186844b18058235440f866b1a5f71eae81635ec71e2514a441466ec399779fec238b55bc5
6
+ metadata.gz: d8106c56673c20e2505606461ad7cc4e79c24131c03ce328c2ddbac3fef2c172eb5e0dffb83f03ffcaaaf5fa1527df1217ae697803060619e1a0d195f8accdf5
7
+ data.tar.gz: a636f5942455a8fa619c233770384a4035df719095933806b9d120576fac52040714df69aa07f7af1d33f99bc3c3b617c366ae28ad2b1c473ee0a67353409258
@@ -1,5 +1,5 @@
1
1
  module Leaflet
2
2
  module Rails
3
- VERSION = "1.0.0-rc3"
3
+ VERSION = "1.0.0"
4
4
  end
5
5
  end
@@ -1,10 +1,10 @@
1
1
  /*
2
- Leaflet 1.0.0-rc.3, a JS library for interactive maps. http://leafletjs.com
3
- (c) 2010-2015 Vladimir Agafonkin, (c) 2010-2011 CloudMade
2
+ Leaflet 1.0.0, a JS library for interactive maps. http://leafletjs.com
3
+ (c) 2010-2016 Vladimir Agafonkin, (c) 2010-2011 CloudMade
4
4
  */
5
5
  (function (window, document, undefined) {
6
6
  var L = {
7
- version: "1.0.0-rc.3"
7
+ version: "1.0.0"
8
8
  };
9
9
 
10
10
  function expose() {
@@ -497,10 +497,7 @@ L.Evented = L.Class.extend({
497
497
  /* get/init listeners for type */
498
498
  var typeListeners = this._events[type];
499
499
  if (!typeListeners) {
500
- typeListeners = {
501
- listeners: [],
502
- count: 0
503
- };
500
+ typeListeners = [];
504
501
  this._events[type] = typeListeners;
505
502
  }
506
503
 
@@ -509,7 +506,7 @@ L.Evented = L.Class.extend({
509
506
  context = undefined;
510
507
  }
511
508
  var newListener = {fn: fn, ctx: context},
512
- listeners = typeListeners.listeners;
509
+ listeners = typeListeners;
513
510
 
514
511
  // check if fn already there
515
512
  for (var i = 0, len = listeners.length; i < len; i++) {
@@ -523,21 +520,18 @@ L.Evented = L.Class.extend({
523
520
  },
524
521
 
525
522
  _off: function (type, fn, context) {
526
- var typeListeners,
527
- listeners,
523
+ var listeners,
528
524
  i,
529
525
  len;
530
526
 
531
527
  if (!this._events) { return; }
532
528
 
533
- typeListeners = this._events[type];
529
+ listeners = this._events[type];
534
530
 
535
- if (!typeListeners) {
531
+ if (!listeners) {
536
532
  return;
537
533
  }
538
534
 
539
- listeners = typeListeners.listeners;
540
-
541
535
  if (!fn) {
542
536
  // Set all removed listeners to noop so they are not called if remove happens in fire
543
537
  for (i = 0, len = listeners.length; i < len; i++) {
@@ -548,7 +542,6 @@ L.Evented = L.Class.extend({
548
542
  return;
549
543
  }
550
544
 
551
-
552
545
  if (context === this) {
553
546
  context = undefined;
554
547
  }
@@ -563,11 +556,10 @@ L.Evented = L.Class.extend({
563
556
 
564
557
  // set the removed listener to noop so that's not called if remove happens in fire
565
558
  l.fn = L.Util.falseFn;
566
- typeListeners.count--;
567
559
 
568
- if (this._isFiring) {
560
+ if (this._firingCount) {
569
561
  /* copy array in case events are being fired */
570
- listeners = listeners.slice();
562
+ this._events[type] = listeners = listeners.slice();
571
563
  }
572
564
  listeners.splice(i, 1);
573
565
 
@@ -587,17 +579,16 @@ L.Evented = L.Class.extend({
587
579
  var event = L.Util.extend({}, data, {type: type, target: this});
588
580
 
589
581
  if (this._events) {
590
- var typeListeners = this._events[type];
582
+ var listeners = this._events[type];
591
583
 
592
- if (typeListeners) {
593
- this._isFiring = true;
594
- var listeners = typeListeners.listeners;
584
+ if (listeners) {
585
+ this._firingCount = (this._firingCount + 1) || 1;
595
586
  for (var i = 0, len = listeners.length; i < len; i++) {
596
587
  var l = listeners[i];
597
588
  l.fn.call(l.ctx || this, event);
598
589
  }
599
590
 
600
- this._isFiring = false;
591
+ this._firingCount--;
601
592
  }
602
593
  }
603
594
 
@@ -612,8 +603,8 @@ L.Evented = L.Class.extend({
612
603
  // @method listens(type: String): Boolean
613
604
  // Returns `true` if a particular event type has any listeners attached to it.
614
605
  listens: function (type, propagate) {
615
- var typeListeners = this._events && this._events[type];
616
- if (typeListeners && typeListeners.count) { return true; }
606
+ var listeners = this._events && this._events[type];
607
+ if (listeners && listeners.length) { return true; }
617
608
 
618
609
  if (propagate) {
619
610
  // also check parents for listeners if event propagates
@@ -2094,13 +2085,13 @@ L.CRS = {
2094
2085
  },
2095
2086
 
2096
2087
  // @method zoom(scale: Number): Number
2097
- // Inverse of `scale()`, returns the zoom level correspondingto a scale
2088
+ // Inverse of `scale()`, returns the zoom level corresponding to a scale
2098
2089
  // factor of `scale`.
2099
2090
  zoom: function (scale) {
2100
2091
  return Math.log(scale / 256) / Math.LN2;
2101
2092
  },
2102
2093
 
2103
- // @method getProjectedBounds(zoom): Bounds
2094
+ // @method getProjectedBounds(zoom: Number): Bounds
2104
2095
  // Returns the projection's bounds scaled and transformed for the provided `zoom`.
2105
2096
  getProjectedBounds: function (zoom) {
2106
2097
  if (this.infinite) { return null; }
@@ -2113,7 +2104,7 @@ L.CRS = {
2113
2104
  return L.bounds(min, max);
2114
2105
  },
2115
2106
 
2116
- // @method distance(latlng1: LatLng, latlng1: LatLng): Number
2107
+ // @method distance(latlng1: LatLng, latlng2: LatLng): Number
2117
2108
  // Returns the distance between two geographical coordinates.
2118
2109
 
2119
2110
  // @property code: String
@@ -2661,11 +2652,19 @@ L.Map = L.Evented.extend({
2661
2652
 
2662
2653
  this._initEvents(true);
2663
2654
 
2655
+ if (this._containerId !== this._container._leaflet_id) {
2656
+ throw new Error('Map container is being reused by another instance');
2657
+ }
2658
+
2664
2659
  try {
2665
2660
  // throws error in IE6-8
2666
- delete this._container._leaflet;
2661
+ delete this._container._leaflet_id;
2662
+ delete this._containerId;
2667
2663
  } catch (e) {
2668
- this._container._leaflet = undefined;
2664
+ /*eslint-disable */
2665
+ this._container._leaflet_id = undefined;
2666
+ /*eslint-enable */
2667
+ this._containerId = undefined;
2669
2668
  }
2670
2669
 
2671
2670
  L.DomUtil.remove(this._mapPane);
@@ -2857,7 +2856,8 @@ L.Map = L.Evented.extend({
2857
2856
  getScaleZoom: function (scale, fromZoom) {
2858
2857
  var crs = this.options.crs;
2859
2858
  fromZoom = fromZoom === undefined ? this._zoom : fromZoom;
2860
- return crs.zoom(scale * crs.scale(fromZoom));
2859
+ var zoom = crs.zoom(scale * crs.scale(fromZoom));
2860
+ return isNaN(zoom) ? Infinity : zoom;
2861
2861
  },
2862
2862
 
2863
2863
  // @method project(latlng: LatLng, zoom: Number): Point
@@ -2968,12 +2968,12 @@ L.Map = L.Evented.extend({
2968
2968
 
2969
2969
  if (!container) {
2970
2970
  throw new Error('Map container not found.');
2971
- } else if (container._leaflet) {
2971
+ } else if (container._leaflet_id) {
2972
2972
  throw new Error('Map container is already initialized.');
2973
2973
  }
2974
2974
 
2975
2975
  L.DomEvent.addListener(container, 'scroll', this._onScroll, this);
2976
- container._leaflet = true;
2976
+ this._containerId = L.Util.stamp(container);
2977
2977
  },
2978
2978
 
2979
2979
  _initLayout: function () {
@@ -3099,14 +3099,14 @@ L.Map = L.Evented.extend({
3099
3099
  this._pixelOrigin = this._getNewPixelOrigin(center);
3100
3100
 
3101
3101
  // @event zoom: Event
3102
- // Fired repeteadly during any change in zoom level, including zoom
3102
+ // Fired repeatedly during any change in zoom level, including zoom
3103
3103
  // and fly animations.
3104
3104
  if (zoomChanged || (data && data.pinch)) { // Always fire 'zoom' if pinching because #3530
3105
3105
  this.fire('zoom', data);
3106
3106
  }
3107
3107
 
3108
3108
  // @event move: Event
3109
- // Fired repeteadly during any movement of the map, including pan and
3109
+ // Fired repeatedly during any movement of the map, including pan and
3110
3110
  // fly animations.
3111
3111
  return this.fire('move', data);
3112
3112
  },
@@ -3182,7 +3182,7 @@ L.Map = L.Evented.extend({
3182
3182
  // default browser context menu from showing if there are listeners on
3183
3183
  // this event. Also fired on mobile when the user holds a single touch
3184
3184
  // for a second (also called long press).
3185
- // @event keypress: Event
3185
+ // @event keypress: KeyboardEvent
3186
3186
  // Fired when the user presses a key from the keyboard while the map is focused.
3187
3187
  L.DomEvent[onOff](this._container, 'click dblclick mousedown mouseup ' +
3188
3188
  'mouseover mouseout mousemove contextmenu keypress', this._handleDOMEvent, this);
@@ -3899,7 +3899,7 @@ L.GridLayer = L.Layer.extend({
3899
3899
  },
3900
3900
 
3901
3901
  initialize: function (options) {
3902
- options = L.setOptions(this, options);
3902
+ L.setOptions(this, options);
3903
3903
  },
3904
3904
 
3905
3905
  onAdd: function () {
@@ -3950,7 +3950,7 @@ L.GridLayer = L.Layer.extend({
3950
3950
  return this.options.attribution;
3951
3951
  },
3952
3952
 
3953
- // @method getContainer: String
3953
+ // @method getContainer: HTMLElement
3954
3954
  // Returns the HTML element that contains the tiles for this layer.
3955
3955
  getContainer: function () {
3956
3956
  return this._container;
@@ -4458,8 +4458,13 @@ L.GridLayer = L.Layer.extend({
4458
4458
  nwPoint = coords.scaleBy(tileSize),
4459
4459
  sePoint = nwPoint.add(tileSize),
4460
4460
 
4461
- nw = map.wrapLatLng(map.unproject(nwPoint, coords.z)),
4462
- se = map.wrapLatLng(map.unproject(sePoint, coords.z));
4461
+ nw = map.unproject(nwPoint, coords.z),
4462
+ se = map.unproject(sePoint, coords.z);
4463
+
4464
+ if (!this.options.noWrap) {
4465
+ nw = map.wrapLatLng(nw);
4466
+ se = map.wrapLatLng(se);
4467
+ }
4463
4468
 
4464
4469
  return new L.LatLngBounds(nw, se);
4465
4470
  },
@@ -5095,7 +5100,7 @@ L.ImageOverlay = L.Layer.extend({
5095
5100
  }
5096
5101
  },
5097
5102
 
5098
- // @method setOpacity(): this
5103
+ // @method setOpacity(opacity: Number): this
5099
5104
  // Sets the opacity of the overlay.
5100
5105
  setOpacity: function (opacity) {
5101
5106
  this.options.opacity = opacity;
@@ -5374,12 +5379,24 @@ L.icon = function (options) {
5374
5379
 
5375
5380
 
5376
5381
  /*
5377
- * L.Icon.Default is the blue marker icon used by default in Leaflet.
5382
+ * @miniclass Icon.Default (Icon)
5383
+ * @aka L.Icon.Default
5384
+ * @section
5385
+ *
5386
+ * A trivial subclass of `Icon`, represents the icon to use in `Marker`s when
5387
+ * no icon is specified. Points to the blue marker image distributed with Leaflet
5388
+ * releases.
5389
+ *
5390
+ * In order to change the default icon, just change the properties of `L.Icon.Default.prototype.options`
5391
+ * (which is a set of `Icon options`).
5378
5392
  */
5379
5393
 
5380
5394
  L.Icon.Default = L.Icon.extend({
5381
5395
 
5382
5396
  options: {
5397
+ iconUrl: 'marker-icon.png',
5398
+ iconRetinaUrl: 'marker-icon-2x.png',
5399
+ shadowUrl: 'marker-shadow.png',
5383
5400
  iconSize: [25, 41],
5384
5401
  iconAnchor: [12, 41],
5385
5402
  popupAnchor: [1, -34],
@@ -5388,37 +5405,28 @@ L.Icon.Default = L.Icon.extend({
5388
5405
  },
5389
5406
 
5390
5407
  _getIconUrl: function (name) {
5391
- var key = name + 'Url';
5392
-
5393
- if (this.options[key]) {
5394
- return this.options[key];
5408
+ if (!L.Icon.Default.imagePath) { // Deprecated, backwards-compatibility only
5409
+ L.Icon.Default.imagePath = this._detectIconPath();
5395
5410
  }
5396
5411
 
5397
- var path = L.Icon.Default.imagePath;
5398
-
5399
- if (!path) {
5400
- throw new Error('Couldn\'t autodetect L.Icon.Default.imagePath, set it manually.');
5401
- }
5402
-
5403
- return path + '/marker-' + name + (L.Browser.retina && name === 'icon' ? '-2x' : '') + '.png';
5404
- }
5405
- });
5406
-
5407
- L.Icon.Default.imagePath = (function () {
5408
- var scripts = document.getElementsByTagName('script'),
5409
- leafletRe = /[\/^]leaflet[\-\._]?([\w\-\._]*)\.js\??/;
5412
+ // @option imagePath: String
5413
+ // `L.Icon.Default` will try to auto-detect the absolute location of the
5414
+ // blue icon images. If you are placing these images in a non-standard
5415
+ // way, set this option to point to the right absolute path.
5416
+ return (this.options.imagePath || L.Icon.Default.imagePath) + L.Icon.prototype._getIconUrl.call(this, name);
5417
+ },
5410
5418
 
5411
- var i, len, src, path;
5419
+ _detectIconPath: function () {
5420
+ var el = L.DomUtil.create('div', 'leaflet-default-icon-path', document.body);
5421
+ var path = L.DomUtil.getStyle(el, 'background-image') ||
5422
+ L.DomUtil.getStyle(el, 'backgroundImage'); // IE8
5412
5423
 
5413
- for (i = 0, len = scripts.length; i < len; i++) {
5414
- src = scripts[i].src || '';
5424
+ document.body.removeChild(el);
5415
5425
 
5416
- if (src.match(leafletRe)) {
5417
- path = src.split(leafletRe)[0];
5418
- return (path ? path + '/' : '') + 'images';
5419
- }
5426
+ return path.indexOf('url') === 0 ?
5427
+ path.replace(/^url\([\"\']?/, '').replace(/[\"\']?\)$/, '') : '';
5420
5428
  }
5421
- }());
5429
+ });
5422
5430
 
5423
5431
 
5424
5432
 
@@ -5441,7 +5449,7 @@ L.Marker = L.Layer.extend({
5441
5449
  // @aka Marker options
5442
5450
  options: {
5443
5451
  // @option icon: Icon = *
5444
- // Icon class to use for rendering the marker. See [Icon documentation](#L.Icon) for details on how to customize the marker icon. Set to new `L.Icon.Default()` by default.
5452
+ // Icon class to use for rendering the marker. See [Icon documentation](#L.Icon) for details on how to customize the marker icon. If not specified, a new `L.Icon.Default` is used.
5445
5453
  icon: new L.Icon.Default(),
5446
5454
 
5447
5455
  // Option inherited from "Interactive layer" abstract class
@@ -5843,11 +5851,6 @@ L.DivOverlay = L.Layer.extend({
5843
5851
  // of the popup when opening it on some overlays.
5844
5852
  offset: [0, 7],
5845
5853
 
5846
- // @option zoomAnimation: Boolean = true
5847
- // Whether to animate the popup on zoom. Disable it if you have
5848
- // problems with Flash content inside popups.
5849
- zoomAnimation: true,
5850
-
5851
5854
  // @option className: String = ''
5852
5855
  // A custom CSS class name to assign to the popup.
5853
5856
  className: '',
@@ -5864,7 +5867,7 @@ L.DivOverlay = L.Layer.extend({
5864
5867
  },
5865
5868
 
5866
5869
  onAdd: function (map) {
5867
- this._zoomAnimated = this._zoomAnimated && this.options.zoomAnimation;
5870
+ this._zoomAnimated = map._zoomAnimated;
5868
5871
 
5869
5872
  if (!this._container) {
5870
5873
  this._initLayout();
@@ -6108,7 +6111,11 @@ L.Popup = L.DivOverlay.extend({
6108
6111
  // Set it to `false` if you want to override the default behavior of
6109
6112
  // the popup closing when user clicks the map (set globally by
6110
6113
  // the Map's [closePopupOnClick](#map-closepopuponclick) option).
6111
- autoClose: true
6114
+ autoClose: true,
6115
+
6116
+ // @option className: String = ''
6117
+ // A custom CSS class name to assign to the popup.
6118
+ className: ''
6112
6119
  },
6113
6120
 
6114
6121
  // @namespace Popup
@@ -6187,7 +6194,7 @@ L.Popup = L.DivOverlay.extend({
6187
6194
  var prefix = 'leaflet-popup',
6188
6195
  container = this._container = L.DomUtil.create('div',
6189
6196
  prefix + ' ' + (this.options.className || '') +
6190
- ' leaflet-zoom-' + (this._zoomAnimated ? 'animated' : 'hide'));
6197
+ ' leaflet-zoom-animated');
6191
6198
 
6192
6199
  if (this.options.closeButton) {
6193
6200
  var closeButton = this._closeButton = L.DomUtil.create('a', prefix + '-close-button', container);
@@ -6254,9 +6261,7 @@ L.Popup = L.DivOverlay.extend({
6254
6261
  containerWidth = this._containerWidth,
6255
6262
  layerPos = new L.Point(this._containerLeft, -containerHeight - this._containerBottom);
6256
6263
 
6257
- if (this._zoomAnimated) {
6258
- layerPos._add(L.DomUtil.getPosition(this._container));
6259
- }
6264
+ layerPos._add(L.DomUtil.getPosition(this._container));
6260
6265
 
6261
6266
  var containerPos = map.layerPointToContainerPoint(layerPos),
6262
6267
  padding = L.point(this.options.autoPanPadding),
@@ -6728,7 +6733,7 @@ L.Tooltip = L.DivOverlay.extend({
6728
6733
 
6729
6734
  _getAnchor: function () {
6730
6735
  // Where should we anchor the tooltip on the source layer?
6731
- return L.point(this._source._getTooltipAnchor && !this.options.sticky ? this._source._getTooltipAnchor() : [0, 0]);
6736
+ return L.point(this._source && this._source._getTooltipAnchor && !this.options.sticky ? this._source._getTooltipAnchor() : [0, 0]);
6732
6737
  }
6733
6738
 
6734
6739
  });
@@ -6901,7 +6906,7 @@ L.Layer.include({
6901
6906
  closeTooltip: function () {
6902
6907
  if (this._tooltip) {
6903
6908
  this._tooltip._close();
6904
- if (this._tooltip.options.interactive) {
6909
+ if (this._tooltip.options.interactive && this._tooltip._container) {
6905
6910
  L.DomUtil.removeClass(this._tooltip._container, 'leaflet-clickable');
6906
6911
  this.removeInteractiveTarget(this._tooltip._container);
6907
6912
  }
@@ -7144,14 +7149,19 @@ L.layerGroup = function (layers) {
7144
7149
  * @aka L.FeatureGroup
7145
7150
  * @inherits LayerGroup
7146
7151
  *
7147
- * Extended `LayerGroup` that also has mouse events (propagated from members of the group) and a shared bindPopup method.
7152
+ * Extended `LayerGroup` that makes it easier to do the same thing to all its member layers:
7153
+ * * [`bindPopup`](#layer-bindpopup) binds a popup to all of the layers at once (likewise with [`bindTooltip`](#layer-bindtooltip))
7154
+ * * Events are propagated to the `FeatureGroup`, so if the group has an event
7155
+ * handler, it will handle events from any of the layers. This includes mouse events
7156
+ * and custom events.
7157
+ * * Has `layeradd` and `layerremove` events
7148
7158
  *
7149
7159
  * @example
7150
7160
  *
7151
7161
  * ```js
7152
7162
  * L.featureGroup([marker1, marker2, polyline])
7153
7163
  * .bindPopup('Hello world!')
7154
- * .on('click', function() { alert('Clicked on a group!'); })
7164
+ * .on('click', function() { alert('Clicked on a member of the group!'); })
7155
7165
  * .addTo(map);
7156
7166
  * ```
7157
7167
  */
@@ -7167,6 +7177,8 @@ L.FeatureGroup = L.LayerGroup.extend({
7167
7177
 
7168
7178
  L.LayerGroup.prototype.addLayer.call(this, layer);
7169
7179
 
7180
+ // @event layeradd: LayerEvent
7181
+ // Fired when a layer is added to this `FeatureGroup`
7170
7182
  return this.fire('layeradd', {layer: layer});
7171
7183
  },
7172
7184
 
@@ -7182,6 +7194,8 @@ L.FeatureGroup = L.LayerGroup.extend({
7182
7194
 
7183
7195
  L.LayerGroup.prototype.removeLayer.call(this, layer);
7184
7196
 
7197
+ // @event layerremove: LayerEvent
7198
+ // Fired when a layer is removed from this `FeatureGroup`
7185
7199
  return this.fire('layerremove', {layer: layer});
7186
7200
  },
7187
7201
 
@@ -7239,6 +7253,9 @@ L.featureGroup = function (layers) {
7239
7253
  *
7240
7254
  * Do not use this class directly, use `SVG` and `Canvas` instead.
7241
7255
  *
7256
+ * @event update: Event
7257
+ * Fired when the renderer updates its bounds, center and zoom, for example when
7258
+ * its map has moved
7242
7259
  */
7243
7260
 
7244
7261
  L.Renderer = L.Layer.extend({
@@ -7317,7 +7334,8 @@ L.Renderer = L.Layer.extend({
7317
7334
  },
7318
7335
 
7319
7336
  _update: function () {
7320
- // update pixel bounds of renderer container (for positioning/sizing/clipping later)
7337
+ // Update pixel bounds of renderer container (for positioning/sizing/clipping later)
7338
+ // Subclasses are responsible of firing the 'update' event.
7321
7339
  var p = this.options.padding,
7322
7340
  size = this._map.getSize(),
7323
7341
  min = this._map.containerPointToLayerPoint(size.multiplyBy(-p)).round();
@@ -7448,16 +7466,17 @@ L.Path = L.Layer.extend({
7448
7466
  this._renderer._initPath(this);
7449
7467
  this._reset();
7450
7468
  this._renderer._addPath(this);
7469
+ this._renderer.on('update', this._update, this);
7451
7470
  },
7452
7471
 
7453
7472
  onRemove: function () {
7454
7473
  this._renderer._removePath(this);
7474
+ this._renderer.off('update', this._update, this);
7455
7475
  },
7456
7476
 
7457
7477
  getEvents: function () {
7458
7478
  return {
7459
7479
  zoomend: this._project,
7460
- moveend: this._update,
7461
7480
  viewreset: this._reset
7462
7481
  };
7463
7482
  },
@@ -7855,6 +7874,11 @@ L.Polyline = L.Path.extend({
7855
7874
  // @method getCenter(): LatLng
7856
7875
  // Returns the center ([centroid](http://en.wikipedia.org/wiki/Centroid)) of the polyline.
7857
7876
  getCenter: function () {
7877
+ // throws error when not yet added to map as this center calculation requires projected coordinates
7878
+ if (!this._map) {
7879
+ throw new Error('Must add layer to map before using getCenter()');
7880
+ }
7881
+
7858
7882
  var i, halfDist, segDist, dist, p1, p2, ratio,
7859
7883
  points = this._rings[0],
7860
7884
  len = points.length;
@@ -8159,6 +8183,11 @@ L.Polygon = L.Polyline.extend({
8159
8183
  },
8160
8184
 
8161
8185
  getCenter: function () {
8186
+ // throws error when not yet added to map as this center calculation requires projected coordinates
8187
+ if (!this._map) {
8188
+ throw new Error('Must add layer to map before using getCenter()');
8189
+ }
8190
+
8162
8191
  var i, j, p1, p2, f, area, x, y, center,
8163
8192
  points = this._rings[0],
8164
8193
  len = points.length;
@@ -8535,7 +8564,7 @@ L.circle = function (latlng, options, legacyOptions) {
8535
8564
  *
8536
8565
  * ```js
8537
8566
  * var map = L.map('map', {
8538
- * renderer: L.svg();
8567
+ * renderer: L.svg()
8539
8568
  * });
8540
8569
  * ```
8541
8570
  *
@@ -8593,6 +8622,8 @@ L.SVG = L.Renderer.extend({
8593
8622
  // movement: update container viewBox so that we don't have to change coordinates of individual layers
8594
8623
  L.DomUtil.setPosition(container, b.min);
8595
8624
  container.setAttribute('viewBox', [b.min.x, b.min.y, size.x, size.y].join(' '));
8625
+
8626
+ this.fire('update');
8596
8627
  },
8597
8628
 
8598
8629
  // methods below are called by vector layers implementations
@@ -8923,7 +8954,7 @@ if (L.Browser.vml) {
8923
8954
  *
8924
8955
  * ```js
8925
8956
  * var map = L.map('map', {
8926
- * renderer: L.canvas();
8957
+ * renderer: L.canvas()
8927
8958
  * });
8928
8959
  * ```
8929
8960
  *
@@ -8986,6 +9017,9 @@ L.Canvas = L.Renderer.extend({
8986
9017
 
8987
9018
  // translate so we use the same path coordinates after canvas element moves
8988
9019
  this._ctx.translate(-b.min.x, -b.min.y);
9020
+
9021
+ // Tell paths to redraw themselves
9022
+ this.fire('update');
8989
9023
  },
8990
9024
 
8991
9025
  _initPath: function (layer) {
@@ -9291,7 +9325,7 @@ L.CircleMarker.prototype._containsPoint = function (p) {
9291
9325
  * @example
9292
9326
  *
9293
9327
  * ```js
9294
- * L.geoJson(data, {
9328
+ * L.geoJSON(data, {
9295
9329
  * style: function (feature) {
9296
9330
  * return {color: feature.properties.color};
9297
9331
  * }
@@ -12794,7 +12828,7 @@ L.Map.include(!zoomAnimated ? {} : {
12794
12828
  // @section Methods for modifying map state
12795
12829
  L.Map.include({
12796
12830
 
12797
- // @method flyTo(latlng: LatLng, zoom?: Number, options?: Zoom/Pan options): this
12831
+ // @method flyTo(latlng: LatLng, zoom?: Number, options?: Zoom/pan options): this
12798
12832
  // Sets the view of the map (geographical center and zoom) performing a smooth
12799
12833
  // pan-zoom animation.
12800
12834
  flyTo: function (targetCenter, targetZoom, options) {