leaflet-js 0.6.beta4 → 0.7.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.
Files changed (226) hide show
  1. checksums.yaml +6 -14
  2. data/CHANGELOG.rdoc +3 -0
  3. data/leaflet-js.gemspec +2 -2
  4. data/lib/leaflet.draw/CHANGELOG.md +45 -0
  5. data/lib/leaflet.draw/README.md +70 -23
  6. data/lib/leaflet.draw/build/deps.js +1 -0
  7. data/lib/leaflet.draw/dist/images/spritesheet-2x.png +0 -0
  8. data/lib/leaflet.draw/dist/images/spritesheet.png +0 -0
  9. data/lib/leaflet.draw/dist/leaflet.draw-src.js +489 -136
  10. data/lib/leaflet.draw/dist/leaflet.draw.css +34 -2
  11. data/lib/leaflet.draw/dist/leaflet.draw.ie.css +5 -0
  12. data/lib/leaflet.draw/dist/leaflet.draw.js +2 -2
  13. data/lib/leaflet.draw/examples/basic.html +14 -7
  14. data/lib/leaflet.draw/examples/libs/images/layers-2x.png +0 -0
  15. data/lib/leaflet.draw/examples/libs/images/layers.png +0 -0
  16. data/lib/leaflet.draw/examples/libs/images/marker-icon-2x.png +0 -0
  17. data/lib/leaflet.draw/examples/libs/leaflet-src.js +1129 -608
  18. data/lib/leaflet.draw/examples/libs/leaflet.css +85 -66
  19. data/lib/leaflet.draw/package.json +2 -2
  20. data/lib/leaflet.draw/spec/suites/DrawControlSpec.js +1 -1
  21. data/lib/leaflet.draw/spec/suites/GeometryUtilSpec.js +25 -0
  22. data/lib/leaflet.draw/spec/suites/LatLngUtilSpec.js +9 -0
  23. data/lib/leaflet.draw/src/Control.Draw.js +1 -0
  24. data/lib/leaflet.draw/src/Leaflet.draw.js +89 -1
  25. data/lib/leaflet.draw/src/Toolbar.js +2 -6
  26. data/lib/leaflet.draw/src/Tooltip.js +20 -7
  27. data/lib/leaflet.draw/src/draw/DrawToolbar.js +26 -22
  28. data/lib/leaflet.draw/src/draw/handler/Draw.Circle.js +11 -6
  29. data/lib/leaflet.draw/src/draw/handler/Draw.Feature.js +6 -2
  30. data/lib/leaflet.draw/src/draw/handler/Draw.Marker.js +7 -2
  31. data/lib/leaflet.draw/src/draw/handler/Draw.Polygon.js +29 -7
  32. data/lib/leaflet.draw/src/draw/handler/Draw.Polyline.js +44 -21
  33. data/lib/leaflet.draw/src/draw/handler/Draw.Rectangle.js +3 -3
  34. data/lib/leaflet.draw/src/draw/handler/Draw.SimpleShape.js +14 -1
  35. data/lib/leaflet.draw/src/edit/EditToolbar.js +86 -16
  36. data/lib/leaflet.draw/src/edit/handler/Edit.Poly.js +10 -7
  37. data/lib/leaflet.draw/src/edit/handler/Edit.SimpleShape.js +1 -2
  38. data/lib/leaflet.draw/src/edit/handler/EditToolbar.Delete.js +15 -3
  39. data/lib/leaflet.draw/src/edit/handler/EditToolbar.Edit.js +56 -38
  40. data/lib/leaflet.draw/src/ext/GeometryUtil.js +68 -0
  41. data/lib/leaflet.draw/src/images/spritesheet.svg +41 -0
  42. data/lib/leaflet.label/CHANGELOG.md +32 -0
  43. data/lib/leaflet.label/README.md +21 -4
  44. data/lib/leaflet.label/build/build.js +2 -2
  45. data/lib/leaflet.label/build/deps.js +2 -0
  46. data/lib/leaflet.label/build/hintrc.js +4 -0
  47. data/lib/leaflet.label/dist/leaflet.label-src.js +266 -83
  48. data/lib/leaflet.label/dist/leaflet.label.css +23 -4
  49. data/lib/leaflet.label/dist/leaflet.label.js +1 -1
  50. data/lib/leaflet.label/example/label.html +6 -3
  51. data/lib/leaflet.label/libs/leaflet/images/layers-2x.png +0 -0
  52. data/lib/leaflet.label/libs/leaflet/images/layers.png +0 -0
  53. data/lib/leaflet.label/libs/leaflet/images/marker-icon-2x.png +0 -0
  54. data/lib/leaflet.label/libs/leaflet/leaflet-src.js +1129 -608
  55. data/lib/leaflet.label/libs/leaflet/leaflet.css +85 -66
  56. data/lib/leaflet.label/libs/leaflet/leaflet.js +6 -5
  57. data/lib/leaflet.label/package.json +19 -0
  58. data/lib/leaflet.label/src/BaseMarkerMethods.js +129 -0
  59. data/lib/leaflet.label/src/CircleMarker.Label.js +7 -0
  60. data/lib/leaflet.label/src/Label.js +161 -37
  61. data/lib/leaflet.label/src/Leaflet.label.js +1 -1
  62. data/lib/leaflet.label/src/Map.Label.js +0 -2
  63. data/lib/leaflet.label/src/Marker.Label.js +15 -120
  64. data/lib/leaflet.label/src/Path.Label.js +11 -11
  65. data/lib/leaflet/CHANGELOG.md +299 -31
  66. data/lib/leaflet/CONTRIBUTING.md +3 -3
  67. data/lib/leaflet/FAQ.md +138 -0
  68. data/lib/leaflet/Jakefile.js +24 -4
  69. data/lib/leaflet/PLUGIN-GUIDE.md +127 -0
  70. data/lib/leaflet/README.md +10 -6
  71. data/lib/leaflet/build/build.html +3 -19
  72. data/lib/leaflet/build/build.js +21 -51
  73. data/lib/leaflet/build/deps.js +10 -7
  74. data/lib/leaflet/build/hintrc.js +6 -4
  75. data/lib/leaflet/debug/hacks/jitter.html +0 -1
  76. data/lib/leaflet/debug/map/canvas.html +11 -12
  77. data/lib/leaflet/debug/map/controls.html +3 -4
  78. data/lib/leaflet/debug/map/geolocation.html +0 -1
  79. data/lib/leaflet/debug/map/iframe.html +11 -0
  80. data/lib/leaflet/debug/map/image-overlay.html +0 -1
  81. data/lib/leaflet/debug/map/map-mobile.html +0 -1
  82. data/lib/leaflet/debug/map/map.html +1 -2
  83. data/lib/leaflet/debug/map/max-bounds.html +2 -1
  84. data/lib/leaflet/debug/map/opacity.html +223 -0
  85. data/lib/leaflet/debug/map/scroll.html +6 -1
  86. data/lib/leaflet/debug/map/simple-proj.html +0 -1
  87. data/lib/leaflet/debug/map/wms-marble.html +4 -5
  88. data/lib/leaflet/debug/map/wms.html +0 -1
  89. data/lib/leaflet/debug/map/zoomlevels.html +0 -1
  90. data/lib/leaflet/debug/tests/add_remove_layers.html +5 -6
  91. data/lib/leaflet/debug/tests/bringtoback.html +0 -1
  92. data/lib/leaflet/debug/tests/canvasloop.html +47 -0
  93. data/lib/leaflet/debug/tests/click_on_canvas.html +0 -1
  94. data/lib/leaflet/debug/tests/dragging_and_copyworldjump.html +61 -0
  95. data/lib/leaflet/debug/tests/opacity.html +0 -1
  96. data/lib/leaflet/debug/tests/popupcontextmenuclicks.html +59 -0
  97. data/lib/leaflet/debug/tests/remove_while_dragging.html +4 -5
  98. data/lib/leaflet/debug/tests/removetilewhilepan.html +0 -1
  99. data/lib/leaflet/debug/tests/reuse_popups.html +0 -1
  100. data/lib/leaflet/debug/tests/rtl.html +42 -0
  101. data/lib/leaflet/debug/tests/rtl2.html +27 -0
  102. data/lib/leaflet/debug/tests/set_icon_reuse_dom.html +43 -0
  103. data/lib/leaflet/debug/tests/svg_clicks.html +3 -4
  104. data/lib/leaflet/debug/vector/bounds-extend.html +0 -1
  105. data/lib/leaflet/debug/vector/feature-group-bounds.html +0 -1
  106. data/lib/leaflet/debug/vector/geojson.html +0 -1
  107. data/lib/leaflet/debug/vector/rectangle.html +0 -1
  108. data/lib/leaflet/debug/vector/touchzoomemu.html +2 -3
  109. data/lib/leaflet/debug/vector/vector-bounds.html +0 -1
  110. data/lib/leaflet/debug/vector/vector-canvas.html +0 -1
  111. data/lib/leaflet/debug/vector/vector-mobile.html +0 -1
  112. data/lib/leaflet/debug/vector/vector-simple.html +0 -1
  113. data/lib/leaflet/debug/vector/vector.html +0 -1
  114. data/lib/leaflet/dist/images/layers-2x.png +0 -0
  115. data/lib/leaflet/dist/images/layers.png +0 -0
  116. data/lib/leaflet/dist/leaflet.css +85 -66
  117. data/lib/leaflet/package.json +25 -20
  118. data/lib/leaflet/spec/after.js +1 -1
  119. data/lib/leaflet/spec/index.html +21 -13
  120. data/lib/leaflet/spec/karma.conf.js +51 -50
  121. data/lib/leaflet/spec/spec.hintrc.js +25 -0
  122. data/lib/leaflet/spec/suites/LeafletSpec.js +2 -2
  123. data/lib/leaflet/spec/suites/SpecHelper.js +37 -21
  124. data/lib/leaflet/spec/suites/control/Control.LayersSpec.js +1 -1
  125. data/lib/leaflet/spec/suites/core/ClassSpec.js +12 -12
  126. data/lib/leaflet/spec/suites/core/EventsSpec.js +74 -18
  127. data/lib/leaflet/spec/suites/core/UtilSpec.js +69 -25
  128. data/lib/leaflet/spec/suites/dom/DomEventSpec.js +16 -16
  129. data/lib/leaflet/spec/suites/dom/DomUtilSpec.js +9 -16
  130. data/lib/leaflet/spec/suites/dom/PosAnimationSpec.js +27 -0
  131. data/lib/leaflet/spec/suites/geo/CRSSpec.js +47 -0
  132. data/lib/leaflet/spec/suites/geo/LatLngBoundsSpec.js +22 -14
  133. data/lib/leaflet/spec/suites/geo/LatLngSpec.js +22 -8
  134. data/lib/leaflet/spec/suites/geo/ProjectionSpec.js +21 -20
  135. data/lib/leaflet/spec/suites/geometry/BoundsSpec.js +15 -15
  136. data/lib/leaflet/spec/suites/geometry/PointSpec.js +12 -12
  137. data/lib/leaflet/spec/suites/geometry/TransformationSpec.js +4 -4
  138. data/lib/leaflet/spec/suites/layer/FeatureGroupSpec.js +59 -9
  139. data/lib/leaflet/spec/suites/layer/GeoJSONSpec.js +213 -17
  140. data/lib/leaflet/spec/suites/layer/LayerGroupSpec.js +6 -6
  141. data/lib/leaflet/spec/suites/layer/PopupSpec.js +65 -5
  142. data/lib/leaflet/spec/suites/layer/TileLayerSpec.js +16 -15
  143. data/lib/leaflet/spec/suites/layer/marker/MarkerSpec.js +94 -0
  144. data/lib/leaflet/spec/suites/layer/vector/CircleMarkerSpec.js +7 -7
  145. data/lib/leaflet/spec/suites/layer/vector/PolygonSpec.js +38 -2
  146. data/lib/leaflet/spec/suites/layer/vector/PolylineGeometrySpec.js +4 -4
  147. data/lib/leaflet/spec/suites/layer/vector/PolylineSpec.js +2 -2
  148. data/lib/leaflet/spec/suites/map/MapSpec.js +318 -26
  149. data/lib/leaflet/spec/suites/map/handler/Map.DragSpec.js +38 -0
  150. data/lib/leaflet/src/Leaflet.js +2 -2
  151. data/lib/leaflet/src/control/Control.Attribution.js +6 -0
  152. data/lib/leaflet/src/control/Control.Layers.js +33 -24
  153. data/lib/leaflet/src/control/Control.Zoom.js +12 -4
  154. data/lib/leaflet/src/control/Control.js +10 -0
  155. data/lib/leaflet/src/copyright.js +2 -1
  156. data/lib/leaflet/src/core/Browser.js +11 -10
  157. data/lib/leaflet/src/core/Events.js +15 -11
  158. data/lib/leaflet/src/core/Util.js +19 -14
  159. data/lib/leaflet/src/dom/DomEvent.DoubleTap.js +13 -12
  160. data/lib/leaflet/src/dom/DomEvent.Pointer.js +155 -0
  161. data/lib/leaflet/src/dom/DomEvent.js +57 -19
  162. data/lib/leaflet/src/dom/DomUtil.js +89 -34
  163. data/lib/leaflet/src/dom/Draggable.js +26 -89
  164. data/lib/leaflet/src/dom/PosAnimation.js +13 -2
  165. data/lib/leaflet/src/geo/LatLng.js +16 -5
  166. data/lib/leaflet/src/geo/LatLngBounds.js +5 -2
  167. data/lib/leaflet/src/geo/crs/CRS.EPSG3395.js +2 -2
  168. data/lib/leaflet/src/geo/crs/CRS.js +5 -0
  169. data/lib/leaflet/src/geo/projection/Projection.Mercator.js +3 -3
  170. data/lib/leaflet/src/geometry/LineUtil.js +2 -2
  171. data/lib/leaflet/src/images/layers.svg +8 -0
  172. data/lib/leaflet/src/images/marker.svg +61 -1
  173. data/lib/leaflet/src/layer/FeatureGroup.js +24 -7
  174. data/lib/leaflet/src/layer/GeoJSON.js +97 -56
  175. data/lib/leaflet/src/layer/ImageOverlay.js +9 -0
  176. data/lib/leaflet/src/layer/LayerGroup.js +8 -3
  177. data/lib/leaflet/src/layer/Popup.js +56 -34
  178. data/lib/leaflet/src/layer/marker/DivIcon.js +4 -2
  179. data/lib/leaflet/src/layer/marker/Icon.Default.js +1 -1
  180. data/lib/leaflet/src/layer/marker/Icon.js +15 -18
  181. data/lib/leaflet/src/layer/marker/Marker.Drag.js +7 -5
  182. data/lib/leaflet/src/layer/marker/Marker.Popup.js +22 -5
  183. data/lib/leaflet/src/layer/marker/Marker.js +75 -32
  184. data/lib/leaflet/src/layer/tile/TileLayer.Anim.js +14 -26
  185. data/lib/leaflet/src/layer/tile/TileLayer.Canvas.js +7 -6
  186. data/lib/leaflet/src/layer/tile/TileLayer.WMS.js +14 -10
  187. data/lib/leaflet/src/layer/tile/TileLayer.js +53 -32
  188. data/lib/leaflet/src/layer/vector/CircleMarker.js +11 -0
  189. data/lib/leaflet/src/layer/vector/MultiPoly.js +10 -0
  190. data/lib/leaflet/src/layer/vector/Path.SVG.js +14 -3
  191. data/lib/leaflet/src/layer/vector/Path.VML.js +12 -2
  192. data/lib/leaflet/src/layer/vector/Path.js +7 -3
  193. data/lib/leaflet/src/layer/vector/Polygon.js +14 -3
  194. data/lib/leaflet/src/layer/vector/canvas/CircleMarker.Canvas.js +9 -0
  195. data/lib/leaflet/src/layer/vector/canvas/Path.Canvas.js +1 -0
  196. data/lib/leaflet/src/map/Map.js +192 -125
  197. data/lib/leaflet/src/map/anim/Map.PanAnimation.js +29 -19
  198. data/lib/leaflet/src/map/anim/Map.ZoomAnimation.js +21 -9
  199. data/lib/leaflet/src/map/ext/Map.Geolocation.js +11 -4
  200. data/lib/leaflet/src/map/handler/Map.BoxZoom.js +26 -12
  201. data/lib/leaflet/src/map/handler/Map.DoubleClickZoom.js +10 -3
  202. data/lib/leaflet/src/map/handler/Map.Drag.js +12 -6
  203. data/lib/leaflet/src/map/handler/Map.Keyboard.js +5 -2
  204. data/lib/leaflet/src/map/handler/Map.ScrollWheelZoom.js +7 -1
  205. data/lib/leaflet/src/map/handler/Map.Tap.js +107 -0
  206. data/lib/leaflet/src/map/handler/Map.TouchZoom.js +9 -3
  207. data/vendor/assets/images/layers-2x.png +0 -0
  208. data/vendor/assets/images/layers.png +0 -0
  209. data/vendor/assets/images/spritesheet-2x.png +0 -0
  210. data/vendor/assets/images/spritesheet.png +0 -0
  211. data/vendor/assets/javascripts/leaflet.draw.js +2 -4
  212. data/vendor/assets/javascripts/leaflet.js +3 -1
  213. data/vendor/assets/javascripts/leaflet.label.js +2 -0
  214. data/vendor/assets/stylesheets/leaflet.css.erb +337 -318
  215. data/vendor/assets/stylesheets/leaflet.draw.css.erb +35 -3
  216. data/vendor/assets/stylesheets/leaflet.draw.ie.css +5 -0
  217. data/vendor/assets/stylesheets/leaflet.label.css +23 -4
  218. metadata +40 -14
  219. data/lib/leaflet.draw/examples/libs/leaflet.ie.css +0 -51
  220. data/lib/leaflet.label/libs/leaflet/leaflet.ie.css +0 -51
  221. data/lib/leaflet/dist/leaflet-src.js +0 -8579
  222. data/lib/leaflet/dist/leaflet.ie.css +0 -51
  223. data/lib/leaflet/dist/leaflet.js +0 -8
  224. data/lib/leaflet/spec/happen.js +0 -93
  225. data/lib/leaflet/src/dom/DomEvent.MsTouch.js +0 -146
  226. data/vendor/assets/stylesheets/leaflet.ie.css +0 -51
@@ -1,6 +1,6 @@
1
1
  describe('LayerGroup', function () {
2
2
  describe("#addLayer", function () {
3
- it('adds a layer', function() {
3
+ it('adds a layer', function () {
4
4
  var lg = L.layerGroup(),
5
5
  marker = L.marker([0, 0]);
6
6
 
@@ -10,7 +10,7 @@
10
10
  });
11
11
  });
12
12
  describe("#removeLayer", function () {
13
- it('removes a layer', function() {
13
+ it('removes a layer', function () {
14
14
  var lg = L.layerGroup(),
15
15
  marker = L.marker([0, 0]);
16
16
 
@@ -21,7 +21,7 @@
21
21
  });
22
22
  });
23
23
  describe("#clearLayers", function () {
24
- it('removes all layers', function() {
24
+ it('removes all layers', function () {
25
25
  var lg = L.layerGroup(),
26
26
  marker = L.marker([0, 0]);
27
27
 
@@ -32,7 +32,7 @@
32
32
  });
33
33
  });
34
34
  describe("#getLayers", function () {
35
- it('gets all layers', function() {
35
+ it('gets all layers', function () {
36
36
  var lg = L.layerGroup(),
37
37
  marker = L.marker([0, 0]);
38
38
 
@@ -42,14 +42,14 @@
42
42
  });
43
43
  });
44
44
  describe("#eachLayer", function () {
45
- it('iterates over all layers', function() {
45
+ it('iterates over all layers', function () {
46
46
  var lg = L.layerGroup(),
47
47
  marker = L.marker([0, 0]),
48
48
  ctx = { foo: 'bar' };
49
49
 
50
50
  lg.addLayer(marker);
51
51
 
52
- lg.eachLayer(function(layer) {
52
+ lg.eachLayer(function (layer) {
53
53
  expect(layer).to.eql(marker);
54
54
  expect(this).to.eql(ctx);
55
55
  }, ctx);
@@ -1,16 +1,76 @@
1
- describe('Popup', function() {
1
+ describe('Popup', function () {
2
2
 
3
- var map;
3
+ var c, map;
4
4
 
5
5
  beforeEach(function () {
6
- var c = document.createElement('div');
6
+ c = document.createElement('div');
7
7
  c.style.width = '400px';
8
8
  c.style.height = '400px';
9
9
  map = new L.Map(c);
10
10
  map.setView(new L.LatLng(55.8, 37.6), 6);
11
11
  });
12
12
 
13
- it("should trigger popupopen on marker when popup opens", function() {
13
+ it("closes on map click when map has closePopupOnClick option", function () {
14
+ map.options.closePopupOnClick = true;
15
+
16
+ var popup = new L.Popup()
17
+ .setLatLng(new L.LatLng(55.8, 37.6))
18
+ .openOn(map);
19
+
20
+ happen.click(c);
21
+
22
+ expect(map.hasLayer(popup)).to.be(false);
23
+ });
24
+
25
+ it("closes on map click when popup has closeOnClick option", function () {
26
+ map.options.closePopupOnClick = false;
27
+
28
+ var popup = new L.Popup({closeOnClick: true})
29
+ .setLatLng(new L.LatLng(55.8, 37.6))
30
+ .openOn(map);
31
+
32
+ happen.click(c);
33
+
34
+ expect(map.hasLayer(popup)).to.be(false);
35
+ });
36
+
37
+ it("does not close on map click when popup has closeOnClick: false option", function () {
38
+ map.options.closePopupOnClick = true;
39
+
40
+ var popup = new L.Popup({closeOnClick: false})
41
+ .setLatLng(new L.LatLng(55.8, 37.6))
42
+ .openOn(map);
43
+
44
+ happen.click(c);
45
+
46
+ expect(map.hasLayer(popup)).to.be(true);
47
+ });
48
+
49
+ it("toggles its visibility when marker is clicked", function () {
50
+ var marker = new L.Marker(new L.LatLng(55.8, 37.6));
51
+ map.addLayer(marker);
52
+
53
+ marker.bindPopup('Popup1').openPopup();
54
+
55
+ map.options.closePopupOnClick = true;
56
+ happen.click(c);
57
+
58
+ // toggle open popup
59
+ sinon.spy(marker, "openPopup");
60
+ marker.fire('click');
61
+ expect(marker.openPopup.calledOnce).to.be(true);
62
+ expect(map.hasLayer(marker._popup)).to.be(true);
63
+ marker.openPopup.restore();
64
+
65
+ // toggle close popup
66
+ sinon.spy(marker, "closePopup");
67
+ marker.fire('click');
68
+ expect(marker.closePopup.calledOnce).to.be(true);
69
+ expect(map.hasLayer(marker._popup)).to.be(false);
70
+ marker.closePopup.restore();
71
+ });
72
+
73
+ it("should trigger popupopen on marker when popup opens", function () {
14
74
  var marker1 = new L.Marker(new L.LatLng(55.8, 37.6));
15
75
  var marker2 = new L.Marker(new L.LatLng(57.123076977278, 44.861962891635));
16
76
 
@@ -31,7 +91,7 @@ describe('Popup', function() {
31
91
  expect(spy.called).to.be(true);
32
92
  });
33
93
 
34
- it("should trigger popupclose on marker when popup closes", function() {
94
+ it("should trigger popupclose on marker when popup closes", function () {
35
95
  var marker1 = new L.Marker(new L.LatLng(55.8, 37.6));
36
96
  var marker2 = new L.Marker(new L.LatLng(57.123076977278, 44.861962891635));
37
97
 
@@ -11,12 +11,14 @@ describe('TileLayer', function () {
11
11
  it("has the same zoomlevels as the tilelayer", function () {
12
12
  var maxZoom = 10,
13
13
  minZoom = 5;
14
- map.setView([0, 0], 1);
15
14
 
16
- L.tileLayer(tileUrl, {
17
- maxZoom: maxZoom,
18
- minZoom: minZoom
19
- }).addTo(map);
15
+ map.setView([0, 0], 1);
16
+
17
+ L.tileLayer(tileUrl, {
18
+ maxZoom: maxZoom,
19
+ minZoom: minZoom
20
+ }).addTo(map);
21
+
20
22
  expect(map.getMaxZoom()).to.be(maxZoom);
21
23
  expect(map.getMinZoom()).to.be(minZoom);
22
24
  });
@@ -35,33 +37,32 @@ describe('TileLayer', function () {
35
37
  it("has its zoomlevels updated to fit the new layer", function () {
36
38
  map.setView([0, 0], 1);
37
39
 
38
- L.tileLayer(tileUrl, { minZoom:10, maxZoom: 15 }).addTo(map);
40
+ L.tileLayer(tileUrl, {minZoom: 10, maxZoom: 15}).addTo(map);
39
41
  expect(map.getMinZoom()).to.be(10);
40
42
  expect(map.getMaxZoom()).to.be(15);
41
43
 
42
- L.tileLayer(tileUrl, { minZoom:5, maxZoom: 10 }).addTo(map);
44
+ L.tileLayer(tileUrl, {minZoom: 5, maxZoom: 10}).addTo(map);
43
45
  expect(map.getMinZoom()).to.be(5); // changed
44
46
  expect(map.getMaxZoom()).to.be(15); // unchanged
45
47
 
46
-
47
- L.tileLayer(tileUrl,{ minZoom:10, maxZoom: 20 }).addTo(map);
48
+ L.tileLayer(tileUrl, {minZoom: 10, maxZoom: 20}).addTo(map);
48
49
  expect(map.getMinZoom()).to.be(5); // unchanged
49
50
  expect(map.getMaxZoom()).to.be(20); // changed
50
51
 
51
52
 
52
- L.tileLayer(tileUrl, { minZoom:0, maxZoom: 25 }).addTo(map);
53
+ L.tileLayer(tileUrl, {minZoom: 0, maxZoom: 25}).addTo(map);
53
54
  expect(map.getMinZoom()).to.be(0); // changed
54
55
  expect(map.getMaxZoom()).to.be(25); // changed
55
56
  });
56
57
  });
57
58
  describe("when a tilelayer is removed from a map", function () {
58
59
  it("has its zoomlevels updated to only fit the layers it currently has", function () {
59
- var tiles = [ L.tileLayer(tileUrl, { minZoom:10, maxZoom: 15 }).addTo(map),
60
- L.tileLayer(tileUrl, { minZoom:5, maxZoom: 10 }).addTo(map),
61
- L.tileLayer(tileUrl, { minZoom:10, maxZoom: 20 }).addTo(map),
62
- L.tileLayer(tileUrl, { minZoom:0, maxZoom: 25 }).addTo(map)
60
+ var tiles = [ L.tileLayer(tileUrl, {minZoom: 10, maxZoom: 15}).addTo(map),
61
+ L.tileLayer(tileUrl, {minZoom: 5, maxZoom: 10}).addTo(map),
62
+ L.tileLayer(tileUrl, {minZoom: 10, maxZoom: 20}).addTo(map),
63
+ L.tileLayer(tileUrl, {minZoom: 0, maxZoom: 25}).addTo(map)
63
64
  ];
64
- map.whenReady(function() {
65
+ map.whenReady(function () {
65
66
  expect(map.getMinZoom()).to.be(0);
66
67
  expect(map.getMaxZoom()).to.be(25);
67
68
 
@@ -0,0 +1,94 @@
1
+ describe("Marker", function () {
2
+ var map,
3
+ spy,
4
+ icon1,
5
+ icon2;
6
+
7
+ beforeEach(function () {
8
+ map = L.map(document.createElement('div')).setView([0, 0], 0);
9
+ icon1 = new L.Icon.Default();
10
+ icon2 = new L.Icon.Default({
11
+ iconUrl: icon1._getIconUrl('icon') + '?2',
12
+ shadowUrl: icon1._getIconUrl('shadow') + '?2'
13
+ });
14
+ });
15
+
16
+ describe("#setIcon", function () {
17
+ it("changes the icon to another image", function () {
18
+ var marker = new L.Marker([0, 0], {icon: icon1});
19
+ map.addLayer(marker);
20
+
21
+ var beforeIcon = marker._icon;
22
+ marker.setIcon(icon2);
23
+ var afterIcon = marker._icon;
24
+
25
+ expect(beforeIcon).to.be(afterIcon);
26
+ expect(afterIcon.src).to.contain(icon2._getIconUrl('icon'));
27
+ });
28
+
29
+ it("changes the icon to another DivIcon", function () {
30
+ var marker = new L.Marker([0, 0], {icon: new L.DivIcon({html: 'Inner1Text' }) });
31
+ map.addLayer(marker);
32
+
33
+ var beforeIcon = marker._icon;
34
+ marker.setIcon(new L.DivIcon({html: 'Inner2Text' }));
35
+ var afterIcon = marker._icon;
36
+
37
+ expect(beforeIcon).to.be(afterIcon);
38
+ expect(afterIcon.innerHTML).to.contain('Inner2Text');
39
+ });
40
+
41
+ it("removes text when changing to a blank DivIcon", function () {
42
+ var marker = new L.Marker([0, 0], {icon: new L.DivIcon({html: 'Inner1Text' }) });
43
+ map.addLayer(marker);
44
+
45
+ marker.setIcon(new L.DivIcon());
46
+ var afterIcon = marker._icon;
47
+
48
+ expect(marker._icon.innerHTML).to.not.contain('Inner1Text');
49
+ });
50
+
51
+ it("changes a DivIcon to an image", function () {
52
+ var marker = new L.Marker([0, 0], {icon: new L.DivIcon({html: 'Inner1Text' }) });
53
+ map.addLayer(marker);
54
+ var oldIcon = marker._icon;
55
+
56
+ marker.setIcon(icon1);
57
+
58
+ expect(oldIcon).to.not.be(marker._icon);
59
+ expect(oldIcon.parentNode).to.be(null);
60
+
61
+ expect(marker._icon.src).to.contain('marker-icon.png');
62
+ expect(marker._icon.parentNode).to.be(map._panes.markerPane);
63
+ });
64
+
65
+ it("changes an image to a DivIcon", function () {
66
+ var marker = new L.Marker([0, 0], {icon: icon1});
67
+ map.addLayer(marker);
68
+ var oldIcon = marker._icon;
69
+
70
+ marker.setIcon(new L.DivIcon({html: 'Inner1Text' }));
71
+
72
+ expect(oldIcon).to.not.be(marker._icon);
73
+ expect(oldIcon.parentNode).to.be(null);
74
+
75
+ expect(marker._icon.innerHTML).to.contain('Inner1Text');
76
+ expect(marker._icon.parentNode).to.be(map._panes.markerPane);
77
+ });
78
+
79
+ it("reuses the icon/shadow when changing icon", function () {
80
+ var marker = new L.Marker([0, 0], { icon: icon1});
81
+ map.addLayer(marker);
82
+ var oldIcon = marker._icon;
83
+ var oldShadow = marker._shadow;
84
+
85
+ marker.setIcon(icon2);
86
+
87
+ expect(oldIcon).to.be(marker._icon);
88
+ expect(oldShadow).to.be(marker._shadow);
89
+
90
+ expect(marker._icon.parentNode).to.be(map._panes.markerPane);
91
+ expect(marker._shadow.parentNode).to.be(map._panes.shadowPane);
92
+ });
93
+ });
94
+ });
@@ -1,13 +1,13 @@
1
- describe('CircleMarker', function() {
2
- describe("#_radius", function() {
1
+ describe('CircleMarker', function () {
2
+ describe("#_radius", function () {
3
3
  var map;
4
- beforeEach(function() {
4
+ beforeEach(function () {
5
5
  map = L.map(document.createElement('div'));
6
6
  map.setView([0, 0], 1);
7
7
  });
8
- describe("when a CircleMarker is added to the map ", function() {
9
- describe("with a radius set as an option", function() {
10
- it("takes that radius", function() {
8
+ describe("when a CircleMarker is added to the map ", function () {
9
+ describe("with a radius set as an option", function () {
10
+ it("takes that radius", function () {
11
11
  var marker = L.circleMarker([0, 0], { radius: 20 }).addTo(map);
12
12
 
13
13
  expect(marker._radius).to.be(20);
@@ -33,7 +33,7 @@
33
33
  });
34
34
 
35
35
  describe("and setStyle is used to change the radius after adding", function () {
36
- it("takes the given radius", function() {
36
+ it("takes the given radius", function () {
37
37
  var marker = L.circleMarker([0, 0], { radius: 20 });
38
38
  marker.addTo(map);
39
39
  marker.setStyle({ radius: 15 });
@@ -1,4 +1,4 @@
1
- describe('Polygon', function() {
1
+ describe('Polygon', function () {
2
2
 
3
3
  var c = document.createElement('div');
4
4
  c.style.width = '400px';
@@ -6,7 +6,7 @@ describe('Polygon', function() {
6
6
  var map = new L.Map(c);
7
7
  map.setView(new L.LatLng(55.8, 37.6), 6);
8
8
 
9
- describe("#initialize", function() {
9
+ describe("#initialize", function () {
10
10
  it("doesn't overwrite the given latlng array", function () {
11
11
  var originalLatLngs = [
12
12
  [1, 2],
@@ -19,6 +19,26 @@ describe('Polygon', function() {
19
19
  expect(sourceLatLngs).to.eql(originalLatLngs);
20
20
  expect(polygon._latlngs).to.not.eql(sourceLatLngs);
21
21
  });
22
+
23
+ it("can be called with an empty array", function () {
24
+ var polygon = new L.Polygon([]);
25
+ expect(polygon.getLatLngs()).to.eql([]);
26
+ });
27
+
28
+ it("can be initialized with holes", function () {
29
+ var originalLatLngs = [
30
+ [ //external rink
31
+ [0, 10], [10, 10], [10, 0]
32
+ ], [ //hole
33
+ [2, 3], [2, 4], [3, 4]
34
+ ]
35
+ ];
36
+
37
+ var polygon = new L.Polygon(originalLatLngs);
38
+
39
+ //getLatLngs() returns only external ring
40
+ expect(polygon.getLatLngs()).to.eql([L.latLng([0, 10]), L.latLng([10, 10]), L.latLng([10, 0])]);
41
+ });
22
42
  });
23
43
 
24
44
  describe("#setLatLngs", function () {
@@ -35,6 +55,22 @@ describe('Polygon', function() {
35
55
 
36
56
  expect(sourceLatLngs).to.eql(originalLatLngs);
37
57
  });
58
+
59
+ it("can be set external ring and holes", function () {
60
+ var latLngs = [
61
+ [ //external rink
62
+ [0, 10], [10, 10], [10, 0]
63
+ ], [ //hole
64
+ [2, 3], [2, 4], [3, 4]
65
+ ]
66
+ ];
67
+
68
+ var polygon = new L.Polygon([]);
69
+ polygon.setLatLngs(latLngs);
70
+
71
+ //getLatLngs() returns only external ring
72
+ expect(polygon.getLatLngs()).to.eql([L.latLng([0, 10]), L.latLng([10, 10]), L.latLng([10, 0])]);
73
+ });
38
74
  });
39
75
 
40
76
  describe("#spliceLatLngs", function () {
@@ -1,4 +1,4 @@
1
- describe('PolylineGeometry', function() {
1
+ describe('PolylineGeometry', function () {
2
2
 
3
3
  var c = document.createElement('div');
4
4
  c.style.width = '400px';
@@ -6,12 +6,12 @@ describe('PolylineGeometry', function() {
6
6
  var map = new L.Map(c);
7
7
  map.setView(new L.LatLng(55.8, 37.6), 6);
8
8
 
9
- describe("#distanceTo", function() {
10
- it("calculates distances to points", function() {
9
+ describe("#distanceTo", function () {
10
+ it("calculates distances to points", function () {
11
11
  var p1 = map.latLngToLayerPoint(new L.LatLng(55.8, 37.6));
12
12
  var p2 = map.latLngToLayerPoint(new L.LatLng(57.123076977278, 44.861962891635));
13
13
  var latlngs = [[56.485503424111, 35.545556640339], [55.972522915346, 36.116845702918], [55.502459116923, 34.930322265253], [55.31534617509, 38.973291015816]]
14
- .map(function(ll) {
14
+ .map(function (ll) {
15
15
  return new L.LatLng(ll[0], ll[1]);
16
16
  });
17
17
  var polyline = new L.Polyline([], {
@@ -1,4 +1,4 @@
1
- describe('Polyline', function() {
1
+ describe('Polyline', function () {
2
2
 
3
3
  var c = document.createElement('div');
4
4
  c.style.width = '400px';
@@ -6,7 +6,7 @@ describe('Polyline', function() {
6
6
  var map = new L.Map(c);
7
7
  map.setView(new L.LatLng(55.8, 37.6), 6);
8
8
 
9
- describe("#initialize", function() {
9
+ describe("#initialize", function () {
10
10
  it("doesn't overwrite the given latlng array", function () {
11
11
  var originalLatLngs = [
12
12
  [1, 2],
@@ -29,8 +29,8 @@ describe("Map", function () {
29
29
  var container = document.createElement('div'),
30
30
  map = new L.Map(container);
31
31
  expect(function () {
32
- new L.Map(container);
33
- }).to.throwException(function(e) {
32
+ L.map(container);
33
+ }).to.throwException(function (e) {
34
34
  expect(e.message).to.eql("Map container is already initialized.");
35
35
  });
36
36
  map.remove();
@@ -38,8 +38,8 @@ describe("Map", function () {
38
38
 
39
39
  it("throws an exception if a container is not found", function () {
40
40
  expect(function () {
41
- new L.Map('nonexistentdivelement');
42
- }).to.throwException(function(e) {
41
+ L.map('nonexistentdivelement');
42
+ }).to.throwException(function (e) {
43
43
  expect(e.message).to.eql("Map container not found.");
44
44
  });
45
45
  map.remove();
@@ -72,11 +72,24 @@ describe("Map", function () {
72
72
  });
73
73
 
74
74
  describe('#getCenter', function () {
75
- it ('throws if not set before', function () {
75
+ it('throws if not set before', function () {
76
76
  expect(function () {
77
77
  map.getCenter();
78
78
  }).to.throwError();
79
79
  });
80
+
81
+ it('returns a precise center when zoomed in after being set (#426)', function () {
82
+ var center = L.latLng(10, 10);
83
+ map.setView(center, 1);
84
+ map.setZoom(19);
85
+ expect(map.getCenter()).to.eql(center);
86
+ });
87
+
88
+ it('returns correct center after invalidateSize (#1919)', function () {
89
+ map.setView(L.latLng(10, 10), 1);
90
+ map.invalidateSize();
91
+ expect(map.getCenter()).not.to.eql(L.latLng(10, 10));
92
+ });
80
93
  });
81
94
 
82
95
  describe("#whenReady", function () {
@@ -108,6 +121,12 @@ describe("Map", function () {
108
121
  expect(map.getZoom()).to.be(13);
109
122
  expect(map.getCenter().distanceTo([51.505, -0.09])).to.be.lessThan(5);
110
123
  });
124
+ it("can be passed without a zoom specified", function () {
125
+ map.setZoom(13);
126
+ expect(map.setView([51.605, -0.11])).to.be(map);
127
+ expect(map.getZoom()).to.be(13);
128
+ expect(map.getCenter().distanceTo([51.605, -0.11])).to.be.lessThan(5);
129
+ });
111
130
  });
112
131
 
113
132
  describe("#getBounds", function () {
@@ -120,24 +139,135 @@ describe("Map", function () {
120
139
  });
121
140
  });
122
141
 
142
+ describe('#setMaxBounds', function () {
143
+ it("aligns pixel-wise map view center with maxBounds center if it cannot move view bounds inside maxBounds (#1908)", function () {
144
+ var container = map.getContainer();
145
+ // large view, cannot fit within maxBounds
146
+ container.style.width = container.style.height = "1000px";
147
+ document.body.appendChild(container);
148
+ // maxBounds
149
+ var bounds = L.latLngBounds([51.5, -0.05], [51.55, 0.05]);
150
+ map.setMaxBounds(bounds, {animate: false});
151
+ // set view outside
152
+ map.setView(L.latLng([53.0, 0.15]), 12, {animate: false});
153
+ // get center of bounds in pixels
154
+ var boundsCenter = map.project(bounds.getCenter()).round();
155
+ expect(map.project(map.getCenter()).round()).to.eql(boundsCenter);
156
+ document.body.removeChild(container);
157
+ });
158
+ it("moves map view within maxBounds by changing one coordinate", function () {
159
+ var container = map.getContainer();
160
+ // small view, can fit within maxBounds
161
+ container.style.width = container.style.height = "200px";
162
+ document.body.appendChild(container);
163
+ // maxBounds
164
+ var bounds = L.latLngBounds([51, -0.2], [52, 0.2]);
165
+ map.setMaxBounds(bounds, {animate: false});
166
+ // set view outside maxBounds on one direction only
167
+ // leaves untouched the other coordinate (that is not already centered)
168
+ var initCenter = [53.0, 0.1];
169
+ map.setView(L.latLng(initCenter), 16, {animate: false});
170
+ // one pixel coordinate hasn't changed, the other has
171
+ var pixelCenter = map.project(map.getCenter()).round();
172
+ var pixelInit = map.project(initCenter).round();
173
+ expect(pixelCenter.x).to.eql(pixelInit.x);
174
+ expect(pixelCenter.y).not.to.eql(pixelInit.y);
175
+ // the view is inside the bounds
176
+ expect(bounds.contains(map.getBounds())).to.be(true);
177
+ document.body.removeChild(container);
178
+ });
179
+ });
180
+
123
181
  describe("#getMinZoom and #getMaxZoom", function () {
182
+ describe('#getMinZoom', function () {
183
+ it('returns 0 if not set by Map options or TileLayer options', function () {
184
+ var map = L.map(document.createElement('div'));
185
+ expect(map.getMinZoom()).to.be(0);
186
+ });
187
+ });
188
+
124
189
  it("minZoom and maxZoom options overrides any minZoom and maxZoom set on layers", function () {
125
- var c = document.createElement('div'),
126
- map = L.map(c, { minZoom: 5, maxZoom: 10 });
127
- L.tileLayer("{z}{x}{y}", { minZoom:0, maxZoom: 10 }).addTo(map);
128
- L.tileLayer("{z}{x}{y}", { minZoom:5, maxZoom: 15 }).addTo(map);
129
- expect(map.getMinZoom()).to.be(5);
130
- expect(map.getMaxZoom()).to.be(10);
190
+
191
+ var map = L.map(document.createElement('div'), {minZoom: 2, maxZoom: 20});
192
+
193
+ L.tileLayer("{z}{x}{y}", {minZoom: 4, maxZoom: 10}).addTo(map);
194
+ L.tileLayer("{z}{x}{y}", {minZoom: 6, maxZoom: 17}).addTo(map);
195
+ L.tileLayer("{z}{x}{y}", {minZoom: 0, maxZoom: 22}).addTo(map);
196
+
197
+ expect(map.getMinZoom()).to.be(2);
198
+ expect(map.getMaxZoom()).to.be(20);
131
199
  });
132
200
  });
133
201
 
134
202
  describe("#addLayer", function () {
203
+ it("calls layer.onAdd immediately if the map is ready", function () {
204
+ var layer = { onAdd: sinon.spy() };
205
+ map.setView([0, 0], 0);
206
+ map.addLayer(layer);
207
+ expect(layer.onAdd.called).to.be.ok();
208
+ });
209
+
210
+ it("calls layer.onAdd when the map becomes ready", function () {
211
+ var layer = { onAdd: sinon.spy() };
212
+ map.addLayer(layer);
213
+ expect(layer.onAdd.called).not.to.be.ok();
214
+ map.setView([0, 0], 0);
215
+ expect(layer.onAdd.called).to.be.ok();
216
+ });
217
+
218
+ it("does not call layer.onAdd if the layer is removed before the map becomes ready", function () {
219
+ var layer = { onAdd: sinon.spy(), onRemove: sinon.spy() };
220
+ map.addLayer(layer);
221
+ map.removeLayer(layer);
222
+ map.setView([0, 0], 0);
223
+ expect(layer.onAdd.called).not.to.be.ok();
224
+ });
225
+
226
+ it("fires a layeradd event immediately if the map is ready", function () {
227
+ var layer = { onAdd: sinon.spy() },
228
+ spy = sinon.spy();
229
+ map.on('layeradd', spy);
230
+ map.setView([0, 0], 0);
231
+ map.addLayer(layer);
232
+ expect(spy.called).to.be.ok();
233
+ });
234
+
235
+ it("fires a layeradd event when the map becomes ready", function () {
236
+ var layer = { onAdd: sinon.spy() },
237
+ spy = sinon.spy();
238
+ map.on('layeradd', spy);
239
+ map.addLayer(layer);
240
+ expect(spy.called).not.to.be.ok();
241
+ map.setView([0, 0], 0);
242
+ expect(spy.called).to.be.ok();
243
+ });
244
+
245
+ it("does not fire a layeradd event if the layer is removed before the map becomes ready", function () {
246
+ var layer = { onAdd: sinon.spy(), onRemove: sinon.spy() },
247
+ spy = sinon.spy();
248
+ map.on('layeradd', spy);
249
+ map.addLayer(layer);
250
+ map.removeLayer(layer);
251
+ map.setView([0, 0], 0);
252
+ expect(spy.called).not.to.be.ok();
253
+ });
254
+
255
+ it("adds the layer before firing layeradd", function (done) {
256
+ var layer = { onAdd: sinon.spy(), onRemove: sinon.spy() };
257
+ map.on('layeradd', function () {
258
+ expect(map.hasLayer(layer)).to.be.ok();
259
+ done();
260
+ });
261
+ map.setView([0, 0], 0);
262
+ map.addLayer(layer);
263
+ });
264
+
135
265
  describe("When the first layer is added to a map", function () {
136
266
  it("fires a zoomlevelschange event", function () {
137
267
  var spy = sinon.spy();
138
268
  map.on("zoomlevelschange", spy);
139
269
  expect(spy.called).not.to.be.ok();
140
- L.tileLayer("{z}{x}{y}", { minZoom:0, maxZoom: 10 }).addTo(map);
270
+ L.tileLayer("{z}{x}{y}", {minZoom: 0, maxZoom: 10}).addTo(map);
141
271
  expect(spy.called).to.be.ok();
142
272
  });
143
273
  });
@@ -145,10 +275,10 @@ describe("Map", function () {
145
275
  describe("when a new layer with greater zoomlevel coverage than the current layer is added to a map", function () {
146
276
  it("fires a zoomlevelschange event", function () {
147
277
  var spy = sinon.spy();
148
- L.tileLayer("{z}{x}{y}", { minZoom:0, maxZoom: 10 }).addTo(map);
278
+ L.tileLayer("{z}{x}{y}", {minZoom: 0, maxZoom: 10}).addTo(map);
149
279
  map.on("zoomlevelschange", spy);
150
280
  expect(spy.called).not.to.be.ok();
151
- L.tileLayer("{z}{x}{y}", { minZoom:0, maxZoom: 15 }).addTo(map);
281
+ L.tileLayer("{z}{x}{y}", {minZoom: 0, maxZoom: 15}).addTo(map);
152
282
  expect(spy.called).to.be.ok();
153
283
  });
154
284
  });
@@ -156,23 +286,84 @@ describe("Map", function () {
156
286
  describe("when a new layer with the same or lower zoomlevel coverage as the current layer is added to a map", function () {
157
287
  it("fires no zoomlevelschange event", function () {
158
288
  var spy = sinon.spy();
159
- L.tileLayer("{z}{x}{y}", { minZoom:0, maxZoom: 10 }).addTo(map);
289
+ L.tileLayer("{z}{x}{y}", {minZoom: 0, maxZoom: 10}).addTo(map);
160
290
  map.on("zoomlevelschange", spy);
161
291
  expect(spy.called).not.to.be.ok();
162
- L.tileLayer("{z}{x}{y}", { minZoom:0, maxZoom: 10 }).addTo(map);
292
+ L.tileLayer("{z}{x}{y}", {minZoom: 0, maxZoom: 10}).addTo(map);
163
293
  expect(spy.called).not.to.be.ok();
164
- L.tileLayer("{z}{x}{y}", { minZoom:0, maxZoom: 5 }).addTo(map);
294
+ L.tileLayer("{z}{x}{y}", {minZoom: 0, maxZoom: 5}).addTo(map);
165
295
  expect(spy.called).not.to.be.ok();
166
296
  });
167
297
  });
168
298
  });
169
299
 
170
300
  describe("#removeLayer", function () {
301
+ it("calls layer.onRemove if the map is ready", function () {
302
+ var layer = { onAdd: sinon.spy(), onRemove: sinon.spy() };
303
+ map.setView([0, 0], 0);
304
+ map.addLayer(layer);
305
+ map.removeLayer(layer);
306
+ expect(layer.onRemove.called).to.be.ok();
307
+ });
308
+
309
+ it("does not call layer.onRemove if the layer was not added", function () {
310
+ var layer = { onAdd: sinon.spy(), onRemove: sinon.spy() };
311
+ map.setView([0, 0], 0);
312
+ map.removeLayer(layer);
313
+ expect(layer.onRemove.called).not.to.be.ok();
314
+ });
315
+
316
+ it("does not call layer.onRemove if the map is not ready", function () {
317
+ var layer = { onAdd: sinon.spy(), onRemove: sinon.spy() };
318
+ map.addLayer(layer);
319
+ map.removeLayer(layer);
320
+ expect(layer.onRemove.called).not.to.be.ok();
321
+ });
322
+
323
+ it("fires a layerremove event if the map is ready", function () {
324
+ var layer = { onAdd: sinon.spy(), onRemove: sinon.spy() },
325
+ spy = sinon.spy();
326
+ map.on('layerremove', spy);
327
+ map.setView([0, 0], 0);
328
+ map.addLayer(layer);
329
+ map.removeLayer(layer);
330
+ expect(spy.called).to.be.ok();
331
+ });
332
+
333
+ it("does not fire a layerremove if the layer was not added", function () {
334
+ var layer = { onAdd: sinon.spy(), onRemove: sinon.spy() },
335
+ spy = sinon.spy();
336
+ map.on('layerremove', spy);
337
+ map.setView([0, 0], 0);
338
+ map.removeLayer(layer);
339
+ expect(spy.called).not.to.be.ok();
340
+ });
341
+
342
+ it("does not fire a layerremove if the map is not ready", function () {
343
+ var layer = { onAdd: sinon.spy(), onRemove: sinon.spy() },
344
+ spy = sinon.spy();
345
+ map.on('layerremove', spy);
346
+ map.addLayer(layer);
347
+ map.removeLayer(layer);
348
+ expect(spy.called).not.to.be.ok();
349
+ });
350
+
351
+ it("removes the layer before firing layerremove", function (done) {
352
+ var layer = { onAdd: sinon.spy(), onRemove: sinon.spy() };
353
+ map.on('layerremove', function () {
354
+ expect(map.hasLayer(layer)).not.to.be.ok();
355
+ done();
356
+ });
357
+ map.setView([0, 0], 0);
358
+ map.addLayer(layer);
359
+ map.removeLayer(layer);
360
+ });
361
+
171
362
  describe("when the last tile layer on a map is removed", function () {
172
363
  it("fires a zoomlevelschange event", function () {
173
- map.whenReady(function(){
364
+ map.whenReady(function () {
174
365
  var spy = sinon.spy();
175
- var tl = L.tileLayer("{z}{x}{y}", { minZoom:0, maxZoom: 10 }).addTo(map);
366
+ var tl = L.tileLayer("{z}{x}{y}", {minZoom: 0, maxZoom: 10}).addTo(map);
176
367
 
177
368
  map.on("zoomlevelschange", spy);
178
369
  expect(spy.called).not.to.be.ok();
@@ -184,10 +375,10 @@ describe("Map", function () {
184
375
 
185
376
  describe("when a tile layer is removed from a map and it had greater zoom level coverage than the remainding layer", function () {
186
377
  it("fires a zoomlevelschange event", function () {
187
- map.whenReady(function(){
378
+ map.whenReady(function () {
188
379
  var spy = sinon.spy(),
189
- tl = L.tileLayer("{z}{x}{y}", { minZoom:0, maxZoom: 10 }).addTo(map),
190
- t2 = L.tileLayer("{z}{x}{y}", { minZoom:0, maxZoom: 15 }).addTo(map);
380
+ tl = L.tileLayer("{z}{x}{y}", {minZoom: 0, maxZoom: 10}).addTo(map),
381
+ t2 = L.tileLayer("{z}{x}{y}", {minZoom: 0, maxZoom: 15}).addTo(map);
191
382
 
192
383
  map.on("zoomlevelschange", spy);
193
384
  expect(spy.called).to.not.be.ok();
@@ -199,10 +390,10 @@ describe("Map", function () {
199
390
 
200
391
  describe("when a tile layer is removed from a map it and it had lesser or the sa,e zoom level coverage as the remainding layer(s)", function () {
201
392
  it("fires no zoomlevelschange event", function () {
202
- map.whenReady(function(){
203
- var tl = L.tileLayer("{z}{x}{y}", { minZoom:0, maxZoom: 10 }).addTo(map),
204
- t2 = L.tileLayer("{z}{x}{y}", { minZoom:0, maxZoom: 10 }).addTo(map),
205
- t3 = L.tileLayer("{z}{x}{y}", { minZoom:0, maxZoom: 5 }).addTo(map);
393
+ map.whenReady(function () {
394
+ var tl = L.tileLayer("{z}{x}{y}", {minZoom: 0, maxZoom: 10}).addTo(map),
395
+ t2 = L.tileLayer("{z}{x}{y}", {minZoom: 0, maxZoom: 10}).addTo(map),
396
+ t3 = L.tileLayer("{z}{x}{y}", {minZoom: 0, maxZoom: 5}).addTo(map);
206
397
 
207
398
  map.on("zoomlevelschange", spy);
208
399
  expect(spy).not.toHaveBeenCalled();
@@ -241,4 +432,105 @@ describe("Map", function () {
241
432
  expect(spy.thisValues[0]).to.eql(map);
242
433
  });
243
434
  });
435
+
436
+ describe("#invalidateSize", function () {
437
+ var container,
438
+ origWidth = 100,
439
+ clock;
440
+
441
+ beforeEach(function () {
442
+ container = map.getContainer();
443
+ container.style.width = origWidth + "px";
444
+ document.body.appendChild(container);
445
+ map.setView([0, 0], 0);
446
+ map.invalidateSize({pan: false});
447
+ clock = sinon.useFakeTimers();
448
+ });
449
+
450
+ afterEach(function () {
451
+ document.body.removeChild(container);
452
+ clock.restore();
453
+ });
454
+
455
+ it("pans by the right amount when growing in 1px increments", function () {
456
+ container.style.width = (origWidth + 1) + "px";
457
+ map.invalidateSize();
458
+ expect(map._getMapPanePos().x).to.be(1);
459
+
460
+ container.style.width = (origWidth + 2) + "px";
461
+ map.invalidateSize();
462
+ expect(map._getMapPanePos().x).to.be(1);
463
+
464
+ container.style.width = (origWidth + 3) + "px";
465
+ map.invalidateSize();
466
+ expect(map._getMapPanePos().x).to.be(2);
467
+ });
468
+
469
+ it("pans by the right amount when shrinking in 1px increments", function () {
470
+ container.style.width = (origWidth - 1) + "px";
471
+ map.invalidateSize();
472
+ expect(map._getMapPanePos().x).to.be(0);
473
+
474
+ container.style.width = (origWidth - 2) + "px";
475
+ map.invalidateSize();
476
+ expect(map._getMapPanePos().x).to.be(-1);
477
+
478
+ container.style.width = (origWidth - 3) + "px";
479
+ map.invalidateSize();
480
+ expect(map._getMapPanePos().x).to.be(-1);
481
+ });
482
+
483
+ it("pans back to the original position after growing by an odd size and back", function () {
484
+ container.style.width = (origWidth + 5) + "px";
485
+ map.invalidateSize();
486
+
487
+ container.style.width = origWidth + "px";
488
+ map.invalidateSize();
489
+
490
+ expect(map._getMapPanePos().x).to.be(0);
491
+ });
492
+
493
+ it("emits no move event if the size has not changed", function () {
494
+ var spy = sinon.spy();
495
+ map.on("move", spy);
496
+
497
+ map.invalidateSize();
498
+
499
+ expect(spy.called).not.to.be.ok();
500
+ });
501
+
502
+ it("emits a move event if the size has changed", function () {
503
+ var spy = sinon.spy();
504
+ map.on("move", spy);
505
+
506
+ container.style.width = (origWidth + 5) + "px";
507
+ map.invalidateSize();
508
+
509
+ expect(spy.called).to.be.ok();
510
+ });
511
+
512
+ it("emits a moveend event if the size has changed", function () {
513
+ var spy = sinon.spy();
514
+ map.on("moveend", spy);
515
+
516
+ container.style.width = (origWidth + 5) + "px";
517
+ map.invalidateSize();
518
+
519
+ expect(spy.called).to.be.ok();
520
+ });
521
+
522
+ it("debounces the moveend event if the debounceMoveend option is given", function () {
523
+ var spy = sinon.spy();
524
+ map.on("moveend", spy);
525
+
526
+ container.style.width = (origWidth + 5) + "px";
527
+ map.invalidateSize({debounceMoveend: true});
528
+
529
+ expect(spy.called).not.to.be.ok();
530
+
531
+ clock.tick(200);
532
+
533
+ expect(spy.called).to.be.ok();
534
+ });
535
+ });
244
536
  });