Skip to content

Commit

Permalink
Merge pull request #10271 from emberjs/boot-reform
Browse files Browse the repository at this point in the history
Clean up boot process
  • Loading branch information
rwjblue committed Jan 30, 2015
2 parents 48e1159 + f578a04 commit c84b77d
Show file tree
Hide file tree
Showing 25 changed files with 524 additions and 202 deletions.
10 changes: 9 additions & 1 deletion FEATURES.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ for a detailed explanation.

## Feature Flags

* `ember-application-visit`

Provides an API for creating an application instance and specifying
an initial URL that it should route to. This is useful for testing
(you can have multiple instances of an app without having to run
serially and call `reset()` each time), as well as being critical to
for FastBoot.

* `ember-application-instance-initializers`

Splits apart initializers into two phases:
Expand Down Expand Up @@ -217,4 +225,4 @@ for a detailed explanation.
});
```

Added in [#10274](https://github.com/emberjs/ember.js/pull/10274)
Added in [#10274](https://github.com/emberjs/ember.js/pull/10274)
3 changes: 2 additions & 1 deletion features.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
"ember-htmlbars-each-with-index": true,
"ember-application-instance-initializers": null,
"ember-application-initializer-context": null,
"ember-router-willtransition": true
"ember-router-willtransition": true,
"ember-application-visit": null
},
"debugStatements": [
"Ember.warn",
Expand Down
8 changes: 4 additions & 4 deletions packages/container/lib/container.js
Original file line number Diff line number Diff line change
Expand Up @@ -270,8 +270,8 @@ function injectionsFor(container, fullName) {
var type = splitName[0];

var injections = buildInjections(container,
registry.typeInjections[type],
registry.injections[fullName]);
registry.getTypeInjections(type),
registry.getInjections(fullName));
injections._debugContainerKey = fullName;
injections.container = container;

Expand All @@ -284,8 +284,8 @@ function factoryInjectionsFor(container, fullName) {
var type = splitName[0];

var factoryInjections = buildInjections(container,
registry.factoryTypeInjections[type],
registry.factoryInjections[fullName]);
registry.getFactoryTypeInjections(type),
registry.getFactoryInjections(fullName));
factoryInjections._debugContainerKey = fullName;

return factoryInjections;
Expand Down
120 changes: 93 additions & 27 deletions packages/container/lib/registry.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,33 @@ var VALID_FULL_NAME_REGEXP = /^[^:]+.+:[^:]+$/;
@class Registry
*/
function Registry(options) {
this.fallback = options && options.fallback ? options.fallback : null;

this.resolver = options && options.resolver ? options.resolver : function() {};

this.registrations = dictionary(options && options.registrations ? options.registrations : null);
this.typeInjections = dictionary(options && options.typeInjections ? options.typeInjections : null);
this.injections = dictionary(null);
this.factoryTypeInjections = dictionary(null);
this.factoryInjections = dictionary(null);

this._normalizeCache = dictionary(null);
this._resolveCache = dictionary(null);
this._typeInjections = dictionary(null);
this._injections = dictionary(null);
this._factoryTypeInjections = dictionary(null);
this._factoryInjections = dictionary(null);

this._normalizeCache = dictionary(null);
this._resolveCache = dictionary(null);

this._options = dictionary(options && options.options ? options.options : null);
this._typeOptions = dictionary(options && options.typeOptions ? options.typeOptions : null);
this._options = dictionary(null);
this._typeOptions = dictionary(null);
}

Registry.prototype = {
/**
A backup registry for resolving registrations when no matches can be found.
@property fallback
@type Registry
*/
fallback: null,

/**
@property resolver
@type function
Expand All @@ -47,28 +58,36 @@ Registry.prototype = {
registrations: null,

/**
@property typeInjections
@private
@property _typeInjections
@type InheritingDict
*/
typeInjections: null,
_typeInjections: null,

/**
@property injections
@private
@property _injections
@type InheritingDict
*/
injections: null,
_injections: null,

/**
@property factoryTypeInjections
@private
@property _factoryTypeInjections
@type InheritingDict
*/
factoryTypeInjections: null,
_factoryTypeInjections: null,

/**
@property factoryInjections
@private
@property _factoryInjections
@type InheritingDict
*/
factoryInjections: null,
_factoryInjections: null,

/**
@private
Expand Down Expand Up @@ -249,7 +268,11 @@ Registry.prototype = {
*/
resolve: function(fullName) {
Ember.assert('fullName must be a proper full name', this.validateFullName(fullName));
return resolve(this, this.normalize(fullName));
var factory = resolve(this, this.normalize(fullName));
if (factory === undefined && this.fallback) {
factory = this.fallback.resolve(fullName);
}
return factory;
},

/**
Expand Down Expand Up @@ -349,7 +372,11 @@ Registry.prototype = {
},

getOptionsForType: function(type) {
return this._typeOptions[type];
var optionsForType = this._typeOptions[type];
if (optionsForType === undefined && this.fallback) {
optionsForType = this.fallback.getOptionsForType(type);
}
return optionsForType;
},

/**
Expand All @@ -365,7 +392,11 @@ Registry.prototype = {

getOptions: function(fullName) {
var normalizedName = this.normalize(fullName);
return this._options[normalizedName];
var options = this._options[normalizedName];
if (options === undefined && this.fallback) {
options = this.fallback.getOptions(fullName);
}
return options;
},

getOption: function(fullName, optionName) {
Expand All @@ -378,8 +409,11 @@ Registry.prototype = {
var type = fullName.split(':')[0];
options = this._typeOptions[type];

if (options) {
if (options && options[optionName] !== undefined) {
return options[optionName];

} else if (this.fallback) {
return this.fallback.getOption(fullName, optionName);
}
},

Expand Down Expand Up @@ -435,8 +469,8 @@ Registry.prototype = {
'` as a different type and perform the typeInjection.');
}

var injections = this.typeInjections[type] ||
(this.typeInjections[type] = []);
var injections = this._typeInjections[type] ||
(this._typeInjections[type] = []);

injections.push({
property: property,
Expand Down Expand Up @@ -500,8 +534,8 @@ Registry.prototype = {
Ember.assert('fullName must be a proper full name', this.validateFullName(fullName));
var normalizedName = this.normalize(fullName);

var injections = this.injections[normalizedName] ||
(this.injections[normalizedName] = []);
var injections = this._injections[normalizedName] ||
(this._injections[normalizedName] = []);

injections.push({
property: property,
Expand Down Expand Up @@ -540,8 +574,8 @@ Registry.prototype = {
@param {String} fullName
*/
factoryTypeInjection: function(type, property, fullName) {
var injections = this.factoryTypeInjections[type] ||
(this.factoryTypeInjections[type] = []);
var injections = this._factoryTypeInjections[type] ||
(this._factoryTypeInjections[type] = []);

injections.push({
property: property,
Expand Down Expand Up @@ -609,7 +643,7 @@ Registry.prototype = {
return this.factoryTypeInjection(normalizedName, property, normalizedInjectionName);
}

var injections = this.factoryInjections[normalizedName] || (this.factoryInjections[normalizedName] = []);
var injections = this._factoryInjections[normalizedName] || (this._factoryInjections[normalizedName] = []);

injections.push({
property: property,
Expand Down Expand Up @@ -652,6 +686,38 @@ Registry.prototype = {
}
}

return injections;
},

getInjections: function(fullName) {
var injections = this._injections[fullName] || [];
if (this.fallback) {
injections = injections.concat(this.fallback.getInjections(fullName));
}
return injections;
},

getTypeInjections: function(type) {
var injections = this._typeInjections[type] || [];
if (this.fallback) {
injections = injections.concat(this.fallback.getTypeInjections(type));
}
return injections;
},

getFactoryInjections: function(fullName) {
var injections = this._factoryInjections[fullName] || [];
if (this.fallback) {
injections = injections.concat(this.fallback.getFactoryInjections(fullName));
}
return injections;
},

getFactoryTypeInjections: function(type) {
var injections = this._factoryTypeInjections[type] || [];
if (this.fallback) {
injections = injections.concat(this.fallback.getFactoryTypeInjections(type));
}
return injections;
}
};
Expand Down
72 changes: 71 additions & 1 deletion packages/container/tests/registry_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ test("The registry can take a hook to resolve factories lazily", function() {
strictEqual(registry.resolve('controller:post'), PostController, "The correct factory was provided");
});

test("The registry respect the resolver hook for `has`", function() {
test("The registry respects the resolver hook for `has`", function() {
var registry = new Registry();
var PostController = factory();

Expand Down Expand Up @@ -275,3 +275,73 @@ test("registry.container creates an associated container", function() {
ok(postController instanceof PostController, "The lookup is an instance of the registered factory");
strictEqual(registry._defaultContainer, container, "_defaultContainer is set to the first created container and used for Ember 1.x Container compatibility");
});

test("`resolve` can be handled by a fallback registry", function() {
var fallback = new Registry();

var registry = new Registry({ fallback: fallback });
var PostController = factory();

fallback.register('controller:post', PostController);

var PostControllerFactory = registry.resolve('controller:post');

ok(PostControllerFactory, 'factory is returned');
ok(PostControllerFactory.create() instanceof PostController, "The return of factory.create is an instance of PostController");
});

test("`has` can be handled by a fallback registry", function() {
var fallback = new Registry();

var registry = new Registry({ fallback: fallback });
var PostController = factory();

fallback.register('controller:post', PostController);

equal(registry.has('controller:post'), true, "Fallback registry is checked for registration");
});

test("`getInjections` includes injections from a fallback registry", function() {
var fallback = new Registry();
var registry = new Registry({ fallback: fallback });

equal(registry.getInjections('model:user').length, 0, "No injections in the primary registry");

fallback.injection('model:user', 'post', 'model:post');

equal(registry.getInjections('model:user').length, 1, "Injections from the fallback registry are merged");
});

test("`getTypeInjections` includes type injections from a fallback registry", function() {
var fallback = new Registry();
var registry = new Registry({ fallback: fallback });

equal(registry.getTypeInjections('model').length, 0, "No injections in the primary registry");

fallback.injection('model', 'source', 'source:main');

equal(registry.getTypeInjections('model').length, 1, "Injections from the fallback registry are merged");
});

test("`getFactoryInjections` includes factory injections from a fallback registry", function() {
var fallback = new Registry();
var registry = new Registry({ fallback: fallback });

equal(registry.getFactoryInjections('model:user').length, 0, "No factory injections in the primary registry");

fallback.factoryInjection('model:user', 'store', 'store:main');

equal(registry.getFactoryInjections('model:user').length, 1, "Factory injections from the fallback registry are merged");
});


test("`getFactoryTypeInjections` includes factory type injections from a fallback registry", function() {
var fallback = new Registry();
var registry = new Registry({ fallback: fallback });

equal(registry.getFactoryTypeInjections('model').length, 0, "No factory type injections in the primary registry");

fallback.factoryInjection('model', 'store', 'store:main');

equal(registry.getFactoryTypeInjections('model').length, 1, "Factory type injections from the fallback registry are merged");
});
Loading

0 comments on commit c84b77d

Please sign in to comment.