Skip to content

Commit

Permalink
Fix - Esri Attribution not removed when VectorBasemapLayer is removed (
Browse files Browse the repository at this point in the history
…#208)

* fix: add / remove attribution

* fix broken tests

* fix: add a call to removeEsriAttribution method

this method removes the "Powered by Esri" attribution

* add a test to onRemove-attribution scenario

* Update esri-leaflet version

* check if function exists before calling it

+ avoid error when using previous versions of esri-leaflet that do not contain the function
  • Loading branch information
BrunoCaimar committed Dec 20, 2023
1 parent 4743313 commit 4462d7d
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 8 deletions.
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 @@ -249,4 +250,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 @@ -83,7 +83,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 @@ -148,12 +148,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

0 comments on commit 4462d7d

Please sign in to comment.