diff --git a/FEATURES.md b/FEATURES.md index 91c8a673601..0d9e088f44f 100644 --- a/FEATURES.md +++ b/FEATURES.md @@ -204,3 +204,17 @@ for a detailed explanation. ``` Added in [#10160](https://github.com/emberjs/ember.js/pull/10160) + +* `ember-router-willtransition` + + Adds `willTransition` hook to `Ember.Router`. For example, + + ```js + Ember.Router.extend({ + onBeforeTransition: function(transition) { + //doSomething + }.on('willTransition') + }); + ``` + + Added in [#10274](https://github.com/emberjs/ember.js/pull/10274) \ No newline at end of file diff --git a/bower.json b/bower.json index 160cf951a56..2e513440063 100644 --- a/bower.json +++ b/bower.json @@ -8,7 +8,7 @@ "devDependencies": { "backburner": "https://github.com/ebryn/backburner.js.git#f4bd6a2df221240ed36d140f0c53c036a7ecacad", "rsvp": "https://github.com/tildeio/rsvp.js.git#3.0.14", - "router.js": "https://github.com/tildeio/router.js.git#a1ffd97dc66a6d9d4e8dd89a72c1c4e21a3328c5", + "router.js": "https://github.com/tildeio/router.js.git#72eb0d336c1c3b7ad3965198b330fe148d935efe", "dag-map": "https://github.com/krisselden/dag-map.git#e307363256fe918f426e5a646cb5f5062d3245be", "ember-dev": "https://github.com/emberjs/ember-dev.git#1c30a1666273ab2a9b134a42bad28c774f9ecdfc" } diff --git a/features.json b/features.json index 572628786bf..9040f020a1a 100644 --- a/features.json +++ b/features.json @@ -16,7 +16,8 @@ "ember-metal-stream": null, "ember-htmlbars-each-with-index": true, "ember-application-instance-initializers": null, - "ember-application-initializer-context": null + "ember-application-initializer-context": null, + "ember-router-willtransition": true }, "debugStatements": [ "Ember.warn", diff --git a/packages/ember-routing/lib/system/router.js b/packages/ember-routing/lib/system/router.js index 652ba47f8f9..c4144cf84c5 100644 --- a/packages/ember-routing/lib/system/router.js +++ b/packages/ember-routing/lib/system/router.js @@ -188,6 +188,24 @@ var EmberRouter = EmberObject.extend(Evented, { } }, + /** + Handles notifying any listeners of an impending URL + change. + + Triggers the router level `willTransition` hook. + + @method willTransition + @private + @since 1.11.0 + */ + willTransition: function(oldInfos, newInfos, transition) { + run.once(this, this.trigger, 'willTransition', transition); + + if (get(this, 'namespace').LOG_TRANSITIONS) { + Ember.Logger.log("Preparing to transition from '" + EmberRouter._routePath(oldInfos) + "' to '" + EmberRouter._routePath(newInfos) + "'"); + } + }, + handleURL: function(url) { // Until we have an ember-idiomatic way of accessing #hashes, we need to // remove it because router.js doesn't know how to handle it. @@ -419,6 +437,12 @@ var EmberRouter = EmberObject.extend(Evented, { router.didTransition = function(infos) { emberRouter.didTransition(infos); }; + + if (Ember.FEATURES.isEnabled('ember-router-willtransition')) { + router.willTransition = function(oldInfos, newInfos, transition) { + emberRouter.willTransition(oldInfos, newInfos, transition); + }; + } }, _serializeQueryParams: function(targetRouteName, queryParams) { diff --git a/packages/ember/tests/routing/basic_test.js b/packages/ember/tests/routing/basic_test.js index b2961af3a06..15526994703 100644 --- a/packages/ember/tests/routing/basic_test.js +++ b/packages/ember/tests/routing/basic_test.js @@ -2738,6 +2738,54 @@ test("Route silently fails when cleaning an outlet from an inactive view", funct Ember.run(function() { router.send('hideModal'); }); }); +if (Ember.FEATURES.isEnabled('ember-router-willtransition')) { + test("Router `willTransition` hook passes in cancellable transition", function() { + // Should hit willTransition 3 times, once for the initial route, and then 2 more times + // for the two handleURL calls below + expect(3); + + Router.map(function() { + this.route("nork"); + this.route("about"); + }); + + Router.reopen({ + init: function() { + this._super(); + this.on('willTransition', this.testWillTransitionHook); + }, + testWillTransitionHook: function(transition, url) { + ok(true, "willTransition was called " + url); + transition.abort(); + } + }); + + App.LoadingRoute = Ember.Route.extend({ + activate: function() { + ok(false, "LoadingRoute was not entered"); + } + }); + + App.NorkRoute = Ember.Route.extend({ + activate: function() { + ok(false, "NorkRoute was not entered"); + } + }); + + App.AboutRoute = Ember.Route.extend({ + activate: function() { + ok(false, "AboutRoute was not entered"); + } + }); + + bootApplication(); + + // Attempted transitions out of index should abort. + Ember.run(router, 'handleURL', '/nork'); + Ember.run(router, 'handleURL', '/about'); + }); +} + test("Aborting/redirecting the transition in `willTransition` prevents LoadingRoute from being entered", function() { expect(8);