Currently it's required to pass in the tag name when determining the security context, however with selectorless we might not have a tag name. These changes update the logic to account for it.
PR Close#60724
Renames the `hostProperty` instruction to `domProperty` since it's not really host-specific and we can use it for other DOM-specific operations in the future.
PR Close#60608
Moves the logic for parsing event names out into methods on the `BindingParser` so we don't have to duplicate it. Also updates the types to more accurately represent the runtime value.
PR Close#60561
The `TemplateLiteralElementExpr` has some logic where it tries to estimate the `rawText` if one isn't provided by looking at the node's source span. The problem with this approach is that we have some long-standing issues with our expression AST parser (see https://github.com/angular/angular/pull/60267#discussion_r1986402524) where it might not produce accurate spans if escape sequences are involved. This in turn can lead to unrecoverable errors, because TypeScript will throw an error if the raw string doesn't match the cooked one when constructing a TypeScript AST node.
These changes remove the logic that depends on the source span and relies purely on the secondary fallback that inserts escaped characters manually.
It's also worth noting that the `rawText` doesn't seem to matter much at this point, because the main usage of it is when downlevelling template literals to ES5 which we no longer support.
Fixes#60528.
PR Close#60529
This adds a new instruction for dealing with creating conditionals. It ensures flags are set on the TNode for later identification during hydration.
PR Close#60425
Removes logic that was explicitly adding parentheses around ternaries
used as the condition of another ternary. Instead we can just rely on
Typescript to add the parentheses if they are needed to make the code
match the structure of the AST.
Also added a note pointing to the issue that currently prevents us from
removing similar logic pertaining to nullish coalescing
PR Close#60263
Adds the `HostElement` AST node that can be used to represent the host of a directive. Also exposes the `BindingParser` type so it's easier to pass around the return value of `makeBindingParser`.
PR Close#60267
Now that the expression AST contains parenthesized expressions, this
refactors the template pipeline to strip out the ones we don't need.
PR Close#60169
Following up on #60127 which added the concept of a parenthesized
expression to the output AST, this does the same for the expression AST.
PR Close#60169
Currently `R3TargetBinder.bind` gets a set of data back from `DirectiveBinder.apply` and `TemplateBinder.applyWithScope`. This will be annoying if we have multiple sources of data, because we'd have to do merge them at the end.
These changes switch to constructing the various data structures ahead of time and passing them into the binders to populate them instead.
I also extracted some of the less trivial types into type aliases so we don't have to repeat them.
PR Close#60191
Instead of using a property on BinaryOperatorExpr / UnaryOperatorExpr,
introduce a ParenthesizedExpr which can be used to parenthesize any
expression.
PR Close#60127
Add support for the `void` operator in templates and host bindings.
This is useful when binding a listener that may return `false` and
unintentionally prevent the default event behavior.
Ex:
```
@Directive({
host: { '(mousedown)': 'void handleMousedown()' }
})
```
BREAKING CHANGE: `void` in an expression now refers to the operator
Previously an expression in the template like `{{void}}` referred to a
property on the component class. After this change it now refers to the
`void` operator, which would make the above example invalid. If you have
existing expressions that need to refer to a property named `void`,
change the expression to use `this.void` instead: `{{this.void}}`.
PR Close#59894
Currently when we generate the tracking expression for a `@for` block, we process its expression in the context of the creation block. This is incorrect, because the expression may require ops of its own for cases like nullish coalescing or safe reads. The result is that while we do generate the correct variable, they're added to the creation block rather than the tracking function which causes an error at runtime.
These changes address the issue by keeping track of a separate set of ops for the `track` expression that are prepended to the generated function, similarly to how we handle event listeners.
Fixes#56256.
PR Close#58520
Adjusts the code we generate for HMR so that it passes in the HMR ID and `import.meta` to the `replaceMetadata` call. This is necessary so we can do better logging of errors.
PR Close#59854
When we generate an HMR replacement function, we determine which locals from the file are used and we pass them by reference. This works fine in most cases, but breaks down for const enums which don't have a runtime representation.
These changes work around the issue by passing in all the values as an object literal.
Fixes#59800.
PR Close#59815
Makes the following cleanups in the output AST:
* The `TemplateLiteral` and `TemplateLiteralElement` nodes have been renamed to `TemplateLiteralExpr` and `TemplateLiteralElementExpr` respectively for consistency and to avoid overlaps with the expression AST nodes.
* The `TemplateLiteralExpr` and `TemplateLiteralElementExpr` have been refactored to be `Expression`s for correctness. This involves updating some existing code.
* The `TaggedTemplateExpr` has been renamed to `TaggedTemplateLiteralExpr` for consistency.
PR Close#59230
Reworks the lexer's scanner to produce more than one token at a time. This can be useful for the cases where one token means the end of another one.
Also cleans up the scanner by making all non-essential methods private and using strict equality everywhere.
PR Close#59230
Both `:host` and `:host-context` work by looking for a specific character sequence that is terminated by `,` or `{` and replacing selectors inside of it with scoped versions. This is implemented as a regex which isn't aware of things like nested selectors. Normally this is fine for `:host`, because each `:host` produces one scoped selector which doesn't affect any child selectors, however it breaks down with `:host-context` which replaces each instance with two selectors. For example, if we have a selector in the form of `:host-context(.foo) a:not(.a, .b)`, the compiler ends up determining that `.a,` is the end selector and produces `.foo[a-host] a[contenta]:not(.a, .foo [a-host] a[contenta]:not(.a, .b) {}`.
These changes resolve the issue by splitting the CSS alogn top-level commas, processing the `:host-context` in them individually, and stiching the CSS back together.
PR Close#59276
The URL that is dynamically imported to fetch a potential component update
for HMR is now based on the value of `import.meta.url`. This ensures that
the request is sent to the same location that was used to retrieve the
application code. For some development server setups the HTML base HREF
may not be the location of the Angular development server. By using the
application code location which was generated by the development server,
HMR requests can continue to work as expected in these scenarios. In
most common cases, this change will not have any effect as the HTML base
HREF aligns with the location of the application code files.
PR Close#59459