]> git.openstreetmap.org Git - rails.git/blobdiff - app/assets/javascripts/router.js
Merge remote-tracking branch 'upstream/pull/4200'
[rails.git] / app / assets / javascripts / router.js
index 2f76f2f184983a01efbbaa651dcbb9f9d5b256c5..c4e52417004c5c50871f23fe28edf967596c68b7 100644 (file)
    OSM.Router also handles updating the hash portion of the URL containing transient
    map state such as the position and zoom level. Some route controllers may wish to
    temporarily suppress updating the hash (for example, to omit the hash on pages
    OSM.Router also handles updating the hash portion of the URL containing transient
    map state such as the position and zoom level. Some route controllers may wish to
    temporarily suppress updating the hash (for example, to omit the hash on pages
-   such as `/way/1234` unless the map is moved). This can be done by calling
-   `OSM.router.moveListenerOff` and `OSM.router.moveListenerOn`.
+   such as `/way/1234` unless the map is moved). This can be done by using
+   `OSM.router.withoutMoveListener` to run a block of code that may update
+   move the map without the hash changing.
  */
  */
-OSM.Router = function(map, rts) {
-  var escapeRegExp  = /[\-{}\[\]+?.,\\\^$|#\s]/g;
+OSM.Router = function (map, rts) {
+  var escapeRegExp = /[-{}[\]+?.,\\^$|#\s]/g;
   var optionalParam = /\((.*?)\)/g;
   var optionalParam = /\((.*?)\)/g;
-  var namedParam    = /(\(\?)?:\w+/g;
-  var splatParam    = /\*\w+/g;
+  var namedParam = /(\(\?)?:\w+/g;
+  var splatParam = /\*\w+/g;
 
   function Route(path, controller) {
 
   function Route(path, controller) {
-    var regexp = new RegExp('^' +
-      path.replace(escapeRegExp, '\\$&')
-        .replace(optionalParam, '(?:$1)?')
-        .replace(namedParam, function(match, optional){
-          return optional ? match : '([^\/]+)';
+    var regexp = new RegExp("^" +
+      path.replace(escapeRegExp, "\\$&")
+        .replace(optionalParam, "(?:$1)?")
+        .replace(namedParam, function (match, optional) {
+          return optional ? match : "([^/]+)";
         })
         })
-        .replace(splatParam, '(.*?)') + '(?:\\?.*)?$');
+        .replace(splatParam, "(.*?)") + "(?:\\?.*)?$");
 
     var route = {};
 
 
     var route = {};
 
-    route.match = function(path) {
+    route.match = function (path) {
       return regexp.test(path);
     };
 
       return regexp.test(path);
     };
 
-    route.run = function(action, path) {
+    route.run = function (action, path) {
       var params = [];
 
       if (path) {
       var params = [];
 
       if (path) {
-        params = regexp.exec(path).map(function(param, i) {
+        params = regexp.exec(path).map(function (param, i) {
           return (i > 0 && param) ? decodeURIComponent(param) : param;
         });
       }
 
           return (i > 0 && param) ? decodeURIComponent(param) : param;
         });
       }
 
+      params = params.concat(Array.prototype.slice.call(arguments, 2));
+
       return (controller[action] || $.noop).apply(controller, params);
     };
 
       return (controller[action] || $.noop).apply(controller, params);
     };
 
@@ -82,70 +85,80 @@ OSM.Router = function(map, rts) {
   }
 
   var routes = [];
   }
 
   var routes = [];
-  for (var r in rts)
-    routes.push(Route(r, rts[r]));
+  for (var r in rts) {
+    routes.push(new Route(r, rts[r]));
+  }
 
 
-  routes.recognize = function(path) {
+  routes.recognize = function (path) {
     for (var i = 0; i < this.length; i++) {
       if (this[i].match(path)) return this[i];
     }
   };
 
     for (var i = 0; i < this.length; i++) {
       if (this[i].match(path)) return this[i];
     }
   };
 
-  var currentPath = window.location.pathname.replace(/(.)\/$/, '$1') + window.location.search,
-    currentRoute = routes.recognize(currentPath),
-    currentHash = location.hash || OSM.formatHash(map);
+  var currentPath = window.location.pathname.replace(/(.)\/$/, "$1") + window.location.search,
+      currentRoute = routes.recognize(currentPath),
+      currentHash = location.hash || OSM.formatHash(map);
 
   var router = {};
 
 
   var router = {};
 
-  if (window.history && window.history.pushState) {
-    $(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);
-      map.setState(e.originalEvent.state, {animate: false});
+  function updateSecondaryNav() {
+    $("header nav.secondary > ul > li > a").each(function () {
+      var active = $(this).attr("href") === window.location.pathname;
+
+      $(this)
+        .toggleClass("text-secondary", !active)
+        .toggleClass("text-secondary-emphasis", active);
     });
     });
+  }
 
 
-    router.route = function (url) {
-      var path = url.replace(/#.*/, ''),
+  $(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,
         route = routes.recognize(path);
         route = routes.recognize(path);
-      if (!route) return false;
-      window.history.pushState(OSM.parseHash(url), document.title, url);
-      currentRoute.run('unload');
-      currentPath = path;
-      currentRoute = route;
-      currentRoute.run('pushstate', currentPath);
-      return true;
-    };
+    if (path === currentPath) return;
+    currentRoute.run("unload", null, route === currentRoute);
+    currentPath = path;
+    currentRoute = route;
+    currentRoute.run("popstate", currentPath);
+    updateSecondaryNav();
+    map.setState(e.originalEvent.state, { animate: false });
+  });
+
+  router.route = function (url) {
+    var path = url.replace(/#.*/, ""),
+        route = routes.recognize(path);
+    if (!route) return false;
+    currentRoute.run("unload", null, route === currentRoute);
+    var state = OSM.parseHash(url);
+    map.setState(state);
+    window.history.pushState(state, document.title, url);
+    currentPath = path;
+    currentRoute = route;
+    currentRoute.run("pushstate", currentPath);
+    updateSecondaryNav();
+    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 {
-    router.route = function (url) {
-      window.location.assign(url);
-    };
+  router.replace = function (url) {
+    window.history.replaceState(OSM.parseHash(url), document.title, url);
+  };
 
 
-    router.stateChange = function(state) {
-      if (state.center) window.location.replace(OSM.formatHash(state));
-    };
-  }
+  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);
+    }
+  };
 
 
-  router.updateHash = function() {
+  router.updateHash = function () {
     var hash = OSM.formatHash(map);
     if (hash === currentHash) return;
     currentHash = hash;
     router.stateChange(OSM.parseHash(hash));
   };
 
     var hash = OSM.formatHash(map);
     if (hash === currentHash) return;
     currentHash = hash;
     router.stateChange(OSM.parseHash(hash));
   };
 
-  router.hashUpdated = function() {
+  router.hashUpdated = function () {
     var hash = location.hash;
     if (hash === currentHash) return;
     currentHash = hash;
     var hash = location.hash;
     if (hash === currentHash) return;
     currentHash = hash;
@@ -154,16 +167,21 @@ OSM.Router = function(map, rts) {
     router.stateChange(state, hash);
   };
 
     router.stateChange(state, hash);
   };
 
-  router.moveListenerOn = function() {
-    map.on('moveend', router.updateHash);
-  };
+  router.withoutMoveListener = function (callback) {
+    function disableMoveListener() {
+      map.off("moveend", router.updateHash);
+      map.once("moveend", function () {
+        map.on("moveend", router.updateHash);
+      });
+    }
 
 
-  router.moveListenerOff = function() {
-    map.off('moveend', router.updateHash);
+    map.once("movestart", disableMoveListener);
+    callback();
+    map.off("movestart", disableMoveListener);
   };
 
   };
 
-  router.load = function() {
-    var loadState = currentRoute.run('load', currentPath);
+  router.load = function () {
+    var loadState = currentRoute.run("load", currentPath);
     router.stateChange(loadState || {});
   };
 
     router.stateChange(loadState || {});
   };
 
@@ -172,8 +190,8 @@ OSM.Router = function(map, rts) {
     currentRoute = routes.recognize(currentPath);
   };
 
     currentRoute = routes.recognize(currentPath);
   };
 
-  map.on('moveend baselayerchange overlaylayerchange', router.updateHash);
-  $(window).on('hashchange', router.hashUpdated);
+  map.on("moveend baselayerchange overlaylayerchange", router.updateHash);
+  $(window).on("hashchange", router.hashUpdated);
 
   return router;
 };
 
   return router;
 };