leaflet-rails 1.0.0.pre.rc3 → 1.0.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.
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) {