UNPKG

mapbox-gl

Version:
119 lines (94 loc) 3.7 kB
'use strict'; const DOM = require('../../util/dom'); const util = require('../../util/util'); /** * An `AttributionControl` control presents the map's [attribution information](https://www.mapbox.com/help/attribution/). * * @implements {IControl} * @param {Object} [options] * @param {boolean} [options.compact] If `true` force a compact attribution that shows the full attribution on mouse hover, or if `false` force the full attribution control. The default is a responsive attribution that collapses when the map is less than 640 pixels wide. * @example * var map = new mapboxgl.Map({attributionControl: false}) * .addControl(new mapboxgl.AttributionControl({ * compact: true * })); */ class AttributionControl { constructor(options) { this.options = options; util.bindAll([ '_updateEditLink', '_updateData', '_updateCompact' ], this); } getDefaultPosition() { return 'bottom-right'; } onAdd(map) { const compact = this.options && this.options.compact; this._map = map; this._container = DOM.create('div', 'mapboxgl-ctrl mapboxgl-ctrl-attrib'); if (compact) { this._container.classList.add('compact'); } this._updateAttributions(); this._updateEditLink(); this._map.on('sourcedata', this._updateData); this._map.on('moveend', this._updateEditLink); if (compact === undefined) { this._map.on('resize', this._updateCompact); this._updateCompact(); } return this._container; } onRemove() { this._container.parentNode.removeChild(this._container); this._map.off('sourcedata', this._updateData); this._map.off('moveend', this._updateEditLink); this._map.off('resize', this._updateCompact); this._map = undefined; } _updateEditLink() { if (!this._editLink) this._editLink = this._container.querySelector('.mapbox-improve-map'); if (this._editLink) { const center = this._map.getCenter(); this._editLink.href = `https://www.mapbox.com/map-feedback/#/${ center.lng}/${center.lat}/${Math.round(this._map.getZoom() + 1)}`; } } _updateData(e) { if (e && e.sourceDataType === 'metadata') { this._updateAttributions(); this._updateEditLink(); } } _updateAttributions() { if (!this._map.style) return; let attributions = []; const sourceCaches = this._map.style.sourceCaches; for (const id in sourceCaches) { const source = sourceCaches[id].getSource(); if (source.attribution && attributions.indexOf(source.attribution) < 0) { attributions.push(source.attribution); } } // remove any entries that are substrings of another entry. // first sort by length so that substrings come first attributions.sort((a, b) => a.length - b.length); attributions = attributions.filter((attrib, i) => { for (let j = i + 1; j < attributions.length; j++) { if (attributions[j].indexOf(attrib) >= 0) { return false; } } return true; }); this._container.innerHTML = attributions.join(' | '); // remove old DOM node from _editLink this._editLink = null; } _updateCompact() { const compact = this._map.getCanvasContainer().offsetWidth <= 640; this._container.classList[compact ? 'add' : 'remove']('compact'); } } module.exports = AttributionControl;