Skip to content

Commit 5848031

Browse files
committed
Merge pull request #607 from ghybs/removeAnimClassOnMapRemovedButSpiderfied
Remove "leaflet-cluster-anim" class on map remove while spiderfied
2 parents ad78e3c + fd59fa4 commit 5848031

File tree

2 files changed

+167
-21
lines changed

2 files changed

+167
-21
lines changed

spec/suites/spiderfySpec.js

+163-20
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,74 @@
11
describe('spiderfy', function () {
2-
var map, div, clock;
3-
beforeEach(function () {
4-
clock = sinon.useFakeTimers();
52

6-
div = document.createElement('div');
7-
div.style.width = '200px';
8-
div.style.height = '200px';
9-
document.body.appendChild(div);
3+
/**
4+
* Avoid as much as possible creating and destroying objects for each test.
5+
* Instead, try re-using them, except for the ones under test of course.
6+
* PhantomJS does not perform garbage collection for the life of the page,
7+
* i.e. during the entire test process (Karma runs all tests in a single page).
8+
* http://stackoverflow.com/questions/27239708/how-to-get-around-memory-error-with-karma-phantomjs
9+
*
10+
* The `beforeEach` and `afterEach do not seem to cause much issue.
11+
* => they can still be used to initialize some setup between each test.
12+
* Using them keeps a readable spec/index.
13+
*
14+
* But refrain from re-creating div and map every time. Re-use those objects.
15+
*/
16+
17+
/////////////////////////////
18+
// SETUP FOR EACH TEST
19+
/////////////////////////////
20+
21+
beforeEach(function () {
1022

11-
map = L.map(div, { maxZoom: 18 });
23+
clock = sinon.useFakeTimers();
1224

13-
map.fitBounds(new L.LatLngBounds([
14-
[1, 1],
15-
[2, 2]
16-
]));
1725
});
26+
1827
afterEach(function () {
28+
29+
if (group instanceof L.MarkerClusterGroup) {
30+
group.clearLayers();
31+
map.removeLayer(group);
32+
}
33+
34+
// group must be thrown away since we are testing it with a potentially
35+
// different configuration at each test.
36+
group = null;
37+
1938
clock.restore();
20-
document.body.removeChild(div);
39+
clock = null;
40+
2141
});
2242

43+
44+
/////////////////////////////
45+
// PREPARATION CODE
46+
/////////////////////////////
47+
48+
var div, map, group, clock;
49+
50+
div = document.createElement('div');
51+
div.style.width = '200px';
52+
div.style.height = '200px';
53+
document.body.appendChild(div);
54+
55+
map = L.map(div, { maxZoom: 18 });
56+
57+
// Corresponds to zoom level 8 for the above div dimensions.
58+
map.fitBounds(new L.LatLngBounds([
59+
[1, 1],
60+
[2, 2]
61+
]));
62+
63+
64+
/////////////////////////////
65+
// TESTS
66+
/////////////////////////////
67+
2368
it('Spiderfies 2 Markers', function () {
2469

25-
var group = new L.MarkerClusterGroup();
70+
group = new L.MarkerClusterGroup();
71+
2672
var marker = new L.Marker([1.5, 1.5]);
2773
var marker2 = new L.Marker([1.5, 1.5]);
2874

@@ -38,7 +84,8 @@
3884

3985
it('Spiderfies 2 CircleMarkers', function () {
4086

41-
var group = new L.MarkerClusterGroup();
87+
group = new L.MarkerClusterGroup();
88+
4289
var marker = new L.CircleMarker([1.5, 1.5]);
4390
var marker2 = new L.CircleMarker([1.5, 1.5]);
4491

@@ -54,7 +101,8 @@
54101

55102
it('Spiderfies 2 Circles', function () {
56103

57-
var group = new L.MarkerClusterGroup();
104+
group = new L.MarkerClusterGroup();
105+
58106
var marker = new L.Circle([1.5, 1.5], 10);
59107
var marker2 = new L.Circle([1.5, 1.5], 10);
60108

@@ -70,7 +118,8 @@
70118

71119
it('Spiderfies at current zoom if all child markers are at the exact same position', function () {
72120

73-
var group = new L.MarkerClusterGroup();
121+
group = new L.MarkerClusterGroup();
122+
74123
var marker = new L.Marker([1.5, 1.5]);
75124
var marker2 = new L.Marker([1.5, 1.5]);
76125

@@ -100,7 +149,8 @@
100149

101150
it('Spiderfies at current zoom if all child markers are still within a single cluster at map maxZoom', function () {
102151

103-
var group = new L.MarkerClusterGroup();
152+
group = new L.MarkerClusterGroup();
153+
104154
var marker = new L.Marker([1.5, 1.50001]);
105155
var marker2 = new L.Marker([1.5, 1.5]);
106156

@@ -130,10 +180,93 @@
130180

131181
});
132182

183+
it('removes all markers and spider legs when group is removed from map', function () {
184+
185+
group = new L.MarkerClusterGroup();
186+
187+
var marker = new L.Marker([1.5, 1.5]);
188+
var marker2 = new L.Marker([1.5, 1.5]);
189+
190+
group.addLayers([marker, marker2]);
191+
map.addLayer(group);
192+
193+
marker.__parent.spiderfy();
194+
195+
expect(map._panes.markerPane.childNodes.length).to.be(3); // The 2 markers + semi-transparent cluster.
196+
expect(map._pathRoot.childNodes.length).to.be(2); // The 2 spider legs.
197+
198+
});
199+
200+
it('adds then removes class "leaflet-cluster-anim" from mapPane on spiderfy', function () {
201+
202+
group = new L.MarkerClusterGroup();
203+
204+
var marker = new L.Marker([1.5, 1.5]);
205+
var marker2 = new L.Marker([1.5, 1.5]);
206+
207+
group.addLayers([marker, marker2]);
208+
map.addLayer(group);
209+
210+
marker.__parent.spiderfy();
211+
212+
expect(map._panes.mapPane.className).to.contain('leaflet-cluster-anim');
213+
214+
clock.tick(1000);
215+
216+
expect(map._panes.mapPane.className).to.not.contain('leaflet-cluster-anim');
217+
218+
});
219+
220+
it('adds then removes class "leaflet-cluster-anim" from mapPane on unspiderfy', function () {
221+
222+
group = new L.MarkerClusterGroup();
223+
224+
var marker = new L.Marker([1.5, 1.5]);
225+
var marker2 = new L.Marker([1.5, 1.5]);
226+
227+
group.addLayers([marker, marker2]);
228+
map.addLayer(group);
229+
230+
marker.__parent.spiderfy();
231+
232+
clock.tick(1000);
233+
234+
marker.__parent.unspiderfy();
235+
236+
expect(map._panes.mapPane.className).to.contain('leaflet-cluster-anim');
237+
238+
clock.tick(1000);
239+
240+
expect(map._panes.mapPane.className).to.not.contain('leaflet-cluster-anim');
241+
242+
});
243+
244+
it('does not leave class "leaflet-cluster-anim" on mapPane when group is removed while spiderfied', function () {
245+
246+
group = new L.MarkerClusterGroup();
247+
248+
var marker = new L.Marker([1.5, 1.5]);
249+
var marker2 = new L.Marker([1.5, 1.5]);
250+
251+
group.addLayers([marker, marker2]);
252+
map.addLayer(group);
253+
254+
marker.__parent.spiderfy();
255+
256+
clock.tick(1000);
257+
258+
map.removeLayer(group);
259+
260+
expect(map._panes.mapPane.className).to.not.contain('leaflet-cluster-anim');
261+
262+
});
263+
133264
describe('zoomend event listener', function () {
265+
134266
it('unspiderfies correctly', function () {
135267

136-
var group = new L.MarkerClusterGroup();
268+
group = new L.MarkerClusterGroup();
269+
137270
var marker = new L.Circle([1.5, 1.5], 10);
138271
var marker2 = new L.Circle([1.5, 1.5], 10);
139272

@@ -150,5 +283,15 @@
150283
//We should unspiderfy with no animation, so this should be null
151284
expect(group._spiderfied).to.be(null);
152285
});
286+
153287
});
154-
});
288+
289+
290+
/////////////////////////////
291+
// CLEAN UP CODE
292+
/////////////////////////////
293+
294+
map.remove();
295+
document.body.removeChild(div);
296+
297+
});

src/MarkerCluster.Spiderfier.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -361,8 +361,11 @@ L.MarkerClusterGroup.include({
361361
this._map.off('click', this._unspiderfyWrapper, this);
362362
this._map.off('zoomstart', this._unspiderfyZoomStart, this);
363363
this._map.off('zoomanim', this._unspiderfyZoomAnim, this);
364+
this._map.off('zoomend', this._noanimationUnspiderfy, this);
364365

365-
this._unspiderfy(); //Ensure that markers are back where they should be
366+
//Ensure that markers are back where they should be
367+
// Use no animation to avoid a sticky leaflet-cluster-anim class on mapPane
368+
this._noanimationUnspiderfy();
366369
},
367370

368371
//On zoom start we add a zoomanim handler so that we are guaranteed to be last (after markers are animated)

0 commit comments

Comments
 (0)