134 Commits

Author SHA1 Message Date
Paul Gschwendtner
8de3c20e50 fix(ivy): do not reset view dirty state in check no changes mode (#34495)
Unlike in View Engine, we currently reset the dirty state of
components in the check no changes change detection cycle.

This means that components cannot be marked as dirty from
view lifecycle hooks because the dirty state is reset and
the lifecycle hooks do not run in the check no changes CD cycle.

PR Close #34495
2020-01-13 09:43:16 -08:00
crisbeto
8eb0596463 fix(ivy): unknown property and element checks not working correctly in IE (#34305)
We have a couple of cases where we use something like `typeof Node === 'function'` to figure out whether we're in a worker context. This works in most browsers, but IE returns `object` instead of `function`. I've updated all the usages to account for it.

PR Close #34305
2019-12-13 14:19:56 -08:00
Andrew Kushnir
c8b5b81516 refactor(ivy): avoid type coercion in saveNameToExportMap function (#34335)
TypeScript 3.7 flags `if` conditions that implicitly coerce a function/method definition. While checking for the `template` presence on a def (actually checking whether we work with Component) in `saveNameToExportMap`, the `if` condition had implicit type coercion. This commit updates the condition to use the `isComponentDef` function (that checks `def.template` against `null` internally) to avoid compilation errors with TypeScript 3.7.

PR Close #34335
2019-12-10 14:06:25 -08:00
Misko Hevery
c8447d21bd refactor(ivy): pull property read into a constant (#34290)
PR Close #34290
2019-12-10 10:33:19 -08:00
Misko Hevery
4ef6f1ab2e refactor(ivy): prevent -0 from being generated (#34290)
PR Close #34290
2019-12-10 10:33:19 -08:00
Andrew Kushnir
b342a69bbc fix(ivy): do not invoke change detection for destroyed views (#34241)
Prior to this commit, calling change detection for destroyed views resulted in errors being thrown in some cases. This commit adds a check to make sure change detection is invoked for non-destroyed views only.

PR Close #34241
2019-12-06 13:03:08 -08:00
crisbeto
953365d090 refactor(ivy): remove tsickle workaround in chainable instruction (#34019)
Previously if a type was returning itself it would cause an infinite loop in tsickle. We worked around it with a type that alises to `any`. Now that the issue has been resolved in tsickle, we can clean up the workaround.

PR Close #34019
2019-11-25 22:36:00 -05:00
Kara Erickson
1a0ee18d62 fix(ivy): run pre-order hooks in injection order (#34026)
This commit fixes a compatibility bug where pre-order lifecycle
hooks (onInit, doCheck, OnChanges) for directives on the same
host node were executed based on the order the directives were
matched, rather than the order the directives were instantiated
(i.e. injection order).

This discrepancy can cause issues with forms, where it is common
to inject NgControl and try to extract its control property in
ngOnInit. As the NgControl directive is injected, it should be
instantiated before the control value accessor directive (and
thus its hooks should run first). This ensures that the NgControl
ngOnInit can set up the form control before the ngOnInit
for the control value accessor tries to access it.

Closes #32522

PR Close #34026
2019-11-25 18:41:22 -05:00
Pawel Kozlowski
e698d355c1 refactor(ivy): stricter TNode.inputs typing (#33798)
TNode.inputs are initialised during directives resolution now so we know early
if a node has directives with inputs or no. We don't need to use undefined value
as an indicator that inputs were not resolved yet.

PR Close #33798
2019-11-19 11:56:00 -08:00
Pawel Kozlowski
da0c372fdf perf(ivy): don't store public input names in two places (#33798)
Before this change a public name of a directive's input
was stored in 2 places:
- as a key of an object on TNode.index;
- as a value of PropertyAliasValue at the index 1

This PR changes the data structure so the public name is stored
only once as a key on TNode.index. This saves one array entry
for each and every directive input.

PR Close #33798
2019-11-19 11:55:59 -08:00
Pawel Kozlowski
ad4300f52b refactor(ivy): limit reads from TView.consts (#33856)
PR Close #33856
2019-11-19 11:41:49 -08:00
Miško Hevery
7c64b1889f refactor(ivy): Remove findComponentView since we now store it in LView[DECLARATION_COMPONENT_VIEW] (#33810)
PR Close #33810
2019-11-15 10:41:02 -08:00
Miško Hevery
f4cdd35b3c perf(ivy): Improve performance of transplanted views (#33702)
PR Close #33702
2019-11-14 09:27:58 -08:00
Andrew Kushnir
cf10b336e7 fix(ivy): ComponentFactory.create should clear host element content (#33487)
Prior to this change, ComponentFactory.create function invocation in Ivy retained the content of the host element (in case host element reference or CSS seelctor is provided as an argument). This behavior is different in View Engine, where the content of the host element was cleared, except for the case when ShadowDom encapsulation is used (to make sure native slot projection works). This commit aligns Ivy and View Engine and makes sure the host element is cleared before component content insertion.

PR Close #33487
2019-11-12 21:34:06 -08:00
Misko Hevery
b62b11bd6b fix(ivy): Run ChangeDetection on transplanted views (#33644)
https://hackmd.io/@mhevery/rJUJsvv9H

Closes #33393

PR Close #33644
2019-11-12 13:53:54 -08:00
Miško Hevery
c25503b142 test(ivy): Have more descriptive names for LView (#33449)
When debugging `LView`s it is easy to get lost since all of them have
the same name. This change does three things:

1. It makes `TView` have an explicit type:
  - `Host`: for the top level `TView` for bootstrap
  - `Component`: for the `TView` which represents components template
  - `Embedded`: for the `TView` which represents an embedded template
2. It changes the name of `LView` to `LHostView`, `LComponentView`, and
  `LEmbeddedView` depending on the `TView` type.
3. For `LComponentView` and `LEmbeddedView` we also append the name of
  of the `context` constructor. The result is that we have `LView`s which
  are name as: `LComponentView_MyComponent` and `LEmbeddedView_NgIfContext`.

The above changes will make it easier to understand the structure of the
application when debugging.

NOTE: All of these are behind `ngDevMode` and will get removed in
production application.

PR Close #33449
2019-11-07 15:33:50 +00:00
Matias Niemelä
9c13d6e8e6 refactor(ivy): rename tView.firstTemplatePass to tView.firstCreatePass (#31270)
PR Close #31270
2019-11-04 21:39:23 +00:00
Matias Niemelä
91147ade2e refactor(ivy): introduce a firstUpdatePass flag for TView instances (#31270)
This patch introduces a `firstUpdatePass` flag which can be used inside
of instruction code to determine if this is the first time each
instruction is running inside of the update block of a template or
a hostBindings function.

PR Close #31270
2019-11-04 21:39:22 +00:00
crisbeto
66725b7b37 perf(ivy): move local references into consts array (#33129)
Follow-up from #32798. Moves the local references array into the component def's `consts` in order to make it compress better.

Before:
```
const _c0 = ['foo', ''];

SomeComp.ngComponentDef = defineComponent({
  template: function() {
    element(0, 'div', null, _c0);
  }
});
```

After:
```
SomeComp.ngComponentDef = defineComponent({
  consts: [['foo', '']],
  template: function() {
    element(0, 'div', null, 0);
  }
});
```

PR Close #33129
2019-11-04 16:30:53 +00:00
crisbeto
c83f5013bf feat(ivy): implement unknown element detection in jit mode (#33419)
In ViewEngine we used to throw an error if we encountered an unknown element while rendering. We have this already for Ivy in AoT, but we didn't in JiT. These changes implement the error for JiT mode.

PR Close #33419
2019-11-04 15:59:10 +00:00
Pawel Kozlowski
4452d6d848 perf(ivy): avoid repeated tNode.initialInputs reads (#33322)
PR Close #33322
2019-10-31 22:46:50 +00:00
Pawel Kozlowski
41caafcaf2 perf(ivy): avoid repeated native node retrieval and patching (#33322)
Before this change instantiating multiple directives on the same
host node would result in repeated RNode retrieval and patching.
This commint re-organises code around directive instance creation
so the host node processing (common to all directives) happens
once and only once.

As the additional benefit the directive instantiation logic gets
centralised in one function (at the expense of patching logic
duplication for root node).

PR Close #33322
2019-10-31 22:46:50 +00:00
Pawel Kozlowski
2c208f98a9 refactor(ivy): in-line postProcessDirective to avoid repeated isComponentDef checks (#33322)
PR Close #33322
2019-10-31 22:46:50 +00:00
Pawel Kozlowski
3ff712a0f5 refactor(ivy): correct typings in instantiateAllDirectives (#33322)
PR Close #33322
2019-10-31 22:46:49 +00:00
Miško Hevery
e16f75db56 refactor(ivy): move bindingIndex from LView to LFrame (#33235)
`bindingIndex` stores the current location of the bindings in the
template function. Because it used to be stored in `LView` that `LView`
was not reentrant. This could happen if a binding was a getter and had
a side-effect of calling `detectChanges()`.

By moving the `bindingIndex` to `LFrame` where all of the global state
is kept in reentrant way we correct the issue.

PR Close #33235
2019-10-28 10:59:29 -07:00
Matias Niemelä
5607ad8c62 perf(ivy): apply static styles/classes directly to an element's style/className properties (#33364)
PR Close #33364
2019-10-25 13:56:27 -07:00
Miško Hevery
09a2bb839f refactor(ivy): Intruduce LFrame to store global instruction information (#33178)
`LFrame` stores information specifice to the current `LView` As the code
enters and leaves `LView`s we use `enterView()` and `leaveView()`
respectively to build a a stack of `LFrame`s. This allows us to easily
restore the previous `LView` instruction state.

PR Close #33178
2019-10-24 14:42:15 -07:00
Miško Hevery
f1ffd57105 refactor(ivy): rename getComponentViewByIndex to getComponentLViewByIndex (#33074)
PR Close #33074
2019-10-22 12:00:20 -07:00
Andrew Kushnir
6f203c9575 fix(ivy): handling className as an input properly (#33188)
Prior to this commit, all `className` inputs were not set because the runtime code assumed that the `classMap` instruction is only generated for `[class]` bindings. However the `[className]` binding also produces the same `classMap`, thus the code needs to distinguish between `class` and `className`. This commit adds extra logic to select the right input name and also throws an error in case `[class]` and `[className]` bindings are used on the same element simultaneously.

PR Close #33188
2019-10-17 14:16:02 -04:00
Pawel Kozlowski
3e14c2d02c perf(ivy): limit global state read / write in host bindings (#33195)
PR Close #33195
2019-10-16 14:54:06 -04:00
Pawel Kozlowski
aef7dca234 perf(ivy): initialise inputs from static attrs on the first template pass only (#33195)
This change assures that data structures related to initial inputs
(ones set from static attributes) are created only once (during the
first template pass) and no additional runtime checks are done for
subsequent passes.

Additionally this commit changes the data structure used by initial inputs
on TNode - previously initial inputs for a directive were stored at the
directive index in LView. This meant that an array holding initial inputs
was relativelly big and had many null elements (as placeholders for elements,
directives, injector etc.). After the change we only create an array of a size
equal to a number of directives matched on a given TNode.
For the `directive_instantiate` benchmark it boils to allocating a 1-element
array vs. 100-element array previously.

PR Close #33195
2019-10-16 14:54:06 -04:00
Andrew Kushnir
11e04b1892 fix(ivy): avoid DOM element assertions if procedural renderer is used (#33156)
Prior to this commit, Ivy runtime asserted that a given element is an instance of a DOM node. These asserts may not be correct in case custom renderer is used, which operates objects with a shape different than DOM nodes. This commit updates the code to avoid the mentioned checks in case procedural renderer is used.

PR Close #33156
2019-10-15 21:03:29 +00:00
Pawel Kozlowski
d4d07233dc perf(ivy): guard host binding execution with a TNode flag (#33102)
Based on the results of the `directive_instantiate` executing host
bindings logic (in creation mode) account for ~23% of time spent in
the directive instantiation, even if a directive doesn't have host
bindings! This is clearly wastful hence a new flag.

PR Close #33102
2019-10-11 15:44:39 -07:00
Pawel Kozlowski
b800b88224 perf(ivy): stricter null checks in setInputsFromAttrs (#33102)
PR Close #33102
2019-10-11 15:44:39 -07:00
crisbeto
d5b87d32b0 perf(ivy): move attributes array into component def (#32798)
Currently Ivy stores the element attributes into an array above the component def and passes it into the relevant instructions, however the problem is that upon minification the array will get a unique name which won't compress very well. These changes move the attributes array into the component def and pass in the index into the instructions instead.

Before:
```
const _c0 = ['foo', 'bar'];

SomeComp.ngComponentDef = defineComponent({
  template: function() {
    element(0, 'div', _c0);
  }
});
```

After:
```
SomeComp.ngComponentDef = defineComponent({
  consts: [['foo', 'bar']],
  template: function() {
    element(0, 'div', 0);
  }
});
```

A couple of cases that this PR doesn't handle:
* Template references are still in a separate array.
* i18n attributes are still in a separate array.

PR Close #32798
2019-10-09 13:16:55 -07:00
Pawel Kozlowski
9f0c549bc8 perf(ivy): avoid memory allocation in the isAnimationProp check (#32997)
Accessing a string's character at index allocates a new, single character string.
A better (faster) check is to use `charCodeAt` that doesn't trigger allocation.

This simple change speeds up the element_text_create benchmark by ~7%.

PR Close #32997
2019-10-08 13:02:11 -07:00
Andrew Kushnir
90fb5d9f7a fix(ivy): generate ng-reflect properties for i18n attributes (#32989)
Prior to this change, ng-reflect properties were not created in case an attribute was marked as translatable (for ex. `i18n-title`). This commit adds the logic to generate ng-reflect for such cases.

PR Close #32989
2019-10-07 10:50:44 -07:00
Pawel Kozlowski
60047037a3 perf(ivy): attempt rendering initial styling only if present (#32979)
PR Close #32979
2019-10-04 11:44:57 -07:00
Pawel Kozlowski
e6881b5b42 perf(ivy): limit TNode.inputs reads on first template pass (#32979)
PR Close #32979
2019-10-04 11:44:57 -07:00
Andrew Scott
72f3747d7b fix(ivy): refresh child components before executing ViewQuery function (#32922)
Child component refresh must happen before executing the ViewQueryFn because
child components could insert a template from the host that contains the result
of the ViewQuery function (see related test added in this PR).

PR Close #32922
2019-10-01 14:47:15 -07:00
Matias Niemelä
f88f717094 refactor(ivy): remame styling_next directory to styling (#32731)
PR Close #32731
2019-09-18 15:06:39 -07:00
Matias Niemelä
a2e890e4f7 refactor(ivy): get rid of styling cleanup functions outside of styling code (#32591)
Prior to this patch, each time `advance()` would run (or when a
templateFn or hostBindings code exits) then the core change detection
code would check to see whether the styling data needs to be reset. This
patch removes that functionality and places everything inside of the
scheduled styling exit function. This means that each time one or more
styling bindings run (even if the value hasn't changed) then an exit
function will be scheduled and that will do all the cleanup.

PR Close #32591
2019-09-16 14:12:48 -07:00
Matias Niemelä
4f41473048 refactor(ivy): remove styling state storage and introduce direct style writing (#32591)
This patch is a final major refactor in styling Angular.

This PR includes three main fixes:

All temporary state taht is persisted between template style/class application
and style/class application in host bindings is now removed.
Removes the styling() and stylingApply() instructions.
Introduces a "direct apply" mode that is used apply prop-based
style/class in the event that there are no map-based bindings as
well as property collisions.

PR Close #32259

PR Close #32591
2019-09-16 14:12:48 -07:00
crisbeto
e6ed4a21e4 perf(ivy): avoid repeat LView reads in property instructions (#32681)
Currently all property instructions eventually call into `elementPropertyInternal` which in turn calls to `getLView`, however all of the instructions already have access to the LView. These changes switch to passing in the LView as a parameter.

PR Close #32681
2019-09-16 10:51:48 -07:00
Pawel Kozlowski
ad178c55fd perf(ivy): initialise TNode inputs / outputs on the first creation pass (#32608)
This perf-focused refactoring moves the TNode's input / output initialization
logic to the first template pass - close to the place where directives are
matched and resolved.

This code change makes it possible to update-mode checks for both property
bindings and listeners registration.

PR Close #32608
2019-09-12 12:11:32 -07:00
Pawel Kozlowski
fcdd06896e perf(ivy): avoid megamorphic reads during property binding (#32574)
While determining a property name to bind to we were checking a mapping object
resulting in the megamorphic read. Replacing such read with a series of if checks
speeds up rproprty update benchmark ~30% (~1400ms down to ~1000ms).

PR Close #32574
2019-09-12 06:30:08 -04:00
Filipe Silva
5f095a501e fix(core): initialize global ngDevMode without toplevel side effects (#32079)
Fix #31595

PR Close #32079
2019-09-11 20:31:14 -04:00
Matias Niemelä
53dbff66d7 revert: refactor(ivy): remove styling state storage and introduce direct style writing (#32259)
This reverts commit 15aeab16207fd6491e296db02501a14f92ff8e97.
2019-09-11 15:24:10 -07:00
Matias Niemelä
15aeab1620 refactor(ivy): remove styling state storage and introduce direct style writing (#32259) (#32596)
This patch is a final major refactor in styling Angular.

This PR includes three main fixes:

All temporary state taht is persisted between template style/class application
and style/class application in host bindings is now removed.
Removes the styling() and stylingApply() instructions.
Introduces a "direct apply" mode that is used apply prop-based
style/class in the event that there are no map-based bindings as
well as property collisions.

PR Close #32259

PR Close #32596
2019-09-11 16:27:10 -04:00
Matias Niemelä
c84c27f7f4 revert: refactor(ivy): remove styling state storage and introduce direct style writing (#32259) 2019-09-10 18:08:05 -04:00