leaflet-rails 1.0.2 → 1.0.3

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: e7af20726cf087075dc8c98f2fcdb828d11f7d56
4
- data.tar.gz: d18e1d715af0b4a073582736ac5443a0f0705e48
3
+ metadata.gz: bc0632e7cd8566f7fe86c3ac3f08ec67085cf609
4
+ data.tar.gz: 91b0d158c06340badf388a11745d4c0f00924672
5
5
  SHA512:
6
- metadata.gz: 95f5d7b0fd3523b677efffa888ee3b307488410e1966c92787c449e0f301d96e39f3da008bba6d1d9db270f65311e9c897d9ff4cb244e174662380cdca753863
7
- data.tar.gz: c97b6c2c3b0752f549a72fab30b5de7d515b0f4207028d738f3503175d463b82552ef6d6884698601a1ef40f4911348c18a79fa14858352592c5d70e3665081b
6
+ metadata.gz: bf8ec06aa08fb6086491c0bd9405e2063a42bfa3bc47e2e355e3efdf0984f1620bc3c855ef169de09e79bc9834e97bcc4dcf62dc7bdd423d22d70e9a0ff164c6
7
+ data.tar.gz: b2be300ad70bbd21d4bb8cb1e81f46254075b0f611ceee1b0fb9cf5b5ce3da6686707165056d9276b2a6aa82402e6ab04fb4a9bfa27f302833b0318b74f811f6
data/.travis.yml CHANGED
@@ -1,14 +1,20 @@
1
1
  sudo: false
2
2
  language: ruby
3
3
  cache: bundler
4
- rvm:
5
- - ruby-head
6
- - jruby-head
7
- - 2.0.0
8
- - 2.1.8
9
- - 2.2.4
10
- - 2.3.0
11
4
  matrix:
5
+ include:
6
+ - rvm: 2.0.0
7
+ gemfile: gemfiles/Gemfile.rails4
8
+ - rvm: 2.1.8
9
+ gemfile: gemfiles/Gemfile.rails4
10
+ - rvm: 2.2.4
11
+ gemfile: Gemfile
12
+ - rvm: 2.3.0
13
+ gemfile: Gemfile
14
+ - rvm: ruby-head
15
+ gemfile: Gemfile
16
+ - rvm: jruby-head
17
+ gemfile: Gemfile
12
18
  allow_failures:
13
19
  - rvm: ruby-head
14
20
  - rvm: jruby-head
@@ -0,0 +1,11 @@
1
+ source "http://rubygems.org"
2
+
3
+ #ruby=1.9.3-p374
4
+ #ruby-gemset=leaflet-rails
5
+
6
+ # Specify your gem's dependencies in leaflet-rails.gemspec
7
+ gemspec :path => '../'
8
+
9
+ gem "actionpack", '~> 4.2.0'
10
+ gem "activesupport", '~> 4.2.0'
11
+ gem "railties", '~> 4.2.0'
@@ -19,9 +19,7 @@ Gem::Specification.new do |s|
19
19
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
20
  s.require_paths = ["lib"]
21
21
 
22
+ s.add_dependency "rails", '>= 4.2.0'
22
23
  s.add_development_dependency "rspec", '<= 3.4.0'
23
24
  s.add_development_dependency "simplecov-rcov"
24
- s.add_development_dependency "actionpack", '>= 4.2.0'
25
- s.add_development_dependency "activesupport", '>= 4.2.0'
26
- s.add_development_dependency "railties", '>= 4.2.0'
27
25
  end
data/lib/leaflet-rails.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require "leaflet-rails/version"
2
2
  require "leaflet-rails/view_helpers"
3
+ require "rails"
3
4
 
4
5
  module Leaflet
5
6
  mattr_accessor :tile_layer
@@ -10,7 +11,9 @@ module Leaflet
10
11
  module Rails
11
12
  class Engine < ::Rails::Engine
12
13
  initializer 'leaflet-rails.precompile' do |app|
13
- app.config.assets.precompile += %w(layers-2x.png layers.png marker-icon-2x.png marker-icon.png marker-shadow.png)
14
+ if app.config.respond_to? (:assets)
15
+ app.config.assets.precompile += %w(layers-2x.png layers.png marker-icon-2x.png marker-icon.png marker-shadow.png)
16
+ end
14
17
  end
15
18
 
16
19
  initializer 'leaflet-rails.helpers' do
@@ -1,5 +1,5 @@
1
1
  module Leaflet
2
2
  module Rails
3
- VERSION = "1.0.2"
3
+ VERSION = "1.0.3"
4
4
  end
5
5
  end
@@ -1,10 +1,10 @@
1
1
  /*
2
- Leaflet 1.0.2, a JS library for interactive maps. http://leafletjs.com
2
+ Leaflet 1.0.3, a JS library for interactive maps. http://leafletjs.com
3
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.2"
7
+ version: "1.0.3"
8
8
  };
9
9
 
10
10
  function expose() {
@@ -516,7 +516,6 @@ L.Evented = L.Class.extend({
516
516
  }
517
517
 
518
518
  listeners.push(newListener);
519
- typeListeners.count++;
520
519
  },
521
520
 
522
521
  _off: function (type, fn, context) {
@@ -824,6 +823,9 @@ L.Mixin = {Events: proto};
824
823
 
825
824
  // @property touch: Boolean
826
825
  // `true` for all browsers supporting [touch events](https://developer.mozilla.org/docs/Web/API/Touch_events).
826
+ // This does not necessarily mean that the browser is running in a computer with
827
+ // a touchscreen, it only means that the browser is capable of understanding
828
+ // touch events.
827
829
  touch: !!touch,
828
830
 
829
831
  // @property msPointer: Boolean
@@ -1662,7 +1664,7 @@ L.LatLng.prototype = {
1662
1664
  },
1663
1665
 
1664
1666
  // @method toBounds(sizeInMeters: Number): LatLngBounds
1665
- // Returns a new `LatLngBounds` object in which each boundary is `sizeInMeters` meters apart from the `LatLng`.
1667
+ // Returns a new `LatLngBounds` object in which each boundary is `sizeInMeters/2` meters apart from the `LatLng`.
1666
1668
  toBounds: function (sizeInMeters) {
1667
1669
  var latAccuracy = 180 * sizeInMeters / 40075017,
1668
1670
  lngAccuracy = latAccuracy / Math.cos((Math.PI / 180) * this.lat);
@@ -1869,7 +1871,7 @@ L.LatLngBounds.prototype = {
1869
1871
  // @method contains (latlng: LatLng): Boolean
1870
1872
  // Returns `true` if the rectangle contains the given point.
1871
1873
  contains: function (obj) { // (LatLngBounds) or (LatLng) -> Boolean
1872
- if (typeof obj[0] === 'number' || obj instanceof L.LatLng) {
1874
+ if (typeof obj[0] === 'number' || obj instanceof L.LatLng || 'lat' in obj) {
1873
1875
  obj = L.latLng(obj);
1874
1876
  } else {
1875
1877
  obj = L.latLngBounds(obj);
@@ -2132,12 +2134,35 @@ L.CRS = {
2132
2134
  // @method wrapLatLng(latlng: LatLng): LatLng
2133
2135
  // Returns a `LatLng` where lat and lng has been wrapped according to the
2134
2136
  // CRS's `wrapLat` and `wrapLng` properties, if they are outside the CRS's bounds.
2137
+ // Only accepts actual `L.LatLng` instances, not arrays.
2135
2138
  wrapLatLng: function (latlng) {
2136
2139
  var lng = this.wrapLng ? L.Util.wrapNum(latlng.lng, this.wrapLng, true) : latlng.lng,
2137
2140
  lat = this.wrapLat ? L.Util.wrapNum(latlng.lat, this.wrapLat, true) : latlng.lat,
2138
2141
  alt = latlng.alt;
2139
2142
 
2140
2143
  return L.latLng(lat, lng, alt);
2144
+ },
2145
+
2146
+ // @method wrapLatLngBounds(bounds: LatLngBounds): LatLngBounds
2147
+ // Returns a `LatLngBounds` with the same size as the given one, ensuring
2148
+ // that its center is within the CRS's bounds.
2149
+ // Only accepts actual `L.LatLngBounds` instances, not arrays.
2150
+ wrapLatLngBounds: function (bounds) {
2151
+ var center = bounds.getCenter(),
2152
+ newCenter = this.wrapLatLng(center),
2153
+ latShift = center.lat - newCenter.lat,
2154
+ lngShift = center.lng - newCenter.lng;
2155
+
2156
+ if (latShift === 0 && lngShift === 0) {
2157
+ return bounds;
2158
+ }
2159
+
2160
+ var sw = bounds.getSouthWest(),
2161
+ ne = bounds.getNorthEast(),
2162
+ newSw = L.latLng({lat: sw.lat - latShift, lng: sw.lng - lngShift}),
2163
+ newNe = L.latLng({lat: ne.lat - latShift, lng: ne.lng - lngShift});
2164
+
2165
+ return new L.LatLngBounds(newSw, newNe);
2141
2166
  }
2142
2167
  };
2143
2168
 
@@ -2305,7 +2330,7 @@ L.Map = L.Evented.extend({
2305
2330
 
2306
2331
  // @option maxBounds: LatLngBounds = null
2307
2332
  // When this option is set, the map restricts the view to the given
2308
- // geographical bounds, bouncing the user back when he tries to pan
2333
+ // geographical bounds, bouncing the user back if the user tries to pan
2309
2334
  // outside the view. To set the restriction dynamically, use
2310
2335
  // [`setMaxBounds`](#map-setmaxbounds) method.
2311
2336
  maxBounds: undefined,
@@ -2512,7 +2537,7 @@ L.Map = L.Evented.extend({
2512
2537
  };
2513
2538
  },
2514
2539
 
2515
- // @method fitBounds(bounds: LatLngBounds, options: fitBounds options): this
2540
+ // @method fitBounds(bounds: LatLngBounds, options?: fitBounds options): this
2516
2541
  // Sets a map view that contains the given geographical bounds with the
2517
2542
  // maximum zoom level possible.
2518
2543
  fitBounds: function (bounds, options) {
@@ -3041,7 +3066,7 @@ L.Map = L.Evented.extend({
3041
3066
  nw = bounds.getNorthWest(),
3042
3067
  se = bounds.getSouthEast(),
3043
3068
  size = this.getSize().subtract(padding),
3044
- boundsSize = this.project(se, zoom).subtract(this.project(nw, zoom)),
3069
+ boundsSize = L.bounds(this.project(se, zoom), this.project(nw, zoom)).getSize(),
3045
3070
  snap = L.Browser.any3d ? this.options.zoomSnap : 1;
3046
3071
 
3047
3072
  var scale = Math.min(size.x / boundsSize.x, size.y / boundsSize.y);
@@ -3060,8 +3085,8 @@ L.Map = L.Evented.extend({
3060
3085
  getSize: function () {
3061
3086
  if (!this._size || this._sizeChanged) {
3062
3087
  this._size = new L.Point(
3063
- this._container.clientWidth,
3064
- this._container.clientHeight);
3088
+ this._container.clientWidth || 0,
3089
+ this._container.clientHeight || 0);
3065
3090
 
3066
3091
  this._sizeChanged = false;
3067
3092
  }
@@ -3182,6 +3207,16 @@ L.Map = L.Evented.extend({
3182
3207
  return this.options.crs.wrapLatLng(L.latLng(latlng));
3183
3208
  },
3184
3209
 
3210
+ // @method wrapLatLngBounds(bounds: LatLngBounds): LatLngBounds
3211
+ // Returns a `LatLngBounds` with the same size as the given one, ensuring that
3212
+ // its center is within the CRS's bounds.
3213
+ // By default this means the center longitude is wrapped around the dateline so its
3214
+ // value is between -180 and +180 degrees, and the majority of the bounds
3215
+ // overlaps the CRS's bounds.
3216
+ wrapLatLngBounds: function (latlng) {
3217
+ return this.options.crs.wrapLatLngBounds(L.latLngBounds(latlng));
3218
+ },
3219
+
3185
3220
  // @method distance(latlng1: LatLng, latlng2: LatLng): Number
3186
3221
  // Returns the distance between two geographical coordinates according to
3187
3222
  // the map's CRS. By default this measures distance in meters.
@@ -3203,7 +3238,7 @@ L.Map = L.Evented.extend({
3203
3238
  return L.point(point).add(this._getMapPanePos());
3204
3239
  },
3205
3240
 
3206
- // @method containerPointToLatLng(point: Point): Point
3241
+ // @method containerPointToLatLng(point: Point): LatLng
3207
3242
  // Given a pixel coordinate relative to the map container, returns
3208
3243
  // the corresponding geographical coordinate (for the current zoom level).
3209
3244
  containerPointToLatLng: function (point) {
@@ -3889,7 +3924,7 @@ L.Layer = L.Evented.extend({
3889
3924
 
3890
3925
  // @option attribution: String = null
3891
3926
  // String to be shown in the attribution control, describes the layer data, e.g. "© Mapbox".
3892
- attribution: null,
3927
+ attribution: null
3893
3928
  },
3894
3929
 
3895
3930
  /* @section
@@ -3959,8 +3994,8 @@ L.Layer = L.Evented.extend({
3959
3994
 
3960
3995
  this.onAdd(map);
3961
3996
 
3962
- if (this.getAttribution && this._map.attributionControl) {
3963
- this._map.attributionControl.addAttribution(this.getAttribution());
3997
+ if (this.getAttribution && map.attributionControl) {
3998
+ map.attributionControl.addAttribution(this.getAttribution());
3964
3999
  }
3965
4000
 
3966
4001
  this.fire('add');
@@ -4205,7 +4240,10 @@ L.DomEvent = {
4205
4240
  if (L.Browser.pointer && type.indexOf('touch') === 0) {
4206
4241
  this.addPointerListener(obj, type, handler, id);
4207
4242
 
4208
- } else if (L.Browser.touch && (type === 'dblclick') && this.addDoubleTapListener) {
4243
+ } else if (L.Browser.touch && (type === 'dblclick') && this.addDoubleTapListener &&
4244
+ !(L.Browser.pointer && L.Browser.chrome)) {
4245
+ // Chrome >55 does not need the synthetic dblclicks from addDoubleTapListener
4246
+ // See #5180
4209
4247
  this.addDoubleTapListener(obj, handler, id);
4210
4248
 
4211
4249
  } else if ('addEventListener' in obj) {
@@ -4712,7 +4750,9 @@ L.GridLayer = L.Layer.extend({
4712
4750
  // @option noWrap: Boolean = false
4713
4751
  // Whether the layer is wrapped around the antimeridian. If `true`, the
4714
4752
  // GridLayer will only be displayed once at low zoom levels. Has no
4715
- // effect when the [map CRS](#map-crs) doesn't wrap around.
4753
+ // effect when the [map CRS](#map-crs) doesn't wrap around. Can be used
4754
+ // in combination with [`bounds`](#gridlayer-bounds) to prevent requesting
4755
+ // tiles outside the CRS limits.
4716
4756
  noWrap: false,
4717
4757
 
4718
4758
  // @option pane: String = 'tilePane'
@@ -5283,14 +5323,14 @@ L.GridLayer = L.Layer.extend({
5283
5323
  sePoint = nwPoint.add(tileSize),
5284
5324
 
5285
5325
  nw = map.unproject(nwPoint, coords.z),
5286
- se = map.unproject(sePoint, coords.z);
5326
+ se = map.unproject(sePoint, coords.z),
5327
+ bounds = new L.LatLngBounds(nw, se);
5287
5328
 
5288
5329
  if (!this.options.noWrap) {
5289
- nw = map.wrapLatLng(nw);
5290
- se = map.wrapLatLng(se);
5330
+ map.wrapLatLngBounds(bounds);
5291
5331
  }
5292
5332
 
5293
- return new L.LatLngBounds(nw, se);
5333
+ return bounds;
5294
5334
  },
5295
5335
 
5296
5336
  // converts tile coordinates to key for the tile cache
@@ -5476,7 +5516,7 @@ L.gridLayer = function (options) {
5476
5516
  * @example
5477
5517
  *
5478
5518
  * ```js
5479
- * L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png?{foo}', {foo: 'bar'}).addTo(map);
5519
+ * L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png?{foo}', {foo: 'bar'}).addTo(map);
5480
5520
  * ```
5481
5521
  *
5482
5522
  * @section URL template
@@ -5662,7 +5702,7 @@ L.TileLayer = L.GridLayer.extend({
5662
5702
 
5663
5703
  _tileOnError: function (done, tile, e) {
5664
5704
  var errorUrl = this.options.errorTileUrl;
5665
- if (errorUrl) {
5705
+ if (errorUrl && tile.src !== errorUrl) {
5666
5706
  tile.src = errorUrl;
5667
5707
  }
5668
5708
  done(e, tile);
@@ -6000,6 +6040,8 @@ L.ImageOverlay = L.Layer.extend({
6000
6040
  return this;
6001
6041
  },
6002
6042
 
6043
+ // @method setBounds(bounds: LatLngBounds): this
6044
+ // Update the bounds that this ImageOverlay covers
6003
6045
  setBounds: function (bounds) {
6004
6046
  this._bounds = bounds;
6005
6047
 
@@ -6022,10 +6064,14 @@ L.ImageOverlay = L.Layer.extend({
6022
6064
  return events;
6023
6065
  },
6024
6066
 
6067
+ // @method getBounds(): LatLngBounds
6068
+ // Get the bounds that this ImageOverlay covers
6025
6069
  getBounds: function () {
6026
6070
  return this._bounds;
6027
6071
  },
6028
6072
 
6073
+ // @method getElement(): HTMLElement
6074
+ // Get the img element that represents the ImageOverlay on the map
6029
6075
  getElement: function () {
6030
6076
  return this._image;
6031
6077
  },
@@ -6493,6 +6539,7 @@ L.Marker = L.Layer.extend({
6493
6539
 
6494
6540
  if (newShadow) {
6495
6541
  L.DomUtil.addClass(newShadow, classToAdd);
6542
+ newShadow.alt = '';
6496
6543
  }
6497
6544
  this._shadow = newShadow;
6498
6545
 
@@ -7348,7 +7395,7 @@ L.Layer.include({
7348
7395
  // @method isPopupOpen(): boolean
7349
7396
  // Returns `true` if the popup bound to this layer is currently open.
7350
7397
  isPopupOpen: function () {
7351
- return this._popup.isOpen();
7398
+ return (this._popup ? this._popup.isOpen() : false);
7352
7399
  },
7353
7400
 
7354
7401
  // @method setPopupContent(content: String|HTMLElement|Popup): this
@@ -8622,9 +8669,9 @@ L.LineUtil = {
8622
8669
  * ```js
8623
8670
  * // create a red polyline from an array of LatLng points
8624
8671
  * var latlngs = [
8625
- * [-122.68, 45.51],
8626
- * [-122.43, 37.77],
8627
- * [-118.2, 34.04]
8672
+ * [45.51, -122.68],
8673
+ * [37.77, -122.43],
8674
+ * [34.04, -118.2]
8628
8675
  * ];
8629
8676
  *
8630
8677
  * var polyline = L.polyline(latlngs, {color: 'red'}).addTo(map);
@@ -8638,12 +8685,12 @@ L.LineUtil = {
8638
8685
  * ```js
8639
8686
  * // create a red polyline from an array of arrays of LatLng points
8640
8687
  * var latlngs = [
8641
- * [[-122.68, 45.51],
8642
- * [-122.43, 37.77],
8643
- * [-118.2, 34.04]],
8644
- * [[-73.91, 40.78],
8645
- * [-87.62, 41.83],
8646
- * [-96.72, 32.76]]
8688
+ * [[45.51, -122.68],
8689
+ * [37.77, -122.43],
8690
+ * [34.04, -118.2]],
8691
+ * [[40.78, -73.91],
8692
+ * [41.83, -87.62],
8693
+ * [32.76, -96.72]]
8647
8694
  * ];
8648
8695
  * ```
8649
8696
  */
@@ -8983,7 +9030,7 @@ L.PolyUtil.clipPolygon = function (points, bounds, round) {
8983
9030
  *
8984
9031
  * ```js
8985
9032
  * // create a red polygon from an array of LatLng points
8986
- * var latlngs = [[-111.03, 41],[-111.04, 45],[-104.05, 45],[-104.05, 41]];
9033
+ * var latlngs = [[37, -109.05],[41, -109.03],[41, -102.05],[37, -102.04]];
8987
9034
  *
8988
9035
  * var polygon = L.polygon(latlngs, {color: 'red'}).addTo(map);
8989
9036
  *
@@ -8995,8 +9042,8 @@ L.PolyUtil.clipPolygon = function (points, bounds, round) {
8995
9042
  *
8996
9043
  * ```js
8997
9044
  * var latlngs = [
8998
- * [[-111.03, 41],[-111.04, 45],[-104.05, 45],[-104.05, 41]], // outer ring
8999
- * [[-108.58,37.29],[-108.58,40.71],[-102.50,40.71],[-102.50,37.29]] // hole
9045
+ * [[37, -109.05],[41, -109.03],[41, -102.05],[37, -102.04]], // outer ring
9046
+ * [[37.29, -108.58],[40.71, -108.58],[40.71, -102.50],[37.29, -102.50]] // hole
9000
9047
  * ];
9001
9048
  * ```
9002
9049
  *
@@ -9005,11 +9052,11 @@ L.PolyUtil.clipPolygon = function (points, bounds, round) {
9005
9052
  * ```js
9006
9053
  * var latlngs = [
9007
9054
  * [ // first polygon
9008
- * [[-111.03, 41],[-111.04, 45],[-104.05, 45],[-104.05, 41]], // outer ring
9009
- * [[-108.58,37.29],[-108.58,40.71],[-102.50,40.71],[-102.50,37.29]] // hole
9055
+ * [[37, -109.05],[41, -109.03],[41, -102.05],[37, -102.04]], // outer ring
9056
+ * [[37.29, -108.58],[40.71, -108.58],[40.71, -102.50],[37.29, -102.50]] // hole
9010
9057
  * ],
9011
9058
  * [ // second polygon
9012
- * [[-109.05, 37],[-109.03, 41],[-102.05, 41],[-102.04, 37],[-109.05, 38]]
9059
+ * [[41, -111.03],[45, -111.04],[45, -104.05],[41, -104.05]]
9013
9060
  * ]
9014
9061
  * ];
9015
9062
  * ```
@@ -9679,6 +9726,7 @@ L.SVG.include(!L.Browser.vml ? {} : {
9679
9726
  container.appendChild(layer._path);
9680
9727
 
9681
9728
  this._updateStyle(layer);
9729
+ this._layers[L.stamp(layer)] = layer;
9682
9730
  },
9683
9731
 
9684
9732
  _addPath: function (layer) {
@@ -9694,6 +9742,7 @@ L.SVG.include(!L.Browser.vml ? {} : {
9694
9742
  var container = layer._container;
9695
9743
  L.DomUtil.remove(container);
9696
9744
  layer.removeInteractiveTarget(container);
9745
+ delete this._layers[L.stamp(layer)];
9697
9746
  },
9698
9747
 
9699
9748
  _updateStyle: function (layer) {
@@ -9815,6 +9864,16 @@ if (L.Browser.vml) {
9815
9864
  */
9816
9865
 
9817
9866
  L.Canvas = L.Renderer.extend({
9867
+ getEvents: function () {
9868
+ var events = L.Renderer.prototype.getEvents.call(this);
9869
+ events.viewprereset = this._onViewPreReset;
9870
+ return events;
9871
+ },
9872
+
9873
+ _onViewPreReset: function () {
9874
+ // Set a flag so that a viewprereset+moveend+viewreset only updates&redraws once
9875
+ this._postponeUpdatePaths = true;
9876
+ },
9818
9877
 
9819
9878
  onAdd: function () {
9820
9879
  L.Renderer.prototype.onAdd.call(this);
@@ -9836,6 +9895,8 @@ L.Canvas = L.Renderer.extend({
9836
9895
  },
9837
9896
 
9838
9897
  _updatePaths: function () {
9898
+ if (this._postponeUpdatePaths) { return; }
9899
+
9839
9900
  var layer;
9840
9901
  this._redrawBounds = null;
9841
9902
  for (var id in this._layers) {
@@ -9876,6 +9937,15 @@ L.Canvas = L.Renderer.extend({
9876
9937
  this.fire('update');
9877
9938
  },
9878
9939
 
9940
+ _reset: function () {
9941
+ L.Renderer.prototype._reset.call(this);
9942
+
9943
+ if (this._postponeUpdatePaths) {
9944
+ this._postponeUpdatePaths = false;
9945
+ this._updatePaths();
9946
+ }
9947
+ },
9948
+
9879
9949
  _initPath: function (layer) {
9880
9950
  this._updateDashArray(layer);
9881
9951
  this._layers[L.stamp(layer)] = layer;
@@ -9962,6 +10032,11 @@ L.Canvas = L.Renderer.extend({
9962
10032
  _redraw: function () {
9963
10033
  this._redrawRequest = null;
9964
10034
 
10035
+ if (this._redrawBounds) {
10036
+ this._redrawBounds.min._floor();
10037
+ this._redrawBounds.max._ceil();
10038
+ }
10039
+
9965
10040
  this._clear(); // clear layers in redraw bounds
9966
10041
  this._draw(); // draw layers
9967
10042
 
@@ -11325,6 +11400,7 @@ L.extend(L.DomEvent, {
11325
11400
  var count;
11326
11401
 
11327
11402
  if (L.Browser.pointer) {
11403
+ if ((!L.Browser.edge) || e.pointerType === 'mouse') { return; }
11328
11404
  count = L.DomEvent._pointersCount;
11329
11405
  } else {
11330
11406
  count = e.touches.length;
@@ -11340,9 +11416,11 @@ L.extend(L.DomEvent, {
11340
11416
  last = now;
11341
11417
  }
11342
11418
 
11343
- function onTouchEnd() {
11419
+ function onTouchEnd(e) {
11344
11420
  if (doubleTap && !touch.cancelBubble) {
11345
11421
  if (L.Browser.pointer) {
11422
+ if ((!L.Browser.edge) || e.pointerType === 'mouse') { return; }
11423
+
11346
11424
  // work around .type being readonly with MSPointer* events
11347
11425
  var newTouch = {},
11348
11426
  prop, i;
@@ -11370,12 +11448,11 @@ L.extend(L.DomEvent, {
11370
11448
  obj.addEventListener(touchstart, onTouchStart, false);
11371
11449
  obj.addEventListener(touchend, onTouchEnd, false);
11372
11450
 
11373
- // On some platforms (notably, chrome on win10 + touchscreen + mouse),
11451
+ // On some platforms (notably, chrome<55 on win10 + touchscreen + mouse),
11374
11452
  // the browser doesn't fire touchend/pointerup events but does fire
11375
11453
  // native dblclicks. See #4127.
11376
- if (!L.Browser.edge) {
11377
- obj.addEventListener('dblclick', handler, false);
11378
- }
11454
+ // Edge 14 also fires native dblclicks, but only for pointerType mouse, see #5180.
11455
+ obj.addEventListener('dblclick', handler, false);
11379
11456
 
11380
11457
  return this;
11381
11458
  },
@@ -11450,7 +11527,7 @@ L.extend(L.DomEvent, {
11450
11527
 
11451
11528
  _addPointerStart: function (obj, handler, id) {
11452
11529
  var onDown = L.bind(function (e) {
11453
- if (e.pointerType !== 'mouse' && e.pointerType !== e.MSPOINTER_TYPE_MOUSE) {
11530
+ if (e.pointerType !== 'mouse' && e.MSPOINTER_TYPE_MOUSE && e.pointerType !== e.MSPOINTER_TYPE_MOUSE) {
11454
11531
  // In IE11, some touch events needs to fire for form controls, or
11455
11532
  // the controls will stop working. We keep a whitelist of tag names that
11456
11533
  // need these events. For other target tags, we prevent default on the event.
@@ -12916,7 +12993,8 @@ L.Control.Layers = L.Control.extend({
12916
12993
 
12917
12994
  _initLayout: function () {
12918
12995
  var className = 'leaflet-control-layers',
12919
- container = this._container = L.DomUtil.create('div', className);
12996
+ container = this._container = L.DomUtil.create('div', className),
12997
+ collapsed = this.options.collapsed;
12920
12998
 
12921
12999
  // makes this work on IE touch devices by stopping it from firing a mouseout event when the touch is released
12922
13000
  container.setAttribute('aria-haspopup', true);
@@ -12928,11 +13006,15 @@ L.Control.Layers = L.Control.extend({
12928
13006
 
12929
13007
  var form = this._form = L.DomUtil.create('form', className + '-list');
12930
13008
 
12931
- if (!L.Browser.android) {
12932
- L.DomEvent.on(container, {
12933
- mouseenter: this.expand,
12934
- mouseleave: this.collapse
12935
- }, this);
13009
+ if (collapsed) {
13010
+ this._map.on('click', this.collapse, this);
13011
+
13012
+ if (!L.Browser.android) {
13013
+ L.DomEvent.on(container, {
13014
+ mouseenter: this.expand,
13015
+ mouseleave: this.collapse
13016
+ }, this);
13017
+ }
12936
13018
  }
12937
13019
 
12938
13020
  var link = this._layersLink = L.DomUtil.create('a', className + '-toggle', container);
@@ -12952,10 +13034,9 @@ L.Control.Layers = L.Control.extend({
12952
13034
  setTimeout(L.bind(this._onInputClick, this), 0);
12953
13035
  }, this);
12954
13036
 
12955
- this._map.on('click', this.collapse, this);
12956
13037
  // TODO keyboard accessibility
12957
13038
 
12958
- if (!this.options.collapsed) {
13039
+ if (!collapsed) {
12959
13040
  this.expand();
12960
13041
  }
12961
13042