77 */
88
99import { isDevMode } from '../application_ref' ;
10+ import { RendererTypeV2 , RendererV2 } from '../render/api' ;
1011import { SecurityContext } from '../security' ;
1112
12- import { BindingDef , BindingType , DebugContext , DisposableFn , ElementData , ElementHandleEventFn , ElementOutputDef , NodeData , NodeDef , NodeFlags , NodeType , QueryValueType , Services , ViewData , ViewDefinition , ViewDefinitionFactory , ViewFlags , asElementData } from './types' ;
13+ import { BindingDef , BindingType , DebugContext , DisposableFn , ElementData , ElementHandleEventFn , NodeData , NodeDef , NodeFlags , NodeType , OutputDef , OutputType , QueryValueType , Services , ViewData , ViewDefinition , ViewDefinitionFactory , ViewFlags , asElementData , asProviderData } from './types' ;
1314import { checkAndUpdateBinding , dispatchEvent , elementEventFullName , filterQueryId , getParentRenderElement , resolveViewDefinition , sliceErrorStack , splitMatchedQueriesDsl , splitNamespace } from './util' ;
1415
1516const NOOP : any = ( ) => { } ;
@@ -34,20 +35,20 @@ export function anchorDef(
3435 parent : undefined ,
3536 renderParent : undefined ,
3637 bindingIndex : undefined ,
37- disposableIndex : undefined ,
38+ outputIndex : undefined ,
3839 // regular values
3940 flags,
4041 childFlags : 0 ,
4142 childMatchedQueries : 0 , matchedQueries, matchedQueryIds, references, ngContentIndex, childCount,
4243 bindings : [ ] ,
43- disposableCount : 0 ,
44+ outputs : [ ] ,
4445 element : {
4546 ns : undefined ,
4647 name : undefined ,
47- attrs : undefined ,
48- outputs : [ ] , template , source ,
49- // will bet set by the view definition
50- component : undefined ,
48+ attrs : undefined , template , source ,
49+ componentProvider : undefined ,
50+ componentView : undefined ,
51+ componentRendererType : undefined ,
5152 publicProviders : undefined ,
5253 allProviders : undefined , handleEvent
5354 } ,
@@ -65,8 +66,13 @@ export function elementDef(
6566 fixedAttrs : [ string , string ] [ ] = [ ] ,
6667 bindings ?:
6768 ( [ BindingType . ElementClass , string ] | [ BindingType . ElementStyle , string , string ] |
68- [ BindingType . ElementAttribute | BindingType . ElementProperty , string , SecurityContext ] ) [ ] ,
69- outputs ?: ( string | [ string , string ] ) [ ] , handleEvent ?: ElementHandleEventFn ) : NodeDef {
69+ [
70+ BindingType . ElementAttribute | BindingType . ElementProperty |
71+ BindingType . ComponentHostProperty ,
72+ string , SecurityContext
73+ ] ) [ ] ,
74+ outputs ?: ( [ string , string ] ) [ ] , handleEvent ?: ElementHandleEventFn ,
75+ componentView ?: ( ) => ViewDefinition , componentRendererType ?: RendererTypeV2 ) : NodeDef {
7076 if ( ! handleEvent ) {
7177 handleEvent = NOOP ;
7278 }
@@ -93,29 +99,35 @@ export function elementDef(
9399 break ;
94100 case BindingType . ElementAttribute :
95101 case BindingType . ElementProperty :
102+ case BindingType . ComponentHostProperty :
96103 securityContext = < SecurityContext > entry [ 2 ] ;
97104 break ;
98105 }
99106 bindingDefs [ i ] = { type : bindingType , ns, name, nonMinifiedName : name , securityContext, suffix} ;
100107 }
101108 outputs = outputs || [ ] ;
102- const outputDefs : ElementOutputDef [ ] = new Array ( outputs . length ) ;
109+ const outputDefs : OutputDef [ ] = new Array ( outputs . length ) ;
103110 for ( let i = 0 ; i < outputs . length ; i ++ ) {
104- const output = outputs [ i ] ;
105- let target : string ;
106- let eventName : string ;
107- if ( Array . isArray ( output ) ) {
108- [ target , eventName ] = output ;
109- } else {
110- eventName = output ;
111- }
112- outputDefs [ i ] = { eventName : eventName , target : target } ;
111+ const [ target , eventName ] = outputs [ i ] ;
112+ outputDefs [ i ] = {
113+ type : OutputType . ElementOutput ,
114+ target : < any > target , eventName,
115+ propName : undefined
116+ } ;
113117 }
114118 fixedAttrs = fixedAttrs || [ ] ;
115119 const attrs = < [ string , string , string ] [ ] > fixedAttrs . map ( ( [ namespaceAndName , value ] ) => {
116120 const [ ns , name ] = splitNamespace ( namespaceAndName ) ;
117121 return [ ns , name , value ] ;
118122 } ) ;
123+ // This is needed as the jit compiler always uses an empty hash as default RendererTypeV2,
124+ // which is not filled for host views.
125+ if ( componentRendererType && componentRendererType . encapsulation == null ) {
126+ componentRendererType = null ;
127+ }
128+ if ( componentView ) {
129+ flags |= NodeFlags . HasComponent ;
130+ }
119131 return {
120132 type : NodeType . Element ,
121133 // will bet set by the view definition
@@ -124,21 +136,21 @@ export function elementDef(
124136 parent : undefined ,
125137 renderParent : undefined ,
126138 bindingIndex : undefined ,
127- disposableIndex : undefined ,
139+ outputIndex : undefined ,
128140 // regular values
129141 flags,
130142 childFlags : 0 ,
131143 childMatchedQueries : 0 , matchedQueries, matchedQueryIds, references, ngContentIndex, childCount,
132144 bindings : bindingDefs ,
133- disposableCount : outputDefs . length ,
145+ outputs : outputDefs ,
134146 element : {
135147 ns,
136148 name,
137149 attrs,
138- outputs : outputDefs , source,
150+ source,
139151 template : undefined ,
140152 // will bet set by the view definition
141- component : undefined ,
153+ componentProvider : undefined , componentView , componentRendererType ,
142154 publicProviders : undefined ,
143155 allProviders : undefined , handleEvent,
144156 } ,
@@ -174,21 +186,24 @@ export function createElement(view: ViewData, renderHost: any, def: NodeDef): El
174186 renderer . setAttribute ( el , name , value , ns ) ;
175187 }
176188 }
177- if ( elDef . outputs . length ) {
178- for ( let i = 0 ; i < elDef . outputs . length ; i ++ ) {
179- const output = elDef . outputs [ i ] ;
180- const handleEventClosure = renderEventHandlerClosure (
181- view , def . index , elementEventFullName ( output . target , output . eventName ) ) ;
182- const disposable =
183- < any > renderer . listen ( output . target || el , output . eventName , handleEventClosure ) ;
184- view . disposables [ def . disposableIndex + i ] = disposable ;
189+ return el ;
190+ }
191+
192+ export function listenToElementOutputs ( view : ViewData , compView : ViewData , def : NodeDef , el : any ) {
193+ for ( let i = 0 ; i < def . outputs . length ; i ++ ) {
194+ const output = def . outputs [ i ] ;
195+ const handleEventClosure = renderEventHandlerClosure (
196+ view , def . index , elementEventFullName ( output . target , output . eventName ) ) ;
197+ let listenTarget = output . target ;
198+ let listenerView = view ;
199+ if ( output . target === 'component' ) {
200+ listenTarget = null ;
201+ listenerView = compView ;
185202 }
203+ const disposable =
204+ < any > listenerView . renderer . listen ( listenTarget || el , output . eventName , handleEventClosure ) ;
205+ view . disposables [ def . outputIndex + i ] = disposable ;
186206 }
187- return {
188- renderElement : el ,
189- embeddedViews : ( def . flags & NodeFlags . HasEmbeddedViews ) ? [ ] : undefined ,
190- projectedViews : undefined
191- } ;
192207}
193208
194209function renderEventHandlerClosure ( view : ViewData , index : number , eventName : string ) {
@@ -223,7 +238,8 @@ function checkAndUpdateElementValue(view: ViewData, def: NodeDef, bindingIdx: nu
223238 return ;
224239 }
225240 const binding = def . bindings [ bindingIdx ] ;
226- const renderNode = asElementData ( view , def . index ) . renderElement ;
241+ const elData = asElementData ( view , def . index ) ;
242+ const renderNode = elData . renderElement ;
227243 const name = binding . name ;
228244 switch ( binding . type ) {
229245 case BindingType . ElementAttribute :
@@ -238,6 +254,9 @@ function checkAndUpdateElementValue(view: ViewData, def: NodeDef, bindingIdx: nu
238254 case BindingType . ElementProperty :
239255 setElementProperty ( view , binding , renderNode , name , value ) ;
240256 break ;
257+ case BindingType . ComponentHostProperty :
258+ setElementProperty ( elData . componentView , binding , renderNode , name , value ) ;
259+ break ;
241260 }
242261}
243262
0 commit comments