move add/removeLayer logic to Layer; ditch tilelayersload event

This commit is contained in:
Vladimir Agafonkin 2013-12-05 19:47:58 +02:00
parent a30a872a78
commit 4011a6199f
3 changed files with 66 additions and 82 deletions

View File

@ -199,16 +199,24 @@ describe("Map", function () {
});
});
function layerSpy() {
var layer = new L.Layer();
layer.onAdd = sinon.spy();
layer.onRemove = sinon.spy();
return layer;
}
describe("#addLayer", function () {
it("calls layer.onAdd immediately if the map is ready", function () {
var layer = { onAdd: sinon.spy() };
var layer = layerSpy();
map.setView([0, 0], 0);
map.addLayer(layer);
expect(layer.onAdd.called).to.be.ok();
});
it("calls layer.onAdd when the map becomes ready", function () {
var layer = { onAdd: sinon.spy() };
var layer = layerSpy();
map.addLayer(layer);
expect(layer.onAdd.called).not.to.be.ok();
map.setView([0, 0], 0);
@ -216,7 +224,7 @@ describe("Map", function () {
});
it("does not call layer.onAdd if the layer is removed before the map becomes ready", function () {
var layer = { onAdd: sinon.spy(), onRemove: sinon.spy() };
var layer = layerSpy();
map.addLayer(layer);
map.removeLayer(layer);
map.setView([0, 0], 0);
@ -224,7 +232,7 @@ describe("Map", function () {
});
it("fires a layeradd event immediately if the map is ready", function () {
var layer = { onAdd: sinon.spy() },
var layer = layerSpy(),
spy = sinon.spy();
map.on('layeradd', spy);
map.setView([0, 0], 0);
@ -233,7 +241,7 @@ describe("Map", function () {
});
it("fires a layeradd event when the map becomes ready", function () {
var layer = { onAdd: sinon.spy() },
var layer = layerSpy(),
spy = sinon.spy();
map.on('layeradd', spy);
map.addLayer(layer);
@ -243,7 +251,7 @@ describe("Map", function () {
});
it("does not fire a layeradd event if the layer is removed before the map becomes ready", function () {
var layer = { onAdd: sinon.spy(), onRemove: sinon.spy() },
var layer = layerSpy(),
spy = sinon.spy();
map.on('layeradd', spy);
map.addLayer(layer);
@ -253,7 +261,7 @@ describe("Map", function () {
});
it("adds the layer before firing layeradd", function (done) {
var layer = { onAdd: sinon.spy(), onRemove: sinon.spy() };
var layer = layerSpy();
map.on('layeradd', function () {
expect(map.hasLayer(layer)).to.be.ok();
done();
@ -299,7 +307,7 @@ describe("Map", function () {
describe("#removeLayer", function () {
it("calls layer.onRemove if the map is ready", function () {
var layer = { onAdd: sinon.spy(), onRemove: sinon.spy() };
var layer = layerSpy();
map.setView([0, 0], 0);
map.addLayer(layer);
map.removeLayer(layer);
@ -307,21 +315,21 @@ describe("Map", function () {
});
it("does not call layer.onRemove if the layer was not added", function () {
var layer = { onAdd: sinon.spy(), onRemove: sinon.spy() };
var layer = layerSpy();
map.setView([0, 0], 0);
map.removeLayer(layer);
expect(layer.onRemove.called).not.to.be.ok();
});
it("does not call layer.onRemove if the map is not ready", function () {
var layer = { onAdd: sinon.spy(), onRemove: sinon.spy() };
var layer = layerSpy();
map.addLayer(layer);
map.removeLayer(layer);
expect(layer.onRemove.called).not.to.be.ok();
});
it("fires a layerremove event if the map is ready", function () {
var layer = { onAdd: sinon.spy(), onRemove: sinon.spy() },
var layer = layerSpy(),
spy = sinon.spy();
map.on('layerremove', spy);
map.setView([0, 0], 0);
@ -331,7 +339,7 @@ describe("Map", function () {
});
it("does not fire a layerremove if the layer was not added", function () {
var layer = { onAdd: sinon.spy(), onRemove: sinon.spy() },
var layer = layerSpy(),
spy = sinon.spy();
map.on('layerremove', spy);
map.setView([0, 0], 0);
@ -340,7 +348,7 @@ describe("Map", function () {
});
it("does not fire a layerremove if the map is not ready", function () {
var layer = { onAdd: sinon.spy(), onRemove: sinon.spy() },
var layer = layerSpy(),
spy = sinon.spy();
map.on('layerremove', spy);
map.addLayer(layer);
@ -349,7 +357,7 @@ describe("Map", function () {
});
it("removes the layer before firing layerremove", function (done) {
var layer = { onAdd: sinon.spy(), onRemove: sinon.spy() };
var layer = layerSpy();
map.on('layerremove', function () {
expect(map.hasLayer(layer)).not.to.be.ok();
done();

View File

@ -7,10 +7,51 @@ L.Layer = L.Class.extend({
},
addTo: function (map) {
map.addLayer(this);
this._map = map;
var id = L.stamp(this);
if (map._layers[id]) { return this; }
map._layers[id] = this;
// TODO getMaxZoom, getMinZoom in ILayer (instead of options)
if (this.options && (!isNaN(this.options.maxZoom) || !isNaN(this.options.minZoom))) {
map._zoomBoundLayers[id] = this;
map._updateZoomLevels();
}
map.whenReady(this._layerAdd, this);
return this;
},
_layerAdd: function () {
// check in case layer gets added and then removed before the map is ready
if (!this._map.hasLayer(this)) { return; }
this.onAdd(this._map);
this._map.fire('layeradd', {layer: this});
},
removeFrom: function (map) {
var id = L.stamp(this);
if (!map._layers[id]) { return this; }
if (map._loaded) {
this.onRemove(map);
}
delete map._layers[id];
if (map._loaded) {
map.fire('layerremove', {layer: this});
}
if (map._zoomBoundLayers[id]) {
delete map._zoomBoundLayers[id];
map._updateZoomLevels();
}
},
getPane: function () {
// TODO make pane if not present
return this._map._panes[this.options.pane];

View File

@ -44,7 +44,6 @@ L.Map = L.Class.extend({
this._layers = {};
this._zoomBoundLayers = {};
this._tileLayersNum = 0;
this.callInitHooks();
@ -152,61 +151,12 @@ L.Map = L.Class.extend({
},
addLayer: function (layer) {
// TODO method is too big, refactor
var id = L.stamp(layer);
if (this._layers[id]) { return this; }
this._layers[id] = layer;
// TODO getMaxZoom, getMinZoom in ILayer (instead of options)
if (layer.options && (!isNaN(layer.options.maxZoom) || !isNaN(layer.options.minZoom))) {
this._zoomBoundLayers[id] = layer;
this._updateZoomLevels();
}
// TODO looks ugly, refactor!!!
if (this.options.zoomAnimation && L.TileLayer && (layer instanceof L.TileLayer)) {
this._tileLayersNum++;
this._tileLayersToLoad++;
layer.on('load', this._onTileLayerLoad, this);
}
if (this._loaded) {
this._layerAdd(layer);
}
layer.addTo(this);
return this;
},
removeLayer: function (layer) {
var id = L.stamp(layer);
if (!this._layers[id]) { return this; }
if (this._loaded) {
layer.onRemove(this);
}
delete this._layers[id];
if (this._loaded) {
this.fire('layerremove', {layer: layer});
}
if (this._zoomBoundLayers[id]) {
delete this._zoomBoundLayers[id];
this._updateZoomLevels();
}
// TODO looks ugly, refactor
if (this.options.zoomAnimation && L.TileLayer && (layer instanceof L.TileLayer)) {
this._tileLayersNum--;
this._tileLayersToLoad--;
layer.off('load', this._onTileLayerLoad, this);
}
layer.removeFrom(this);
return this;
},
@ -568,14 +518,11 @@ L.Map = L.Class.extend({
this._initialTopLeftPoint._add(this._getMapPanePos());
}
this._tileLayersToLoad = this._tileLayersNum;
var loading = !this._loaded;
this._loaded = true;
if (loading) {
this.fire('load');
this.eachLayer(this._layerAdd, this);
}
this.fire('viewreset', {hard: !preserveMapOffset});
@ -698,13 +645,6 @@ L.Map = L.Class.extend({
});
},
_onTileLayerLoad: function () {
this._tileLayersToLoad--;
if (this._tileLayersNum && !this._tileLayersToLoad) {
this.fire('tilelayersload');
}
},
_clearHandlers: function () {
for (var i = 0, len = this._handlers.length; i < len; i++) {
this._handlers[i].disable();
@ -720,11 +660,6 @@ L.Map = L.Class.extend({
return this;
},
_layerAdd: function (layer) {
layer.onAdd(this);
this.fire('layeradd', {layer: layer});
},
// private methods for getting map state