X-Git-Url: https://git.openstreetmap.org/rails.git/blobdiff_plain/35458c009652645972a9167d80aba1c4fdce82cf..653f7c0d74ba29a761865248728db7fd439a749e:/app/assets/javascripts/router.js diff --git a/app/assets/javascripts/router.js b/app/assets/javascripts/router.js index 654ec860b..cbd418895 100644 --- a/app/assets/javascripts/router.js +++ b/app/assets/javascripts/router.js @@ -1,4 +1,4 @@ -OSM.Router = function(rts) { +OSM.Router = function(map, rts) { var escapeRegExp = /[\-{}\[\]+?.,\\\^$|#\s]/g; var optionalParam = /\((.*?)\)/g; var namedParam = /(\(\?)?:\w+/g; @@ -28,7 +28,7 @@ OSM.Router = function(rts) { }); } - (controller[action] || $.noop).apply(controller, params); + return (controller[action] || $.noop).apply(controller, params); }; return route; @@ -45,34 +45,89 @@ OSM.Router = function(rts) { }; var currentPath = window.location.pathname + window.location.search, - currentRoute = routes.recognize(currentPath); + currentRoute = routes.recognize(currentPath), + currentHash = location.hash || OSM.formatHash(map); - currentRoute.run('load', currentPath); + var router, stateChange; if (window.history && window.history.pushState) { - $(window).on('popstate', function() { + $(window).on('popstate', function(e) { + if (!e.originalEvent.state) return; // Is it a real popstate event or just a hash change? var path = window.location.pathname + window.location.search; if (path === currentPath) return; currentRoute.run('unload'); currentPath = path; currentRoute = routes.recognize(currentPath); currentRoute.run('popstate', currentPath); + var state = e.originalEvent.state; + if (state.center) { + map.setView(state.center, state.zoom, {animate: false}); + map.updateLayers(state.layers); + } }); - return function (url) { + router = function (url) { var path = url.replace(/#.*/, ''), route = routes.recognize(path); if (!route) return false; - window.history.pushState({}, document.title, url); + window.history.pushState(OSM.parseHash(url) || {}, document.title, url); currentRoute.run('unload'); currentPath = path; currentRoute = route; currentRoute.run('pushstate', currentPath); return true; - } + }; + + router.stateChange = function(state) { + if (state.center) { + window.history.replaceState(state, document.title, OSM.formatHash(state)); + } else { + window.history.replaceState(state, document.title, window.location); + } + }; } else { - return function (url) { + router = function (url) { window.location.assign(url); - } + }; + + router.stateChange = function(state) { + if (state.center) window.location.replace(OSM.formatHash(state)); + }; } + + router.updateHash = function() { + var hash = OSM.formatHash(map); + if (hash === currentHash) return; + currentHash = hash; + router.stateChange(OSM.parseHash(hash)); + }; + + router.hashUpdated = function() { + var hash = location.hash; + if (hash === currentHash) return; + currentHash = hash; + var state = OSM.parseHash(hash); + if (!state) return; + map.setView(state.center, state.zoom); + map.updateLayers(state.layers); + router.stateChange(state, hash); + }; + + router.moveListenerOn = function() { + map.on('moveend', router.updateHash); + }; + + router.moveListenerOff = function() { + map.off('moveend', router.updateHash); + }; + + router.load = function() { + var loadState = currentRoute.run('load', currentPath); + router.stateChange(loadState || {}); + }; + + map.on('moveend baselayerchange overlaylayerchange', router.updateHash); + $(window).on('hashchange', router.hashUpdated); + + return router; };