Skip to content

Commit

Permalink
Merge pull request #2 from glimmerjs/integrate-component
Browse files Browse the repository at this point in the history
Integrate @glimmer/component
  • Loading branch information
dgeb committed Feb 3, 2017
2 parents d697e4a + 9c3724e commit 57c56f5
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 31 deletions.
29 changes: 26 additions & 3 deletions packages/@glimmer/application/Brocfile.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,37 @@
const build = require('@glimmer/build');
const buildVendorPackage = require('@glimmer/build/lib/build-vendor-package');
const funnel = require('broccoli-funnel');
const path = require('path');

let buildOptions = {};

if (process.env.BROCCOLI_ENV === 'tests') {
buildOptions.vendorTrees = [
buildVendorPackage('@glimmer/di', {
buildVendorPackage('@glimmer/compiler', {
external: ['babel-helpers', '@glimmer/syntax', '@glimmer/wire-format', '@glimmer/util'] }),
buildVendorPackage('@glimmer/component', {
external: ['babel-helpers', '@glimmer/di', '@glimmmer/reference', '@glimmer/runtime', '@glimmer/object-reference', '@glimmer/util'] }),
buildVendorPackage('@glimmer/di', {
external: ['babel-helpers', '@glimmer/util'] }),
buildVendorPackage('@glimmer/util', {
external: ['babel-helpers'] })
buildVendorPackage('@glimmer/object-reference', {
external: ['babel-helpers', '@glimmer/util', '@glimmer/reference'] }),
buildVendorPackage('@glimmer/reference', {
external: ['babel-helpers', '@glimmer/util'] }),
buildVendorPackage('@glimmer/runtime', {
external: ['babel-helpers',
'@glimmer/util',
'@glimmer/reference',
'@glimmer/wire-format',
'@glimmer/syntax']}),
buildVendorPackage('@glimmer/syntax', {
external: ['babel-helpers', 'handlebars', 'simple-html-tokenizer'] }),
buildVendorPackage('@glimmer/util', {
external: ['babel-helpers'] }),
buildVendorPackage('@glimmer/wire-format', {
external: ['@glimmer/util'] }),
buildVendorPackage('simple-html-tokenizer'),
funnel(path.dirname(require.resolve('handlebars/package')), {
include: ['dist/handlebars.amd.js'] })
];
}

Expand Down
1 change: 1 addition & 0 deletions packages/@glimmer/application/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"test": "testem ci"
},
"dependencies": {
"@glimmer/component": "^0.1.0",
"@glimmer/di": "^0.1.7",
"@glimmer/util": "^0.21.0"
},
Expand Down
79 changes: 76 additions & 3 deletions packages/@glimmer/application/src/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,41 @@ import {
RegistrationOptions,
setOwner
} from '@glimmer/di';
import {
DynamicScope,
Environment
} from '@glimmer/component';
import {
Simple,
templateFactory
} from '@glimmer/runtime';

function isTypeSpecifier(specifier: string) {
return specifier.indexOf(':') === -1;
}

export interface ApplicationOptions {
rootName: string;
rootElement?: Simple.Element;
resolver?: Resolver;
}

export default class Application implements Owner {
public rootName: string;
public rootElement: any;
public resolver: Resolver;
public env: Environment;
private _registry: Registry;
private _container: Container;
private _renderResult: any; // TODO - type

constructor(options: ApplicationOptions) {
this.rootName = options.rootName;
this.rootElement = options.rootElement;
this.resolver = options.resolver;

constructor(resolver?: Resolver) {
this.resolver = resolver;
this._registry = new Registry();
this._container = new Container(this._registry, resolver);
this._container = new Container(this._registry, this.resolver);

// Inject `this` (the app) as the "owner" of every object instantiated
// by its container.
Expand All @@ -30,8 +51,52 @@ export default class Application implements Owner {
setOwner(hash, this);
return hash;
}

this.initRegistrations();
}

initRegistrations(): void {
this.register(`environment:/${this.rootName}/main/main`, Environment);
this.registerOption('template', 'instantiate', false);
}

boot(): void {
this.env = this.lookup(`environment:/${this.rootName}/main/main`);

if (!this.rootElement) {
this.rootElement = this.env.getDOM().createElement('div');
self.document.body.append(this.rootElement);
}

this.render();
}

render() {
this.env.begin();

let mainTemplate = this.lookup(`template:/${this.rootName}/components/main`);
let mainLayout = templateFactory(mainTemplate).create(this.env);
let result = mainLayout.render(null, this.rootElement, new DynamicScope());

this.env.commit();

this._renderResult = result;
}

rerender() {
this.env.begin();
this._renderResult.rerender();
this.env.commit();
}

/**
* Registry accessor methods that normalize specifiers.
*
* TODO: consider converting Registry to be an interface instead of a class
* and then extract these methods to a separate accessor class that implements
* Registry.
*/

register(specifier: string, factory: any, options?: RegistrationOptions): void {
let normalizedSpecifier = this._toAbsoluteSpecifier(specifier);
this._registry.register(normalizedSpecifier, factory, options);
Expand Down Expand Up @@ -73,6 +138,10 @@ export default class Application implements Owner {
this._registry.registerInjection(normalizedSpecifier, property, normalizedInjection);
}

/**
* Owner interface implementation
*/

identify(specifier: string, referrer?: string): string {
return this._toAbsoluteSpecifier(specifier, referrer);
}
Expand All @@ -87,6 +156,10 @@ export default class Application implements Owner {
return this._container.lookup(absoluteSpecifier);
}

/**
* Private methods
*/

private _toAbsoluteSpecifier(specifier: string, referrer?: string): string {
if (isSpecifierStringAbsolute(specifier)) {
return specifier;
Expand Down
2 changes: 1 addition & 1 deletion packages/@glimmer/application/src/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { default as Application } from './application';
export { default as Application, ApplicationOptions } from './application';
25 changes: 13 additions & 12 deletions packages/@glimmer/application/test/application-container-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const { module, test } = QUnit;
module('Application - Container interface');

test('#identify - returns an absolute specifier unchanged', function(assert) {
let app = new Application();
let app = new Application({ rootName: 'app' });
let absSpecifier = 'component:/app/components/date-picker';
assert.equal(app.identify(absSpecifier), absSpecifier, 'specifier was returned unchanged');
});
Expand All @@ -19,9 +19,10 @@ test('#identify - uses a resolver to convert a relative specifier to an absolute
assert.equal(specifier, 'component:date-picker', 'FakeResolver#identify was invoked');
return 'component:/app/components/date-picker';
}
retrieve(specifier: string): any {}
}
let resolver = new FakeResolver();
let app = new Application(resolver);
let app = new Application({ rootName: 'app', resolver });
let specifier = 'component:date-picker';
assert.equal(app.identify(specifier, 'component:/app/components/form-controls'), 'component:/app/components/date-picker', 'absolute specifier was returned');
});
Expand All @@ -31,7 +32,7 @@ test('#factoryFor - returns a registered factory', function(assert) {
static create() { return { foo: 'bar' }; }
}

let app = new Application();
let app = new Application({ rootName: 'app' });

app.register('component:/app/components/date-picker', DatePicker);
assert.strictEqual(app.factoryFor('component:/app/components/date-picker'), DatePicker, 'expected factory was returned');
Expand All @@ -56,7 +57,7 @@ test('#factoryFor - will use a resolver to locate a factory', function(assert) {
}

let resolver = new FakeResolver();
let app = new Application(resolver);
let app = new Application({ rootName: 'app', resolver });
assert.strictEqual(app.factoryFor('component:date-picker'), DatePicker, 'expected factory was returned');
});

Expand All @@ -83,7 +84,7 @@ test('#factoryFor - will use a resolver to locate a factory, even if one is regi
}

let resolver = new FakeResolver();
let app = new Application(resolver);
let app = new Application({ rootName: 'app', resolver });
app.register('foo:/app/foos/bar', Foo);
assert.strictEqual(app.factoryFor('foo:bar'), FooBar, 'factory from resolver was returned');
});
Expand All @@ -101,7 +102,7 @@ test('#lookup - returns an instance created by the factory', function(assert) {
}
}

let app = new Application();
let app = new Application({ rootName: 'app' });

app.register('foo:/app/foos/bar', FooBar);
let foobar = app.lookup('foo:/app/foos/bar');
Expand All @@ -120,7 +121,7 @@ test('#lookup - caches looked up instances by default', function(assert) {
}
}

let app = new Application();
let app = new Application({ rootName: 'app' });

app.register('foo:/app/foos/bar', FooBar);
let foo1 = app.lookup('foo:/app/foos/bar');
Expand All @@ -142,7 +143,7 @@ test('#lookup - will not cache lookups specified as non-singletons', function(as
}
}

let app = new Application();
let app = new Application({ rootName: 'app' });

app.register('foo:/app/foos/bar', FooBar, { singleton: false });
let foo1 = app.lookup('foo:/app/foos/bar');
Expand All @@ -159,7 +160,7 @@ test('#lookup - returns the factory when registrations specify instantiate: fals

let factory = {};

let app = new Application();
let app = new Application({ rootName: 'app' });

app.register('foo:/app/foos/bar', factory, { instantiate: false });
let foo1 = app.lookup('foo:/app/foos/bar');
Expand All @@ -185,7 +186,7 @@ test('#lookup - uses the resolver to locate a registration', function(assert) {
}

let resolver = new FakeResolver();
let app = new Application(resolver);
let app = new Application({ rootName: 'app', resolver });
let foo1 = app.lookup('foo:bar');

assert.deepEqual(foo1, { foo: 'bar' }, 'expected factory was invoked');
Expand Down Expand Up @@ -213,7 +214,7 @@ test('#lookup - injects references registered by name', function(assert) {
}
}

let app = new Application();
let app = new Application({ rootName: 'app' });
app.register('foo:/app/foos/bar', FooBar);
app.register('router:/app/root/main', Router);
app.registerInjection('foo:/app/foos/bar', 'router', 'router:/app/root/main');
Expand Down Expand Up @@ -243,7 +244,7 @@ test('#lookup - injects references registered by type', function(assert) {
}
}

let app = new Application();
let app = new Application({ rootName: 'app' });
app.register('foo:/app/foos/bar', FooBar);
app.register('router:/app/root/main', Router);
app.registerInjection('foo:/app/foos/bar', 'router', 'router:/app/root/main');
Expand Down
17 changes: 6 additions & 11 deletions packages/@glimmer/application/test/application-registry-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,12 @@ const { module, test } = QUnit;

module('Application - Registry interface');

test('can be instantiated', function(assert) {
let app = new Application();
assert.ok(app, 'app exists');
});

test('#register - registers a factory', function(assert) {
class Foo {
static create() { return { foo: 'bar' }; }
}

let app = new Application();
let app = new Application({ rootName: 'app' });

assert.strictEqual(app.registration('foo:/app/foos/bar'), undefined, 'factory has not yet been registered');
app.register('foo:/app/foos/bar', Foo);
Expand All @@ -27,7 +22,7 @@ test('#register - can register options together with a factory', function(assert
static create() { return { foo: 'bar' }; }
}

let app = new Application();
let app = new Application({ rootName: 'app' });

assert.strictEqual(app.registration('foo:/app/foos/bar'), undefined, 'factory has not yet been registered');
app.register('foo:/app/foos/bar', Foo, { instantiate: false });
Expand All @@ -40,7 +35,7 @@ test('#registration - returns a factory has been registered', function(assert) {
static create() { return { foo: 'bar' }; }
}

let app = new Application();
let app = new Application({ rootName: 'app' });

assert.strictEqual(app.registration('foo:/app/foos/bar'), undefined, 'factory has not yet been registered');
app.register('foo:/app/foos/bar', Foo);
Expand All @@ -52,7 +47,7 @@ test('#unregister - unregisters a factory', function(assert) {
static create() { return { foo: 'bar' }; }
}

let app = new Application();
let app = new Application({ rootName: 'app' });

app.register('foo:/app/foos/bar', Foo);
assert.strictEqual(app.registration('foo:/app/foos/bar'), Foo, 'factory has been registered');
Expand All @@ -65,7 +60,7 @@ test('#registerOption, #registeredOptions, #registeredOption, #unregisterOption'
static create() { return { foo: 'bar' }; }
}

let app = new Application();
let app = new Application({ rootName: 'app' });

app.register('foo:/app/foos/bar', Foo);
assert.strictEqual(app.registeredOptions('foo:/app/foos/bar'), undefined);
Expand All @@ -85,7 +80,7 @@ test('Options registered by full name supercede those registered by type', funct
static create() { return { foo: 'bar' }; }
}

let app = new Application();
let app = new Application({ rootName: 'app' });

app.register('foo:/app/foos/bar', Foo);

Expand Down
2 changes: 1 addition & 1 deletion packages/@glimmer/application/test/application-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ const { module, test } = QUnit;
module('Application');

test('can be instantiated', function(assert) {
let app = new Application();
let app = new Application({ rootName: 'app' });
assert.ok(app, 'app exists');
});

0 comments on commit 57c56f5

Please sign in to comment.