]> git.openstreetmap.org Git - rails.git/blobdiff - app/assets/javascripts/router.js
Reduce condition complexity
[rails.git] / app / assets / javascripts / router.js
index 05e47c3560955e4f8fb3fec90eb32d5cfc5f918e..63a320c6a9d76e6a2810289d4f105e448d788a72 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
-   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 namedParam    = /(\(\?)?:\w+/g;
-  var splatParam    = /\*\w+/g;
+  var namedParam = /(\(\?)?:\w+/g;
+  var splatParam = /\*\w+/g;
 
   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 = {};
 
-    route.match = function(path) {
+    route.match = function (path) {
       return regexp.test(path);
     };
 
-    route.run = function(action, path) {
+    route.run = function (action, 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;
         });
       }
 
+      params = params.concat(Array.prototype.slice.call(arguments, 2));
+
       return (controller[action] || $.noop).apply(controller, params);
     };
 
     return route;
   }
 
-  var routes = [];
-  for (var r in rts)
-    routes.push(Route(r, rts[r]));
+  const routes = Object.entries(rts)
+    .map(([r, t]) => new Route(r, t));
 
-  routes.recognize = function(path) {
-    for (var i = 0; i < this.length; i++) {
-      if (this[i].match(path)) return this[i];
+  routes.recognize = function (path) {
+    for (const route of this) {
+      if (route.match(path)) return route;
     }
   };
 
-  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 = {};
 
-  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);
-      if (!route) return false;
-      currentRoute.run('unload');
-      window.history.pushState(OSM.parseHash(url), document.title, url);
-      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.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.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.location.replace(OSM.formatHash(state));
-    };
-  }
+  router.replace = function (url) {
+    window.history.replaceState(OSM.parseHash(url), document.title, url);
+  };
 
-  router.updateHash = function() {
+  router.stateChange = function (state) {
+    const url = state.center ? OSM.formatHash(state) : window.location;
+    window.history.replaceState(state, document.title, url);
+  };
+
+  router.updateHash = function () {
     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;
@@ -154,16 +162,21 @@ OSM.Router = function(map, rts) {
     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 || {});
   };
 
@@ -172,11 +185,8 @@ OSM.Router = function(map, rts) {
     currentRoute = routes.recognize(currentPath);
   };
 
-  map.on('moveend baselayerchange overlaylayerchange', router.updateHash);
-  $(window).on('hashchange', router.hashUpdated);
-  $(window).on('unload', function(e) {
-      $(".query_wrapper.routing input").val("");
-  });
+  map.on("moveend baselayerchange overlayadd overlayremove", router.updateHash);
+  $(window).on("hashchange", router.hashUpdated);
 
   return router;
 };