PageSourceSearch

https://24geo.ru/static/leaflet.plugins/Leaflet.IconLayers/src/iconLayers.js

js 24geo.ru collected 2026-09-24 10:52:54 UTC 11,480 bytes, 310 lines download raw bytes

1/*eslint-env commonjs, browser */
2(function(factory) {
3    if (typeof module !== 'undefined' && module.exports) {
4        module.exports = factory(require('leaflet'));
5    } else {
6        window.L.control.iconLayers = factory(window.L);
7        window.L.Control.IconLayers = window.L.control.iconLayers.Constructor;
8    }
9})(function(L) {
10    function each(o, cb) {
11        for (var p in o) {
12            if (o.hasOwnProperty(p)) {
13                cb(o[p], p, o);
14            }
15        }
16    }
17
18    function find(ar, cb) {
19        if (ar.length) {
20            for (var i = 0; i < ar.length; i++) {
21                if (cb(ar[i])) {
22                    return ar[i];
23                }
24            }
25        } else {
26            for (var p in ar) {
27                if (ar.hasOwnProperty(p) && cb(ar[p])) {
28                    return ar[p];
29                }
30            }
31        }
32    }
33
34    function first(o) {
35        for (var p in o) {
36            if (o.hasOwnProperty(p)) {
37                return o[p];
38            }
39        }
40    }
41
42    function length(o) {
43        var length = 0;
44        for (var p in o) {
45            if (o.hasOwnProperty(p)) {
46                length++;
47            }
48        }
49        return length;
50    }
51
52    function prepend(parent, el) {
53        if (parent.children.length) {
54            parent.insertBefore(el, parent.children[0]);
55        } else {
56            parent.appendChild(el);
57        }
58    }
59
60    var IconLayers = L.Control.extend({
61        includes: L.Mixin.Events,
62        _getActiveLayer: function() {
63            if (this._activeLayerId) {
64                return this._layers[this._activeLayerId];
65            } else if (length(this._layers)) {
66                return first(this._layers);
67            } else {
68                return null;
69            }
70        },
71        _getPreviousLayer: function() {
72            var activeLayer = this._getActiveLayer();
73            if (!activeLayer) {
74                return null;
75            } else if (this._previousLayerId) {
76                return this._layers[this._previousLayerId];
77            } else {
78                return find(this._layers, function(l) {
79                    return l.id !== activeLayer.id;
80                }.bind(this)) || null;
81            }
82        },
83        _getInactiveLayers: function() {
84            var ar = [];
85            var activeLayerId = this._getActiveLayer() ? this._getActiveLayer().id : null;
86            var previousLayerId = this._getPreviousLayer() ? this._getPreviousLayer().id : null;
87            each(this._layers, function(l) {
88                if ((l.id !== activeLayerId) && (l.id !== previousLayerId)) {
89                    ar.push(l);
90                }
91            });
92            return ar;
93        },
94        _arrangeLayers: function() {
95            var behaviors = {};
96            behaviors.previous = function() {
97                var layers = this._getInactiveLayers();
98                if (this._getActiveLayer()) {
99                    layers.unshift(this._getActiveLayer());
100                }
101                if (this._getPreviousLayer()) {
102                    layers.unshift(this._getPreviousLayer());
103                }
104                return layers;
105            };
106            return behaviors[this.options.behavior].apply(this, arguments);
107        },
108        _getLayerCellByLayerId: function(id) {
109            var els = this._container.getElementsByClassName('leaflet-iconLayers-layerCell');
110            for (var i = 0; i < els.length; i++) {
111                if (els[i].getAttribute('data-layerid') == id) {
112                    return els[i];
113                }
114            }
115        },
116        _createLayerElement: function(layerObj) {
117            var el = L.DomUtil.create('div', 'leaflet-iconLayers-layer');
118            if (layerObj.title) {
119                var titleContainerEl = L.DomUtil.create('div', 'leaflet-iconLayers-layerTitleContainer');
120                var titleEl = L.DomUtil.create('div', 'leaflet-iconLayers-layerTitle');
121                var checkIconEl = L.DomUtil.create('div', 'leaflet-iconLayers-layerCheckIcon');
122                titleEl.innerHTML = layerObj.title;
123                titleContainerEl.appendChild(titleEl);
124                el.appendChild(titleContainerEl);
125                el.appendChild(checkIconEl);
126            }
127            if (layerObj.icon) {
128                el.setAttribute('style', 'background-image: url(\'' + layerObj.icon + '\')');
129            }
130            return el;
131        },
132        _createLayerElements: function() {
133            var currentRow, layerCell;
134            var layers = this._arrangeLayers();
135            var activeLayerId = this._getActiveLayer() && this._getActiveLayer().id;
136
137            for (var i = 0; i < layers.length; i++) {
138                if (i % this.options.maxLayersInRow === 0) {
139                    currentRow = L.DomUtil.create('div', 'leaflet-iconLayers-layersRow');
140                    if (this.options.position.indexOf('bottom') === -1) {
141                        this._container.appendChild(currentRow);
142                    } else {
143                        prepend(this._container, currentRow);
144                    }
145                }
146                layerCell = L.DomUtil.create('div', 'leaflet-iconLayers-layerCell');
147                layerCell.setAttribute('data-layerid', layers[i].id);
148                if (i !== 0) {
149                    L.DomUtil.addClass(layerCell, 'leaflet-iconLayers-layerCell_hidden');
150                }
151                if (layers[i].id === activeLayerId) {
152                    L.DomUtil.addClass(layerCell, 'leaflet-iconLayers-layerCell_active');
153                }
154                if (this._expandDirection === 'left') {
155                    L.DomUtil.addClass(layerCell, 'leaflet-iconLayers-layerCell_expandLeft');
156                } else {
157                    L.DomUtil.addClass(layerCell, 'leaflet-iconLayers-layerCell_expandRight');
158                }
159                layerCell.appendChild(this._createLayerElement(layers[i])
159);
160
161                if (this.options.position.indexOf('right') === -1) {
162                    currentRow.appendChild(layerCell);
163                } else {
164                    prepend(currentRow, layerCell);
165                }
166            }
167        },
168        _onLayerClick: function(e) {
169            e.stopPropagation();
170            var layerId = e.currentTarget.getAttribute('data-layerid');
171            var layer = this._layers[layerId];
172            this.setActiveLayer(layer.layer);
173            this.expand();
174        },
175        _attachEvents: function() {
176            each(this._layers, function(l) {
177                var e = this._getLayerCellByLayerId(l.id);
178                if (e) {
179                    e.addEventListener('click', this._onLayerClick.bind(this));
180                }
181            }.bind(this));
182            var layersRowCollection = this._container.getElementsByClassName('leaflet-iconLayers-layersRow');
183
184            var onMouseEnter = function(e) {
185                e.stopPropagation();
186                this.expand();
187            }.bind(this);
188
189            var onMouseLeave = function(e) {
190                e.stopPropagation();
191                this.collapse();
192            }.bind(this);
193
194            var stopPropagation = function(e) {
195                e.stopPropagation();
196            };
197
198            //TODO Don't make functions within a loop.
199            for (var i = 0; i < layersRowCollection.length; i++) {
200                var el = layersRowCollection[i];
201                el.addEventListener('mouseenter', onMouseEnter);
202                el.addEventListener('mouseleave', onMouseLeave);
203                el.addEventListener('mousemove', stopPropagation);
204            }
205        },
206        _render: function() {
207            this._container.innerHTML = '';
208            this._createLayerElements();
209            this._attachEvents();
210        },
211        _switchMapLayers: function() {
212            if (!this._map) {
213                return;
214            }
215            var activeLayer = this._getActiveLayer();
216            var previousLayer = this._getPreviousLayer();
217            if (previousLayer) {
218                this._map.removeLayer(previousLayer.layer);
219            } else {
220                each(this._layers, function(layerObject) {
221                    var layer = layerObject.layer;
222                    this._map.removeLayer(layer);
223                }.bind(this));
224            }
225            if (activeLayer) {
226                this._map.addLayer(activeLayer.layer);
227            }
228        },
229        options: {
230            position: 'bottomleft', // one of expanding directions depends on this
231            behavior: 'previous', // may be 'previous', 'expanded' or 'first'
232            expand: 'horizontal', // or 'vertical'
233            autoZIndex: true, // from L.Control.Layers
234            maxLayersInRow: 5,
235            manageLayers: true
236        },
237        initialize: function(layers, options) {
238            if (!L.Util.isArray(arguments[0])) {
239                // first argument is options
240                options = layers;
241                layers = [];
242            }
243            L.setOptions(this, options);
244            this._expandDirection = (this.options.position.indexOf('left') != -1) ? 'right' : 'left';
245            if (this.options.manageLayers) {
246                this.on('activelayerchange', this._switchMapLayers, this);
247            }
248            this.setLayers(layers);
249        },
250        onAdd: function(map) {
251            this._container = L.DomUtil.create('div', 'leaflet-iconLayers');
252            L.DomUtil.addClass(this._container, 'leaflet-iconLayers_' + this.options.position);
253            this._render();
254            map.on('click', this.collapse, this);
255            if (this.options.manageLayers) {
256                this._switchMapLayers();
257            }
258            return this._container;
259        },
260        onRemove: function(map) {
261            map.off('click', this.collapse, this);
262        },
263        setLayers: function(layers) {
264            this._layers = {};
265            layers.map(function(layer) {
266                var id = L.stamp(layer.layer);
267                this._layers[id] = L.extend(layer, {
268                    id: id
269                });
270            }.bind(this));
271            if (this._container) {
272                this._render();
273            }
274        },
275        setActiveLayer: function(layer) {
276            var l = layer && this._layers[L.stamp(layer)];
277            if (!l || l.id === this._activeLayerId) {
278                return;
279            }
280            this._previousLayerId = this._activeLayerId;
281            this._activeLayerId = l.id;
282            if (this._container) {
283                this._render();
284            }
285            this.fire('activelayerchange', {
286                layer: layer
287            });
288        },
289        expand: function() {
290            this._arrangeLayers().slice(1).map(function(l) {
291                var el = this._getLayerCellByLayerId(l.id);
292                L.DomUtil.removeClass(el, 'leaflet-iconLayers-layerCell_hidden');
293            }.bind(this));
294        },
295        collapse: function() {
296            this._arrangeLayers().slice(1).map(function(l) {
297                var el = this._getLayerCellByLayerId(l.id);
298                L.DomUtil.addClass(el, 'leaflet-iconLayers-layerCell_hidden');
299            }.bind(this));
300        }
301    });
302
303    var iconLayers = function(layers, options) {
304        return new IconLayers(layers, options);
305    };
306
307    iconLayers.Constructor = IconLayers;
308
309    return iconLayers;
310});

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.