Commit Graph

522 Commits

Author SHA1 Message Date
Ben Lesh 33963ca0d3 feat(ivy): add property instruction (#29513)
- Adds `property` instruction
- Does _NOT_ add compiler changes to accommodate `property` instruction, that will be a follow up PR.
- Updates `select` instruction to set the selected index in state.
- Adds dev mode assertions around the selected index state.

Related #29527

PR Close #29513
2019-03-28 15:22:37 -07:00
Miško Hevery 931d356a10 Revert "feat(ivy): add property instruction (#29513)"
This reverts commit e4c1c88cbc.
2019-03-27 16:11:04 -07:00
Ben Lesh e4c1c88cbc feat(ivy): add property instruction (#29513)
- Adds `property` instruction
- Does _NOT_ add compiler changes to accommodate `property` instruction, that will be a follow up PR.
- Updates `select` instruction to set the selected index in state.
- Adds dev mode assertions around the selected index state.

Related #29527

PR Close #29513
2019-03-27 13:49:01 -07:00
Pawel Kozlowski dd69e4e780 refactor(ivy): remove duplicated flatten util (#29547)
This commit removes code duplication where we had 2 versions of a
`flatten` utility. Moreover this change results in queries using
a non-recursive version of `flatten` which should result in a better
performance of query refresh operations.

PR Close #29547
2019-03-27 12:36:23 -07:00
Ben Lesh a2f8f5595f refactor(ivy): rename flushHooksUpTo to select (#29527)
PR Close #29527
2019-03-27 09:35:55 -07:00
Marc Laval c412374854 fix(ivy): DebugNode.query should query nodes in the logical tree (#29480)
PR Close #29480
2019-03-26 12:48:37 -07:00
Marc Laval 66b72bfa58 fix(ivy): ViewContainerRef.destroy should properly clean the DOM (#29414)
PR Close #29414
2019-03-22 13:13:12 -07:00
Matias Niemelä 8714daf276 fix(ivy): introduce host-specific styling instructions (#29292)
This patch is the first of a few patches which separates the
styling logic between template bindings (e.g. <div [style])
from host bindings (e.g. @HostBinding('style')). This patch
in particular introduces a series of host-specific styling
instructions and changes the existing set of template styling
instructions not to accept directives. The underyling code (which
communicates with the styling algorithm) still works as it did
before.

This PR also separates the styling instruction code into a separate
file and moves over all other instructions into an dedicated
instructions directory.

PR Close #29292
2019-03-19 16:33:39 -04:00
Matias Niemelä d5e3f2c64b refactor(ivy): move instructions into separate directory (#29292)
PR Close #29292
2019-03-19 16:33:39 -04:00
Ben Lesh d87b035ebb refactor(ivy): Update query-related comments (#29342)
Just updating comments in query-related things to make it easier for the next person that has to grok this for the first time.

Also adds a demo from @mhevery to one of the query specs

Related #29031

PR Close #29342
2019-03-18 17:37:20 -04:00
Matias Niemelä b759d63389 revert: refactor(ivy): Update query-related comments (#29342) 2019-03-18 13:39:10 -07:00
Ben Lesh fe759ee0cf refactor(ivy): Update query-related comments (#29342)
Just updating comments in query-related things to make it easier for the next person that has to grok this for the first time.

Also adds a demo from @mhevery to one of the query specs

Related #29031

PR Close #29342
2019-03-18 15:09:03 -04:00
Kristiyan Kostadinov 3d5b98631a fix(ivy): listeners inherited twice if sub class has own propMetadata (#29353)
Fixes host listeners being inherited twice, if the sub class has its own `propMetadata`. This is related to #29170 which fixed something similar, however all of the test cases there had a super class with some metadata and a sub class that didn't have any. The issue manifested itself in the `MatTreeToggle` which inherits a listener from the `CdkTreeToggle` and adds an extra `Input` of its own, causing the listener to be added twice.

PR Close #29353
2019-03-18 07:16:40 -07:00
Olivier Combe 7c297e05f3 fix(ivy): correctly remove placeholders inside of *ngFor with runtime i18n (#29308)
Following my previous change for placeholders removal, some special code that was used to find the last created node was no longer needed and had wrong interactions with the *ngFor directive.
Removing it fixed the issue.
PR Close #29308
2019-03-14 16:47:09 -04:00
Kristiyan Kostadinov 0ffa2f2e73 fix(ivy): unable to inherit view queries into component from directive (#29203)
Fixes components not being able to inherit their view queries from a directive.

This PR resolves FW-1146.

PR Close #29203
2019-03-13 17:12:14 -04:00
Alex Rickabaugh 73da2792c9 fix(ivy): properly compile NgModules with forward referenced types (#29198)
Previously, ngtsc would resolve forward references while evaluating the
bootstrap, declaration, imports, and exports fields of NgModule types.
However, when generating the resulting ngModuleDef, the forward nature of
these references was not taken into consideration, and so the generated JS
code would incorrectly reference types not yet declared.

This commit fixes this issue by introducing function closures in the
NgModuleDef type, similarly to how NgComponentDef uses them for forward
declarations of its directives and pipes arrays. ngtsc will then generate
closures when required, and the runtime will unwrap them if present.

PR Close #29198
2019-03-12 18:26:42 -07:00
Olivier Combe 7315a68ac6 fix(ivy): only remove missing placeholders with runtime i18n (#29252)
Dynamic nodes are created at the end of the view stack, but we were removing all the placeholders between `i18nStart` and the last created node index, instead of removing everything between `i18nStart` and `i18nEnd`. This caused errors when dynamic nodes where created in multiple i18n blocks because we would remove all of the dynamic nodes created in the previous i18n blocks.
PR Close #29252
2019-03-12 11:46:44 -07:00
Kristiyan Kostadinov a746b5b1ea fix(ivy): inherited host listeners called twice (#29170)
Fixes host listeners being inherited twice when going through `setClassMetadata`.

This PR resolves FW-1142.

PR Close #29170
2019-03-08 11:57:58 -08:00
Pete Bacon Darwin f535f31d78 fix(ivy): match attribute selectors for content projection with inline-templates (#29041)
The content projection mechanism is static, in that it only looks at the static
template nodes before directives are matched and change detection is run.
When you have a selector-based content projection the selection is based
on nodes that are available in the template.

For example:

```
<ng-content selector="[some-attr]"></ng-content>
```

would match

```
<div some-attr="..."></div>
```

If you have an inline-template in your projected nodes. For example:

```
<div *ngIf="..." some-attr="..."></div>
```

This gets pre-parsed and converted to a canonical form.

For example:

```
<ng-template [ngIf]="...">
  <div some-attr=".."></div>
</ng-template>
```

Note that only structural attributes (e.g. `*ngIf`) stay with the `<ng-template>`
node. The other attributes move to the contained element inside the template.

When this happens in ivy, the ng-template content is removed
from the component template function and is compiled into its own
template function. But this means that the information about the
attributes that were on the content are lost and the projection
selection mechanism is unable to match the original
`<div *ngIf="..." some-attr>`.

This commit adds support for this in ivy. Attributes are separated into three
groups (Bindings, Templates and "other"). For inline-templates the Bindings
and "other" types are hoisted back from the contained node to the `template()`
instruction, so that they can be used in content projection matching.

PR Close #29041
2019-03-07 11:27:36 -08:00
Pete Bacon Darwin 423ac01dcf refactor: rename `AttributeMarker.ProjectOnly` to `AttributeMarker.Bindings` (#29041)
PR Close #29041
2019-03-07 11:27:35 -08:00
Marc Laval 25166d4f41 fix(ivy): support property values changed in ngOnChanges (forward rref case) (#29054)
PR Close #29054
2019-03-05 14:27:08 -08:00
Matias Niemelä 78adcfe0ee fix(ivy): ensure static styling is properly inherited into child components (#29015)
Angular supports having a component extend off of a parent component.
When this happens, all annotation-level data is inherited including styles
and classes. Up until now, Ivy only paid attention to static styling
values on the parent component and not the child component. This patch
ensures that both the parent's component and child component's styling
data is merged and rendered accordingly.

Jira Issue: FW-1081

PR Close #29015
2019-03-04 13:36:19 -08:00
Greg Magolan ea09430039 build: rules_nodejs 0.26.0 & use @npm instead of @ngdeps now that downstream angular build uses angular bundles (#28871)
PR Close #28871
2019-02-28 12:06:36 -08:00
George Kalpakas 2dd44d712d ci(core): fix `legacy-unit-tests-saucelabs` job (#29009)
Karma is not configured to retrieve the imported scripts using those
absolute deep paths. Using relative paths instead.
See [here][1] for an example failing job.

[1]: https://circleci.com/gh/angular/angular/220751

PR Close #29009
2019-02-27 10:32:40 -08:00
Wassim Chegham ce68b4d839 style: enforce buildifier lint on CI (#28186)
PR Close #28186
2019-02-26 16:57:41 -08:00
Misko Hevery 3cb497c6ac refactor(ivy): simplify differentiation of LView, `RNode`, `LView`, `LContainer`, `StylingContext` (#28947)
For efficiency reasons we often put several different data types (`RNode`, `LView`, `LContainer`,
`StylingContext`) in same location in `LView`. This is because we don't want to pre-allocate
space
for it because the storage is sparse. This file contains utilities for dealing with such data
types.
How do we know what is stored at a given location in `LView`.
- `Array.isArray(value) === false` => `RNode` (The normal storage value)
- `Array.isArray(value) === true` => than the `value[0]` represents the wrapped value.
  - `typeof value[TYPE] === 'object'` => `LView`
     - This happens when we have a component at a given location
  - `typeof value[TYPE] === 'number'` => `StylingContext`
     - This happens when we have style/class binding at a given location.
  - `typeof value[TYPE] === true` => `LContainer`
     - This happens when we have `LContainer` binding at a given location.
NOTE: it is assumed that `Array.isArray` and `typeof` operations are very efficient.

PR Close #28947
2019-02-26 02:01:07 +00:00
Misko Hevery bd65f58784 refactor(ivy): moved wrapped reference to 0 position in array (#28947)
`LView`, `LContainer`, `StylingContext` are all arrays which wrap either
an `HTMLElement`, `LView`, `LContainer`, `StylingContext`. It is often
necessary to retrieve the correct type of element from the location
which means that we often have to wrap the arrays. Logically it makes
more sense if the thing  which we are wrapping is at `0` location. Also
it may be more performant since data is more local which may result in
more L2 cache hits in CPU.
PR Close #28947
2019-02-26 02:01:07 +00:00
Misko Hevery 22880eae16 feat(ivy): add debug view of internal deta structures (#28945)
This change contains conditionally attached classes which provide human readable (debug) level
information for `LView`, `LContainer` and other internal data structures. These data structures
are stored internally as array which makes it very difficult during debugging to reason about the
current state of the system.

Patching the array with extra property does change the array's hidden class' but it does not
change the cost of access, therefore this patching should not have significant if any impact in
`ngDevMode` mode. (see: https://jsperf.com/array-vs-monkey-patch-array)

So instead of seeing:

```
Array(30) [Object, 659, null, …]
```

```
LViewDebug {
  views: [...],
  flags: {attached: true, ...}
  nodes: [
    {html: '<div id="123">', ..., nodes: [
      {html: '<span>', ..., nodes: null}
    ]}
  ]
}
```

PR Close #28945
2019-02-25 08:15:35 -08:00
Ben Lesh c64b13e593 refactor(ivy): split util functions into different files (#28382)
Google3 detected circular references here, so splitting up this rather hodge-podge list of functions into slightly better organizational units.

PR Close #28382
2019-02-22 13:17:30 -08:00
Kristiyan Kostadinov 32ae84da28 fixup! fix(ivy): incorrectly remapping certain properties that refer to inputs (#28765)
PR Close #28765
2019-02-21 17:59:50 -08:00
Kristiyan Kostadinov 93a7836f7a fix(ivy): incorrectly remapping certain properties that refer inputs (#28765)
During build time we remap particular property bindings, because their names don't match their attribute equivalents (e.g. the property for the `for` attribute is called `htmlFor`). This breaks down if the particular element has an input that has the same name, because the property gets mapped to something invalid.

The following changes address the issue by mapping the name during runtime, because that's when directives are resolved and we know all of the inputs that are associated with a particular element.

PR Close #28765
2019-02-21 17:59:50 -08:00
Kristiyan Kostadinov e1aaa7ec48 fix(ivy): component destroy hook called twice when configured as provider (#28470)
Fixes the `ngOnDestroy` hook on a component or directive being called twice, if the type is also registered as a provider.

This PR resolves FW-1010.

PR Close #28470
2019-02-21 09:34:26 -08:00
Matias Niemelä cfb2d176f8 feat(ivy): convert [ngStyle] and [ngClass] to use ivy styling bindings (#28711)
Prior to this fix, both the `NgStyle` and `NgClass` directives made use
of `Renderer2` and this dependency raised issues for future versions of
Angular that cannot inject it. This patch ensures that there are two
versions of both directives: one for the VE and another for Ivy.

Jira Issue: FW-882

PR Close #28711
2019-02-20 13:46:15 -08:00
Greg Magolan 67ad8a2632 build: move rxjs type reference to event emitter (#28720)
PR Close #28720
2019-02-19 16:28:14 -08:00
Greg Magolan 25aae64274 build(bazel): do not build rxjs from source under Bazel (#28720)
PR Close #28720
2019-02-19 16:28:14 -08:00
Olivier Combe ad6475ffac fix(ivy): re-create node links after creating/moving/removing nodes with i18n (#28827)
I18n can change the order of the nodes, or insert new dynamic nodes. When that happens it can break the existing links (`TNode.next`) or even create loops:
```
div1 → div2 → div3 → div4 → div5
```

Can become:
```
div1 → div4 → div2 → div3  div5
         🡑             │
         └─────────────┘
```

This PR fixes this issue by recreating the broken links between those nodes.
PR Close #28827
2019-02-19 15:54:33 -08:00
Kara Erickson a4638d5a81 fix(ivy): support static ViewChild queries (#28811)
This commit adds support for the `static: true` flag in
`ViewChild` queries. Prior to this commit, all `ViewChild`
queries were resolved after change detection ran. This is
a problem for backwards compatibility because View Engine
also supported "static" queries which would resolve before
change detection.

Now if users add a `static: true` option, the query will be
resolved in creation mode (before change detection runs).
For example:

```ts
@ViewChild(TemplateRef, {static: true}) template !: TemplateRef;
```

This feature will come in handy for components that need
to create components dynamically.

PR Close #28811
2019-02-19 15:29:00 -08:00
Kristiyan Kostadinov 80a5934af6 fix(ivy): support schemas at runtime (#28637)
Accounts for schemas in when validating properties in Ivy.

This PR resolves FW-819.

A couple of notes:
* I had to rework the test slightly, in order to have it fail when we expect it to. The one in master is passing since Ivy's validation runs during the update phase, rather than creation.
* I had to deviate from the design in FW-819 and not add an `enableSchema` instruction, because the schema is part of the `NgModule` scope, however the scope is only assigned to a component once all of the module's declarations have been resolved and some of them can be async. Instead, I opted to have the `schemas` on the component definition.

PR Close #28637
2019-02-14 19:31:51 +00:00
Matias Niemelä 627cecdfe2 fix(ivy): ensure host bindings and host styling works on a root component (#28664)
Prior to this fix if a root component was instantiated it create host
bindings, but never render them once update mode ran unless one or more
slot-allocated bindings were issued. Since styling in Ivy does not make
use of LView slots, the host bindings function never ran on the root
component.

This fix ensures that the `hostBindings` function does run for a root
component and also renders the schedlued styling instructions when
executed.

Jira Issue: FW-1062

PR Close #28664
2019-02-14 19:23:25 +00:00
Andrew Kushnir 39d0311e4e refactor(ivy): combine contentQueries and contentQueriesRefresh functions (#28503)
Prior to this update we had separate contentQueries and contentQueriesRefresh functions to handle creation and update phases. This approach was inconsistent with View Queries, Host Bindings and Template functions that we generate for Component/Directive defs. Now the mentioned 2 functions are combines into one (contentQueries), creation and update logic is separated with RenderFlags (similar to what we have in other generated functions).

PR Close #28503
2019-02-13 12:01:32 -08:00
JoostK 06ec95f2ef fix(ivy): allow directive inheritance in strict mode (#28634)
For TypeScript compilation units that have the "strictFunctionTypes"
option enabled, an error would be produced for Ivy's definition fields
in declaration files in the case of inheritance across directives or
pipes.

This change loosens the definition types to allow for subtypes of the
defined type where necessary.

A test package that has the "strict" option enabled verifies that we
won't regress in environments where strict type checking is enabled.

Fixes #28079

PR Close #28634
2019-02-13 09:50:15 -08:00
Marc Laval 94b8aaeba8 fix(ivy): ngOnChanges should be inherited from super class (#28563)
PR Close #28563
2019-02-11 16:22:31 -08:00
Matias Niemelä fe8301c462 feat(ivy): provide support for map-based host bindings for [style] and [class] (#28246)
Up until now, `[style]` and `[class]` bindings (the map-based ones) have only
worked as template bindings and have not been supported at all inside of host
bindings. This patch ensures that multiple host binding sources (components and
directives) all properly assign style values and merge them correctly in terms
of priority.

Jira: FW-882

PR Close #28246
2019-02-11 16:21:19 -08:00
Pawel Kozlowski e9bedc63bb fix(ivy): properly query root nodes of embedded views(shallow queries) (#28560)
PR Close #28560
2019-02-08 16:42:45 -08:00
Olivier Combe 9d109929be fix(ivy): remove nested placeholders with i18n (#28595)
PR Close #28595
2019-02-07 16:56:36 -08:00
Kara Erickson 1950e2d9ba fix(ivy): throw on bindings to unknown properties (#28537)
This commit adds a devMode-only check which will throw if a user
attempts to bind a property that does not match a directive
input or a known HTML property.

Example:
```
<div [unknownProp]="someValue"></div>
```

The above will throw because "unknownProp" is not a known
property of HTMLDivElement.

This check is similar to the check executed in View Engine during
template parsing, but occurs at runtime instead of compile-time.

Note: This change uncovered an existing bug with host binding
inheritance, so some Material tests had to be turned off. They
will be fixed in an upcoming PR.

PR Close #28537
2019-02-07 12:37:32 -08:00
Andrew Kushnir 7660d0d74a fix(ivy): extended next pointer lookup while traversing tNode tree (#28533)
Prior to this change we only checked whether current lView has a next pointer while traversing tNode tree. However in some cases this pointer can be undefined and we need to look up parents chain to find suitable next pointer. This commit adds the logic of searching for the next pointer taking parents chain into account.

PR Close #28533
2019-02-07 12:37:13 -08:00
Miško Hevery 62a13e795a refactor(ivy): pass host into createLView explicitly (#28461)
`LView` `HOST` was set in most cases right after creating `LView`.
This makes the API cleaner by explicitly passing it ont `createLView`.

PR Close #28461
2019-02-06 00:24:24 -05:00
Kara Erickson 8f15cdbc7c test(ivy): move some local ref tests to use TestBed infrastructure. (#28534)
When we first started writing tests for Ivy, we did not yet have a
compatible compiler. For this reason, we set up the Ivy runtime tests
to run with generated code that we wrote by hand (instead of real code
generated by the compiler).

Now that we have a working Ivy compiler and TestBed infrastructure
that is compatible with Ivy, we should start writing integration
tests that leverage them (no more handwritten generated code!). This
will prevent bugs where the compiler code and runtime code become
out of sync (which is easy if they are tested separately). And
eventually, we should migrate all the existing runtime tests in
"core/test/render3" to TestBed and ngtsc.

To kick off this effort, this commit migrates some existing tests
from "core/test/render3/exports_spec.ts" and saves them in a new file
with the same name in the "core/test/acceptance" folder.

PR Close #28534
2019-02-05 23:31:08 -05:00
Olivier Combe baf103c98f fix(ivy): don't increment `expandoStartIndex` after directives are matched (#28424)
i18n instructions create text nodes dynamically and save them between bindings and the expando block in `LView`. e.g., they try to create the following order in `LView`.

```
| -- elements -- | -- bindings -- | -- dynamic i18n text -- | -- expando (dirs, injectors) -- |
```

Each time a new text node is created, it is pushed to the end of the array and the `expandoStartIndex` marker is incremented, so the section begins slightly later. This happens in `allocExpando`.

This is fine if no directives have been created yet. The end of the array will be in the "dynamic text node" section.

| -- elements -- | -- bindings -- | -- dynamic i18n text -- |

However, this approach doesn't work if dynamic text nodes are created after directives are matched (for example when the directive uses host bindings). In that case, there are already directives and injectors saved in the "expando" section. So pushing to the end of `LView` actually pushes after the expando section. What we get is this:

```
| -- elements -- | -- bindings -- | -- dynamic i18n text -- | -- expando -- | -- dynamic i18n text-- |
```

In this case, the `expandoStartIndex` shouldn't be incremented because we are not inserting anything before the expando section (it's now after the expando section). But because it is incremented in the code right now, it's now pointing to an index in the middle of the expando section.

This PR fixes that so that we only increment the `expandoStartIndex` if nothing was pushed into the expando section.

FW-978 #resolve

PR Close #28424
2019-02-05 23:30:37 -05:00