Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix - Esri Attribution not removed when VectorBasemapLayer is removed #208

Merged
merged 8 commits into from
Dec 20, 2023
12 changes: 6 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

99 changes: 99 additions & 0 deletions spec/VectorBasemapLayerSpec.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

/* eslint-env mocha */
const itemId = '287c07ef752246d08bb4712fd4b74438';
const apikey = '1234';
Expand Down Expand Up @@ -225,4 +226,102 @@ describe('VectorBasemapLayer', function () {
expect(attributionUrls[0]).to.equal('https://static.arcgis.com/attribution/Vector/World_Basemap_v2');
});
});

describe('_setupAttribution', function () {
it('should add attribution for non itemId item', function () {
const key = 'ArcGIS:Streets';
const layer = new L.esri.Vector.VectorBasemapLayer(key, {
token: apikey
});
layer._ready = false;
let attributionValue = '';
const fakeMap = {
attributionControl: {
setPrefix: function () {},
_container: { className: '', querySelector: () => {} },
addAttribution: function () {
attributionValue = arguments[0];
}
},
getSize: function () {
return { x: 0, y: 0 };
},
on: function () {}
};
layer.onAdd(fakeMap);
layer._setupAttribution();
expect(attributionValue).to.be.equal('<span class="esri-dynamic-attribution"></span>');
});

it('should add attribution for itemId item', function () {
const key = '3e1a00aeae81496587988075fe529f71';
const layer = new L.esri.Vector.VectorBasemapLayer(key, {
token: apikey
});
layer._ready = false;
let attributionValue = '?';
const fakeMap = {
attributionControl: {
setPrefix: function () {},
_container: { className: '', querySelector: () => {} },
addAttribution: function () {
attributionValue = arguments[0];
}
},
getSize: function () {
return { x: 0, y: 0 };
},
on: function () {}
};
layer.onAdd(fakeMap);
layer._maplibreGL.getMaplibreMap = function () {
return {
style: {
stylesheet: {
sources: {
one: {
attribution: '@ my attribution',
copyrightText: '@ my copyright text'
}
}
}
}
};
};

layer._setupAttribution();
const expectedAttributionValue = '<span class="esri-dynamic-attribution">@ my attribution, @ my copyright text</span>';
expect(attributionValue).to.be.equal(expectedAttributionValue);
});
});

describe('onRemove', function () {
it('should call esri-leaflet and attributionControl remove attribution methods', function () {
const key = 'ArcGIS:Streets';
const layer = new L.esri.Vector.VectorBasemapLayer(key, {
token: apikey
});
layer._ready = false;
const fakeMap = {
attributionControl: {
removeAttribution: function () {}
},
off: function () {},
removeLayer: function () {}
};

const attributionControlSpy = sinon.spy(fakeMap.attributionControl);
const utilSpy = sinon.spy(L.esri.Util, 'removeEsriAttribution');

sinon.stub(document, 'getElementsByClassName').callsFake(function () {
return [{ outerHTML: '<div>' }];
});

layer.onRemove(fakeMap);
document.getElementsByClassName.restore();

expect(utilSpy.calledWith(fakeMap)).to.be.true;
expect(attributionControlSpy.removeAttribution.callCount).to.be.equal(2);
});
});
});
9 changes: 7 additions & 2 deletions src/VectorBasemapLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export var VectorBasemapLayer = VectorTileLayer.extend({
}
});

this._map.attributionControl.addAttribution('<span class="">' + allAttributions.join(', ') + '</span>');
this._map.attributionControl.addAttribution(`<span class="esri-dynamic-attribution">${allAttributions.join(', ')}</span>`);
} else {
// this is an enum
if (!this.options.attributionUrls) {
Expand Down Expand Up @@ -138,12 +138,17 @@ export var VectorBasemapLayer = VectorTileLayer.extend({
map.removeLayer(this._maplibreGL);

if (map.attributionControl) {
if (Util.removeEsriAttribution) Util.removeEsriAttribution(map);

const element = document.getElementsByClassName('esri-dynamic-attribution');

if (element && element.length > 0) {
const vectorAttribution = element[0].outerHTML;
// this doesn't work, not sure why.
// call removeAttribution twice here
// this is needed due to the 2 different ways that addAttribution is called inside _setupAttribution.
// leaflet attributionControl.removeAttribution method ignore a call when the attribution sent is not present there
map.attributionControl.removeAttribution(vectorAttribution);
map.attributionControl.removeAttribution('<span class="esri-dynamic-attribution"></span>');
}
}
},
Expand Down