diff --git a/backbone.js b/backbone.js index 74bde79b0..c2e561892 100644 --- a/backbone.js +++ b/backbone.js @@ -1,4 +1,4 @@ -// Backbone.js 0.3.3 +// Backbone.js 0.5.0-pre // (c) 2010 Jeremy Ashkenas, DocumentCloud Inc. // Backbone may be freely distributed under the MIT license. // For all details and documentation: @@ -25,7 +25,7 @@ } // Current version of the library. Keep in sync with `package.json`. - Backbone.VERSION = '0.3.3'; + Backbone.VERSION = '0.5.0-pre'; // Require Underscore, if we're on the server, and it's not already present. var _ = root._; @@ -70,7 +70,7 @@ // Passing `"all"` will bind the callback to all events fired. bind : function(ev, callback) { var calls = this._callbacks || (this._callbacks = {}); - var list = this._callbacks[ev] || (this._callbacks[ev] = []); + var list = calls[ev] || (calls[ev] = []); list.push(callback); return this; }, @@ -410,13 +410,10 @@ // its models in sort order, as they're added and removed. Backbone.Collection = function(models, options) { options || (options = {}); - if (options.comparator) { - this.comparator = options.comparator; - delete options.comparator; - } + if (options.comparator) this.comparator = options.comparator; _.bindAll(this, '_onModelEvent', '_removeReference'); this._reset(); - if (models) this.refresh(models, {silent: true}); + if (models) this.reset(models, {silent: true}); this.initialize(models, options); }; @@ -485,7 +482,7 @@ options || (options = {}); if (!this.comparator) throw new Error('Cannot sort a set without a comparator'); this.models = this.sortBy(this.comparator); - if (!options.silent) this.trigger('refresh', this, options); + if (!options.silent) this.trigger('reset', this, options); return this; }, @@ -495,27 +492,27 @@ }, // When you have more items than you want to add or remove individually, - // you can refresh the entire set with a new list of models, without firing - // any `added` or `removed` events. Fires `refresh` when finished. - refresh : function(models, options) { + // you can reset the entire set with a new list of models, without firing + // any `added` or `removed` events. Fires `reset` when finished. + reset : function(models, options) { models || (models = []); options || (options = {}); this.each(this._removeReference); this._reset(); this.add(models, {silent: true}); - if (!options.silent) this.trigger('refresh', this, options); + if (!options.silent) this.trigger('reset', this, options); return this; }, - // Fetch the default set of models for this collection, refreshing the + // Fetch the default set of models for this collection, resetting the // collection when they arrive. If `add: true` is passed, appends the - // models to the collection instead of refreshing. + // models to the collection instead of resetting. fetch : function(options) { options || (options = {}); var collection = this; var success = options.success; options.success = function(resp, status, xhr) { - collection[options.add ? 'add' : 'refresh'](collection.parse(resp, xhr), options); + collection[options.add ? 'add' : 'reset'](collection.parse(resp, xhr), options); if (success) success(collection, resp); }; options.error = wrapError(options.error, collection, options); @@ -532,7 +529,7 @@ if (!model) return false; var success = options.success; options.success = function(nextModel, resp, xhr) { - coll.add(nextModel); + coll.add(nextModel, options); if (success) success(nextModel, resp, xhr); }; model.save(null, options); @@ -584,7 +581,9 @@ if (already) throw new Error(["Can't add the same model to a set twice", already.id]); this._byId[model.id] = model; this._byCid[model.cid] = model; - var index = this.comparator ? this.sortedIndex(model, this.comparator) : this.length; + var index = options.at != null ? options.at : + this.comparator ? this.sortedIndex(model, this.comparator) : + this.length; this.models.splice(index, 0, model); model.bind('all', this._onModelEvent); this.length++; @@ -646,12 +645,12 @@ }; }); - // Backbone.Controller + // Backbone.Router // ------------------- - // Controllers map faux-URLs to actions, and fire events when routes are + // Routers map faux-URLs to actions, and fire events when routes are // matched. Creating a new one sets its `routes` hash, if not set statically. - Backbone.Controller = function(options) { + Backbone.Router = function(options) { options || (options = {}); if (options.routes) this.routes = options.routes; this._bindRoutes(); @@ -664,8 +663,8 @@ var splatParam = /\*([\w\d]+)/g; var escapeRegExp = /[-[\]{}()+?.,\\^$|#\s]/g; - // Set up all inheritable **Backbone.Controller** properties and methods. - _.extend(Backbone.Controller.prototype, Backbone.Events, { + // Set up all inheritable **Backbone.Router** properties and methods. + _.extend(Backbone.Router.prototype, Backbone.Events, { // Initialize is an empty function by default. Override it with your own // initialization logic. @@ -680,8 +679,8 @@ route : function(route, name, callback) { Backbone.history || (Backbone.history = new Backbone.History); if (!_.isRegExp(route)) route = this._routeToRegExp(route); - Backbone.history.route(route, _.bind(function(hash) { - var args = this._extractParameters(route, hash); + Backbone.history.route(route, _.bind(function(fragment) { + var args = this._extractParameters(route, fragment); callback.apply(this, args); this.trigger.apply(this, ['route:' + name].concat(args)); }, this)); @@ -689,8 +688,15 @@ // Simple proxy to `Backbone.history` to save a fragment into the history, // without triggering routes. - saveLocation : function(hash) { - Backbone.history.saveLocation(hash); + saveLocation : function(fragment) { + Backbone.history.saveLocation(fragment); + }, + + // Simple proxy to `Backbone.history` to both save a fragment into the + // history and to then load the route at that fragment. + setLocation : function(fragment) { + Backbone.history.saveLocation(fragment); + Backbone.history.loadUrl(fragment); }, // Bind all defined routes to `Backbone.history`. We have to reverse the @@ -718,8 +724,8 @@ // Given a route, and a URL fragment that it matches, return the array of // extracted parameters. - _extractParameters : function(route, hash) { - return route.exec(hash).slice(1); + _extractParameters : function(route, fragment) { + return route.exec(fragment).slice(1); } }); @@ -727,7 +733,7 @@ // Backbone.History // ---------------- - // Handles cross-browser history management, based on URL hashes. If the + // Handles cross-browser history management, based on URL fragments. If the // browser does not support `onhashchange`, falls back to polling. Backbone.History = function() { this.handlers = []; @@ -750,33 +756,64 @@ // twenty times a second. interval: 50, - // Get the cross-browser normalized URL fragment. - getHash : function(loc) { - return (loc || window.location).hash.replace(hashStrip, ''); + // Get the cross-browser normalized URL fragment, either from the URL, + // the hash, or the override. + getFragment : function(fragment, forcePushState) { + if (fragment == null) { + if (this._hasPushState || forcePushState) { + fragment = window.location.pathname; + var search = window.location.search; + if (search) fragment += search; + if (fragment.indexOf(this.options.root) == 0) fragment = fragment.substr(this.options.root.length); + } else { + fragment = window.location.hash; + } + } + return fragment.replace(hashStrip, ''); }, // Start the hash change handling, returning `true` if the current URL matches // an existing route, and `false` otherwise. - start : function() { + start : function(options) { + + // Figure out the initial configuration. Do we need an iframe? + // Is pushState desired ... is it available? if (historyStarted) throw new Error("Backbone.history has already been started"); - var hash = this.getHash(); - var docMode = document.documentMode; - var oldIE = (isExplorer.exec(navigator.userAgent.toLowerCase()) && (!docMode || docMode <= 7)); + this.options = _.extend({}, {root: '/'}, this.options, options); + this._wantsPushState = !!this.options.pushState; + this._hasPushState = !!(this.options.pushState && window.history && window.history.pushState); + var fragment = this.getFragment(); + var docMode = document.documentMode; + var oldIE = (isExplorer.exec(navigator.userAgent.toLowerCase()) && (!docMode || docMode <= 7)); if (oldIE) { this.iframe = $('').hide().appendTo('body')[0].contentWindow; - this.saveLocation(hash); + this.saveLocation(fragment); } - if ('onhashchange' in window && !oldIE) { + + // Depending on whether we're using pushState or hashes, and whether + // 'onhashchange' is supported, determine how we check the URL state. + if (this._hasPushState) { + $(window).bind('popstate', this.checkUrl); + } else if ('onhashchange' in window && !oldIE) { $(window).bind('hashchange', this.checkUrl); } else { setInterval(this.checkUrl, this.interval); } - this.hash = hash; + + // Determine if we need to change the base url, for a pushState link + // opened by a non-pushState browser. + this.fragment = fragment; historyStarted = true; - return this.loadUrl(); + var started = this.loadUrl() || this.loadUrl(window.location.hash); + if (this._wantsPushState && !this._hasPushState && window.location.pathname != this.options.root) { + this.fragment = this.getFragment(null, true); + window.location = this.options.root + '#' + this.fragment; + } else { + return started; + } }, - // Add a route to be tested when the hash changes. Routes added later may + // Add a route to be tested when the fragment changes. Routes added later may // override previous routes. route : function(route, callback) { this.handlers.unshift({route : route, callback : callback}); @@ -784,23 +821,22 @@ // Checks the current URL to see if it has changed, and if it has, // calls `loadUrl`, normalizing across the hidden iframe. - checkUrl : function() { - var hash = this.getHash(); - if (hash == this.hash && this.iframe) hash = this.getHash(this.iframe.location); - if (hash == this.hash || hash == decodeURIComponent(this.hash)) return false; - if (this.iframe) this.saveLocation(hash); - this.hash = hash; - this.loadUrl(); + checkUrl : function(e) { + var current = this.getFragment(); + if (current == this.fragment && this.iframe) current = this.getFragment(this.iframe.location.hash); + if (current == this.fragment || current == decodeURIComponent(this.fragment)) return false; + if (this.iframe) this.saveLocation(current); + this.loadUrl() || this.loadUrl(window.location.hash); }, // Attempt to load the current URL fragment. If a route succeeds with a // match, returns `true`. If no defined routes matches the fragment, // returns `false`. - loadUrl : function() { - var hash = this.hash; + loadUrl : function(fragmentOverride) { + var fragment = this.fragment = this.getFragment(fragmentOverride); var matched = _.any(this.handlers, function(handler) { - if (handler.route.test(hash)) { - handler.callback(hash); + if (handler.route.test(fragment)) { + handler.callback(fragment); return true; } }); @@ -810,13 +846,20 @@ // Save a fragment into the hash history. You are responsible for properly // URL-encoding the fragment in advance. This does not trigger // a `hashchange` event. - saveLocation : function(hash) { - hash = (hash || '').replace(hashStrip, ''); - if (this.hash == hash) return; - window.location.hash = this.hash = hash; - if (this.iframe && (hash != this.getHash(this.iframe.location))) { - this.iframe.document.open().close(); - this.iframe.location.hash = hash; + saveLocation : function(fragment) { + fragment = (fragment || '').replace(hashStrip, ''); + if (this.fragment == fragment || this.fragment == decodeURIComponent(fragment)) return; + if (this._hasPushState) { + var loc = window.location; + if (fragment.indexOf(this.options.root) != 0) fragment = this.options.root + fragment; + this.fragment = fragment; + window.history.pushState({}, document.title, loc.protocol + '//' + loc.host + fragment); + } else { + window.location.hash = this.fragment = fragment; + if (this.iframe && (fragment != this.getFragment(this.iframe.location.hash))) { + this.iframe.document.open().close(); + this.iframe.location.hash = fragment; + } } } @@ -956,7 +999,7 @@ // Set up inheritance for the model, collection, and view. Backbone.Model.extend = Backbone.Collection.extend = - Backbone.Controller.extend = Backbone.View.extend = extend; + Backbone.Router.extend = Backbone.View.extend = extend; // Map from CRUD to HTTP for our default `Backbone.sync` implementation. var methodMap = { @@ -1098,7 +1141,7 @@ // Helper function to escape a string for HTML rendering. var escapeHTML = function(string) { - return string.replace(/&(?!\w+;|#\d+;|#x[\da-f]+;)/gi, '&').replace(//g, '>').replace(/"/g, '"'); + return string.replace(/&(?!\w+;|#\d+;|#x[\da-f]+;)/gi, '&').replace(//g, '>').replace(/"/g, '"').replace(/'/g, ''').replace(/\//g,'/'); }; }).call(this); diff --git a/examples/todos/todos.js b/examples/todos/todos.js index 3e2ef6b4d..1c7c8486a 100644 --- a/examples/todos/todos.js +++ b/examples/todos/todos.js @@ -187,7 +187,7 @@ $(function(){ this.input = this.$("#new-todo"); Todos.bind('add', this.addOne); - Todos.bind('refresh', this.addAll); + Todos.bind('reset', this.addAll); Todos.bind('all', this.render); Todos.fetch(); diff --git a/index.html b/index.html index 0f5b24b46..b2f2b07ff 100644 --- a/index.html +++ b/index.html @@ -220,19 +220,20 @@
- escapemodel.escape(attribute)
-
- Similar to get, but returns the HTML-escaped version
- of a model's attribute. If you're interpolating data from the model into
- HTML, using escape to retrieve attributes will prevent
- XSS attacks.
-
-var hacker = new Backbone.Model({ - name: "<script>alert('xss')</script>" -}); - -alert(hacker.escape('name')); --
setmodel.set(attributes, [options])
@@ -712,6 +697,11 @@
+ Remember that in JavaScript, objects are passed by reference, so if you + include an object as a default value, it will be shared among all instances. +
+
toJSONmodel.toJSON()
@@ -1027,7 +1017,7 @@
@@ -1240,7 +1232,7 @@-Backbone.Collection
Force a collection to re-sort itself. You don't need to call this under normal circumstances, as a collection with a comparator function will maintain itself in proper sort order at all times. Calling sort - triggers the collection's "refresh" event, unless silenced by passing + triggers the collection's "reset" event, unless silenced by passing {silent: true} @@ -1314,7 +1306,7 @@Backbone.Collection
success and error callbacks which will be passed (collection, response) as arguments. When the model data returns from the server, the collection will - refresh. + reset. Delegates to Backbone.sync under the covers, for custom persistence strategies. The server handler for fetch requests should return a JSON array of @@ -1337,6 +1329,12 @@Backbone.Collection
of replacing the collection's contents, pass {add: true} as an option to fetch. + ++ jQuery.ajax options can also be passed directly as fetch options, + so to fetch a specific page of a paginated collection: + Documents.fetch({data: {page: 3}}) +
Note that fetch should not be used to populate collections on @@ -1347,27 +1345,33 @@
Backbone.Collection
toggled open and closed. -- refresh
collection.refresh(models, [options])
++ reset
collection.reset(models, [options])
Adding and removing models one at a time is all well and good, but sometimes you have so many models to change that you'd rather just update the collection - in bulk. Use refresh to replace a collection with a new list - of models (or attribute hashes), triggering a single "refresh" event - at the end. Pass {silent: true} to suppress the "refresh" event. + in bulk. Use reset to replace a collection with a new list + of models (or attribute hashes), triggering a single "reset" event + at the end. Pass {silent: true} to suppress the "reset" event. + Using reset with no arguments is useful as a way to empty the collection.- Here's an example using refresh to bootstrap a collection during initial page load, + Here's an example using reset to bootstrap a collection during initial page load, in a Rails application.
<script> - Accounts.refresh(<%= @accounts.to_json %>); + Accounts.reset(<%= @accounts.to_json %>); </script>++ Calling collection.reset() without passing any models as arguments + will empty the entire collection. +
+create
collection.create(attributes, [options])
@@ -1395,39 +1399,32 @@Backbone.Collection
});
Web applications often choose to change their URL fragment (#fragment) in order to provide shareable, bookmarkable URLs for an Ajax-heavy application. - Backbone.Controller provides methods for routing client-side URL + Backbone.Router provides methods for routing client-side URL fragments, and connecting them to actions and events.
-- Backbone controllers do not yet make use of HTML5 pushState and - replaceState. Currently, pushState and replaceState - need special handling on the server-side, cause you to mint duplicate URLs, - and have an incomplete API. We may start supporting them in the future - when these issues have been resolved. -
-- During page load, after your application has finished creating all of its controllers, - be sure to call Backbone.history.start() to route the initial URL. + During page load, after your application has finished creating all of its routers, + be sure to call Backbone.history.start(), or + Backbone.history.start({pushState: true}) to route the initial URL.
-
- extendBackbone.Controller.extend(properties, [classProperties])
+
+ extendBackbone.Router.extend(properties, [classProperties])
- Get started by creating a custom controller class. You'll
+ Get started by creating a custom router class. You'll
want to define actions that are triggered when certain URL fragments are
- matched, and provide a routes hash
+ matched, and provide a routes hash
that pairs routes to actions.
-var Workspace = Backbone.Controller.extend({ +var Workspace = Backbone.Router.extend({ routes: { "help": "help", // #help @@ -1446,10 +1443,10 @@-Backbone.Controller
});
- routescontroller.routes
+
+ routesrouter.routes
- The routes hash maps URLs with parameters to functions on your controller,
+ The routes hash maps URLs with parameters to functions on your router,
similar to the View's events hash.
Routes can contain parameter parts, :param, which match a single URL
component between slashes; and splat parts *splat, which can match
@@ -1467,9 +1464,9 @@
When the visitor presses the back button, or enters a URL, and a particular route is matched, the name of the action will be fired as an - event, so that other objects can listen to the controller, + event, so that other objects can listen to the router, and be notified. In the following example, visiting #help/uploading - will fire a route:help event from the controller. + will fire a route:help event from the router.
@@ -1482,25 +1479,25 @@Backbone.Controller
-controller.bind("route:help", function(page) { +router.bind("route:help", function(page) { ... });-
- constructor / initializenew Controller([options])
+
+ constructor / initializenew Router([options])
- When creating a new controller, you may pass its
- routes hash directly as an option, if you
+ When creating a new router, you may pass its
+ routes hash directly as an option, if you
choose. All options will also be passed to your initialize
function, if defined.
- routecontroller.route(route, name, callback)
+
+ routerouter.route(route, name, callback)
- Manually create a route for the controller, The route argument may
- be a routing string or regular expression.
+ Manually create a route for the router, The route argument may
+ be a routing string or regular expression.
Each matching capture from the route or regular expression will be passed as
an argument to the callback. The name argument will be triggered as
a "route:name" event whenever the route is matched.
@@ -1518,8 +1515,8 @@
- saveLocationcontroller.saveLocation(fragment)
+
+ saveLocationrouter.saveLocation(fragment)
Whenever you reach a point in your application that you'd like to save
as a URL, call saveLocation in order to update the URL fragment
@@ -1532,6 +1529,18 @@
+ setLocationrouter.setLocation(fragment)
+
+ Just like saveLocation, but also triggers
+ your route action at the same time. Useful if you want to transition to a page
+ where no state serialization is necessary, like a simple string.
+
+app.setLocation("help/troubleshooting");
startBackbone.history.start()
- When all of your Controllers have been created,
+ When all of your Routers have been created,
and all of the routes are set up properly, call Backbone.history.start()
to begin monitoring hashchange events, and dispatching routes.
$(function(){ - new WorkspaceController(); - new HelpPaneController(); + new WorkspaceRouter(); + new HelpPaneRouter(); Backbone.history.start(); });@@ -2100,7 +2109,7 @@
Michael Aufreiter is building an open source document authoring and publishing engine: Substance. - Substance makes use of Backbone.View and Backbone.Controller, while + Substance makes use of Backbone.View and Backbone.Router, while Backbone plays well together with Data.js, which is used for data persistence. @@ -2145,12 +2154,12 @@
<script> - Accounts.refresh(<%= @accounts.to_json %>); - Projects.refresh(<%= @projects.to_json(:collaborators => true) %>); + Accounts.reset(<%= @accounts.to_json %>); + Projects.reset(<%= @projects.to_json(:collaborators => true) %>); </script>@@ -2233,7 +2242,7 @@
+ 0.4.0 — FUTURE DATE, 2011
+ Collection.refresh renamed to Collection.reset to emphasize
+ its ability to both refresh the collection with new models, as well as empty
+ out the collection when used with no parameters.
+
0.3.3 — Dec 1, 2010
Backbone.js now supports Zepto, alongside
diff --git a/package.json b/package.json
index da66d8777..071d838f4 100644
--- a/package.json
+++ b/package.json
@@ -10,5 +10,5 @@
},
"lib" : ".",
"main" : "backbone.js",
- "version" : "0.3.3"
+ "version" : "0.5.0-pre"
}
diff --git a/test/collection.js b/test/collection.js
index 1d679af77..7e9d77088 100644
--- a/test/collection.js
+++ b/test/collection.js
@@ -83,6 +83,16 @@ $(document).ready(function() {
equals(otherCol.length, 1);
equals(secondAdded, null);
ok(opts.amazing);
+
+ var f = new Backbone.Model({id: 20, label : 'f'});
+ var g = new Backbone.Model({id: 21, label : 'g'});
+ var h = new Backbone.Model({id: 22, label : 'h'});
+ var atCol = new Backbone.Collection([f, g, h]);
+ equals(atCol.length, 3);
+ atCol.add(e, {at: 1});
+ equals(atCol.length, 4);
+ equals(atCol.at(1), e);
+ equals(atCol.last(), h);
});
test("Collection: add model to multiple collections", function() {
@@ -131,7 +141,7 @@ $(document).ready(function() {
emcees.bind('change', function(){ counter++; });
dj.set({name : 'Kool'});
equals(counter, 1);
- emcees.refresh([]);
+ emcees.reset([]);
equals(dj.collection, undefined);
dj.set({name : 'Shadow'});
equals(counter, 1);
@@ -283,20 +293,20 @@ $(document).ready(function() {
[0, 4]);
});
- test("Collection: refresh", function() {
- var refreshed = 0;
+ test("Collection: reset", function() {
+ var resetCount = 0;
var models = col.models;
- col.bind('refresh', function() { refreshed += 1; });
- col.refresh([]);
- equals(refreshed, 1);
+ col.bind('reset', function() { resetCount += 1; });
+ col.reset([]);
+ equals(resetCount, 1);
equals(col.length, 0);
equals(col.last(), null);
- col.refresh(models);
- equals(refreshed, 2);
+ col.reset(models);
+ equals(resetCount, 2);
equals(col.length, 4);
equals(col.last(), a);
- col.refresh(_.map(models, function(m){ return m.attributes; }));
- equals(refreshed, 3);
+ col.reset(_.map(models, function(m){ return m.attributes; }));
+ equals(resetCount, 3);
equals(col.length, 4);
ok(col.last() !== a);
ok(_.isEqual(col.last().attributes, a.attributes));
@@ -304,7 +314,7 @@ $(document).ready(function() {
test("Collection: trigger custom events on models", function() {
var fired = null;
- a.bind("custom", function() { fired = true });
+ a.bind("custom", function() { fired = true; });
a.trigger("custom");
equals(fired, true);
});
diff --git a/test/controller.js b/test/router.js
similarity index 58%
rename from test/controller.js
rename to test/router.js
index 2c02953a7..170daa7ea 100644
--- a/test/controller.js
+++ b/test/router.js
@@ -1,8 +1,8 @@
$(document).ready(function() {
- module("Backbone.Controller");
+ module("Backbone.Router");
- var Controller = Backbone.Controller.extend({
+ var Router = Backbone.Router.extend({
routes: {
"search/:query": "search",
@@ -43,74 +43,75 @@ $(document).ready(function() {
});
- var controller = new Controller({testing: 101});
+ Backbone.history = null;
+ var router = new Router({testing: 101});
Backbone.history.interval = 9;
- Backbone.history.start();
+ Backbone.history.start({pushState: false});
- test("Controller: initialize", function() {
- equals(controller.testing, 101);
+ test("Router: initialize", function() {
+ equals(router.testing, 101);
});
- asyncTest("Controller: routes (simple)", 2, function() {
+ asyncTest("Router: routes (simple)", 2, function() {
window.location.hash = 'search/news';
setTimeout(function() {
- equals(controller.query, 'news');
- equals(controller.page, undefined);
+ equals(router.query, 'news');
+ equals(router.page, undefined);
start();
}, 10);
});
- asyncTest("Controller: routes (two part)", 2, function() {
+ asyncTest("Router: routes (two part)", 2, function() {
window.location.hash = 'search/nyc/p10';
setTimeout(function() {
- equals(controller.query, 'nyc');
- equals(controller.page, '10');
+ equals(router.query, 'nyc');
+ equals(router.page, '10');
start();
}, 10);
});
- asyncTest("Controller: routes (splats)", function() {
+ asyncTest("Router: routes (splats)", function() {
window.location.hash = 'splat/long-list/of/splatted_99args/end';
setTimeout(function() {
- equals(controller.args, 'long-list/of/splatted_99args');
+ equals(router.args, 'long-list/of/splatted_99args');
start();
}, 10);
});
- asyncTest("Controller: routes (complex)", 3, function() {
+ asyncTest("Router: routes (complex)", 3, function() {
window.location.hash = 'one/two/three/complex-part/four/five/six/seven';
setTimeout(function() {
- equals(controller.first, 'one/two/three');
- equals(controller.part, 'part');
- equals(controller.rest, 'four/five/six/seven');
+ equals(router.first, 'one/two/three');
+ equals(router.part, 'part');
+ equals(router.rest, 'four/five/six/seven');
start();
}, 10);
});
- asyncTest("Controller: routes (query)", 2, function() {
+ asyncTest("Router: routes (query)", 2, function() {
window.location.hash = 'mandel?a=b&c=d';
setTimeout(function() {
- equals(controller.entity, 'mandel');
- equals(controller.queryArgs, 'a=b&c=d');
+ equals(router.entity, 'mandel');
+ equals(router.queryArgs, 'a=b&c=d');
start();
}, 10);
});
- asyncTest("Controller: routes (anything)", 1, function() {
+ asyncTest("Router: routes (anything)", 1, function() {
window.location.hash = 'doesnt-match-a-route';
setTimeout(function() {
- equals(controller.anything, 'doesnt-match-a-route');
+ equals(router.anything, 'doesnt-match-a-route');
start();
window.location.hash = '';
}, 10);
});
- asyncTest("Controller: routes (hashbang)", 2, function() {
+ asyncTest("Router: routes (hashbang)", 2, function() {
window.location.hash = '!search/news';
setTimeout(function() {
- equals(controller.query, 'news');
- equals(controller.page, undefined);
+ equals(router.query, 'news');
+ equals(router.page, undefined);
start();
}, 10);
});
diff --git a/test/test-zepto.html b/test/test-zepto.html
index 2b090e5a4..a03e65c5e 100644
--- a/test/test-zepto.html
+++ b/test/test-zepto.html
@@ -13,7 +13,7 @@
-
+
diff --git a/test/test.html b/test/test.html
index 091d1073a..1d272c4a1 100644
--- a/test/test.html
+++ b/test/test.html
@@ -14,7 +14,7 @@
-
+