294 Commits

Author SHA1 Message Date
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
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ä
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
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
Pawel Kozlowski
4452d6d848 perf(ivy): avoid repeated tNode.initialInputs reads (#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
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
Miško Hevery
9ea3430a5b style: correct comments (#33178)
PR Close #33178
2019-10-24 14:42:15 -07:00
Igor Minar
86e1e6c082 feat: typescript 3.6 support (#32946)
BREAKING CHANGE: typescript 3.4 and 3.5 are no longer supported, please update to typescript 3.6

Fixes #32380

PR Close #32946
2019-10-18 13:15:16 -04:00
Matias Niemelä
f45c43188f fix(ivy): ensure errors are thrown during checkNoChanges for style/class bindings (#33103)
Prior to this fix, all style/class bindings (e.g. `[style]` and
`[class.foo]`) would quietly update a binding value if and when the
current binding value changes during checkNoChanges.

With this patch, all styling instructions will properly check to see
if the value has changed during the second pass of detectChanges()
if checkNoChanges is active.

PR Close #33103
2019-10-17 16:46:49 -04:00
Kara Erickson
d62eff7316 refactor(core): rename ngPipeDef to ɵpipe (#33142)
Pipe defs are not considered public API, so the property
that contains them should be prefixed with Angular's marker
for "private" ('ɵ') to discourage apps from relying on def
APIs directly.

This commit adds the prefix and shortens the name from
ngPipeDef to pipe. This is because property names
cannot be minified by Uglify without turning on property
mangling (which most apps have turned off) and are thus
size-sensitive.

PR Close #33142
2019-10-14 23:08:10 +00:00
Kara Erickson
0de2a5e408 refactor(core): rename ngFactoryDef to ɵfac (#33116)
Factory defs are not considered public API, so the property
that contains them should be prefixed with Angular's marker
for "private" ('ɵ') to discourage apps from relying on def
APIs directly.

This commit adds the prefix and shortens the name from
ngFactoryDef to fac. This is because property names
cannot be minified by Uglify without turning on property
mangling (which most apps have turned off) and are thus
size-sensitive.

Note that the other "defs" (ngPipeDef, etc) will be
prefixed and shortened in follow-up PRs, in an attempt to
limit how large and conflict-y this change is.

PR Close #33116
2019-10-14 20:27:25 +00:00
Kara Erickson
1a67d70bf8 refactor(core): rename ngDirectiveDef to ɵdir (#33110)
Directive defs are not considered public API, so the property
that contains them should be prefixed with Angular's marker
for "private" ('ɵ') to discourage apps from relying on def
APIs directly.

This commit adds the prefix and shortens the name from
ngDirectiveDef to dir. This is because property names
cannot be minified by Uglify without turning on property
mangling (which most apps have turned off) and are thus
size-sensitive.

Note that the other "defs" (ngFactoryDef, etc) will be
prefixed and shortened in follow-up PRs, in an attempt to
limit how large and conflict-y this change is.

PR Close #33110
2019-10-14 16:20:11 +00:00
Kara Erickson
64fd0d6db9 refactor(core): rename ngComponentDef to ɵcmp (#33088)
Component defs are not considered public API, so the property
that contains them should be prefixed with Angular's marker
for "private" ('ɵ') to discourage apps from relying on def
APIs directly.

This commit adds the prefix and shortens the name from
`ngComponentDef` to `cmp`. This is because property names
cannot be minified by Uglify without turning on property
mangling (which most apps have turned off) and are thus
size-sensitive.

Note that the other "defs" (ngDirectiveDef, etc) will be
prefixed and shortened in follow-up PRs, in an attempt to
limit how large and conflict-y this change is.

PR Close #33088
2019-10-11 15:45:22 -07: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
Matias Niemelä
b2decf0266 perf(ivy): speed up bindings when no directives are present (#32919)
Prior to this fix, whenever a style or class binding is present, the
binding application process would require an instance of `TStylingContext`
to be built regardless of whether or not any binding resolution is needed
(just so that it knows whether or not there are any collisions).
This check is, however, unnecessary because if (and only if) there
are directives present on the element then are collisions possible.

This patch removes the need for style/class bindings to register
themselves on to a `TStylingContext` if there are no directives and
present on an element. This means that all map and prop-based
style/class bindings are applied as soon as bindings are updated on
an element.

PR Close #32919
2019-10-10 13:57:24 -07:00
Pawel Kozlowski
8d111da7f6 perf(ivy): use instanceof operator to check for NodeInjectorFactory instances (#33082)
We used to have a custom version of the NodeInjectorFactory check that was
supposed to be faster to the direct usage of the `instanceof` operator. This
might have been the case in the past but the recent benchmark shows that using
`instanceof` speeds up the `directive_instantiate` by ~10%
(from time getting from ~340ms down to ~305ms).

PR Close #33082
2019-10-10 13:56:52 -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
60047037a3 perf(ivy): attempt rendering initial styling only if present (#32979)
PR Close #32979
2019-10-04 11:44:57 -07:00
Martin Probst
5332b04f35 build: TypeScript 3.6 compatibility. (#32908)
This PR updates Angular to compile with TypeScript 3.6 while retaining
compatibility with TS3.5. We achieve this by inserting several `as any`
casts for compatiblity around `ts.CompilerHost` APIs.

PR Close #32908
2019-10-03 09:09:11 -07:00
Matias Niemelä
5d12cb9fdf refactor(ivy): move styling/interfaces.ts to interfaces/styling.ts (#32731)
PR Close #32731
2019-09-18 15:06:39 -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
Pawel Kozlowski
5ab7cb4188 refactor(ivy): remove superfluous bind() function (#32489)
Historically bind() used to be a separate instruction. With a series of
refactoring it became a utility function but after recent code changes
it does not provide any valuable abstraction / help. On the contrary -
it can be seen as a performance problem (forces unnecessary comparison to
`NO_CHANGE` during change detection).

PR Close #32489
2019-09-05 18:08:27 -04:00
Pawel Kozlowski
641c5c1c1e perf(ivy): guard directive-related operations with a TNode flag (#32445)
PR Close #32445
2019-09-04 11:39:57 -07:00
Pawel Kozlowski
a383a5a165 refactor(ivy): simplify property binding metadata storage (#32457)
Since property binding metadata storage is guarded with the ngDevMode now
and several instructions were merged together, we can simplify the way we
store and read property binding metadata.

PR Close #32457
2019-09-04 11:37:35 -07:00
Kristiyan Kostadinov
c885178d5f refactor(ivy): move directive, component and pipe factories to ngFactoryFn (#31953)
Reworks the compiler to output the factories for directives, components and pipes under a new static field called `ngFactoryFn`, instead of the usual `factory` property in their respective defs. This should eventually allow us to inject any kind of decorated class (e.g. a pipe).

**Note:** these changes are the first part of the refactor and they don't include injectables. I decided to leave injectables for a follow-up PR, because there's some more cases we need to handle when it comes to their factories. Furthermore, directives, components and pipes make up most of the compiler output tests that need to be refactored and it'll make follow-up PRs easier to review if the tests are cleaned up now.

This is part of the larger refactor for FW-1468.

PR Close #31953
2019-08-27 13:57:00 -07:00
Miško Hevery
2e4d17f3a9 perf(core): make sanitization tree-shakable in Ivy mode (#31934)
In VE the `Sanitizer` is always available in `BrowserModule` because the VE retrieves it using injection.

In Ivy the injection is optional and we have instructions instead of component definition arrays. The implication of this is that in Ivy the instructions can pull in the sanitizer only when they are working with a property which is known to be unsafe. Because the Injection is optional this works even if no Sanitizer is present. So in Ivy we first use the sanitizer which is pulled in by the instruction, unless one is available through the `Injector` then we use that one instead.

This PR does few things:
1) It makes `Sanitizer` optional in Ivy.
2) It makes `DomSanitizer` tree shakable.
3) It aligns the semantics of Ivy `Sanitizer` with that of the Ivy sanitization rules.
4) It refactors `DomSanitizer` to use same functions as Ivy sanitization for consistency.

PR Close #31934
2019-08-15 10:30:12 -07:00
Matias Niemelä
f50dede8f7 refactor(ivy): remove all old styling code prior to refactor (#31193)
In the previous patch () all the existing styling code was turned
off in favor of using the new refactored ivy styling code. This
patch is a follow up patch to that and removes all old, unused
styling code from the render3 directory.

PR Close #31193
2019-07-23 15:45:32 -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
Miško Hevery
f14693b9a4 refactor(ivy): correct circular dependency which causes g3 failures (#31665)
PR Close #31665
2019-07-19 15:06:46 -07:00
Paul Gschwendtner
dda781ecce fix(ivy): incorrect type definition for ɵɵdefineComponent (#30993)
Currently the `ɵɵdefineComponent` method has incorrect type
definitions the `directives` and `pipes` metadata property.

The incorrect types allow developers to pass in already instantiated
`DirectiveDef` or `ComponentDef` objects. This can cause unexpected
failures because the definition internally only expects `Type` objects
and now incorrectly tries to read the `ngDirectiveDef` or `ngComponentDef`
of existing definitions.

This issue has been unveiled by enabling the strict function parameter
types flag, where the directive definitions are determined from each array
element in the `directives` or `pipes` property (which can throw).

PR Close #30993
2019-07-18 14:21:26 -07:00
Paul Gschwendtner
2200884e55 refactor(core): ensure compatibility with typescript strict flag (#30993)
As part of FW-1265, the `@angular/core` package is made compatible
with the TypeScript `--strict` flag. This already unveiled a few bugs,
so the strictness flag seems to help with increasing the overall code health.

Read more about the strict flag [here](https://www.typescriptlang.org/docs/handbook/compiler-options.html)

PR Close #30993
2019-07-18 14:21:25 -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
Misko Hevery
29a9909232 refactor(ivy): simplify walkTNodeTree method for readability (#31182)
PR Close #31182
2019-06-25 17:03:51 -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
dc613b336d refactor(ivy): removing unused properties from i18n interfaces (#31171)
Fixes #31165
PR Close #31171
2019-06-20 18:46:20 -07:00
Alex Rickabaugh
0ee09cdd7e refactor(ivy): fix type of factory functions to allow explicit types (#30855)
Factory functions written by the compiler optionally allow an explicit type
to be passed. If called with this type, an instance of the given type will
be created instead of the type for which the factory was generated. This is
used to power inheritance of Angular types, as if the constructor of a class
is inherited from its superclass, then the factory function of the
superclass must be used (it has all the DI info) to construct an instance of
the derived class.

This commit adjusts typings in a few places to allow factory functions to be
called with this extra type parameter.

PR Close #30855
2019-06-11 14:27:17 -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
Pawel Kozlowski
8154433130 perf(ivy): limit allocation of LQueries_ objects (#30664)
Before this change we would systematically call LQueries.clone() when executting
elementStart / elementContainerStart instructions. This was often unnecessary as
LQueries can be mutated under 2 conditions only:
- we are crossing an element that has directives with content queries
  (new queries must be added);
- we are descending into element hierarchy (creating a child element of an existing element)
  and the current LQueries object is tracking shallow queries (shallow queries are removed).

With this PR LQueires.clone() is only done when needed and this gratelly reduces number
of LQueries object created: in the "expanding rows" benchmark number of allocated
(and often GCed just after!) LQueries is reduced from ~100k -> ~35k. This represents
over 1MB of memory that is not allocated.

PR Close #30664
2019-06-03 12:01:35 -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
Olivier Combe
53c6b78c51 feat(ivy): add AttributeMarker.I18n for i18n attributes (#30402)
`i18nAttributes` instructions always occur after the element instruction. This means that we need to treat `i18n-` attributes differently.
By defining a specific `AttributeMarker` we can ensure that we won't trigger directive inputs with untranslated attribute values.

FW-1332 #resolve
PR Close #30402
2019-05-30 16:39:24 -04:00
Ben Lesh
d7eaae6f22 refactor(ivy): Move instructions back to ɵɵ (#30546)
There is an encoding issue with using delta `Δ`, where the browser will attempt to detect the file encoding if the character set is not explicitly declared on a `<script/>` tag, and Chrome will find the `Δ` character and decide it is window-1252 encoding, which misinterprets the `Δ` character to be some other character that is not a valid JS identifier character

So back to the frog eyes we go.

```
    __
   /ɵɵ\
  ( -- ) - I am ineffable. I am forever.
 _/    \_
/  \  /  \
==  ==  ==
```

PR Close #30546
2019-05-20 16:37:47 -07:00
Miško Hevery
6454f76cf6 refactor(ivy): remove ngPrivateData megamorphic prop access (#30548)
PR Close #30548
2019-05-20 10:12:07 -07:00
Matias Niemelä
f03475cac8 refactor(ivy): evaluate prop-based styling bindings with a new algorithm (#30469)
This is the first refactor PR designed to change how styling bindings
(i.e. `[style]` and `[class]`) behave in Ivy. Instead of having a heavy
element-by-element context be generated for each element, this new
refactor aims to use a single context for each `tNode` element that is
examined and iterated over when styling values are to be applied to the
element.

This patch brings this new functionality to prop-based bindings such as
`[style.prop]` and `[class.name]`.

PR Close #30469
2019-05-17 09:54:19 -07:00