All files router.js

100% Statements 20/20
100% Branches 6/6
100% Functions 11/11
100% Lines 20/20
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96                      1x                     3x 1x 1x     3x 3x             1x 3x               6x             6x   6x 11x 10x 4x 4x 4x                     4x 2x                       10x                   3x      
import Route from "./route";
 
export default class Router {
 
  /**
   * @constructor
   */
  constructor() {
    /**
     * @type {Array<Route>}
     */
    this.routes = [];
  }
 
  /**
   * Add a pattern route and associated callback function to the Router instance attached to the
   * window object.
   *
   * @param {String} pattern
   * @param {Function} callback
   */
  static when(pattern, callback) {
    if (window.ESToolboxRouter === undefined) {
      window.ESToolboxRouter = new Router();
      window.ESToolboxRouter.watchURLHash();
    }
 
    window.ESToolboxRouter.when(pattern, callback);
    window.ESToolboxRouter.checkURLHash();
  }
 
  /**
   * Watch for any changes that occur in the URL hash and run the route checker.
   */
  watchURLHash() {
    window.addEventListener("hashchange", () => {
      this.checkURLHash();
    }, false);
  }
 
  /**
   * Check if we have a pattern that matches the current URL hash.
   */
  checkURLHash() {
    this.checkPath(window.location.hash.replace(/^[^/]*/, ""));
  }
 
  /**
   * @param {String} path Path to be compared to known patterns.
   */
  checkPath(path) {
    let found = false;
 
    this.routes.forEach((route) => {
      if (!found) {
        if (this.compare(path, route.pattern)) {
          found = true;
          this.parsePatternVariablesFromPath(route, path);
          route.callback(route);
        }
      }
    });
  }
 
  /**
   * @param {Route} route
   * @param {String} path
   */
  parsePatternVariablesFromPath(route, path) {
    route.patternKeys.forEach((key, index) => {
      route.variables[key.name] = route.pattern.exec(path)[(index + 1)];
    });
  }
 
  /**
   * Compare a pattern to a route.
   *
   * @param {String} path A URL hash path.
   * @param {RegExp} pattern A URL route matching pattern.
   * @return {Boolean} True if pattern matches route, else false.
   */
  compare(path, pattern) {
    return pattern.exec(path) !== null;
  }
 
  /**
   * Add a pattern route and associated callback function.
   *
   * @param {String} pattern
   * @param {Function} callback
   */
  when(pattern, callback) {
    this.routes.push(new Route(pattern, callback));
  }
}