src/cm/media/js/lib/yui/yui3-3.15.0/build/router/router-debug.js
author Yves-Marie Haussonne <ymh.work+github@gmail.com>
Fri, 09 May 2014 18:35:26 +0200
changeset 656 a84519031134
parent 602 e16a97fb364a
permissions -rw-r--r--
add link to "privacy policy" in the header test
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
602
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
     1
YUI.add('router', function (Y, NAME) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
     2
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
     3
/**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
     4
Provides URL-based routing using HTML5 `pushState()` or the location hash.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
     5
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
     6
@module app
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
     7
@submodule router
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
     8
@since 3.4.0
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
     9
**/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    10
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    11
var HistoryHash = Y.HistoryHash,
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    12
    QS          = Y.QueryString,
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    13
    YArray      = Y.Array,
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    14
    YLang       = Y.Lang,
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    15
    YObject     = Y.Object,
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    16
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    17
    win = Y.config.win,
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    18
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    19
    // Holds all the active router instances. This supports the static
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    20
    // `dispatch()` method which causes all routers to dispatch.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    21
    instances = [],
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    22
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    23
    // We have to queue up pushState calls to avoid race conditions, since the
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    24
    // popstate event doesn't actually provide any info on what URL it's
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    25
    // associated with.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    26
    saveQueue = [],
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    27
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    28
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    29
    Fired when the router is ready to begin dispatching to route handlers.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    30
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    31
    You shouldn't need to wait for this event unless you plan to implement some
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    32
    kind of custom dispatching logic. It's used internally in order to avoid
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    33
    dispatching to an initial route if a browser history change occurs first.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    34
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    35
    @event ready
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    36
    @param {Boolean} dispatched `true` if routes have already been dispatched
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    37
      (most likely due to a history change).
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    38
    @fireOnce
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    39
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    40
    EVT_READY = 'ready';
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    41
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    42
/**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    43
Provides URL-based routing using HTML5 `pushState()` or the location hash.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    44
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    45
This makes it easy to wire up route handlers for different application states
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    46
while providing full back/forward navigation support and bookmarkable, shareable
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    47
URLs.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    48
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    49
@class Router
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    50
@param {Object} [config] Config properties.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    51
    @param {Boolean} [config.html5] Overrides the default capability detection
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    52
        and forces this router to use (`true`) or not use (`false`) HTML5
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    53
        history.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    54
    @param {String} [config.root=''] Root path from which all routes should be
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    55
        evaluated.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    56
    @param {Array} [config.routes=[]] Array of route definition objects.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    57
@constructor
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    58
@extends Base
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    59
@since 3.4.0
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    60
**/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    61
function Router() {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    62
    Router.superclass.constructor.apply(this, arguments);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    63
}
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    64
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    65
Y.Router = Y.extend(Router, Y.Base, {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    66
    // -- Protected Properties -------------------------------------------------
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    67
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    68
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    69
    Whether or not `_dispatch()` has been called since this router was
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    70
    instantiated.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    71
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    72
    @property _dispatched
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    73
    @type Boolean
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    74
    @default undefined
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    75
    @protected
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    76
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    77
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    78
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    79
    Whether or not we're currently in the process of dispatching to routes.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    80
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    81
    @property _dispatching
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    82
    @type Boolean
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    83
    @default undefined
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    84
    @protected
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    85
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    86
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    87
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    88
    History event handle for the `history:change` or `hashchange` event
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    89
    subscription.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    90
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    91
    @property _historyEvents
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    92
    @type EventHandle
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    93
    @protected
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    94
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    95
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    96
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    97
    Cached copy of the `html5` attribute for internal use.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    98
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
    99
    @property _html5
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   100
    @type Boolean
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   101
    @protected
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   102
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   103
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   104
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   105
    Map which holds the registered param handlers in the form:
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   106
    `name` -> RegExp | Function.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   107
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   108
    @property _params
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   109
    @type Object
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   110
    @protected
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   111
    @since 3.12.0
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   112
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   113
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   114
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   115
    Whether or not the `ready` event has fired yet.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   116
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   117
    @property _ready
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   118
    @type Boolean
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   119
    @default undefined
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   120
    @protected
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   121
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   122
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   123
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   124
    Regex used to break up a URL string around the URL's path.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   125
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   126
    Subpattern captures:
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   127
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   128
      1. Origin, everything before the URL's path-part.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   129
      2. The URL's path-part.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   130
      3. The URL's query.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   131
      4. The URL's hash fragment.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   132
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   133
    @property _regexURL
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   134
    @type RegExp
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   135
    @protected
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   136
    @since 3.5.0
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   137
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   138
    _regexURL: /^((?:[^\/#?:]+:\/\/|\/\/)[^\/]*)?([^?#]*)(\?[^#]*)?(#.*)?$/,
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   139
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   140
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   141
    Regex used to match parameter placeholders in route paths.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   142
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   143
    Subpattern captures:
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   144
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   145
      1. Parameter prefix character. Either a `:` for subpath parameters that
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   146
         should only match a single level of a path, or `*` for splat parameters
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   147
         that should match any number of path levels.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   148
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   149
      2. Parameter name, if specified, otherwise it is a wildcard match.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   150
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   151
    @property _regexPathParam
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   152
    @type RegExp
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   153
    @protected
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   154
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   155
    _regexPathParam: /([:*])([\w\-]+)?/g,
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   156
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   157
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   158
    Regex that matches and captures the query portion of a URL, minus the
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   159
    preceding `?` character, and discarding the hash portion of the URL if any.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   160
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   161
    @property _regexUrlQuery
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   162
    @type RegExp
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   163
    @protected
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   164
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   165
    _regexUrlQuery: /\?([^#]*).*$/,
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   166
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   167
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   168
    Regex that matches everything before the path portion of a URL (the origin).
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   169
    This will be used to strip this part of the URL from a string when we
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   170
    only want the path.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   171
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   172
    @property _regexUrlOrigin
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   173
    @type RegExp
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   174
    @protected
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   175
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   176
    _regexUrlOrigin: /^(?:[^\/#?:]+:\/\/|\/\/)[^\/]*/,
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   177
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   178
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   179
    Collection of registered routes.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   180
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   181
    @property _routes
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   182
    @type Array
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   183
    @protected
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   184
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   185
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   186
    // -- Lifecycle Methods ----------------------------------------------------
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   187
    initializer: function (config) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   188
        var self = this;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   189
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   190
        self._html5  = self.get('html5');
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   191
        self._params = {};
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   192
        self._routes = [];
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   193
        self._url    = self._getURL();
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   194
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   195
        // Necessary because setters don't run on init.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   196
        self._setRoutes(config && config.routes ? config.routes :
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   197
                self.get('routes'));
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   198
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   199
        // Set up a history instance or hashchange listener.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   200
        if (self._html5) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   201
            self._history       = new Y.HistoryHTML5({force: true});
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   202
            self._historyEvents =
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   203
                    Y.after('history:change', self._afterHistoryChange, self);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   204
        } else {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   205
            self._historyEvents =
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   206
                    Y.on('hashchange', self._afterHistoryChange, win, self);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   207
        }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   208
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   209
        // Fire a `ready` event once we're ready to route. We wait first for all
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   210
        // subclass initializers to finish, then for window.onload, and then an
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   211
        // additional 20ms to allow the browser to fire a useless initial
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   212
        // `popstate` event if it wants to (and Chrome always wants to).
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   213
        self.publish(EVT_READY, {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   214
            defaultFn  : self._defReadyFn,
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   215
            fireOnce   : true,
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   216
            preventable: false
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   217
        });
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   218
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   219
        self.once('initializedChange', function () {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   220
            Y.once('load', function () {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   221
                setTimeout(function () {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   222
                    self.fire(EVT_READY, {dispatched: !!self._dispatched});
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   223
                }, 20);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   224
            });
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   225
        });
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   226
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   227
        // Store this router in the collection of all active router instances.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   228
        instances.push(this);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   229
    },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   230
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   231
    destructor: function () {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   232
        var instanceIndex = YArray.indexOf(instances, this);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   233
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   234
        // Remove this router from the collection of active router instances.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   235
        if (instanceIndex > -1) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   236
            instances.splice(instanceIndex, 1);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   237
        }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   238
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   239
        if (this._historyEvents) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   240
            this._historyEvents.detach();
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   241
        }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   242
    },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   243
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   244
    // -- Public Methods -------------------------------------------------------
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   245
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   246
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   247
    Dispatches to the first route handler that matches the current URL, if any.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   248
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   249
    If `dispatch()` is called before the `ready` event has fired, it will
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   250
    automatically wait for the `ready` event before dispatching. Otherwise it
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   251
    will dispatch immediately.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   252
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   253
    @method dispatch
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   254
    @chainable
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   255
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   256
    dispatch: function () {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   257
        this.once(EVT_READY, function () {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   258
            var req, res;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   259
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   260
            this._ready = true;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   261
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   262
            if (!this.upgrade()) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   263
                req = this._getRequest('dispatch');
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   264
                res = this._getResponse(req);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   265
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   266
                this._dispatch(req, res);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   267
            }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   268
        });
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   269
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   270
        return this;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   271
    },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   272
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   273
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   274
    Gets the current route path.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   275
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   276
    @method getPath
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   277
    @return {String} Current route path.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   278
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   279
    getPath: function () {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   280
        return this._getPath();
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   281
    },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   282
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   283
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   284
    Returns `true` if this router has at least one route that matches the
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   285
    specified URL, `false` otherwise.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   286
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   287
    This method enforces the same-origin security constraint on the specified
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   288
    `url`; any URL which is not from the same origin as the current URL will
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   289
    always return `false`.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   290
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   291
    @method hasRoute
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   292
    @param {String} url URL to match.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   293
    @return {Boolean} `true` if there's at least one matching route, `false`
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   294
      otherwise.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   295
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   296
    hasRoute: function (url) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   297
        var path;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   298
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   299
        if (!this._hasSameOrigin(url)) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   300
            return false;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   301
        }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   302
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   303
        if (!this._html5) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   304
            url = this._upgradeURL(url);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   305
        }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   306
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   307
        // Get just the path portion of the specified `url`.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   308
        path = this.removeQuery(url.replace(this._regexUrlOrigin, ''));
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   309
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   310
        return !!this.match(path).length;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   311
    },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   312
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   313
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   314
    Returns an array of route objects that match the specified URL path.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   315
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   316
    If this router has a `root`, then the specified `path` _must_ be
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   317
    semantically within the `root` path to match any routes.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   318
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   319
    This method is called internally to determine which routes match the current
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   320
    path whenever the URL changes. You may override it if you want to customize
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   321
    the route matching logic, although this usually shouldn't be necessary.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   322
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   323
    Each returned route object has the following properties:
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   324
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   325
      * `callback`: A function or a string representing the name of a function
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   326
        this router that should be executed when the route is triggered.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   327
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   328
      * `keys`: An array of strings representing the named parameters defined in
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   329
        the route's path specification, if any.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   330
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   331
      * `path`: The route's path specification, which may be either a string or
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   332
        a regex.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   333
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   334
      * `regex`: A regular expression version of the route's path specification.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   335
        This regex is used to determine whether the route matches a given path.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   336
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   337
    @example
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   338
        router.route('/foo', function () {});
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   339
        router.match('/foo');
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   340
        // => [{callback: ..., keys: [], path: '/foo', regex: ...}]
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   341
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   342
    @method match
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   343
    @param {String} path URL path to match. This should be an absolute path that
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   344
        starts with a slash: "/".
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   345
    @return {Object[]} Array of route objects that match the specified path.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   346
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   347
    match: function (path) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   348
        var root = this.get('root');
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   349
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   350
        if (root) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   351
            // The `path` must be semantically within this router's `root` path
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   352
            // or mount point, if it's not then no routes should be considered a
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   353
            // match.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   354
            if (!this._pathHasRoot(root, path)) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   355
                return [];
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   356
            }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   357
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   358
            // Remove this router's `root` from the `path` before checking the
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   359
            // routes for any matches.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   360
            path = this.removeRoot(path);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   361
        }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   362
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   363
        return YArray.filter(this._routes, function (route) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   364
            return path.search(route.regex) > -1;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   365
        });
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   366
    },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   367
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   368
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   369
    Adds a handler for a route param specified by _name_.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   370
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   371
    Param handlers can be registered via this method and are used to
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   372
    validate/format values of named params in routes before dispatching to the
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   373
    route's handler functions. Using param handlers allows routes to defined
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   374
    using string paths which allows for `req.params` to use named params, but
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   375
    still applying extra validation or formatting to the param values parsed
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   376
    from the URL.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   377
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   378
    If a param handler regex or function returns a value of `false`, `null`,
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   379
    `undefined`, or `NaN`, the current route will not match and be skipped. All
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   380
    other return values will be used in place of the original param value parsed
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   381
    from the URL.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   382
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   383
    @example
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   384
        router.param('postId', function (value) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   385
            return parseInt(value, 10);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   386
        });
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   387
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   388
        router.param('username', /^\w+$/);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   389
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   390
        router.route('/posts/:postId', function (req) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   391
            Y.log('Post: ' + req.params.id);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   392
        });
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   393
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   394
        router.route('/users/:username', function (req) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   395
            // `req.params.username` is an array because the result of calling
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   396
            // `exec()` on the regex is assigned as the param's value.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   397
            Y.log('User: ' + req.params.username[0]);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   398
        });
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   399
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   400
        router.route('*', function () {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   401
            Y.log('Catch-all no routes matched!');
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   402
        });
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   403
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   404
        // URLs which match routes:
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   405
        router.save('/posts/1');     // => "Post: 1"
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   406
        router.save('/users/ericf'); // => "User: ericf"
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   407
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   408
        // URLs which do not match routes because params fail validation:
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   409
        router.save('/posts/a');            // => "Catch-all no routes matched!"
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   410
        router.save('/users/ericf,rgrove'); // => "Catch-all no routes matched!"
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   411
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   412
    @method param
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   413
    @param {String} name Name of the param used in route paths.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   414
    @param {Function|RegExp} handler Function to invoke or regular expression to
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   415
        `exec()` during route dispatching whose return value is used as the new
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   416
        param value. Values of `false`, `null`, `undefined`, or `NaN` will cause
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   417
        the current route to not match and be skipped. When a function is
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   418
        specified, it will be invoked in the context of this instance with the
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   419
        following parameters:
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   420
      @param {String} handler.value The current param value parsed from the URL.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   421
      @param {String} handler.name The name of the param.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   422
    @chainable
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   423
    @since 3.12.0
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   424
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   425
    param: function (name, handler) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   426
        this._params[name] = handler;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   427
        return this;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   428
    },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   429
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   430
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   431
    Removes the `root` URL from the front of _url_ (if it's there) and returns
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   432
    the result. The returned path will always have a leading `/`.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   433
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   434
    @method removeRoot
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   435
    @param {String} url URL.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   436
    @return {String} Rootless path.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   437
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   438
    removeRoot: function (url) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   439
        var root = this.get('root'),
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   440
            path;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   441
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   442
        // Strip out the non-path part of the URL, if any (e.g.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   443
        // "http://foo.com"), so that we're left with just the path.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   444
        url = url.replace(this._regexUrlOrigin, '');
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   445
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   446
        // Return the host-less URL if there's no `root` path to further remove.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   447
        if (!root) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   448
            return url;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   449
        }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   450
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   451
        path = this.removeQuery(url);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   452
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   453
        // Remove the `root` from the `url` if it's the same or its path is
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   454
        // semantically within the root path.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   455
        if (path === root || this._pathHasRoot(root, path)) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   456
            url = url.substring(root.length);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   457
        }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   458
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   459
        return url.charAt(0) === '/' ? url : '/' + url;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   460
    },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   461
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   462
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   463
    Removes a query string from the end of the _url_ (if one exists) and returns
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   464
    the result.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   465
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   466
    @method removeQuery
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   467
    @param {String} url URL.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   468
    @return {String} Queryless path.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   469
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   470
    removeQuery: function (url) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   471
        return url.replace(/\?.*$/, '');
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   472
    },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   473
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   474
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   475
    Replaces the current browser history entry with a new one, and dispatches to
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   476
    the first matching route handler, if any.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   477
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   478
    Behind the scenes, this method uses HTML5 `pushState()` in browsers that
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   479
    support it (or the location hash in older browsers and IE) to change the
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   480
    URL.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   481
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   482
    The specified URL must share the same origin (i.e., protocol, host, and
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   483
    port) as the current page, or an error will occur.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   484
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   485
    @example
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   486
        // Starting URL: http://example.com/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   487
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   488
        router.replace('/path/');
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   489
        // New URL: http://example.com/path/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   490
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   491
        router.replace('/path?foo=bar');
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   492
        // New URL: http://example.com/path?foo=bar
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   493
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   494
        router.replace('/');
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   495
        // New URL: http://example.com/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   496
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   497
    @method replace
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   498
    @param {String} [url] URL to set. This URL needs to be of the same origin as
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   499
      the current URL. This can be a URL relative to the router's `root`
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   500
      attribute. If no URL is specified, the page's current URL will be used.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   501
    @chainable
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   502
    @see save()
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   503
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   504
    replace: function (url) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   505
        return this._queue(url, true);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   506
    },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   507
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   508
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   509
    Adds a route handler for the specified `route`.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   510
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   511
    The `route` parameter may be a string or regular expression to represent a
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   512
    URL path, or a route object. If it's a string (which is most common), it may
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   513
    contain named parameters: `:param` will match any single part of a URL path
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   514
    (not including `/` characters), and `*param` will match any number of parts
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   515
    of a URL path (including `/` characters). These named parameters will be
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   516
    made available as keys on the `req.params` object that's passed to route
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   517
    handlers.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   518
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   519
    If the `route` parameter is a regex, all pattern matches will be made
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   520
    available as numbered keys on `req.params`, starting with `0` for the full
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   521
    match, then `1` for the first subpattern match, and so on.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   522
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   523
    Alternatively, an object can be provided to represent the route and it may
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   524
    contain a `path` property which is a string or regular expression which
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   525
    causes the route to be process as described above. If the route object
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   526
    already contains a `regex` or `regexp` property, the route will be
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   527
    considered fully-processed and will be associated with any `callacks`
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   528
    specified on the object and those specified as parameters to this method.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   529
    **Note:** Any additional data contained on the route object will be
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   530
    preserved.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   531
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   532
    Here's a set of sample routes along with URL paths that they match:
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   533
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   534
      * Route: `/photos/:tag/:page`
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   535
        * URL: `/photos/kittens/1`, params: `{tag: 'kittens', page: '1'}`
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   536
        * URL: `/photos/puppies/2`, params: `{tag: 'puppies', page: '2'}`
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   537
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   538
      * Route: `/file/*path`
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   539
        * URL: `/file/foo/bar/baz.txt`, params: `{path: 'foo/bar/baz.txt'}`
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   540
        * URL: `/file/foo`, params: `{path: 'foo'}`
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   541
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   542
    **Middleware**: Routes also support an arbitrary number of callback
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   543
    functions. This allows you to easily reuse parts of your route-handling code
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   544
    with different route. This method is liberal in how it processes the
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   545
    specified `callbacks`, you can specify them as separate arguments, or as
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   546
    arrays, or both.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   547
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   548
    If multiple route match a given URL, they will be executed in the order they
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   549
    were added. The first route that was added will be the first to be executed.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   550
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   551
    **Passing Control**: Invoking the `next()` function within a route callback
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   552
    will pass control to the next callback function (if any) or route handler
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   553
    (if any). If a value is passed to `next()`, it's assumed to be an error,
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   554
    therefore stopping the dispatch chain, unless that value is: `"route"`,
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   555
    which is special case and dispatching will skip to the next route handler.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   556
    This allows middleware to skip any remaining middleware for a particular
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   557
    route.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   558
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   559
    @example
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   560
        router.route('/photos/:tag/:page', function (req, res, next) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   561
            Y.log('Current tag: ' + req.params.tag);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   562
            Y.log('Current page number: ' + req.params.page);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   563
        });
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   564
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   565
        // Using middleware.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   566
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   567
        router.findUser = function (req, res, next) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   568
            req.user = this.get('users').findById(req.params.user);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   569
            next();
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   570
        };
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   571
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   572
        router.route('/users/:user', 'findUser', function (req, res, next) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   573
            // The `findUser` middleware puts the `user` object on the `req`.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   574
            Y.log('Current user:' req.user.get('name'));
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   575
        });
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   576
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   577
    @method route
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   578
    @param {String|RegExp|Object} route Route to match. May be a string or a
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   579
      regular expression, or a route object.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   580
    @param {Array|Function|String} callbacks* Callback functions to call
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   581
        whenever this route is triggered. These can be specified as separate
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   582
        arguments, or in arrays, or both. If a callback is specified as a
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   583
        string, the named function will be called on this router instance.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   584
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   585
      @param {Object} callbacks.req Request object containing information about
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   586
          the request. It contains the following properties.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   587
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   588
        @param {Array|Object} callbacks.req.params Captured parameters matched
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   589
          by the route path specification. If a string path was used and
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   590
          contained named parameters, then this will be a key/value hash mapping
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   591
          parameter names to their matched values. If a regex path was used,
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   592
          this will be an array of subpattern matches starting at index 0 for
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   593
          the full match, then 1 for the first subpattern match, and so on.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   594
        @param {String} callbacks.req.path The current URL path.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   595
        @param {Number} callbacks.req.pendingCallbacks Number of remaining
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   596
          callbacks the route handler has after this one in the dispatch chain.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   597
        @param {Number} callbacks.req.pendingRoutes Number of matching routes
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   598
          after this one in the dispatch chain.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   599
        @param {Object} callbacks.req.query Query hash representing the URL
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   600
          query string, if any. Parameter names are keys, and are mapped to
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   601
          parameter values.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   602
        @param {Object} callbacks.req.route Reference to the current route
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   603
          object whose callbacks are being dispatched.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   604
        @param {Object} callbacks.req.router Reference to this router instance.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   605
        @param {String} callbacks.req.src What initiated the dispatch. In an
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   606
          HTML5 browser, when the back/forward buttons are used, this property
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   607
          will have a value of "popstate". When the `dispath()` method is
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   608
          called, the `src` will be `"dispatch"`.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   609
        @param {String} callbacks.req.url The full URL.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   610
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   611
      @param {Object} callbacks.res Response object containing methods and
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   612
          information that relate to responding to a request. It contains the
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   613
          following properties.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   614
        @param {Object} callbacks.res.req Reference to the request object.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   615
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   616
      @param {Function} callbacks.next Function to pass control to the next
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   617
          callback or the next matching route if no more callbacks (middleware)
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   618
          exist for the current route handler. If you don't call this function,
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   619
          then no further callbacks or route handlers will be executed, even if
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   620
          there are more that match. If you do call this function, then the next
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   621
          callback (if any) or matching route handler (if any) will be called.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   622
          All of these functions will receive the same `req` and `res` objects
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   623
          that were passed to this route (so you can use these objects to pass
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   624
          data along to subsequent callbacks and routes).
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   625
        @param {String} [callbacks.next.err] Optional error which will stop the
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   626
          dispatch chaining for this `req`, unless the value is `"route"`, which
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   627
          is special cased to jump skip past any callbacks for the current route
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   628
          and pass control the next route handler.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   629
    @chainable
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   630
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   631
    route: function (route, callbacks) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   632
        // Grab callback functions from var-args.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   633
        callbacks = YArray(arguments, 1, true);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   634
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   635
        var keys, regex;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   636
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   637
        // Supports both the `route(path, callbacks)` and `route(config)` call
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   638
        // signatures, allowing for fully-processed route configs to be passed.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   639
        if (typeof route === 'string' || YLang.isRegExp(route)) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   640
            // Flatten `callbacks` into a single dimension array.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   641
            callbacks = YArray.flatten(callbacks);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   642
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   643
            keys  = [];
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   644
            regex = this._getRegex(route, keys);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   645
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   646
            route = {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   647
                callbacks: callbacks,
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   648
                keys     : keys,
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   649
                path     : route,
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   650
                regex    : regex
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   651
            };
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   652
        } else {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   653
            // Look for any configured `route.callbacks` and fallback to
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   654
            // `route.callback` for back-compat, append var-arg `callbacks`,
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   655
            // then flatten the entire collection to a single dimension array.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   656
            callbacks = YArray.flatten(
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   657
                [route.callbacks || route.callback || []].concat(callbacks)
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   658
            );
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   659
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   660
            // Check for previously generated regex, also fallback to `regexp`
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   661
            // for greater interop.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   662
            keys  = route.keys;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   663
            regex = route.regex || route.regexp;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   664
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   665
            // Generates the route's regex if it doesn't already have one.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   666
            if (!regex) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   667
                keys  = [];
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   668
                regex = this._getRegex(route.path, keys);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   669
            }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   670
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   671
            // Merge specified `route` config object with processed data.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   672
            route = Y.merge(route, {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   673
                callbacks: callbacks,
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   674
                keys     : keys,
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   675
                path     : route.path || regex,
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   676
                regex    : regex
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   677
            });
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   678
        }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   679
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   680
        this._routes.push(route);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   681
        return this;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   682
    },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   683
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   684
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   685
    Saves a new browser history entry and dispatches to the first matching route
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   686
    handler, if any.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   687
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   688
    Behind the scenes, this method uses HTML5 `pushState()` in browsers that
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   689
    support it (or the location hash in older browsers and IE) to change the
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   690
    URL and create a history entry.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   691
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   692
    The specified URL must share the same origin (i.e., protocol, host, and
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   693
    port) as the current page, or an error will occur.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   694
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   695
    @example
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   696
        // Starting URL: http://example.com/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   697
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   698
        router.save('/path/');
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   699
        // New URL: http://example.com/path/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   700
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   701
        router.save('/path?foo=bar');
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   702
        // New URL: http://example.com/path?foo=bar
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   703
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   704
        router.save('/');
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   705
        // New URL: http://example.com/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   706
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   707
    @method save
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   708
    @param {String} [url] URL to set. This URL needs to be of the same origin as
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   709
      the current URL. This can be a URL relative to the router's `root`
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   710
      attribute. If no URL is specified, the page's current URL will be used.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   711
    @chainable
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   712
    @see replace()
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   713
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   714
    save: function (url) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   715
        return this._queue(url);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   716
    },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   717
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   718
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   719
    Upgrades a hash-based URL to an HTML5 URL if necessary. In non-HTML5
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   720
    browsers, this method is a noop.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   721
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   722
    @method upgrade
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   723
    @return {Boolean} `true` if the URL was upgraded, `false` otherwise.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   724
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   725
    upgrade: function () {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   726
        if (!this._html5) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   727
            return false;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   728
        }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   729
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   730
        // Get the resolve hash path.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   731
        var hashPath = this._getHashPath();
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   732
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   733
        if (hashPath) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   734
            // This is an HTML5 browser and we have a hash-based path in the
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   735
            // URL, so we need to upgrade the URL to a non-hash URL. This
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   736
            // will trigger a `history:change` event, which will in turn
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   737
            // trigger a dispatch.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   738
            this.once(EVT_READY, function () {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   739
                this.replace(hashPath);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   740
            });
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   741
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   742
            return true;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   743
        }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   744
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   745
        return false;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   746
    },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   747
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   748
    // -- Protected Methods ----------------------------------------------------
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   749
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   750
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   751
    Wrapper around `decodeURIComponent` that also converts `+` chars into
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   752
    spaces.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   753
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   754
    @method _decode
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   755
    @param {String} string String to decode.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   756
    @return {String} Decoded string.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   757
    @protected
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   758
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   759
    _decode: function (string) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   760
        return decodeURIComponent(string.replace(/\+/g, ' '));
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   761
    },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   762
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   763
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   764
    Shifts the topmost `_save()` call off the queue and executes it. Does
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   765
    nothing if the queue is empty.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   766
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   767
    @method _dequeue
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   768
    @chainable
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   769
    @see _queue
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   770
    @protected
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   771
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   772
    _dequeue: function () {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   773
        var self = this,
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   774
            fn;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   775
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   776
        // If window.onload hasn't yet fired, wait until it has before
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   777
        // dequeueing. This will ensure that we don't call pushState() before an
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   778
        // initial popstate event has fired.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   779
        if (!YUI.Env.windowLoaded) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   780
            Y.once('load', function () {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   781
                self._dequeue();
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   782
            });
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   783
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   784
            return this;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   785
        }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   786
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   787
        fn = saveQueue.shift();
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   788
        return fn ? fn() : this;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   789
    },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   790
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   791
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   792
    Dispatches to the first route handler that matches the specified _path_.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   793
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   794
    If called before the `ready` event has fired, the dispatch will be aborted.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   795
    This ensures normalized behavior between Chrome (which fires a `popstate`
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   796
    event on every pageview) and other browsers (which do not).
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   797
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   798
    @method _dispatch
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   799
    @param {object} req Request object.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   800
    @param {String} res Response object.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   801
    @chainable
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   802
    @protected
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   803
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   804
    _dispatch: function (req, res) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   805
        var self      = this,
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   806
            decode    = self._decode,
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   807
            routes    = self.match(req.path),
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   808
            callbacks = [],
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   809
            matches, paramsMatch, routePath;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   810
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   811
        self._dispatching = self._dispatched = true;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   812
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   813
        if (!routes || !routes.length) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   814
            self._dispatching = false;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   815
            return self;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   816
        }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   817
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   818
        routePath = self.removeRoot(req.path);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   819
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   820
        function next(err) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   821
            var callback, name, route;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   822
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   823
            if (err) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   824
                // Special case "route" to skip to the next route handler
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   825
                // avoiding any additional callbacks for the current route.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   826
                if (err === 'route') {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   827
                    callbacks = [];
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   828
                    next();
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   829
                } else {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   830
                    Y.error(err);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   831
                }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   832
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   833
            } else if ((callback = callbacks.shift())) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   834
                if (typeof callback === 'string') {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   835
                    name     = callback;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   836
                    callback = self[name];
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   837
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   838
                    if (!callback) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   839
                        Y.error('Router: Callback not found: ' + name, null, 'router');
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   840
                    }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   841
                }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   842
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   843
                // Allow access to the number of remaining callbacks for the
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   844
                // route.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   845
                req.pendingCallbacks = callbacks.length;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   846
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   847
                callback.call(self, req, res, next);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   848
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   849
            } else if ((route = routes.shift())) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   850
                // Make a copy of this route's `callbacks` so the original array
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   851
                // is preserved.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   852
                callbacks = route.callbacks.concat();
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   853
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   854
                // Decode each of the path matches so that the any URL-encoded
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   855
                // path segments are decoded in the `req.params` object.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   856
                matches = YArray.map(route.regex.exec(routePath) || [],
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   857
                        function (match) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   858
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   859
                    // Decode matches, or coerce `undefined` matches to an empty
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   860
                    // string to match expectations of working with `req.params`
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   861
                    // in the content of route dispatching, and normalize
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   862
                    // browser differences in their handling of regex NPCGs:
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   863
                    // https://github.com/yui/yui3/issues/1076
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   864
                    return (match && decode(match)) || '';
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   865
                });
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   866
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   867
                paramsMatch = true;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   868
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   869
                // Use named keys for parameter names if the route path contains
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   870
                // named keys. Otherwise, use numerical match indices.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   871
                if (matches.length === route.keys.length + 1) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   872
                    matches    = matches.slice(1);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   873
                    req.params = YArray.hash(route.keys, matches);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   874
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   875
                    paramsMatch = YArray.every(route.keys, function (key, i) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   876
                        var paramHandler = self._params[key],
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   877
                            value        = matches[i];
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   878
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   879
                        if (paramHandler && value && typeof value === 'string') {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   880
                            // Check if `paramHandler` is a RegExp, becuase this
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   881
                            // is true in Android 2.3 and other browsers!
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   882
                            // `typeof /.*/ === 'function'`
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   883
                            value = YLang.isRegExp(paramHandler) ?
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   884
                                    paramHandler.exec(value) :
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   885
                                    paramHandler.call(self, value, key);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   886
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   887
                            if (value !== false && YLang.isValue(value)) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   888
                                req.params[key] = value;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   889
                                return true;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   890
                            }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   891
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   892
                            return false;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   893
                        }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   894
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   895
                        return true;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   896
                    });
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   897
                } else {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   898
                    req.params = matches.concat();
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   899
                }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   900
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   901
                // Allow access to current route and the number of remaining
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   902
                // routes for this request.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   903
                req.route         = route;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   904
                req.pendingRoutes = routes.length;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   905
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   906
                // Execute this route's `callbacks` or skip this route because
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   907
                // some of the param regexps don't match.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   908
                if (paramsMatch) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   909
                    next();
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   910
                } else {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   911
                    next('route');
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   912
                }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   913
            }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   914
        }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   915
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   916
        next();
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   917
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   918
        self._dispatching = false;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   919
        return self._dequeue();
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   920
    },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   921
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   922
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   923
    Returns the resolved path from the hash fragment, or an empty string if the
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   924
    hash is not path-like.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   925
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   926
    @method _getHashPath
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   927
    @param {String} [hash] Hash fragment to resolve into a path. By default this
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   928
        will be the hash from the current URL.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   929
    @return {String} Current hash path, or an empty string if the hash is empty.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   930
    @protected
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   931
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   932
    _getHashPath: function (hash) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   933
        hash || (hash = HistoryHash.getHash());
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   934
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   935
        // Make sure the `hash` is path-like.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   936
        if (hash && hash.charAt(0) === '/') {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   937
            return this._joinURL(hash);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   938
        }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   939
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   940
        return '';
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   941
    },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   942
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   943
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   944
    Gets the location origin (i.e., protocol, host, and port) as a URL.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   945
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   946
    @example
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   947
        http://example.com
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   948
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   949
    @method _getOrigin
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   950
    @return {String} Location origin (i.e., protocol, host, and port).
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   951
    @protected
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   952
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   953
    _getOrigin: function () {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   954
        var location = Y.getLocation();
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   955
        return location.origin || (location.protocol + '//' + location.host);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   956
    },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   957
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   958
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   959
    Getter for the `params` attribute.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   960
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   961
    @method _getParams
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   962
    @return {Object} Mapping of param handlers: `name` -> RegExp | Function.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   963
    @protected
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   964
    @since 3.12.0
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   965
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   966
    _getParams: function () {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   967
        return Y.merge(this._params);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   968
    },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   969
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   970
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   971
    Gets the current route path.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   972
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   973
    @method _getPath
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   974
    @return {String} Current route path.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   975
    @protected
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   976
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   977
    _getPath: function () {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   978
        var path = (!this._html5 && this._getHashPath()) ||
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   979
                Y.getLocation().pathname;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   980
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   981
        return this.removeQuery(path);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   982
    },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   983
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   984
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   985
    Returns the current path root after popping off the last path segment,
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   986
    making it useful for resolving other URL paths against.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   987
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   988
    The path root will always begin and end with a '/'.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   989
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   990
    @method _getPathRoot
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   991
    @return {String} The URL's path root.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   992
    @protected
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   993
    @since 3.5.0
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   994
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   995
    _getPathRoot: function () {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   996
        var slash = '/',
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   997
            path  = Y.getLocation().pathname,
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   998
            segments;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
   999
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1000
        if (path.charAt(path.length - 1) === slash) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1001
            return path;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1002
        }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1003
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1004
        segments = path.split(slash);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1005
        segments.pop();
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1006
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1007
        return segments.join(slash) + slash;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1008
    },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1009
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1010
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1011
    Gets the current route query string.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1012
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1013
    @method _getQuery
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1014
    @return {String} Current route query string.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1015
    @protected
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1016
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1017
    _getQuery: function () {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1018
        var location = Y.getLocation(),
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1019
            hash, matches;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1020
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1021
        if (this._html5) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1022
            return location.search.substring(1);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1023
        }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1024
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1025
        hash    = HistoryHash.getHash();
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1026
        matches = hash.match(this._regexUrlQuery);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1027
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1028
        return hash && matches ? matches[1] : location.search.substring(1);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1029
    },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1030
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1031
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1032
    Creates a regular expression from the given route specification. If _path_
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1033
    is already a regex, it will be returned unmodified.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1034
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1035
    @method _getRegex
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1036
    @param {String|RegExp} path Route path specification.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1037
    @param {Array} keys Array reference to which route parameter names will be
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1038
      added.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1039
    @return {RegExp} Route regex.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1040
    @protected
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1041
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1042
    _getRegex: function (path, keys) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1043
        if (YLang.isRegExp(path)) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1044
            return path;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1045
        }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1046
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1047
        // Special case for catchall paths.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1048
        if (path === '*') {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1049
            return (/.*/);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1050
        }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1051
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1052
        path = path.replace(this._regexPathParam, function (match, operator, key) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1053
            // Only `*` operators are supported for key-less matches to allowing
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1054
            // in-path wildcards like: '/foo/*'.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1055
            if (!key) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1056
                return operator === '*' ? '.*' : match;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1057
            }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1058
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1059
            keys.push(key);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1060
            return operator === '*' ? '(.*?)' : '([^/#?]*)';
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1061
        });
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1062
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1063
        return new RegExp('^' + path + '$');
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1064
    },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1065
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1066
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1067
    Gets a request object that can be passed to a route handler.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1068
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1069
    @method _getRequest
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1070
    @param {String} src What initiated the URL change and need for the request.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1071
    @return {Object} Request object.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1072
    @protected
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1073
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1074
    _getRequest: function (src) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1075
        return {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1076
            path  : this._getPath(),
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1077
            query : this._parseQuery(this._getQuery()),
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1078
            url   : this._getURL(),
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1079
            router: this,
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1080
            src   : src
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1081
        };
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1082
    },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1083
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1084
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1085
    Gets a response object that can be passed to a route handler.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1086
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1087
    @method _getResponse
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1088
    @param {Object} req Request object.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1089
    @return {Object} Response Object.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1090
    @protected
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1091
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1092
    _getResponse: function (req) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1093
        return {req: req};
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1094
    },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1095
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1096
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1097
    Getter for the `routes` attribute.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1098
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1099
    @method _getRoutes
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1100
    @return {Object[]} Array of route objects.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1101
    @protected
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1102
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1103
    _getRoutes: function () {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1104
        return this._routes.concat();
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1105
    },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1106
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1107
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1108
    Gets the current full URL.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1109
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1110
    @method _getURL
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1111
    @return {String} URL.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1112
    @protected
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1113
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1114
    _getURL: function () {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1115
        var url = Y.getLocation().toString();
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1116
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1117
        if (!this._html5) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1118
            url = this._upgradeURL(url);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1119
        }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1120
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1121
        return url;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1122
    },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1123
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1124
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1125
    Returns `true` when the specified `url` is from the same origin as the
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1126
    current URL; i.e., the protocol, host, and port of the URLs are the same.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1127
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1128
    All host or path relative URLs are of the same origin. A scheme-relative URL
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1129
    is first prefixed with the current scheme before being evaluated.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1130
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1131
    @method _hasSameOrigin
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1132
    @param {String} url URL to compare origin with the current URL.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1133
    @return {Boolean} Whether the URL has the same origin of the current URL.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1134
    @protected
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1135
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1136
    _hasSameOrigin: function (url) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1137
        var origin = ((url && url.match(this._regexUrlOrigin)) || [])[0];
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1138
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1139
        // Prepend current scheme to scheme-relative URLs.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1140
        if (origin && origin.indexOf('//') === 0) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1141
            origin = Y.getLocation().protocol + origin;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1142
        }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1143
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1144
        return !origin || origin === this._getOrigin();
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1145
    },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1146
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1147
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1148
    Joins the `root` URL to the specified _url_, normalizing leading/trailing
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1149
    `/` characters.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1150
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1151
    @example
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1152
        router.set('root', '/foo');
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1153
        router._joinURL('bar');  // => '/foo/bar'
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1154
        router._joinURL('/bar'); // => '/foo/bar'
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1155
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1156
        router.set('root', '/foo/');
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1157
        router._joinURL('bar');  // => '/foo/bar'
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1158
        router._joinURL('/bar'); // => '/foo/bar'
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1159
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1160
    @method _joinURL
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1161
    @param {String} url URL to append to the `root` URL.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1162
    @return {String} Joined URL.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1163
    @protected
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1164
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1165
    _joinURL: function (url) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1166
        var root = this.get('root');
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1167
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1168
        // Causes `url` to _always_ begin with a "/".
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1169
        url = this.removeRoot(url);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1170
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1171
        if (url.charAt(0) === '/') {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1172
            url = url.substring(1);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1173
        }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1174
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1175
        return root && root.charAt(root.length - 1) === '/' ?
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1176
                root + url :
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1177
                root + '/' + url;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1178
    },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1179
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1180
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1181
    Returns a normalized path, ridding it of any '..' segments and properly
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1182
    handling leading and trailing slashes.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1183
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1184
    @method _normalizePath
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1185
    @param {String} path URL path to normalize.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1186
    @return {String} Normalized path.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1187
    @protected
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1188
    @since 3.5.0
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1189
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1190
    _normalizePath: function (path) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1191
        var dots  = '..',
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1192
            slash = '/',
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1193
            i, len, normalized, segments, segment, stack;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1194
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1195
        if (!path || path === slash) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1196
            return slash;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1197
        }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1198
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1199
        segments = path.split(slash);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1200
        stack    = [];
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1201
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1202
        for (i = 0, len = segments.length; i < len; ++i) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1203
            segment = segments[i];
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1204
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1205
            if (segment === dots) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1206
                stack.pop();
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1207
            } else if (segment) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1208
                stack.push(segment);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1209
            }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1210
        }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1211
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1212
        normalized = slash + stack.join(slash);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1213
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1214
        // Append trailing slash if necessary.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1215
        if (normalized !== slash && path.charAt(path.length - 1) === slash) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1216
            normalized += slash;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1217
        }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1218
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1219
        return normalized;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1220
    },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1221
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1222
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1223
    Parses a URL query string into a key/value hash. If `Y.QueryString.parse` is
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1224
    available, this method will be an alias to that.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1225
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1226
    @method _parseQuery
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1227
    @param {String} query Query string to parse.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1228
    @return {Object} Hash of key/value pairs for query parameters.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1229
    @protected
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1230
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1231
    _parseQuery: QS && QS.parse ? QS.parse : function (query) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1232
        var decode = this._decode,
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1233
            params = query.split('&'),
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1234
            i      = 0,
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1235
            len    = params.length,
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1236
            result = {},
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1237
            param;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1238
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1239
        for (; i < len; ++i) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1240
            param = params[i].split('=');
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1241
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1242
            if (param[0]) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1243
                result[decode(param[0])] = decode(param[1] || '');
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1244
            }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1245
        }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1246
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1247
        return result;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1248
    },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1249
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1250
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1251
    Returns `true` when the specified `path` is semantically within the
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1252
    specified `root` path.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1253
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1254
    If the `root` does not end with a trailing slash ("/"), one will be added
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1255
    before the `path` is evaluated against the root path.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1256
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1257
    @example
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1258
        this._pathHasRoot('/app',  '/app/foo'); // => true
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1259
        this._pathHasRoot('/app/', '/app/foo'); // => true
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1260
        this._pathHasRoot('/app/', '/app/');    // => true
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1261
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1262
        this._pathHasRoot('/app',  '/foo/bar'); // => false
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1263
        this._pathHasRoot('/app/', '/foo/bar'); // => false
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1264
        this._pathHasRoot('/app/', '/app');     // => false
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1265
        this._pathHasRoot('/app',  '/app');     // => false
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1266
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1267
    @method _pathHasRoot
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1268
    @param {String} root Root path used to evaluate whether the specificed
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1269
        `path` is semantically within. A trailing slash ("/") will be added if
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1270
        it does not already end with one.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1271
    @param {String} path Path to evaluate for containing the specified `root`.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1272
    @return {Boolean} Whether or not the `path` is semantically within the
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1273
        `root` path.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1274
    @protected
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1275
    @since 3.13.0
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1276
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1277
    _pathHasRoot: function (root, path) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1278
        var rootPath = root.charAt(root.length - 1) === '/' ? root : root + '/';
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1279
        return path.indexOf(rootPath) === 0;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1280
    },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1281
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1282
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1283
    Queues up a `_save()` call to run after all previously-queued calls have
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1284
    finished.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1285
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1286
    This is necessary because if we make multiple `_save()` calls before the
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1287
    first call gets dispatched, then both calls will dispatch to the last call's
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1288
    URL.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1289
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1290
    All arguments passed to `_queue()` will be passed on to `_save()` when the
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1291
    queued function is executed.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1292
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1293
    @method _queue
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1294
    @chainable
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1295
    @see _dequeue
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1296
    @protected
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1297
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1298
    _queue: function () {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1299
        var args = arguments,
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1300
            self = this;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1301
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1302
        saveQueue.push(function () {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1303
            if (self._html5) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1304
                if (Y.UA.ios && Y.UA.ios < 5) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1305
                    // iOS <5 has buggy HTML5 history support, and needs to be
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1306
                    // synchronous.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1307
                    self._save.apply(self, args);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1308
                } else {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1309
                    // Wrapped in a timeout to ensure that _save() calls are
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1310
                    // always processed asynchronously. This ensures consistency
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1311
                    // between HTML5- and hash-based history.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1312
                    setTimeout(function () {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1313
                        self._save.apply(self, args);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1314
                    }, 1);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1315
                }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1316
            } else {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1317
                self._dispatching = true; // otherwise we'll dequeue too quickly
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1318
                self._save.apply(self, args);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1319
            }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1320
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1321
            return self;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1322
        });
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1323
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1324
        return !this._dispatching ? this._dequeue() : this;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1325
    },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1326
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1327
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1328
    Returns the normalized result of resolving the `path` against the current
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1329
    path. Falsy values for `path` will return just the current path.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1330
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1331
    @method _resolvePath
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1332
    @param {String} path URL path to resolve.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1333
    @return {String} Resolved path.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1334
    @protected
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1335
    @since 3.5.0
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1336
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1337
    _resolvePath: function (path) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1338
        if (!path) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1339
            return Y.getLocation().pathname;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1340
        }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1341
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1342
        if (path.charAt(0) !== '/') {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1343
            path = this._getPathRoot() + path;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1344
        }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1345
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1346
        return this._normalizePath(path);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1347
    },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1348
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1349
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1350
    Resolves the specified URL against the current URL.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1351
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1352
    This method resolves URLs like a browser does and will always return an
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1353
    absolute URL. When the specified URL is already absolute, it is assumed to
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1354
    be fully resolved and is simply returned as is. Scheme-relative URLs are
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1355
    prefixed with the current protocol. Relative URLs are giving the current
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1356
    URL's origin and are resolved and normalized against the current path root.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1357
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1358
    @method _resolveURL
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1359
    @param {String} url URL to resolve.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1360
    @return {String} Resolved URL.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1361
    @protected
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1362
    @since 3.5.0
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1363
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1364
    _resolveURL: function (url) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1365
        var parts    = url && url.match(this._regexURL),
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1366
            origin, path, query, hash, resolved;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1367
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1368
        if (!parts) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1369
            return Y.getLocation().toString();
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1370
        }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1371
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1372
        origin = parts[1];
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1373
        path   = parts[2];
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1374
        query  = parts[3];
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1375
        hash   = parts[4];
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1376
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1377
        // Absolute and scheme-relative URLs are assumed to be fully-resolved.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1378
        if (origin) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1379
            // Prepend the current scheme for scheme-relative URLs.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1380
            if (origin.indexOf('//') === 0) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1381
                origin = Y.getLocation().protocol + origin;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1382
            }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1383
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1384
            return origin + (path || '/') + (query || '') + (hash || '');
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1385
        }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1386
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1387
        // Will default to the current origin and current path.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1388
        resolved = this._getOrigin() + this._resolvePath(path);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1389
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1390
        // A path or query for the specified URL trumps the current URL's.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1391
        if (path || query) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1392
            return resolved + (query || '') + (hash || '');
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1393
        }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1394
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1395
        query = this._getQuery();
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1396
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1397
        return resolved + (query ? ('?' + query) : '') + (hash || '');
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1398
    },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1399
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1400
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1401
    Saves a history entry using either `pushState()` or the location hash.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1402
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1403
    This method enforces the same-origin security constraint; attempting to save
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1404
    a `url` that is not from the same origin as the current URL will result in
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1405
    an error.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1406
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1407
    @method _save
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1408
    @param {String} [url] URL for the history entry.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1409
    @param {Boolean} [replace=false] If `true`, the current history entry will
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1410
      be replaced instead of a new one being added.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1411
    @chainable
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1412
    @protected
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1413
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1414
    _save: function (url, replace) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1415
        var urlIsString = typeof url === 'string',
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1416
            currentPath, root, hash;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1417
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1418
        // Perform same-origin check on the specified URL.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1419
        if (urlIsString && !this._hasSameOrigin(url)) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1420
            Y.error('Security error: The new URL must be of the same origin as the current URL.');
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1421
            return this;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1422
        }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1423
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1424
        // Joins the `url` with the `root`.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1425
        if (urlIsString) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1426
            url = this._joinURL(url);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1427
        }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1428
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1429
        // Force _ready to true to ensure that the history change is handled
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1430
        // even if _save is called before the `ready` event fires.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1431
        this._ready = true;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1432
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1433
        if (this._html5) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1434
            this._history[replace ? 'replace' : 'add'](null, {url: url});
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1435
        } else {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1436
            currentPath = Y.getLocation().pathname;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1437
            root        = this.get('root');
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1438
            hash        = HistoryHash.getHash();
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1439
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1440
            if (!urlIsString) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1441
                url = hash;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1442
            }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1443
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1444
            // Determine if the `root` already exists in the current location's
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1445
            // `pathname`, and if it does then we can exclude it from the
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1446
            // hash-based path. No need to duplicate the info in the URL.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1447
            if (root === currentPath || root === this._getPathRoot()) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1448
                url = this.removeRoot(url);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1449
            }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1450
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1451
            // The `hashchange` event only fires when the new hash is actually
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1452
            // different. This makes sure we'll always dequeue and dispatch
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1453
            // _all_ router instances, mimicking the HTML5 behavior.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1454
            if (url === hash) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1455
                Y.Router.dispatch();
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1456
            } else {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1457
                HistoryHash[replace ? 'replaceHash' : 'setHash'](url);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1458
            }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1459
        }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1460
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1461
        return this;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1462
    },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1463
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1464
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1465
    Setter for the `params` attribute.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1466
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1467
    @method _setParams
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1468
    @param {Object} params Map in the form: `name` -> RegExp | Function.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1469
    @return {Object} The map of params: `name` -> RegExp | Function.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1470
    @protected
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1471
    @since 3.12.0
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1472
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1473
    _setParams: function (params) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1474
        this._params = {};
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1475
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1476
        YObject.each(params, function (regex, name) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1477
            this.param(name, regex);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1478
        }, this);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1479
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1480
        return Y.merge(this._params);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1481
    },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1482
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1483
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1484
    Setter for the `routes` attribute.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1485
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1486
    @method _setRoutes
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1487
    @param {Object[]} routes Array of route objects.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1488
    @return {Object[]} Array of route objects.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1489
    @protected
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1490
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1491
    _setRoutes: function (routes) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1492
        this._routes = [];
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1493
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1494
        YArray.each(routes, function (route) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1495
            this.route(route);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1496
        }, this);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1497
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1498
        return this._routes.concat();
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1499
    },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1500
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1501
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1502
    Upgrades a hash-based URL to a full-path URL, if necessary.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1503
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1504
    The specified `url` will be upgraded if its of the same origin as the
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1505
    current URL and has a path-like hash. URLs that don't need upgrading will be
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1506
    returned as-is.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1507
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1508
    @example
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1509
        app._upgradeURL('http://example.com/#/foo/'); // => 'http://example.com/foo/';
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1510
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1511
    @method _upgradeURL
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1512
    @param {String} url The URL to upgrade from hash-based to full-path.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1513
    @return {String} The upgraded URL, or the specified URL untouched.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1514
    @protected
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1515
    @since 3.5.0
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1516
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1517
    _upgradeURL: function (url) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1518
        // We should not try to upgrade paths for external URLs.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1519
        if (!this._hasSameOrigin(url)) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1520
            return url;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1521
        }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1522
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1523
        var hash       = (url.match(/#(.*)$/) || [])[1] || '',
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1524
            hashPrefix = Y.HistoryHash.hashPrefix,
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1525
            hashPath;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1526
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1527
        // Strip any hash prefix, like hash-bangs.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1528
        if (hashPrefix && hash.indexOf(hashPrefix) === 0) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1529
            hash = hash.replace(hashPrefix, '');
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1530
        }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1531
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1532
        // If the hash looks like a URL path, assume it is, and upgrade it!
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1533
        if (hash) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1534
            hashPath = this._getHashPath(hash);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1535
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1536
            if (hashPath) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1537
                return this._resolveURL(hashPath);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1538
            }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1539
        }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1540
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1541
        return url;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1542
    },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1543
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1544
    // -- Protected Event Handlers ---------------------------------------------
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1545
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1546
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1547
    Handles `history:change` and `hashchange` events.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1548
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1549
    @method _afterHistoryChange
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1550
    @param {EventFacade} e
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1551
    @protected
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1552
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1553
    _afterHistoryChange: function (e) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1554
        var self       = this,
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1555
            src        = e.src,
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1556
            prevURL    = self._url,
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1557
            currentURL = self._getURL(),
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1558
            req, res;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1559
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1560
        self._url = currentURL;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1561
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1562
        // Handles the awkwardness that is the `popstate` event. HTML5 browsers
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1563
        // fire `popstate` right before they fire `hashchange`, and Chrome fires
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1564
        // `popstate` on page load. If this router is not ready or the previous
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1565
        // and current URLs only differ by their hash, then we want to ignore
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1566
        // this `popstate` event.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1567
        if (src === 'popstate' &&
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1568
                (!self._ready || prevURL.replace(/#.*$/, '') === currentURL.replace(/#.*$/, ''))) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1569
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1570
            return;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1571
        }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1572
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1573
        req = self._getRequest(src);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1574
        res = self._getResponse(req);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1575
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1576
        self._dispatch(req, res);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1577
    },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1578
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1579
    // -- Default Event Handlers -----------------------------------------------
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1580
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1581
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1582
    Default handler for the `ready` event.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1583
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1584
    @method _defReadyFn
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1585
    @param {EventFacade} e
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1586
    @protected
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1587
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1588
    _defReadyFn: function (e) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1589
        this._ready = true;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1590
    }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1591
}, {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1592
    // -- Static Properties ----------------------------------------------------
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1593
    NAME: 'router',
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1594
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1595
    ATTRS: {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1596
        /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1597
        Whether or not this browser is capable of using HTML5 history.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1598
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1599
        Setting this to `false` will force the use of hash-based history even on
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1600
        HTML5 browsers, but please don't do this unless you understand the
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1601
        consequences.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1602
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1603
        @attribute html5
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1604
        @type Boolean
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1605
        @initOnly
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1606
        **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1607
        html5: {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1608
            // Android versions lower than 3.0 are buggy and don't update
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1609
            // window.location after a pushState() call, so we fall back to
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1610
            // hash-based history for them.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1611
            //
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1612
            // See http://code.google.com/p/android/issues/detail?id=17471
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1613
            valueFn: function () { return Y.Router.html5; },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1614
            writeOnce: 'initOnly'
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1615
        },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1616
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1617
        /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1618
        Map of params handlers in the form: `name` -> RegExp | Function.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1619
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1620
        If a param handler regex or function returns a value of `false`, `null`,
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1621
        `undefined`, or `NaN`, the current route will not match and be skipped.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1622
        All other return values will be used in place of the original param
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1623
        value parsed from the URL.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1624
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1625
        This attribute is intended to be used to set params at init time, or to
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1626
        completely reset all params after init. To add params after init without
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1627
        resetting all existing params, use the `param()` method.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1628
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1629
        @attribute params
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1630
        @type Object
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1631
        @default `{}`
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1632
        @see param
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1633
        @since 3.12.0
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1634
        **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1635
        params: {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1636
            value : {},
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1637
            getter: '_getParams',
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1638
            setter: '_setParams'
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1639
        },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1640
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1641
        /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1642
        Absolute root path from which all routes should be evaluated.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1643
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1644
        For example, if your router is running on a page at
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1645
        `http://example.com/myapp/` and you add a route with the path `/`, your
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1646
        route will never execute, because the path will always be preceded by
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1647
        `/myapp`. Setting `root` to `/myapp` would cause all routes to be
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1648
        evaluated relative to that root URL, so the `/` route would then execute
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1649
        when the user browses to `http://example.com/myapp/`.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1650
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1651
        @example
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1652
            router.set('root', '/myapp');
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1653
            router.route('/foo', function () { ... });
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1654
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1655
            Y.log(router.hasRoute('/foo'));       // => false
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1656
            Y.log(router.hasRoute('/myapp/foo')); // => true
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1657
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1658
            // Updates the URL to: "/myapp/foo"
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1659
            router.save('/foo');
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1660
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1661
        @attribute root
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1662
        @type String
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1663
        @default `''`
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1664
        **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1665
        root: {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1666
            value: ''
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1667
        },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1668
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1669
        /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1670
        Array of route objects.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1671
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1672
        Each item in the array must be an object with the following properties
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1673
        in order to be processed by the router:
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1674
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1675
          * `path`: String or regex representing the path to match. See the docs
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1676
            for the `route()` method for more details.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1677
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1678
          * `callbacks`: Function or a string representing the name of a
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1679
            function on this router instance that should be called when the
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1680
            route is triggered. An array of functions and/or strings may also be
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1681
            provided. See the docs for the `route()` method for more details.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1682
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1683
        If a route object contains a `regex` or `regexp` property, or if its
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1684
        `path` is a regular express, then the route will be considered to be
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1685
        fully-processed. Any fully-processed routes may contain the following
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1686
        properties:
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1687
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1688
          * `regex`: The regular expression representing the path to match, this
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1689
            property may also be named `regexp` for greater compatibility.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1690
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1691
          * `keys`: Array of named path parameters used to populate `req.params`
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1692
            objects when dispatching to route handlers.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1693
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1694
        Any additional data contained on these route objects will be retained.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1695
        This is useful to store extra metadata about a route; e.g., a `name` to
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1696
        give routes logical names.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1697
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1698
        This attribute is intended to be used to set routes at init time, or to
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1699
        completely reset all routes after init. To add routes after init without
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1700
        resetting all existing routes, use the `route()` method.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1701
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1702
        @attribute routes
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1703
        @type Object[]
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1704
        @default `[]`
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1705
        @see route
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1706
        **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1707
        routes: {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1708
            value : [],
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1709
            getter: '_getRoutes',
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1710
            setter: '_setRoutes'
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1711
        }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1712
    },
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1713
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1714
    // Used as the default value for the `html5` attribute, and for testing.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1715
    html5: Y.HistoryBase.html5 && (!Y.UA.android || Y.UA.android >= 3),
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1716
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1717
    // To make this testable.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1718
    _instances: instances,
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1719
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1720
    /**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1721
    Dispatches to the first route handler that matches the specified `path` for
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1722
    all active router instances.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1723
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1724
    This provides a mechanism to cause all active router instances to dispatch
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1725
    to their route handlers without needing to change the URL or fire the
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1726
    `history:change` or `hashchange` event.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1727
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1728
    @method dispatch
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1729
    @static
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1730
    @since 3.6.0
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1731
    **/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1732
    dispatch: function () {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1733
        var i, len, router, req, res;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1734
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1735
        for (i = 0, len = instances.length; i < len; i += 1) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1736
            router = instances[i];
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1737
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1738
            if (router) {
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1739
                req = router._getRequest('dispatch');
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1740
                res = router._getResponse(req);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1741
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1742
                router._dispatch(req, res);
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1743
            }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1744
        }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1745
    }
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1746
});
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1747
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1748
/**
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1749
The `Controller` class was deprecated in YUI 3.5.0 and is now an alias for the
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1750
`Router` class. Use that class instead. This alias will be removed in a future
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1751
version of YUI.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1752
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1753
@class Controller
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1754
@constructor
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1755
@extends Base
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1756
@deprecated Use `Router` instead.
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1757
@see Router
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1758
**/
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1759
Y.Controller = Y.Router;
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1760
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1761
e16a97fb364a Use YUI 3.15
gibus
parents:
diff changeset
  1762
}, '@VERSION@', {"optional": ["querystring-parse"], "requires": ["array-extras", "base-build", "history"]});