import { createEl } from '../core/util/dom';
import Control, { ControlOptionsType } from './Control';
import Map from '../map/Map';
import { isString } from '../core/util';
/**
* @property {Object} options - options
* @property {Object} [options.position='bottom-left'] - position of the control, this option defined in [Control.position]{@link Control#positions}.
* @property {String} [options.content='Powered by maptalks'] - content of the attribution control, HTML format
* @memberOf control.Attribution
* @instance
*/
const options: AttributionOptionsType = {
'position': {
'bottom': 0,
'left': 0
},
'content': 'maptalks',
'custom': false
};
const layerEvents = 'addlayer removelayer setbaselayer baselayerremove';
/**
* @classdesc
* A control to allows to display attribution content in a small text box on the map.
* @category control
* @extends control.Control
* @memberOf control
* @example
* var map = new maptalks.Map('map', {
* center: [-0.113049, 51.498568],
* zoom: 14,
* attribution: {
* content : 'my attribution',
* position : 'bottom-left'
* },
* baseLayer: new maptalks.TileLayer('base', {
* urlTemplate: 'http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png',
* subdomains: ['a','b','c','d'],
* attribution: '© OpenStreetMap contributors, © CARTO'
* })
* });
* map.addLayer(new maptalks.TileLayer('base', {
* urlTemplate: 'http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png',
* subdomains: ['a','b','c','d'],
* attribution: '© OpenStreetMap contributors, © CARTO'
* }));
*/
class Attribution extends Control {
//@internal
_attributionContainer: HTMLDivElement;
buildOn() {
this._attributionContainer = createEl('div') as HTMLDivElement;
this._attributionContainer.className = 'maptalks-attribution';
this._appendCustomClass(this._attributionContainer);
this._update();
return this._attributionContainer;
}
getContent() {
return this.options.content;
}
setContent(content: string | HTMLElement) {
this.options.content = content;
this._update();
return this;
}
onAdd() {
this.getMap().on(layerEvents, this._update, this);
}
onRemove() {
this.getMap().off(layerEvents, this._update, this);
}
//@internal
_updateContent() {
const container = this._attributionContainer;
const content = this.options.content || '';
if (container) {
//clear
container.innerHTML = '';
if (isString(content)) {
container.innerHTML = content;
} else if (content instanceof HTMLElement) {
container.appendChild(container);
}
}
return this;
}
//@internal
_update() {
if (this.options.custom) {
this._updateContent();
return;
}
const map = this.getMap();
if (!map) {
return;
}
const attributions = map
._getLayers(layer => !!layer.options['attribution'])
.reverse()
.map(layer => layer.options['attribution']);
const content = this.options['content'] + (attributions.length > 0 ? ' - ' + attributions.join(', ') : '');
this._attributionContainer.innerHTML = '' + content + '';
}
}
Attribution.mergeOptions(options);
Map.mergeOptions({
'attribution': true
});
Map.addOnLoadHook(function () {
const a = this.options['attribution'] || this.options['attributionControl'];
if (a) {
this.attributionControl = new Attribution(a);
this.addControl(this.attributionControl);
}
});
export default Attribution;
export type AttributionOptionsTypeSpec = {
content?: string | HTMLElement;
custom?: boolean;
};
export type AttributionOptionsType = AttributionOptionsTypeSpec & ControlOptionsType;