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
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
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
Before this change instantiating multiple directives on the same
host node would result in repeated RNode retrieval and patching.
This commint re-organises code around directive instance creation
so the host node processing (common to all directives) happens
once and only once.
As the additional benefit the directive instantiation logic gets
centralised in one function (at the expense of patching logic
duplication for root node).
PR Close#33322
`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
This patch ensures that the `[style]` and `[class]` based bindings
are directly applied to an element's style and className attributes.
This patch optimizes the algorithm so that it...
- Doesn't construct an update an instance of `StylingMapArray` for
`[style]` and `[class]` bindings
- Doesn't apply `[style]` and `[class]` based entries using
`classList` and `style` (direct attributes are used instead)
- Doesn't split or iterate over all string-based tokens in a
string value obtained from a `[class]` binding.
This patch speeds up the following cases:
- `<div [class]>` and `<div class="..." [class]>`
- `<div [style]>` and `<div style="..." [style]>`
The overall speec increase is by over 5x.
PR Close#33336
`LFrame` stores information specifice to the current `LView` As the code
enters and leaves `LView`s we use `enterView()` and `leaveView()`
respectively to build a a stack of `LFrame`s. This allows us to easily
restore the previous `LView` instruction state.
PR Close#33178
Until now, the template type checker has not checked any of the event
bindings that could be present on an element, for example
```
<my-cmp
(changed)="handleChange($event)"
(click)="handleClick($event)"></my-cmp>
```
has two event bindings: the `change` event corresponding with an
`@Output()` on the `my-cmp` component and the `click` DOM event.
This commit adds functionality to the template type checker in order to
type check both kind of event bindings. This means that the correctness
of the bindings expressions, as well as the type of the `$event`
variable will now be taken into account during template type checking.
Resolves FW-1598
PR Close#33125
Turns out that writing to global state is more expensive than writing to
a property on an object.
Slower:
````
let count = 0;
function increment() {
count++;
}
```
Faster:
````
const state = {
count: 0
};
function increment() {
state.count++;
}
```
This change moves all of the instruction state into a single state object.
`noop_change_detection` benchmark
Pre refactoring: 16.7 us
Post refactoring: 14.523 us (-13.3%)
PR Close#33093
Prior to this commit, all `className` inputs were not set because the runtime code assumed that the `classMap` instruction is only generated for `[class]` bindings. However the `[className]` binding also produces the same `classMap`, thus the code needs to distinguish between `class` and `className`. This commit adds extra logic to select the right input name and also throws an error in case `[class]` and `[className]` bindings are used on the same element simultaneously.
PR Close#33188
Injectable 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
ngInjectableDef to "prov" (for "provider", since injector defs
are known as "inj"). 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#33151
Injector 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
ngInjectorDef to inj. 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#33151
Prior to this patch, if a map-class binding is applied directly then
that value will be incorrectly provided a sanitizer even if there is no
sanitization present for an element.
PR Close#33154
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
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
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
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
Accessing a string's character at index allocates a new, single character string.
A better (faster) check is to use `charCodeAt` that doesn't trigger allocation.
This simple change speeds up the element_text_create benchmark by ~7%.
PR Close#32997
In an attempt to be compatible with previous translation files
the Angular compiler was generating instructions that always
included the message id. This was because it was not possible
to accurately re-generate the id from the calls to `$localize()` alone.
In line with https://hackmd.io/EQF4_-atSXK4XWg8eAha2g this
commit changes the compiler so that it only renders ids if they are
"custom" ones provided by the template author.
NOTE:
When translating messages generated by the Angular compiler
from i18n tags in templates, the `$localize.translate()` function
will compute message ids, if no custom id is provided, using a
common digest function that only relies upon the information
available in the `$localize()` calls.
This computed message id will not be the same as the message
ids stored in legacy translation files. Such files will need to be
migrated to use the new common digest function.
This only affects developers who have been trialling `$localize`, have
been calling `loadTranslations()`, and are not exclusively using custom
ids in their templates.
PR Close#32867
Now that the `$localize` translations are `MessageId` based the
compiler must render `MessageId`s in its generated `$localize` code.
This is because the `MessageId` used by the compiler is computed
from information that does not get passed through to the `$localize`
tagged string.
For example, the generated code for the following template
```html
<div id="static" i18n-title="m|d" title="introduction"></div>
```
will contain these localization statements
```ts
if (ngI18nClosureMode) {
/**
* @desc d
* @meaning m
*/
const MSG_EXTERNAL_8809028065680254561$$APP_SPEC_TS_1 = goog.getMsg("introduction");
I18N_1 = MSG_EXTERNAL_8809028065680254561$$APP_SPEC_TS_1;
}
else {
I18N_1 = $localize \`:m|d@@8809028065680254561:introduction\`;
}
```
Since `$localize` is not able to accurately regenerate the source-message
(and so the `MessageId`) from the generated code, it must rely upon the
`MessageId` being provided explicitly in the generated code.
The compiler now prepends all localized messages with a "metadata block"
containing the id (and the meaning and description if defined).
Note that this metadata block will also allow translation file extraction
from the compiled code - rather than relying on the legacy ViewEngine
extraction code. (This will be implemented post-v9).
Although these metadata blocks add to the initial code size, compile-time
inlining will completely remove these strings and so will not impact on
production bundle size.
PR Close#32594
Prior to this patch, each time `advance()` would run (or when a
templateFn or hostBindings code exits) then the core change detection
code would check to see whether the styling data needs to be reset. This
patch removes that functionality and places everything inside of the
scheduled styling exit function. This means that each time one or more
styling bindings run (even if the value hasn't changed) then an exit
function will be scheduled and that will do all the cleanup.
PR Close#32591
This patch is a final major refactor in styling Angular.
This PR includes three main fixes:
All temporary state taht is persisted between template style/class application
and style/class application in host bindings is now removed.
Removes the styling() and stylingApply() instructions.
Introduces a "direct apply" mode that is used apply prop-based
style/class in the event that there are no map-based bindings as
well as property collisions.
PR Close#32259
PR Close#32591
This is a refactoring that moves the source code around to provide a better
platform for adding the compile-time inlining.
1. Move the global side-effect import from the primary entry-point to a
secondary entry-point @angular/localize/init.
This has two benefits: first it allows the top level entry-point to
contain tree-shakable shareable code; second it gives the side-effect
import more of an "action" oriented name, which indicates that importing
it does something tangible
2. Move all the source code into the top src folder, and import the localize
related functions into the localize/init/index.ts entry-point.
This allows the different parts of the package to share code without
a proliferation of secondary entry-points (i.e. localize/utils).
3. Avoid publicly exporting any utilities at this time - the only public
API at this point are the global `$localize` function and the two runtime
helpers `loadTranslations()` and `clearTranslations()`.
This does not mean that we will not expose additional helpers for 3rd
party tooling in the future, but it avoid us preemptively exposing
something that we might want to change in the near future.
Notes:
It is not possible to have the `$localize` code in the same Bazel package
as the rest of the code. If we did this, then the bundled `@angular/localize/init`
entry-point code contains all of the helper code, even though most of it is not used.
Equally it is not possible to have the `$localize` types (i.e. `LocalizeFn`
and `TranslateFn`) defined in the `@angular/localize/init` entry-point because
these types are needed for the runtime code, which is inside the primary
entry-point. Importing them from `@angular/localize/init` would run the
side-effect.
The solution is to have a Bazel sub-package at `//packages/localize/src/localize`
which contains these types and the `$localize` function implementation.
The primary `//packages/localize` entry-point imports the types without
any side-effect.
The secondary `//packages/localize/init` entry-point imports the `$localize`
function and attaches it to the global scope as a side-effect, without
bringing with it all the other utility functions.
BREAKING CHANGES:
The entry-points have changed:
* To attach the `$localize` function to the global scope import from
`@angular/localize/init`. Previously it was `@angular/localize`.
* To access the `loadTranslations()` and `clearTranslations()` functions,
import from `@angular/localize`. Previously it was `@angular/localize/run_time`.
PR Close#32488
This perf-focused refactoring moves the TNode's input / output initialization
logic to the first template pass - close to the place where directives are
matched and resolved.
This code change makes it possible to update-mode checks for both property
bindings and listeners registration.
PR Close#32608
Before this refactoring we had 2 utility functions to check if a given
TNode has matching directives. This PR leaves just one such function
(one that does less memory read).
PR Close#32495
While determining a property name to bind to we were checking a mapping object
resulting in the megamorphic read. Replacing such read with a series of if checks
speeds up rproprty update benchmark ~30% (~1400ms down to ~1000ms).
PR Close#32574
Ensures that the "core_all:size_test" target runs with "--define=compile=aot".
This is necessary because we don't run this test on CI currently, but if we run
it manually, we need to ensure that it runs with Ivy for proper size comparisons.
PR Close#32613
This patch is a final major refactor in styling Angular.
This PR includes three main fixes:
All temporary state taht is persisted between template style/class application
and style/class application in host bindings is now removed.
Removes the styling() and stylingApply() instructions.
Introduces a "direct apply" mode that is used apply prop-based
style/class in the event that there are no map-based bindings as
well as property collisions.
PR Close#32259
PR Close#32596
This patch is a final major refactor in styling Angular.
This PR includes three main fixes:
All temporary state taht is persisted between template style/class application
and style/class application in host bindings is now removed.
Removes the styling() and stylingApply() instructions.
Introduces a "direct apply" mode that is used apply prop-based
style/class in the event that there are no map-based bindings as
well as property collisions.
PR Close#32259
Replaces the `select` instruction with a new one called `advance`. Instead of the jumping to a specific index, the new instruction goes forward X amount of elements. The advantage of doing this is that it should generate code the compresses better.
PR Close#32516
The `goog.getMsg()` function requires placeholder names to be camelCased.
This is not the case for `$localize`. Here placeholder names need
match what is serialized to translation files.
Specifically such placeholder names keep their casing but have all characters
that are not in `a-z`, `A-Z`, `0-9` and `_` converted to `_`.
PR Close#32509