Commit Graph

162 Commits

Author SHA1 Message Date
Kara Erickson 0e68c7edf9 fix(ivy): support projecting containers created by query reads (#31790)
PR Close #31790
2019-07-22 23:07:01 -07:00
Kara Erickson 54ef63b0f4 fix(ivy): support ICU expressions inserted in ngTemplateOutlets inside ngFors (#31789)
This commit fixes a bug where ICU expressions inserted into ngTemplateOutlets
that are inside ngFor blocks would throw an error. We were assuming in view
insertion code that text nodes would always exist by the time a view\`s
creation block had executed. This is not true for text nodes created dynamically
by ICUs because this happens in the update block (in `i18nApply`).

This change ensures such dynamically created nodes are skipped when encountered
too early (as they will be attached later by i18n code anyway).

PR Close #31789
2019-07-22 23:06:42 -07:00
Kara Erickson 215ef3c5f4 fix(ivy): ensure NgClass does not overwrite other dir data (#31788)
We currently have a handwritten version of the Ivy directive def for NgClass so
we can switch between Ivy and View Engine behavior. This generated code needs to
be kept up-to-date with what the Ivy compiler generates.

PR 30742 recently changed `classMap` such that it now requires allocation of
host binding slots. This means that the `allocHostVars()` function must be
called in the NgClass directive def to match compiler output, but the
handwritten directive def was not updated. This caused a bug where NgClass
was inappropriately overwriting data for other directives because space was
not allocated for its values.

PR Close #31788
2019-07-22 16:56:27 -07:00
Pawel Kozlowski d52ae7cbab perf(ivy): match query results on the TView level (#31489)
PR Close #31489
2019-07-19 20:38:08 -07:00
Matias Niemelä 9c954ebc62 refactor(ivy): make styling instructions use the new styling algorithm (#30742)
This commit is the final patch of the ivy styling algorithm refactor.
This patch swaps functionality from the old styling mechanism to the
new refactored code by changing the instruction code the compiler
generates and by pointing the runtime instruction code to the new
styling algorithm.

PR Close #30742
2019-07-19 16:40:40 -07:00
Paul Gschwendtner 647d7bdd88 refactor: fix typescript strict flag failures in all tests (#30993)
Fixes all TypeScript failures caused by enabling the `--strict`
flag for test source files. We also want to enable the strict
options for tests as the strictness enforcement improves the
overall codehealth, unveiled common issues and additionally it
allows us to enable `strict` in the `tsconfig.json` that is picked
up by IDE's.

PR Close #30993
2019-07-18 14:21:26 -07:00
Paul Gschwendtner e061e638cb fix(ivy): semantic module check incorrectly handles nested arrays (#30993)
In View Engine, developers can pass bootstrap and entry components
as nested arrays. e.g.

```ts
export const MyOtherEntryComponents = [A, B, C]

@NgModule({
  entryComponents: [MyComp, MyOtherEntryComponents]
})
```

Currently using nested arrays for these properties causes
unexpected errors to be reported in Ivy since the semantic
NgModule checks aren't properly recursing into the nested
entry/bootstrap components. This issue has been unveiled by
enabling the strict function parameter checks.

PR Close #30993
2019-07-18 14:21:26 -07:00
crisbeto 12fd06916b fix(ivy): don't match directives against attribute bindings (#31541)
Fixes Ivy matching directives against attribute bindings (e.g. `[attr.some-directive]="foo"`). Works by excluding attribute bindings from the attributes array during compilation. This has the added benefit of generating less code.

**Note:** My initial approach to implementing this was to have a different marker for attribute bindings so that they can be ignored when matching directives, however as I was implementing it I realized that the attributes in that array were only used for directive matching (as far as I could tell). I decided to drop the attribute bindings completely, because it results in less generated code.

PR Close #31541
2019-07-16 23:59:13 -04:00
crisbeto 9e83822679 fix(ivy): a couple of typos in error messages (#31571)
Fixes a couple of typos that were noticed after the initial PR (#31543) got merged in.

PR Close #31571
2019-07-16 23:58:52 -04:00
crisbeto 31ea254a07 fix(ivy): align NgModule assertions with ViewEngine (#31543)
Aligns Ivy's `NgModule` assertion messages with the ones from `ViewEngine` and adds a few that hadn't been implemented.

PR Close #31543
2019-07-15 13:58:19 -04:00
Andrew Kushnir 63e458dd3a fix(ivy): handle ICUs with placeholders in case other nested ICUs are present (#31516)
Prior to this fix, the logic to set the right placeholder format for ICUs was a bit incorrect: if there was a nested ICU in one of the root ICU cases, that led to a problem where placeholders in subsequent branches used the wrong ({$placeholder}) format instead of {PLACEHOLDER} one. This commit updates the logic to make sure we properly transform all placeholders even if nested ICUs are present.

PR Close #31516
2019-07-12 11:37:16 -04:00
Andrew Kushnir dee16a4355 fix(ivy): update ICU placeholders format to match Closure compiler (#31459)
Since `goog.getMsg` does not process ICUs (post-processing is required via goog.i18n.MessageFormat, https://google.github.io/closure-library/api/goog.i18n.MessageFormat.html) and placeholder format used for ICUs and regular messages inside `goog.getMsg` are different, the current implementation (that assumed the same placeholder format) needs to be updated. This commit updates placeholder format used inside ICUs from `{$placeholder}` to `{PLACEHOLDER}` to better align with Closure. ICU placeholders (that were left as is prior to this commit) are now replaced with actual values in post-processing step (inside `i18nPostprocess`).

PR Close #31459
2019-07-10 18:31:33 -04:00
Andrew Kushnir 6da1446afc fix(ivy): handle &ngsp; in i18n translations correctly (#31479)
Prior to this commit, the `` unicode symbol that represents `&ngsp` in translations was not handled correctly, i.e. was not replaced with a whitespace, thus appearing on a screen. This commit adds post-processing and replaces the mentioned symbol with a whitespace.

PR Close #31479
2019-07-10 18:29:32 -04:00
Olivier Combe 2b44be984e fix(ivy): i18n should not alloc expando slots when there is no new var (#31451)
`i18nStart` was calling `allocExpando` even if there was 0 new variable created.
This created a new expando instruction with the value 0 which was later interpreted as the start of a new expando block instead of just skipping 0 instructions.

FW-1417 #resolve

PR Close #31451
2019-07-09 14:31:10 -07:00
crisbeto 23e0d65471 perf(ivy): add self-closing elementContainer instruction (#31444)
Adds a new `elementContainer` instruction that can be used to avoid two instruction (`elementContainerStart` and `elementContainerEnd`) for `ng-container` that has text-only content. This is particularly useful when we have `ng-container` inside i18n sections.

This PR resolves FW-1105.

PR Close #31444
2019-07-09 13:50:28 -07:00
crisbeto 02491a6ce8 refactor(ivy): move classMap interpolation logic internally (#31211)
Adds the new `classMapInterpolate1` through `classMapInterpolate8` instructions which handle interpolations inside the `class` attribute and moves the interpolation logic internally. This allows us to remove the `interpolationX` instructions in a follow-up PR.

These changes also add an error if an interpolation is encountered inside a `style` tag (e.g. `style="width: {{value}}"`). Up until now this would actually generate valid instructions, because `styleMap` goes through the same code path as `classMap` which does support interpolation. At runtime, however, `styleMap` would set invalid styles that look like `<div style="0:w;1:i;2:d;3:t;4:h;5::;7:1;">`. In `ViewEngine` interpolations inside `style` weren't supported either, however there we'd output invalid styles like `<div style="unsafe">`, even if the content was trusted.

PR Close #31211
2019-07-02 11:07:14 -07:00
Pawel Kozlowski 7ca611cd12 fix(ivy): properly handle re-projection with an empty set of nodes to re-project (#31306)
PR Close #31306
2019-06-28 12:21:37 -07:00
Andrew Kushnir c12b6fa028 fix(ivy): attach host element for views created via TestBed.createComponent (#31318)
Prior to this commit, host element of a view created via TestBed.createComponent was not attached to the component's host, making it problematic to use TestBed.createComponent API in component factories, which might be used for testing purposes only. This behavior is observed in google3 app tests and was supported by VE, so this commit aligns Ivy and VE.

PR Close #31318
2019-06-28 12:20:53 -07:00
Olivier Combe 4f38419e33 fix(ivy): handle ICU expressions in `executeActionOnNode` (#31313)
When `walkTNodeTree` was refactored, the case of ICU expressions was forgotten (because it was handled in the `else` previously).
This PR fixes that to handle it like `ElementContainer`.

FW-1411 #resolve
PR Close #31313
2019-06-27 15:53:10 -07:00
Kristiyan Kostadinov f2360aab9d fix(ivy): incorrect namespace for root node created through ViewContainerRef (#31232)
Currently in Ivy whenever we encounter a new namespace, we set it in the global state so that all subsequent nodes are created under the same namespace. Next time a template is run the namespace will be reset back to HTML.

This breaks down if the last node that was rendered was under the SVG or MathML namespace and we create a component through `ViewContainerRef.create`, because the next template function hasn't run yet and it hasn't had the chance to update the namespace. The result is that the root node of the new component will retain the wrong namespace and may not end up rendering at all (e.g. if we're trying to show a `div` inside the SVG namespace). This issue has the potential to affect a lot of apps, because all components inserted through the router also go through `ViewContainerRef.create`.

PR Close #31232
2019-06-27 09:50:52 -07:00
Alex Rickabaugh 32c760f5e7 fix(ivy): don't mask errors by calling lifecycle hooks after a crash (#31244)
The Angular runtime frequently calls into user code (for example, when
writing to a property binding). Since user code can throw errors, calls to
it are frequently wrapped in a try-finally block. In Ivy, the following
pattern is common:

```typescript
enterView();
try {
  callUserCode();
} finally {
  leaveView();
}
```

This has a significant problem, however: `leaveView` has a side effect: it
calls any pending lifecycle hooks that might've been scheduled during the
current round of change detection. Generally it's a bad idea to run
lifecycle hooks after the application has crashed. The application is in an
inconsistent state - directives may not be instantiated fully, queries may
not be resolved, bindings may not have been applied, etc. Invariants that
the app code relies upon may not hold. Further crashes or broken behavior
are likely.

Frequently, lifecycle hooks are used to make assertions about these
invariants. When these assertions fail, they will throw and "swallow" the
original error, making debugging of the problem much more difficult.

This commit modifies `leaveView` to understand whether the application is
currently crashing, via a parameter `safeToRunHooks`. This parameter is set
by modifying the above pattern:

```typescript
enterView();
let safeToRunHooks = false;
try {
  callUserCode();
  safeToRunHooks = true;
} finally {
  leaveView(..., safeToRunHooks);
}
```

If `callUserCode` crashes, then `safeToRunHooks` will never be set to `true`
and `leaveView` won't call any further user code. The original error will
then propagate back up the stack and be reported correctly. A test is added
to verify this behavior.

PR Close #31244
2019-06-26 08:01:14 -07:00
Misko Hevery 29a9909232 refactor(ivy): simplify `walkTNodeTree` method for readability (#31182)
PR Close #31182
2019-06-25 17:03:51 -07:00
crisbeto 23c017121e perf(ivy): chain multiple attribute instructions (#31152)
Similarly to what we did in #31078, these changes implement chaining for the `attribute` instruction.

This PR resolves FW-1390.

PR Close #31152
2019-06-24 12:33:49 -07:00
crisbeto fcb03abc72 fix(ivy): injecting incorrect Renderer2 into child components (#31063)
In ViewEngine injecting a Renderer2 returns a renderer that is specific to the particular component, however in Ivy we inject the renderer for the parent view instead. This causes it to set incorrect `ngcontent` attributes when creating elements through the renderer.

The issue comes from the fact that the `Renderer2` is created according to the current `LView`, but because DI happens before we've entered the `LView` of the component that's injecting the renderer, we end up with one that's one level up. We work around the issue by finding the `LView` that corresponds to the `previousOrParentTNode` inside of the parent view and associating the `Renderer2` with it.

This PR resolves FW-1382.

PR Close #31063
2019-06-24 11:33:31 -07:00
Alex Rickabaugh bd3b0564e6 fix(ivy): sync ViewRefs between multiple ViewContainerRefs (#30985)
Previously, multiple ViewContainerRef instances (obtained by injecting
ViewContainerRef multiple times) each had private state that could be out of
sync with actual LContainer, if views were inserted/removed/queried across
the different instances. In particular each instance had its own array which
tracked ViewRefs inserted via that instance.

This commit moves the ViewRefs array onto the LContainer itself, so that it
can be shared across multiple ViewContainerRef instances. A test is added
that verifies ViewContainerRefs now provide a consistent view of the
container.

FW-1377 #resolve

PR Close #30985
2019-06-21 10:18:06 -07:00
Olivier Combe 65544ac742 fix(ivy): reprojected ICU expression nodes when creating embedded views (#30979)
When using `createEmbeddedView` after the creation of an ICU expression, the nodes for the current selected case were not reprojected (only the anchor comment node was moved to the new location).
Now we reproject correctly all the child nodes of an ICU expression when an anchor comment node is projected.

FW-1372 #resolve

PR Close #30979
2019-06-18 09:48:46 -07:00
crisbeto 8f5c396a7c fix(ivy): don't throw when attempting to destroy a destroyed ComponentRef (#31022)
Currently in Ivy we throw when attempting to destroy a `ComponentRef` that has been destroyed, however in ViewEngine we didn't which can cause some tests to break. These changes remove the error to match ViewEngine.

These changes resolve FW-1379.

PR Close #31022
2019-06-14 10:44:30 -07:00
Paul Gschwendtner 58be2ff884 fix(ivy): unable to bind to implicit receiver in embedded views (#30897)
To provide some context: The implicit receiver is part of the
parsed Angular template AST. Any property reads in bindings,
interpolations etc. read from a given object (usually the component
instance). In that case there is an _implicit_ receiver which can also
be specified explicitly by just using `this`.

e.g.

```html
<ng-template>{{this.myProperty}}</ng-template>
```

This works as expected in Ivy and View Engine, but breaks in case the
implicit receiver is not used for property reads. For example:

```html
<my-dir [myFn]="greetFn.bind(this)"></my-dir>
```

In that case the `this` will not be properly translated into the generated
template function code because the Ivy compiler currently always treats
the `ctx` variable as the implicit receiver. This is **not correct** and breaks
compatibility with View Engine. Rather we need to ensure that we retrieve
the root context for the standalone implicit receiver similar to how it works
for property reads (as seen in the example above with `this.myProperty`)

Note that this requires some small changes to the `expression_converter`
because we only want to generate the `eenextContent()` instruction if the
implicit receiver is _actually_ used/needed. View Engine determines if that is the case by recursively walking through the converted output AST and
checking for usages of the `o.variable('_co')` variable ([see here][ve_check]). This would work too for Ivy, but involves most likely more code duplication
since templates are isolated in different functions and it another pass
through the output AST for every template expression.

[ve_check]: 0d6c9d36a1/packages/compiler/src/view_compiler/view_compiler.ts (L206-L208)

Resolves FW-1366.

PR Close #30897
2019-06-11 14:29:42 -07:00
Paul Gschwendtner 8c4bd61b2f test(core): add missing static flag to view_insertion test view queries (#30967)
17d87d4e10 has been created before the changes
to the `@ViewChild` and `@ContentChild` decorators. Meaning that it still uses the queries
without the `static` flag. This results in failures in `master` because #30625 has been merged.

PR Close #30967
2019-06-11 09:37:19 -07:00
Olivier Combe 4155ed439a fix(ivy): correctly set `TView.firstChild` with runtime i18n (#30920)
`TView.firstChild` was defined as the first node with index 0, but when we use runtime i18n then the instruction `i18nStart` can be the one with index 0 and the first node will be index 1 or more.
With this fix we set `TView.firstChild` when we see the first node with index 0 or later if `TView.firstChild` is still null.

FW-1367 #resolve
PR Close #30920
2019-06-11 00:09:32 +00:00
Ben Lesh 17d87d4e10 test(ivy): Add acceptance tests for view insertion (#30625)
This work is being done ahead of changes to how view insertion is done in Ivy in accordance with [this design document](https://hackmd.io/Ae3W_2pOQlKouu9YNy1t6A?view).

The idea is to make sure we have acceptance tests ahead of that change.

PR Close #30625
2019-06-10 23:53:34 +00:00
Pawel Kozlowski 11a4454ab3 perf(ivy): remove check for function type in renderStringify (#30838)
The `renderStringify` function shows up pretty high in the CPU profiling.
Turns out that this function contained unnecessary `typeof` check for
function types - the check only makes sense / is used in error messages.

The PR also alligns how ivy and view engine stringify functions used in
interpolations.

PR Close #30838
2019-06-06 13:47:41 -07:00
Olivier Combe b4b7af86c2 fix(ivy): trigger directive inputs for each template creation (#30870)
A directive input that doesn't use a binding is triggered during the creation phase. But this was only executed at the first template pass, and not on subsequent ones.
Now only the creation of the update instruction is executed on the first template pass, anything else is executed every time a template is created.

FW-1361 #resolve
PR Close #30870
2019-06-06 13:46:40 -07:00
Olivier Combe 30efb6b8ea fix(ivy): don't project removed placeholders with runtime i18n (#30783)
When translated content was projected, all of the content was reappended, even the placeholders that had been removed in the translation.
To avoid that we added a new flag on `TNode` that specifies that a node is detached, in which case it should be ignored by the projection.

FW-1319 #resolve
PR Close #30783
2019-06-05 21:28:39 -07:00
Olivier Combe 00cc905b98 feat(ivy): support `ng-content` in runtime i18n translations (#30782)
Added a new syntax for projections (`¤` will represent `ng-content` nodes) so that we can treat them specifically.
When we enter an i18n block with the instruction `i18nStart`, a new `delayProjection` variable is set to true to prevent the instruction `projection` from projecting the nodes. Once we reach the `i18nEnd` instruction and encounter a projection in the translation we will project its nodes.
If a projection was removed from a translation, then its nodes won't be projected at all.
The variable `delayProjection` is restored to `false` at the end of `i18nEnd` so that it doesn't stop projections outside of i18n blocks.

FW-1261 #resolve
PR Close #30782
2019-06-05 09:04:13 -07:00
Olivier Combe 0d4f8c7dd9 fix(ivy): allow empty cases for ICU expressions (#30846)
We used to ignore empty strings for optimization purposes, but it turns out that empty strings are also valid values for ICU cases and we shouldn't ignore those.

FW-1290 #resolve
PR Close #30846
2019-06-04 13:36:28 -07:00
Miško Hevery 55a14e4866 feat(ivy): in `ngDevMode` use named object literals and arrays for easier debugging/profiling (#30542)
PR Close #30542
2019-06-04 12:01:46 -07:00
Olivier Combe 680d38513b fix(ivy): correctly project bare ICU expressions (#30696)
Projecting bare ICU expressions failed because we would assume that component's content nodes would be projected later and doing so at that point would be wasteful. But ICU nodes are handled independently and should be inserted immediately because they will be ignored by projections.

FW-1348 #resolve

PR Close #30696
2019-06-03 08:59:14 -07:00
Paul Gschwendtner aca339e864 fix(ivy): unable to project into multiple slots with default selector (#30561)
With View engine it was possible to declare multiple projection
definitions and to programmatically project nodes into the slots.

e.g.

```html
<ng-content></ng-content>
<ng-content></ng-content>
```

Using `ViewContainerRef#createComponent` allowed projecting
nodes into one of the projection defs (through index)

This no longer works with Ivy as the `projectionDef` instruction only
retrieves a list of selectors instead of also retrieving entries for
reserved projection slots which appear when using the default
selector multiple times (as seen above).

In order to fix this issue, the Ivy compiler now passes all
projection slots to the `projectionDef` instruction. Meaning that
there can be multiple projection slots with the same wildcard
selector. This allows multi-slot projection as seen in the
example above, and it also allows us to match the multi-slot node
projection order from View Engine (to avoid breaking changes).

It basically ensures that Ivy fully matches the View Engine behavior
except of a very small edge case that has already been discussed
in FW-886 (with the conclusion of working as intended).

Read more here: https://hackmd.io/s/Sy2kQlgTE

PR Close #30561
2019-05-31 09:52:32 -07:00
Paul Gschwendtner 6d861f240b fix(ivy): module with providers are processed too early (#30688)
Currently with Ivy, `ModuleWithProvider` providers are processed in order
of declaration in the `NgModule` imports. This technically makes makes
sense but is a potential breaking change as `ModuleWithProvider` providers
are processed after all imported modules in View Engine.

In order to keep the behavior of View Engine, the `r3_injector` is updated
to no longer process `ModuleWithProvider` providers egarly.

Resolves FW-1349

PR Close #30688
2019-05-31 09:48:39 -07:00
Matias Niemelä 19bbf4bc8e test(ivy): fix sanitization state leaking issue
Due to sanitization being stored as a temp/global value between
instructions, unit tests randomly failed because one test failed
to clean up its temporary value. This patch fixes this issue.
2019-05-30 13:53:06 -07:00
Olivier Combe 91699259b2 fix(ivy): trigger directive inputs with i18n translations (#30402)
Changed runtime i18n to define attributes with bindings, or matching directive inputs/outputs as element properties as we are supposed to do in Angular.
This PR fixes the issue where directive inputs wouldn't be trigged.

FW-1315 #resolve
PR Close #30402
2019-05-30 16:39:24 -04:00
Olivier Combe 5e0f982961 feat(ivy): use i18n locale data to determine the plural form of ICU expressions (#29249)
Plural ICU expressions depend on the locale (different languages have different plural forms). Until now the locale was hard coded as `en-US`.
For compatibility reasons, if you use ivy with AOT and bootstrap your app with `bootstrapModule` then the `LOCALE_ID` token will be set automatically for ivy, which is then used to get the correct plural form.
If you use JIT, you need to define the `LOCALE_ID` provider on the module that you bootstrap.
For `TestBed` you can use either `configureTestingModule` or `overrideProvider` to define that provider.
If you don't use the compat mode and start your app with `renderComponent` you need to call `ɵsetLocaleId` manually to define the `LOCALE_ID` before bootstrap. We expect this to change once we start adding the new i18n APIs, so don't rely on this function (there's a reason why it's a private export).
PR Close #29249
2019-05-30 15:09:02 -04:00
Matias Niemelä 82682bb93f refactor(ivy): enable sanitization support for the new styling algorithm (#30667)
This patch is one of the final patches to refactor the styling algorithm
to be more efficient, performant and less complex.

This patch enables sanitization support for map-based and prop-based
style bindings.

PR Close #30667
2019-05-30 01:03:39 -04:00
Ben Lesh dd0815095f feat(ivy): add ɵɵtextInterpolateX instructions (#30011)
- `ɵɵtextBinding(..., ɵɵinterpolationX())` instructions will now just be `ɵɵtextInterpolate(...)` instructions

PR Close #30011
2019-05-29 12:38:58 -04:00
Alex Rickabaugh 661c6e6f10 fix(ivy): fix PR collision with static: true and new test (#30666)
This fixes a collision between #30639 and #30543 where the latter added
usages of @ViewChild without the static flag present, but the former
made the flag required.

PR Close #30666
2019-05-24 18:02:17 -04:00
Matias Niemelä dc6406e5e8 refactor(ivy): evaluate map-based styling bindings with a new algorithm (#30543)
This patch in the second runtime change which refactors how styling
bindings work in Angular. This patch refactors how map-based
`[style]` and `[class]` bindings work using a new algorithm which
is faster and less complex than the former one.

This patch is a follow-up to an earlier refactor which enabled
support for prop-based `[style.name]` and `[class.name]`
bindings (see f03475cac8).

PR Close #30543
2019-05-24 14:31:35 -04:00
Olivier Combe 68cd0cab8c fix(ivy): don't throw on unmatched placeholder replacements in `i18nPostprocess` (#30632)
Depending on which placeholders the translation uses, there are some legitimate cases where we might not use all placeholder replacements in `i18nPostprocess`. For example if some of the placeholders of the original messages have been removed in the translation.

FW-1312 #resolve
PR Close #30632
2019-05-24 13:57:44 -04:00
Kara Erickson faac51fd2e test(core): update query-specific tests in core (#30626)
PR Close #30626
2019-05-23 10:31:32 -07:00
Kara Erickson 4299ecf9be test(core): update core tests (unrelated to queries) to use static flag (#30626)
PR Close #30626
2019-05-23 10:31:32 -07:00