The current logic pulls multiproviders up to the parent module's
provider list. The result is that the multi provider being defined both in
the imported ModuleWithProviders and the parent and getting an extra
item in the multi provided array of values. This PR fixes that problem
by not pulling providers in ModuleWithProviders up to the parent module.
PR Close#34914
We had some logic for generating and passing in the `elIndex` parameter into the `hostBindings` function, but it wasn't actually being used for anything. The only place left that had a reference to it was the `StylingBuilder` and it only stored it without referencing it again.
PR Close#34969
Previously we would write to class/style as strings `element.className` and `element.style.cssText`. Turns out that approach is good for initial render but not good for updates. Updates using this approach are problematic because we have to check to see if there was an out of bound write to style and than perform reconciliation. This also requires the browser to bring up CSS parser which is expensive.
Another problem with old approach is that we had to queue the DOM writes and flush them twice. Once on element advance instruction and once in `hostBindings`. The double flushing is expensive but it also means that a directive can observe that styles are not yet written (they are written after directive executes.)
The new approach uses `element.classList.add/remove` and `element.style.setProperty/removeProperty` API for updates only (it continues to use `element.className` and `element.style.cssText` for initial render as it is cheaper.) The other change is that the styling changes are applied immediately (no queueing). This means that it is the instruction which computes priority. In some circumstances it may result in intermediate writes which are than overwritten with new value. (This should be rare)
Overall this change deletes most of the previous code and replaces it with new simplified implement. The simplification results in code savings.
PR Close#34804
This change introduces several functions for manipulating items in an array in an efficient (binary search) way.
- `arraySplice` a faster version of `Array.splice()`.
- `arrayInsert` a faster version of `Array.splice(index, 0, value)`.
- `arrayInsert2` a faster version of `Array.splice(index, 0, value1, value2)`.
- `arrayInsertSorted` a way to insert a value into sorted list.
- `arrayRemoveSorted` a way to remove a value from a sorted list.
- `arrayIndexOfSorted` a way to find a value in a sorted list.
- `ArrayMap` Efficient implementation of `Map` as an `Array`.
- `arrayMapSet`, `arrayMapGet`, `arrayMapIndexOf`, and `arrayMapDelete` for manipulating `ArrayMap`s.
PR Close#34804
NOTE: This change must be reverted with previous deletes so that it code remains in build-able state.
This change deletes old styling code and replaces it with a simplified styling algorithm.
The mental model for the new algorithm is:
- Create a linked list of styling bindings in the order of priority. All styling bindings ere executed in compiled order and than a linked list of bindings is created in priority order.
- Flush the style bindings at the end of `advance()` instruction. This implies that there are two flush events. One at the end of template `advance` instruction in the template. Second one at the end of `hostBindings` `advance` instruction when processing host bindings (if any).
- Each binding instructions effectively updates the string to represent the string at that location. Because most of the bindings are additive, this is a cheap strategy in most cases. In rare cases the strategy requires removing tokens from the styling up to this point. (We expect that to be rare case)S Because, the bindings are presorted in the order of priority, it is safe to resume the processing of the concatenated string from the last change binding.
PR Close#34616
NOTE: This change deletes code and creates a BROKEN SHA. If reverting this SHA needs to be reverted with the next SHA to get back into a valid state.
PR Close#34616
The `computeStaticStyling` will be used for computing static styling value during `firstCreatePass`.
The function takes into account static styling from the template as well as from the host bindings. The host bindings need to be merged in front of the template so that they have the correct priority.
PR Closes#34418
Parsing styling is now simplified to be used like so:
```
for (let i = parseStyle(text); i <= 0; i = parseStyleNext(text, i)) {
const key = getLastParsedKey();
const value = getLastParsedValue();
...
}
```
This change makes it easier to invoke the parser from other locations in the system without paying the cost of creating and iterating over `Map` of styles.
PR Closes#34418
This change moves information from instructions to declarative position:
- `ɵɵallocHostVars(vars)` => `DirectiveDef.hostVars`
- `ɵɵelementHostAttrs(attrs)` => `DirectiveDef.hostAttrs`
When merging directives it is necessary to know about `hostVars` and `hostAttrs`. Before this change the information was stored in the `hostBindings` function. This was problematic, because in order to get to the information the `hostBindings` would have to be executed. In order for `hostBindings` to be executed the directives would have to be instantiated. This means that the directive instantiation would happen before we had knowledge about the `hostAttrs` and as a result the directive could observe in the constructor that not all of the `hostAttrs` have been applied. This further complicates the runtime as we have to apply `hostAttrs` in parts over many invocations.
`ɵɵallocHostVars` was unnecessarily complicated because it would have to update the `LView` (and Blueprint) while existing directives are already executing. By moving it out of `hostBindings` function we can access it statically and we can create correct `LView` (and Blueprint) in a single pass.
This change only changes how the instructions are generated, but does not change the runtime much. (We cheat by emulating the old behavior by calling `ɵɵallocHostVars` and `ɵɵelementHostAttrs`) Subsequent change will refactor the runtime to take advantage of the static information.
PR Close#34683
This adds `insertTStyleValue` but does not hook it up to anything yet.
The purpose of this function is to create a linked-list of styling
related bindings. The bindings can be traversed during flush.
The linked list also keeps track of duplicates. This is important
for binding to know if it needs to check other styles for reconciliation.
PR Close#34004
This change introduces class/style reconciliation algorithm for DOM elements.
NOTE: The code is not yet hooked up, it will be used by future style algorithm.
Background:
Styling algorithm currently has [two paths](https://hackmd.io/@5zDGNGArSxiHhgvxRGrg-g/rycZk3N5S)
when computing how the style should be rendered.
1. A direct path which concatenates styling and uses `elemnent.className`/`element.style.cssText` and
2. A merge path which uses internal data structures and uses `element.classList.add/remove`/`element.style[property]`.
The situation is confusing and hard to follow/maintain. So a future PR will remove the merge-path and do everything with
direct-path. This however breaks when some other code adds class or style to the element without Angular's knowledge.
If this happens instead of switching from direct-path to merge-path algorithm, this change provides a different mental model
whereby we always do `direct-path` but the code which writes to the DOM detects the situation and reconciles the out of bound write.
The reconciliation process is as follows:
1. Detect that no one has modified `className`/`cssText` and if so just write directly (fast path).
2. If out of bounds write did occur, switch from writing using `className`/`cssText` to `element.classList.add/remove`/`element.style[property]`.
This does require that the write function computes the difference between the previous Angular expected state and current Angular state.
(This requires a parser. The advantage of having a parser is that we can support `style="width: {{exp}}px" kind of bindings.`)
Compute the diff and apply it in non destructive way using `element.classList.add/remove`/`element.style[property]`
Properties of approach:
- If no out of bounds style modification:
- Very fast code path: Just concatenate string in right order and write them to DOM.
- Class list order is preserved
- If out of bounds style modification detected:
- Penalty for parsing
- Switch to non destructive modification: `element.classList.add/remove`/`element.style[property]`
- Switch to alphabetical way of setting classes.
PR Close#34004
Fixes Ivy detecting changes inside child embedded views, even though they're detached.
Note that there's on subtlety here: I made the changes inside `refreshDynamicEmbeddedViews` rather than `refreshView`, because we support detecting changes on a detached view (evidenced by a couple of unit tests), but only if it's triggered directly from the view's `ChangeDetectorRef`, however we shouldn't be detecting changes in the detached child view when something happens in the parent.
Fixes#34816.
PR Close#34846
by DebugElement.triggerEventHandler. ZoneJS tracks the eventListeners on
a node but we need to be able to differentiate between those added by
Angular and those that were added outside the Angular context. This fix
aligns with the behavior that was present in View Engine (not calling
those listeners). If we decide later that we want to call those
listeners, we still need a way to differentiate between those that
we have wrapped in dom_renderer and those that were not (because they
were added outside the Angular context).
PR Close#34514
Fixes Ivy throwing an error when trying to access the `DebugNode.classes` of an SVG element. The problem is that the `className` of an SVG element is an `SVGAnimatedString`, rather than a plain string.
Fixes#34868.
PR Close#34872
This patch removes the need for the styleSanitizer() instruction in
favor of passing the sanitizer into directly into the styleProp
instruction.
This patch also increases the binding index size for all style/class bindings in preparation for #34418
PR Close#34480
In #28162 we introduced an extra `removeNode` call for host elements which can cause the parent element to be removed before all child animations have finished. The issue is only in Ivy, because that the only place where we pass in the `isHostElement` flag. These changes fix the issue by not re-triggering the removal logic if the element has in-progress animations.
Fixes#33597.
PR Close#34702
Before ivy it was possible to configure a mutable service value
in an application initializer (by providing an `APP_INITIALIZER`)
that could be read in the provider of `LOCALE_ID`. This is a common
scenario if you wanted to load the locale id asynchronously from
an HTTP request for instance.
When using the ivy, the runtime needs to be told what the current
locale is, which is done by calling the `setLocaleId()` function with
the value injected by the `LOCALE_ID` token. Previously this was
being done before the application initializers were run, which meant
that the `LOCALE_ID` provider was being executed before the
app initializers had a chance to get a new value for it.
Now this initalization of the locale for the ivy runtime is done after the
application initializers have been run.
Closes#34701
PR Close#34830
This brings in a few minor fixes including a better way to patch require for bootstrap scripts
Also remove install_source_map_support attribute from nodejs_binary targets This attribute will be removed from nodejs_binary in the future
PR Close#34736
The major one that affects the angular repo is the removal of the bootstrap attribute in nodejs_binary, nodejs_test and jasmine_node_test in favor of using templated_args --node_options=--require=/path/to/script. The side-effect of this is that the bootstrap script does not get the require.resolve patches with explicitly loading the targets _loader.js file.
PR Close#34736
Currently ngtsc looks for the first `ConstructorDeclaration` when figuring out what the parameters are so that it can generate the DI instructions. The problem is that if a constructor has overloads, it'll have several `ConstructorDeclaration` members with a different number of parameters. These changes tweak the logic so it looks for the constructor implementation.
PR Close#34590
DebugElement.query also matches elements that may have been created
outside of Angular (ex: with `document.appendChild`). If those matched
DebugElements are in turn used to query for more elements, an error
occurs because the first step in queryAll is to load the LContext.
PR Close#34687
Default currency code in CurrencyPipe is currently hardcoded to USD
and is not configurable. This commit allows the default currency code
to be configurable by adding a DEFAULT_CURRENCY_CODE injection token.
Example:
```
providers: [{ provide: DEFAULT_CURRENCY_CODE, useValue: "GBP" }]
...
{{ 123.45 | currency }} // outputs £123.45 as opposed to always $123.45 before
```
Closes: #25461
PR Close#32584
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
The major one that affects the angular repo is the removal of the bootstrap attribute in nodejs_binary, nodejs_test and jasmine_node_test in favor of using templated_args --node_options=--require=/path/to/script. The side-effect of this is that the bootstrap script does not get the require.resolve patches with explicitly loading the targets _loader.js file.
PR Close#34589
This commit improves `ExpressionChangedAfterChecked` error message for attributes by including attribute name and the content of the entire expression that contains interpolation(s). In order to achieve that, metadata is now stored in `TData` array when `attribute` and `attributeInterpolate` instructions are being called (similar to `property` and `propertyInterpolate` instructions).
PR Close#34505
Fixes classes with trailing or leading space that are passed to `ngClass` (e.g. `{'foo ': bar}`) not being applied in Ivy. The issue comes from the fact that when the styling differ builds up the style map it uses the trimmed key to look up the value in the map that uses non-trimmed keys.
Fixes#34476.
PR Close#34539
Follow-up from [this discussion](https://github.com/angular/angular/pull/33419#discussion_r339296216). In Ivy we don't use the schema to validate tag names, but instead we use feature detection to figure out whether an element is supported. While this should generally be more accurate, it'll also end up throwing for some more innocent cases. E.g. now Ivy throws an error for `main` elements in IE which is accurate since IE doesn't support the element, but is annoying since there is no functionality attached.
These changes switch to logging a warning instead, similarly to what we're doing for unknown properties.
PR Close#34524
The `getProjectAsAttrValue` in `node_selector_matcher` finds the
ProjectAs marker and then additionally checks that the marker appears in
an even index of the node attributes because "attribute names are stored
at even indexes". This is true for "regular" attribute bindings but
classes, styles, bindings, templates, and i18n do not necessarily follow
this rule because there can be an uneven number of them, causing the
next "special" attribute "name" to appear at an odd index. To address
this issue, ensure ngProjectAs is placed right after "regular"
attributes.
PR Close#34617
Prior to this commit, there were no `advance` instructions generated before `i18nExp` instructions and as a result, lifecycle hooks for components used inside i18n blocks were flushed too late. This commit adds the logic to generate `advance` instructions in front of `i18nExp` ones (similar to what we have in other places like interpolations, property bindings, etc), so that the necessary lifecycle hooks are flushed before expression value is captured.
PR Close#34436
The main logic of the `InheritDefinitionFeature` is to go through the prototype chain of a given Component and merge all Angular-specific information onto that Component def. The problem happens in case there is a Component in a hierarchy that also contains the `InheritDefinitionFeature` (i.e. it extends some other Component), so it inherits all Angular-specific information from its super class. As a result, the root Component may end up having duplicate information inherited from different Components in hierarchy.
Let's consider the following structure: `GrandChild` extends `Child` that extends `Base` and the `Base` class has a `HostListener`. In this scenario `GrandChild` and `Child` will have `InheritDefinitionFeature` included into the `features` list. The processing will happend in the following order:
- `Child` inherits `HostListener` from the `Base` class
- `GrandChild` inherits `HostListener` from the `Child` class
- since `Child` has a parent, `GrandChild` also inherits from the `Base` class
The result is that the `GrandChild` def has duplicated host listener, which is not correct.
This commit introduces additional logic that checks whether we came across a def that has `InheritDefinitionFeature` feature (which means that this def already inherited information from its super classes). If that's the case, we skip further fields-related inheritance logic, but keep going though the prototype chain to look for super classes that contain other features (like NgOnChanges), that we need to invoke for a given Component def.
PR Close#34244
Fixes an error that is thrown when a provider is overridden in `TestBed`, if the module definition of one of the imported modules uses a function for the `imports` that is set via `setNgModuleScope`. The problem was that we have a `for...of` loop that assumes that the imports are an array, but they can also be a function. This was handled correctly in other places, but this one was missed.
Note that the above-mentioned error is only thrown at runtime when the code is transpiled to es6. In es5 TS generates a call to a helper that handles the error silently so the attached unit test only fails in es6.
Fixes#34623.
PR Close#34629
Prior to this change, the ExpressionChangedAfterChecked error thrown in Ivy was missing useful information that was available in View Engine, specifically: missing property name for proprty bindings and also the content of the entire property interpolation (only a changed value was displayed) if one of expressions was changed unexpectedly. This commit improves the error message by including the mentioned information into the error text.
PR Close#34381
The ordering matters because we don't currently throw if multiple
configurations are provided (i.e. provider has *both* useExisting and
useFactory). We should actually throw an error in this case, but to
avoid another breaking change in v9, this PR simply aligns the Ivy
behavior with ViewEngine.
PR Close#34433
Currently we only run Saucelabs on PRs using the legacy View Engine
build. Switching that build to Ivy is not trivial and there are various
options:
1. Updating the R3 switches to use POST_R3 by default. At first glance,
this doesn't look easy because the current ngtsc switch logic seems to
be unidirectional (only PRE_R3 to POST_R3).
2. Updating the legacy setup to run with Ivy. This sounds like the easiest
solution at first.. but it turns out to be way more complicated. Packages
would need to be built with ngtsc using legacy tools (i.e. first building
the compiler-cli; and then building packages) and View Engine only tests
would need to be determined and filtered out. Basically it will result in
re-auditing all test targets. This is contradictory to the fact that we have
this information in Bazel already.
3. Creating a new job that runs tests on Saucelabs with Bazel. We specify
fine-grained test targets that should run. This would be a good start
(e.g. acceptance tests) and also would mean that we do not continue maintaining
the legacy setup..
This commit implements the third option as it allows us to move forward
with the general Bazel migration. We don't want to spend too much time
on our legacy setup since it will be removed anyway in the future.
PR Close#34277
When we log DI errors we get the name of the provider via `SomeClass.name`. In IE functions that inherit from other functions don't have their own `name`, but they take the `name` from the lowest parent in the chain, before `Function`. I've added some changes to fall back to parsing out the function name from the function's string form.
PR Close#34305
The way definitions are added in JIT mode is through `Object.defineProperty`, but the problem is that in IE10 properties defined through `defineProperty` won't be inherited which means that inheriting injectable definitions no longer works. These changes add a workaround only for JIT mode where we define a fallback method for retrieving the definition. This isn't ideal, but it should only be required until v10 where we'll no longer support inheriting injectable definitions from undecorated classes.
PR Close#34305
We've got some tests that assert that the generate DOM looks correct. The problem is that IE changes the attribute order in `innerHTML` which caused the tests to fail. I've reworked the relevant tests not to assert directly against `innerHTML`.
PR Close#34305
This commit fixes a couple issues that prevent `class_binding` benchmark from running: moving constants requires by the `benchmark` function before function declaration and referencing correct consts in template instructions.
PR Close#34242
The `ModuleWithProviders` type has an optional type parameter that
should be specified to indicate what NgModule class will be provided.
This enables the Ivy compiler to statically determine the NgModule type
from the declaration files. This type parameter will become required in
the future, however to aid in the migration the compiler will detect
code patterns where using `ModuleWithProviders` as return type is
appropriate, in which case it transforms the emitted .d.ts files to
include the generic type argument.
This should reduce the number of occurrences where `ModuleWithProviders`
is referenced without its generic type argument.
Resolves FW-389
PR Close#34235
Prior to this commit, values wrapped into SafeStyle were not handled correctly in [style.prop] bindings in case style sanitizer is present (when template contains some style props that require sanitization). Style sanitizer was not unwrapping values in case a given prop doesn't require sanitization.As a result, wrapped values were used as final styling values (see https://github.com/angular/angular/blob/master/packages/core/src/render3/styling/bindings.ts#L620). This commit updates the logic to unwrap safe values in sanitizer in case no sanitization is required.
PR Close#34286
Occasionally a factory function needs to be generated for an "invalid"
constructor (one with parameters types which aren't injectable). Typically
this happens in JIT mode where understanding of parameters cannot be done in
the same "up-front" way that the AOT compiler can.
This commit changes the JIT compiler to generate a new `invalidFactoryDep`
call for each invalid parameter. This instruction will error at runtime if
called, indicating both the index of the invalid parameter as well as (via
the stack trace) the factory function which was generated for the type being
constructed.
Fixes#33637
PR Close#33739
In Ivy, if you do:
`TestBed.configureTestingModule({providers: [{provide: Service}]});`
the injector will attempt to inject Service as if it was simply listed
in the providers array like `{providers: [Service]}`
This fixes an inconsistency when similarly providing an override with no
`useValue` or `useFactory`.
PR Close#33769
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
Prior to this commit, there was no check in R3TestBed to verify that metadata is resolved using a given Type. That leads to some cryptic error messages (when TestBed tries to compile a Type without having metadata) in case TestBed override functions receive unexpected Types (for example a Directive is used in `TestBed.overrideComponent` call). This commit adds the necessary checks to verify metadata presence before TestBed tries to (re)compile a Type.
PR Close#34204
Prior to this commit, if a template (for example, generated using structural directive such as *ngIf) contains `ngProjectAs` attribute, it was not included into attributes array in generated code and as a result, these templates were not matched at runtime during content projection. This commit adds the logic to append `ngProjectAs` values into corresponding element's attribute arrays, so content projection works as expected.
PR Close#34200
Prior to this commit, i18n runtime code failed with the exception saying that no provider was found for ChangeDetectorRef for a pipe used in ICU. The problem happened because the underlying `createViewRef` function was not taking into account IcuContainer as a valid TNodeType. This commit updates the `createViewRef` function to return corresponding ViewRef for TNodeType.IcuContainer.
PR Close#34198
Fixes ngtsc incorrectly logging an unknown element diagnostic for HTML elements that are inside an SVG `foreignObject` with the `xhtml` namespace.
Fixes#34171.
PR Close#34178
Prior to this commit, the unknown element can happen twice for AOT-compiled components: once during compilation and once again at runtime. Due to the fact that `schemas` information is not present on Component and NgModule defs after AOT compilation, the second check (at runtime) may fail, even though the same check was successful at compile time. This commit updates the code to avoid the second check for AOT-compiled components by checking whether `schemas` information is present in a logic that executes the unknown element check.
PR Close#34024
Use angular_ivy_enabled to determine if Ivy is being used for the ivy_test_selector.ts symbols.
Additionally, remove the reflect_metadata genrules as we not longer have a "jit" compile option
so all possible invocations result in the same generated file. Instead we can just commit this
file.
PR Close#33983
Since config=ivy now sets the define=compile flag and the define=angular_ivy_enabled
flag to cause usage of Ivy, we can update all of the documentation and scripts that
reference compile=aot to use config=ivy.
PR Close#33983
Prior to this commit, there was a runtime check in i18n logic to make sure "other" case is always present in an ICU. That was not a requirement in View Engine, so ICUs that previously worked may produce errors. This commit removes that restriction and adds support for ICUs without "other" cases.
PR Close#34042
When inserting a `viewRef` it is possible to not provide
an `index`, which is regarded as appending to the end of
the container.
If the `viewRef` already exists in the container, then
this results in a move. But there was a fault in the logic
that computed where to insert the `viewRef` that did not
account for the fact that the `viewRef` was already in
the container, so the insertion `index` was outside the
bounds of the array.
Fixes#33924
PR Close#34052
Prior to this commit, all styles extracted from Component's template (defined using <style> tags) were ignored by JIT compiler, so only `styles` array values defined in @Component decorator were used. This change updates JIT compiler to take styles extracted from the template into account. It also ensures correct order where `styles` array values are applied first and template styles are applied second.
PR Close#34017
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
Micro-benchmarks were broken after we've introduced concept of
DECLARATION_COMPONENT_VIEW on LView (after this change embedded
views must have a pointer to a parent LView).
PR Close#34031
The root view case is already covered by the existing code in the
getRenderParent function so no need to have an explicit checks
(and associated memory reads) again.
PR Close#33988
The assertion that we have in the `directiveInject` instruction is too restrictive and we came across some pattern where it throws unnecessarily. This commit removes that assertion for now and more detailed investigation is needed to decide is we need to restrict the set of TNodeType again.
This commit also adds a test which triggered the TNodeType.View to come up in the `directiveInject` instruction, so it might be useful to avoid regressions during further refactoring.
PR Close#33948
NgModule compilation in JIT mode (that is also used in TestBed) caches module scopes on NgModule defs (using `transitiveCompileScopes` field). Module overrides (defined via TestBed.overrideModule) may invalidate this data by adding/removing items in `declarations` list. This commit forces TestBed to recalculate transitive scopes in case module overrides are present, so TestBed always gets the most up-to-date information.
PR Close#33787
This change enables "var(--my-var)" to pass through the style sanitizer.
After consulation with our security team, allowing these doesn't create
new attack vectors, so the sanitizer doesn't need to strip them.
Fixes parts of #23485 related to the sanitizer, other use cases discussed
there related to binding have been addressed via other changes to the
class and style handling in the runtime.
Closes#23485
PR Close#33841
Originally, QueryList implemented Iterable and provided a Symbol.iterator
on its prototype. This caused issues with tree-shaking, so QueryList was
refactored and the Symbol.iterator added in its constructor instead. As
part of this change, QueryList no longer implemented Iterable directly.
Unfortunately, this meant that QueryList was no longer assignable to
Iterable or, consequently, NgIterable. NgIterable is used for NgFor's input,
so this meant that QueryList was not usable (in a type sense) for NgFor
iteration. View Engine's template type checking would not catch this, but
Ivy's did.
As a fix, this commit adds the declaration (but not the implementation) of
the Symbol.iterator function back to QueryList. This has no runtime effect,
so it doesn't affect tree-shaking of QueryList, but it ensures that
QueryList is assignable to NgIterable and thus usable with NgFor.
Fixes#29842
PR Close#33536
This refactorings clearly separates the first and subsequent creation execution
of the `template` instruction. This approach has the following benefits:
- it is clear what happens during the first vs. subsequent executions;
- we can avoid several memory reads and checks after the first creation pass
(there is measurable performance improvement on various benchmarks);
- the template instructions becomes smaller and should become a candidate
for optimisations / inlining faster;
PR Close#33856
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
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
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
This is a breaking change in nodejs rules 0.40.0 as part of the API review & cleanup for the 1.0 release. Their APIs are identical as ts_web_test was just karma_web_test without the config_file attribute.
PR Close#33802
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
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
The `ngInjectableDef` property was renamed to `ɵprov`, but core must
still support both because there are published libraries that use the
older term.
We are only interested in such properties that are defined directly on
the type being injected, not on base classes. So there is a check that
the defintion is specifically for the given type.
Previously if you tried to inject a class that had `ngInjectableDef` but
also inherited `ɵprov` then the check would fail on the `ɵprov` property
and never even try the `ngInjectableDef` property resulting in a failed
injection.
This commit fixes this by attempting to find each of the properties
independently.
Fixes https://github.com/angular/ngcc-validation/pull/526
PR Close#33732
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
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
While overriding providers in Ivy TestBed (via TestBed.overrideProvider call), the old providers were retained in the list, since the override takes precedence. However, presence of providers in the list might have side-effect: if a provider has the `ngOnDestroy` lifecycle hook, this hook will be registered and invoked later (when component is destroyed). This commit updates TestBed logic to clear provider list by removing the ones which have overrides.
PR Close#33706
Prior to this patch all the styling benchmarks only tested for
template map-based style/class bindings. Because of each of the bindings
being only present in the template, there was no possibility of
there being any duplicate map-based styling bindings.
This benchmark introduces benchmarking for map-based style/class bindings
that are evaluated from both template bindings as well as directives.
This benchmark can be executed by calling:
```
bazel build //packages/core/test/render3/perf:duplicate_map_based_style_and_class_bindings_lib.min_debug.es2015.js
node dist/bin/packages/core/test/render3/perf/duplicate_map_based_style_and_class_bindings_lib.min_debug.es2015.js
```
The benchmark is also run via the `profile_all.js` script (found in
`packages/core/test/render3/perf/`)
PR Close#33608
Prior to this patch all the styling benchmarks only tested for
template-based style/class bindings. Because of each of the bindings
being only present in the template, there was no possibility of
there being any duplicate bindings. This benchmark introduces
style/class bindings being evaluated from both a template and from
various directives.
This benchmark can be executed by calling:
```
bazel build //packages/core/test/render3/perf:duplicate_style_and_class_bindings_lib.min_debug.es2015.js
node dist/bin/packages/core/test/render3/perf/duplicate_style_and_class_bindings_lib.min_debug.es2015.js
```
The benchmark is also run via the `profile_all.js` script (found in
`packages/core/test/render3/perf/`)
PR Close#33600
Prior to this change, namespaced elements such as SVG elements would not
participate correctly in directive matching as their namespace was not
ignored, which was the case with the View Engine compiler. This led to
incorrect behavior at runtime and template type checking.
This commit resolved the issue by ignoring the namespace of elements and
attributes like they were in View Engine.
Fixes#32061
PR Close#33555
This issue was found when debugging a test failure that was using lazy
loaded modules with the router. When doing this, the router calls
`NgModuleFactory.create` for the loaded module. This module gets a new
injector so the overrides provided in TestBed are not applied unless the
Injectable is in the providers list (which is not the case for
{providedIn...} Injectables).
PR Close#33606
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
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
The legacy nodejs rules rollup_bundle is now deprecated and will be removed in the nodejs rules 1.0 release due in mid-November. This PR brings in the rules_nodejs internal API deps that ng_rollup_bundle, ng_package and ls_rollup_bundle depend on into this repo to break the dependency. In the future these rules should switch to use the new rollup_bundle via a macro as done in https://github.com/angular/angular/pull/33329 but this is not possible right now due to the complication of having esm5 re-rooted ts_library dependencies.
The es6 sources now have .mjs extensions so they no longer need to be re-rooted to `{package}.es6`. This eliminates the need for the collect_es6_sources() function.
Note: repo has been updated to the newest working version of rollup which is 1.25.2. There is some regression in 1.26.0 which causes the following bundling failure:
```
ERROR: /Users/greg/google/angular/packages/localize/BUILD.bazel:20:1: Optimizing JavaScript packages/localize/localize.umd.min.js [terser] failed (Exit 1) terser.sh failed: error executing command bazel-out/host/bin/external/npm/terser/bin/terser.sh bazel-out/darwin-fastbuild/bin/packages/localize/localize.umd.js --output bazel-out/darwin-fastbuild/bin/packages/localize/localize.umd.min.js ... (remaining 5 argument(s) skipped)
Use --sandbox_debug to see verbose messages from the sandbox
Parse error at packages/localize/localize.umd.js:491,4
export * from './src/constants';
^
ERROR: Export statement may only appear at top level
at js_error (/private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/sandbox/darwin-sandbox/79/execroot/angular/bazel-out/host/bin/external/npm/terser/bin/terser.sh.runfiles/npm/node_modules/terser/lib/parse.js:357:11)
at Dn.visit (/private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/sandbox/darwin-sandbox/79/execroot/angular/bazel-out/host/bin/external/npm/terser/bin/terser.sh.runfiles/npm/node_modules/terser/lib/scope.js:347:13)
at Dn._visit (/private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/sandbox/darwin-sandbox/79/execroot/angular/bazel-out/host/bin/external/npm/terser/bin/terser.sh.runfiles/npm/node_modules/terser/lib/ast.js:1207:24)
at AST_Export._walk (/private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/sandbox/darwin-sandbox/79/execroot/angular/bazel-out/host/bin/external/npm/terser/bin/terser.sh.runfiles/npm/node_modules/terser/lib/ast.js:718:17)
at walk_body (/private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/sandbox/darwin-sandbox/79/execroot/angular/bazel-out/host/bin/external/npm/terser/bin/terser.sh.runfiles/npm/node_modules/terser/lib/ast.js:168:17)
at AST_Function.call (/private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/sandbox/darwin-sandbox/79/execroot/angular/bazel-out/host/bin/external/npm/terser/bin/terser.sh.runfiles/npm/node_modules/terser/lib/ast.js:430:13)
at descend (/private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/sandbox/darwin-sandbox/79/execroot/angular/bazel-out/host/bin/external/npm/terser/bin/terser.sh.runfiles/npm/node_modules/terser/lib/ast.js:1208:21)
at Dn.visit (/private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/sandbox/darwin-sandbox/79/execroot/angular/bazel-out/host/bin/external/npm/terser/bin/terser.sh.runfiles/npm/node_modules/terser/lib/scope.js:256:13)
at Dn._visit (/private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/sandbox/darwin-sandbox/79/execroot/angular/bazel-out/host/bin/external/npm/terser/bin/terser.sh.runfiles/npm/node_modules/terser/lib/ast.js:1207:24)
at AST_Function._walk (/private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/sandbox/darwin-sandbox/79/execroot/angular/bazel-out/host/bin/external/npm/terser/bin/terser.sh.runfiles/npm/node_modules/terser/lib/ast.js:424:24)
[Function]
Target //packages/localize:npm_package failed to build
Use --verbose_failures to see the command lines of failed build steps.
ERROR: /Users/greg/google/angular/packages/localize/BUILD.bazel:20:1 Optimizing JavaScript packages/localize/localize.umd.min.js [terser] failed (Exit 1) terser.sh failed: error executing command bazel-out/host/bin/external/npm/terser/bin/terser.sh bazel-out/darwin-fastbuild/bin/packages/localize/localize.umd.js --output bazel-out/darwin-fastbuild/bin/packages/localize/localize.umd.min.js ... (remaining 5 argument(s) skipped)
```
Will leave that for another day.
Terser also updated to 4.3.3. Updating to 4.3.4 (https://github.com/terser/terser/blob/master/CHANGELOG.md) turns comments preservation on by default which increases the size of the //packages/core/test/bundling/todo:bundle.min.js in CI. After bazelbuild/rules_nodejs#1317 terser can be updated to the latest as passing —comments /a^/ to args can turn off all comments for the //packages/core/test/bundling/todo:bundle.min.js size test.
PR Close#33201
PR Close#33607
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
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
The legacy nodejs rules rollup_bundle is now deprecated and will be removed in the nodejs rules 1.0 release due in mid-November. This PR brings in the rules_nodejs internal API deps that ng_rollup_bundle, ng_package and ls_rollup_bundle depend on into this repo to break the dependency. In the future these rules should switch to use the new rollup_bundle via a macro as done in https://github.com/angular/angular/pull/33329 but this is not possible right now due to the complication of having esm5 re-rooted ts_library dependencies.
The es6 sources now have .mjs extensions so they no longer need to be re-rooted to `{package}.es6`. This eliminates the need for the collect_es6_sources() function.
Note: repo has been updated to the newest working version of rollup which is 1.25.2. There is some regression in 1.26.0 which causes the following bundling failure:
```
ERROR: /Users/greg/google/angular/packages/localize/BUILD.bazel:20:1: Optimizing JavaScript packages/localize/localize.umd.min.js [terser] failed (Exit 1) terser.sh failed: error executing command bazel-out/host/bin/external/npm/terser/bin/terser.sh bazel-out/darwin-fastbuild/bin/packages/localize/localize.umd.js --output bazel-out/darwin-fastbuild/bin/packages/localize/localize.umd.min.js ... (remaining 5 argument(s) skipped)
Use --sandbox_debug to see verbose messages from the sandbox
Parse error at packages/localize/localize.umd.js:491,4
export * from './src/constants';
^
ERROR: Export statement may only appear at top level
at js_error (/private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/sandbox/darwin-sandbox/79/execroot/angular/bazel-out/host/bin/external/npm/terser/bin/terser.sh.runfiles/npm/node_modules/terser/lib/parse.js:357:11)
at Dn.visit (/private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/sandbox/darwin-sandbox/79/execroot/angular/bazel-out/host/bin/external/npm/terser/bin/terser.sh.runfiles/npm/node_modules/terser/lib/scope.js:347:13)
at Dn._visit (/private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/sandbox/darwin-sandbox/79/execroot/angular/bazel-out/host/bin/external/npm/terser/bin/terser.sh.runfiles/npm/node_modules/terser/lib/ast.js:1207:24)
at AST_Export._walk (/private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/sandbox/darwin-sandbox/79/execroot/angular/bazel-out/host/bin/external/npm/terser/bin/terser.sh.runfiles/npm/node_modules/terser/lib/ast.js:718:17)
at walk_body (/private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/sandbox/darwin-sandbox/79/execroot/angular/bazel-out/host/bin/external/npm/terser/bin/terser.sh.runfiles/npm/node_modules/terser/lib/ast.js:168:17)
at AST_Function.call (/private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/sandbox/darwin-sandbox/79/execroot/angular/bazel-out/host/bin/external/npm/terser/bin/terser.sh.runfiles/npm/node_modules/terser/lib/ast.js:430:13)
at descend (/private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/sandbox/darwin-sandbox/79/execroot/angular/bazel-out/host/bin/external/npm/terser/bin/terser.sh.runfiles/npm/node_modules/terser/lib/ast.js:1208:21)
at Dn.visit (/private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/sandbox/darwin-sandbox/79/execroot/angular/bazel-out/host/bin/external/npm/terser/bin/terser.sh.runfiles/npm/node_modules/terser/lib/scope.js:256:13)
at Dn._visit (/private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/sandbox/darwin-sandbox/79/execroot/angular/bazel-out/host/bin/external/npm/terser/bin/terser.sh.runfiles/npm/node_modules/terser/lib/ast.js:1207:24)
at AST_Function._walk (/private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/sandbox/darwin-sandbox/79/execroot/angular/bazel-out/host/bin/external/npm/terser/bin/terser.sh.runfiles/npm/node_modules/terser/lib/ast.js:424:24)
[Function]
Target //packages/localize:npm_package failed to build
Use --verbose_failures to see the command lines of failed build steps.
ERROR: /Users/greg/google/angular/packages/localize/BUILD.bazel:20:1 Optimizing JavaScript packages/localize/localize.umd.min.js [terser] failed (Exit 1) terser.sh failed: error executing command bazel-out/host/bin/external/npm/terser/bin/terser.sh bazel-out/darwin-fastbuild/bin/packages/localize/localize.umd.js --output bazel-out/darwin-fastbuild/bin/packages/localize/localize.umd.min.js ... (remaining 5 argument(s) skipped)
```
Will leave that for another day.
Terser also updated to 4.3.3. Updating to 4.3.4 (https://github.com/terser/terser/blob/master/CHANGELOG.md) turns comments preservation on by default which increases the size of the //packages/core/test/bundling/todo:bundle.min.js in CI. After bazelbuild/rules_nodejs#1317 terser can be updated to the latest as passing —comments /a^/ to args can turn off all comments for the //packages/core/test/bundling/todo:bundle.min.js size test.
PR Close#33201
To support compile time localization, we need to be
able to provide the locales via a well known global property.
This commit changes `getLocaleData()` so that it will attempt
to read the local from the global `ng.common.locales` if the
locale has not already been registered via `registerLocaleData()`.
PR Close#33523
To limit the exposure of the private `LOCALE_DATA` from outside
`@angular/core` this commit exposes private functions in the core
to hide the internal structures better.
* The `registerLocaleData()` implementation has moved from
`@angular/common` to `@angular/core`. A stub that delegates to
core has been left in common for backward compatibility.
* A new `ɵunregisterLocaleData()` function has been provided,
which is particularly useful in tests to clear out registered locales
to prevent subsequent tests from being affected.
* A private export of `ɵregisterLocaleData()` has been removed
from `@angular/common`. This was not being used and is accessible
via `@angular/core` anyway.
PR Close#33523
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
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
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
The 4b81bb5c97 patch seemingly broke the
`profile_all.js` file due to the file renaming. This patch restores the
functionality of said script.
PR Close#33494