When resolving references, the Ivy compiler has a few strategies it could use.
For relative path, one of strategies is [`RelativePathStrategy`](
https://github.com/angular/angular/blob/master/packages/compiler-cli/src/
ngtsc/imports/README.md#relativepathstrategy). This strategy
relies on `compilerOptions.rootDir` and `compilerOptions.rootDirs` to perform
the resolution, but language service only passes `rootDirs` to the compiler,
and not `rootDir`.
In reality, `rootDir` is very different from `rootDirs` even though they
sound the same.
According to the official [TS documentation][1],
> `rootDir` specifies the root directory of input files. Only use to control
> the output directory structure with --outDir.
> `rootDirs` is a list of root folders whose combined content represent the
> structure of the project at runtime. See [Module Resolution documentation](
> https://www.typescriptlang.org/docs/handbook/
> module-resolution.html#virtual-directories-with-rootdirs)
> for more details.
For now, we keep the behavior between compiler and language service consistent,
but we will revisit the notion of `rootDir` and how it is used later.
Fixangular/vscode-ng-language-service#1039
[1]: https://www.typescriptlang.org/docs/handbook/compiler-options.html
PR Close#40243
CSS supports escaping in selectors, e.g. writing `.foo:bar` will match an element with the
`foo` class and `bar` pseudo-class, but `.foo\:bar` will match the `foo:bar` class. Our
shimmed shadow DOM encapsulation always assumes that `:` means a pseudo selector
which breaks a selector like `.foo\:bar`.
These changes add some extra logic so that escaped characters in selectors are preserved.
Fixes#31844.
PR Close#40264
In some browsers, notably a mobile version of webkit on iPad, the
result of calling `DOMParser.parseFromString()` returns a document
whose `body` property is null until the next tick of the browser.
Since this is of no use to us for sanitization, we now fall back to the
"inert document" strategy for this case.
Fixes#39834
PR Close#40107
The `yarn symbol-extractor:check` and `yarn symbol-extractor:update` commands don't seem to work currently -
the script is unable to calculate the list of relevant targets. Running the `bazel query ...` command used in the
script fails due to the missing quotes around the query argument. This commit fixes the problem by updating the
script to wrap query argument into single quotes.
PR Close#40163
The `ɵɵngDeclareComponent` calls are designed to be translated to fully
AOT compiled code during a build transform, but in cases this is not
done it is still possible to compile the declaration object in the
browser using the JIT compiler. This commit adds a runtime
implementation of `ɵɵngDeclareComponent` which invokes the JIT compiler
using the declaration object, such that a compiled component definition
is made available to the Ivy runtime.
PR Close#40127
The `render3` test targets are currently also executed for ViewEngine
builds, even though the `render3` infrastructure only concerns Ivy
infrastructure. This commit tags the test targets as ivy-only to disable
those tests for View Engine.
PR Close#40127
The link to the "speeding-up-ngcc-compilation" URL does not exist,
it was removed shortly after it was added, but the link in the ngcc
error message was not updated.
Fixes#39837
PR Close#40285
https://developer.mozilla.org/en-US/docs/Web/CSS/font-family
"You should always include at least one generic family name in a font-family list,
since there's no guarantee that any given font is available. This lets the browser
select an acceptable fallback font when necessary."
PR Close#40254
Currently we check whether a property binding contains an interpolation using a regex so
that we can throw an error. The problem is that the regex doesn't account for quotes
which means that something like `[prop]="'{{ foo }}'"` will be considered an error, even
though it's not actually an interpolation.
These changes build on top of the logic from #39826 to account for interpolation
characters inside quotes.
Fixes#39601.
PR Close#40267
The trustConstantHtml and trustConstantResourceUrl functions are only
meant to be passed constant strings extracted from Angular application
templates, as passing other strings or variables could introduce XSS
vulnerabilities.
To better protect these APIs, turn them into template tags. This makes
it possible to assert that the associated template literals do not
contain any interpolation, and thus must be constant.
Also add tests for the change to prevent regression.
PR Close#40082
When talking about parameter inheritance, one might think that matrix
parameters can be inherited from the "parent" segment, or the segment
which appears immediately to the left. In reality, when we talk about
a "parent" in the `Router`, we mean the parent `Route` config. This
config may contain more than one segment and matrix parameters must
appear at the end or they do not "belong" to any config.
PR Close#40304
There are two parts to this commit:
1. Revert the changes from #38379. This change had an incomplete view of
how things worked and also diverged the implementations of
`applyRedirects` and `recognize` even more.
2. Apply the fixes from the `recognize` algorithm to ensure that named
outlets with empty path parents can be matched. This change also passes
all the tests that were added in #38379 with the added benefit of being
a more complete fix that stays in-line with the `recognize` algorithm.
This was made possible by using the same approach for `split` by
always creating segments for empty path matches (previously, this was
only done in `applyRedirects` if there was a `redirectTo` value). At the
end of the expansions, we need to squash all empty segments so that
serializing the final `UrlTree` returns the same result as before.
Fixes#39952Fixes#10726Closes#30410
PR Close#40029
The `applyRedirects` and `recognize` algorithms have the same overall goal:
match a `UrlTree` with the application's `Routes` config. There are a
few key functions in these algorithms which can be shared rather than
duplicated between the two. This also makes it easier to see how the two
are similar and where they diverge.
PR Close#40029
This commit updates the `recognize` algorithm to work with named outlets
which have empty path parents. For example, given the following config
```
const routes = [
{
path: '',
children: [
{path: 'a', outlet: 'aux', component: AuxComponent}
]}
];
```
The url `/(aux:a)` should match this config. In order to do so, we need
to allow the children of `UrlSegmentGroup`s to match a `Route` config
for a different outlet (in this example, the `primary`) when it's an
empty path. This should also *only* happen if we were unable to find a
match for the outlet in the level above. That is, the matching strategy
is to find the first `Route` in the list which _matches the given
outlet_. If we are unable to do that, then we allow empty paths from
other outlets to match and try to find some child there whose outlet
matches our segment.
PR Close#40029
To make the tests suite easier to follow, `Recognize#apply` can be made
into a synchronous function rather than one that return an `Observable`.
Also, as a chore, remove as many `any` types as possible.
PR Close#40029
This commit updates the `recognize` algorithm to return `null` when a
segment does not match a given config rather than throwing an error.
This makes the code much easier to follow because the "no match" result
has to be explicitly handled rather than catching the error in very
specific places.
PR Close#40029
When stepping through the `recognize` algorithm, it is much easier to
follow when using a simple `for...of` rather than the helper
`mapChildrenIntoArray` with the passed closure. The only special thing that
`mapChildrenIntoArray` does is ensure the primary route appears first.
This change will have no affect on the result because `processChildren` later calls
`sortActivatedRouteSnapshots`, which does the same thing.
PR Close#40029
Prior to this commit, removing `FormControlDirective` and `FormGroupName` directive instances didn't clear
the callbacks previously registered on FromControl/FormGroup class instances. As a result, these callbacks
were executed even after `FormControlDirective` and `FormGroupName` directive instances were destroyed. That was
also causing memory leaks since these callbacks also retained references to DOM elements.
This commit updates the cleanup logic to take care of properly detaching FormControl/FormGroup/FormArray instances
from the view by removing view-specific callback at destroy time.
Closes#20007, #37431, #39590.
PR Close#39235
DI providers can be defined via `useFactory` function, which may have arguments configured via `deps` array.
The `deps` array may contain DI flags represented by DI decorators (such as `@Self`, `@SkipSelf`, etc). Prior to this
commit, having the `@Host` decorator in `deps` array resulted in runtime error in Ivy. The problem was that the `@Host`
decorator was not taken into account while `useFactory` argument list was constructed, the `@Host` decorator was
treated as a token that should be looked up.
This commit updates the logic which prepares `useFactory` arguments to recognize the `@Host` decorator.
PR Close#40122
The CLI integration can provide code files in a non-deterministic
order, which led to the extracted translation files having
messages in a non-consistent order between extractions.
This commit fixes this by ensuring that serialized messages
are ordered by their location.
Fixes#39262
PR Close#40192
`Route` configs with `redirectTo` as well as `canActivate` are not valid
because the `canActivate` guards will never execute. Redirects are
applied before activation. There is no error currently for these
configs, but another commit will change this so that an error does
appear in dev mode. This migration fixes the configs by removing the
`canActivate` property.
PR Close#40067
Redirects in the router are processed before activations. This means that a canActivate will
never execute if a route has a redirect. Rather than silently ignoring
the invalid config, developers should be notified so they know why it
doesn't work.
Closes#18605
The feature request for a function/class redirect is covered in #13373.
PR Close#40067
Given the template
`<div (click)="doSomething($event)"></div>`
If you request references for the `$event`, the results include both `$event` and `(click)="doSomething($event)"`.
This happens because in the TCB, `$event` is passed to the `subscribe`/`addEventListener`
function as an argument. So when we ask typescript to give us the references, we
get the result from the usage in the subscribe body as well as the one passed in as an argument.
This commit adds an identifier to the `$event` parameter in the TCB so
that the result returned from `getReferencesAtPosition` can be
identified and filtered out.
fixes#40157
PR Close#40158
According to the [spec](https://html.spec.whatwg.org/#scroll-to-fragid),
we should attempt to set the browser focus after scrolling to a
fragment. Note that this change does not exactly follow the robust steps
outlined in the spec by finding a fallback target if the original is not
focusable. Instead, we simply attempt to focus the element by calling
`focus` on it, which will do nothing if the element is not focusable.
fixes#30067
PR Close#40241
The `ɵɵngDeclareDirective` calls are designed to be translated to fully
AOT compiled code during a build transform, but in cases this is not
done it is still possible to compile the declaration object in the
browser using the JIT compiler. This commit adds a runtime
implementation of `ɵɵngDeclareDirective` which invokes the JIT compiler
using the declaration object, such that a compiled directive definition
is made available to the Ivy runtime.
PR Close#40101
With this change we change the `Boolean and enumerated options` to use kebab-case flags
as the camelCase variant are deprecated. We also remove the `enumerated option description`
as this is no longer correct and needed following the CLI MAN page update in #40038
PR Close#40224
The linker is implemented using a Babel transform such that Babel needs
to parse and walk a source file to find the declarations that need to be
compiled. If it can be determined that a source file is known not to
contain any declarations the parsing and walking can be skipped as a
performance improvement. This commit adds an exposed function for tools
that integrate the linker to use to allow short-circuiting of the linker
transform.
PR Close#40137
Internally we store lifecycle hooks in the format `[index, hook, index, hook]` and when
iterating over them, we check one place ahead to figure out whether we've hit found
a hook or an index. The problem is that the loop is set up to iterate up to `hooks.length`
which means that we may go out of bounds on the last iteration, depending on where
we started. This appears to happen under a specific set of circumstances where a
directive calls `detectChanges` from an input setter while it has `ngOnChanges` and
`ngAfterViewInit` hooks.
These changes resolve the issue by only iterating up to `length - 1` which guarantees that
we can always look one place ahead.
This appears to have regressed some time in version 10.
Fixes#38611.
PR Close#40206
Previously `\r\n` was being treated as a single character in source-map
line start positions, which caused segment positions to become offset.
Now the `\r` is ignored when splitting, leaving it at the end of the
previous line, which solves the offsetting problem, and does not affect
source-mappings.
Fixes#40169Fixes#39654
PR Close#40187
This commit fixes an issue in the ivy native language service
that caused the logic that finds a target node given a template
position to throw away the results. This happened because the
source span of a variable node in the shorthand structural
directive syntax (i.e. `*ngIf=`) included the entire binding.
The result was that we would add the variable node to the path and then
later detect that the cursor was outside the key and value spans and
throw away the whole result. In general, we do this because we do not
want to show information when the cursor is between a key/value
(`inputA=¦"123"`). However, when using the shorthand syntax, we run into
the situation where we can match an `AttributeBinding` as well as the
vaariable in `*ngIf="som¦eValue as myLocalVar"`. This commit updates the
visitor to retain enough information in the visit path to throw away
invalid targets but keep valid ones if there were multiple results on a
`t.Element` or `t.Template`.
PR Close#40239
The linker entry-points were not previously exposed in the NPM Bazel
target so they were omitted from the bundle. This commit adds the
necessary entry-points to the compiler-cli's npm_package target.
PR Close#40180
The types of directives and pipes that are used in a component's
template may be emitted into the partial declaration wrapped inside a
closure, which is needed when the type is declared later in the module.
This poses a problem for JIT compilation of partial declarations, as
this closure is indistinguishable from a class reference itself. To mark
the forward reference function as such, this commit changes the partial
declaration codegen to emit a `forwardRef` invocation wrapped around
the closure, which ensures that the closure is properly tagged as a
forward reference. This allows the forward reference to be treated as
such during JIT compilation.
PR Close#40117
PR #39876 introduced an error where the `onDestroy` of `ComponentRef`
would only get called if `ngDevMode` was set to true. This was because
in dev mode we would freeze `TCleanup` to verify that no more
static cleanup would get added to `TCleanup` array. This ensured
that `TCleanup` was always present in dev mode. In production the
`TCleanup` would get created only when needed. The resulting cleanup
code was incorrectly indented and would only run if `TCleanup` was
present causing this issue.
Fix#40105
PR Close#40120
Previously, the `SpyDirective` in the `lifecycle-hooks` docs example
would use a different ID when logging `onInit` and when logging
`onDestroy` for the same instance, making it impossible to associate the
two calls. This was not helpful and came in constrast with how the
directive was described in the corresponding guide and shown in the
accompanying `spy-directive.gif` image.
This commit fixes the logic of the `SpyDirective` class to use the same
ID for all log operations of an instance.
Partially addresses #40193.
PR Close#40208
Previously, the docregion code referenced a `nextId` variable that was
not shown in the code, which was confusing for the reader.
This commit makes the declaration of the `nextId` variable part of the
docregion, so it is clear to the reader where it comes from and how it
is initialized.
This commit also removes the `logIt()` helper method, which didn't seem
to add value and calls `logger.log()` directly instead.
PR Close#40208