You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
171 lines
3.5 KiB
171 lines
3.5 KiB
/* globals setPath, history */
|
|
|
|
var queryString = require('query-string')
|
|
|
|
function get () {
|
|
var state = {}
|
|
|
|
// repo
|
|
if (global.mainRepo !== '') {
|
|
state.repo = global.mainRepo
|
|
}
|
|
|
|
// path
|
|
if (currentPath) {
|
|
state.path = currentPath
|
|
}
|
|
|
|
// location
|
|
if (typeof map.getZoom() !== 'undefined') {
|
|
var center = map.getCenter().wrap()
|
|
var zoom = map.getZoom()
|
|
|
|
state.lat = center.lat
|
|
state.lon = center.lng
|
|
state.zoom = zoom
|
|
}
|
|
|
|
// other modules
|
|
call_hooks('state-get', state)
|
|
|
|
// done
|
|
return state
|
|
}
|
|
|
|
function apply (state) {
|
|
// path
|
|
setPath(state.path, state)
|
|
|
|
// location
|
|
if (state.lat && state.lon && state.zoom) {
|
|
if (typeof map.getZoom() === 'undefined') {
|
|
map.setView({ lat: state.lat, lng: state.lon }, state.zoom)
|
|
} else {
|
|
map.flyTo({ lat: state.lat, lng: state.lon }, state.zoom)
|
|
}
|
|
}
|
|
|
|
// other modules
|
|
call_hooks('state-apply', state)
|
|
}
|
|
|
|
function stringify (state) {
|
|
var link = ''
|
|
|
|
if (!state) {
|
|
state = get()
|
|
}
|
|
|
|
var tmpState = JSON.parse(JSON.stringify(state))
|
|
|
|
// path
|
|
if (state.path) {
|
|
link += state.path
|
|
delete tmpState.path
|
|
}
|
|
|
|
// location
|
|
var locPrecision = 5
|
|
if (state.zoom) {
|
|
locPrecision =
|
|
state.zoom > 16 ? 5
|
|
: state.zoom > 8 ? 4
|
|
: state.zoom > 4 ? 3
|
|
: state.zoom > 2 ? 2
|
|
: state.zoom > 1 ? 1
|
|
: 0
|
|
}
|
|
|
|
if (state.zoom && state.lat && state.lon) {
|
|
link += (link === '' ? '' : '&') + 'map=' +
|
|
parseFloat(state.zoom).toFixed(0) + '/' +
|
|
state.lat.toFixed(locPrecision) + '/' +
|
|
state.lon.toFixed(locPrecision)
|
|
|
|
delete tmpState.zoom
|
|
delete tmpState.lat
|
|
delete tmpState.lon
|
|
}
|
|
|
|
var newHash = queryString.stringify(tmpState)
|
|
|
|
// Characters we dont's want escaped
|
|
newHash = newHash.replace(/%2F/g, '/')
|
|
newHash = newHash.replace(/%2C/g, ',')
|
|
|
|
if (newHash !== '') {
|
|
link += (link === '' ? '' : '&') + newHash
|
|
}
|
|
|
|
return link
|
|
}
|
|
|
|
function parse (link) {
|
|
var firstEquals = link.search('=')
|
|
var firstAmp = link.search('&')
|
|
var urlNonPathPart = ''
|
|
var newState = {}
|
|
var newPath = ''
|
|
|
|
if (link === '') {
|
|
// nothing
|
|
} else if (firstEquals === -1) {
|
|
if (firstAmp === -1) {
|
|
newPath = link
|
|
} else {
|
|
newPath = link.substr(0, firstAmp)
|
|
}
|
|
} else {
|
|
if (firstAmp === -1) {
|
|
urlNonPathPart = link
|
|
} else if (firstAmp < firstEquals) {
|
|
newPath = link.substr(0, firstAmp)
|
|
urlNonPathPart = link.substr(firstAmp + 1)
|
|
} else {
|
|
urlNonPathPart = link
|
|
}
|
|
}
|
|
|
|
newState = queryString.parse(urlNonPathPart)
|
|
if (newPath !== '') {
|
|
newState.path = newPath
|
|
}
|
|
|
|
if ('map' in newState) {
|
|
var parts = newState.map.split('/')
|
|
newState.zoom = parts[0]
|
|
newState.lat = parts[1]
|
|
newState.lon = parts[2]
|
|
delete newState.map
|
|
}
|
|
|
|
return newState
|
|
}
|
|
|
|
function update (state, push) {
|
|
if (!state) {
|
|
state = get()
|
|
}
|
|
|
|
var newHash = '#' + stringify(state)
|
|
|
|
call_hooks('state-update', state, newHash)
|
|
|
|
if (push) {
|
|
history.pushState(null, null, newHash)
|
|
call_hooks('statePush', state, newHash)
|
|
} else if (location.hash !== newHash && (location.hash !== '' || newHash !== '#')) {
|
|
history.replaceState(null, null, newHash)
|
|
call_hooks('stateReplace', state, newHash)
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
get: get, // get the current app state
|
|
apply: apply, // apply a state to the current app
|
|
|
|
stringify: stringify, // create a link from a state (or the current state)
|
|
parse: parse, // parse a state from a link
|
|
|
|
update: update // update url (either replace or push)
|
|
}
|