When a layer is repeated in Control.Layers, behavior is not consistent. (#5672)

* Check if the map has a layer after layers removal, not before.

* fix wrong layer to add

* do symetric code with removedLayers and addedLayers

* add unit test for repeated layers
This commit is contained in:
Javier Jimenez Shaw 2017-07-31 09:20:40 +02:00 committed by Per Liedman
parent 0d36e46dc6
commit 922593addb
2 changed files with 36 additions and 7 deletions

View File

@ -130,6 +130,33 @@ describe("Control.Layers", function () {
expect(layers._layers.length).to.be.equal(1);
});
it("having repeated layers works as expected", function () {
document.body.appendChild(map._container);
var layerA = L.tileLayer(''), layerB = L.tileLayer(''),
baseLayers = {"Layer 1": layerA, "Layer 2": layerB, "Layer 3": layerA},
layers = L.control.layers(baseLayers).addTo(map);
function checkInputs(idx) {
var inputs = map._container.querySelectorAll('.leaflet-control-layers-base input');
for (var i = 0; i < inputs.length; i++) {
expect(inputs[i].checked === (idx === i)).to.be.ok();
}
}
happen.click(layers._baseLayersList.getElementsByTagName("input")[1]);
checkInputs(1);
expect(map._layers[L.Util.stamp(layerB)]).to.be.equal(layerB);
expect(map._layers[L.Util.stamp(layerA)]).to.be.equal(undefined);
happen.click(layers._baseLayersList.getElementsByTagName("input")[0]);
checkInputs(0);
expect(map._layers[L.Util.stamp(layerA)]).to.be.equal(layerA);
expect(map._layers[L.Util.stamp(layerB)]).to.be.equal(undefined);
happen.click(layers._baseLayersList.getElementsByTagName("input")[2]);
checkInputs(2);
expect(map._layers[L.Util.stamp(layerA)]).to.be.equal(layerA);
expect(map._layers[L.Util.stamp(layerB)]).to.be.equal(undefined);
});
});
describe("is removed cleanly", function () {

View File

@ -362,7 +362,7 @@ export var Layers = Control.extend({
_onInputClick: function () {
var inputs = this._layerControlInputs,
input, layer, hasLayer;
input, layer;
var addedLayers = [],
removedLayers = [];
@ -371,22 +371,24 @@ export var Layers = Control.extend({
for (var i = inputs.length - 1; i >= 0; i--) {
input = inputs[i];
layer = this._getLayer(input.layerId).layer;
hasLayer = this._map.hasLayer(layer);
if (input.checked && !hasLayer) {
if (input.checked) {
addedLayers.push(layer);
} else if (!input.checked && hasLayer) {
} else if (!input.checked) {
removedLayers.push(layer);
}
}
// Bugfix issue 2318: Should remove all old layers before readding new ones
for (i = 0; i < removedLayers.length; i++) {
this._map.removeLayer(removedLayers[i]);
if (this._map.hasLayer(removedLayers[i])) {
this._map.removeLayer(removedLayers[i]);
}
}
for (i = 0; i < addedLayers.length; i++) {
this._map.addLayer(addedLayers[i]);
if (!this._map.hasLayer(addedLayers[i])) {
this._map.addLayer(addedLayers[i]);
}
}
this._handlingClick = false;