@@ -31,6 +31,7 @@ import {
31
31
Element ,
32
32
ForLoopBlock ,
33
33
ForLoopBlockEmpty ,
34
+ HostElement ,
34
35
HoverDeferredTrigger ,
35
36
Icu ,
36
37
IfBlock ,
@@ -169,7 +170,7 @@ export class R3TargetBinder<DirectiveT extends DirectiveMeta> implements TargetB
169
170
* metadata about the types referenced in the template.
170
171
*/
171
172
bind ( target : Target ) : BoundTarget < DirectiveT > {
172
- if ( ! target . template ) {
173
+ if ( ! target . template && ! target . host ) {
173
174
throw new Error ( 'Empty bound targets are not supported' ) ;
174
175
}
175
176
@@ -221,6 +222,21 @@ export class R3TargetBinder<DirectiveT extends DirectiveMeta> implements TargetB
221
222
) ;
222
223
}
223
224
225
+ // Bind the host element in a separate scope. Note that it only uses the
226
+ // `TemplateBinder` since directives don't apply inside a host context.
227
+ if ( target . host ) {
228
+ TemplateBinder . applyWithScope (
<
8000
/code>
229
+ target . host ,
230
+ Scope . apply ( target . host ) ,
231
+ expressions ,
232
+ symbols ,
233
+ nestingLevel ,
234
+ usedPipes ,
235
+ eagerPipes ,
236
+ deferBlocks ,
237
+ ) ;
238
+ }
239
+
224
240
return new R3BoundTarget (
225
241
target ,
226
242
directives ,
@@ -280,7 +296,7 @@ class Scope implements Visitor {
280
296
* Process a template (either as a `Template` sub-template with variables, or a plain array of
281
297
* template `Node`s) and construct its `Scope`.
282
298
*/
283
- static apply ( template : Node [ ] ) : Scope {
299
+ static apply ( template : ScopedNode | Node [ ] ) : Scope {
284
300
const scope = Scope . newRootScope ( ) ;
285
301
scope . ingest ( template ) ;
286
302
return scope ;
@@ -315,7 +331,7 @@ class Scope implements Visitor {
315
331
nodeOrNodes instanceof Content
316
332
) {
317
333
nodeOrNodes . children . forEach ( ( node ) => node . visit ( this ) ) ;
318
- } else {
334
+ } else if ( ! ( nodeOrNodes instanceof HostElement ) ) {
319
335
// No overarching `Template` instance, so process the nodes directly.
320
336
nodeOrNodes . forEach ( ( node ) => node . visit ( this ) ) ;
321
337
}
@@ -702,7 +718,7 @@ class TemplateBinder extends RecursiveAstVisitor implements Visitor {
702
718
/**
703
719
* Process a template and extract metadata about expressions and symbols within.
704
720
*
705
- * @param nodes the nodes of the template to process
721
+ * @param nodeOrNodes the nodes of the template to process
706
722
* @param scope the `Scope` of the template being processed.
707
723
* @returns three maps which contain metadata about the template: `expressions` which interprets
708
724
* special `AST` nodes in expressions as pointing to references or variables declared within the
@@ -712,7 +728,7 @@ class TemplateBinder extends RecursiveAstVisitor implements Visitor {
712
728
* at 1.
713
729
*/
714
730
static applyWithScope (
715
- nodes : Node [ ] ,
731
+ nodeOrNodes : ScopedNode | Node [ ] ,
716
732
scope : Scope ,
717
733
expressions : Map < AST , TemplateEntity > ,
718
734
symbols : Map < TemplateEntity , Template > ,
@@ -721,7 +737,7 @@ class TemplateBinder extends RecursiveAstVisitor implements Visitor {
721
737
eagerPipes : Set < string > ,
722
738
deferBlocks : DeferBlockScopes ,
723
739
) : void {
724
- const template = nodes instanceof Template ? nodes : null ;
740
+ const template = nodeOrNodes instanceof Template ? nodeOrNodes : null ;
725
741
// The top-level template has nesting level 0.
726
742
const binder = new TemplateBinder (
727
743
expressions ,
@@ -734,7 +750,7 @@ class TemplateBinder extends RecursiveAstVisitor implements Visitor {
734
750
template ,
735
751
0 ,
736
752
) ;
737
- binder . ingest ( nodes ) ;
753
+ binder . ingest ( nodeOrNodes ) ;
738
754
}
739
755
740
756
private ingest ( nodeOrNodes : ScopedNode | Node [ ] ) : void {
@@ -777,6 +793,9 @@ class TemplateBinder extends RecursiveAstVisitor implements Visitor {
777
793
) {
778
794
nodeOrNodes . children . forEach ( ( node ) => node . visit ( this ) ) ;
779
795
this . nestingLevel . set ( nodeOrNodes , this . level ) ;
796
+ } else if ( nodeOrNodes instanceof HostElement ) {
797
+ // Host elements are always at the top level.
798
+ this . nestingLevel . set ( nodeOrNodes , 0 ) ;
780
799
} else {
781
800
// Visit each node from the top-level template.
782
801
nodeOrNodes . forEach ( this . visitNode ) ;
@@ -967,7 +986,7 @@ class TemplateBinder extends RecursiveAstVisitor implements Visitor {
967
986
*
968
987
* See `BoundTarget` for documentation on the individual methods.
969
988
*/
970
- export class R3BoundTarget < DirectiveT extends DirectiveMeta > implements BoundTarget < DirectiveT > {
989
+ class R3BoundTarget < DirectiveT extends DirectiveMeta > implements BoundTarget < DirectiveT > {
971
990
/** Deferred blocks, ordered as they appear in the template. */
972
991
private deferredBlocks : DeferredBlock [ ] ;
973
992
0 commit comments