1
1
import { DEBUG } from '@glimmer/env' ;
2
2
import { ComponentCapabilities } from '@glimmer/interfaces' ;
3
- import { CONSTANT_TAG , Tag , validate , value , VersionedPathReference } from '@glimmer/reference' ;
4
- import { ComponentDefinition , Invocation , WithDynamicLayout } from '@glimmer/runtime' ;
3
+ import { CONSTANT_TAG , Tag , VersionedPathReference } from '@glimmer/reference' ;
4
+ import { Arguments , ComponentDefinition , Invocation , WithDynamicLayout } from '@glimmer/runtime' ;
5
5
import { Destroyable , Opaque , Option } from '@glimmer/util' ;
6
6
7
7
import { Owner } from '@ember/-internals/owner' ;
8
8
import { generateControllerFactory } from '@ember/-internals/routing' ;
9
9
import { OwnedTemplateMeta } from '@ember/-internals/views' ;
10
+ import { EMBER_ROUTING_MODEL_ARG } from '@ember/canary-features' ;
11
+ import { assert } from '@ember/debug' ;
12
+
10
13
import { TemplateFactory } from '../..' ;
11
14
import Environment from '../environment' ;
12
15
import RuntimeResolver from '../resolver' ;
@@ -23,24 +26,18 @@ interface EngineState {
23
26
engine : EngineInstance ;
24
27
controller : any ;
25
28
self : RootReference < any > ;
26
- tag : Tag ;
27
- }
28
-
29
- interface EngineWithModelState extends EngineState {
30
- modelRef : VersionedPathReference < Opaque > ;
31
- modelRev : number ;
29
+ modelRef ?: VersionedPathReference < Opaque > ;
32
30
}
33
31
34
32
interface EngineDefinitionState {
35
33
name : string ;
36
- modelRef : VersionedPathReference < Opaque > | undefined ;
37
34
}
38
35
39
36
const CAPABILITIES = {
40
37
dynamicLayout : true ,
41
38
dynamicTag : false ,
42
39
prepareArgs : false ,
43
- createArgs : false ,
40
+ createArgs : true ,
44
41
attributeHook : false ,
45
42
elementHook : false ,
46
43
createCaller : true ,
@@ -49,10 +46,13 @@ const CAPABILITIES = {
49
46
createInstance : true ,
50
47
} ;
51
48
52
- class MountManager
53
- extends AbstractManager < EngineState | EngineWithModelState , EngineDefinitionState >
54
- implements
55
- WithDynamicLayout < EngineState | EngineWithModelState , OwnedTemplateMeta , RuntimeResolver > {
49
+ // TODO
50
+ // This "disables" the "@model" feature by making the arg untypable syntatically
51
+ // Delete this when EMBER_ROUTING_MODEL_ARG has shipped
52
+ export const MODEL_ARG_NAME = EMBER_ROUTING_MODEL_ARG || ! DEBUG ? 'model' : ' untypable model arg ' ;
53
+
54
+ class MountManager extends AbstractManager < EngineState , EngineDefinitionState >
55
+ implements WithDynamicLayout < EngineState , OwnedTemplateMeta , RuntimeResolver > {
56
56
getDynamicLayout ( state : EngineState , _ : RuntimeResolver ) : Invocation {
57
57
let templateFactory = state . engine . lookup ( 'template:application' ) as TemplateFactory ;
58
58
let template = templateFactory ( state . engine ) ;
@@ -68,39 +68,40 @@ class MountManager
68
68
return CAPABILITIES ;
69
69
}
70
70
71
- create ( environment : Environment , state : EngineDefinitionState ) {
71
+ create ( environment : Environment , { name } : EngineDefinitionState , args : Arguments ) {
72
72
if ( DEBUG ) {
73
- this . _pushEngineToDebugStack ( `engine:${ state . name } ` , environment ) ;
73
+ this . _pushEngineToDebugStack ( `engine:${ name } ` , environment ) ;
74
74
}
75
75
76
76
// TODO
77
77
// mount is a runtime helper, this shouldn't use dynamic layout
78
78
// we should resolve the engine app template in the helper
79
79
// it also should use the owner that looked up the mount helper.
80
80
81
- let engine = environment . owner . buildChildEngineInstance < EngineInstance > ( state . name ) ;
81
+ let engine = environment . owner . buildChildEngineInstance < EngineInstance > ( name ) ;
82
82
83
83
engine . boot ( ) ;
84
84
85
85
let applicationFactory = engine . factoryFor ( `controller:application` ) ;
86
86
let controllerFactory = applicationFactory || generateControllerFactory ( engine , 'application' ) ;
87
87
let controller : any ;
88
88
let self : RootReference < any > ;
89
- let bucket : EngineState | EngineWithModelState ;
90
- let tag : Tag ;
91
- let modelRef = state . modelRef ;
89
+ let bucket : EngineState ;
90
+ let modelRef ;
91
+
92
+ if ( args . named . has ( MODEL_ARG_NAME ) ) {
93
+ modelRef = args . named . get ( MODEL_ARG_NAME ) ;
94
+ }
95
+
92
96
if ( modelRef === undefined ) {
93
97
controller = controllerFactory . create ( ) ;
94
98
self = new RootReference ( controller ) ;
95
- tag = CONSTANT_TAG ;
96
- bucket = { engine, controller, self, tag } ;
99
+ bucket = { engine, controller, self } ;
97
100
} else {
98
101
let model = modelRef . value ( ) ;
99
- let modelRev = value ( modelRef . tag ) ;
100
102
controller = controllerFactory . create ( { model } ) ;
101
103
self = new RootReference ( controller ) ;
102
- tag = modelRef . tag ;
103
- bucket = { engine, controller, self, tag, modelRef, modelRev } ;
104
+ bucket = { engine, controller, self, modelRef } ;
104
105
}
105
106
106
107
return bucket ;
@@ -110,8 +111,12 @@ class MountManager
110
111
return self ;
111
112
}
112
113
113
- getTag ( state : EngineState | EngineWithModelState ) : Tag {
114
- return state . tag ;
114
+ getTag ( state : EngineState ) : Tag {
115
+ if ( state . modelRef ) {
116
+ return state . modelRef . tag ;
117
+ } else {
118
+ return CONSTANT_TAG ;
119
+ }
115
120
}
116
121
117
122
getDestructor ( { engine } : EngineState ) : Option < Destroyable > {
@@ -124,13 +129,9 @@ class MountManager
124
129
}
125
130
}
126
131
127
- update ( bucket : EngineWithModelState ) : void {
128
- let { controller, modelRef, modelRev } = bucket ;
129
- if ( ! validate ( modelRef . tag , modelRev ! ) ) {
130
- let model = modelRef . value ( ) ;
131
- bucket . modelRev = value ( modelRef . tag ) ;
132
- controller . set ( 'model' , model ) ;
133
- }
132
+ update ( { controller, modelRef } : EngineState ) : void {
133
+ assert ( '[BUG] `update` should only be called when modelRef is present' , modelRef !== undefined ) ;
134
+ controller . set ( 'model' , modelRef ! . value ( ) ) ;
134
135
}
135
136
}
136
137
@@ -140,7 +141,7 @@ export class MountDefinition implements ComponentDefinition {
140
141
public state : EngineDefinitionState ;
141
142
public manager = MOUNT_MANAGER ;
142
143
143
- constructor ( name : string , modelRef : VersionedPathReference < Opaque > | undefined ) {
144
- this . state = { name, modelRef } ;
144
+ constructor ( name : string ) {
145
+ this . state = { name } ;
145
146
}
146
147
}
0 commit comments