Source: core/Router.js

// Generated by github.com/steida/coffee2closure 0.1.12
goog.provide('spark.core.Router');
goog.require('spark.core.Object');
goog.require('spark.core.HistoryManager');
goog.require('goog.Uri');

/**
  Router manager class with built-in HistoryManager. Add routes to router and
  let Router to handle those routes along with HistoryManager.

  @constructor
  @export
  @param   {Object=} options Class options.
  @param   {*=} data Class data
  @extends {spark.core.Object}
 */
spark.core.Router = function(options, data) {
  var callback, route, routes, _ref;
  if (options == null) {
    options = {};
  }
  if (options.useHtml5History == null) {
    options.useHtml5History = (_ref = options['useHtml5History']) != null ? _ref : false;
  }
  options.routes || (options.routes = options['routes'] || {});
  spark.core.Router.superClass_.constructor.call(this, options, data);
  this.historyManager = new spark.core.HistoryManager({
    useHtml5History: options.useHtml5History
  });
  this.routes = {};
  this.routeRegexes = {};
  this.latestHandledRoute = null;
  this.historyManager.on('Navigated', (function(_this) {
    return function(e) {
      var path;
      path = e.data;
      if (_this.latestHandledRoute !== path) {
        _this.handleRoute_(path);
        _this.latestHandledRoute = path;
        return _this.emit('RouteChanged', path);
      }
    };
  })(this));
  routes = options.routes;
  for (route in routes) {
    callback = routes[route];
    this.addRoute(route, callback);
  }
  this.init();
}
goog.inherits(spark.core.Router, spark.core.Object);

/**
  Add route with callback function to handle it.

  @export
  @param {!string} route Route path.
  @param {!Function} callback Callback to handle route action.
 */
spark.core.Router.prototype.addRoute = function(route, callback) {
  this.routes[route] = callback;
  return this.createRegexRoute_(route);
};

/**
  Sets HistoryManager's token to update URL. When history token is changed
  HistoryManager will emit Navigated event. It's handled in here and it will
  call the correct callback for that route.

  @export
  @param {string} path Path to change the active route.
 */
spark.core.Router.prototype.route = function(path) {
  return this.historyManager.setToken(path);
};

/**
  Routes back on the page. If there is no previous route, it will do nothing.

  @export
 */
spark.core.Router.prototype.back = function() {
  return window.history.back();
};

/**
  Routes forward on the page. If there is no next route, it will do nothing.

  @export
 */
spark.core.Router.prototype.forward = function() {
  return window.history.forward();
};

/**
  Handle route for current page path. This is useful for handling the initial
  route of the page when page reload. This method should be called by user
  because Router doesn't actually know when all routes are added.

  TODO: Rename this method.
  @export
 */
spark.core.Router.prototype.init = function() {
  var host, href, protocol, route, _ref;
  _ref = document.location, href = _ref.href, host = _ref.host, protocol = _ref.protocol;
  route = href.replace("" + protocol + "//" + host, '');
  return this.handleRoute_(route.replace('/#', ''));
};

/**
  Returns the currently added routes.

  @export
  @return {Object} Routes object.
 */
spark.core.Router.prototype.getRoutes = function() {
  return this.routes;
};

/**
  Returns spark.core.HistoryManager instance.

  @export
  @return {spark.core.HistoryManager} HistoryManager instance of the Router.
 */
spark.core.Router.prototype.getHistoryManager = function() {
  return this.historyManager;
};

/**
  Execute callback function for particular route path.

  @private
 */
spark.core.Router.prototype.handleRoute_ = function(path) {
  var cb, index, key, params, query, queryData, queryKeys, queryValues, regex, route, token, tokens, uri, values, _i, _j, _len, _len1, _ref, _results;
  uri = new goog.Uri(path);
  path = uri.getPath();
  params = null;
  query = null;
  queryData = uri.getQueryData();
  queryKeys = queryData.getKeys();
  queryValues = queryData.getValues();
  if (queryKeys.length) {
    query = {};
    for (index = _i = 0, _len = queryKeys.length; _i < _len; index = ++_i) {
      key = queryKeys[index];
      query[key] = queryValues[index];
    }
  }
  cb = this.routes[path];
  if (cb) {
    return cb.call(this, params, query);
  }
  _ref = this.routeRegexes;
  _results = [];
  for (route in _ref) {
    regex = _ref[route];
    values = regex.exec(path);
    if (!values) {
      continue;
    }
    cb = this.routes[route];
    tokens = route.match(/(:\w+)/g);
    params = {};
    values.shift();
    for (index = _j = 0, _len1 = tokens.length; _j < _len1; index = ++_j) {
      token = tokens[index];
      token = token.replace(/:/g, '');
      params[token] = values[index];
    }
    _results.push(cb != null ? cb.call(this, params, query) : void 0);
  }
  return _results;
};

/**
  Creates a regex for route to match actual page link with our routes.
  This method create a regex like `\/activity\/post\/(\w+)\/comment\/(\w+)$`
  to match this route `/activity/post/1/comment/2`. Here is the regex101
  https://www.regex101.com/r/wX2kB6/1

  @private
  @param {!string} route Actual page route.
  @return {RegExp|undefined} RegExp to match page URL.
 */
spark.core.Router.prototype.createRegexRoute_ = function(route) {
  var captureParams, escapeSlashes, routeRegex;
  if (route.indexOf(':') === -1) {
    return;
  }
  escapeSlashes = /\//g;
  captureParams = /:(\w+)/g;
  routeRegex = route.replace(escapeSlashes, '\/').replace(captureParams, '(\\w+)');
  return this.routeRegexes[route] = new RegExp("" + routeRegex + "$");
};

/**
  Destroy the router instance. If you want to create a new router instance
  for some reason, you have to destroy previously created instances. Otherwise
  HistoryManager events will be triggered multiple times.

  @export
 */
spark.core.Router.prototype.destroy = function() {
  if (!this.isDestroyed()) {
    this.historyManager.destroy();
    this.historyManager = null;
  }
  return spark.core.Router.superClass_.destroy.apply(this, arguments);
};
Spark Framework by Fatih Acet
Copyright © 2014 - Fatih Acet
Documentation generated by JSDoc 3.2.2 on 2015-07-19T22:09:29+00:00 using the DocStrap template.