Commit Graph

1800 Commits

Author SHA1 Message Date
cexbrayat e12d9dec64 fix(core): remove duplicated EMPTY_ARRAY constant (#40991)
The codebase currently contains several `EMPTY_ARRAY` constants,
and they can end up in the bundle of an application.
A recent commit 6fbe219 tipped us off
as it introduced several `noop` occurrences in the golden symbol files.
After investigating with @petebacondarwin,
we decided to remove the duplicated symbols.

This probably shaves only a few bytes,
but this commit removes the duplicated functions,
by always using the one in `core/src/utils/empty`.

PR Close #40991
2021-03-01 09:00:43 -08:00
Andrew Scott 6c05c80f19 feat(router): Add more find-tuned control in `routerLinkActiveOptions` (#40303)
This commit adds more configurability to the `Router#isActive` method
and `RouterLinkActive#routerLinkActiveOptions`.
It allows tuning individual match options for query params and the url
tree, which were either both partial or both exact matches in the past.
Additionally, it also allows matching against the fragment and matrix
parameters.

fixes #13205

BREAKING CHANGE:
The type of the `RouterLinkActive.routerLinkActiveOptions` input was
expanded to allow more fine-tuned control. Code that previously read
this property may need to be updated to account for the new type.

PR Close #40303
2021-02-24 15:32:05 -08:00
Kristiyan Kostadinov 29d8a0ab09 feat(animations): add support for disabling animations through BrowserAnimationsModule.withConfig (#40731)
Currently the only way to disable animations is by providing the `NoopAnimationsModule`
which doesn't allow for it to be disabled based on runtime information. These changes
add support for disabling animations based on runtime information by using
`BrowserAnimationsModule.withConfig({disableAnimations: true})`.

PR Close #40731
2021-02-24 15:08:27 -08:00
Pete Bacon Darwin 3c24136b98 fix(compiler): ensure JIT compilation of ɵɵngDeclarePipe() works (#40929)
Previously the compiler was not evaluating the JIT compilation
of `ɵɵngDeclarePipe()` but there was no test to check it.

PR Close #40929
2021-02-24 15:07:08 -08:00
Kristiyan Kostadinov a3e17190e7 fix(core): allow EmbeddedViewRef context to be updated (#40360)
Currently `EmbeddedViewRef.context` is read-only which means that the only way to update
it is to mutate the object which can lead to some undesirable outcomes if the template
and the context are provided by an external consumer (see #24515).

These changes make the property writeable since there doesn't appear to be a specific
reason why it was readonly to begin with.

PR Close #40360
2021-02-23 08:14:01 -08:00
JiaLiPassion dc9fd1aaef fix(core): NgZone coaleascing options should trigger onStable correctly (#40540)
fix https://github.com/angular/components/issues/21674

When setting `ngZoneRunCoalescing` to true, `onStable` is not emitted correctly.
the reason is before this commit, the code looks like this:

```
// application code call `ngZone.run()`
ngzone.run(() => {}); // step 1

// inside NgZone, in the OnInvoke hook, NgZone try to delay the checkStable()

function delayChangeDetectionForEvents(zone: NgZonePrivate) {
  if (zone.lastRequestAnimationFrameId !== -1) { // step 9
    return;
  }
  zone.lastRequestAnimationFrameId = zone.nativeRequestAnimationFrame.call(global, () => { // step 2
    if (!zone.fakeTopEventTask) {
      zone.fakeTopEventTask = Zone.root.scheduleEventTask('fakeTopEventTask', () => {
        zone.lastRequestAnimationFrameId = -1; // step 3
        updateMicroTaskStatus(zone); // step 4
        checkStable(zone); // step 6
      }, undefined, () => {}, () => {});
    }
    zone.fakeTopEventTask.invoke();
  });
  updatemicroTaskStatus(zone);
}

function updateMicroTaskStatus(zone: NgZonePrivate, ignoreCheckRAFId = false) {
  if (zone._hasPendingMicrotasks ||
      ((zone.shouldCoalesceEventChangeDetection || zone.shouldCoalesceRunChangeDetection) &&
       zone.lastRequestAnimationFrameId !== -1)) { // step 5
    zone.hasPendingMicrotasks = true;
  } else {
    zone.hasPendingMicrotasks = false;
  }
}

function checkStable(zone: NgZonePrivate) {
  if (zone._nesting == 0 && !zone.hasPendingMicrotasks && !zone.isStable) { // step 7
    try {
      zone._nesting++;
      zone.onMicrotaskEmpty.emit(null);
    ...
}

// application ref subscribe onMicroTaskEmpty
ngzone.onMicroTaskEmpty.subscribe(() => {
  ngzone.run(() => { // step 8
    tick();
  });
});

```

and the process is:
1. step 1: application call ngZone.run()
2. step 2: NgZone delay the checkStable() call in a requestAnimationFrame, and also set
zone.lastRequestAnimationFrameId
3. step 3: Inside the requestAnimationFrame callback, reset zone.lastRequestAnimationFrameId first
4. step 4: update microTask status
5, step 5: if zone.lastRequestAnimationFrameId is -1, that means no microTask pending.
6. step 6: checkStable and trigger onMicrotaskEmpty emitter.
7. step 7: ApplicationRef subscribed onMicrotaskEmpty, so it will call another `ngZone.run()` to process
tick()
8. step 8: And this new `ngZone.run()` will try to check `zone.lastRequestAnimationFrameId` in `step 9`
when trying to delay the checkStable(), and since the zone.lastRequestAnimationFrameId is already reset
to -1 in step 3, so this ngZone.run() will run into step 2 again.
9. and become a infinite loop..., so onStable is never emit

in this commit, there is a new flag `zone.isCheckStableRunning` added to
prevent re-entry when `shouldCoaleascing` flag is enabled.

PR Close #40540
2021-02-22 10:01:31 -08:00
Andrew Kushnir 995adb2297 test(core): refactor ApplicationInitStatus tests to avoid TestBed side-effects (#33222)
Currently TestBed (both ViewEngine and Ivy) invoke `ApplicationInitStatus.runInitializers` as a part of the
bootstrap process to mimic real bootstrap steps. This is problematic for the `ApplicationInitStatus` class
tests since the `runInitializers` call performed by TestBed interfere with actual tests.

This commit updates ApplicationInitStatus tests to interact with the class directly instead of relying on TestBed
APIs to retrieve the class though DI.

PR Close #33222
2021-02-22 08:41:49 -08:00
vthinkxie ca17ac523c feat(core): support APP_INITIALIZER work with observable (#33222)
This commit adds support for Observables that now can be used as a part of APP_INITIALIZER. Previously, only
Primises were supported.

Closes #15088.

PR Close #33222
2021-02-22 08:41:49 -08:00
Andrew Kushnir d1d1dadb41 refactor(core): use RuntimeError to throw provider not found error (#40901)
This PR performs a small refactoring to use `RuntimeError` class and corresponding error code (by calling
`throwProviderNotFoundError` which formats the message) to make it more consistent with other places where
similar errors are thrown.

PR Close #40901
2021-02-19 14:38:18 -08:00
Pete Bacon Darwin 9cb43fb507 refactor(compiler-cli): implement `ɵɵngDeclarePipe()` (#40803)
This commit implements creating of `ɵɵngDeclarePipe()` calls in partial
compilation, and processing of those calls in the linker and JIT compiler.

See #40677

PR Close #40803
2021-02-12 09:00:16 -08:00
stsogoo 0654c05c41 fix(core): properly move embedded views of dynamic component's projectable nodes (#37167)
This commit fixes the issue of the ASSERTION ERROR issue when
a projected node(RNode) inside an array is checked against the types
of TNodeType.Element, TNodeType.Container, TNodeType.ElementContainer,
TNodeType.IcuContainer, TNodeType.Projection. As it's inside an array,
it doesn't fall into any of those types, as a result, it throws
the ASSERTION ERROR.

PR Close #37120

PR Close #37167
2021-02-10 11:03:06 -08:00
Matias Niemelä 4ce44eac33 fix(animations): properly track listeners for a removed element (#40712)
Prior to this patch, if an element was removed multiple times (due
to the nature of parent/child elements), the leave listeners may
have been fired for an element that was already removed. This patch
adds a guard within the animations code to prevent this.

PR Close #40712
2021-02-09 10:50:19 -08:00
Misko Hevery d754cc1ea5 Revert "fix(core): NgZone coaleascing options should trigger onStable correctly (#40540)"
This reverts commit 22f9e454a4.
2021-01-29 15:09:37 -08:00
JiaLiPassion 22f9e454a4 fix(core): NgZone coaleascing options should trigger onStable correctly (#40540)
fix https://github.com/angular/components/issues/21674

When setting `ngZoneRunCoalescing` to true, `onStable` is not emitted correctly.
The reason is before this commit, the code looks like this

```
// Application code call `ngZone.run()`
ngZone.run(() => {}); // step 1

// Inside NgZone, in the OnInvoke hook, NgZone try to delay the checkStable()

function delayChangeDetectionForEvents(zone: NgZonePrivate) {
  if (zone.lastRequestAnimationFrameId !== -1) { // step 9
    return;
  }
  zone.lastRequestAnimationFrameId = zone.nativeRequestAnimationFrame.call(global, () => { // step 2
    if (!zone.fakeTopEventTask) {
      zone.fakeTopEventTask = Zone.root.scheduleEventTask('fakeTopEventTask', () => {
        zone.lastRequestAnimationFrameId = -1; // step 3
        updateMicroTaskStatus(zone); // step 4
        checkStable(zone); // step 6
      }, undefined, () => {}, () => {});
    }
    zone.fakeTopEventTask.invoke();
  });
  updateMicroTaskStatus(zone);
}

function updateMicroTaskStatus(zone: NgZonePrivate, ignoreCheckRAFId = false) {
  if (zone._hasPendingMicrotasks ||
      ((zone.shouldCoalesceEventChangeDetection || zone.shouldCoalesceRunChangeDetection) &&
       zone.lastRequestAnimationFrameId !== -1)) { // step 5
    zone.hasPendingMicrotasks = true;
  } else {
    zone.hasPendingMicrotasks = false;
  }
}

function checkStable(zone: NgZonePrivate) {
  if (zone._nesting == 0 && !zone.hasPendingMicrotasks && !zone.isStable) { // step 7
    try {
      zone._nesting++;
      zone.onMicrotaskEmpty.emit(null);
    ...
}

// application ref subscribe onMicroTaskEmpty
ngZone.onMicroTaskEmpty.subscribe(() => {
  ngZone.run(() => { // step 8
    tick();
  });
});

```

And the process is:
1. step 1: application call ngZone.run()
2. step 2: NgZone delay the checkStable() call in a requestAnimationFrame, and also set
zone.lastRequestAnimationFrameId
3. step 3: Inside the requestAnimationFrame callback, reset zone.lastRequestAnimationFrameId first
4. step 4: update microTask status
5, step 5: if zone.lastRequestAnimationFrameId is -1, that means no microTask pending.
6. step 6: checkStable and trigger onMicrotaskEmpty emitter.
7. step 7: ApplicationRef subscribed onMicrotaskEmpty, so it will call another `ngZone.run()` to process
tick()
8. step 8: And this new `ngZone.run()` will try to check `zone.lastRequestAnimationFrameId` in `step 9`
when trying to delay the checkStable(), and since the zone.lastRequestAnimationFrameId is already reset
to -1 in step 3, so this ngZone.run() will run into step 2 again.
9. And become a infinite loop..., so onStable is never emit

In this commit, the `zone.lastRequestAnimationFrameId` reset is moved after `checkStable()` call.

PR Close #40540
2021-01-28 15:53:38 -08:00
Misko Hevery 88f8ddd3d3 Revert "fix(core): remove duplicated EMPTY_ARRAY constant (#40587)"
This reverts commit 34aa9c3531.
2021-01-28 14:35:03 -08:00
cexbrayat 34aa9c3531 fix(core): remove duplicated EMPTY_ARRAY constant (#40587)
The codebase currently contains several `EMPTY_ARRAY` constants,
and they can end up in the bundle of an application.
A recent commit 6fbe219 tipped us off
as it introduced several `noop` occurrences in the golden symbol files.
After investigating with @petebacondarwin,
we decided to remove the duplicated symbols.

This probably shaves only a few bytes,
but this commit removes the duplicated functions,
by always using the one in `core/src/utils/empty`.

PR Close #40587
2021-01-28 08:55:53 -08:00
Sirui Chen a8269264bf fix(core): make DefaultIterableDiffer keep the order of duplicates (#23941)
Previously, in `_mismatch()`, the `DefaultIterableDiffer` first checks
`_linkedRecords` for `itemTrackBy`, then checks `_unlinkedRecords`.
This cause the `DefaultIterableDiffer` to move "later" items that match the
`itemTrackBy` from the old collection, rather than using the "earlier" one.

Now we check `_unlinkedRecords` first, so that the `DefaultIterableDiffer`
can give a more stable and reasonable result after diffing. For example,
rather than (`a1` and `a2` have same trackById)

```
a1 b c a2 => b a2 c a1
```

we get

```
a1 b c a2 => b a1 c a2
```

where a1 and a2 retain their original order despite both
having the same track by value.

Fixes #23815

PR Close #23941
2021-01-26 15:44:42 -08:00
Misko Hevery 6bf99e0eda fix(core): fix possible XSS attack in development through SSR (#40525)
This is a follow up fix for
894286dd0c.

It turns out that comments can be closed in several ways:
- `<!-->`
- `<!-- -->`
- `<!-- --!>`

All of the above are valid ways to close comment per:
https://html.spec.whatwg.org/multipage/syntax.html#comments

The new fix surrounds `<` and `>` with zero width space so that it
renders in the same way, but it prevents the comment to be closed eagerly.

PR Close #40525
2021-01-26 09:32:27 -08:00
Jessica Janiuk c64a56fbcc Revert "fix(core): fix possible XSS attack in development through SSR (#40525)" (#40533)
This reverts commit bb3b315eee.

Reason for Revert: Issues with Google3 TAP Failures

PR Close #40533
2021-01-22 16:44:34 -08:00
Misko Hevery bb3b315eee fix(core): fix possible XSS attack in development through SSR (#40525)
This is a follow up fix for
894286dd0c.

It turns out that comments can be closed in several ways:
- `<!-->`
- `<!-- -->`
- `<!-- --!>`

All of the above are valid ways to close comment per:
https://html.spec.whatwg.org/multipage/syntax.html#comments

The new fix surrounds `<` and `>` with zero width space so that it
renders in the same way, but it prevents the comment to be closed eagerly.

PR Close #40525
2021-01-22 14:19:52 -08:00
Misko Hevery 1e4b51e9f7 fix(core): improve injector debug information in `ngDevMode` (#40476)
- `LViewDebug` now properly shows when `TNode` has `NO_NODE_INJECTOR`.
- Provide `injectorResolutionPath` property `DebugNode`

PR Close #40476
2021-01-22 10:21:25 -08:00
JoostK 69385f7df4 test(core): verify that token IDs that exceed the bloom filter size are handled correctly (#40489)
This commits adds additional expectations to verify that the bloom
filter is able to correctly handle token IDs that exceed the size of
the bloom filter (which is currently 256 bits).

PR Close #40489
2021-01-20 17:02:02 -08:00
twerske bfdca0b87f refactor(core): add links to top runtime errors (#40326)
add links to 5 runtime error messages
navigate user to AIO new /errors pages for debugging

PR Close #40326
2021-01-19 10:14:56 -08:00
Misko Hevery d516113803 refactor(core): Remove the need for explicit static query instruction (#40091)
Because the query now has `flags` which specify the mode, the static query
instruction can now be remove. It is simply normal query with `static` flag.

PR Close #40091
2021-01-14 13:55:02 -08:00
Misko Hevery e32b6256ce fix(core): `QueryList` should not fire changes if the underlying list did not change. (#40091)
Previous implementation would fire changes `QueryList.changes.subscribe`
whenever the `QueryList` was recomputed. This resulted in artificially
high number of change notifications, as it is possible that recomputing
`QueryList` results in the same list. When the `QueryList` gets recomputed
is an implementation detail and it should not be the thing which determines
how often change event should fire.

This change introduces a new `emitDistinctChangesOnly` option for
`ContentChildren` and `ViewChildren`.

```
export class QueryCompWithStrictChangeEmitParent {
  @ContentChildren('foo', {
    // This option will become the default in the future
    emitDistinctChangesOnly: true,
  })
  foos!: QueryList<any>;
}
```

PR Close #40091
2021-01-14 13:55:02 -08:00
Andrew Kushnir 6cff877f4f perf(core): make DI decorators tree-shakable when used for `useFactory` deps config (#40145)
This commit updates the logic that calculates `useFactory` function arguments to avoid relying on `instanceof`
checks (thus always retaining symbols) and relies on flags that DI decorators contain (as a monkey-patched property).

Another perf benefit is having less megamorphic reads while calculating args for the `useFactory` call: we used to
check whether a token has `ngMetadataName` property 4 times (in worst case), now we have just 1 megamorphic read in
all cases.

Closes #40143.

PR Close #40145
2021-01-13 14:08:45 -08:00
JoostK b48eabddb8 refactor(compiler-cli): include `template` source directly inside declaration object (#40383)
The `template` and `isInline` fields were previously stored in a nested
object, which was initially done to accommodate for additional template
information to support accurate source maps for external templates. In
the meantime the source mapping has been accomplished in a different
way, and I feel this flattened structure is simpler and smaller so is
preferable over the nested object. This change also makes the `isInline`
property optional with a default value of `false`.

PR Close #40383
2021-01-11 15:37:12 -08:00
Martin Sikora 9105005192 refactor(router): refactor and simplify router RxJS chains (#40290)
Refactor and simplifiy RxJS usage in the router package
in order to reduce its size and increase performance.

PR Close #40290
2021-01-11 15:30:55 -08:00
Kristiyan Kostadinov 4f73820ad6 fix(core): memory leak if view container host view is destroyed while view ref is not (#40219)
When we attach a `ViewRef` to a `ViewContainerRef`, we save a reference to the container
onto the `ViewRef` so that we can remove it when the ref is destroyed. The problem is
that if the container's `hostView` is destroyed first, the `ViewRef` has no way of knowing
that it should stop referencing the container.

These changes remove the leak by not saving a reference at all. Instead, when a `ViewRef`
is destroyed, we clean it up through the `LContainer` directly. We don't need to worry
about the case where the container is destroyed before the view, because containers
automatically clean up all of their views upon destruction.

Fixes #38648.

PR Close #40219
2021-01-08 09:45:12 -08:00
JoostK da6c739bb6 test(core): update test expectation to account for IE11 anonymous function name (#40342)
The "monitoring" workflow has been failing since #40127 was merged,
due to a Saucelabs test failure in Internet Explorer 11. The issue is
with the test's expectation which does not account for Ivy instruction
invocations to use "anonymous" instead of the instruction's function
name. This commit changes the test expectation to also accept
"anonymous", which was already the case for similar expectations.

PR Close #40342
2021-01-07 13:29:49 -08:00
Kristiyan Kostadinov 104546569e fix(compiler): incorrectly interpreting some HostBinding names (#40233)
Currently when analyzing the metadata of a directive, we bundle together the bindings from `host`
and the `HostBinding` and `HostListener` together. This can become a problem later on in the
compilation pipeline, because we try to evaluate the value of the binding, causing something like
`@HostBinding('class.foo') public true = 1;` to be treated the same as
`host: {'[class.foo]': 'true'}`.

While looking into the issue, I noticed another one that is closely related: we weren't treating
quoted property names correctly. E.g. `@HostBinding('class.foo') public "foo-bar" = 1;` was being
interpreted as `classProp('foo', ctx.foo - ctx.bar)` due to the same issue where property names
were being evaluated.

These changes resolve both of the issues by treating all `HostBinding` instance as if they're
reading the property from `this`. E.g. the `@HostBinding('class.foo') public true = 1;` from above
is now being treated as `host: {'[class.foo]': 'this.true'}` which further down the pipeline becomes
`classProp('foo', ctx.true)`. This doesn't have any payload size implications for existing code,
because we've always been prefixing implicit property reads with `ctx.`. If the property doesn't
have an identifier that can be read using dotted access, we convert it to a quoted one (e.g.
`classProp('foo', ctx['is-foo']))`.

Fixes #40220.
Fixes #40230.
Fixes #18698.

PR Close #40233
2021-01-07 13:15:46 -08:00
Pete Bacon Darwin 8ebac24b48 fix(core): ensure sanitizer works if DOMParser return null body (#40107)
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
2021-01-06 10:32:24 -08:00
JoostK d4327d51d1 feat(compiler-cli): JIT compilation of component declarations (#40127)
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
2021-01-06 08:28:03 -08:00
JoostK 826b77b632 test(core): tag `render3` test targets as ivy-only (#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
2021-01-06 08:28:03 -08:00
Kristiyan Kostadinov 6abc13330b fix(compiler): don't report parse error for interpolation inside string in property binding (#40267)
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
2021-01-05 13:57:23 -08:00
Bjarki 6a9d7e5969 refactor(core): express trusted constants with tagged template literals (#40082)
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
2021-01-05 13:56:57 -08:00
Andrew Scott e43f7e26fe fix(router): apply redirects should match named outlets with empty path parents (#40029)
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 #39952
Fixes #10726
Closes #30410

PR Close #40029
2021-01-05 12:43:47 -08:00
Andrew Kushnir a3849611b7 fix(forms): clean up connection between FormControl/FormGroup and corresponding directive instances (#39235)
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
2021-01-05 11:15:08 -08:00
Andrew Kushnir 3735633bb0 fix(core): take @Host into account while processing `useFactory` arguments (#40122)
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
2021-01-05 10:14:25 -08:00
JoostK 9186f1feea feat(compiler-cli): JIT compilation of directive declarations (#40101)
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
2020-12-23 09:52:19 -08:00
Kristiyan Kostadinov e4fbab9ec8 fix(core): error if detectChanges is called at the wrong time under specific circumstances (#40206)
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
2020-12-22 14:52:12 -08:00
Misko Hevery fc1cd07eb0 fix(core): Call `onDestroy` in production mode as well (#40120)
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
2020-12-22 08:02:27 -08:00
Alan Agius 475468cc8f refactor(core): remove custom globalThis (#40123)
This is provided by TypeScript since version 3.4

PR Close #40123
2020-12-17 11:43:28 -08:00
Misko Hevery 47d9b6d72d fix(core): fix possible XSS attack in development through SSR. (#40136)
Escape the content of the strings so that it can be safely inserted into a comment node.
The issue is that HTML does not specify any way to escape comment end text inside the comment.
`<!-- The way you close a comment is with "-->". -->`. Above the `"-->"` is meant to be text
not an end to the comment. This can be created programmatically through DOM APIs.

```
div.innerHTML = div.innerHTML
```
One would expect that the above code would be safe to do, but it turns out that because comment
text is not escaped, the comment may contain text which will prematurely close the comment
opening up the application for XSS attack. (In SSR we programmatically create comment nodes which
may contain such text and expect them to be safe.)
This function escapes the comment text by looking for the closing char sequence `-->` and replace
it with `-_-_>` where the `_` is a zero width space `\u200B`. The result is that if a comment
contains `-->` text it will render normally but it will not cause the HTML parser to close the
comment.

PR Close #40136
2020-12-16 09:38:08 -08:00
Andrew Kushnir caa4666335 fix(compiler): avoid duplicate i18n blocks for i18n attrs on elements with structural directives (#40077)
Currently when `ɵɵtemplate` and `ɵɵelement` instructions are generated by compiler, all static attributes are
duplicated for both instructions. As a part of this duplication, i18n translation blocks for static i18n attributes
are generated twice as well, causing duplicate entries in extracted translation files (when Ivy extraction mechanisms
are used). This commit fixes this issue by introducing a cache for i18n translation blocks (for static attributes
only).

Also this commit further aligns `ɵɵtemplate` and `ɵɵelement` instruction attributes, which should help implement
more effective attributes deduplication logic.

Closes #39942.

PR Close #40077
2020-12-15 13:40:09 -08:00
Kristiyan Kostadinov dc6d40e5bc fix(compiler): handle strings inside bindings that contain binding characters (#39826)
Currently the compiler treats something like `{{  '{{a}}' }}` as a nested
binding and throws an error, because it doesn't account for quotes
when it looks for binding characters. These changes add a bit of
logic to skip over text inside quotes when parsing.

Fixes #39601.

PR Close #39826
2020-12-10 11:11:21 -08:00
Misko Hevery 5fc45082ca fix(core): Support extending differs from root `NgModule` (#39981)
Differs tries to inject parent differ in order to support extending.
This does not work in the 'root' injector as the provider overrides the
default injector. The fix is to just assume standard set of providers
and extend those instead.

PR close #25015
Issue close #11309 `Can't extend IterableDiffers`
Issue close #18554 `IterableDiffers.extend is not AOT compatible`
  (This is fixed because we no longer have an arrow function in the
  factory but a proper function which can be imported.)

PR Close #39981
2020-12-07 09:51:27 -08:00
arturovt 5a3a154cd8 fix(core): unsubscribe from the `onError` when the root view is removed (#39940)
At the moment, when creating a root module, a subscription to the
`onError` subject is also created. It captures the scope where `NgModuleRef`
is created and prevents it from being garbage collected. Also note that this
`NgModuleRef` has a reference to the root module instance (e.g. `AppModule`),
which also prevents it from being GC'd.

PR Close #39940
2020-12-03 13:44:17 -08:00
Andrew Kushnir a55e01b89c test(core): verify `onDestroy` callbacks are invoked when ComponentRef is destroyed (#39876)
This commit adds a few tests to verify that the `onDestroy` callbacks are invoked when `ComponentRef` instance
is destroyed and the logic is consistent between ViewEngine and Ivy.

PR Close #39876
2020-12-02 12:56:05 -08:00
arturovt df27027ecb fix(core): remove application from the testability registry when the root view is removed (#39876)
In the new behavior Angular removes applications from the testability registry when the
root view gets destroyed. This eliminates a memory leak, because before that the
TestabilityRegistry holds references to HTML elements, thus they cannot be GCed.

PR Close #22106

PR Close #39876
2020-12-02 12:56:04 -08:00