Replace loose equality (==) with strict equality (===) for the 'code' variable.
This change ensures type safety and prevents unintended type coercion.
PR Close#56944
Enables the new `@let` syntax by default.
`@let` declarations are defined as:
1. The `@let` keyword.
2. Followed by one or more whitespaces.
3. Followed by a valid JavaScript name and zero or more whitespaces.
4. Followed by the `=` symbol and zero or more whitespaces.
5. Followed by an Angular expression which can be multi-line.
6. Terminated by the `;` symbol.
Example usage:
```
@let user = user$ | async;
@let greeting = user ? 'Hello, ' + user.name : 'Loading';
<h1>{{greeting}}</h1>
```
Fixes#15280.
PR Close#56715
TemplateDefinitionBuilder is apparently more careful about when it attempts to split namespaces in attribute values. However, we are doing this on style attributes, which might start with a single `:`. Rather than refactor our logic to only try to split namespaces in some cases, we can just add an option to make namespace splitting fail gracefully. We only use this option for attributes, not elements.
Note also: the compiled code for this, while "correct" is absolutely insane. Maybe we should consider fixing this, as a matter of principle.
PR Close#53574
When blocks were initially implemented, they were represented as containers in the i18n AST. This is problematic, because block affect the structure of the message.
These changes introduce a new `BlockPlaceholder` AST node and integrate it into the i18n pipeline. With the new node blocks are represented with the `START_BLOCK_<name>` and `CLOSE_BLOCK_<name>` placeholders.
PR Close#52958
Previously, autocompletions were not available in two main cases. We correct them.
1. Autocompletions immediately after `@` were usually not working, for example `foo @|`. We fix this by causing the lexer to not consider the `@` part of the text node.
2. Autocompletions such as `@\nfoo`, where a newline follows a bare `@`, were not working because the language service visitor considered us inside the subsequent text node. We fix this by adding a block name span for the block keyword, and special-case whether we are completing inside the name span. If we are, we don't continue to the following text node.
PR Close#52198
Fixes that the compiler was throwing an error if an element tag name is the same as a built-in prototype property (e.g. `constructor` or `toString`). The problem was that we were storing the tag names in an object literal with the `Object` prototype. These changes resolve the issue by creating an object without a prototype.
Fixes#52224.
PR Close#52225
Adds some logic to treat incomplete blocks as empty blocks so that we can recover from them. Also logs an error about the incomplete block.
PR Close#52047
Updates the lexer to parse blocks as incomplete, instead of throwing errors. This will allow us to better handle them further down in the pipeline.
PR Close#52047
Enables the new `@` block syntax by default by removing the `enabledBlockTypes` flags. There are still some internal flags that allow special use cases to opt out of the block syntax, like during XML parsing and when compiling older libraries (see #51979).
PR Close#51994
Switches the syntax for blocks from `{#block}{/block}` to `@block {}` based on the feedback from the community.
Read more about the decision-making process in our blog: https://blog.angular.io/meet-angulars-new-control-flow-a02c6eee7843
The existing block types changed in the following ways:
**Conditional blocks:**
```html
<!-- Before -->
{#if cond}
Main content
{:else if otherCond}
Else if content
{:else}
Else content
{/if}
<!-- After -->
@if (cond) {
Main content
} @else if (otherCond) {
Else if content
} @else {
Else content
}
```
**Deferred blocks**
```html
<!-- Before -->
{#defer when isLoaded}
Main content
{:loading} Loading...
{:placeholder} <icon>pending</icon>
{:error} Failed to load
{/defer}
<!-- After -->
@defer (when isLoaded) {
Main content
} @loading {
Loading...
} @placeholder {
<icon>pending</icon>
} @error {
Failed to load
}
```
**Switch blocks:**
```html
<!-- Before -->
{#switch value}
{:case 1}
One
{:case 2}
Two
{:default}
Default
{/switch}
<!-- After -->
@switch (value) {
@case (1) {
One
}
@case (2) {
Two
}
@default {
Default
}
}
```
**For loops**
```html
<!-- Before -->
{#for item of items; track item}
{{item.name}}
{:empty} No items
{/for}
<!-- After -->
@for (item of items; track item) {
{{item.name}}
} @empty {
No items
}
```
PR Close#51891
Currently internally Angular has some customized tsconfig files, because we don't align with the tsconfig of the rest of g3. These changes enable `noImplicitReturns` and `noPropertyAccessFromIndexSignature` to align better with the internal config.
PR Close#51728
Change sourceSpan for Comment nodes to cover the whole comment
instead of just the opening token.
The primary motivation for this is the interaction between ESLint and
`@angular-eslint`. ESLint can detect unused `eslint-disable` directives
in comments and automatically remove them when running with `--fix`.
This is based on ranges computed from AST spans, and as a result
does not work inside Angular templates - right now all comments
claim to be 4 characters long so only the opening `<!--` is removed.
PR Close#50855
Fixes that using braces in the block parameters would result in incorrect tokens being produced. Currently we don't have any blocks that allow object literal parameters, but it may come up in the future.
PR Close#51143
⚠️Disclaimer⚠️ this PR implements syntax that is still in an open RFC. It will be adjusted once the RFC is closed.
These changes implement the `BlockGroup` and `Block` AST nodes that will then be used to generate instructions based on the new syntax. A `BlockGroup` is a container for `Block` instances. The first block of a block is always implicit and required while any subsequent blocks are optional.
PR Close#50953
⚠️Disclaimer⚠️ this PR implements syntax that is still in an open RFC. It will be adjusted once the RFC is closed.
These changes extend the lexer to recognize the concepts of a block group (`{#foo paramA; paramB}{/foo}`) and a block (`{:foo paramA; paramB;}`) which will be useful later on for the control flow and defer proposals. Block groups can be used anywhere and require a closing tag while block can only be used inside of a block.
The idea is that in the next PRs the markup AST will be expanded to have some more specialized node like `ConditionalBlock` or `DeferBlock` which will then be turned into instructions.
PR Close#50895
Allows for self-closing tags to be used for non-native tag names, e.g. `<foo [input]="bar"></foo>` can now be written as `<foo [input]="bar"/>`. Native tag names still have to have closing tags.
Fixes#39525.
PR Close#48535
.substr() is deprecated so we replace it with functions which work similarily but aren't deprecated
Signed-off-by: Tobias Speicher <rootcommander@gmail.com>
PR Close#45397
After updating to a more recent version of rollup, rollup started to
complain because the `TreeParseResult` class is being re-exported
twice in the `index.ts -> public-api.ts -> compiler.ts` entry-point.
Rollup threw errors like:
```
Error: "ParseTreeResult" cannot be exported from
<..>/ml_parser/parser.mjs as it is a re-export that references itself.
```
It seems like Rollup ideally would not throw here, similar to TypeScript
which detects that these exports are the same and just dedupes them, but
it's low-effort fixing this for now and actually is a good opportunity
to make the public API a little more easy understand (when looking at
the `compiler.ts` file).
PR Close#43431
Adds support for TypeScript 4.4. High-level overview of the changes made in this PR:
* Bumps the various packages to `typescript@4.4.2` and `tslib@2.3.0`.
* The `useUnknownInCatchVariables` compiler option has been disabled so that we don't have to cast error objects explicitly everywhere.
* TS now passes in a third argument to the `__spreadArray` call inside child class constructors. I had to update a couple of places in the runtime and ngcc to be able to pick up the calls correctly.
* TS now generates code like `(0, foo)(arg1, arg2)` for imported function calls. I had to update a few of our tests to account for it. See https://github.com/microsoft/TypeScript/pull/44624.
* Our `ngtsc` test setup calls the private `matchFiles` function from TS. I had to update our usage, because a new parameter was added.
* There was one place where we were setting the readonly `hasTrailingComma` property. I updated the usage to pass in the value when constructing the object instead.
* Some browser types were updated which meant that I had to resolve some trivial type errors.
* The downlevel decorators tranform was running into an issue where the Closure synthetic comments were being emitted twice. I've worked around it by recreating the class declaration node instead of cloning it.
PR Close#43281
These token interfaces will make it easier to reason about tokens in the
parser and in specs.
Previously, it was never clear what items could appear in the `parts`
array of a token given a particular `TokenType`. Now, each token interface
declares a labelled tuple for the parts, which helps to document the token
better.
PR Close#43132
When it was tokenized, text content is split into parts that can include
interpolations and encoded entities tokens.
To make this information available to downstream processing, this commit
adds these tokens to the `Text` AST nodes, with suitable processing.
PR Close#43132
The lexer now splits encoded entity tokens out from text and attribute value tokens.
Previously encoded entities would be decoded and the decoded value would be
included as part of the text token of the surrounding text. Now the entities
have their own tokens. There are two scenarios: text and attribute values.
Previously the contents of `<div>Hello & goodbye</div>` would be a single
TEXT token. Now it will be three tokens:
```
TEXT: "Hello "
ENCODED_ENTITY: "&", "&"
TEXT: " goodbye"
```
Previously the attribute value in `<div title="Hello & goodbye">` would be
a single text token. Now it will be three tokens:
```
ATTR_VALUE_TEXT: "Hello "
ENCODED_ENTITY: "&", "&"
ATTR_VALUE_TEXT: " goodbye"
```
- ENCODED_ENTITY tokens have two parts: "decoded" and "encoded".
- ENCODED_ENTITY tokens are always preceded and followed by either TEXT tokens
or ATTR_VALUE_TEXT tokens, depending upon the context, even if they represent
an empty string.
The HTML parser has been modified to recombine these tokens to allow this
refactoring to have limited effect in this commit. Further refactorings
to use these new tokens will follow in subsequent commits.
PR Close#43132
The lexer now splits interpolation tokens out from text tokens.
Previously the contents of `<div>Hello, {{ name}}<div>` would be a single
text token. Now it will be three tokens:
```
TEXT: "Hello, "
INTERPOLATION: "{{", " name", "}}"
TEXT: ""
```
- INTERPOLATION tokens have three parts, "start marker", "expression"
and "end marker".
- INTERPOLATION tokens are always preceded and followed by TEXT tokens,
even if they represent an empty string.
The HTML parser has been modified to recombine these tokens to allow this
refactoring to have limited effect in this commit. Further refactorings
to use these new tokens will follow in subsequent commits.
PR Close#43132
These token interfaces will make it easier to reason about tokens in the
parser and in specs.
Previously, it was never clear what items could appear in the `parts`
array of a token given a particular `TokenType`. Now, each token interface
declares a labelled tuple for the parts, which helps to document the token
better.
PR Close#42062
Previously, the way templates were tokenized meant that we lost information
about the location of interpolations if the template contained encoded HTML
entities. This meant that the mapping back to the source interpolated strings
could be offset incorrectly.
Also, the source-span assigned to an i18n message did not include leading
whitespace. This confused the output source-mappings so that the first text
nodes of the message stopped at the first non-whitespace character.
This commit makes use of the previous refactorings, where more fine grain
information was provided in text tokens, to enable the parser to identify
the location of the interpolations in the original source more accurately.
Fixes#41034
PR Close#42062
When it was tokenized, text content is split into parts that can include
interpolations and encoded entities tokens.
To make this information available to downstream processing, this commit
adds these tokens to the `Text` AST nodes, with suitable processing.
PR Close#42062
The lexer now splits encoded entity tokens out from text and attribute value tokens.
Previously encoded entities would be decoded and the decoded value would be
included as part of the text token of the surrounding text. Now the entities
have their own tokens. There are two scenarios: text and attribute values.
Previously the contents of `<div>Hello & goodbye</div>` would be a single
TEXT token. Now it will be three tokens:
```
TEXT: "Hello "
ENCODED_ENTITY: "&", "&"
TEXT: " goodbye"
```
Previously the attribute value in `<div title="Hello & goodbye">` would be
a single text token. Now it will be three tokens:
```
ATTR_VALUE_TEXT: "Hello "
ENCODED_ENTITY: "&", "&"
ATTR_VALUE_TEXT: " goodbye"
```
- ENCODED_ENTITY tokens have two parts: "decoded" and "encoded".
- ENCODED_ENTITY tokens are always preceded and followed by either TEXT tokens
or ATTR_VALUE_TEXT tokens, depending upon the context, even if they represent
an empty string.
The HTML parser has been modified to recombine these tokens to allow this
refactoring to have limited effect in this commit. Further refactorings
to use these new tokens will follow in subsequent commits.
PR Close#42062
The lexer now splits interpolation tokens out from attribute value tokens.
Previously the attribute value of `<div attr="Hello, {{ name}}">` would be a single
token. Now it will be three tokens:
```
ATTR_VALUE_TEXT: "Hello, "
ATTR_VALUE_INTERPOLATION: "{{", " name", "}}"
ATTR_VALUE_TEXT: ""
```
- ATTR_VALUE_INTERPOLATION tokens have three parts, "start marker",
"expression" and "end marker".
- ATTR_VALUE_INTERPOLATION tokens are always preceded and followed
by TEXT tokens, even if they represent an empty string.
The HTML parser has been modified to recombine these tokens to allow this
refactoring to have limited effect in this commit. Further refactorings
to use these new tokens will follow in subsequent commits.
PR Close#42062
The lexer now splits interpolation tokens out from text tokens.
Previously the contents of `<div>Hello, {{ name}}<div>` would be a single
text token. Now it will be three tokens:
```
TEXT: "Hello, "
INTERPOLATION: "{{", " name", "}}"
TEXT: ""
```
- INTERPOLATION tokens have three parts, "start marker", "expression"
and "end marker".
- INTERPOLATION tokens are always preceded and followed by TEXT tokens,
even if they represent an empty string.
The HTML parser has been modified to recombine these tokens to allow this
refactoring to have limited effect in this commit. Further refactorings
to use these new tokens will follow in subsequent commits.
PR Close#42062
Angular inserts text either through text nodes (`document.createTextNode`) or using `textContent`, but the drawback of doing so is that HTML entities won't be decoded. In order to work around it, the compiler has some logic that maps the entities to their unicode representation which can safely be inserted. The problem is that our current mapping is arbitrarily limited which means that some entities will be mapped while others will throw an error, even though they're valid.
These changes expand the list to cover all entities that are supported by the HTML spec.
Fixes#41186.
PR Close#42818
In combination with the TS `noImplicitOverride` compatibility changes,
we also want to follow the best-practice of adding `override` to
members which are implemented as part of abstract classes. This
commit fixes all instances which will be flagged as part of the
custom `no-implicit-override-abstract` TSLint rule.
PR Close#42512
Previously the lexer would break out of consuming a text token if it contains
a `<` character. Then if the next characters did not indicate an HTML syntax
item, such as a tag or comment, then it would start a new text token. These
consecutive text tokens are then merged into each other in a post tokenization
step.
In the commit before this, interpolation no longer leaks across text tokens.
The approach given above to handling `<` characters that appear in text is
no longer adequate. This change ensures that the lexer only breaks out of
a text token if the next characters indicate a valid HTML tag, comment,
CDATA etc.
PR Close#42605