Skip to content

Commit

Permalink
Merge pull request #19306 from emberjs/update/bump-vm-enable-strict-c…
Browse files Browse the repository at this point in the history
…lassic

[FEATURE strict-mode] Enable classic component usage in strict mode
  • Loading branch information
Chris Garrett authored Dec 14, 2020
2 parents 4dd8f0d + 8072096 commit 9588535
Show file tree
Hide file tree
Showing 22 changed files with 281 additions and 313 deletions.
24 changes: 12 additions & 12 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,19 +74,19 @@
},
"devDependencies": {
"@babel/preset-env": "^7.9.5",
"@glimmer/compiler": "0.69.3",
"@glimmer/compiler": "0.70.0",
"@glimmer/env": "^0.1.7",
"@glimmer/global-context": "0.69.3",
"@glimmer/interfaces": "0.69.3",
"@glimmer/manager": "0.69.3",
"@glimmer/destroyable": "0.69.3",
"@glimmer/owner": "0.69.3",
"@glimmer/node": "0.69.3",
"@glimmer/opcode-compiler": "0.69.3",
"@glimmer/program": "0.69.3",
"@glimmer/reference": "0.69.3",
"@glimmer/runtime": "0.69.3",
"@glimmer/validator": "0.69.3",
"@glimmer/global-context": "0.70.0",
"@glimmer/interfaces": "0.70.0",
"@glimmer/manager": "0.70.0",
"@glimmer/destroyable": "0.70.0",
"@glimmer/owner": "0.70.0",
"@glimmer/node": "0.70.0",
"@glimmer/opcode-compiler": "0.70.0",
"@glimmer/program": "0.70.0",
"@glimmer/reference": "0.70.0",
"@glimmer/runtime": "0.70.0",
"@glimmer/validator": "0.70.0",
"@simple-dom/document": "^1.4.0",
"@types/qunit": "^2.9.1",
"@types/rsvp": "^4.0.3",
Expand Down
8 changes: 1 addition & 7 deletions packages/@ember/-internals/glimmer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -371,13 +371,7 @@ export { InputComponent as Input } from './lib/components/input';
export { default as Component } from './lib/component';
export { default as Helper, helper } from './lib/helper';
export { SafeString, escapeExpression, htmlSafe, isHTMLSafe } from './lib/utils/string';
export {
Renderer,
InertRenderer,
InteractiveRenderer,
_resetRenderers,
renderSettled,
} from './lib/renderer';
export { Renderer, _resetRenderers, renderSettled } from './lib/renderer';
export {
getTemplate,
setTemplate,
Expand Down
36 changes: 20 additions & 16 deletions packages/@ember/-internals/glimmer/lib/component-managers/curly.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Factory, getOwner } from '@ember/-internals/owner';
import { Factory, getOwner, Owner, setOwner } from '@ember/-internals/owner';
import { enumerableSymbol, guidFor, symbol } from '@ember/-internals/utils';
import { addChildView, setElementView, setViewElement } from '@ember/-internals/views';
import { assert, debugFreeze } from '@ember/debug';
Expand Down Expand Up @@ -131,7 +131,7 @@ type ComponentFactory = Factory<

export default class CurlyComponentManager
implements
WithCreateInstance<ComponentStateBucket, Environment>,
WithCreateInstance<ComponentStateBucket>,
WithDynamicLayout<ComponentStateBucket, RuntimeResolver>,
WithDynamicTagName<ComponentStateBucket> {
protected templateFor(component: Component): CompilableProgram | null {
Expand Down Expand Up @@ -250,9 +250,10 @@ export default class CurlyComponentManager
* etc.
*/
create(
environment: Environment,
owner: Owner,
ComponentClass: ComponentFactory,
args: VMArguments,
{ isInteractive }: Environment,
dynamicScope: DynamicScope,
callerSelfRef: Reference,
hasBlock: boolean
Expand Down Expand Up @@ -285,6 +286,8 @@ export default class CurlyComponentManager
// `_target`, so bubbled actions are routed to the right place.
props._target = valueForRef(callerSelfRef);

setOwner(props, owner);

// caller:
// <FaIcon @name="bug" />
//
Expand Down Expand Up @@ -314,26 +317,26 @@ export default class CurlyComponentManager

// We usually do this in the `didCreateElement`, but that hook doesn't fire for tagless components
if (!hasWrappedElement) {
if (environment.isInteractive) {
if (isInteractive) {
component.trigger('willRender');
}

component._transitionTo('hasElement');

if (environment.isInteractive) {
if (isInteractive) {
component.trigger('willInsertElement');
}
}

// Track additional lifecycle metadata about this component in a state bucket.
// Essentially we're saving off all the state we'll need in the future.
let bucket = new ComponentStateBucket(
environment,
component,
capturedArgs,
argsTag,
finalizer,
hasWrappedElement
hasWrappedElement,
isInteractive
);

if (args.named.has('class')) {
Expand All @@ -344,7 +347,7 @@ export default class CurlyComponentManager
processComponentInitializationAssertions(component, props);
}

if (environment.isInteractive && hasWrappedElement) {
if (isInteractive && hasWrappedElement) {
component.trigger('willRender');
}

Expand All @@ -368,7 +371,7 @@ export default class CurlyComponentManager
}

didCreateElement(
{ component, classRef, environment, rootRef }: ComponentStateBucket,
{ component, classRef, isInteractive, rootRef }: ComponentStateBucket,
element: SimpleElement,
operations: ElementOperations
): void {
Expand Down Expand Up @@ -411,7 +414,7 @@ export default class CurlyComponentManager

component._transitionTo('hasElement');

if (environment.isInteractive) {
if (isInteractive) {
beginUntrackFrame();
component.trigger('willInsertElement');
endUntrackFrame();
Expand All @@ -423,16 +426,16 @@ export default class CurlyComponentManager
bucket.finalize();
}

didCreate({ component, environment }: ComponentStateBucket): void {
if (environment.isInteractive) {
didCreate({ component, isInteractive }: ComponentStateBucket): void {
if (isInteractive) {
component._transitionTo('inDOM');
component.trigger('didInsertElement');
component.trigger('didRender');
}
}

update(bucket: ComponentStateBucket): void {
let { component, args, argsTag, argsRevision, environment } = bucket;
let { component, args, argsTag, argsRevision, isInteractive } = bucket;

bucket.finalizer = _instrumentStart('render.component', rerenderInstrumentDetails, component);

Expand All @@ -453,7 +456,7 @@ export default class CurlyComponentManager
component.trigger('didReceiveAttrs');
}

if (environment.isInteractive) {
if (isInteractive) {
component.trigger('willUpdate');
component.trigger('willRender');
}
Expand All @@ -468,8 +471,8 @@ export default class CurlyComponentManager
bucket.finalize();
}

didUpdate({ component, environment }: ComponentStateBucket): void {
if (environment.isInteractive) {
didUpdate({ component, isInteractive }: ComponentStateBucket): void {
if (isInteractive) {
component.trigger('didUpdate');
component.trigger('didRender');
}
Expand Down Expand Up @@ -553,6 +556,7 @@ export const CURLY_CAPABILITIES: InternalComponentCapabilities = {
createInstance: true,
wrapped: true,
willDestroy: true,
hasSubOwner: false,
};

export const CURLY_COMPONENT_MANAGER = new CurlyComponentManager();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const CAPABILITIES: InternalComponentCapabilities = {
createInstance: true,
wrapped: false,
willDestroy: false,
hasSubOwner: false,
};

export interface InternalComponentState {
Expand All @@ -40,27 +41,21 @@ export default class InternalManager
implements
InternalComponentManager<InternalComponentState, EmberInternalComponentConstructor>,
WithCreateInstance {
static for(
definition: EmberInternalComponentConstructor,
name: string
): (owner: Owner) => InternalManager {
return (owner: Owner) => new InternalManager(owner, definition, name);
static for(definition: EmberInternalComponentConstructor, name: string): () => InternalManager {
return () => new InternalManager(definition, name);
}

constructor(
private owner: Owner,
private ComponentClass: EmberInternalComponentConstructor,
private name: string
) {}
constructor(private ComponentClass: EmberInternalComponentConstructor, private name: string) {}

getCapabilities(): InternalComponentCapabilities {
return CAPABILITIES;
}

create(
env: Environment,
owner: Owner,
_definition: unknown,
args: VMArguments,
env: Environment,
_dynamicScope: DynamicScope,
caller: Reference
): InternalComponentState {
Expand All @@ -71,7 +66,7 @@ export default class InternalManager
args.positional.length === 0
);

let { ComponentClass, owner } = this;
let { ComponentClass } = this;
let instance = new ComponentClass(owner, args.named.capture(), valueForRef(caller));

let state = { env, instance };
Expand Down
15 changes: 11 additions & 4 deletions packages/@ember/-internals/glimmer/lib/component-managers/mount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
WithCreateInstance,
WithCustomDebugRenderTree,
WithDynamicLayout,
WithSubOwner,
} from '@glimmer/interfaces';
import { capabilityFlagsFrom } from '@glimmer/manager';
import { createConstRef, Reference, valueForRef } from '@glimmer/reference';
Expand Down Expand Up @@ -45,13 +46,15 @@ const CAPABILITIES = {
createInstance: true,
wrapped: false,
willDestroy: false,
hasSubOwner: true,
};

class MountManager
implements
WithCreateInstance<EngineState, Environment>,
WithCreateInstance<EngineState>,
WithDynamicLayout<EngineState, RuntimeResolver>,
WithCustomDebugRenderTree<EngineState, EngineDefinitionState> {
WithCustomDebugRenderTree<EngineState, EngineDefinitionState>,
WithSubOwner<EngineState> {
getDynamicLayout(state: EngineState) {
let templateFactory = state.engine.lookup('template:application') as TemplateFactory;
return unwrapTemplate(templateFactory(state.engine)).asLayout();
Expand All @@ -61,13 +64,17 @@ class MountManager
return CAPABILITIES;
}

create(env: Environment<Owner>, { name }: EngineDefinitionState, args: VMArguments) {
getOwner(state: EngineState) {
return state.engine;
}

create(owner: Owner, { name }: EngineDefinitionState, args: VMArguments, env: Environment) {
// TODO
// mount is a runtime helper, this shouldn't use dynamic layout
// we should resolve the engine app template in the helper
// it also should use the owner that looked up the mount helper.

let engine = env.owner.buildChildEngineInstance(name);
let engine = owner.buildChildEngineInstance(name);

engine.boot();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ENV } from '@ember/-internals/environment';
import { Owner } from '@ember/-internals/owner';
import { guidFor } from '@ember/-internals/utils';
import { assert } from '@ember/debug';
import EngineInstance from '@ember/engine/instance';
Expand Down Expand Up @@ -64,16 +65,18 @@ const CAPABILITIES: InternalComponentCapabilities = {
createInstance: true,
wrapped: false,
willDestroy: false,
hasSubOwner: false,
};

class OutletComponentManager
implements
WithCreateInstance<OutletInstanceState, Environment>,
WithCreateInstance<OutletInstanceState>,
WithCustomDebugRenderTree<OutletInstanceState, OutletDefinitionState> {
create(
env: Environment,
_owner: Owner,
definition: OutletDefinitionState,
_args: VMArguments,
env: Environment,
dynamicScope: DynamicScope
): OutletInstanceState {
let parentStateRef = dynamicScope.get('outletState');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
Environment,
InternalComponentCapabilities,
Option,
Owner,
VMArguments,
} from '@glimmer/interfaces';
import { capabilityFlagsFrom } from '@glimmer/manager';
Expand All @@ -27,9 +28,10 @@ class RootComponentManager extends CurlyComponentManager {
}

create(
environment: Environment,
_owner: Owner,
_state: unknown,
_args: Option<VMArguments>,
{ isInteractive }: Environment,
dynamicScope: DynamicScope
) {
let component = this.component;
Expand All @@ -42,13 +44,13 @@ class RootComponentManager extends CurlyComponentManager {

// We usually do this in the `didCreateElement`, but that hook doesn't fire for tagless components
if (!hasWrappedElement) {
if (environment.isInteractive) {
if (isInteractive) {
component.trigger('willRender');
}

component._transitionTo('hasElement');

if (environment.isInteractive) {
if (isInteractive) {
component.trigger('willInsertElement');
}
}
Expand All @@ -58,12 +60,12 @@ class RootComponentManager extends CurlyComponentManager {
}

let bucket = new ComponentStateBucket(
environment,
component,
null,
CONSTANT_TAG,
finalizer,
hasWrappedElement
hasWrappedElement,
isInteractive
);

consumeTag(component[DIRTY_TAG]);
Expand All @@ -87,6 +89,7 @@ export const ROOT_CAPABILITIES: InternalComponentCapabilities = {
createInstance: true,
wrapped: true,
willDestroy: false,
hasSubOwner: false,
};

export class RootComponentDefinition implements ComponentDefinition {
Expand Down
2 changes: 1 addition & 1 deletion packages/@ember/-internals/glimmer/lib/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -724,7 +724,7 @@ const Component = CoreView.extend(
this[DIRTY_TAG] = createTag();
this[BOUNDS] = null;

if (DEBUG && this.renderer._destinedForDOM && this.tagName === '') {
if (DEBUG && this.renderer._isInteractive && this.tagName === '') {
let eventNames = [];
let eventDispatcher = getOwner(this).lookup<any | undefined>('event_dispatcher:main');
let events = (eventDispatcher && eventDispatcher._finalEvents) || {};
Expand Down
Loading

0 comments on commit 9588535

Please sign in to comment.