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:
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