From 232ff7bff340d6a12dce8ec70d9b491a2b8c9fdb Mon Sep 17 00:00:00 2001 From: Michael Donaldson Date: Mon, 27 Feb 2017 10:18:01 +0000 Subject: [PATCH 1/2] Refactor mount syntax --- packages/ember-glimmer/lib/syntax/mount.js | 70 +++++++++++++++++----- 1 file changed, 54 insertions(+), 16 deletions(-) diff --git a/packages/ember-glimmer/lib/syntax/mount.js b/packages/ember-glimmer/lib/syntax/mount.js index 0570e85567e..bc6b1a270fb 100644 --- a/packages/ember-glimmer/lib/syntax/mount.js +++ b/packages/ember-glimmer/lib/syntax/mount.js @@ -13,6 +13,14 @@ import { OutletLayoutCompiler } from './outlet'; import { FACTORY_FOR } from 'container'; import AbstractManager from './abstract-manager'; +function dynamicEngineFor(vm, symbolTable) { + let env = vm.env; + let args = vm.getArgs(); + let nameRef = args.positional.at(0); + + return new DynamicEngineReference({ nameRef, env, symbolTable }); +} + /** The `{{mount}}` helper lets you embed a routeless engine in a template. Mounting an engine will cause an instance to be booted and its `application` @@ -39,45 +47,75 @@ export function mountMacro(path, params, hash, builder) { params.length === 1 && hash === null ); - let name = params[0]; - assert( 'The first argument of {{mount}} must be quoted, e.g. {{mount "chat-engine"}}.', - typeof name === 'string' - ); - - assert( - `You used \`{{mount '${name}'}}\`, but the engine '${name}' can not be found.`, - builder.env.owner.hasRegistration(`engine:${name}`) + typeof params[0] === 'string' ); - builder.component.static(new MountDefinition(name, builder.env), [params, hash, null, null], builder.symbolTable); + let definitionArgs = [params.slice(0, 1), null, null, null]; + let args = [null, null, null, null]; + builder.component.dynamic(definitionArgs, dynamicEngineFor, args, builder.symbolTable); return true; } +class DynamicEngineReference { + constructor({ nameRef, env, symbolTable, args }) { + this.tag = nameRef.tag; + this.nameRef = nameRef; + this.env = env; + this.symbolTable = symbolTable; + this.args = args; + this._lastName = undefined; + this._lastDef = undefined; + } + + value() { + let { env, nameRef, /*symbolTable*/ } = this; + let nameOrDef = nameRef.value(); + + if (this._lastName === nameOrDef) { + return this._lastDef; + } + + assert( + `You used \`{{mount '${nameOrDef}'}}\`, but the engine '${nameOrDef}' can not be found.`, + env.owner.hasRegistration(`engine:${nameOrDef}`) + ); + + if (!env.owner.hasRegistration(`engine:${nameOrDef}`)) { + return null; + } + + this._lastName = nameOrDef; + this._lastDef = new MountDefinition(nameOrDef, env); + + return this._lastDef; + } +} + class MountManager extends AbstractManager { prepareArgs(definition, args) { return args; } - create(environment, { name, env }, args, dynamicScope) { - runInDebug(() => this._pushEngineToDebugStack(`engine:${name}`, env)); + create(environment, { name }, args, dynamicScope) { + runInDebug(() => this._pushEngineToDebugStack(`engine:${name}`, environment)); dynamicScope.outletState = UNDEFINED_REFERENCE; - let engine = env.owner.buildChildEngineInstance(name); + let engine = environment.owner.buildChildEngineInstance(name); engine.boot(); - return { engine }; + return engine; } - layoutFor(definition, { engine }, env) { + layoutFor(definition, engine, env) { let template = engine.lookup(`template:application`); return env.getCompiledBlock(OutletLayoutCompiler, template); } - getSelf({ engine }) { + getSelf(engine) { let applicationFactory = engine[FACTORY_FOR](`controller:application`); let factory = applicationFactory || generateControllerFactory(engine, 'application'); return new RootReference(factory.create()); @@ -87,7 +125,7 @@ class MountManager extends AbstractManager { return null; } - getDestructor({ engine }) { + getDestructor(engine) { return engine; } From a2b168490d1b75d64e5ea654069d2ec09bb1e9de Mon Sep 17 00:00:00 2001 From: Michael Donaldson Date: Thu, 2 Mar 2017 10:34:59 +0000 Subject: [PATCH 2/2] Cleanup mount syntax refactor --- packages/ember-glimmer/lib/syntax/mount.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/ember-glimmer/lib/syntax/mount.js b/packages/ember-glimmer/lib/syntax/mount.js index bc6b1a270fb..564c1cd0d50 100644 --- a/packages/ember-glimmer/lib/syntax/mount.js +++ b/packages/ember-glimmer/lib/syntax/mount.js @@ -64,7 +64,6 @@ class DynamicEngineReference { this.nameRef = nameRef; this.env = env; this.symbolTable = symbolTable; - this.args = args; this._lastName = undefined; this._lastDef = undefined; } @@ -87,7 +86,7 @@ class DynamicEngineReference { } this._lastName = nameOrDef; - this._lastDef = new MountDefinition(nameOrDef, env); + this._lastDef = new MountDefinition(nameOrDef); return this._lastDef; } @@ -144,8 +143,7 @@ class MountManager extends AbstractManager { const MOUNT_MANAGER = new MountManager(); class MountDefinition extends ComponentDefinition { - constructor(name, env) { + constructor(name) { super(name, MOUNT_MANAGER, null); - this.env = env; } }