diff --git a/spec/suites/map/MapSpec.js b/spec/suites/map/MapSpec.js index 122bba96..064f1f0e 100644 --- a/spec/suites/map/MapSpec.js +++ b/spec/suites/map/MapSpec.js @@ -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(); diff --git a/src/layer/Layer.js b/src/layer/Layer.js index 89f244c2..be91af7e 100644 --- a/src/layer/Layer.js +++ b/src/layer/Layer.js @@ -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]; diff --git a/src/map/Map.js b/src/map/Map.js index fe078f73..2a12a302 100644 --- a/src/map/Map.js +++ b/src/map/Map.js @@ -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