nakarte

Source code of https://map.sikmir.ru (fork)
git clone git://git.sikmir.ru/nakarte
Log | Files | Refs | LICENSE

commit e8d651ca4854ceef73561d76308f1990f17ac09e
parent e742fef2557e66913d64ce6818e4308d0efd9e50
Author: Sergej Orlov <wladimirych@gmail.com>
Date:   Wed, 30 Nov 2016 01:56:26 +0300

refactored hash state module and handling in controls to make more consistent

Diffstat:
Msrc/lib/leaflet.control.panoramas/panoramas.js | 50++++++++++++++++++++++++--------------------------
Msrc/lib/leaflet.control.track-list/track-list.hash-state.js | 2+-
Msrc/lib/leaflet.hashState/Leaflet.Control.Layers.js | 14+++++++++++++-
Msrc/lib/leaflet.hashState/Leaflet.Map.js | 4+---
Msrc/lib/leaflet.hashState/hashState.js | 32++++++++++++++++++++------------
Msrc/lib/leaflet.hashState/leaflet.hashState.js | 37+++++++++++++++++++++++++------------
6 files changed, 84 insertions(+), 55 deletions(-)

diff --git a/src/lib/leaflet.control.panoramas/panoramas.js b/src/lib/leaflet.control.panoramas/panoramas.js @@ -167,7 +167,7 @@ L.Control.Panoramas = L.Control.extend({ }, notifyChanged: function() { - this.fire('panoramachanged') + this.fire('panoramachanged'); }, getGoogleApi: function() { @@ -203,45 +203,43 @@ L.Control.Panoramas.include({ serializeState: function() { if (!this.coverageVisible) { - return []; + return null; } const state = []; - if (this.panoramaVisible) { - state.push('1'); - if (this.panoramaPosition && this.panoramaAngle !== undefined) { - state.push(this.panoramaPosition.lat.toFixed(5)); - state.push(this.panoramaPosition.lng.toFixed(5)); - state.push(Math.round(this.panoramaAngle.heading).toFixed()); - state.push(Math.round(this.panoramaAngle.pitch).toFixed()); - state.push(Math.round(this.panoramaAngle.zoom).toFixed(2)); - } - } else { - state.push('0'); + if (this.panoramaVisible && this.panoramaPosition && this.panoramaAngle !== undefined) { + state.push(this.panoramaPosition.lat.toFixed(5)); + state.push(this.panoramaPosition.lng.toFixed(5)); + state.push(Math.round(this.panoramaAngle.heading).toFixed()); + state.push(Math.round(this.panoramaAngle.pitch).toFixed()); + state.push(Math.round(this.panoramaAngle.zoom).toFixed(2)); } return state; }, unserializeState: function(state) { - if (!state || !state.length) { + if (!state) { this.hidePanorama(); this.hideCoverage(); - return; + return true; } - if (state[0] === '1') { + if (state.length === 0) { + this.hidePanorama(); this.showCoverage(); - const lat = parseFloat(state[1]); - const lng = parseFloat(state[2]); - const heading = parseFloat(state[3]); - const pitch = parseFloat(state[4]); - const zoom = parseFloat(state[5]); - if (!isNaN(lat) && !isNaN(lng) && !isNaN(heading) && !isNaN(pitch)) { - this.showPanoramaAtPos(L.latLng(lat, lng), {heading, pitch, zoom}); - } + return true; + } - } else { - this.hidePanorama(); + const lat = parseFloat(state[0]); + const lng = parseFloat(state[1]); + const heading = parseFloat(state[2]); + const pitch = parseFloat(state[3]); + const zoom = parseFloat(state[4]); + if (!isNaN(lat) && !isNaN(lng) && !isNaN(heading) && !isNaN(pitch)) { this.showCoverage(); + this.showPanoramaAtPos(L.latLng(lat, lng), {heading, pitch, zoom}); + return true; } + + return false; } } ); \ No newline at end of file diff --git a/src/lib/leaflet.control.track-list/track-list.hash-state.js b/src/lib/leaflet.control.track-list/track-list.hash-state.js @@ -6,7 +6,7 @@ L.Control.TrackList.include({ stateChangeEvents: [], serializeState: function(e) { - return []; + return null; }, unserializeState: function(values) { diff --git a/src/lib/leaflet.hashState/Leaflet.Control.Layers.js b/src/lib/leaflet.hashState/Leaflet.Control.Layers.js @@ -25,8 +25,20 @@ L.Control.Layers.include({ return false; } + let hasBaselayer; for (let layer of this._layers) { - if (values.includes(layer.layer.options.code)) { + if (layer.layer.options && values.includes(layer.layer.options.code) && !layer.overlay) { + hasBaselayer = true; + break; + } + } + + if (!hasBaselayer) { + return false; + } + + for (let layer of this._layers) { + if (layer.layer.options && values.includes(layer.layer.options.code)) { this._map.addLayer(layer.layer); } else { this._map.removeLayer(layer.layer); diff --git a/src/lib/leaflet.hashState/Leaflet.Map.js b/src/lib/leaflet.hashState/Leaflet.Map.js @@ -13,7 +13,7 @@ L.Map.include({ var state = [ zoom.toString(), center.lat.toFixed(precision), - center.lng.toFixed(precision), + center.lng.toFixed(precision) ]; return state; }, @@ -28,9 +28,7 @@ L.Map.include({ if (isNaN(zoom) || isNaN(lat) || isNaN(lng) || zoom < 0 || zoom > 32 || lat < -90 || lat > 90 ) { return false; } - // this._updating_state = true; this.setView([lat, lng], zoom); - // this._updating_state = false; return true; } } diff --git a/src/lib/leaflet.hashState/hashState.js b/src/lib/leaflet.hashState/hashState.js @@ -1,6 +1,4 @@ function arrayItemsEqual(l1, l2) { - l1 = l1 || []; - l2 = l2 || []; if (l1.length !== l2.length) return false; for (var i = 0; i < l1.length; i++) { @@ -35,7 +33,11 @@ const hashState = { }, updateState: function(key, values) { - this._state[key] = values; + if (values) { + this._state[key] = values; + } else { + delete this._state[key]; + } this._saveStateToHash(); }, @@ -51,11 +53,15 @@ const hashState = { hash = hash.substr(i + 1).trim(); let m, key, value; for (let pair of hash.split('&')) { - m = /(.+?)=(.+)/.exec(pair); + m = /^([^=]+?)(?:=(.*))?$/.exec(pair); if (m) { [, key, value] = m; - value = value.split('/'); - value = value.map(decodeURIComponent); + if (value) { + value = value.split('/'); + value = value.map(decodeURIComponent); + } else { + value = []; + } args[key] = value; } } @@ -66,9 +72,13 @@ const hashState = { _saveStateToHash: function() { var stateItems = []; for (let key of Object.keys(this._state)) { - if (this._state[key].length) { - var values = this._state[key].join('/'); - stateItems.push(key + '=' + values); + if (this._state[key]) { + if (this._state[key].length) { + var values = this._state[key].join('/'); + stateItems.push(key + '=' + values); + } else { + stateItems.push(key); + } } } var hashString = '#' + stateItems.join('&'); @@ -80,7 +90,7 @@ const hashState = { const newState = this._parseHash(); const changedKeys = {}; for (let key of Object.keys(newState)) { - if (!arrayItemsEqual(newState[key], this._state[key])) { + if (!(key in this._state) || !arrayItemsEqual(newState[key], this._state[key])) { changedKeys[key] = 1; } } @@ -93,8 +103,6 @@ const hashState = { for (let [key, callback] of this._listeners) { if (key in changedKeys) { - // setTimeout(callback.bind(null, newState[key]), 0); - callback(newState[key]); } } diff --git a/src/lib/leaflet.hashState/leaflet.hashState.js b/src/lib/leaflet.hashState/leaflet.hashState.js @@ -5,30 +5,43 @@ L.Mixin.HashState = { enableHashState: function(key, defaultInitialState = null) { this._hashStateKey = key; const eventSource = this.stateChangeEventsSource ? this[this.stateChangeEventsSource] : this; + + // setup event listeners this.stateChangeEvents.forEach((event) => { - eventSource.on(event, this.updateHashState, this); + eventSource.on(event, this._onControlStateChanged, this); } ); - hashState.addEventListener(key, (state) => { - if (!this.unserializeState(state)) { // state from hash is invalid, update hash from component state - hashState.updateState(key, this.serializeState()); - } - } - ); + hashState.addEventListener(key, (state) => this._onExternalStateChanged(state)); + + // initialize control state from hash const state = hashState.getState(key) || defaultInitialState; - if (state) { - if (!this.unserializeState(state) && !this.unserializeState(defaultInitialState)) { // state from hash is invalid, update hash from default state - hashState.updateState(key, this.serializeState()); - } + this._ignoreStateChange = true; + if (!this.unserializeState(state) && !this.unserializeState(defaultInitialState)) { // state from hash is invalid, update hash from default state + hashState.updateState(key, this.serializeState()); } + hashState.updateState(this._hashStateKey, this.serializeState()); + this._ignoreStateChange = false; + return this; }, - updateHashState: function(state) { + _onControlStateChanged: function() { + if (this._ignoreStateChange) { + return; + } hashState.updateState(this._hashStateKey, this.serializeState()); + }, + + _onExternalStateChanged: function(state) { + this._ignoreStateChange = true; + if (!this.unserializeState(state)) { // state from hash is invalid, update hash from component state + hashState.updateState(this._hashStateKey, this.serializeState()); + } + this._ignoreStateChange = false; } + // TODO: disableHashState }; \ No newline at end of file