router-debug.js revision 8868b979badbb9aeed3c32f3fb02eafead9aedfe
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsyncProvides URL-based routing using HTML5 `pushState()` or the location hash.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync@submodule router
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync@since 3.4.0
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync origin = location.origin || (location.protocol + '//' + location.host),
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync // We have to queue up pushState calls to avoid race conditions, since the
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync // popstate event doesn't actually provide any info on what URL it's
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync // associated with.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Fired when the router is ready to begin dispatching to route handlers.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync You shouldn't need to wait for this event unless you plan to implement some
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync kind of custom dispatching logic. It's used internally in order to avoid
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync dispatching to an initial route if a browser history change occurs first.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @event ready
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @param {Boolean} dispatched `true` if routes have already been dispatched
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync (most likely due to a history change).
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsyncProvides URL-based routing using HTML5 `pushState()` or the location hash.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsyncThis makes it easy to wire up route handlers for different application states
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsyncwhile providing full back/forward navigation support and bookmarkable, shareable
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync@class Router
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync@param {Object} [config] Config properties.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @param {Boolean} [config.html5] Overrides the default capability detection
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync and forces this router to use (`true`) or not use (`false`) HTML5
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @param {String} [config.root=''] Root path from which all routes should be
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @param {Array} [config.routes=[]] Array of route definition objects.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync@constructor
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync@extends Base
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync@since 3.4.0
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Router.superclass.constructor.apply(this, arguments);
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync // -- Protected Properties -------------------------------------------------
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Whether or not `_dispatch()` has been called since this router was
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync instantiated.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @property _dispatched
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @type Boolean
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @default undefined
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Whether or not we're currently in the process of dispatching to routes.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @property _dispatching
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @type Boolean
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @default undefined
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Cached copy of the `html5` attribute for internal use.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @property _html5
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @type Boolean
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Whether or not the `ready` event has fired yet.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @property _ready
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @type Boolean
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @default undefined
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Regex used to match parameter placeholders in route paths.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Subpattern captures:
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync 1. Parameter prefix character. Either a `:` for subpath parameters that
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync should only match a single level of a path, or `*` for splat parameters
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync that should match any number of path levels.
64863d3a0ffadf1ac248b295b78be5d55db6ee13vboxsync 2. Parameter name.
64863d3a0ffadf1ac248b295b78be5d55db6ee13vboxsync @property _regexPathParam
64863d3a0ffadf1ac248b295b78be5d55db6ee13vboxsync @type RegExp
64863d3a0ffadf1ac248b295b78be5d55db6ee13vboxsync _regexPathParam: /([:*])([\w\-]+)/g,
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Regex that matches and captures the query portion of a URL, minus the
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync preceding `?` character, and discarding the hash portion of the URL if any.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @property _regexUrlQuery
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @type RegExp
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync _regexUrlQuery: /\?([^#]*).*$/,
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Regex that matches everything before the path portion of a URL (the origin).
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync This will be used to strip this part of the URL from a string when we
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync only want the path.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @property _regexUrlOrigin
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @type RegExp
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync _regexUrlOrigin: /^(?:[^\/#?:]+:\/\/|\/\/)[^\/]*/,
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync // -- Lifecycle Methods ----------------------------------------------------
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync var self = this;
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync // Necessary because setters don't run on init.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync this._setRoutes(config && config.routes ? config.routes :
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync // Set up a history instance or hashchange listener.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Y.after('history:change', self._afterHistoryChange, self);
4aebc69aadd38c5c13ed4211d60635ad49538275vboxsync Y.on('hashchange', self._afterHistoryChange, win, self);
4aebc69aadd38c5c13ed4211d60635ad49538275vboxsync // Fire a 'ready' event once we're ready to route. We wait first for all
4aebc69aadd38c5c13ed4211d60635ad49538275vboxsync // subclass initializers to finish, then for window.onload, and then an
4aebc69aadd38c5c13ed4211d60635ad49538275vboxsync // additional 20ms to allow the browser to fire a useless initial
4aebc69aadd38c5c13ed4211d60635ad49538275vboxsync // `popstate` event if it wants to (and Chrome always wants to).
4aebc69aadd38c5c13ed4211d60635ad49538275vboxsync setTimeout(function () {
4aebc69aadd38c5c13ed4211d60635ad49538275vboxsync self.fire(EVT_READY, {dispatched: !!self._dispatched});
4aebc69aadd38c5c13ed4211d60635ad49538275vboxsync destructor: function () {
4aebc69aadd38c5c13ed4211d60635ad49538275vboxsync Y.detach('history:change', this._afterHistoryChange, this);
4aebc69aadd38c5c13ed4211d60635ad49538275vboxsync Y.detach('hashchange', this._afterHistoryChange, win);
4aebc69aadd38c5c13ed4211d60635ad49538275vboxsync // -- Public Methods -------------------------------------------------------
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Dispatches to the first route handler that matches the current URL, if any.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync If `dispatch()` is called before the `ready` event has fired, it will
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync automatically wait for the `ready` event before dispatching. Otherwise it
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync will dispatch immediately.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @method dispatch
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync dispatch: function () {
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync this._ready = true;
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync return this;
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Gets the current route path, relative to the `root` (if any).
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @method getPath
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @return {String} Current route path.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync getPath: function () {
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync return this._getPath();
241adddf415cbdf66230864a215b24415f482e72vboxsync Returns `true` if this router has at least one route that matches the
241adddf415cbdf66230864a215b24415f482e72vboxsync specified URL, `false` otherwise.
241adddf415cbdf66230864a215b24415f482e72vboxsync This method enforces the same-origin security constraint on the specified
241adddf415cbdf66230864a215b24415f482e72vboxsync `url`; any URL which is not from the same origin as the current URL will
241adddf415cbdf66230864a215b24415f482e72vboxsync always return `false`.
241adddf415cbdf66230864a215b24415f482e72vboxsync @method hasRoute
241adddf415cbdf66230864a215b24415f482e72vboxsync @param {String} url URL to match.
241adddf415cbdf66230864a215b24415f482e72vboxsync @return {Boolean} `true` if there's at least one matching route, `false`
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync return false;
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Returns an array of route objects that match the specified URL path.
a8ce9568e18b8c1a49833bf3b3ac2b2cc634b13cvboxsync This method is called internally to determine which routes match the current
a8ce9568e18b8c1a49833bf3b3ac2b2cc634b13cvboxsync path whenever the URL changes. You may override it if you want to customize
a8ce9568e18b8c1a49833bf3b3ac2b2cc634b13cvboxsync the route matching logic, although this usually shouldn't be necessary.
a8ce9568e18b8c1a49833bf3b3ac2b2cc634b13cvboxsync Each returned route object has the following properties:
a8ce9568e18b8c1a49833bf3b3ac2b2cc634b13cvboxsync * `callback`: A function or a string representing the name of a function
a8ce9568e18b8c1a49833bf3b3ac2b2cc634b13cvboxsync this router that should be executed when the route is triggered.
a8ce9568e18b8c1a49833bf3b3ac2b2cc634b13cvboxsync * `keys`: An array of strings representing the named parameters defined in
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync the route's path specification, if any.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync * `path`: The route's path specification, which may be either a string or
241adddf415cbdf66230864a215b24415f482e72vboxsync * `regex`: A regular expression version of the route's path specification.
241adddf415cbdf66230864a215b24415f482e72vboxsync This regex is used to determine whether the route matches a given path.
241adddf415cbdf66230864a215b24415f482e72vboxsync router.route('/foo', function () {});
241adddf415cbdf66230864a215b24415f482e72vboxsync router.match('/foo');
241adddf415cbdf66230864a215b24415f482e72vboxsync // => [{callback: ..., keys: [], path: '/foo', regex: ...}]
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @method match
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @param {String} path URL path to match.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @return {Object[]} Array of route objects that match the specified path.
a8ce9568e18b8c1a49833bf3b3ac2b2cc634b13cvboxsync return YArray.filter(this._routes, function (route) {
a8ce9568e18b8c1a49833bf3b3ac2b2cc634b13cvboxsync Removes the `root` URL from the front of _url_ (if it's there) and returns
a8ce9568e18b8c1a49833bf3b3ac2b2cc634b13cvboxsync the result. The returned path will always have a leading `/`.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @method removeRoot
241adddf415cbdf66230864a215b24415f482e72vboxsync @param {String} url URL.
241adddf415cbdf66230864a215b24415f482e72vboxsync @return {String} Rootless path.
241adddf415cbdf66230864a215b24415f482e72vboxsync // Strip out the non-path part of the URL, if any (e.g.
241adddf415cbdf66230864a215b24415f482e72vboxsync // "http://foo.com"), so that we're left with just the path.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Replaces the current browser history entry with a new one, and dispatches to
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync the first matching route handler, if any.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Behind the scenes, this method uses HTML5 `pushState()` in browsers that
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync support it (or the location hash in older browsers and IE) to change the
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync The specified URL must share the same origin (i.e., protocol, host, and
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync port) as the current page, or an error will occur.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync // Starting URL: http://example.com/
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync router.replace('/path/');
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync router.replace('/path?foo=bar');
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync router.replace('/');
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @method replace
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @param {String} [url] URL to set. This URL needs to be of the same origin as
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync the current URL. This can be a URL relative to the router's `root`
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync attribute. If no URL is specified, the page's current URL will be used.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @see save()
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Adds a route handler for the specified URL _path_.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync The _path_ parameter may be either a string or a regular expression. If it's
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync a string, it may contain named parameters: `:param` will match any single
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync part of a URL path (not including `/` characters), and `*param` will match
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync any number of parts of a URL path (including `/` characters). These named
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync parameters will be made available as keys on the `req.params` object that's
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync passed to route handlers.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync If the _path_ parameter is a regex, all pattern matches will be made
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync available as numbered keys on `req.params`, starting with `0` for the full
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync match, then `1` for the first subpattern match, and so on.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Here's a set of sample routes along with URL paths that they match:
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync * Route: `/photos/:tag/:page`
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync * URL: `/photos/kittens/1`, params: `{tag: 'kittens', page: '1'}`
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync * URL: `/photos/puppies/2`, params: `{tag: 'puppies', page: '2'}`
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync * Route: `/file/*path`
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync * URL: `/file/foo/bar/baz.txt`, params: `{path: 'foo/bar/baz.txt'}`
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync * URL: `/file/foo`, params: `{path: 'foo'}`
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync If multiple route handlers match a given URL, they will be executed in the
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync order they were added. The first route that was added will be the first to
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync be executed.
4791a729647f035b6561d292c9f848dd1fc797a9vboxsync router.route('/photos/:tag/:page', function (req, res, next) {
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Y.log('Current tag: ' + req.params.tag);
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Y.log('Current page number: ' + req.params.page);
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @method route
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @param {String|RegExp} path Path to match. May be a string or a regular
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync expression.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @param {Function|String} callback Callback function to call whenever this
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync route is triggered. If specified as a string, the named function will be
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync called on this router instance.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @param {Object} callback.req Request object containing information about
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync the request. It contains the following properties.
3dd1d8fdf12303b292d9ee378edbc5f5fb6d6cb5vboxsync @param {Array|Object} callback.req.params Captured parameters matched by
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync the route path specification. If a string path was used and contained
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync named parameters, then this will be a key/value hash mapping parameter
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync names to their matched values. If a regex path was used, this will be
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync an array of subpattern matches starting at index 0 for the full match,
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync then 1 for the first subpattern match, and so on.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @param {String} callback.req.path The current URL path.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @param {Object} callback.req.query Query hash representing the URL query
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync string, if any. Parameter names are keys, and are mapped to parameter
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @param {String} callback.req.url The full URL.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @param {String} callback.req.src What initiated the dispatch. In an
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync HTML5 browser, when the back/forward buttons are used, this property
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync will have a value of "popstate".
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @param {Object} callback.res Response object containing methods and
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync information that relate to responding to a request. It contains the
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync following properties.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @param {Object} callback.res.req Reference to the request object.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @param {Function} callback.next Callback to pass control to the next
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync matching route. If you don't call this function, then no further route
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync handlers will be executed, even if there are more that match. If you do
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync call this function, then the next matching route handler (if any) will
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync be called, and will receive the same `req` object that was passed to
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync this route (so you can use the request object to pass data along to
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync subsequent routes).
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync return this;
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Saves a new browser history entry and dispatches to the first matching route
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync handler, if any.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Behind the scenes, this method uses HTML5 `pushState()` in browsers that
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync support it (or the location hash in older browsers and IE) to change the
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync URL and create a history entry.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync The specified URL must share the same origin (i.e., protocol, host, and
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync port) as the current page, or an error will occur.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync // Starting URL: http://example.com/
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync router.save('/path/');
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync router.save('/path?foo=bar');
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync router.save('/');
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @method save
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @param {String} [url] URL to set. This URL needs to be of the same origin as
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync the current URL. This can be a URL relative to the router's `root`
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync attribute. If no URL is specified, the page's current URL will be used.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @see replace()
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Upgrades a hash-based URL to an HTML5 URL if necessary. In non-HTML5
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync browsers, this method is a noop.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @method upgrade
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @return {Boolean} `true` if the URL was upgraded, `false` otherwise.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync upgrade: function () {
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync if (!this._html5) {
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync return false;
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync // Get the full hash in all its glory!
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync // This is an HTML5 browser and we have a hash-based path in the
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync // URL, so we need to upgrade the URL to a non-hash URL. This
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync // will trigger a `history:change` event, which will in turn
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync // trigger a dispatch.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync return true;
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync return false;
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync // -- Protected Methods ----------------------------------------------------
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Wrapper around `decodeURIComponent` that also converts `+` chars into
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @method _decode
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @param {String} string String to decode.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @return {String} Decoded string.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync return decodeURIComponent(string.replace(/\+/g, ' '));
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Shifts the topmost `_save()` call off the queue and executes it. Does
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync nothing if the queue is empty.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @method _dequeue
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @see _queue
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync _dequeue: function () {
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync var self = this,
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync // If window.onload hasn't yet fired, wait until it has before
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync // dequeueing. This will ensure that we don't call pushState() before an
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync // initial popstate event has fired.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync return this;
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Dispatches to the first route handler that matches the specified _path_.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync If called before the `ready` event has fired, the dispatch will be aborted.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync This ensures normalized behavior between Chrome (which fires a `popstate`
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync event on every pageview) and other browsers (which do not).
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @method _dispatch
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @param {String} path URL path.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @param {String} url Full URL.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @param {String} src What initiated the dispatch.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync var self = this,
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync // Use named keys for parameter names if the route path contains
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync // named keys. Otherwise, use numerical match indices.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync req.params = YArray.hash(route.keys, matches.slice(1));
64863d3a0ffadf1ac248b295b78be5d55db6ee13vboxsync Gets the current path from the location hash, or an empty string if the
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync hash is empty.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @method _getHashPath
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @return {String} Current hash path, or an empty string if the hash is empty.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync _getHashPath: function () {
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync return HistoryHash.getHash().replace(this._regexUrlQuery, '');
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Gets the location origin (i.e., protocol, host, and port) as a URL.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @method _getOrigin
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @return {String} Location origin (i.e., protocol, host, and port).
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync _getOrigin: function () {
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Gets the current route path, relative to the `root` (if any).
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @method _getPath
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @return {String} Current route path.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync _getPath: function () {
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync var path = (!this._html5 && this._getHashPath()) || location.pathname;
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Gets the current route query string.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @method _getQuery
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @return {String} Current route query string.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync _getQuery: function () {
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync return hash && matches ? matches[1] : location.search.substring(1);
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Creates a regular expression from the given route specification. If _path_
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync is already a regex, it will be returned unmodified.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @method _getRegex
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @param {String|RegExp} path Route path specification.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @param {Array} keys Array reference to which route parameter names will be
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @return {RegExp} Route regex.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync if (path instanceof RegExp) {
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync // Special case for catchall paths.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync return /.*/;
2927a95ee3fe77d319ee5959368c7dfc119a96fbvboxsync path = path.replace(this._regexPathParam, function (match, operator, key) {
574d36adfdd4d9e62af3640ecde108bdefb1c663vboxsync Gets a request object that can be passed to a route handler.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @method _getRequest
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @param {String} path Current path being dispatched.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @param {String} url Current full URL being dispatched.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @param {String} src What initiated the dispatch.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @return {Object} Request object.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Gets a response object that can be passed to a route handler.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @method _getResponse
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @param {Object} req Request object.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @return {Object} Response Object.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync // For backwards compatibility, the response object is a function that
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync // calls `next()` on the request object and returns the result.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync var res = function () {
d2f75d9ba9861d2f77e46d06b818eff7dc680982vboxsync Getter for the `routes` attribute.
d2f75d9ba9861d2f77e46d06b818eff7dc680982vboxsync @method _getRoutes
3e0090e25f336e84cefbe2697bec04151abfc44dvboxsync @return {Object[]} Array of route objects.
d2f75d9ba9861d2f77e46d06b818eff7dc680982vboxsync _getRoutes: function () {
5f33a06f645ac83b9e28a1b792fd80df96676e11vboxsync Gets the current full URL.
3e0090e25f336e84cefbe2697bec04151abfc44dvboxsync @method _getURL
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @return {String} URL.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync _getURL: function () {
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Returns `true` when the specified `url` is from the same origin as the
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync current URL; i.e., the protocol, host, and port of the URLs are the same.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync All host or path relative URLs are of the same origin. A scheme-relative URL
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync is first prefixed with the current scheme before being evaluated.
447cbf113f44132911fc13dc33cb26603759b82evboxsync @method _hasSameOrigin
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @param {String} url URL to compare origin with the current URL.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @return {Boolean} Whether the URL has the same origin of the current URL.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync var origin = ((url && url.match(this._regexUrlOrigin)) || [])[0];
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync // Prepend current scheme to scheme-relative URLs.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Joins the `root` URL to the specified _url_, normalizing leading/trailing
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync `/` characters.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync router.set('root', '/foo');
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync router._joinURL('bar'); // => '/foo/bar'
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync router._joinURL('/bar'); // => '/foo/bar'
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync router.set('root', '/foo/');
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync router._joinURL('bar'); // => '/foo/bar'
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync router._joinURL('/bar'); // => '/foo/bar'
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @method _joinURL
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @param {String} url URL to append to the `root` URL.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @return {String} Joined URL.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync return root && root.charAt(root.length - 1) === '/' ?
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Parses a URL query string into a key/value hash. If `Y.QueryString.parse` is
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync available, this method will be an alias to that.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @method _parseQuery
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @param {String} query Query string to parse.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @return {Object} Hash of key/value pairs for query parameters.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync _parseQuery: QS && QS.parse ? QS.parse : function (query) {
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync for (; i < len; ++i) {
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Queues up a `_save()` call to run after all previously-queued calls have
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync This is necessary because if we make multiple `_save()` calls before the
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync first call gets dispatched, then both calls will dispatch to the last call's
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync All arguments passed to `_queue()` will be passed on to `_save()` when the
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync queued function is executed.
4fac78486305f1f002adbf23953382e5d832af94vboxsync @method _queue
447cbf113f44132911fc13dc33cb26603759b82evboxsync @see _dequeue
447cbf113f44132911fc13dc33cb26603759b82evboxsync _queue: function () {
447cbf113f44132911fc13dc33cb26603759b82evboxsync // iOS <5 has buggy HTML5 history support, and needs to be
447cbf113f44132911fc13dc33cb26603759b82evboxsync // synchronous.
447cbf113f44132911fc13dc33cb26603759b82evboxsync // Wrapped in a timeout to ensure that _save() calls are
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync // always processed asynchronously. This ensures consistency
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync // between HTML5- and hash-based history.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync setTimeout(function () {
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync self._dispatching = true; // otherwise we'll dequeue too quickly
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync return !this._dispatching ? this._dequeue() : this;
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Saves a history entry using either `pushState()` or the location hash.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync This method enforces the same-origin security constraint; attempting to save
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync a `url` that is not from the same origin as the current URL will result in
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @method _save
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @param {String} [url] URL for the history entry.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @param {Boolean} [replace=false] If `true`, the current history entry will
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync be replaced instead of a new one being added.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync // Perform same-origin check on the specified URL.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Y.error('Security error: The new URL must be of the same origin as the current URL.');
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync return this;
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync // Force _ready to true to ensure that the history change is handled
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync // even if _save is called before the `ready` event fires.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync this._ready = true;
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync // Remove the root from the URL before it's set as the hash.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync // The `hashchange` event only fires when the new hash is actually
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync // different. This makes sure we'll always dequeue and dispatch,
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync // mimicking the HTML5 behavior.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync HistoryHash[replace ? 'replaceHash' : 'setHash'](url);
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync return this;
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Setter for the `routes` attribute.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @method _setRoutes
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @param {Object[]} routes Array of route objects.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @return {Object[]} Array of route objects.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync // -- Protected Event Handlers ---------------------------------------------
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Handles `history:change` and `hashchange` events.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @method _afterHistoryChange
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @param {EventFacade} e
859c9a7cc74066a52cf7e76d54169859e7705c3dvboxsync _afterHistoryChange: function (e) {
859c9a7cc74066a52cf7e76d54169859e7705c3dvboxsync var self = this,
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync self._dispatch(self._getPath(), self._getURL(), src);
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync // -- Default Event Handlers -----------------------------------------------
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Default handler for the `ready` event.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @method _defReadyFn
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @param {EventFacade} e
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync _defReadyFn: function (e) {
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync this._ready = true;
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync // -- Static Properties ----------------------------------------------------
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Whether or not this browser is capable of using HTML5 history.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Setting this to `false` will force the use of hash-based history even on
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync HTML5 browsers, but please don't do this unless you understand the
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync consequences.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @attribute html5
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @type Boolean
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync // Android versions lower than 3.0 are buggy and don't update
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync // window.location after a pushState() call, so we fall back to
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync // hash-based history for them.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync // See http://code.google.com/p/android/issues/detail?id=17471
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Absolute root path from which all routes should be evaluated.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync For example, if your router is running on a page at
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync `http://example.com/myapp/` and you add a route with the path `/`, your
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync route will never execute, because the path will always be preceded by
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync `/myapp`. Setting `root` to `/myapp` would cause all routes to be
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync evaluated relative to that root URL, so the `/` route would then execute
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync when the user browses to `http://example.com/myapp/`.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @attribute root
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @type String
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @default `''`
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Array of route objects.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync Each item in the array must be an object with the following properties:
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync * `path`: String or regex representing the path to match. See the docs
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync for the `route()` method for more details.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync * `callback`: Function or a string representing the name of a function
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync on this router instance that should be called when the route is
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync triggered. See the docs for the `route()` method for more details.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync This attribute is intended to be used to set routes at init time, or to
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync completely reset all routes after init. To add routes after init without
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync resetting all existing routes, use the `route()` method.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @attribute routes
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @type Object[]
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync @default `[]`
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync // Used as the default value for the `html5` attribute, and for testing.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync html5: Y.HistoryBase.html5 && (!Y.UA.android || Y.UA.android >= 3)
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsyncThe `Controller` class was deprecated in YUI 3.5.0 and is now an alias for the
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync`Router` class. Use that class instead. This alias will be removed in a future
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsyncversion of YUI.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync@class Controller
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync@constructor
4791a729647f035b6561d292c9f848dd1fc797a9vboxsync@extends Base
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync@deprecated Use `Router` instead.
febf3f1de573e25fb134b8453a22b0732b4c52e2vboxsync}, '@VERSION@' ,{optional:['querystring-parse'], requires:['array-extras', 'base-build', 'history']});