1060 Commits

Author SHA1 Message Date
Pawel Kozlowski
c44415494a refactor(ivy): separate first creation pass in the elementContainerStart instruction (#33894)
PR Close #33894
2019-11-18 16:01:54 -08:00
Pawel Kozlowski
96499c898f refactor(ivy): separate first creation pass in the text instruction (#33894)
PR Close #33894
2019-11-18 16:01:54 -08:00
Pawel Kozlowski
49c9f782ab fix(ivy): properly insert views into ViewContainerRef injected by querying <ng-container> (#33816)
When asking for a ViewContainerRef on <ng-container> we do reuse <ng-container> comment
node as a LContainer's anachor. Before this fix the act of re-using a <ng-container>'s
comment node would result in this comment node being re-appended to the DOM in the wrong
place. With the fix in this PR we make sure that re-using <ng-container>'s comment node
doesn't result in unwanted DOM manipulation (ng-gontainer's comment node is already part
of the DOM and doesn't have to be re-created / re-appended).

PR Close #33816
2019-11-18 16:00:00 -08:00
Miško Hevery
f2828a08bd fix(ivy): ExpressionChangedAfterItHasBeenCheckedError for SafeValue (#33749)
Fix #33448

PR Close #33749
2019-11-15 10:44:23 -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
Andrew Kushnir
e51ec671a5 fix(ivy): extend assertion in directiveInject function to support IcuContainers (#33832)
Prior to this commit the assert that we have in `directiveInject` (assert introduced recently) didn't include IcuContainer TNode type and as a result, the error is thrown in case pipes with dependencies are used inside ICUs. This commit extends the assert to allow for IcuContainer TNode types.

PR Close #33832
2019-11-14 16:01:30 -08:00
Andrew Kushnir
96c9ccc81a fix(ivy): avoid cyclical dependency in imports (#33831)
This commit moves the `setLContainerActiveIndex` and `getLContainerActiveIndex` functions used in a few files to a common `util/view_util.ts` lib to avoid cyclical dependency while importing `instructions/container.ts` where these functions located originally.

PR Close #33831
2019-11-14 12:13:26 -08:00
Pawel Kozlowski
784fd26473 refactor(ivy): minor improvements / cleanup in the DI code (#33794)
PR Close #33794
2019-11-14 09:28:26 -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
crisbeto
fcdada53f1 fix(ivy): constant object literals shared across element and component instances (#33705)
Currently if a consumer does something like the following, the object literal will be shared across the two elements and any instances of the component template. The same applies to array literals:

```
<div [someDirective]="{}"></div>
<div [someDirective]="{}"></div>
```

These changes make it so that we generate a pure function even if an object is constant so that each instance gets its own object.

Note that the original design for this fix included moving the pure function factories into the `consts` array. In the process of doing so I realized that pure function are also used inside of directive host bindings which means that we don't have access to the `consts`.

These changes also:
* Fix an issue that meant that the `pureFunction0` instruction could only be run during creation mode.
* Make the `getConstant` utility slightly more convenient to use. This isn't strictly required for these changes to work, but I had made it as a part of a larger refactor that I ended up reverting.

PR Close #33705
2019-11-13 13:36:41 -08:00
Andrew Kushnir
0fecea1427 fix(ivy): reset style property value defined using [style.prop.px] (#33780)
Prior to this change, setting style prop value to undefined or empty string would not result in resetting prop value in case the style prop is defined using [style.prop.px] syntax. The problem is that the check for empty value (and thus reseting the value) considered successful only in case of `null` value. This commit updates the check to use `isStylingValueDefined` function that also checks for undefined and empty string.

PR Close #33780
2019-11-13 13:32:33 -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
Miško Hevery
7a29b24720 style: Remove use of String as type and use string instead. (#33763)
PR Close #33763
2019-11-12 13:59:16 -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
crisbeto
e31f62045d perf(ivy): chain listener instructions (#33720)
Chains multiple listener instructions on a particular element into a single call which results in less generated code. Also handles listeners on templates, host listeners and synthetic host listeners.

PR Close #33720
2019-11-12 09:59:13 -08:00
Andrew Scott
a972e4cd4d fix(ivy): auto register NgModules with ID (#33663)
PR Close #33663
2019-11-12 09:53:15 -08:00
Pete Bacon Darwin
e511bfcab5 fix(ivy): ensure that the correct document is available (#33712)
Most of the use of `document` in the framework is within
the DI so they just inject the `DOCUMENT` token and are done.

Ivy is special because it does not rely upon the DI and must
get hold of the document some other way. There are a limited
number of places relevant to ivy that currently consume a global
document object.

The solution is modelled on the `LOCALE_ID` approach, which has
`getLocaleId()` and `setLocaleId()` top-level functions for ivy (see
`core/src/render3/i18n.ts`).  In the rest of Angular (i.e. using DI) the
`LOCALE_ID` token has a provider that also calls setLocaleId() to
ensure that ivy has the same value.

This commit defines `getDocument()` and `setDocument() `top-level
functions for ivy. Wherever ivy needs the global `document`, it calls
`getDocument()` instead.  Each of the platforms (e.g. Browser, Server,
WebWorker) have providers for `DOCUMENT`. In each of those providers
they also call `setDocument()` accordingly.

Fixes #33651

PR Close #33712
2019-11-11 14:01:04 -08:00
Pawel Kozlowski
39712bcdb2 test(ivy): get ViewRef.rootNodes should get all root nodes from projectable nodes (#33647)
PR Close #33647
2019-11-11 09:37:38 -08:00
Pawel Kozlowski
9d99c7244f refactor(ivy): simplify getFirstNativeNode processing of LContainer (#33647)
PR Close #33647
2019-11-11 09:37:38 -08:00
Pawel Kozlowski
05d7c575e4 fix(ivy): properly insert views in front of empty views (#33647)
PR Close #33647
2019-11-11 09:37:38 -08:00
Pawel Kozlowski
056236cafd fix(ivy): properly insert views in front of views with an empty element container (#33647)
PR Close #33647
2019-11-11 09:37:38 -08:00
Pawel Kozlowski
f63e5d9319 fix(ivy): properly determine the first native node of a view (#33627)
PR Close #33627
2019-11-07 16:50:29 -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
Andrew Kushnir
39550746f8 fix(ivy): better support for i18n attributes on <ng-container>s (#33599)
Prior to this commit, i18n runtime logic used `elementAttributeInternal` function (that uses `setAttribute` function under the hood) for all elements where i18n attributes are present. However the `<ng-container>` elements in a template may also have i18n attributes and calling `setAttribute` fails, since they are represented as comment nodes in DOM. This commit ensures that we call `setAttribute` on nodes with TNodeType.Element type (that support that operation) only.

PR Close #33599
2019-11-07 01:51:42 +00:00
Matias Niemelä
41560b47c4 refactor(ivy): move all styling configurations into TNodeFlags (#33540)
This patch gets rid of the configuration settings present in the
`TStylingContext` array that is used within the styling algorithm
for `[style]`, `[style.prop]`, `[class]` and `[class.name]` bindings.
These configurations now all live inside of the `TNodeFlags`.

PR Close #33540
2019-11-06 19:18:36 +00:00
Matias Niemelä
3297a76195 refactor(ivy): remove TStylingContext locking in favor of firstUpdatePass flag (#33521)
This patch removes the need to lock the style and class context
instances to track when bindings can be added. What happens now is
that the `tNode.firstUpdatePass` is used to track when bindings are
registered on the context instances.

PR Close #33521
2019-11-06 16:19:29 +00:00
Matias Niemelä
5453c4cd96 refactor(ivy): use hex flags instead of binary for TNodeFlags (#33605)
PR Close #33605
2019-11-06 16:12:59 +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
Pawel Kozlowski
4ff43e1324 refactor(ivy): remove the getHostNative utility function (#33554)
We already store a reference to a native host of a component
view so we can drop the getHostNative utility function (that
was getting the same reference from another data structure).

PR Close #33554
2019-11-04 20:07:06 +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
083d48e072 perf(ivy): avoid native node retrieval from LView (#33511)
PR Close #33511
2019-10-31 22:53:29 +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
Pawel Kozlowski
563a507315 fix(ivy): descend into ICU containers when collecting rootNodes (#33493)
PR Close #33493
2019-10-30 11:46:09 -07:00
Pawel Kozlowski
a5167bd53c fix(ivy): descend into view containers on ng-container when collecting rootNodes (#33493)
PR Close #33493
2019-10-30 11:46:09 -07:00
Pawel Kozlowski
87743f1aa1 fix(ivy): descend into view containers on elements when collecting rootNodes (#33493)
PR Close #33493
2019-10-30 11:46:09 -07:00
Pawel Kozlowski
502fb7e307 fix(ivy): descend into view containers on ng-template when collecting rootNodes (#33493)
PR Close #33493
2019-10-30 11:46:09 -07:00
crisbeto
c3e93564d0 perf(ivy): avoid generating selectors array for directives without a selector (#33431)
Now that we've replaced `ngBaseDef` with an abstract directive definition, there are a lot more cases where we generate a directive definition without a selector. These changes make it so that we don't generate the `selectors` array if it's going to be empty.

PR Close #33431
2019-10-29 12:06:15 -07:00
Andrew Kushnir
bd40c89688 fix(ivy): handle elements with local refs in i18n blocks (#33415)
Prior to this commit, i18n logic which ensures that elements removed in a translation are also removed in DOM, didn't take into account the fact that elements may have local refs. As a result, remove operation failed, since there is no corresponding tNode found. This commit updates the logic to skip all local refs while going though the list of nodes to ensure that DOM matches elements present in translation.

PR Close #33415
2019-10-29 11:47:28 -07: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
crisbeto
14c4b1b205 refactor(ivy): remove ngBaseDef (#33264)
Removes `ngBaseDef` from the compiler and any runtime code that was still referring to it. In the cases where we'd previously generate a base def we now generate a definition for an abstract directive.

PR Close #33264
2019-10-25 13:11:34 -07:00
JoostK
8d15bfa6ee fix(ivy): allow abstract directives to have an invalid constructor (#32987)
For abstract directives, i.e. directives without a selector, it may
happen that their constructor is called explicitly from a subclass,
hence its parameters are not required to be valid for Angular's DI
purposes. Prior to this commit however, having an abstract directive
with a constructor that has parameters that are not eligible for
Angular's DI would produce a compilation error.

A similar scenario may occur for `@Injectable`s, where an explicit
`use*` definition allows for the constructor to be irrelevant. For
example, the situation where `useFactory` is specified allows for the
constructor to be called explicitly with any value, so its constructor
parameters are not required to be valid. For `@Injectable`s this is
handled by generating a DI factory function that throws.

This commit implements the same solution for abstract directives, such
that a compilation error is avoided while still producing an error at
runtime if the type is instantiated implicitly by Angular's DI
mechanism.

Fixes #32981

PR Close #32987
2019-10-25 12:13:23 -07:00
Alex Rickabaugh
818c514968 feat(ivy): add a runtime feature to copy cmp/dir definitions (#33362)
This commit adds CopyDefinitionFeature, which supports the case where an
entire decorator (@Component or @Directive) is inherited from parent to
child.

The existing inheritance feature, InheritDefinitionFeature, supports merging
of parent and child definitions when both were originally present. This
merges things like inputs, outputs, host bindings, etc.

CopyDefinitionFeature, on the other hand, compensates for a definition that
was missing entirely on the child class, by copying fields that aren't
ordinarily inherited (like the template function itself).

This feature is intended to only be used as part of ngcc code generation.

PR Close #33362
2019-10-25 09:16:50 -07:00
Matias Niemelä
dcdb433b7d perf(ivy): apply [style]/[class] bindings directly to style/className (#33336)
This patch ensures that the `[style]` and `[class]` based bindings
are directly applied to an element's style and className attributes.

This patch optimizes the algorithm so that it...
- Doesn't construct an update an instance of `StylingMapArray` for
  `[style]` and `[class]` bindings
- Doesn't apply `[style]` and `[class]` based entries using
  `classList` and `style` (direct attributes are used instead)
- Doesn't split or iterate over all string-based tokens in a
  string value obtained from a `[class]` binding.

This patch speeds up the following cases:
- `<div [class]>` and `<div class="..." [class]>`
- `<div [style]>` and `<div style="..." [style]>`

The overall speec increase is by over 5x.

PR Close #33336
2019-10-24 17:42:46 -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