L.Control.Layers = L.Class.extend({ options: { collapsed: !L.Browser.touch }, initialize: function (baseLayers, overlays, options) { L.Util.setOptions(this, options); this._layers = {}; for (var i in baseLayers) { if (baseLayers.hasOwnProperty(i)) { this._addLayer(baseLayers[i], i); } } for (i in overlays) { if (overlays.hasOwnProperty(i)) { this._addLayer(overlays[i], i, true); } } }, onAdd: function (map) { this._map = map; this._initLayout(); this._update(); }, getContainer: function () { return this._container; }, getPosition: function () { return L.Control.Position.TOP_RIGHT; }, addBaseLayer: function (layer, name) { this._addLayer(layer, name); this._update(); return this; }, addOverlay: function (layer, name) { this._addLayer(layer, name, true); this._update(); return this; }, removeLayer: function (layer) { var id = L.Util.stamp(layer); delete this._layers[id]; this._update(); return this; }, _initLayout: function () { this._container = L.DomUtil.create('div', 'leaflet-control-layers'); L.DomEvent.disableClickPropagation(this._container); this._form = L.DomUtil.create('form', 'leaflet-control-layers-list'); if (this.options.collapsed) { L.DomEvent.addListener(this._container, 'mouseover', this._expand, this); L.DomEvent.addListener(this._container, 'mouseout', this._collapse, this); var link = this._layersLink = L.DomUtil.create('a', 'leaflet-control-layers-toggle'); link.href = '#'; link.title = 'Layers'; L.DomEvent.addListener(link, 'focus', this._expand, this); L.DomEvent.addListener(this._map, L.Draggable.START, this._collapse, this); // TODO keyboard accessibility this._container.appendChild(link); } else { this._expand(); } this._baseLayersList = L.DomUtil.create('div', 'leaflet-control-layers-base', this._form); this._separator = L.DomUtil.create('div', 'leaflet-control-layers-separator', this._form); this._overlaysList = L.DomUtil.create('div', 'leaflet-control-layers-overlays', this._form); this._container.appendChild(this._form); }, _addLayer: function (layer, name, overlay) { var id = L.Util.stamp(layer); this._layers[id] = { layer: layer, name: name, overlay: overlay }; }, _update: function () { if (!this._container) { return; } this._baseLayersList.innerHTML = ''; this._overlaysList.innerHTML = ''; var baseLayersPresent = false, overlaysPresent = false; for (var i in this._layers) { if (this._layers.hasOwnProperty(i)) { var obj = this._layers[i]; this._addItem(obj); overlaysPresent = overlaysPresent || obj.overlay; baseLayersPresent = baseLayersPresent || !obj.overlay; } } this._separator.style.display = (overlaysPresent && baseLayersPresent ? '' : 'none'); }, _addItem: function (obj, onclick) { var label = document.createElement('label'); var input = document.createElement('input'); if (!obj.overlay) { input.name = 'leaflet-base-layers'; } input.type = obj.overlay ? 'checkbox' : 'radio'; input.checked = this._map.hasLayer(obj.layer); input.layerId = L.Util.stamp(obj.layer); L.DomEvent.addListener(input, 'click', this._onInputClick, this); var name = document.createTextNode(' ' + obj.name); label.appendChild(input); label.appendChild(name); var container = obj.overlay ? this._overlaysList : this._baseLayersList; container.appendChild(label); }, _onInputClick: function () { var i, input, obj, inputs = this._form.getElementsByTagName('input'), inputsLen = inputs.length; for (i = 0; i < inputsLen; i++) { input = inputs[i]; obj = this._layers[input.layerId]; if (input.checked) { this._map.addLayer(obj.layer, !obj.overlay); } else { this._map.removeLayer(obj.layer); } } }, _expand: function () { L.DomUtil.addClass(this._container, 'leaflet-control-layers-expanded'); }, _collapse: function () { this._container.className = this._container.className.replace(' leaflet-control-layers-expanded', ''); } });