diff --git a/package-lock.json b/package-lock.json index 6c5a2e0..8955009 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3330,9 +3330,9 @@ } }, "node_modules/esri-leaflet": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/esri-leaflet/-/esri-leaflet-3.0.8.tgz", - "integrity": "sha512-mLb4pRfDAbkG1YhuajD22erLXIAtrF1R32hmgmlJNI3t47n6KjTppCb8lViia0O7+GDORXFuJ9Lj9RkpsaKhSA==", + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/esri-leaflet/-/esri-leaflet-3.0.12.tgz", + "integrity": "sha512-Yi7oH/mK4quOlCe920yuEYvUk0BjJRjmmE78ReAdJT5EbibW5wJoT9DtvG3JEJD22mQ0oF1LhcfL0Wb5jRhDAQ==", "dev": true, "dependencies": { "@terraformer/arcgis": "^2.1.0", @@ -11793,9 +11793,9 @@ } }, "esri-leaflet": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/esri-leaflet/-/esri-leaflet-3.0.8.tgz", - "integrity": "sha512-mLb4pRfDAbkG1YhuajD22erLXIAtrF1R32hmgmlJNI3t47n6KjTppCb8lViia0O7+GDORXFuJ9Lj9RkpsaKhSA==", + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/esri-leaflet/-/esri-leaflet-3.0.12.tgz", + "integrity": "sha512-Yi7oH/mK4quOlCe920yuEYvUk0BjJRjmmE78ReAdJT5EbibW5wJoT9DtvG3JEJD22mQ0oF1LhcfL0Wb5jRhDAQ==", "dev": true, "requires": { "@terraformer/arcgis": "^2.1.0", diff --git a/spec/VectorBasemapLayerSpec.js b/spec/VectorBasemapLayerSpec.js index 1b6ccbc..a8e0fe9 100644 --- a/spec/VectorBasemapLayerSpec.js +++ b/spec/VectorBasemapLayerSpec.js @@ -1,3 +1,4 @@ + /* eslint-env mocha */ const itemId = '287c07ef752246d08bb4712fd4b74438'; const apikey = '1234'; @@ -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(''); + }); + + 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 = '@ my attribution, @ my copyright text'; + 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: '
' }]; + }); + + layer.onRemove(fakeMap); + document.getElementsByClassName.restore(); + + expect(utilSpy.calledWith(fakeMap)).to.be.true; + expect(attributionControlSpy.removeAttribution.callCount).to.be.equal(2); + }); + }); }); diff --git a/src/VectorBasemapLayer.js b/src/VectorBasemapLayer.js index 0b56a39..cb3f518 100644 --- a/src/VectorBasemapLayer.js +++ b/src/VectorBasemapLayer.js @@ -83,7 +83,7 @@ export var VectorBasemapLayer = VectorTileLayer.extend({ } }); - this._map.attributionControl.addAttribution('' + allAttributions.join(', ') + ''); + this._map.attributionControl.addAttribution(`${allAttributions.join(', ')}`); } else { // this is an enum if (!this.options.attributionUrls) { @@ -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(''); } } },