8000 refactor(compiler): account for host element in binder (#60267) · angular/angular@7ffcb50 · GitHub
[go: up one dir, main page]

Skip to content

Commit 7ffcb50

Browse files
crisbetopkozlowski-opensource
authored andcommitted
refactor(compiler): account for host element in binder (#60267)
Updates the `R3TargetBinder` to ingest host element nodes. PR Close #60267
1 parent a34353c commit 7ffcb50

File tree

2 files changed

+31
-9
lines changed

2 files changed

+31
-9
lines changed

packages/compiler/src/render3/view/t2_api.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
Element,
2020
ForLoopBlock,
2121
ForLoopBlockEmpty,
22+
HostElement,
2223
IfBlockBranch,
2324
LetDeclaration,
2425
Node,
@@ -40,7 +41,8 @@ export type ScopedNode =
4041
| DeferredBlockError
4142
| DeferredBlockLoading
4243
| DeferredBlockPlaceholder
43-
| Content;
44+
| Content
45+
| HostElement;
4446

4547
/** Possible values that a reference can be resolved to. */
4648
export type ReferenceTarget<DirectiveT> =
@@ -68,6 +70,7 @@ export type TemplateEntity = Reference | Variable | LetDeclaration;
6870
*/
6971
export interface Target {
7072
template?: Node[];
73+
host?: HostElement;
7174
}
7275

7376
/**

packages/compiler/src/render3/view/t2_binder.ts

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import {
3131
Element,
3232
ForLoopBlock,
3333
ForLoopBlockEmpty,
34+
HostElement,
3435
HoverDeferredTrigger,
3536
Icu,
3637
IfBlock,
@@ -169,7 +170,7 @@ export class R3TargetBinder<DirectiveT extends DirectiveMeta> implements TargetB
169170
* metadata about the types referenced in the template.
170171
*/
171172
bind(target: Target): BoundTarget<DirectiveT> {
172-
if (!target.template) {
173+
if (!target.template && !target.host) {
173174
throw new Error('Empty bound targets are not supported');
174175
}
175176

@@ -221,6 +222,21 @@ export class R3TargetBinder<DirectiveT extends DirectiveMeta> implements TargetB
221222
);
222223
}
223224

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+
224240
return new R3BoundTarget(
225241
target,
226242
directives,
@@ -280,7 +296,7 @@ class Scope implements Visitor {
280296
* Process a template (either as a `Template` sub-template with variables, or a plain array of
281297
* template `Node`s) and construct its `Scope`.
282298
*/
283-
static apply(template: Node[]): Scope {
299+
static apply(template: ScopedNode | Node[]): Scope {
284300
const scope = Scope.newRootScope();
285301
scope.ingest(template);
286302
return scope;
@@ -315,7 +331,7 @@ class Scope implements Visitor {
315331
nodeOrNodes instanceof Content
316332
) {
317333
nodeOrNodes.children.forEach((node) => node.visit(this));
318-
} else {
334+
} else if (!(nodeOrNodes instanceof HostElement)) {
319335
// No overarching `Template` instance, so process the nodes directly.
320336
nodeOrNodes.forEach((node) => node.visit(this));
321337
}
@@ -702,7 +718,7 @@ class TemplateBinder extends RecursiveAstVisitor implements Visitor {
702718
/**
703719
* Process a template and extract metadata about expressions and symbols within.
704720
*
705-
* @param nodes the nodes of the template to process
721+
* @param nodeOrNodes the nodes of the template to process
706722
* @param scope the `Scope` of the template being processed.
707723
* @returns three maps which contain metadata about the template: `expressions` which interprets
708724
* special `AST` nodes in expressions as pointing to references or variables declared within the
@@ -712,7 +728,7 @@ class TemplateBinder extends RecursiveAstVisitor implements Visitor {
712728
* at 1.
713729
*/
714730
static applyWithScope(
715-
nodes: Node[],
731+
nodeOrNodes: ScopedNode | Node[],
716732
scope: Scope,
717733
expressions: Map<AST, TemplateEntity>,
718734
symbols: Map<TemplateEntity, Template>,
@@ -721,7 +737,7 @@ class TemplateBinder extends RecursiveAstVisitor implements Visitor {
721737
eagerPipes: Set<string>,
722738
deferBlocks: DeferBlockScopes,
723739
): void {
724-
const template = nodes instanceof Template ? nodes : null;
740+
const template = nodeOrNodes instanceof Template ? nodeOrNodes : null;
725741
// The top-level template has nesting level 0.
726742
const binder = new TemplateBinder(
727743
expressions,
@@ -734,7 +750,7 @@ class TemplateBinder extends RecursiveAstVisitor implements Visitor {
734750
template,
735751
0,
736752
);
737-
binder.ingest(nodes);
753+
binder.ingest(nodeOrNodes);
738754
}
739755

740756
private ingest(nodeOrNodes: ScopedNode | Node[]): void {
@@ -777,6 +793,9 @@ class TemplateBinder extends RecursiveAstVisitor implements Visitor {
777793
) {
778794
nodeOrNodes.children.forEach((node) => node.visit(this));
779795
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);
780799
} else {
781800
// Visit each node from the top-level template.
782801
nodeOrNodes.forEach(this.visitNode);
@@ -967,7 +986,7 @@ class TemplateBinder extends RecursiveAstVisitor implements Visitor {
967986
*
968987
* See `BoundTarget` for documentation on the individual methods.
969988
*/
970-
export class R3BoundTarget<DirectiveT extends DirectiveMeta> implements BoundTarget<DirectiveT> {
989+
class R3BoundTarget<DirectiveT extends DirectiveMeta> implements BoundTarget<DirectiveT> {
971990
/** Deferred blocks, ordered as they appear in the template. */
972991
private deferredBlocks: DeferredBlock[];
973992

0 commit comments

Comments
 (0)
0