UNPKG

maplair

Version:

JavaScript library for mobile-friendly interactive maps

148 lines (116 loc) • 4.1 kB
import {Control} from './Control.js'; import * as DomEvent from '../dom/DomEvent.js'; import * as DomUtil from '../dom/DomUtil.js'; import {I18n} from '../core/I18n.js'; const mapleLeaf = '<span aria-hidden="true" class="maplair-attribution-leaf">&#x1F341;</span>'; /* * @class AttributionControl * @inherits Control * * The attribution control allows you to display attribution data in a small text box on a map. It is put on the map by default unless you set its [`attributionControl` option](#map-attributioncontrol) to `false`, and it fetches attribution texts from layers with the [`getAttribution` method](#layer-getattribution) automatically. Extends Control. */ // @namespace AttributionControl // @constructor AttributionControl(options: AttributionControl options) // Creates an attribution control. export class AttributionControl extends Control { static { // @section // @aka AttributionControl options this.setDefaultOptions({ // @option position: String = 'bottomright' // The position of the control (one of the map corners). Possible values are `'topleft'`, // `'topright'`, `'bottomleft'` or `'bottomright'` position: 'bottomright', // @option prefix: String|false = 'Maplair' // The HTML text shown before the attributions. Pass `false` to disable. prefix: null }); } constructor(options) { super(options); if (this.options.prefix === null) { const title = I18n.translate('A JavaScript library for interactive maps'); this.options.prefix = `<a target="_blank" href="https://maplair.org" title="${title}">${mapleLeaf}Maplair</a>`; } this._attributions = {}; this.callInitHooks(AttributionControl); } onAdd(map) { map.attributionControl = this; this._container = DomUtil.create('div', 'maplair-control-attribution'); DomEvent.disableClickPropagation(this._container); // TODO ugly, refactor for (const layer of Object.values(map._layers)) { if (layer.getAttribution) { this.addAttribution(layer.getAttribution()); } } this._update(); map.on('layeradd', this._addAttribution, this); return this._container; } onRemove(map) { map.off('layeradd', this._addAttribution, this); } _addAttribution(ev) { if (ev.layer.getAttribution) { this.addAttribution(ev.layer.getAttribution()); ev.layer.once('remove', () => this.removeAttribution(ev.layer.getAttribution())); } } // @method setPrefix(prefix: String|false): this // The HTML text shown before the attributions. Pass `false` to disable. setPrefix(prefix) { this.options.prefix = prefix; this._update(); return this; } // @method addAttribution(text: String): this // Adds an attribution text (e.g. `'&copy; OpenStreetMap contributors'`). addAttribution(text) { if (!text) { return this; } if (!this._attributions[text]) { this._attributions[text] = 0; } this._attributions[text]++; this._update(); return this; } // @method removeAttribution(text: String): this // Removes an attribution text. removeAttribution(text) { if (!text) { return this; } if (this._attributions[text]) { this._attributions[text]--; this._update(); } return this; } _update() { if (!this._map) { return; } const attribs = Object.keys(this._attributions).filter(i => this._attributions[i]); const prefixAndAttribs = []; if (this.options.prefix) { prefixAndAttribs.push(this.options.prefix); } if (attribs.length) { prefixAndAttribs.push(attribs.join(', ')); } this._container.innerHTML = prefixAndAttribs.join(' <span aria-hidden="true">|</span> '); } // Registers this default feature on the map class, called by `MaplairMap` itself. static register(MaplairMap) { // @namespace MaplairMap // @section Control options // @option attributionControl: Boolean = true // Whether a [attribution control](#control-attribution) is added to the map by default. MaplairMap.mergeOptions({ attributionControl: true }); MaplairMap.addInitHook(function () { if (this.options.attributionControl) { new AttributionControl().addTo(this); } }); } }