controller-debug.js revision f2bfddd5b3480b2b18d35d9f46aa0769e08e5e58
The app framework provides simple MVC-like building blocks (models, model lists, views, and controllers) for writing single-page JavaScript applications. Provides URL-based routing using HTML5 `pushState()` or the location hash. This makes it easy to wire up route handlers for different application states while providing full back/forward navigation support and bookmarkable, shareable // Android versions lower than 3.0 are buggy and don't update // window.location after a pushState() call, so we fall back to hash-based Fired when the controller is ready to begin dispatching to route handlers. You shouldn't need to wait for this event unless you plan to implement some kind of custom dispatching logic. It's used internally in order to avoid dispatching to an initial route if a browser history change occurs first. @param {Boolean} dispatched `true` if routes have already been dispatched (most likely due to a history change). // -- Public Properties ---------------------------------------------------- Whether or not this browser is capable of using HTML5 history. This property is for informational purposes only. It's not configurable, and changing it will have no effect. Root path from which all routes should be evaluated. For example, if your controller is running on a page at route will never execute, because the path will always be preceded by `/myapp`. Setting `root` to `/myapp` would cause all routes to be evaluated relative to that root URL, so the `/` route would then execute when the This property may be overridden in a subclass, set after instantiation, or passed as a config attribute when instantiating a `Y.Controller`-based Array of route objects specifying routes to be created at instantiation Each item in the array must be an object with the following properties: * `path`: String or regex representing the path to match. See the docs for the `route()` method for more details. * `callback`: Function or a string representing the name of a function on this controller instance that should be called when the route is triggered. See the docs for the `route()` method for more details. This property may be overridden in a subclass or passed as a config attribute when instantiating a `Y.Controller`-based class, but setting it after instantiation will have no effect (use the `route()` method instead). If routes are passed at instantiation time, they will override any routes // -- Protected Properties ------------------------------------------------- Whether or not `_dispatch()` has been called since this controller was Whether or not the `ready` event has fired yet. Regex used to match parameter placeholders in route paths. 1. Parameter prefix character. Either a `:` for subpath parameters that should only match a single level of a path, or `*` for splat parameters that should match any number of path levels. @property _regexPathParam Regex that matches and captures the query portion of a URL, minus the preceding `?` character, and discarding the hash portion of the URL if any. // -- Lifecycle Methods ---------------------------------------------------- // Set config properties. // Set up a history instance or hashchange listener. // Fire a 'ready' event once we're ready to route. We wait first for all // subclass initializers to finish, and then an additional 20ms to allow // the browser to fire an initial `popstate` event if it wants to. self.
once(
'initializedChange',
function () {
// -- Public Methods ------------------------------------------------------- Dispatches to the first route handler that matches the current URL, if any. If `dispatch()` is called before the `ready` event has fired, it will automatically wait for the `ready` event before dispatching. Otherwise it will dispatch immediately. // This is an HTML5 browser and we have a hash-based path in the // URL, so we need to upgrade the URL to a non-hash URL. This // will trigger a `history:change` event, which will in turn Returns an array of route objects that match the specified URL path. This method is called internally to determine which routes match the current path whenever the URL changes. You may override it if you want to customize the route matching logic, although this usually shouldn't be necessary. Each returned route object has the following properties: * `callback`: A function or a string representing the name of a function this controller that should be executed when the route is triggered. * `keys`: An array of strings representing the named parameters defined in the route's path specification, if any. * `path`: The route's path specification, which may be either a string or * `regex`: A regular expression version of the route's path specification. This regex is used to determine whether the route matches a given path. controller.route('/foo', function () {}); controller.match('/foo'); // => [{callback: ..., keys: [], path: '/foo', regex: ...}] @param {String} path URL path to match. @return {Object[]} Array of route objects that match the specified path. Replaces the current browser history entry with a new one, and dispatches to the first matching route handler, if any. Behind the scenes, this method uses HTML5 `pushState()` in browsers that support it (or the location hash in older browsers and IE) to change the The specified URL must share the same origin (i.e., protocol, host, and port) as the current page, or an error will occur. controller.replace('/path/'); controller.replace('/path?foo=bar'); @param {String} [url] URL to set. Should be a relative URL. If this controller's `root` property is set, this URL must be relative to the root URL. If no URL is specified, the page's current URL will be used. Adds a route handler for the specified URL _path_. The _path_ parameter may be either a string or a regular expression. If it's a string, it may contain named parameters: `:param` will match any single part of a URL path (not including `/` characters), and `*param` will match any number of parts of a URL path (including `/` characters). These named parameters will be made available as keys on the `req.params` object that's passed to route handlers. If the _path_ parameter is a regex, all pattern matches will be made available as numbered keys on `req.params`, starting with `0` for the full match, then `1` for the first subpattern match, and so on. Here's a set of sample routes along with URL paths that they match: * Route: `/photos/:tag/:page` * URL: `/photos/kittens/1`, params: `{tag: 'kittens', 'page': '1'}` * URL: `/photos/puppies/2`, params: `{tag: 'puppies', 'page': '2'}` * URL: `/file/foo`, params: `{path: 'foo'}` If multiple route handlers match a given URL, they will be executed in the order they were added. The first route that was added will be the first to controller.route('/photos/:tag/:page', function (req, next) { Y.log('Current tag: ' + req.params.tag); Y.log('Current page number: ' + req.params.page); @param {String|RegExp} path Path to match. May be a string or a regular @param {Function|String} callback Callback function to call whenever this route is triggered. If specified as a string, the named function will be called on this controller instance. @param {Object} callback.req Request object containing information about the request. It contains the following properties. @param {Object} callback.req.params Captured parameters matched by the route path specification. If a string path was used and contained named parameters, then this will be a key/value hash mapping parameter names to their matched values. If a regex path was used, the keys will be numbered subpattern matches starting at `'0'` for the full match, then `'1'` for the first subpattern match, and so on. @param {String} callback.req.path The current URL path. @param {Object} callback.req.query Query hash representing the URL query string, if any. Parameter names are keys, and are mapped to parameter @param {Function} callback.next Callback to pass control to the next matching route. If you don't call this function, then no further route handlers will be executed, even if there are more that match. If you do call this function, then the next matching route handler (if any) will be called, and will receive the same `req` object that was passed to this route (so you can use the request object to pass data along to Saves a new browser history entry and dispatches to the first matching route Behind the scenes, this method uses HTML5 `pushState()` in browsers that support it (or the location hash in older browsers and IE) to change the URL and create a history entry. The specified URL must share the same origin (i.e., protocol, host, and port) as the current page, or an error will occur. controller.save('/path/'); controller.save('/path?foo=bar'); @param {String} [url] URL to set. Should be a relative URL. If this controller's `root` property is set, this URL must be relative to the root URL. If no URL is specified, the page's current URL will be used. // -- Protected Methods ---------------------------------------------------- Wrapper around `decodeURIComponent` that also converts `+` chars into @param {String} string String to decode. @return {String} Decoded string. Dispatches to the first route handler that matches the specified _path_. If called before the `ready` event has fired, the dispatch will be aborted. This ensures normalized behavior between Chrome (which fires a `popstate` event on every pageview) and other browsers (which do not). @param {String} path URL path. // Use named keys for parameter names if the route path contains // named keys. Otherwise, use numerical match indices. Gets the current path from the location hash, or an empty string if the @return {String} Current hash path, or an empty string if the hash is empty. Gets the current route path. @return {String} Current route path. Gets the current route query string. @return {String} Current route query string. Creates a regular expression from the given route specification. If _path_ is already a regex, it will be returned unmodified. @param {String|RegExp} path Route path specification. @param {Array} keys Array reference to which route parameter names will be @return {RegExp} Route regex. if (
path instanceof RegExp) {
return operator ===
'*' ?
'(.*?)' :
'([^/]*)';
return new RegExp(
'^' +
path +
'$');
Gets a request object that can be passed to a route handler. @param {String} path Current path being dispatched. @return {Object} Request object. controller._joinURL('bar'); // => '/foo/bar' controller._joinURL('/bar'); // => '/foo/bar' controller.root = '/foo/' controller._joinURL('bar'); // => '/foo/bar' controller._joinURL('/bar'); // => '/foo/bar' @param {String} url URL to append to the `root` URL. @return {String} Joined URL. Parses a URL query string into a key/value hash. If `Y.QueryString.parse` is available, this method will be an alias to that. @param {String} query Query string to parse. @return {Object} Hash of key/value pairs for query parameters. Removes the `root` URL from the from of _path_ (if it's there) and returns the result. The returned path will always have a leading `/`. @param {String} path URL path. @return {String} Rootless path. Saves a history entry using either `pushState()` or the location hash. @param {String} [url] URL for the history entry. @param {Boolean} [replace=false] If `true`, the current history entry will be replaced instead of a new one being added. // Force _ready to true to ensure that the history change is handled // even if _save is called before the `ready` event fires. // -- Protected Event Handlers --------------------------------------------- Handles `history:change` and `hashchange` events. @method _afterHistoryChange // We need to yield control to the UI thread to allow the browser to // update window.location before we dispatch. // -- Default Event Handlers ----------------------------------------------- Default handler for the `ready` event. },
'@VERSION@' ,{
optional:[
'querystring-parse'],
requires:[
'array-extras',
'base-build',
'history']});