Skip to content

Commit

Permalink
Merge pull request #10256 from emberjs/app-sessions
Browse files Browse the repository at this point in the history
Simplify and modularize app/router initialization
  • Loading branch information
rwjblue committed Jan 22, 2015
2 parents 8ca36b5 + e929b74 commit 6baf493
Show file tree
Hide file tree
Showing 12 changed files with 722 additions and 152 deletions.
21 changes: 21 additions & 0 deletions FEATURES.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,27 @@ for a detailed explanation.

## Feature Flags

* `ember-application-instance-initializers`

Splits apart initializers into two phases:

* Boot-time Initializers that receive a registry, and use it to set up
code structures
* Instance Initializers that receive an application instance, and use
it to set up application state per run of the application.

In FastBoot, each request will have its own run of the application,
and will only need to run the instance initializers.

In the future, tests will also be able to use this differentiation to
run just the instance initializers per-test.

With this change, `App.initializer` becomes a "boot-time" initializer,
and issues a deprecation warning if instances are accessed.

Apps should migrate any initializers that require instances to the new
`App.instanceInitializer` API.

* `ember-application-initializer-context`

Sets the context of the initializer function to its object instead of the
Expand Down
1 change: 1 addition & 0 deletions features.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"ember-testing-checkbox-helpers": null,
"ember-metal-stream": null,
"ember-htmlbars-each-with-index": true,
"ember-application-instance-initializers": null,
"ember-application-initializer-context": null
},
"debugStatements": [
Expand Down
12 changes: 10 additions & 2 deletions packages/container/lib/registry.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,13 +136,21 @@ Registry.prototype = {

lookup: function(fullName, options) {
Ember.assert('Create a container on the registry (with `registry.container()`) before calling `lookup`.', this._defaultContainer);
Ember.deprecate('`lookup` should not be called on a Registry. Call `lookup` directly on an associated Container instead.');

if (Ember.FEATURES.isEnabled('ember-application-instance-initializers')) {
Ember.deprecate('`lookup` was called on a Registry. The `initializer` API no longer receives a container, and you should use an `instanceInitializer` to look up objects from the container.', { url: "http://emberjs.com/guides/deprecations#toc_deprecate-access-to-instances-in-initializers" });
}

return this._defaultContainer.lookup(fullName, options);
},

lookupFactory: function(fullName) {
Ember.assert('Create a container on the registry (with `registry.container()`) before calling `lookupFactory`.', this._defaultContainer);
Ember.deprecate('`lookupFactory` should not be called on a Registry. Call `lookupFactory` directly on an associated Container instead.');

if (Ember.FEATURES.isEnabled('ember-application-instance-initializers')) {
Ember.deprecate('`lookupFactory` was called on a Registry. The `initializer` API no longer receives a container, and you should use an `instanceInitializer` to look up objects from the container.', { url: "http://emberjs.com/guides/deprecations#toc_deprecate-access-to-instances-in-initializers" });
}

return this._defaultContainer.lookupFactory(fullName);
},

Expand Down
113 changes: 113 additions & 0 deletions packages/ember-application/lib/system/application-instance.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/**
@module ember
@submodule ember-application
@private
*/

import EmberObject from "ember-runtime/system/object";
import run from "ember-metal/run_loop";

/**
The `ApplicationInstance` encapsulates all of the stateful aspects of a
running `Application`.
At a high-level, we break application boot into two distinct phases:
* Definition time, where all of the classes, templates, and other
dependencies are loaded (typically in the browser).
* Run time, where we begin executing the application once everything
has loaded.
Definition time can be expensive and only needs to happen once since it is
an idempotent operation. For example, between test runs and FastBoot
requests, the application stays the same. It is only the state that we want
to reset.
That state is what the `ApplicationInstance` manages: it is responsible for
creating the container that contains all application state, and disposing of
it once the particular test run or FastBoot request has finished.
*/

export default EmberObject.extend({
/**
The application instance's container. The container stores all of the
instance-specific state for this application run.
@property {Ember.Container} container
*/
container: null,

/**
The application's registry. The registry contains the classes, templates,
and other code that makes up the application.
@property {Ember.Registry} registry
*/
registry: null,

/**
The DOM events for which the event dispatcher should listen.
By default, the application's `Ember.EventDispatcher` listens
for a set of standard DOM events, such as `mousedown` and
`keyup`, and delegates them to your application's `Ember.View`
instances.
@private
@property {Object} customEvents
*/
customEvents: null,

/**
The root DOM element of the Application as an element or a
[jQuery-compatible selector
string](http://api.jquery.com/category/selectors/).
@private
@property {String|DOMElement} rootElement
*/
rootElement: null,

init: function() {
this._super.apply(this, arguments);
this.container = this.registry.container();
},

/**
@private
*/
startRouting: function(isModuleBasedResolver) {
var router = this.container.lookup('router:main');
if (!router) { return; }

router.startRouting(isModuleBasedResolver);
},

/**
@private
*/
handleURL: function(url) {
var router = this.container.lookup('router:main');

return router.handleURL(url);
},

/**
@private
*/
setupEventDispatcher: function() {
var dispatcher = this.container.lookup('event_dispatcher:main');

dispatcher.setup(this.customEvents, this.rootElement);

return dispatcher;
},

/**
@private
*/
willDestroy: function() {
this._super.apply(this, arguments);
run(this.container, 'destroy');
}
});
Loading

0 comments on commit 6baf493

Please sign in to comment.