1/* global L */ 2 3// A layer control which provides for layer groupings. 4// Author: Ishmael Smyrnow 5L.Control.GroupedLayers = L.Control.extend({ 6 7 options: { 8 collapsed: true, 9 position: 'topright', 10 autoZIndex: true 11 }, 12 13 initialize: function (baseLayers, groupedOverlays, options) { 14 var i, j; 15 L.Util.setOptions(this, options); 16 17 this._layers = {}; 18 this._lastZIndex = 0; 19 this._handlingClick = false; 20 this._groupList = []; 21 this._domGroups = []; 22 23 for (i in baseLayers) { 24 this._addLayer(baseLayers[i], i); 25 } 26 27 for (i in groupedOverlays) { 28 for (var j in groupedOverlays[i]) { 29 this._addLayer(groupedOverlays[i][j], j, i, true); 30 } 31 } 32 }, 33 34 onAdd: function (map) { 35 this._initLayout(); 36 this._update(); 37 38 map 39 .on('layeradd', this._onLayerChange, this) 40 .on('layerremove', this._onLayerChange, this); 41 42 return this._container; 43 }, 44 45 onRemove: function (map) { 46 map 47 .off('layeradd', this._onLayerChange) 48 .off('layerremove', this._onLayerChange); 49 }, 50 51 addBaseLayer: function (layer, name) { 52 this._addLayer(layer, name); 53 this._update(); 54 return this; 55 }, 56 57 addOverlay: function (layer, name, group) { 58 this._addLayer(layer, name, group, true); 59 this._update(); 60 return this; 61 }, 62 63 removeLayer: function (layer) { 64 var id = L.Util.stamp(layer); 65 delete this._layers[id]; 66 this._update(); 67 return this; 68 }, 69 70 _initLayout: function () { 71 var className = 'leaflet-control-layers', 72 container = this._container = L.DomUtil.create('div', className); 73 74 //Makes this work on IE10 Touch devices by stopping it from firing a mouseout event when the touch is released 75 container.setAttribute('aria-haspopup', true); 76 77 if (!L.Browser.touch) { 78 L.DomEvent.disableClickPropagation(container); 79 L.DomEvent.on(container, 'wheel', L.DomEvent.stopPropagation); 80 } else { 81 L.DomEvent.on(container, 'click', L.DomEvent.stopPropagation); 82 } 83 84 var form = this._form = L.DomUtil.create('form', className + '-list'); 85 86 if (this.options.collapsed) { 87 if (!L.Browser.android) { 88 L.DomEvent 89 .on(container, 'mouseover', this._expand, this) 90 .on(container, 'mouseout', this._collapse, this); 91 } 92 var link = this._layersLink = L.DomUtil.create('a', className + '-toggle', container); 93 link.href = '#'; 94 link.title = 'Layers'; 95 96 if (L.Browser.touch) { 97 L.DomEvent 98 .on(link, 'click', L.DomEvent.stop) 99 .on(link, 'click', this._expand, this); 100 } 101 else { 102 L.DomEvent.on(link, 'focus', this._expand, this); 103 } 104 105 this._map.on('click', this._collapse, this); 106 // TODO keyboard accessibility 107 } else { 108 this._expand(); 109 } 110 111 this._baseLayersList = L.DomUtil.create('div', className + '-base', form); 112 this._separator = L.DomUtil.create('div', className + '-separator', form); 113 this._overlaysList = L.DomUtil.create('div', className + '-overlays', form); 114 115 container.appendChild(form); 116 }, 117 118 _addLayer: function (layer, name, group, overlay) { 119 var id = L.Util.stamp(layer); 120 121 this._layers[id] = { 122 layer: layer, 123 name: name, 124 overlay: overlay 125 }; 126 127 if (group) { 128 var groupId = this._groupList.indexOf(group); 129 130 if (groupId === -1) { 131 groupId = this._groupList.push(group) - 1; 132 } 133 134 this._layers[id].group = { 135 name: group, 136 id: groupId 137 }; 138 } 139 140 if (this.options.autoZIndex && layer.setZIndex) { 141 this._lastZIndex++; 142 layer.setZIndex(this._lastZIndex); 143 } 144 }, 145 146 _update: function () { 147 if (!this._container) { 148 return; 149 } 150 151 this._baseLayersList.innerHTML = ''; 152 this._overlaysList.innerHTML = ''; 153 this._domGroups.length = 0; 154 155 var baseLayersPresent = false, 156 overlaysPresent = false, 157 i, obj; 158 159 for (i in this._layers) { 160 obj = this._layers[i]; 161 this._addItem(obj); 162 overlaysPresent = overlaysPresent || obj.overlay; 163 baseLayersPresent = baseLayersPresent || !obj.overlay; 164 } 165 166 this._separator.style.display = overlaysPresent && baseLayersPresent ? '' : 'none'; 167 }, 168 169 _onLayerChange: function (e) { 170 var obj = this._layers[L.Util.stamp(e.layer)]; 171 172 if (!obj) { return; } 173 174 if (!this._handlingClick) { 175 this._update(); 176 } 177 178 var type = obj.overlay ? 179 (e.type === 'layeradd' ? 'overlayadd' : 'overlayremove') : 180 (e.type === 'layeradd' ? 'baselayerchange' : null); 181 182 if (type) { 183 this._map.fire(type, obj); 184 } 185 }, 186 187 // IE7 bugs out if you create a radio dynamically, so you have to do it this hacky way (see http://bit.ly/PqYLBe) 188 _createRadioElement: function (name, checked) { 189 190 var radioHtml = '<input type="radio" class="leaflet-control-layers-selector" name="' + name + '"'; 191 if (checked) { 192 radioHtml += ' checked="checked"'; 193 } 194 radioHtml += '/>'; 195 196 var radioFragment = document.createElement('div'); 197 radioFragment.innerHTML = radioHtml; 198 199 return radioFragment.firstChild; 200 }, 201 202 _addItem: function (obj) { 203 var label = document.createElement('label'), 204 input, 205 checked = this._map.hasLayer(obj.layer), 206 container; 207 208 if (obj.overlay) { 209 input = document.createElement('input'); 210 input.type = 'checkbox'; 211 input.className = 'leaflet-control-layers-selector'; 212 input.defaultChecked = checked; 213 } else { 214 input = this._createRadioElement('leaflet-base-layers', checked); 215 } 216 217 input.layerId = L.Util.stamp(obj.layer); 218 219 L.DomEvent.on(input, 'click', this._onInputClick, this); 220 221 var name = document.createElement('span'); 222 name.innerHTML = ' ' + obj.name; 223 224 label.appendChild(input); 225 label.appendChild(name); 226 227 if (obj.overlay) { 228 container = this._overlaysList; 229 230 var groupContainer = this._domGroups[obj.group.id]; 231 232 // Create the group container if it doesn't exist 233 if (!groupContainer) { 234 groupContainer = document.createElement('div'); 235 groupContainer.className = 'leaflet-control-layers-group'; 236 groupContainer.id = 'leaflet-control-layers-group-' + obj.group.id; 237 238 var groupLabel = document.createElement('span'); 239 groupLabel.className = 'leaflet-control-layers-group-name';
240 groupLabel.innerHTML = obj.group.name; 241 242 groupContainer.appendChild(groupLabel); 243 container.appendChild(groupContainer); 244 245 this._domGroups[obj.group.id] = groupContainer; 246 } 247 248 container = groupContainer; 249 } else { 250 container = this._baseLayersList; 251 } 252 253 container.appendChild(label); 254 255 return label; 256 }, 257 258 _onInputClick: function () { 259 var i, input, obj, 260 inputs = this._form.getElementsByTagName('input'), 261 inputsLen = inputs.length; 262 263 this._handlingClick = true; 264 265 for (i = 0; i < inputsLen; i++) { 266 input = inputs[i]; 267 obj = this._layers[input.layerId]; 268 269 if (input.checked && !this._map.hasLayer(obj.layer)) { 270 this._map.addLayer(obj.layer); 271 272 } else if (!input.checked && this._map.hasLayer(obj.layer)) { 273 this._map.removeLayer(obj.layer); 274 } 275 } 276 277 this._handlingClick = false; 278 }, 279 280 _expand: function () { 281 L.DomUtil.addClass(this._container, 'leaflet-control-layers-expanded'); 282 }, 283 284 _collapse: function () { 285 this._container.className = this._container.className.replace(' leaflet-control-layers-expanded', ''); 286 } 287}); 288 289L.control.groupedLayers = function (baseLayers, groupedOverlays, options) { 290 return new L.Control.GroupedLayers(baseLayers, groupedOverlays, options); 291};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.