diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 17b6c37d9cba2..df88bce447782 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -30,7 +30,7 @@ jobs: persist-credentials: false - name: 'Run analysis' - uses: ossf/scorecard-action@483ef80eb98fb506c348f7d62e28055e49fe2398 # v2.3.0 + uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1 with: results_file: results.sarif results_format: sarif @@ -39,7 +39,7 @@ jobs: # Upload the results as artifacts. - name: 'Upload artifact' - uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 + uses: actions/upload-artifact@c7d193f32edcb7bfad88892161225aeda64e9392 # v4.0.0 with: name: SARIF file path: results.sarif @@ -47,6 +47,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: 'Upload to code-scanning' - uses: github/codeql-action/upload-sarif@0116bc2df50751f9724a2e35ef1f24d22f90e4e1 # v2.22.3 + uses: github/codeql-action/upload-sarif@b374143c1149a9115d881581d29b8390bbcbb59c # v3.22.11 with: sarif_file: results.sarif diff --git a/aio/content/cli/help/add.json b/aio/content/cli/help/add.json index e31e3510462aa..d707946ea671d 100644 --- a/aio/content/cli/help/add.json +++ b/aio/content/cli/help/add.json @@ -22,6 +22,9 @@ { "name": "dry-run", "type": "boolean", + "aliases": [ + "d" + ], "default": false, "description": "Run through and reports activity without writing out results." }, diff --git a/aio/content/cli/help/build-info.json b/aio/content/cli/help/build-info.json index a491df6fc8846..d3b1fa76b81d7 100644 --- a/aio/content/cli/help/build-info.json +++ b/aio/content/cli/help/build-info.json @@ -1,4 +1,4 @@ { "branchName": "refs/heads/main", - "sha": "8c844e03ebe99ac0fda6d1e2fa8d57d6031f1562" + "sha": "9ddd673f70f415f59d953fd72f05ebd32f92a60b" } \ No newline at end of file diff --git a/aio/content/cli/help/build.json b/aio/content/cli/help/build.json index 9f8effcf8af1f..5264217341f11 100644 --- a/aio/content/cli/help/build.json +++ b/aio/content/cli/help/build.json @@ -148,7 +148,7 @@ { "name": "output-path", "type": "string", - "description": "The full path for the new output directory, relative to the current workspace." + "description": "Specify the output path relative to workspace root." }, { "name": "poll", diff --git a/aio/content/cli/help/generate.json b/aio/content/cli/help/generate.json index bbff4a7279a1f..a6d62df446341 100644 --- a/aio/content/cli/help/generate.json +++ b/aio/content/cli/help/generate.json @@ -16,6 +16,9 @@ { "name": "dry-run", "type": "boolean", + "aliases": [ + "d" + ], "default": false, "description": "Run through and reports activity without writing out results." }, diff --git a/aio/content/cli/help/new.json b/aio/content/cli/help/new.json index 523a4e971af99..fc72d886550a5 100644 --- a/aio/content/cli/help/new.json +++ b/aio/content/cli/help/new.json @@ -43,6 +43,9 @@ { "name": "dry-run", "type": "boolean", + "aliases": [ + "d" + ], "default": false, "description": "Run through and reports activity without writing out results." }, diff --git a/devtools/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-forest/component-data-source/index.ts b/devtools/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-forest/component-data-source/index.ts index a026aff1cf160..7c17c454df26f 100644 --- a/devtools/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-forest/component-data-source/index.ts +++ b/devtools/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-forest/component-data-source/index.ts @@ -176,7 +176,7 @@ export class ComponentDataSource extends DataSource { this._treeControl.expansionModel.changed, this._flattenedData, ]; - return merge(...changes) + return merge(...changes) .pipe( map(() => { this._expandedData.next( diff --git a/devtools/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/property-resolver/property-data-source.ts b/devtools/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/property-resolver/property-data-source.ts index cc8e5aac4781b..64485768d872d 100644 --- a/devtools/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/property-resolver/property-data-source.ts +++ b/devtools/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/property-resolver/property-data-source.ts @@ -69,7 +69,7 @@ export class PropertyDataSource extends DataSource { const changes = [collectionViewer.viewChange, this._treeControl.expansionModel.changed, this._data]; - return merge(...changes).pipe(map(() => { + return merge(...changes).pipe(map(() => { this._expandedData.next( this._treeFlattener.expandFlattenedNodes(this.data, this._treeControl)); return this._expandedData.value; diff --git a/docs/DEVELOPER.md b/docs/DEVELOPER.md index d9c81bab657e9..6a455869e7f98 100644 --- a/docs/DEVELOPER.md +++ b/docs/DEVELOPER.md @@ -26,8 +26,9 @@ following products on your development machine: **Windows Users**: Git Bash or an equivalent shell is required\ *Windows Powershell and cmd shells are not supported [#46780](https://github.com/angular/angular/issues/46780) so some commands might fail* -* [Node.js](https://nodejs.org), (version specified in the engines field of [`package.json`](../package.json)) which is used to run a development web server, - run tests, and generate distributable files. +* [Node.js](https://nodejs.org), (version specified in [`.nvmrc`](../.nvmrc)) which is used to run a development web server, + run tests, and generate distributable files. + `.nvmrc` is read by [nvm](https://github.com/nvm-sh/nvm) commands like `nvm install` and `nvm use`. * [Yarn](https://yarnpkg.com) (version specified in the engines field of [`package.json`](../package.json)) which is used to install dependencies. diff --git a/modules/benchmarks/src/expanding_rows/expanding_row_details_caption.ts b/modules/benchmarks/src/expanding_rows/expanding_row_details_caption.ts index 8099f8f4f7882..3badd601c6c25 100644 --- a/modules/benchmarks/src/expanding_rows/expanding_row_details_caption.ts +++ b/modules/benchmarks/src/expanding_rows/expanding_row_details_caption.ts @@ -35,7 +35,7 @@ export class ExpandingRowDetailsCaption implements OnDestroy { @Input() color: string = 'blue'; /** This is triggered when this component is destroyed. */ - private readonly onDestroy = new Subject(); + private readonly onDestroy = new Subject(); /** * We need a reference to parent cfc-expanding-row component here to hide diff --git a/package.json b/package.json index 236fe23b793a9..38216ff1427ad 100644 --- a/package.json +++ b/package.json @@ -126,7 +126,7 @@ "rollup": "~2.79.0", "rollup-plugin-preserve-shebang": "^1.0.1", "rollup-plugin-sourcemaps": "^0.6.3", - "rxjs": "^6.6.7", + "rxjs": "^7.0.0", "selenium-webdriver": "3.5.0", "selenium-webdriver4": "npm:selenium-webdriver@4.14.0", "semver-dsl": "^1.0.1", diff --git a/packages/common/http/test/client_spec.ts b/packages/common/http/test/client_spec.ts index d23f4ad228f15..3fc1b9e08466c 100644 --- a/packages/common/http/test/client_spec.ts +++ b/packages/common/http/test/client_spec.ts @@ -106,11 +106,11 @@ describe('HttpClient', () => { }); it('that returns a stream of events', done => { client.get('/test', {observe: 'events'}).pipe(toArray()).toPromise().then(events => { - expect(events.length).toBe(2); + expect(events!.length).toBe(2); let x = HttpResponse; - expect(events[0].type).toBe(HttpEventType.Sent); - expect(events[1].type).toBe(HttpEventType.Response); - expect(events[1] instanceof HttpResponse).toBeTruthy(); + expect(events![0].type).toBe(HttpEventType.Sent); + expect(events![1].type).toBe(HttpEventType.Response); + expect(events![1] instanceof HttpResponse).toBeTruthy(); done(); }); backend.expectOne('/test').flush({'data': 'hello world'}); diff --git a/packages/common/http/test/fetch_spec.ts b/packages/common/http/test/fetch_spec.ts index 0c765db958037..aea78cf387286 100644 --- a/packages/common/http/test/fetch_spec.ts +++ b/packages/common/http/test/fetch_spec.ts @@ -15,18 +15,17 @@ import {HttpDownloadProgressEvent, HttpErrorResponse, HttpHeaderResponse, HttpPa import {FetchBackend, FetchFactory} from '../src/fetch'; function trackEvents(obs: Observable): Promise { - return obs - .pipe( - // We don't want the promise to fail on HttpErrorResponse - catchError((e) => of(e)), - scan( - (acc, event) => { - acc.push(event); - return acc; - }, - [] as any[]), - ) - .toPromise(); + return obs.pipe( + // We don't want the promise to fail on HttpErrorResponse + catchError((e) => of(e)), + scan( + (acc, event) => { + acc.push(event); + return acc; + }, + [] as any[]), + ) + .toPromise() as Promise; } const TEST_POST = new HttpRequest('POST', '/test', 'some body', { diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/elements/GOLDEN_PARTIAL.js b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/elements/GOLDEN_PARTIAL.js index bd4e8dc8af3b3..94682744bf1ee 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/elements/GOLDEN_PARTIAL.js +++ b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/elements/GOLDEN_PARTIAL.js @@ -684,3 +684,37 @@ export declare class MyModule { static ɵinj: i0.ɵɵInjectorDeclaration; } +/**************************************************************************************************** + * PARTIAL FILE: iframe_attrs.js + ****************************************************************************************************/ +import { Component } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { + constructor() { + this.fullscreen = 'false'; + } +} +MyComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "0.0.0-PLACEHOLDER", type: MyComponent, selector: "my-component", ngImport: i0, template: ` + + `, isInline: true }); +i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyComponent, decorators: [{ + type: Component, + args: [{ + selector: 'my-component', + template: ` + + ` + }] + }] }); + +/**************************************************************************************************** + * PARTIAL FILE: iframe_attrs.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + fullscreen: string; + static ɵfac: i0.ɵɵFactoryDeclaration; + static ɵcmp: i0.ɵɵComponentDeclaration; +} + diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/elements/TEST_CASES.json b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/elements/TEST_CASES.json index 8c57978716e20..ea602d35a7c2f 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/elements/TEST_CASES.json +++ b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/elements/TEST_CASES.json @@ -254,6 +254,17 @@ "failureMessage": "Incorrect generated template." } ] + }, + { + "description": "should validate iframe attributes", + "inputFiles": [ + "iframe_attrs.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect generated template." + } + ] } ] } diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/elements/iframe_attrs.js b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/elements/iframe_attrs.js new file mode 100644 index 0000000000000..42d1bdb67035d --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/elements/iframe_attrs.js @@ -0,0 +1,8 @@ +consts: [["allow", "camera 'none'"]], +template: function MyComponent_Template(rf, ctx) { + if (rf & 1) { + i0.ɵɵelement(0, "iframe", 0); + } if (rf & 2) { + i0.ɵɵattribute("fetchpriority", "low", i0.ɵɵvalidateIframeAttribute)("allowfullscreen", ctx.fullscreen, i0.ɵɵvalidateIframeAttribute); + } +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/elements/iframe_attrs.ts b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/elements/iframe_attrs.ts new file mode 100644 index 0000000000000..302c0805291b2 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/elements/iframe_attrs.ts @@ -0,0 +1,11 @@ +import {Component} from '@angular/core'; + +@Component({ + selector: 'my-component', + template: ` + + ` +}) +export class MyComponent { + fullscreen = 'false'; +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/GOLDEN_PARTIAL.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/GOLDEN_PARTIAL.js index 6c67a2a7f674c..b12233e1c6423 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/GOLDEN_PARTIAL.js +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/GOLDEN_PARTIAL.js @@ -370,3 +370,50 @@ export declare class MyModule { static ɵinj: i0.ɵɵInjectorDeclaration; } +/**************************************************************************************************** + * PARTIAL FILE: duplicate_bindings.js + ****************************************************************************************************/ +import { Component } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { +} +MyComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "0.0.0-PLACEHOLDER", type: MyComponent, isStandalone: true, selector: "my-component", ngImport: i0, template: ` +
+
+
+
+
+
+
+
+ `, isInline: true }); +i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyComponent, decorators: [{ + type: Component, + args: [{ + selector: 'my-component', + standalone: true, + template: ` +
+
+
+
+
+
+
+
+ `, + }] + }] }); + +/**************************************************************************************************** + * PARTIAL FILE: duplicate_bindings.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + value1: any; + value2: any; + static ɵfac: i0.ɵɵFactoryDeclaration; + static ɵcmp: i0.ɵɵComponentDeclaration; +} + diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/TEST_CASES.json b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/TEST_CASES.json index 2c748833ac192..969072755b861 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/TEST_CASES.json +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/TEST_CASES.json @@ -64,14 +64,7 @@ ], "expectations": [ { - "failureMessage": "Incorrect template", - "files": [ - { - "expected": "chain_multiple_bindings_for_multiple_elements_template.js", - "templatePipelineExpected": "chain_multiple_bindings_for_multiple_elements_template.pipeline.js", - "generated": "chain_multiple_bindings_for_multiple_elements.js" - } - ] + "failureMessage": "Incorrect template" } ] }, @@ -82,14 +75,7 @@ ], "expectations": [ { - "failureMessage": "Incorrect template", - "files": [ - { - "expected": "chain_multiple_bindings_with_child_elements_template.js", - "templatePipelineExpected": "chain_multiple_bindings_with_child_elements_template.pipeline.js", - "generated": "chain_multiple_bindings_with_child_elements.js" - } - ] + "failureMessage": "Incorrect template" } ] }, @@ -124,6 +110,17 @@ ] } ] + }, + { + "description": "should handle duplicate bindings", + "inputFiles": [ + "duplicate_bindings.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect handling of duplicate bindings" + } + ] } ] -} \ No newline at end of file +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_bindings_for_multiple_elements_template.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_bindings_for_multiple_elements.js similarity index 100% rename from packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_bindings_for_multiple_elements_template.js rename to packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_bindings_for_multiple_elements.js diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_bindings_for_multiple_elements_template.pipeline.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_bindings_for_multiple_elements_template.pipeline.js deleted file mode 100644 index df9eca0a1bb89..0000000000000 --- a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_bindings_for_multiple_elements_template.pipeline.js +++ /dev/null @@ -1,11 +0,0 @@ -template: function MyComponent_Template(rf, ctx) { - … - if (rf & 2) { - $r3$.ɵɵattribute("title", ctx.myTitle)("id", ctx.buttonId)("tabindex", 1); - $r3$.ɵɵadvance(1); - $r3$.ɵɵattribute("id", 1)("some-attr", 1 + 2); - $r3$.ɵɵadvance(1); - $r3$.ɵɵattribute("some-other-attr", 2); - } - } - \ No newline at end of file diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_bindings_with_child_elements_template.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_bindings_with_child_elements.js similarity index 100% rename from packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_bindings_with_child_elements_template.js rename to packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_bindings_with_child_elements.js diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_bindings_with_child_elements_template.pipeline.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_bindings_with_child_elements_template.pipeline.js deleted file mode 100644 index f66da81600258..0000000000000 --- a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_bindings_with_child_elements_template.pipeline.js +++ /dev/null @@ -1,9 +0,0 @@ -template: function MyComponent_Template(rf, ctx) { - … - if (rf & 2) { - $r3$.ɵɵattribute("title", ctx.myTitle)("id", ctx.buttonId)("tabindex", 1); - $r3$.ɵɵadvance(1); - $r3$.ɵɵattribute("id", 1)("some-attr", 1 + 2); - } - } - \ No newline at end of file diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/duplicate_bindings.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/duplicate_bindings.js new file mode 100644 index 0000000000000..f1756177ae0a0 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/duplicate_bindings.js @@ -0,0 +1,21 @@ +consts: [["aria-label", "hello", "aria-label", "hi"], [2, "height", "0"], [1, "cls2"], [3, "tabindex"], [3, "click"]], +template: function MyComponent_Template(rf, ctx) { + if (rf & 1) { + i0.ɵɵelement(0, "div", 0); + i0.ɵɵelementStart(1, "div", 1); + i0.ɵɵelement(2, "div", 2)(3, "div")(4, "div", 3)(5, "div")(6, "div"); + i0.ɵɵelementStart(7, "div", 4); + i0.ɵɵlistener("click", function MyComponent_Template_div_click_7_listener($event) { return $event.stopPropagation(); })("click", function MyComponent_Template_div_click_7_listener($event) { return $event.preventDefault(); }); + i0.ɵɵelementEnd()(); + } + if (rf & 2) { + i0.ɵɵadvance(3); + i0.ɵɵattribute("aria-label", ctx.value1)("aria-label", ctx.value2); + i0.ɵɵadvance(1); + i0.ɵɵproperty("tabindex", ctx.value1)("tabindex", ctx.value2); + i0.ɵɵadvance(1); + i0.ɵɵclassMap(ctx.value2); + i0.ɵɵadvance(1); + i0.ɵɵstyleMap(ctx.value2); + } +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/duplicate_bindings.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/duplicate_bindings.ts new file mode 100644 index 0000000000000..433791c424c3f --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/duplicate_bindings.ts @@ -0,0 +1,20 @@ +import {Component} from '@angular/core'; + +@Component({ + selector: 'my-component', + standalone: true, + template: ` +
+
+
+
+
+
+
+
+ `, +}) +export class MyComponent { + value1: any; + value2: any; +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/exclude_bindings_from_consts_template.pipeline.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/exclude_bindings_from_consts_template.pipeline.js index f6324d1ce4bc9..23723fbca3a8a 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/exclude_bindings_from_consts_template.pipeline.js +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/exclude_bindings_from_consts_template.pipeline.js @@ -1,3 +1,3 @@ -consts: [["target", "_blank", "aria-label", "link", "foo", "one", "bar", "two", __AttributeMarker.Bindings__, "customEvent", "title", "id"]], +consts: [["target", "_blank", "aria-label", "link", __AttributeMarker.Bindings__, "customEvent", "title", "id"]], … diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/GOLDEN_PARTIAL.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/GOLDEN_PARTIAL.js index f8a773740b75a..da86e0a834d97 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/GOLDEN_PARTIAL.js +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/GOLDEN_PARTIAL.js @@ -1007,3 +1007,56 @@ export declare class MyComponent { static ɵcmp: i0.ɵɵComponentDeclaration; } +/**************************************************************************************************** + * PARTIAL FILE: deceptive_attrs.js + ****************************************************************************************************/ +import { Component } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { +} +MyComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "0.0.0-PLACEHOLDER", type: MyComponent, isStandalone: true, selector: "my-comp", host: { attributes: { "class.is-compact": "false", "style.width": "0", "attr.tabindex": "5" } }, ngImport: i0, template: '', isInline: true }); +i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyComponent, decorators: [{ + type: Component, + args: [{ + selector: 'my-comp', + standalone: true, + template: '', + host: { + ['class.is-compact']: 'false', + ['style.width']: '0', + ['attr.tabindex']: '5', + } + }] + }] }); +export class MyComponent2 { +} +MyComponent2.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyComponent2, deps: [], target: i0.ɵɵFactoryTarget.Component }); +MyComponent2.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "0.0.0-PLACEHOLDER", type: MyComponent2, isStandalone: true, selector: "my-comp-2", host: { properties: { "class.is-compact": "false", "style.width": "0", "attr.tabindex": "5" } }, ngImport: i0, template: '', isInline: true }); +i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyComponent2, decorators: [{ + type: Component, + args: [{ + selector: 'my-comp-2', + standalone: true, + template: '', + host: { + '[class.is-compact]': 'false', + '[style.width]': '0', + '[attr.tabindex]': '5', + } + }] + }] }); + +/**************************************************************************************************** + * PARTIAL FILE: deceptive_attrs.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + static ɵfac: i0.ɵɵFactoryDeclaration; + static ɵcmp: i0.ɵɵComponentDeclaration; +} +export declare class MyComponent2 { + static ɵfac: i0.ɵɵFactoryDeclaration; + static ɵcmp: i0.ɵɵComponentDeclaration; +} + diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/TEST_CASES.json b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/TEST_CASES.json index 5835b76e33751..5ca1b0bef87d7 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/TEST_CASES.json +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/TEST_CASES.json @@ -362,12 +362,29 @@ "files": [ { "expected": "host_with_ts_expression_node_template.js", - "templatePipelineExpected": "host_with_ts_expression_node_template.pipeline.js", "generated": "host_with_ts_expression_node.js" } ] } ] + }, + { + "description": "should handle deceptive attribute names", + "inputFiles": [ + "deceptive_attrs.ts" + ], + "expectations": [ + { + "failureMessage": "Invalid host binding code", + "files": [ + { + "generated": "deceptive_attrs.js", + "expected": "deceptive_attrs.template.js", + "templatePipelineExpected": "deceptive_attrs.pipeline.js" + } + ] + } + ] } ] } diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/deceptive_attrs.pipeline.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/deceptive_attrs.pipeline.js new file mode 100644 index 0000000000000..1f8e244691a5f --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/deceptive_attrs.pipeline.js @@ -0,0 +1,9 @@ +hostAttrs: ["class.is-compact", "false", "style.width", "0", "attr.tabindex", "5"], +… +hostBindings: function MyComponent2_HostBindings(rf, ctx) { + if (rf & 2) { + i0.ɵɵstyleProp("width", 0); + i0.ɵɵclassProp("is-compact", false); + i0.ɵɵattribute("tabindex", 5); + } +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/deceptive_attrs.template.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/deceptive_attrs.template.js new file mode 100644 index 0000000000000..b628c765f9467 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/deceptive_attrs.template.js @@ -0,0 +1,9 @@ +hostAttrs: ["class.is-compact", "false", "style.width", "0", "attr.tabindex", "5"], +… +hostBindings: function MyComponent2_HostBindings(rf, ctx) { + if (rf & 2) { + i0.ɵɵattribute("tabindex", 5); + i0.ɵɵstyleProp("width", 0); + i0.ɵɵclassProp("is-compact", false); + } +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/deceptive_attrs.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/deceptive_attrs.ts new file mode 100644 index 0000000000000..1b9dca682f2bc --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/deceptive_attrs.ts @@ -0,0 +1,27 @@ +import {Component} from '@angular/core'; + +@Component({ + selector: 'my-comp', + standalone: true, + template: '', + host: { + ['class.is-compact']: 'false', + ['style.width']: '0', + ['attr.tabindex']: '5', + } +}) +export class MyComponent { +} + +@Component({ + selector: 'my-comp-2', + standalone: true, + template: '', + host: { + '[class.is-compact]': 'false', + '[style.width]': '0', + '[attr.tabindex]': '5', + } +}) +export class MyComponent2 { +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/host_with_ts_expression_node_template.pipeline.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/host_with_ts_expression_node_template.pipeline.js deleted file mode 100644 index 39c443d3d866e..0000000000000 --- a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/host_with_ts_expression_node_template.pipeline.js +++ /dev/null @@ -1,5 +0,0 @@ -function MyComponent_HostBindings(rf, ctx) { - if (rf & 2) { - i0.ɵɵattribute("foo", BAR_CONST); - } -} \ No newline at end of file diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_control_flow/GOLDEN_PARTIAL.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_control_flow/GOLDEN_PARTIAL.js index ea5163c842130..ca395e33ba22a 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_control_flow/GOLDEN_PARTIAL.js +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_control_flow/GOLDEN_PARTIAL.js @@ -1926,3 +1926,54 @@ export declare class MyApp { static ɵcmp: i0.ɵɵComponentDeclaration; } +/**************************************************************************************************** + * PARTIAL FILE: nested_for_tracking_function.js + ****************************************************************************************************/ +import { Component } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyApp { + constructor() { + this.items = []; + this.trackByGrandparent = (item, index) => index; + this.trackByParent = (item, index) => index; + this.trackByChild = (item, index) => index; + } +} +MyApp.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyApp, deps: [], target: i0.ɵɵFactoryTarget.Component }); +MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "0.0.0-PLACEHOLDER", type: MyApp, selector: "ng-component", ngImport: i0, template: ` + @for (grandparent of items; track trackByGrandparent(grandparent, $index)) { + @for (parent of grandparent.items; track trackByParent(parent, $index)) { + @for (child of parent.items; track trackByChild(child, $index)) { + + } + } + } + `, isInline: true }); +i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyApp, decorators: [{ + type: Component, + args: [{ + template: ` + @for (grandparent of items; track trackByGrandparent(grandparent, $index)) { + @for (parent of grandparent.items; track trackByParent(parent, $index)) { + @for (child of parent.items; track trackByChild(child, $index)) { + + } + } + } + `, + }] + }] }); + +/**************************************************************************************************** + * PARTIAL FILE: nested_for_tracking_function.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyApp { + items: any[]; + trackByGrandparent: (item: any, index: number) => number; + trackByParent: (item: any, index: number) => number; + trackByChild: (item: any, index: number) => number; + static ɵfac: i0.ɵɵFactoryDeclaration; + static ɵcmp: i0.ɵɵComponentDeclaration; +} + diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_control_flow/TEST_CASES.json b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_control_flow/TEST_CASES.json index 8e5b68d6c1d25..b3f688adde156 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_control_flow/TEST_CASES.json +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_control_flow/TEST_CASES.json @@ -617,6 +617,23 @@ } ], "skipForTemplatePipeline": true + }, + { + "description": "should generate tracking function in a nested for loop", + "inputFiles": [ + "nested_for_tracking_function.ts" + ], + "expectations": [ + { + "files": [ + { + "expected": "nested_for_tracking_function_template.js", + "generated": "nested_for_tracking_function.js" + } + ], + "failureMessage": "Incorrect template" + } + ] } ] } diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_control_flow/nested_for_tracking_function.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_control_flow/nested_for_tracking_function.ts new file mode 100644 index 0000000000000..9d01b5e589877 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_control_flow/nested_for_tracking_function.ts @@ -0,0 +1,19 @@ +import {Component} from '@angular/core'; + +@Component({ + template: ` + @for (grandparent of items; track trackByGrandparent(grandparent, $index)) { + @for (parent of grandparent.items; track trackByParent(parent, $index)) { + @for (child of parent.items; track trackByChild(child, $index)) { + + } + } + } + `, +}) +export class MyApp { + items: any[] = []; + trackByGrandparent = (item: any, index: number) => index; + trackByParent = (item: any, index: number) => index; + trackByChild = (item: any, index: number) => index; +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_control_flow/nested_for_tracking_function_template.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_control_flow/nested_for_tracking_function_template.js new file mode 100644 index 0000000000000..81eac05a0b24f --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_control_flow/nested_for_tracking_function_template.js @@ -0,0 +1,44 @@ +function _forTrack0($index, $item) { + return this.trackByGrandparent($item, $index); +} + +function _forTrack1($index, $item) { + return this.trackByParent($item, $index); +} + +function _forTrack2($index, $item) { + return this.trackByChild($item, $index); +} + +function MyApp_For_1_For_1_For_1_Template(rf, ctx) {} + +function MyApp_For_1_For_1_Template(rf, ctx) { + if (rf & 1) { + $r3$.ɵɵrepeaterCreate(0, MyApp_For_1_For_1_For_1_Template, 0, 0, null, null, _forTrack2, true); + } + if (rf & 2) { + const $parent_r7$ = ctx.$implicit; + $r3$.ɵɵrepeater($parent_r7$.items); + } +} + +function MyApp_For_1_Template(rf, ctx) { + if (rf & 1) { + $r3$.ɵɵrepeaterCreate(0, MyApp_For_1_For_1_Template, 2, 0, null, null, _forTrack1, true); + } + if (rf & 2) { + const $grandparent_r1$ = ctx.$implicit; + $r3$.ɵɵrepeater($grandparent_r1$.items); + } +} + +… + +function MyApp_Template(rf, ctx) { + if (rf & 1) { + $r3$.ɵɵrepeaterCreate(0, MyApp_For_1_Template, 2, 0, null, null, _forTrack0, true); + } + if (rf & 2) { + $r3$.ɵɵrepeater(ctx.items); + } +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_deferred/GOLDEN_PARTIAL.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_deferred/GOLDEN_PARTIAL.js index 73d180310c57c..387a2911e286c 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_deferred/GOLDEN_PARTIAL.js +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_deferred/GOLDEN_PARTIAL.js @@ -743,3 +743,151 @@ export declare class MyApp { static ɵcmp: i0.ɵɵComponentDeclaration; } +/**************************************************************************************************** + * PARTIAL FILE: defer_deps_ext.js + ****************************************************************************************************/ +import { Component } from '@angular/core'; +import * as i0 from "@angular/core"; +export class CmpA { +} +CmpA.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: CmpA, deps: [], target: i0.ɵɵFactoryTarget.Component }); +CmpA.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "0.0.0-PLACEHOLDER", type: CmpA, isStandalone: true, selector: "cmp-a", ngImport: i0, template: 'CmpA!', isInline: true }); +i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: CmpA, decorators: [{ + type: Component, + args: [{ standalone: true, selector: 'cmp-a', template: 'CmpA!' }] + }] }); + +/**************************************************************************************************** + * PARTIAL FILE: defer_deps_ext.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class CmpA { + static ɵfac: i0.ɵɵFactoryDeclaration; + static ɵcmp: i0.ɵɵComponentDeclaration; +} + +/**************************************************************************************************** + * PARTIAL FILE: defer_deps.js + ****************************************************************************************************/ +import { Component } from '@angular/core'; +import { CmpA } from './defer_deps_ext'; +import * as i0 from "@angular/core"; +export class LocalDep { +} +LocalDep.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: LocalDep, deps: [], target: i0.ɵɵFactoryTarget.Component }); +LocalDep.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "0.0.0-PLACEHOLDER", type: LocalDep, isStandalone: true, selector: "local-dep", ngImport: i0, template: 'Local dependency', isInline: true }); +i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: LocalDep, decorators: [{ + type: Component, + args: [{ + selector: 'local-dep', + standalone: true, + template: 'Local dependency', + }] + }] }); +export class TestCmp { +} +TestCmp.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: TestCmp, deps: [], target: i0.ɵɵFactoryTarget.Component }); +TestCmp.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "0.0.0-PLACEHOLDER", type: TestCmp, isStandalone: true, selector: "test-cmp", ngImport: i0, template: ` + @defer { + + + } +`, isInline: true }); +i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: TestCmp, decorators: [{ + type: Component, + args: [{ + selector: 'test-cmp', + standalone: true, + imports: [CmpA, LocalDep], + template: ` + @defer { + + + } +`, + }] + }] }); + +/**************************************************************************************************** + * PARTIAL FILE: defer_deps.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class LocalDep { + static ɵfac: i0.ɵɵFactoryDeclaration; + static ɵcmp: i0.ɵɵComponentDeclaration; +} +export declare class TestCmp { + static ɵfac: i0.ɵɵFactoryDeclaration; + static ɵcmp: i0.ɵɵComponentDeclaration; +} + +/**************************************************************************************************** + * PARTIAL FILE: lazy_with_blocks.js + ****************************************************************************************************/ +import { Component } from '@angular/core'; +import * as i0 from "@angular/core"; +class MyLazyCmp { +} +MyLazyCmp.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyLazyCmp, deps: [], target: i0.ɵɵFactoryTarget.Component }); +MyLazyCmp.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "0.0.0-PLACEHOLDER", type: MyLazyCmp, isStandalone: true, selector: "my-lazy-cmp", ngImport: i0, template: 'Hi!', isInline: true }); +i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyLazyCmp, decorators: [{ + type: Component, + args: [{ + selector: 'my-lazy-cmp', + standalone: true, + template: 'Hi!', + }] + }] }); +class SimpleComponent { + constructor() { + this.isVisible = false; + } + ngOnInit() { + setTimeout(() => { + // This changes the triggering condition of the defer block, + // but it should be ignored and the placeholder content should be visible. + this.isVisible = true; + }); + } +} +SimpleComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: SimpleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); +SimpleComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "0.0.0-PLACEHOLDER", type: SimpleComponent, isStandalone: true, selector: "app", ngImport: i0, template: ` + Visible: {{ isVisible }}. + + @defer (when isVisible) { + + } @loading { + Loading... + } @placeholder { + Placeholder! + } @error { + Failed to load dependencies :( + } + `, isInline: true }); +i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: SimpleComponent, decorators: [{ + type: Component, + args: [{ + standalone: true, + selector: 'app', + imports: [MyLazyCmp], + template: ` + Visible: {{ isVisible }}. + + @defer (when isVisible) { + + } @loading { + Loading... + } @placeholder { + Placeholder! + } @error { + Failed to load dependencies :( + } + ` + }] + }] }); + +/**************************************************************************************************** + * PARTIAL FILE: lazy_with_blocks.d.ts + ****************************************************************************************************/ +export {}; + diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_deferred/TEST_CASES.json b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_deferred/TEST_CASES.json index 0088a6dcaccf3..8e9b79291ee81 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_deferred/TEST_CASES.json +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_deferred/TEST_CASES.json @@ -225,6 +225,41 @@ "failureMessage": "Incorrect template" } ] + }, + { + "description": "should generate a deferred block with implicit trigger references", + "inputFiles": [ + "defer_deps.ts", + "defer_deps_ext.ts" + ], + "expectations": [ + { + "files": [ + { + "expected": "defer_deps_template.js", + "generated": "defer_deps.js" + } + ], + "failureMessage": "Incorrect template" + } + ] + }, + { + "description": "should generate a lazy deferred block with empty and placeholder", + "inputFiles": [ + "lazy_with_blocks.ts" + ], + "expectations": [ + { + "files": [ + { + "expected": "lazy_with_blocks_template.js", + "generated": "lazy_with_blocks.js" + } + ], + "failureMessage": "Incorrect template" + } + ] } ] } \ No newline at end of file diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_deferred/defer_deps.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_deferred/defer_deps.ts new file mode 100644 index 0000000000000..d72cec98c9652 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_deferred/defer_deps.ts @@ -0,0 +1,25 @@ +import {Component} from '@angular/core'; + +import {CmpA} from './defer_deps_ext'; + +@Component({ + selector: 'local-dep', + standalone: true, + template: 'Local dependency', +}) +export class LocalDep { +} + +@Component({ + selector: 'test-cmp', + standalone: true, + imports: [CmpA, LocalDep], + template: ` + @defer { + + + } +`, +}) +export class TestCmp { +} \ No newline at end of file diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_deferred/defer_deps_ext.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_deferred/defer_deps_ext.ts new file mode 100644 index 0000000000000..7b1d7d6b877f5 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_deferred/defer_deps_ext.ts @@ -0,0 +1,5 @@ +import {Component} from '@angular/core'; + +@Component({standalone: true, selector: 'cmp-a', template: 'CmpA!'}) +export class CmpA { +} \ No newline at end of file diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_deferred/defer_deps_template.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_deferred/defer_deps_template.js new file mode 100644 index 0000000000000..6c6c59e03685e --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_deferred/defer_deps_template.js @@ -0,0 +1,18 @@ +const TestCmp_Defer_1_DepsFn = () => [import("./defer_deps_ext").then(m => m.CmpA), LocalDep]; + +function TestCmp_Defer_0_Template(rf, ctx) { + if (rf & 1) { + i0.ɵɵelement(0, "cmp-a")(1, "local-dep"); + } +} + +export class LocalDep { +} + +… + +function TestCmp_Template(rf, ctx) { if (rf & 1) { + i0.ɵɵtemplate(0, TestCmp_Defer_0_Template, 2, 0); + i0.ɵɵdefer(1, 0, TestCmp_Defer_1_DepsFn); + i0.ɵɵdeferOnIdle(); +} } \ No newline at end of file diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_deferred/deferred_when_with_pipe_template.pipeline.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_deferred/deferred_when_with_pipe_template.pipeline.js index eb57f1661b54b..15e3e86ca4d9b 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_deferred/deferred_when_with_pipe_template.pipeline.js +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_deferred/deferred_when_with_pipe_template.pipeline.js @@ -8,7 +8,7 @@ function MyApp_Template(rf, ctx) { if (rf & 2) { $r3$.ɵɵtextInterpolate1(" ", ctx.message, " "); $r3$.ɵɵadvance(2); - $r3$.ɵɵdeferWhen(ctx.isVisible() && $r3$.ɵɵpipeBind1(4, 1, ctx.isReady)); + $r3$.ɵɵdeferWhen(ctx.isVisible() && $r3$.ɵɵpipeBind1(4, 2, ctx.isReady)); } } \ No newline at end of file diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_deferred/lazy_with_blocks.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_deferred/lazy_with_blocks.ts new file mode 100644 index 0000000000000..131eb4bc349dd --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_deferred/lazy_with_blocks.ts @@ -0,0 +1,40 @@ +import {Component} from '@angular/core'; + + +@Component({ + selector: 'my-lazy-cmp', + standalone: true, + template: 'Hi!', +}) +class MyLazyCmp { +} + +@Component({ + standalone: true, + selector: 'app', + imports: [MyLazyCmp], + template: ` + Visible: {{ isVisible }}. + + @defer (when isVisible) { + + } @loading { + Loading... + } @placeholder { + Placeholder! + } @error { + Failed to load dependencies :( + } + ` +}) +class SimpleComponent { + isVisible = false; + + ngOnInit() { + setTimeout(() => { + // This changes the triggering condition of the defer block, + // but it should be ignored and the placeholder content should be visible. + this.isVisible = true; + }); + } +} \ No newline at end of file diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_deferred/lazy_with_blocks_template.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_deferred/lazy_with_blocks_template.js new file mode 100644 index 0000000000000..71e8c77157df5 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_deferred/lazy_with_blocks_template.js @@ -0,0 +1,51 @@ +const SimpleComponent_Defer_5_DepsFn = () => [MyLazyCmp]; + +function SimpleComponent_Defer_1_Template(rf, ctx) { + if (rf & 1) { + i0.ɵɵelement(0, "my-lazy-cmp"); + } +} + +function SimpleComponent_DeferLoading_2_Template(rf, ctx) { + if (rf & 1) { + i0.ɵɵtext(0, " Loading... "); + } +} + +function SimpleComponent_DeferPlaceholder_3_Template(rf, ctx) { + if (rf & 1) { + i0.ɵɵtext(0, " Placeholder! "); + } +} + +function SimpleComponent_DeferError_4_Template(rf, ctx) { + if (rf & 1) { + i0.ɵɵtext(0, " Failed to load dependencies :( "); + } +} + +… + +decls: 1, +vars: 0, +template: function MyLazyCmp_Template(rf, ctx) { + if (rf & 1) { + i0.ɵɵtext(0, "Hi!"); + } +} + +… + +decls: 7, +vars: 2, +template: function SimpleComponent_Template(rf, ctx) { + if (rf & 1) { + i0.ɵɵtext(0); + i0.ɵɵtemplate(1, SimpleComponent_Defer_1_Template, 1, 0)(2, SimpleComponent_DeferLoading_2_Template, 1, 0)(3, SimpleComponent_DeferPlaceholder_3_Template, 1, 0)(4, SimpleComponent_DeferError_4_Template, 1, 0); + i0.ɵɵdefer(5, 1, SimpleComponent_Defer_5_DepsFn, 2, 3, 4); + } if (rf & 2) { + i0.ɵɵtextInterpolate1(" Visible: ", ctx.isVisible, ". "); + i0.ɵɵadvance(5); + i0.ɵɵdeferWhen(ctx.isVisible); + } +} \ No newline at end of file diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_listener/GOLDEN_PARTIAL.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_listener/GOLDEN_PARTIAL.js index 269122652384e..e3c96ad6f59c0 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_listener/GOLDEN_PARTIAL.js +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_listener/GOLDEN_PARTIAL.js @@ -818,3 +818,35 @@ export declare class AppModule { static ɵinj: i0.ɵɵInjectorDeclaration; } +/**************************************************************************************************** + * PARTIAL FILE: multiple_statements.js + ****************************************************************************************************/ +import { Component } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { +} +MyComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "0.0.0-PLACEHOLDER", type: MyComponent, isStandalone: true, selector: "my-component", host: { listeners: { "click": "$event.preventDefault(); $event.target.blur()" } }, ngImport: i0, template: ` +
+ `, isInline: true }); +i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyComponent, decorators: [{ + type: Component, + args: [{ + selector: 'my-component', + standalone: true, + host: { '(click)': '$event.preventDefault(); $event.target.blur()' }, + template: ` +
+ ` + }] + }] }); + +/**************************************************************************************************** + * PARTIAL FILE: multiple_statements.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + static ɵfac: i0.ɵɵFactoryDeclaration; + static ɵcmp: i0.ɵɵComponentDeclaration; +} + diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_listener/TEST_CASES.json b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_listener/TEST_CASES.json index 7db4e79715bf0..0abfef1b21450 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_listener/TEST_CASES.json +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_listener/TEST_CASES.json @@ -333,6 +333,17 @@ "failureMessage": "Incorrect template" } ] + }, + { + "description": "should generate listener with multiple statements", + "inputFiles": [ + "multiple_statements.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect template" + } + ] } ] -} \ No newline at end of file +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_listener/multiple_statements.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_listener/multiple_statements.js new file mode 100644 index 0000000000000..5f5f068734f6b --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_listener/multiple_statements.js @@ -0,0 +1,13 @@ +hostBindings: function MyComponent_HostBindings(rf, ctx) { + if (rf & 1) { + i0.ɵɵlistener("click", function MyComponent_click_HostBindingHandler($event) { $event.preventDefault(); return $event.target.blur(); }); + } +} +… +template: function MyComponent_Template(rf, ctx) { + if (rf & 1) { + i0.ɵɵelementStart(0, "div", 0); + i0.ɵɵlistener("click", function MyComponent_Template_div_click_0_listener($event) { $event.preventDefault(); return $event.target.blur(); }); + i0.ɵɵelementEnd(); + } +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_listener/multiple_statements.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_listener/multiple_statements.ts new file mode 100644 index 0000000000000..f72abf7c6c337 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_listener/multiple_statements.ts @@ -0,0 +1,12 @@ +import {Component} from '@angular/core'; + +@Component({ + selector: 'my-component', + standalone: true, + host: {'(click)': '$event.preventDefault(); $event.target.blur()'}, + template: ` +
+ ` +}) +export class MyComponent { +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/GOLDEN_PARTIAL.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/GOLDEN_PARTIAL.js index 52f0edaa6446d..650c62c9e0052 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/GOLDEN_PARTIAL.js +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/GOLDEN_PARTIAL.js @@ -219,3 +219,50 @@ export declare class MyComponent { static ɵcmp: i0.ɵɵComponentDeclaration; } +/**************************************************************************************************** + * PARTIAL FILE: shared_name_with_consts.js + ****************************************************************************************************/ +import { Component } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { + constructor() { + this.tabIndex = 0; + } +} +MyComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "0.0.0-PLACEHOLDER", type: MyComponent, isStandalone: true, selector: "my-component", ngImport: i0, template: ` +
+
+
+
+
+
+
+`, isInline: true }); +i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyComponent, decorators: [{ + type: Component, + args: [{ + selector: 'my-component', + standalone: true, + template: ` +
+
+
+
+
+
+
+` + }] + }] }); + +/**************************************************************************************************** + * PARTIAL FILE: shared_name_with_consts.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + tabIndex: number; + static ɵfac: i0.ɵɵFactoryDeclaration; + static ɵcmp: i0.ɵɵComponentDeclaration; +} + diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/TEST_CASES.json b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/TEST_CASES.json index adb4ec394c3c3..ca8b443f2293b 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/TEST_CASES.json +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/TEST_CASES.json @@ -70,6 +70,24 @@ ] } ] + }, + { + "description": "should handle class that shares its name with other const array items", + "inputFiles": [ + "shared_name_with_consts.ts" + ], + "expectations": [ + { + "files": [ + { + "templatePipelineExpected": "shared_name_with_consts_template.pipeline.js", + "expected": "shared_name_with_consts_template.js", + "generated": "shared_name_with_consts.js" + } + ], + "failureMessage": "Incorrect template" + } + ] } ] } diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/shared_name_with_consts.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/shared_name_with_consts.ts new file mode 100644 index 0000000000000..49a467e61389b --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/shared_name_with_consts.ts @@ -0,0 +1,18 @@ +import {Component} from '@angular/core'; + +@Component({ + selector: 'my-component', + standalone: true, + template: ` +
+
+
+
+
+
+
+` +}) +export class MyComponent { + tabIndex = 0; +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/shared_name_with_consts_template.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/shared_name_with_consts_template.js new file mode 100644 index 0000000000000..090b286ed2e53 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/shared_name_with_consts_template.js @@ -0,0 +1,30 @@ +consts: () => { + __i18nMsg__('label', [], {}, {}) + return [ + ["attr", "", __AttributeMarker.Classes__, "attr"], + ["ngProjectAs", "selector", __AttributeMarker.ProjectAs__, ["selector"], __AttributeMarker.Classes__, "selector"], + [__AttributeMarker.Classes__, "width", __AttributeMarker.Styles__, "width", "0px"], + [__AttributeMarker.Classes__, "tabindex", __AttributeMarker.Bindings__, "tabindex"], + ["class", "ngIf", __AttributeMarker.Template__, "ngIf"], + ["aria-label", i18n_0, __AttributeMarker.Classes__, "aria-label"], + ["all", "", "ngProjectAs", "all", "style", "all:all", "class", "all", __AttributeMarker.ProjectAs__, ["all"], __AttributeMarker.Bindings__, "all", __AttributeMarker.Template__], + [__AttributeMarker.Classes__, "ngIf"], + ["all", "", "ngProjectAs", "all", __AttributeMarker.ProjectAs__, ["all"], __AttributeMarker.Classes__, "all", __AttributeMarker.Styles__, "all", "all", __AttributeMarker.Bindings__, "all"] + ]; +}, +template: function MyComponent_Template(rf, ctx) { + if (rf & 1) { + i0.ɵɵelement(0, "div", 0)(1, "div", 1)(2, "div", 2)(3, "div", 3); + i0.ɵɵtemplate(4, MyComponent_div_4_Template, 1, 0, "div", 4); + i0.ɵɵelement(5, "div", 5); + i0.ɵɵtemplate(6, MyComponent_div_6_Template, 1, 1, "div", 6); + } + if (rf & 2) { + i0.ɵɵadvance(3); + i0.ɵɵproperty("tabindex", ctx.tabIndex); + i0.ɵɵadvance(1); + i0.ɵɵproperty("ngIf", ctx.cond); + i0.ɵɵadvance(2); + i0.ɵɵproperty("all", ctx.all); + } +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/shared_name_with_consts_template.pipeline.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/shared_name_with_consts_template.pipeline.js new file mode 100644 index 0000000000000..876fe77eac405 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/shared_name_with_consts_template.pipeline.js @@ -0,0 +1,32 @@ +consts: () => { + __i18nMsg__('label', [], {}, {}) + return [ + ["attr", "", __AttributeMarker.Classes__, "attr"], + ["ngProjectAs", "selector", __AttributeMarker.ProjectAs__, ["selector"], __AttributeMarker.Classes__, "selector"], + [__AttributeMarker.Classes__, "width", __AttributeMarker.Styles__, "width", "0px"], + [__AttributeMarker.Classes__, "tabindex", __AttributeMarker.Bindings__, "tabindex"], + ["class", "ngIf", __AttributeMarker.Template__, "ngIf"], + ["aria-label", i18n_0, __AttributeMarker.Classes__, "aria-label"], + // NOTE: We tolerate a slight difference -- we emit `all` as a Template binding + ["all", "", "ngProjectAs", "all", "style", "all:all", "class", "all", __AttributeMarker.ProjectAs__, ["all"], __AttributeMarker.Bindings__, "all", __AttributeMarker.Template__, "all"], + [__AttributeMarker.Classes__, "ngIf"], + ["all", "", "ngProjectAs", "all", __AttributeMarker.ProjectAs__, ["all"], __AttributeMarker.Classes__, "all", __AttributeMarker.Styles__, "all", "all", __AttributeMarker.Bindings__, "all"] + ]; + }, + template: function MyComponent_Template(rf, ctx) { + if (rf & 1) { + i0.ɵɵelement(0, "div", 0)(1, "div", 1)(2, "div", 2)(3, "div", 3); + i0.ɵɵtemplate(4, MyComponent_div_4_Template, 1, 0, "div", 4); + i0.ɵɵelement(5, "div", 5); + i0.ɵɵtemplate(6, MyComponent_div_6_Template, 1, 1, "div", 6); + } + if (rf & 2) { + i0.ɵɵadvance(3); + i0.ɵɵproperty("tabindex", ctx.tabIndex); + i0.ɵɵadvance(1); + i0.ɵɵproperty("ngIf", ctx.cond); + i0.ɵɵadvance(2); + i0.ɵɵproperty("all", ctx.all); + } + } + \ No newline at end of file diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/GOLDEN_PARTIAL.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/GOLDEN_PARTIAL.js index bf3b80cac4263..526423b8e87df 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/GOLDEN_PARTIAL.js +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/GOLDEN_PARTIAL.js @@ -323,3 +323,65 @@ export declare class MyModule { static ɵinj: i0.ɵɵInjectorDeclaration; } +/**************************************************************************************************** + * PARTIAL FILE: colon_style.js + ****************************************************************************************************/ +import { Component } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { +} +MyComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "0.0.0-PLACEHOLDER", type: MyComponent, isStandalone: true, selector: "my-component", ngImport: i0, template: ` +
+ `, isInline: true }); +i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyComponent, decorators: [{ + type: Component, + args: [{ + selector: 'my-component', + standalone: true, + template: ` +
+ ` + }] + }] }); + +/**************************************************************************************************** + * PARTIAL FILE: colon_style.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + static ɵfac: i0.ɵɵFactoryDeclaration; + static ɵcmp: i0.ɵɵComponentDeclaration; +} + +/**************************************************************************************************** + * PARTIAL FILE: duplicate_style_bindings.js + ****************************************************************************************************/ +import { Component } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { +} +MyComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "0.0.0-PLACEHOLDER", type: MyComponent, isStandalone: true, selector: "my-component", ngImport: i0, template: ` +
+ `, isInline: true }); +i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyComponent, decorators: [{ + type: Component, + args: [{ + selector: 'my-component', + standalone: true, + template: ` +
+ `, + }] + }] }); + +/**************************************************************************************************** + * PARTIAL FILE: duplicate_style_bindings.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + static ɵfac: i0.ɵɵFactoryDeclaration; + static ɵcmp: i0.ɵɵComponentDeclaration; +} + diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/TEST_CASES.json b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/TEST_CASES.json index b59b4c2739813..8727df0f74766 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/TEST_CASES.json +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/TEST_CASES.json @@ -3,61 +3,110 @@ "cases": [ { "description": "should create style instructions on the element", - "inputFiles": ["style_binding.ts"], + "inputFiles": [ + "style_binding.ts" + ], "expectations": [ { "failureMessage": "Incorrect template", - "files": ["style_binding.js"] + "files": [ + "style_binding.js" + ] } ] }, { "description": "should correctly count the total slots required when style/class bindings include interpolation", - "inputFiles": ["binding_slots.ts"], + "inputFiles": [ + "binding_slots.ts" + ], "expectations": [ { "failureMessage": "Incorrect template", - "files": ["binding_slots.js"] + "files": [ + "binding_slots.js" + ] } ] }, { "description": "should place initial, multi, singular and application followed by attribute style instructions in the template code in that order", - "inputFiles": ["binding_slots_interpolations.ts"], + "inputFiles": [ + "binding_slots_interpolations.ts" + ], "expectations": [ { "failureMessage": "Incorrect template", - "files": ["binding_slots_interpolations.js"] + "files": [ + "binding_slots_interpolations.js" + ] } ] }, { "description": "should assign a sanitizer instance to the element style allocation instruction if any url-based properties are detected", - "inputFiles": ["style_ordering.ts"], + "inputFiles": [ + "style_ordering.ts" + ], "expectations": [ { "failureMessage": "Incorrect template", - "files": ["style_ordering.js"] + "files": [ + "style_ordering.js" + ] } ] }, { "description": "should support [style.foo.suffix] style bindings with a suffix", - "inputFiles": ["style_binding_suffixed.ts"], + "inputFiles": [ + "style_binding_suffixed.ts" + ], "expectations": [ { "failureMessage": "Incorrect template", - "files": ["style_binding_suffixed.js"] + "files": [ + "style_binding_suffixed.js" + ] } ] }, { "description": "should not create instructions for empty style bindings", - "inputFiles": ["empty_style_bindings.ts"], + "inputFiles": [ + "empty_style_bindings.ts" + ], "expectations": [ { "failureMessage": "Incorrect template", - "files": ["empty_style_bindings.js"] + "files": [ + "empty_style_bindings.js" + ] + } + ] + }, + { + "description": "should support style bindings with a colon at the start of the applied style", + "inputFiles": [ + "colon_style.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect template", + "files": [ + "colon_style.js" + ] + } + ] + }, + { + "description": "should handle duplicate style bindings", + "inputFiles": [ + "duplicate_style_bindings.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect template" } ] } diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/colon_style.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/colon_style.js new file mode 100644 index 0000000000000..9e495f2008633 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/colon_style.js @@ -0,0 +1,8 @@ +// NOTE: This is the way TemplateDefinitionBuilder behaves today, but it's crazy!! +// NOTE: TODO: Should we fix it? +consts: [[__AttributeMarker.Styles__, ":root {color", "red"]], +template: function MyComponent_Template(rf, ctx) { + if (rf & 1) { + i0.ɵɵelement(0, "div", 0); + } +} \ No newline at end of file diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/colon_style.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/colon_style.ts new file mode 100644 index 0000000000000..3171558a85152 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/colon_style.ts @@ -0,0 +1,11 @@ +import {Component} from '@angular/core'; + +@Component({ + selector: 'my-component', + standalone: true, + template: ` +
+ ` +}) +export class MyComponent { +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/duplicate_style_bindings.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/duplicate_style_bindings.js new file mode 100644 index 0000000000000..f14313c6b3426 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/duplicate_style_bindings.js @@ -0,0 +1 @@ +consts: [[1, "cls1", "cls1", 2, "width", "1px", "width", "10px"]] diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/duplicate_style_bindings.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/duplicate_style_bindings.ts new file mode 100644 index 0000000000000..53e7b3d4ac621 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/duplicate_style_bindings.ts @@ -0,0 +1,11 @@ +import {Component} from '@angular/core'; + +@Component({ + selector: 'my-component', + standalone: true, + template: ` +
+ `, +}) +export class MyComponent { +} diff --git a/packages/compiler-cli/test/ngtsc/template_mapping_spec.ts b/packages/compiler-cli/test/ngtsc/template_mapping_spec.ts index b8575cbca2a5b..596d30964ec10 100644 --- a/packages/compiler-cli/test/ngtsc/template_mapping_spec.ts +++ b/packages/compiler-cli/test/ngtsc/template_mapping_spec.ts @@ -426,36 +426,39 @@ runInEachFileSystem((os) => { }); }); - it('should correctly handle collapsed whitespace in interpolation placeholder source-mappings', - async () => { - const mappings = await compileAndMap( - `
pre-body {{greeting}} post-body
`); - expectMapping(mappings, { - source: '
', - generated: 'i0.ɵɵelementStart(0, "div", 0)', - sourceUrl: '../test.ts', - }); - expectMapping(mappings, { - source: '
', - generated: 'i0.ɵɵelementEnd()', - sourceUrl: '../test.ts', - }); - expectMapping(mappings, { - source: ' pre-body ', - generated: '` pre-body ${', - sourceUrl: '../test.ts', - }); - expectMapping(mappings, { - source: '{{greeting}}', - generated: '"\\uFFFD0\\uFFFD"', - sourceUrl: '../test.ts', - }); - expectMapping(mappings, { - source: ' post-body', - generated: '}:INTERPOLATION: post-body`', - sourceUrl: '../test.ts', - }); - }); + // TODO: Temporarily disabled because Template Pipeline produces different const indices + // than TemplateDefinitionBuilder. Re-enable after Template Pipeline is the default, and + // update the test with the new const index. + xit('should correctly handle collapsed whitespace in interpolation placeholder source-mappings', + async () => { + const mappings = await compileAndMap( + `
pre-body {{greeting}} post-body
`); + expectMapping(mappings, { + source: '
', + generated: 'i0.ɵɵelementStart(0, "div", 0)', + sourceUrl: '../test.ts', + }); + expectMapping(mappings, { + source: '
', + generated: 'i0.ɵɵelementEnd()', + sourceUrl: '../test.ts', + }); + expectMapping(mappings, { + source: ' pre-body ', + generated: '` pre-body ${', + sourceUrl: '../test.ts', + }); + expectMapping(mappings, { + source: '{{greeting}}', + generated: '"\\uFFFD0\\uFFFD"', + sourceUrl: '../test.ts', + }); + expectMapping(mappings, { + source: ' post-body', + generated: '}:INTERPOLATION: post-body`', + sourceUrl: '../test.ts', + }); + }); it('should correctly handle collapsed whitespace in element placeholder source-mappings', async () => { diff --git a/packages/compiler/src/constant_pool.ts b/packages/compiler/src/constant_pool.ts index 0380535b1d336..03d66904dc41d 100644 --- a/packages/compiler/src/constant_pool.ts +++ b/packages/compiler/src/constant_pool.ts @@ -188,7 +188,11 @@ export class ConstantPool { } } - getSharedFunctionReference(fn: o.FunctionExpr|o.ArrowFunctionExpr, prefix: string): o.Expression { + // TODO: useUniqueName(false) is necessary for naming compatibility with + // TemplateDefinitionBuilder, but should be removed once Template Pipeline is the default. + getSharedFunctionReference( + fn: o.FunctionExpr|o.ArrowFunctionExpr, prefix: string, + useUniqueName: boolean = true): o.Expression { const isArrow = fn instanceof o.ArrowFunctionExpr; for (const current of this.statements) { @@ -206,7 +210,7 @@ export class ConstantPool { } // Otherwise declare the function. - const name = this.uniqueName(prefix); + const name = useUniqueName ? this.uniqueName(prefix) : prefix; this.statements.push(fn.toDeclStmt(name, o.StmtModifier.Final)); return o.variable(name); } diff --git a/packages/compiler/src/ml_parser/tags.ts b/packages/compiler/src/ml_parser/tags.ts index af58e730920ae..ea6c0f443e235 100644 --- a/packages/compiler/src/ml_parser/tags.ts +++ b/packages/compiler/src/ml_parser/tags.ts @@ -24,7 +24,7 @@ export interface TagDefinition { getContentType(prefix?: string): TagContentType; } -export function splitNsName(elementName: string): [string|null, string] { +export function splitNsName(elementName: string, fatal: boolean = true): [string|null, string] { if (elementName[0] != ':') { return [null, elementName]; } @@ -32,7 +32,11 @@ export function splitNsName(elementName: string): [string|null, string] { const colonIndex = elementName.indexOf(':', 1); if (colonIndex === -1) { - throw new Error(`Unsupported format "${elementName}" expecting ":namespace:name"`); + if (fatal) { + throw new Error(`Unsupported format "${elementName}" expecting ":namespace:name"`); + } else { + return [null, elementName]; + } } return [elementName.slice(1, colonIndex), elementName.slice(colonIndex + 1)]; diff --git a/packages/compiler/src/render3/view/template.ts b/packages/compiler/src/render3/view/template.ts index 1a2093ae421be..f01864620948e 100644 --- a/packages/compiler/src/render3/view/template.ts +++ b/packages/compiler/src/render3/view/template.ts @@ -2550,11 +2550,16 @@ export class BindingScope implements LocalResolver { class TrackByBindingScope extends BindingScope { private componentAccessCount = 0; - constructor(parentScope: BindingScope, private globalAliases: Record) { + constructor(parentScope: BindingScope, private globalOverrides: Record) { super(parentScope.bindingLevel + 1, parentScope); } override get(name: string): o.Expression|null { + // Intercept any overridden globals. + if (this.globalOverrides.hasOwnProperty(name)) { + return o.variable(this.globalOverrides[name]); + } + let current: BindingScope|null = this.parent; // Prevent accesses of template variables outside the `for` loop. @@ -2565,11 +2570,6 @@ class TrackByBindingScope extends BindingScope { current = current.parent; } - // Intercept any aliased globals. - if (this.globalAliases[name]) { - return o.variable(this.globalAliases[name]); - } - // When the component scope is accessed, we redirect it through `this`. this.componentAccessCount++; return o.variable('this').prop(name); diff --git a/packages/compiler/src/template/pipeline/ir/src/expression.ts b/packages/compiler/src/template/pipeline/ir/src/expression.ts index 82965731f2678..2036cabb1cfad 100644 --- a/packages/compiler/src/template/pipeline/ir/src/expression.ts +++ b/packages/compiler/src/template/pipeline/ir/src/expression.ts @@ -964,6 +964,9 @@ export function transformExpressionsInOp( op.placeholderConfig = transformExpressionsInExpression(op.placeholderConfig, transform, flags); } + if (op.resolverFn !== null) { + op.resolverFn = transformExpressionsInExpression(op.resolverFn, transform, flags); + } break; case OpKind.I18nMessage: for (const [placeholder, expr] of op.params) { diff --git a/packages/compiler/src/template/pipeline/ir/src/ops/create.ts b/packages/compiler/src/template/pipeline/ir/src/ops/create.ts index 19ec3850be332..7fe6560510fca 100644 --- a/packages/compiler/src/template/pipeline/ir/src/ops/create.ts +++ b/packages/compiler/src/template/pipeline/ir/src/ops/create.ts @@ -14,7 +14,7 @@ import {R3DeferBlockMetadata} from '../../../../../render3/view/api'; import {BindingKind, DeferTriggerKind, I18nContextKind, I18nParamValueFlags, Namespace, OpKind, TemplateKind} from '../enums'; import {SlotHandle} from '../handle'; import {Op, OpList, XrefId} from '../operations'; -import {ConsumesSlotOpTrait, TRAIT_CONSUMES_SLOT} from '../traits'; +import {ConsumesSlotOpTrait, ConsumesVarsTrait, TRAIT_CONSUMES_SLOT, TRAIT_CONSUMES_VARS} from '../traits'; import {ListEndOp, NEW_OP, StatementOp, VariableOp} from './shared'; @@ -101,7 +101,15 @@ export interface ElementOrContainerOpBase extends Op, ConsumesSlotOpTr */ nonBindable: boolean; - sourceSpan: ParseSourceSpan; + /** + * The span of the element's start tag. + */ + startSourceSpan: ParseSourceSpan; + + /** + * The whole source span of the element, including children. + */ + wholeSourceSpan: ParseSourceSpan; } export interface ElementOpBase extends ElementOrContainerOpBase { @@ -135,7 +143,7 @@ export interface ElementStartOp extends ElementOpBase { */ export function createElementStartOp( tag: string, xref: XrefId, namespace: Namespace, i18nPlaceholder: i18n.TagPlaceholder|undefined, - sourceSpan: ParseSourceSpan): ElementStartOp { + startSourceSpan: ParseSourceSpan, wholeSourceSpan: ParseSourceSpan): ElementStartOp { return { kind: OpKind.ElementStart, xref, @@ -146,7 +154,8 @@ export function createElementStartOp( nonBindable: false, namespace, i18nPlaceholder, - sourceSpan, + startSourceSpan, + wholeSourceSpan, ...TRAIT_CONSUMES_SLOT, ...NEW_OP, }; @@ -201,7 +210,7 @@ export interface TemplateOp extends ElementOpBase { export function createTemplateOp( xref: XrefId, templateKind: TemplateKind, tag: string|null, functionNameSuffix: string, namespace: Namespace, i18nPlaceholder: i18n.TagPlaceholder|i18n.BlockPlaceholder|undefined, - sourceSpan: ParseSourceSpan): TemplateOp { + startSourceSpan: ParseSourceSpan, wholeSourceSpan: ParseSourceSpan): TemplateOp { return { kind: OpKind.Template, xref, @@ -216,7 +225,8 @@ export function createTemplateOp( nonBindable: false, namespace, i18nPlaceholder, - sourceSpan, + startSourceSpan, + wholeSourceSpan, ...TRAIT_CONSUMES_SLOT, ...NEW_OP, }; @@ -225,7 +235,7 @@ export function createTemplateOp( /** * An op that creates a repeater (e.g. a for loop). */ -export interface RepeaterCreateOp extends ElementOpBase { +export interface RepeaterCreateOp extends ElementOpBase, ConsumesVarsTrait { kind: OpKind.RepeaterCreate; /** @@ -280,8 +290,6 @@ export interface RepeaterCreateOp extends ElementOpBase { * The i18n placeholder for the empty template. */ emptyI18nPlaceholder: i18n.BlockPlaceholder|undefined; - - sourceSpan: ParseSourceSpan; } // TODO: add source spans? @@ -298,8 +306,8 @@ export interface RepeaterVarNames { export function createRepeaterCreateOp( primaryView: XrefId, emptyView: XrefId|null, tag: string|null, track: o.Expression, varNames: RepeaterVarNames, i18nPlaceholder: i18n.BlockPlaceholder|undefined, - emptyI18nPlaceholder: i18n.BlockPlaceholder|undefined, - sourceSpan: ParseSourceSpan): RepeaterCreateOp { + emptyI18nPlaceholder: i18n.BlockPlaceholder|undefined, startSourceSpan: ParseSourceSpan, + wholeSourceSpan: ParseSourceSpan): RepeaterCreateOp { return { kind: OpKind.RepeaterCreate, attributes: null, @@ -319,9 +327,11 @@ export function createRepeaterCreateOp( usesComponentInstance: false, i18nPlaceholder, emptyI18nPlaceholder, - sourceSpan, + startSourceSpan, + wholeSourceSpan, ...TRAIT_CONSUMES_SLOT, ...NEW_OP, + ...TRAIT_CONSUMES_VARS, numSlotsUsed: emptyView === null ? 2 : 3, }; } diff --git a/packages/compiler/src/template/pipeline/ir/src/ops/update.ts b/packages/compiler/src/template/pipeline/ir/src/ops/update.ts index 3f363311f749b..39b5e09f561d7 100644 --- a/packages/compiler/src/template/pipeline/ir/src/ops/update.ts +++ b/packages/compiler/src/template/pipeline/ir/src/ops/update.ts @@ -604,7 +604,7 @@ export function createRepeaterOp( }; } -export interface DeferWhenOp extends Op, DependsOnSlotContextOpTrait { +export interface DeferWhenOp extends Op, DependsOnSlotContextOpTrait, ConsumesVarsTrait { kind: OpKind.DeferWhen; /** @@ -636,6 +636,7 @@ export function createDeferWhenOp( sourceSpan, ...NEW_OP, ...TRAIT_DEPENDS_ON_SLOT_CONTEXT, + ...TRAIT_CONSUMES_VARS, }; } diff --git a/packages/compiler/src/template/pipeline/src/emit.ts b/packages/compiler/src/template/pipeline/src/emit.ts index babf9ccd26c81..8bfbcbf9280a3 100644 --- a/packages/compiler/src/template/pipeline/src/emit.ts +++ b/packages/compiler/src/template/pipeline/src/emit.ts @@ -25,6 +25,7 @@ import {collectElementConsts} from './phases/const_collection'; import {convertI18nBindings} from './phases/convert_i18n_bindings'; import {createDeferDepsFns} from './phases/create_defer_deps_fns'; import {createI18nContexts} from './phases/create_i18n_contexts'; +import {deduplicateTextBindings} from './phases/deduplicate_text_bindings'; import {configureDeferInstructions} from './phases/defer_configs'; import {resolveDeferTargetNames} from './phases/defer_resolve_targets'; import {collapseEmptyInstructions} from './phases/empty_elements'; @@ -92,6 +93,7 @@ const phases: Phase[] = [ {kind: Kind.Tmpl, fn: emitNamespaceChanges}, {kind: Kind.Tmpl, fn: propagateI18nBlocks}, {kind: Kind.Tmpl, fn: wrapI18nIcus}, + {kind: Kind.Both, fn: deduplicateTextBindings}, {kind: Kind.Both, fn: specializeStyleBindings}, {kind: Kind.Both, fn: specializeBindings}, {kind: Kind.Both, fn: extractAttributes}, diff --git a/packages/compiler/src/template/pipeline/src/ingest.ts b/packages/compiler/src/template/pipeline/src/ingest.ts index 751d0b47764fd..52e087a3be521 100644 --- a/packages/compiler/src/template/pipeline/src/ingest.ts +++ b/packages/compiler/src/template/pipeline/src/ingest.ts @@ -78,7 +78,7 @@ export function ingestHostBinding( .calcPossibleSecurityContexts( input.componentSelector, property.name, bindingKind === ir.BindingKind.Attribute) .filter(context => context !== SecurityContext.NONE); - ingestHostProperty(job, property, bindingKind, false, securityContexts); + ingestHostProperty(job, property, bindingKind, securityContexts); } for (const [name, expr] of Object.entries(input.attributes) ?? []) { const securityContexts = @@ -96,7 +96,7 @@ export function ingestHostBinding( // with ordinary components. This would allow us to share a lot more ingestion code. export function ingestHostProperty( job: HostBindingCompilationJob, property: e.ParsedProperty, bindingKind: ir.BindingKind, - isTextAttribute: boolean, securityContexts: SecurityContext[]): void { + securityContexts: SecurityContext[]): void { let expression: o.Expression|ir.Interpolation; const ast = property.expression.ast; if (ast instanceof e.Interpolation) { @@ -106,19 +106,20 @@ export function ingestHostProperty( expression = convertAst(ast, job, property.sourceSpan); } job.root.update.push(ir.createBindingOp( - job.root.xref, bindingKind, property.name, expression, null, securityContexts, - isTextAttribute, false, null, /* TODO: How do Host bindings handle i18n attrs? */ null, - property.sourceSpan)); + job.root.xref, bindingKind, property.name, expression, null, securityContexts, false, false, + null, /* TODO: How do Host bindings handle i18n attrs? */ null, property.sourceSpan)); } export function ingestHostAttribute( job: HostBindingCompilationJob, name: string, value: o.Expression, securityContexts: SecurityContext[]): void { const attrBinding = ir.createBindingOp( - job.root.xref, ir.BindingKind.Attribute, name, value, null, securityContexts, true, false, - null, + job.root.xref, ir.BindingKind.Attribute, name, value, null, securityContexts, + /* Host attributes should always be extracted to const hostAttrs, even if they are not + *strictly* text literals */ + true, false, null, /* TODO */ null, - /* TODO: host attribute source spans */ null!); + /** TODO: May be null? */ value.sourceSpan!); job.root.update.push(attrBinding); } @@ -126,11 +127,9 @@ export function ingestHostEvent(job: HostBindingCompilationJob, event: e.ParsedE const [phase, target] = event.type === e.ParsedEventType.Regular ? [null, event.targetOrPhase] : [event.targetOrPhase, null]; const eventBinding = ir.createListenerOp( - job.root.xref, new ir.SlotHandle(), event.name, null, [], phase, target, true, + job.root.xref, new ir.SlotHandle(), event.name, null, + makeListenerHandlerOps(job.root, event.handler, event.handlerSpan), phase, target, true, event.sourceSpan); - // TODO: Can this be a chain? - eventBinding.handlerOps.push(ir.createStatementOp(new o.ReturnStatement( - convertAst(event.handler.ast, job, event.sourceSpan), event.handlerSpan))); job.root.create.push(eventBinding); } @@ -181,7 +180,7 @@ function ingestElement(unit: ViewCompilationUnit, element: t.Element): void { const startOp = ir.createElementStartOp( elementName, id, namespaceForKey(namespaceKey), element.i18n instanceof i18n.TagPlaceholder ? element.i18n : undefined, - element.startSourceSpan); + element.startSourceSpan, element.sourceSpan); unit.create.push(startOp); ingestElementBindings(unit, startOp, element); @@ -236,7 +235,7 @@ function ingestTemplate(unit: ViewCompilationUnit, tmpl: t.Template): void { isPlainTemplate(tmpl) ? ir.TemplateKind.NgTemplate : ir.TemplateKind.Structural; const templateOp = ir.createTemplateOp( childView.xref, templateKind, tagNameWithoutNamespace, functionNameSuffix, namespace, - i18nPlaceholder, tmpl.startSourceSpan); + i18nPlaceholder, tmpl.startSourceSpan, tmpl.sourceSpan); unit.create.push(templateOp); ingestTemplateBindings(unit, templateOp, tmpl, templateKind); @@ -359,7 +358,7 @@ function ingestIfBlock(unit: ViewCompilationUnit, ifBlock: t.IfBlock): void { const templateOp = ir.createTemplateOp( cView.xref, ir.TemplateKind.Block, tagName, 'Conditional', ir.Namespace.HTML, - ifCaseI18nMeta, ifCase.sourceSpan); + ifCaseI18nMeta, ifCase.startSourceSpan, ifCase.sourceSpan); unit.create.push(templateOp); if (firstXref === null) { @@ -397,7 +396,7 @@ function ingestSwitchBlock(unit: ViewCompilationUnit, switchBlock: t.SwitchBlock } const templateOp = ir.createTemplateOp( cView.xref, ir.TemplateKind.Block, null, 'Case', ir.Namespace.HTML, switchCaseI18nMeta, - switchCase.sourceSpan); + switchCase.startSourceSpan, switchCase.sourceSpan); unit.create.push(templateOp); if (firstXref === null) { firstXref = cView.xref; @@ -430,7 +429,7 @@ function ingestDeferView( ingestNodes(secondaryView, children); const templateOp = ir.createTemplateOp( secondaryView.xref, ir.TemplateKind.Block, null, `Defer${suffix}`, ir.Namespace.HTML, - i18nMeta, sourceSpan!); + i18nMeta, sourceSpan!, sourceSpan!); unit.create.push(templateOp); return templateOp; } @@ -531,6 +530,11 @@ function ingestDeferBlock(unit: ViewCompilationUnit, deferBlock: t.DeferredBlock deferOnOps.push(deferOnOp); } if (triggers.when !== undefined) { + if (triggers.when.value instanceof e.Interpolation) { + // TemplateDefinitionBuilder supports this case, but it's very strange to me. What would it + // even mean? + throw new Error(`Unexpected interpolation in defer block when trigger`); + } const deferOnOp = ir.createDeferWhenOp( deferXref, convertAst(triggers.when.value, unit.job, triggers.when.sourceSpan), prefetch, triggers.when.sourceSpan); @@ -627,7 +631,7 @@ function ingestForBlock(unit: ViewCompilationUnit, forBlock: t.ForLoopBlock): vo const tagName = ingestControlFlowInsertionPoint(unit, repeaterView.xref, forBlock); const repeaterCreate = ir.createRepeaterCreateOp( repeaterView.xref, emptyView?.xref ?? null, tagName, track, varNames, i18nPlaceholder, - emptyI18nPlaceholder, forBlock.sourceSpan); + emptyI18nPlaceholder, forBlock.startSourceSpan, forBlock.sourceSpan); unit.create.push(repeaterCreate); const expression = convertAst( @@ -767,15 +771,15 @@ function convertAst( } function convertAstWithInterpolation( - job: CompilationJob, value: e.AST|string, - i18nMeta: i18n.I18nMeta|null|undefined): o.Expression|ir.Interpolation { + job: CompilationJob, value: e.AST|string, i18nMeta: i18n.I18nMeta|null|undefined, + sourceSpan?: ParseSourceSpan): o.Expression|ir.Interpolation { let expression: o.Expression|ir.Interpolation; if (value instanceof e.Interpolation) { expression = new ir.Interpolation( - value.strings, value.expressions.map(e => convertAst(e, job, null)), + value.strings, value.expressions.map(e => convertAst(e, job, sourceSpan ?? null)), Object.keys(asMessage(i18nMeta)?.placeholders ?? {})); } else if (value instanceof e.AST) { - expression = convertAst(value, job, null); + expression = convertAst(value, job, sourceSpan ?? null); } else { expression = o.literal(value); } diff --git a/packages/compiler/src/template/pipeline/src/phases/attribute_extraction.ts b/packages/compiler/src/template/pipeline/src/phases/attribute_extraction.ts index 0bf2d914110b0..428b981d1b10f 100644 --- a/packages/compiler/src/template/pipeline/src/phases/attribute_extraction.ts +++ b/packages/compiler/src/template/pipeline/src/phases/attribute_extraction.ts @@ -106,21 +106,11 @@ function extractAttributeOp( return; } - let extractable = op.expression.isConstant(); + let extractable = op.isTextAttribute || op.expression.isConstant(); if (unit.job.compatibility === ir.CompatibilityMode.TemplateDefinitionBuilder) { - // TemplateDefinitionBuilder only extracted attributes that were string literals. - extractable = ir.isStringLiteral(op.expression); - if (op.name === 'style' || op.name === 'class') { - // For style and class attributes, TemplateDefinitionBuilder only extracted them if they were - // text attributes. For example, `[attr.class]="'my-class'"` was not extracted despite being a - // string literal, because it is not a text attribute. - extractable &&= op.isTextAttribute; - } - if (unit.job.kind === CompilationJobKind.Host) { - // TemplateDefinitionBuilder also does not seem to extract string literals if they are part of - // a host attribute. - extractable &&= op.isTextAttribute; - } + // TemplateDefinitionBuilder only extracts text attributes. It does not extract attriibute + // bindings, even if they are constants. + extractable &&= op.isTextAttribute; } if (extractable) { diff --git a/packages/compiler/src/template/pipeline/src/phases/const_collection.ts b/packages/compiler/src/template/pipeline/src/phases/const_collection.ts index 0e82c6a2b6788..9941f54f01f5e 100644 --- a/packages/compiler/src/template/pipeline/src/phases/const_collection.ts +++ b/packages/compiler/src/template/pipeline/src/phases/const_collection.ts @@ -25,7 +25,8 @@ export function collectElementConsts(job: CompilationJob): void { for (const unit of job.units) { for (const op of unit.create) { if (op.kind === ir.OpKind.ExtractedAttribute) { - const attributes = allElementAttributes.get(op.target) || new ElementAttributes(); + const attributes = + allElementAttributes.get(op.target) || new ElementAttributes(job.compatibility); allElementAttributes.set(op.target, attributes); attributes.add(op.bindingKind, op.name, op.expression, op.trustedValueFn); ir.OpList.remove(op); @@ -73,7 +74,7 @@ const FLYWEIGHT_ARRAY: ReadonlyArray = Object.freeze(); + private known = new Map>(); private byKind = new Map; projectAs: string|null = null; @@ -102,12 +103,30 @@ class ElementAttributes { return this.byKind.get(ir.BindingKind.I18n) ?? FLYWEIGHT_ARRAY; } + constructor(private compatibility: ir.CompatibilityMode) {} + + isKnown(kind: ir.BindingKind, name: string, value: o.Expression|null) { + const nameToValue = this.known.get(kind) ?? new Set(); + this.known.set(kind, nameToValue); + if (nameToValue.has(name)) { + return true; + } + nameToValue.add(name); + return false; + } + add(kind: ir.BindingKind, name: string, value: o.Expression|null, trustedValueFn: o.Expression|null): void { - if (this.known.has(name)) { + // TemplateDefinitionBuilder puts duplicate attribute, class, and style values into the consts + // array. This seems inefficient, we can probably keep just the first one or the last value + // (whichever actually gets applied when multiple values are listed for the same attribute). + const allowDuplicates = this.compatibility === ir.CompatibilityMode.TemplateDefinitionBuilder && + (kind === ir.BindingKind.Attribute || kind === ir.BindingKind.ClassName || + kind === ir.BindingKind.StyleProperty); + if (!allowDuplicates && this.isKnown(kind, name, value)) { return; } - this.known.add(name); + // TODO: Can this be its own phase if (name === 'ngProjectAs') { if (value === null || !(value instanceof o.LiteralExpr) || (value.value == null) || @@ -151,7 +170,7 @@ class ElementAttributes { * Gets an array of literal expressions representing the attribute's namespaced name. */ function getAttributeNameLiterals(name: string): o.LiteralExpr[] { - const [attributeNamespace, attributeName] = splitNsName(name); + const [attributeNamespace, attributeName] = splitNsName(name, false); const nameLiteral = o.literal(attributeName); if (attributeNamespace) { diff --git a/packages/compiler/src/template/pipeline/src/phases/create_defer_deps_fns.ts b/packages/compiler/src/template/pipeline/src/phases/create_defer_deps_fns.ts index 56b8f4517a239..9cc8f58c8d20d 100644 --- a/packages/compiler/src/template/pipeline/src/phases/create_defer_deps_fns.ts +++ b/packages/compiler/src/template/pipeline/src/phases/create_defer_deps_fns.ts @@ -42,7 +42,8 @@ export function createDeferDepsFns(job: ComponentCompilationJob): void { 'AssertionError: slot must be assigned bfore extracting defer deps functions'); } op.resolverFn = job.pool.getSharedFunctionReference( - depsFnExpr, `${job.componentName}_Defer_${op.handle.slot}_DepsFn`); + depsFnExpr, `${job.componentName}_Defer_${op.handle.slot}_DepsFn`, + /* Don't use unique names for TDB compatibility */ false); } } } diff --git a/packages/compiler/src/template/pipeline/src/phases/deduplicate_text_bindings.ts b/packages/compiler/src/template/pipeline/src/phases/deduplicate_text_bindings.ts new file mode 100644 index 0000000000000..63f54abc431cb --- /dev/null +++ b/packages/compiler/src/template/pipeline/src/phases/deduplicate_text_bindings.ts @@ -0,0 +1,41 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +import * as ir from '../../ir'; +import type {CompilationJob} from '../compilation'; + +/** + * Deduplicate text bindings, e.g.
+ */ +export function deduplicateTextBindings(job: CompilationJob): void { + const seen = new Map>(); + for (const unit of job.units) { + for (const op of unit.update.reversed()) { + if (op.kind === ir.OpKind.Binding && op.isTextAttribute) { + const seenForElement = seen.get(op.target) || new Set(); + if (seenForElement.has(op.name)) { + if (job.compatibility === ir.CompatibilityMode.TemplateDefinitionBuilder) { + // For most duplicated attributes, TemplateDefinitionBuilder lists all of the values in + // the consts array. However, for style and class attributes it only keeps the last one. + // We replicate that behavior here since it has actual consequences for apps with + // duplicate class or style attrs. + if (op.name === 'style' || op.name === 'class') { + ir.OpList.remove(op); + } + } else { + // TODO: Determine the correct behavior. It would probably make sense to merge multiple + // style and class attributes. Alternatively we could just throw an error, as HTML + // doesn't permit duplicate attributes. + } + } + seenForElement.add(op.name); + seen.set(op.target, seenForElement); + } + } + } +} diff --git a/packages/compiler/src/template/pipeline/src/phases/host_style_property_parsing.ts b/packages/compiler/src/template/pipeline/src/phases/host_style_property_parsing.ts index 87b8b1b8071af..c42dfd2fcfe57 100644 --- a/packages/compiler/src/template/pipeline/src/phases/host_style_property_parsing.ts +++ b/packages/compiler/src/template/pipeline/src/phases/host_style_property_parsing.ts @@ -25,7 +25,7 @@ const BANG_IMPORTANT = '!important'; */ export function parseHostStyleProperties(job: CompilationJob): void { for (const op of job.root.update) { - if (op.kind !== ir.OpKind.Binding) { + if (!(op.kind === ir.OpKind.Binding && op.bindingKind === ir.BindingKind.Property)) { continue; } diff --git a/packages/compiler/src/template/pipeline/src/phases/parse_extracted_styles.ts b/packages/compiler/src/template/pipeline/src/phases/parse_extracted_styles.ts index 6e385faea8710..4695046e0d4cf 100644 --- a/packages/compiler/src/template/pipeline/src/phases/parse_extracted_styles.ts +++ b/packages/compiler/src/template/pipeline/src/phases/parse_extracted_styles.ts @@ -18,10 +18,32 @@ import type {CompilationJob} from '../compilation'; * class property. */ export function parseExtractedStyles(job: CompilationJob) { + const elements = new Map(); + + for (const unit of job.units) { + for (const op of unit.create) { + if (ir.isElementOrContainerOp(op)) { + elements.set(op.xref, op); + } + } + } + for (const unit of job.units) { for (const op of unit.create) { if (op.kind === ir.OpKind.ExtractedAttribute && op.bindingKind === ir.BindingKind.Attribute && ir.isStringLiteral(op.expression!)) { + const target = elements.get(op.target)!; + + if (target !== undefined && target.kind === ir.OpKind.Template && + target.templateKind === ir.TemplateKind.Structural) { + // TemplateDefinitionBuilder will not apply class and style bindings to structural + // directives; instead, it will leave them as attributes. + // (It's not clear what that would mean, anyway -- classes and styles on a structural + // element should probably be a parse error.) + // TODO: We may be able to remove this once Template Pipeline is the default. + continue; + } + if (op.name === 'style') { const parsedStyles = parseStyle(op.expression.value); for (let i = 0; i < parsedStyles.length - 1; i += 2) { diff --git a/packages/compiler/src/template/pipeline/src/phases/reify.ts b/packages/compiler/src/template/pipeline/src/phases/reify.ts index a68ec1202e85b..b50d9f043078e 100644 --- a/packages/compiler/src/template/pipeline/src/phases/reify.ts +++ b/packages/compiler/src/template/pipeline/src/phases/reify.ts @@ -49,14 +49,14 @@ function reifyCreateOperations(unit: CompilationUnit, ops: ir.OpList { + const results = new Set(); + const visit = (node: ts.Node): void => { + if (ts.isIdentifier(node) && names.includes(node.text)) { + results.add(node); + } + ts.forEachChild(node, visit); + }; + visit(sourceFile); + return results; +} diff --git a/packages/core/schematics/ng-generate/control-flow-migration/migration.ts b/packages/core/schematics/ng-generate/control-flow-migration/migration.ts index a60b0192a7d7e..15636b62218e8 100644 --- a/packages/core/schematics/ng-generate/control-flow-migration/migration.ts +++ b/packages/core/schematics/ng-generate/control-flow-migration/migration.ts @@ -47,7 +47,7 @@ export function migrateTemplate( const parsingError = { type: 'parse', error: new Error( - `The migration resulted in invalid HTML for ${file.sourceFilePath}. ` + + `The migration resulted in invalid HTML for ${file.sourceFile.fileName}. ` + `Please check the template for valid HTML structures and run the migration again.`) }; return {migrated: template, errors: [parsingError]}; @@ -68,11 +68,21 @@ export function migrateTemplate( // whether it's safe to remove the CommonModule to the // original component class source file if (templateType === 'templateUrl' && analyzedFiles !== null && - analyzedFiles.has(file.sourceFilePath)) { - const componentFile = analyzedFiles.get(file.sourceFilePath)!; + analyzedFiles.has(file.sourceFile.fileName)) { + const componentFile = analyzedFiles.get(file.sourceFile.fileName)!; + componentFile.getSortedRanges(); + // we have already checked the template file to see if it is safe to remove the imports + // and common module. This check is passed off to the associated .ts file here so + // the class knows whether it's safe to remove from the template side. componentFile.removeCommonModule = file.removeCommonModule; componentFile.canRemoveImports = file.canRemoveImports; + + // At this point, we need to verify the component class file doesn't have any other imports + // that prevent safe removal of common module. It could be that there's an associated ngmodule + // and in that case we can't safely remove the common module import. + componentFile.verifyCanRemoveImports(); } + file.verifyCanRemoveImports(); errors = [ ...ifResult.errors, @@ -81,7 +91,7 @@ export function migrateTemplate( ...caseResult.errors, ]; } else if (file.canRemoveImports) { - migrated = removeImports(template, node, file.removeCommonModule); + migrated = removeImports(template, node, file); } return {migrated, errors}; diff --git a/packages/core/schematics/ng-generate/control-flow-migration/types.ts b/packages/core/schematics/ng-generate/control-flow-migration/types.ts index 428647c83254d..658abf0d5f91a 100644 --- a/packages/core/schematics/ng-generate/control-flow-migration/types.ts +++ b/packages/core/schematics/ng-generate/control-flow-migration/types.ts @@ -9,6 +9,8 @@ import {Attribute, Element, ParseTreeResult, RecursiveVisitor, Text} from '@angular/compiler'; import ts from 'typescript'; +import {lookupIdentifiersInSourceFile} from './identifier-lookup'; + export const ngtemplate = 'ng-template'; export const boundngifelse = '[ngIfElse]'; export const boundngifthenelse = '[ngIfThenElse]'; @@ -21,6 +23,13 @@ export const endMarker = '✢'; export const startI18nMarker = '⚈'; export const endI18nMarker = '⚉'; +export const importRemovals = [ + 'NgIf', 'NgIfElse', 'NgIfThenElse', 'NgFor', 'NgForOf', 'NgForTrackBy', 'NgSwitch', + 'NgSwitchCase', 'NgSwitchDefault' +]; + +export const importWithCommonRemovals = [...importRemovals, 'CommonModule']; + function allFormsOf(selector: string): string[] { return [ selector, @@ -71,7 +80,7 @@ const commonModulePipes = [ */ type Range = { start: number, - end?: number, node: ts.Node, type: string, + end?: number, node: ts.Node, type: string, remove: boolean, }; export type Offsets = { @@ -252,18 +261,25 @@ export class AnalyzedFile { private ranges: Range[] = []; removeCommonModule = false; canRemoveImports = false; - sourceFilePath: string = ''; + sourceFile: ts.SourceFile; + importRanges: Range[] = []; + templateRanges: Range[] = []; + + constructor(sourceFile: ts.SourceFile) { + this.sourceFile = sourceFile; + } /** Returns the ranges in the order in which they should be migrated. */ getSortedRanges(): Range[] { // templates first for checking on whether certain imports can be safely removed - const templateRanges = this.ranges.slice() - .filter(x => x.type !== 'import') - .sort((aStart, bStart) => bStart.start - aStart.start); - const importRanges = this.ranges.slice() - .filter(x => x.type === 'import') - .sort((aStart, bStart) => bStart.start - aStart.start); - return [...templateRanges, ...importRanges]; + this.templateRanges = this.ranges.slice() + .filter(x => x.type === 'template' || x.type === 'templateUrl') + .sort((aStart, bStart) => bStart.start - aStart.start); + this.importRanges = + this.ranges.slice() + .filter(x => x.type === 'importDecorator' || x.type === 'importDeclaration') + .sort((aStart, bStart) => bStart.start - aStart.start); + return [...this.templateRanges, ...this.importRanges]; } /** @@ -273,13 +289,12 @@ export class AnalyzedFile { * @param range Range to be added. */ static addRange( - path: string, sourceFilePath: string, analyzedFiles: Map, + path: string, sourceFile: ts.SourceFile, analyzedFiles: Map, range: Range): void { let analysis = analyzedFiles.get(path); if (!analysis) { - analysis = new AnalyzedFile(); - analysis.sourceFilePath = sourceFilePath; + analysis = new AnalyzedFile(sourceFile); analyzedFiles.set(path, analysis); } @@ -290,6 +305,34 @@ export class AnalyzedFile { analysis.ranges.push(range); } } + + /** + * This verifies whether a component class is safe to remove module imports. + * It is only run on .ts files. + */ + verifyCanRemoveImports() { + // if we already know it's not safe to remove the common module import + // skip this check entirely + if (this.removeCommonModule) { + const importDeclaration = this.importRanges.find(r => r.type === 'importDeclaration'); + const instances = lookupIdentifiersInSourceFile(this.sourceFile, importWithCommonRemovals); + let foundImportDeclaration = false; + let count = 0; + for (let range of this.importRanges) { + for (let instance of instances) { + if (instance.getStart() >= range.start && instance.getEnd() <= range.end!) { + if (range === importDeclaration) { + foundImportDeclaration = true; + } + count++; + } + } + } + if (instances.size !== count && importDeclaration !== undefined && foundImportDeclaration) { + importDeclaration.remove = false; + } + } + } } /** Finds all non-control flow elements from common module. */ diff --git a/packages/core/schematics/ng-generate/control-flow-migration/util.ts b/packages/core/schematics/ng-generate/control-flow-migration/util.ts index 48b52d149fac6..23d3bd3ce1624 100644 --- a/packages/core/schematics/ng-generate/control-flow-migration/util.ts +++ b/packages/core/schematics/ng-generate/control-flow-migration/util.ts @@ -10,13 +10,8 @@ import {Attribute, Element, HtmlParser, Node, ParseTreeResult, visitAll} from '@ import {dirname, join} from 'path'; import ts from 'typescript'; -import {AnalyzedFile, CommonCollector, ElementCollector, ElementToMigrate, endI18nMarker, endMarker, i18nCollector, ParseResult, startI18nMarker, startMarker, Template, TemplateCollector} from './types'; +import {AnalyzedFile, CommonCollector, ElementCollector, ElementToMigrate, endI18nMarker, endMarker, i18nCollector, importRemovals, importWithCommonRemovals, ParseResult, startI18nMarker, startMarker, Template, TemplateCollector} from './types'; -const importRemovals = [ - 'NgIf', 'NgIfElse', 'NgIfThenElse', 'NgFor', 'NgForOf', 'NgForTrackBy', 'NgSwitch', - 'NgSwitchCase', 'NgSwitchDefault' -]; -const importWithCommonRemovals = [...importRemovals, 'CommonModule']; const startMarkerRegex = new RegExp(startMarker, 'gm'); const endMarkerRegex = new RegExp(endMarker, 'gm'); const startI18nMarkerRegex = new RegExp(startI18nMarker, 'gm'); @@ -38,13 +33,18 @@ export function analyze(sourceFile: ts.SourceFile, analyzedFiles: Map r.type === 'importDeclaration'); + if (range === undefined || !range.remove) { + return false; + } + // should change if you can remove the common module // if it's not safe to remove the common module // and that's the only thing there, we should do nothing. const clause = decl.getChildAt(1) as ts.ImportClause; return !( - !removeCommonModule && clause.namedBindings && ts.isNamedImports(clause.namedBindings) && + !file.removeCommonModule && clause.namedBindings && ts.isNamedImports(clause.namedBindings) && clause.namedBindings.elements.length === 1 && clause.namedBindings.elements[0].getText() === 'CommonModule'); } @@ -109,9 +109,13 @@ function analyzeImportDeclarations( const elements = clause.namedBindings.elements.filter(el => importWithCommonRemovals.includes(el.getText())); if (elements.length > 0) { - AnalyzedFile.addRange( - sourceFile.fileName, sourceFile.fileName, analyzedFiles, - {start: node.getStart(), end: node.getEnd(), node, type: 'import'}); + AnalyzedFile.addRange(sourceFile.fileName, sourceFile, analyzedFiles, { + start: node.getStart(), + end: node.getEnd(), + node, + type: 'importDeclaration', + remove: true + }); } } } @@ -148,20 +152,22 @@ function analyzeDecorators( switch (prop.name.text) { case 'template': // +1/-1 to exclude the opening/closing characters from the range. - AnalyzedFile.addRange(sourceFile.fileName, sourceFile.fileName, analyzedFiles, { + AnalyzedFile.addRange(sourceFile.fileName, sourceFile, analyzedFiles, { start: prop.initializer.getStart() + 1, end: prop.initializer.getEnd() - 1, node: prop, - type: 'template' + type: 'template', + remove: true, }); break; case 'imports': - AnalyzedFile.addRange(sourceFile.fileName, sourceFile.fileName, analyzedFiles, { + AnalyzedFile.addRange(sourceFile.fileName, sourceFile, analyzedFiles, { start: prop.name.getStart(), end: prop.initializer.getEnd(), node: prop, - type: 'import' + type: 'importDecorator', + remove: true, }); break; @@ -170,8 +176,8 @@ function analyzeDecorators( if (ts.isStringLiteralLike(prop.initializer)) { const path = join(dirname(sourceFile.fileName), prop.initializer.text); AnalyzedFile.addRange( - path, sourceFile.fileName, analyzedFiles, - {start: 0, node: prop, type: 'templateUrl'}); + path, sourceFile, analyzedFiles, + {start: 0, node: prop, type: 'templateUrl', remove: true}); } break; } @@ -401,13 +407,12 @@ export function canRemoveCommonModule(template: string): boolean { /** * removes imports from template imports and import declarations */ -export function removeImports( - template: string, node: ts.Node, removeCommonModule: boolean): string { +export function removeImports(template: string, node: ts.Node, file: AnalyzedFile): string { if (template.startsWith('imports') && ts.isPropertyAssignment(node)) { - const updatedImport = updateClassImports(node, removeCommonModule); + const updatedImport = updateClassImports(node, file.removeCommonModule); return updatedImport ?? template; - } else if (ts.isImportDeclaration(node) && checkIfShouldChange(node, removeCommonModule)) { - return updateImportDeclaration(node, removeCommonModule); + } else if (ts.isImportDeclaration(node) && checkIfShouldChange(node, file)) { + return updateImportDeclaration(node, file.removeCommonModule); } return template; } @@ -577,6 +582,19 @@ export function formatTemplate(tmpl: string, templateType: string): string { //
||
]*\/>)[^>]*>?/; + // regex for matching an attribute string that was left open at the endof a line + // so we can ensure we have the proper indent + //
+ const closeAttrDoubleRegex = /^\s*([^><]|\\")*"/; + const closeAttrSingleRegex = /^\s*([^><]|\\')*'/; + // regex for matching a self closing html element that has no /> // const selfClosingRegex = new RegExp(`^\\s*<(${selfClosingList}).+\\/?>`); @@ -615,6 +633,8 @@ export function formatTemplate(tmpl: string, templateType: string): string { let i18nDepth = 0; let inMigratedBlock = false; let inI18nBlock = false; + let inAttribute = false; + let isDoubleQuotes = false; for (let [index, line] of lines.entries()) { depth += [...line.matchAll(startMarkerRegex)].length - [...line.matchAll(endMarkerRegex)].length; @@ -628,7 +648,7 @@ export function formatTemplate(tmpl: string, templateType: string): string { lineWasMigrated = true; } if ((line.trim() === '' && index !== 0 && index !== lines.length - 1) && - (inMigratedBlock || lineWasMigrated)) { + (inMigratedBlock || lineWasMigrated) && !inI18nBlock && !inAttribute) { // skip blank lines except if it's the first line or last line // this preserves leading and trailing spaces if they are already present continue; @@ -650,10 +670,25 @@ export function formatTemplate(tmpl: string, templateType: string): string { indent = indent.slice(2); } - const newLine = - inI18nBlock ? line : mindent + (line.trim() !== '' ? indent : '') + line.trim(); + // if a line ends in an unclosed attribute, we need to note that and close it later + if (!inAttribute && openAttrDoubleRegex.test(line)) { + inAttribute = true; + isDoubleQuotes = true; + } else if (!inAttribute && openAttrSingleRegex.test(line)) { + inAttribute = true; + isDoubleQuotes = false; + } + + const newLine = (inI18nBlock || inAttribute) ? + line : + mindent + (line.trim() !== '' ? indent : '') + line.trim(); formatted.push(newLine); + if ((inAttribute && isDoubleQuotes && closeAttrDoubleRegex.test(line)) || + (inAttribute && !isDoubleQuotes && closeAttrSingleRegex.test(line))) { + inAttribute = false; + } + // this matches any self closing element that actually has a /> if (closeMultiLineElRegex.test(line)) { // multi line self closing tag diff --git a/packages/core/schematics/test/control_flow_migration_spec.ts b/packages/core/schematics/test/control_flow_migration_spec.ts index cb4f5319110af..04c95d46ffe01 100644 --- a/packages/core/schematics/test/control_flow_migration_spec.ts +++ b/packages/core/schematics/test/control_flow_migration_spec.ts @@ -4729,6 +4729,7 @@ describe('control flow migration', () => { `

`, `Content here`, ``, + ` `, `

Else Content

`, `
`, `
`, @@ -4745,6 +4746,7 @@ describe('control flow migration', () => { ` Content here`, ` } @else {`, ` `, + ` `, `

Else Content

`, `
`, ` }`, @@ -4753,6 +4755,83 @@ describe('control flow migration', () => { expect(actual).toBe(expected); }); + + it('should indent multi-line attribute strings to the right place', async () => { + writeFile('/comp.ts', ` + import {Component} from '@angular/core'; + import {NgIf} from '@angular/common'; + + @Component({ + templateUrl: './comp.html' + }) + class Comp { + show = false; + } + `); + + writeFile('/comp.html', [ + `
show
`, + ``, + ` Content here`, + ``, + ].join('\n')); + + await runMigration(); + const actual = tree.readContent('/comp.html'); + const expected = [ + `@if (show) {`, + `
show
`, + `}`, + ``, + ` Content here`, + ``, + ].join('\n'); + + expect(actual).toBe(expected); + }); + + it('should indent multi-line attribute strings as single quotes to the right place', + async () => { + writeFile('/comp.ts', ` + import {Component} from '@angular/core'; + import {NgIf} from '@angular/common'; + + @Component({ + templateUrl: './comp.html' + }) + class Comp { + show = false; + } + `); + + writeFile('/comp.html', [ + `
show
`, + ``, + ` Content here`, + ``, + ].join('\n')); + + await runMigration(); + const actual = tree.readContent('/comp.html'); + const expected = [ + `@if (show) {`, + `
show
`, + `}`, + ``, + ` Content here`, + ``, + ].join('\n'); + + expect(actual).toBe(expected); + }); }); describe('imports', () => { @@ -5019,6 +5098,134 @@ describe('control flow migration', () => { expect(actual).toBe(expected); }); + + it('should not remove common module when more common module symbols are found', async () => { + writeFile('/comp.ts', [ + `import {Component, NgModule} from '@angular/core';`, + `import {CommonModule} from '@angular/common';\n`, + `@Component({`, + ` selector: 'example-cmp',`, + ` templateUrl: './comp.html',`, + `})`, + `export class ExampleCmp {`, + `}`, + `@Component({`, + ` standalone: true`, + ` selector: 'example2-cmp',`, + ` imports: [CommonModule],`, + ` templateUrl: './comp.html',`, + `})`, + `export class Example2Cmp {`, + `}`, + `const NG_MODULE_IMPORTS = [CommonModule, OtherModule];`, + ``, + `@NgModule({`, + ` declarations: [ExampleCmp],`, + ` exports: [ExampleCmp],`, + ` imports: [NG_MODULE_IMPORTS],`, + `})`, + `export class ExampleModule {}`, + ].join('\n')); + + writeFile('/comp.html', [ + `
`, + `Content here`, + `
`, + ].join('\n')); + + await runMigration(); + const actual = tree.readContent('/comp.ts'); + const expected = [ + `import {Component, NgModule} from '@angular/core';`, + `import {CommonModule} from '@angular/common';\n`, + `@Component({`, + ` selector: 'example-cmp',`, + ` templateUrl: './comp.html',`, + `})`, + `export class ExampleCmp {`, + `}`, + `@Component({`, + ` standalone: true`, + ` selector: 'example2-cmp',`, + ` imports: [],`, + ` templateUrl: './comp.html',`, + `})`, + `export class Example2Cmp {`, + `}`, + `const NG_MODULE_IMPORTS = [CommonModule, OtherModule];`, + ``, + `@NgModule({`, + ` declarations: [ExampleCmp],`, + ` exports: [ExampleCmp],`, + ` imports: [NG_MODULE_IMPORTS],`, + `})`, + `export class ExampleModule {}`, + ].join('\n'); + + expect(actual).toBe(expected); + }); + + it('should not remove imports when mismatch in counts', async () => { + writeFile('/comp.ts', [ + `import {CommonModule} from '@angular/common';`, + `import {Component, NgModule, Pipe, PipeTransform} from '@angular/core';`, + `@Component({`, + ` selector: 'description',`, + ` template: \`{{getDescription()}}\`,`, + `})`, + `export class DescriptionController {`, + ` getDescription(): string {`, + ` return 'stuff';`, + ` }`, + `}`, + ``, + `@Pipe({name: 'description'})`, + `export class DescriptionPipe implements PipeTransform {`, + ` transform(nameString?: string): string {`, + ` return nameString ?? '';`, + ` }`, + `}`, + `@NgModule({`, + ` declarations: [DescriptionController, DescriptionPipe],`, + ` imports: [CommonModule],`, + ` providers: [],`, + ` exports: [DescriptionController, DescriptionPipe],`, + `})`, + `export class DescriptionModule {}`, + ].join('\n')); + + await runMigration(); + const actual = tree.readContent('/comp.ts'); + const expected = [ + `import {CommonModule} from '@angular/common';`, + `import {Component, NgModule, Pipe, PipeTransform} from '@angular/core';`, + `@Component({`, + ` selector: 'description',`, + ` template: \`{{getDescription()}}\`,`, + `})`, + `export class DescriptionController {`, + ` getDescription(): string {`, + ` return 'stuff';`, + ` }`, + `}`, + ``, + `@Pipe({name: 'description'})`, + `export class DescriptionPipe implements PipeTransform {`, + ` transform(nameString?: string): string {`, + ` return nameString ?? '';`, + ` }`, + `}`, + `@NgModule({`, + ` declarations: [DescriptionController, DescriptionPipe],`, + ` imports: [CommonModule],`, + ` providers: [],`, + ` exports: [DescriptionController, DescriptionPipe],`, + `})`, + `export class DescriptionModule {}`, + ].join('\n'); + + expect(actual).toBe(expected); + }); }); describe('no migration needed', () => { diff --git a/packages/core/src/event_emitter.ts b/packages/core/src/event_emitter.ts index a7eea17c14011..fca146714551c 100644 --- a/packages/core/src/event_emitter.ts +++ b/packages/core/src/event_emitter.ts @@ -6,8 +6,6 @@ * found in the LICENSE file at https://angular.io/license */ -/// - import {PartialObserver, Subject, Subscription} from 'rxjs'; /** diff --git a/packages/core/src/render3/component_ref.ts b/packages/core/src/render3/component_ref.ts index 5a30f134c248a..40be1e456b450 100644 --- a/packages/core/src/render3/component_ref.ts +++ b/packages/core/src/render3/component_ref.ts @@ -23,7 +23,6 @@ import {NgModuleRef} from '../linker/ng_module_factory'; import {Renderer2, RendererFactory2} from '../render/api'; import {Sanitizer} from '../sanitization/sanitizer'; import {assertDefined, assertGreaterThan, assertIndexInRange} from '../util/assert'; -import {VERSION} from '../version'; import {NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR} from '../view/provider_flags'; import {AfterRenderEventManager} from './after_render_hooks'; @@ -501,7 +500,8 @@ function setRootNodeAttributes( hostRenderer: Renderer2, componentDef: ComponentDef, hostRNode: RElement, rootSelectorOrNode: any) { if (rootSelectorOrNode) { - setUpAttributes(hostRenderer, hostRNode, ['ng-version', VERSION.full]); + // The placeholder will be replaced with the actual version at build time. + setUpAttributes(hostRenderer, hostRNode, ['ng-version', '0.0.0-PLACEHOLDER']); } else { // If host element is created as a part of this function call (i.e. `rootSelectorOrNode` // is not defined), also apply attributes and classes extracted from component selector. diff --git a/packages/core/src/version.ts b/packages/core/src/version.ts index 71a5cb88781c8..bc87cf7ae5384 100644 --- a/packages/core/src/version.ts +++ b/packages/core/src/version.ts @@ -17,9 +17,10 @@ export class Version { public readonly patch: string; constructor(public full: string) { - this.major = full.split('.')[0]; - this.minor = full.split('.')[1]; - this.patch = full.split('.').slice(2).join('.'); + const parts = full.split('.'); + this.major = parts[0]; + this.minor = parts[1]; + this.patch = parts.slice(2).join('.'); } } diff --git a/packages/core/test/acceptance/initial_render_pending_tasks_spec.ts b/packages/core/test/acceptance/initial_render_pending_tasks_spec.ts index 32e8b2da71b63..ce4e87e94c987 100644 --- a/packages/core/test/acceptance/initial_render_pending_tasks_spec.ts +++ b/packages/core/test/acceptance/initial_render_pending_tasks_spec.ts @@ -53,9 +53,9 @@ describe('InitialRenderPendingTasks', () => { function hasPendingTasks(pendingTasks: InitialRenderPendingTasks): Promise { return of(EMPTY) - .pipe( - withLatestFrom(pendingTasks.hasPendingTasks), - map(([_, hasPendingTasks]) => hasPendingTasks), - ) - .toPromise(); + .pipe( + withLatestFrom(pendingTasks.hasPendingTasks), + map(([_, hasPendingTasks]) => hasPendingTasks), + ) + .toPromise() as Promise; } diff --git a/packages/core/test/acceptance/outputs_spec.ts b/packages/core/test/acceptance/outputs_spec.ts index c265ad92eab57..10a234722f7a0 100644 --- a/packages/core/test/acceptance/outputs_spec.ts +++ b/packages/core/test/acceptance/outputs_spec.ts @@ -13,14 +13,14 @@ import {TestBed} from '@angular/core/testing'; describe('outputs', () => { @Component({selector: 'button-toggle', template: ''}) class ButtonToggle { - @Output('change') change = new EventEmitter(); + @Output('change') change = new EventEmitter(); - @Output('reset') resetStream = new EventEmitter(); + @Output('reset') resetStream = new EventEmitter(); } @Directive({selector: '[otherDir]'}) class OtherDir { - @Output('change') changeStream = new EventEmitter(); + @Output('change') changeStream = new EventEmitter(); } @Component({selector: 'destroy-comp', template: ''}) @@ -33,7 +33,7 @@ describe('outputs', () => { @Directive({selector: '[myButton]'}) class MyButton { - @Output() click = new EventEmitter(); + @Output() click = new EventEmitter(); } it('should call component output function when event is emitted', () => { diff --git a/packages/core/test/acceptance/property_binding_spec.ts b/packages/core/test/acceptance/property_binding_spec.ts index a6cada6e8fcff..092fccf69f89b 100644 --- a/packages/core/test/acceptance/property_binding_spec.ts +++ b/packages/core/test/acceptance/property_binding_spec.ts @@ -396,7 +396,7 @@ describe('property bindings', () => { class MyDir { @Input() role: string|undefined; @Input('dir') direction: string|undefined; - @Output('change') changeStream = new EventEmitter(); + @Output('change') changeStream = new EventEmitter(); } @Directive({selector: '[myDirB]'}) diff --git a/packages/core/test/bundling/animations-standalone/bundle.golden_symbols.json b/packages/core/test/bundling/animations-standalone/bundle.golden_symbols.json index e2e91b51373a3..2aae6dac46439 100644 --- a/packages/core/test/bundling/animations-standalone/bundle.golden_symbols.json +++ b/packages/core/test/bundling/animations-standalone/bundle.golden_symbols.json @@ -101,6 +101,9 @@ { "name": "CIRCULAR" }, + { + "name": "COMPLETE_NOTIFICATION" + }, { "name": "COMPONENT_REGEX" }, @@ -135,10 +138,7 @@ "name": "ComponentRef2" }, { - "name": "ConnectableObservable" - }, - { - "name": "ConnectableSubscriber" + "name": "ConsumerObserver" }, { "name": "DASH_CASE_REGEXP" @@ -164,18 +164,15 @@ { "name": "DefaultDomRenderer2" }, - { - "name": "DistinctUntilChangedOperator" - }, - { - "name": "DistinctUntilChangedSubscriber" - }, { "name": "DomAdapter" }, { "name": "DomRendererFactory2" }, + { + "name": "EMPTY" + }, { "name": "EMPTY_ARRAY" }, @@ -188,12 +185,18 @@ { "name": "EMPTY_OBJECT" }, + { + "name": "EMPTY_OBSERVER" + }, { "name": "EMPTY_PAYLOAD" }, { "name": "EMPTY_PLAYER_ARRAY" }, + { + "name": "EMPTY_SUBSCRIPTION" + }, { "name": "ENTER_TOKEN_REGEX" }, @@ -287,18 +290,6 @@ { "name": "MOVED_VIEWS" }, - { - "name": "MapOperator" - }, - { - "name": "MapSubscriber" - }, - { - "name": "MergeMapOperator" - }, - { - "name": "MergeMapSubscriber" - }, { "name": "NAMESPACE_URIS" }, @@ -401,6 +392,9 @@ { "name": "Observable" }, + { + "name": "OperatorSubscriber" + }, { "name": "PARAM_REGEX" }, @@ -425,12 +419,6 @@ { "name": "REMOVE_STYLES_ON_COMPONENT_DESTROY" }, - { - "name": "RefCountOperator" - }, - { - "name": "RefCountSubscriber" - }, { "name": "RendererFactory2" }, @@ -461,12 +449,6 @@ { "name": "SimpleChange" }, - { - "name": "SimpleInnerSubscriber" - }, - { - "name": "SimpleOuterSubscriber" - }, { "name": "SpecialCasedStyles" }, @@ -482,24 +464,12 @@ { "name": "Subject" }, - { - "name": "SubjectSubscriber" - }, - { - "name": "SubjectSubscription" - }, { "name": "Subscriber" }, { "name": "Subscription" }, - { - "name": "SwitchMapOperator" - }, - { - "name": "SwitchMapSubscriber" - }, { "name": "TESTABILITY" }, @@ -533,9 +503,6 @@ { "name": "UnsubscriptionError" }, - { - "name": "VERSION" - }, { "name": "ViewEncapsulation" }, @@ -566,6 +533,12 @@ { "name": "_NullComponentFactoryResolver" }, + { + "name": "__asyncValues" + }, + { + "name": "__await" + }, { "name": "__forward_ref__" }, @@ -573,13 +546,13 @@ "name": "_applyRootElementTransformImpl" }, { - "name": "_convertTimeValueToMS" + "name": "_bind" }, { - "name": "_currentInjector" + "name": "_convertTimeValueToMS" }, { - "name": "_enable_super_gross_mode_that_will_cause_bad_things" + "name": "_currentInjector" }, { "name": "_flattenGroupPlayersRecur" @@ -656,6 +629,9 @@ { "name": "applyView" }, + { + "name": "arrRemove" + }, { "name": "assertConsumerNode" }, @@ -668,6 +644,9 @@ { "name": "baseElement" }, + { + "name": "bind" + }, { "name": "bloomHasToken" }, @@ -725,9 +704,6 @@ { "name": "configureViewWithDirective" }, - { - "name": "connectableObservableDescriptor" - }, { "name": "consumerIsLive" }, @@ -737,6 +713,9 @@ { "name": "containsElement" }, + { + "name": "context" + }, { "name": "convertToBitFlags" }, @@ -749,9 +728,15 @@ { "name": "createElementRef" }, + { + "name": "createErrorClass" + }, { "name": "createInjector" }, + { + "name": "createInvalidObservableTypeError" + }, { "name": "createLFrame" }, @@ -761,6 +746,12 @@ { "name": "createNodeInjector" }, + { + "name": "createNotification" + }, + { + "name": "createOperatorSubscriber" + }, { "name": "createTView" }, @@ -779,6 +770,9 @@ { "name": "deepForEachProvider" }, + { + "name": "defaultCompare" + }, { "name": "detachMovedView" }, @@ -803,12 +797,6 @@ { "name": "documentElement" }, - { - "name": "empty" - }, - { - "name": "empty2" - }, { "name": "enterDI" }, @@ -821,6 +809,12 @@ { "name": "eraseStyles" }, + { + "name": "errorContext" + }, + { + "name": "execFinalizer" + }, { "name": "executeCheckHooks" }, @@ -830,6 +824,9 @@ { "name": "executeInitAndCheckHooks" }, + { + "name": "executeSchedule" + }, { "name": "executeTemplate" }, @@ -851,9 +848,6 @@ { "name": "findAttrIndexInNode" }, - { - "name": "flattenUnsubscriptionErrors" - }, { "name": "forEachSingleProvider" }, @@ -867,7 +861,7 @@ "name": "from" }, { - "name": "fromArray" + "name": "fromAsyncIterable" }, { "name": "generateInitialInputs" @@ -999,10 +993,16 @@ "name": "getTView" }, { - "name": "hasTagAndTypeMatch" + "name": "handleReset" + }, + { + "name": "handleStoppedNotification" }, { - "name": "hostReportError" + "name": "handleUnhandledError" + }, + { + "name": "hasTagAndTypeMatch" }, { "name": "icuContainerIterate" @@ -1041,7 +1041,7 @@ "name": "injectableDefOrInjectorDefFactory" }, { - "name": "innerSubscribe" + "name": "innerFrom" }, { "name": "insertBloom" @@ -1071,10 +1071,10 @@ "name": "invokeQuery" }, { - "name": "isArray" + "name": "isArrayLike" }, { - "name": "isArrayLike" + "name": "isAsyncIterable" }, { "name": "isComponentDef" @@ -1103,6 +1103,12 @@ { "name": "isInlineTemplate" }, + { + "name": "isInteropObservable" + }, + { + "name": "isIterable" + }, { "name": "isLContainer" }, @@ -1115,9 +1121,6 @@ { "name": "isNodeMatchingSelectorList" }, - { - "name": "isObject" - }, { "name": "isPlatformServer" }, @@ -1131,11 +1134,14 @@ "name": "isPromise2" }, { - "name": "isScheduler" + "name": "isReadableStreamLike" }, { "name": "isStableFactory" }, + { + "name": "isSubscription" + }, { "name": "isTemplateNode" }, @@ -1148,6 +1154,9 @@ { "name": "iterator" }, + { + "name": "last" + }, { "name": "leaveDI" }, @@ -1178,9 +1187,6 @@ { "name": "makeTimingAst" }, - { - "name": "map" - }, { "name": "markAncestorsForTraversal" }, @@ -1199,9 +1205,6 @@ { "name": "maybeWrapInNotSelector" }, - { - "name": "mergeAll" - }, { "name": "mergeHostAttribute" }, @@ -1235,6 +1238,9 @@ { "name": "noop" }, + { + "name": "noop2" + }, { "name": "normalizeAnimationEntry" }, @@ -1250,12 +1256,18 @@ { "name": "observable" }, + { + "name": "observeOn" + }, { "name": "onEnter" }, { "name": "onLeave" }, + { + "name": "operate" + }, { "name": "optimizeGroupPlayer" }, @@ -1265,6 +1277,9 @@ { "name": "parseTimelineCommand" }, + { + "name": "popScheduler" + }, { "name": "processInjectorTypesWithProviders" }, @@ -1281,7 +1296,7 @@ "name": "provideZoneChangeDetection" }, { - "name": "refCount" + "name": "readableStreamLikeToAsyncGenerator" }, { "name": "refreshContentQueries" @@ -1316,6 +1331,9 @@ { "name": "replacePostStylesAsPre" }, + { + "name": "reportUnhandledError" + }, { "name": "requiresRefreshOrTraversal" }, @@ -1337,14 +1355,11 @@ { "name": "roundOffset" }, - { - "name": "rxSubscriber" - }, { "name": "saveNameToExportMap" }, { - "name": "scheduleArray" + "name": "scheduleAsyncIterable" }, { "name": "searchTokensOnInjector" @@ -1394,9 +1409,6 @@ { "name": "setupStaticAttributes" }, - { - "name": "shareSubjectFactory" - }, { "name": "shimStylesContent" }, @@ -1413,16 +1425,13 @@ "name": "style" }, { - "name": "subscribeTo" + "name": "subscribeOn" }, { - "name": "subscribeToArray" - }, - { - "name": "switchMap" + "name": "throwProviderNotFoundError" }, { - "name": "throwProviderNotFoundError" + "name": "timeoutProvider" }, { "name": "toRefArray" diff --git a/packages/core/test/bundling/animations/bundle.golden_symbols.json b/packages/core/test/bundling/animations/bundle.golden_symbols.json index 24266a7e1a32e..3c13424e0bfbf 100644 --- a/packages/core/test/bundling/animations/bundle.golden_symbols.json +++ b/packages/core/test/bundling/animations/bundle.golden_symbols.json @@ -122,6 +122,9 @@ { "name": "CIRCULAR" }, + { + "name": "COMPLETE_NOTIFICATION" + }, { "name": "COMPONENT_REGEX" }, @@ -159,10 +162,7 @@ "name": "ComponentRef2" }, { - "name": "ConnectableObservable" - }, - { - "name": "ConnectableSubscriber" + "name": "ConsumerObserver" }, { "name": "DASH_CASE_REGEXP" @@ -188,12 +188,6 @@ { "name": "DefaultDomRenderer2" }, - { - "name": "DistinctUntilChangedOperator" - }, - { - "name": "DistinctUntilChangedSubscriber" - }, { "name": "DomAdapter" }, @@ -203,6 +197,9 @@ { "name": "DomRendererFactory2" }, + { + "name": "EMPTY" + }, { "name": "EMPTY_ARRAY" }, @@ -215,12 +212,18 @@ { "name": "EMPTY_OBJECT" }, + { + "name": "EMPTY_OBSERVER" + }, { "name": "EMPTY_PAYLOAD" }, { "name": "EMPTY_PLAYER_ARRAY" }, + { + "name": "EMPTY_SUBSCRIPTION" + }, { "name": "ENTER_TOKEN_REGEX" }, @@ -311,18 +314,6 @@ { "name": "MOVED_VIEWS" }, - { - "name": "MapOperator" - }, - { - "name": "MapSubscriber" - }, - { - "name": "MergeMapOperator" - }, - { - "name": "MergeMapSubscriber" - }, { "name": "NAMESPACE_URIS" }, @@ -440,6 +431,9 @@ { "name": "Observable" }, + { + "name": "OperatorSubscriber" + }, { "name": "PARAM_REGEX" }, @@ -467,12 +461,6 @@ { "name": "REMOVE_STYLES_ON_COMPONENT_DESTROY" }, - { - "name": "RefCountOperator" - }, - { - "name": "RefCountSubscriber" - }, { "name": "RendererFactory2" }, @@ -509,12 +497,6 @@ { "name": "SimpleChange" }, - { - "name": "SimpleInnerSubscriber" - }, - { - "name": "SimpleOuterSubscriber" - }, { "name": "SpecialCasedStyles" }, @@ -527,24 +509,12 @@ { "name": "Subject" }, - { - "name": "SubjectSubscriber" - }, - { - "name": "SubjectSubscription" - }, { "name": "Subscriber" }, { "name": "Subscription" }, - { - "name": "SwitchMapOperator" - }, - { - "name": "SwitchMapSubscriber" - }, { "name": "TESTABILITY" }, @@ -590,9 +560,6 @@ { "name": "UnsubscriptionError" }, - { - "name": "VERSION" - }, { "name": "ViewEncapsulation" }, @@ -623,6 +590,12 @@ { "name": "_NullComponentFactoryResolver" }, + { + "name": "__asyncValues" + }, + { + "name": "__await" + }, { "name": "__forward_ref__" }, @@ -630,13 +603,13 @@ "name": "_applyRootElementTransformImpl" }, { - "name": "_convertTimeValueToMS" + "name": "_bind" }, { - "name": "_currentInjector" + "name": "_convertTimeValueToMS" }, { - "name": "_enable_super_gross_mode_that_will_cause_bad_things" + "name": "_currentInjector" }, { "name": "_flattenGroupPlayersRecur" @@ -716,6 +689,9 @@ { "name": "applyView" }, + { + "name": "arrRemove" + }, { "name": "assertConsumerNode" }, @@ -728,6 +704,9 @@ { "name": "baseElement" }, + { + "name": "bind" + }, { "name": "bloomHasToken" }, @@ -785,9 +764,6 @@ { "name": "configureViewWithDirective" }, - { - "name": "connectableObservableDescriptor" - }, { "name": "consumerIsLive" }, @@ -797,6 +773,9 @@ { "name": "containsElement" }, + { + "name": "context" + }, { "name": "convertToBitFlags" }, @@ -809,12 +788,18 @@ { "name": "createElementRef" }, + { + "name": "createErrorClass" + }, { "name": "createInjector" }, { "name": "createInjectorWithoutInjectorInstances" }, + { + "name": "createInvalidObservableTypeError" + }, { "name": "createLFrame" }, @@ -824,6 +809,12 @@ { "name": "createNodeInjector" }, + { + "name": "createNotification" + }, + { + "name": "createOperatorSubscriber" + }, { "name": "createPlatformFactory" }, @@ -845,6 +836,9 @@ { "name": "deepForEachProvider" }, + { + "name": "defaultCompare" + }, { "name": "detachMovedView" }, @@ -869,12 +863,6 @@ { "name": "documentElement" }, - { - "name": "empty" - }, - { - "name": "empty2" - }, { "name": "enterDI" }, @@ -887,6 +875,12 @@ { "name": "eraseStyles" }, + { + "name": "errorContext" + }, + { + "name": "execFinalizer" + }, { "name": "executeCheckHooks" }, @@ -896,6 +890,9 @@ { "name": "executeInitAndCheckHooks" }, + { + "name": "executeSchedule" + }, { "name": "executeTemplate" }, @@ -917,9 +914,6 @@ { "name": "findAttrIndexInNode" }, - { - "name": "flattenUnsubscriptionErrors" - }, { "name": "forEachSingleProvider" }, @@ -933,7 +927,7 @@ "name": "from" }, { - "name": "fromArray" + "name": "fromAsyncIterable" }, { "name": "generateInitialInputs" @@ -1068,10 +1062,16 @@ "name": "getTView" }, { - "name": "hasTagAndTypeMatch" + "name": "handleReset" + }, + { + "name": "handleStoppedNotification" }, { - "name": "hostReportError" + "name": "handleUnhandledError" + }, + { + "name": "hasTagAndTypeMatch" }, { "name": "icuContainerIterate" @@ -1110,7 +1110,7 @@ "name": "injectableDefOrInjectorDefFactory" }, { - "name": "innerSubscribe" + "name": "innerFrom" }, { "name": "insertBloom" @@ -1140,10 +1140,10 @@ "name": "invokeQuery" }, { - "name": "isArray" + "name": "isArrayLike" }, { - "name": "isArrayLike" + "name": "isAsyncIterable" }, { "name": "isComponentDef" @@ -1172,6 +1172,12 @@ { "name": "isInlineTemplate" }, + { + "name": "isInteropObservable" + }, + { + "name": "isIterable" + }, { "name": "isLContainer" }, @@ -1184,9 +1190,6 @@ { "name": "isNodeMatchingSelectorList" }, - { - "name": "isObject" - }, { "name": "isPlatformServer" }, @@ -1200,11 +1203,14 @@ "name": "isPromise2" }, { - "name": "isScheduler" + "name": "isReadableStreamLike" }, { "name": "isStableFactory" }, + { + "name": "isSubscription" + }, { "name": "isTemplateNode" }, @@ -1217,6 +1223,9 @@ { "name": "iterator" }, + { + "name": "last" + }, { "name": "leaveDI" }, @@ -1247,9 +1256,6 @@ { "name": "makeTimingAst" }, - { - "name": "map" - }, { "name": "markAncestorsForTraversal" }, @@ -1265,9 +1271,6 @@ { "name": "maybeWrapInNotSelector" }, - { - "name": "mergeAll" - }, { "name": "mergeHostAttribute" }, @@ -1304,6 +1307,9 @@ { "name": "noop" }, + { + "name": "noop2" + }, { "name": "normalizeAnimationEntry" }, @@ -1319,12 +1325,18 @@ { "name": "observable" }, + { + "name": "observeOn" + }, { "name": "onEnter" }, { "name": "onLeave" }, + { + "name": "operate" + }, { "name": "optimizeGroupPlayer" }, @@ -1340,6 +1352,9 @@ { "name": "platformCore" }, + { + "name": "popScheduler" + }, { "name": "processInjectorTypesWithProviders" }, @@ -1353,7 +1368,7 @@ "name": "profiler" }, { - "name": "refCount" + "name": "readableStreamLikeToAsyncGenerator" }, { "name": "refreshContentQueries" @@ -1388,6 +1403,9 @@ { "name": "replacePostStylesAsPre" }, + { + "name": "reportUnhandledError" + }, { "name": "requiresRefreshOrTraversal" }, @@ -1409,14 +1427,11 @@ { "name": "roundOffset" }, - { - "name": "rxSubscriber" - }, { "name": "saveNameToExportMap" }, { - "name": "scheduleArray" + "name": "scheduleAsyncIterable" }, { "name": "searchTokensOnInjector" @@ -1466,9 +1481,6 @@ { "name": "setupStaticAttributes" }, - { - "name": "shareSubjectFactory" - }, { "name": "shimStylesContent" }, @@ -1485,16 +1497,13 @@ "name": "style" }, { - "name": "subscribeTo" + "name": "subscribeOn" }, { - "name": "subscribeToArray" - }, - { - "name": "switchMap" + "name": "throwProviderNotFoundError" }, { - "name": "throwProviderNotFoundError" + "name": "timeoutProvider" }, { "name": "toRefArray" diff --git a/packages/core/test/bundling/cyclic_import/bundle.golden_symbols.json b/packages/core/test/bundling/cyclic_import/bundle.golden_symbols.json index 919751bbf1f74..7c60aee2b6e71 100644 --- a/packages/core/test/bundling/cyclic_import/bundle.golden_symbols.json +++ b/packages/core/test/bundling/cyclic_import/bundle.golden_symbols.json @@ -53,6 +53,9 @@ { "name": "CIRCULAR" }, + { + "name": "COMPLETE_NOTIFICATION" + }, { "name": "COMPONENT_REGEX" }, @@ -90,10 +93,7 @@ "name": "ComponentRef2" }, { - "name": "ConnectableObservable" - }, - { - "name": "ConnectableSubscriber" + "name": "ConsumerObserver" }, { "name": "DEFAULT_APP_ID" @@ -110,12 +110,6 @@ { "name": "DepComponent" }, - { - "name": "DistinctUntilChangedOperator" - }, - { - "name": "DistinctUntilChangedSubscriber" - }, { "name": "DomAdapter" }, @@ -125,15 +119,24 @@ { "name": "DomRendererFactory2" }, + { + "name": "EMPTY" + }, { "name": "EMPTY_ARRAY" }, { "name": "EMPTY_OBJ" }, + { + "name": "EMPTY_OBSERVER" + }, { "name": "EMPTY_PAYLOAD" }, + { + "name": "EMPTY_SUBSCRIPTION" + }, { "name": "ENVIRONMENT_INITIALIZER" }, @@ -212,18 +215,6 @@ { "name": "MOVED_VIEWS" }, - { - "name": "MapOperator" - }, - { - "name": "MapSubscriber" - }, - { - "name": "MergeMapOperator" - }, - { - "name": "MergeMapSubscriber" - }, { "name": "Module" }, @@ -329,6 +320,9 @@ { "name": "Observable" }, + { + "name": "OperatorSubscriber" + }, { "name": "PLATFORM_DESTROY_LISTENERS" }, @@ -353,12 +347,6 @@ { "name": "REMOVE_STYLES_ON_COMPONENT_DESTROY" }, - { - "name": "RefCountOperator" - }, - { - "name": "RefCountSubscriber" - }, { "name": "RendererFactory2" }, @@ -386,33 +374,15 @@ { "name": "SimpleChange" }, - { - "name": "SimpleInnerSubscriber" - }, - { - "name": "SimpleOuterSubscriber" - }, { "name": "Subject" }, - { - "name": "SubjectSubscriber" - }, - { - "name": "SubjectSubscription" - }, { "name": "Subscriber" }, { "name": "Subscription" }, - { - "name": "SwitchMapOperator" - }, - { - "name": "SwitchMapSubscriber" - }, { "name": "TESTABILITY" }, @@ -446,9 +416,6 @@ { "name": "UnsubscriptionError" }, - { - "name": "VERSION" - }, { "name": "ViewEncapsulation" }, @@ -464,6 +431,12 @@ { "name": "_NullComponentFactoryResolver" }, + { + "name": "__asyncValues" + }, + { + "name": "__await" + }, { "name": "__forward_ref__" }, @@ -471,10 +444,10 @@ "name": "_applyRootElementTransformImpl" }, { - "name": "_currentInjector" + "name": "_bind" }, { - "name": "_enable_super_gross_mode_that_will_cause_bad_things" + "name": "_currentInjector" }, { "name": "_getInsertInFrontOfRNodeWithI18n" @@ -542,6 +515,9 @@ { "name": "applyView" }, + { + "name": "arrRemove" + }, { "name": "assertConsumerNode" }, @@ -551,6 +527,9 @@ { "name": "baseElement" }, + { + "name": "bind" + }, { "name": "bloomHasToken" }, @@ -590,15 +569,15 @@ { "name": "configureViewWithDirective" }, - { - "name": "connectableObservableDescriptor" - }, { "name": "consumerIsLive" }, { "name": "consumerPollProducersForChange" }, + { + "name": "context" + }, { "name": "convertToBitFlags" }, @@ -608,12 +587,18 @@ { "name": "createElementRef" }, + { + "name": "createErrorClass" + }, { "name": "createInjector" }, { "name": "createInjectorWithoutInjectorInstances" }, + { + "name": "createInvalidObservableTypeError" + }, { "name": "createLFrame" }, @@ -623,6 +608,12 @@ { "name": "createNodeInjector" }, + { + "name": "createNotification" + }, + { + "name": "createOperatorSubscriber" + }, { "name": "createPlatformFactory" }, @@ -635,6 +626,9 @@ { "name": "deepForEachProvider" }, + { + "name": "defaultCompare" + }, { "name": "detachMovedView" }, @@ -657,19 +651,19 @@ "name": "diPublicInInjector" }, { - "name": "empty" + "name": "enterDI" }, { - "name": "empty2" + "name": "enterView" }, { - "name": "enterDI" + "name": "epoch" }, { - "name": "enterView" + "name": "errorContext" }, { - "name": "epoch" + "name": "execFinalizer" }, { "name": "executeCheckHooks" @@ -680,6 +674,9 @@ { "name": "executeInitAndCheckHooks" }, + { + "name": "executeSchedule" + }, { "name": "executeTemplate" }, @@ -695,9 +692,6 @@ { "name": "findAttrIndexInNode" }, - { - "name": "flattenUnsubscriptionErrors" - }, { "name": "forEachSingleProvider" }, @@ -711,7 +705,7 @@ "name": "from" }, { - "name": "fromArray" + "name": "fromAsyncIterable" }, { "name": "generateInitialInputs" @@ -837,10 +831,16 @@ "name": "getTView" }, { - "name": "hasTagAndTypeMatch" + "name": "handleReset" + }, + { + "name": "handleStoppedNotification" + }, + { + "name": "handleUnhandledError" }, { - "name": "hostReportError" + "name": "hasTagAndTypeMatch" }, { "name": "icuContainerIterate" @@ -879,7 +879,7 @@ "name": "injectableDefOrInjectorDefFactory" }, { - "name": "innerSubscribe" + "name": "innerFrom" }, { "name": "insertBloom" @@ -900,10 +900,10 @@ "name": "invokeHostBindingsInCreationMode" }, { - "name": "isArray" + "name": "isArrayLike" }, { - "name": "isArrayLike" + "name": "isAsyncIterable" }, { "name": "isComponentDef" @@ -929,6 +929,12 @@ { "name": "isInlineTemplate" }, + { + "name": "isInteropObservable" + }, + { + "name": "isIterable" + }, { "name": "isLContainer" }, @@ -941,9 +947,6 @@ { "name": "isNodeMatchingSelectorList" }, - { - "name": "isObject" - }, { "name": "isPlatformServer" }, @@ -957,11 +960,14 @@ "name": "isPromise2" }, { - "name": "isScheduler" + "name": "isReadableStreamLike" }, { "name": "isStableFactory" }, + { + "name": "isSubscription" + }, { "name": "isTemplateNode" }, @@ -974,6 +980,9 @@ { "name": "iterator" }, + { + "name": "last" + }, { "name": "lastNodeWasCreated" }, @@ -995,9 +1004,6 @@ { "name": "makeRecord" }, - { - "name": "map" - }, { "name": "markAncestorsForTraversal" }, @@ -1013,9 +1019,6 @@ { "name": "maybeWrapInNotSelector" }, - { - "name": "mergeAll" - }, { "name": "mergeHostAttribute" }, @@ -1052,18 +1055,27 @@ { "name": "noop" }, + { + "name": "noop2" + }, { "name": "notFoundValueOrThrow" }, { "name": "observable" }, + { + "name": "observeOn" + }, { "name": "onEnter" }, { "name": "onLeave" }, + { + "name": "operate" + }, { "name": "optionsReducer" }, @@ -1073,6 +1085,9 @@ { "name": "platformCore" }, + { + "name": "popScheduler" + }, { "name": "processInjectorTypesWithProviders" }, @@ -1086,7 +1101,7 @@ "name": "profiler" }, { - "name": "refCount" + "name": "readableStreamLikeToAsyncGenerator" }, { "name": "refreshContentQueries" @@ -1112,6 +1127,9 @@ { "name": "renderView" }, + { + "name": "reportUnhandledError" + }, { "name": "requiresRefreshOrTraversal" }, @@ -1124,14 +1142,11 @@ { "name": "retrieveHydrationInfo" }, - { - "name": "rxSubscriber" - }, { "name": "saveNameToExportMap" }, { - "name": "scheduleArray" + "name": "scheduleAsyncIterable" }, { "name": "searchTokensOnInjector" @@ -1178,9 +1193,6 @@ { "name": "setupStaticAttributes" }, - { - "name": "shareSubjectFactory" - }, { "name": "shimStylesContent" }, @@ -1194,16 +1206,13 @@ "name": "stringifyCSSSelector" }, { - "name": "subscribeTo" + "name": "subscribeOn" }, { - "name": "subscribeToArray" - }, - { - "name": "switchMap" + "name": "throwProviderNotFoundError" }, { - "name": "throwProviderNotFoundError" + "name": "timeoutProvider" }, { "name": "toRefArray" diff --git a/packages/core/test/bundling/defer/bundle.golden_symbols.json b/packages/core/test/bundling/defer/bundle.golden_symbols.json index 0ea35badcc3a5..b2ab854a6b8b6 100644 --- a/packages/core/test/bundling/defer/bundle.golden_symbols.json +++ b/packages/core/test/bundling/defer/bundle.golden_symbols.json @@ -56,6 +56,9 @@ { "name": "CIRCULAR" }, + { + "name": "COMPLETE_NOTIFICATION" + }, { "name": "COMPONENT_REGEX" }, @@ -90,10 +93,7 @@ "name": "ComponentRef2" }, { - "name": "ConnectableObservable" - }, - { - "name": "ConnectableSubscriber" + "name": "ConsumerObserver" }, { "name": "DEFAULT_APP_ID" @@ -134,12 +134,6 @@ { "name": "DeferDependenciesLoadingState" }, - { - "name": "DistinctUntilChangedOperator" - }, - { - "name": "DistinctUntilChangedSubscriber" - }, { "name": "DomAdapter" }, @@ -149,15 +143,24 @@ { "name": "DomRendererFactory2" }, + { + "name": "EMPTY" + }, { "name": "EMPTY_ARRAY" }, { "name": "EMPTY_OBJ" }, + { + "name": "EMPTY_OBSERVER" + }, { "name": "EMPTY_PAYLOAD" }, + { + "name": "EMPTY_SUBSCRIPTION" + }, { "name": "ENVIRONMENT_INITIALIZER" }, @@ -257,18 +260,6 @@ { "name": "MOVED_VIEWS" }, - { - "name": "MapOperator" - }, - { - "name": "MapSubscriber" - }, - { - "name": "MergeMapOperator" - }, - { - "name": "MergeMapSubscriber" - }, { "name": "NAMESPACE_URIS" }, @@ -371,6 +362,9 @@ { "name": "Observable" }, + { + "name": "OperatorSubscriber" + }, { "name": "PLATFORM_DESTROY_LISTENERS" }, @@ -401,12 +395,6 @@ { "name": "REMOVE_STYLES_ON_COMPONENT_DESTROY" }, - { - "name": "RefCountOperator" - }, - { - "name": "RefCountSubscriber" - }, { "name": "RendererFactory2" }, @@ -440,36 +428,18 @@ { "name": "SimpleChange" }, - { - "name": "SimpleInnerSubscriber" - }, - { - "name": "SimpleOuterSubscriber" - }, { "name": "StandaloneService" }, { "name": "Subject" }, - { - "name": "SubjectSubscriber" - }, - { - "name": "SubjectSubscription" - }, { "name": "Subscriber" }, { "name": "Subscription" }, - { - "name": "SwitchMapOperator" - }, - { - "name": "SwitchMapSubscriber" - }, { "name": "TESTABILITY" }, @@ -491,9 +461,6 @@ { "name": "UnsubscriptionError" }, - { - "name": "VERSION" - }, { "name": "VIEW_REFS" }, @@ -512,6 +479,12 @@ { "name": "_NullComponentFactoryResolver" }, + { + "name": "__asyncValues" + }, + { + "name": "__await" + }, { "name": "__defProp" }, @@ -528,10 +501,10 @@ "name": "_applyRootElementTransformImpl" }, { - "name": "_currentInjector" + "name": "_bind" }, { - "name": "_enable_super_gross_mode_that_will_cause_bad_things" + "name": "_currentInjector" }, { "name": "_ensureDirtyViewsAreAlwaysReachable" @@ -623,6 +596,9 @@ { "name": "applyView" }, + { + "name": "arrRemove" + }, { "name": "assertConsumerNode" }, @@ -632,6 +608,9 @@ { "name": "baseElement" }, + { + "name": "bind" + }, { "name": "bloomHasToken" }, @@ -671,15 +650,15 @@ { "name": "configureViewWithDirective" }, - { - "name": "connectableObservableDescriptor" - }, { "name": "consumerIsLive" }, { "name": "consumerPollProducersForChange" }, + { + "name": "context" + }, { "name": "convertToBitFlags" }, @@ -695,9 +674,15 @@ { "name": "createElementRef" }, + { + "name": "createErrorClass" + }, { "name": "createInjector" }, + { + "name": "createInvalidObservableTypeError" + }, { "name": "createLFrame" }, @@ -707,6 +692,12 @@ { "name": "createNodeInjector" }, + { + "name": "createNotification" + }, + { + "name": "createOperatorSubscriber" + }, { "name": "createTView" }, @@ -716,6 +707,12 @@ { "name": "deepForEachProvider" }, + { + "name": "defaultCompare" + }, + { + "name": "defaultErrorHandler" + }, { "name": "defer_component_exports" }, @@ -746,9 +743,6 @@ { "name": "diPublicInInjector" }, - { - "name": "empty" - }, { "name": "enterDI" }, @@ -758,6 +752,12 @@ { "name": "epoch" }, + { + "name": "errorContext" + }, + { + "name": "execFinalizer" + }, { "name": "executeCheckHooks" }, @@ -767,6 +767,9 @@ { "name": "executeInitAndCheckHooks" }, + { + "name": "executeSchedule" + }, { "name": "executeTemplate" }, @@ -782,9 +785,6 @@ { "name": "findAttrIndexInNode" }, - { - "name": "flattenUnsubscriptionErrors" - }, { "name": "forEachSingleProvider" }, @@ -798,7 +798,7 @@ "name": "from" }, { - "name": "fromArray" + "name": "fromAsyncIterable" }, { "name": "generateInitialInputs" @@ -951,13 +951,19 @@ "name": "handleError" }, { - "name": "hasInSkipHydrationBlockFlag" + "name": "handleReset" }, { - "name": "hasTagAndTypeMatch" + "name": "handleStoppedNotification" }, { - "name": "hostReportError" + "name": "handleUnhandledError" + }, + { + "name": "hasInSkipHydrationBlockFlag" + }, + { + "name": "hasTagAndTypeMatch" }, { "name": "icuContainerIterate" @@ -978,7 +984,7 @@ "name": "init_BehaviorSubject" }, { - "name": "init_ConnectableObservable" + "name": "init_NotificationFactories" }, { "name": "init_ObjectUnsubscribedError" @@ -987,14 +993,11 @@ "name": "init_Observable" }, { - "name": "init_Observer" + "name": "init_OperatorSubscriber" }, { "name": "init_Subject" }, - { - "name": "init_SubjectSubscription" - }, { "name": "init_Subscriber" }, @@ -1043,6 +1046,12 @@ { "name": "init_application_tokens" }, + { + "name": "init_args" + }, + { + "name": "init_arrRemove" + }, { "name": "init_array_utils" }, @@ -1076,9 +1085,6 @@ { "name": "init_bypass" }, - { - "name": "init_canReportError" - }, { "name": "init_change_detection" }, @@ -1196,6 +1202,9 @@ { "name": "init_core_render3_private_export" }, + { + "name": "init_createErrorClass" + }, { "name": "init_create_application" }, @@ -1295,6 +1304,9 @@ { "name": "init_empty" }, + { + "name": "init_empty2" + }, { "name": "init_environment" }, @@ -1304,6 +1316,9 @@ { "name": "init_equality" }, + { + "name": "init_errorContext" + }, { "name": "init_error_details_base_url" }, @@ -1329,11 +1344,14 @@ "name": "init_errors_di" }, { - "name": "init_esm2015" + "name": "init_esm" }, { "name": "init_event_emitter" }, + { + "name": "init_executeSchedule" + }, { "name": "init_fields" }, @@ -1349,9 +1367,6 @@ { "name": "init_from" }, - { - "name": "init_fromArray" - }, { "name": "init_get_current_view" }, @@ -1367,9 +1382,6 @@ { "name": "init_hooks" }, - { - "name": "init_hostReportError" - }, { "name": "init_host_directives_feature" }, @@ -1473,7 +1485,7 @@ "name": "init_injector_utils" }, { - "name": "init_innerSubscribe" + "name": "init_innerFrom" }, { "name": "init_input" @@ -1500,10 +1512,10 @@ "name": "init_interpolation" }, { - "name": "init_isArray" + "name": "init_isArrayLike" }, { - "name": "init_isArrayLike" + "name": "init_isAsyncIterable" }, { "name": "init_isFunction" @@ -1515,10 +1527,10 @@ "name": "init_isIterable" }, { - "name": "init_isObject" + "name": "init_isPromise" }, { - "name": "init_isPromise" + "name": "init_isReadableStreamLike" }, { "name": "init_isScheduler" @@ -1544,6 +1556,9 @@ { "name": "init_lang" }, + { + "name": "init_lift" + }, { "name": "init_linker" }, @@ -1580,6 +1595,9 @@ { "name": "init_mergeAll" }, + { + "name": "init_mergeInternals" + }, { "name": "init_mergeMap" }, @@ -1604,9 +1622,6 @@ { "name": "init_module_patch" }, - { - "name": "init_multicast" - }, { "name": "init_namespace" }, @@ -1673,12 +1688,18 @@ { "name": "init_noop" }, + { + "name": "init_noop2" + }, { "name": "init_null_injector" }, { "name": "init_observable" }, + { + "name": "init_observeOn" + }, { "name": "init_of" }, @@ -1760,9 +1781,6 @@ { "name": "init_reactive_lview_consumer" }, - { - "name": "init_refCount" - }, { "name": "init_reflection_capabilities" }, @@ -1776,10 +1794,10 @@ "name": "init_render3" }, { - "name": "init_resource_loading" + "name": "init_reportUnhandledError" }, { - "name": "init_rxSubscriber" + "name": "init_resource_loading" }, { "name": "init_sanitization" @@ -1790,6 +1808,9 @@ { "name": "init_scheduleArray" }, + { + "name": "init_scheduleAsyncIterable" + }, { "name": "init_scheduleIterable" }, @@ -1799,6 +1820,9 @@ { "name": "init_schedulePromise" }, + { + "name": "init_scheduleReadableStreamLike" + }, { "name": "init_scheduled" }, @@ -1878,19 +1902,7 @@ "name": "init_styling_parser" }, { - "name": "init_subscribeTo" - }, - { - "name": "init_subscribeToArray" - }, - { - "name": "init_subscribeToIterable" - }, - { - "name": "init_subscribeToObservable" - }, - { - "name": "init_subscribeToPromise" + "name": "init_subscribeOn" }, { "name": "init_switchMap" @@ -1911,10 +1923,13 @@ "name": "init_text_interpolation" }, { - "name": "init_timer_scheduler" + "name": "init_throwUnobservableError" }, { - "name": "init_toSubscriber" + "name": "init_timeoutProvider" + }, + { + "name": "init_timer_scheduler" }, { "name": "init_tokens" @@ -1934,12 +1949,18 @@ { "name": "init_trusted_types_bypass" }, + { + "name": "init_tslib_es6" + }, { "name": "init_type" }, { "name": "init_type_checks" }, + { + "name": "init_types" + }, { "name": "init_untracked" }, @@ -2022,7 +2043,7 @@ "name": "injectableDefOrInjectorDefFactory" }, { - "name": "innerSubscribe" + "name": "innerFrom" }, { "name": "insertBloom" @@ -2049,10 +2070,10 @@ "name": "invokeTriggerCleanupFns" }, { - "name": "isArray" + "name": "isArrayLike" }, { - "name": "isArrayLike" + "name": "isAsyncIterable" }, { "name": "isComponentDef" @@ -2081,6 +2102,12 @@ { "name": "isInlineTemplate" }, + { + "name": "isInteropObservable" + }, + { + "name": "isIterable" + }, { "name": "isLContainer" }, @@ -2093,9 +2120,6 @@ { "name": "isNodeMatchingSelectorList" }, - { - "name": "isObject" - }, { "name": "isPlatformServer" }, @@ -2109,11 +2133,14 @@ "name": "isPromise2" }, { - "name": "isScheduler" + "name": "isReadableStreamLike" }, { "name": "isStableFactory" }, + { + "name": "isSubscription" + }, { "name": "isTemplateNode" }, @@ -2129,6 +2156,9 @@ { "name": "iterator" }, + { + "name": "last" + }, { "name": "lastNodeWasCreated" }, @@ -2150,9 +2180,6 @@ { "name": "makeRecord" }, - { - "name": "map" - }, { "name": "markAncestorsForTraversal" }, @@ -2171,9 +2198,6 @@ { "name": "maybeWrapInNotSelector" }, - { - "name": "mergeAll" - }, { "name": "mergeHostAttribute" }, @@ -2210,21 +2234,33 @@ { "name": "noop" }, + { + "name": "noop2" + }, { "name": "notFoundValueOrThrow" }, { "name": "observable" }, + { + "name": "observeOn" + }, { "name": "onEnter" }, { "name": "onLeave" }, + { + "name": "operate" + }, { "name": "performanceMarkFeature" }, + { + "name": "popScheduler" + }, { "name": "populateDehydratedViewsInLContainer" }, @@ -2244,7 +2280,7 @@ "name": "provideZoneChangeDetection" }, { - "name": "refCount" + "name": "readableStreamLikeToAsyncGenerator" }, { "name": "refreshContentQueries" @@ -2276,6 +2312,9 @@ { "name": "renderView" }, + { + "name": "reportUnhandledError" + }, { "name": "requiresRefreshOrTraversal" }, @@ -2291,9 +2330,6 @@ { "name": "retrieveHydrationInfo" }, - { - "name": "rxSubscriber" - }, { "name": "saveNameToExportMap" }, @@ -2301,7 +2337,7 @@ "name": "saveResolvedLocalsInData" }, { - "name": "scheduleArray" + "name": "scheduleAsyncIterable" }, { "name": "searchTokensOnInjector" @@ -2351,9 +2387,6 @@ { "name": "setupStaticAttributes" }, - { - "name": "shareSubjectFactory" - }, { "name": "shimStylesContent" }, @@ -2370,22 +2403,7 @@ "name": "stringifyCSSSelector" }, { - "name": "subscribeTo" - }, - { - "name": "subscribeToArray" - }, - { - "name": "subscribeToIterable" - }, - { - "name": "subscribeToObservable" - }, - { - "name": "subscribeToPromise" - }, - { - "name": "switchMap" + "name": "subscribeOn" }, { "name": "throwError" @@ -2393,6 +2411,9 @@ { "name": "throwProviderNotFoundError" }, + { + "name": "timeoutProvider" + }, { "name": "toRefArray" }, diff --git a/packages/core/test/bundling/forms_reactive/bundle.golden_symbols.json b/packages/core/test/bundling/forms_reactive/bundle.golden_symbols.json index 986f1c707899c..036c5657bc171 100644 --- a/packages/core/test/bundling/forms_reactive/bundle.golden_symbols.json +++ b/packages/core/test/bundling/forms_reactive/bundle.golden_symbols.json @@ -77,6 +77,9 @@ { "name": "CIRCULAR" }, + { + "name": "COMPLETE_NOTIFICATION" + }, { "name": "COMPONENT_REGEX" }, @@ -120,10 +123,7 @@ "name": "ComponentRef2" }, { - "name": "ConnectableObservable" - }, - { - "name": "ConnectableSubscriber" + "name": "ConsumerObserver" }, { "name": "ControlContainer" @@ -155,12 +155,6 @@ { "name": "DefaultValueAccessor" }, - { - "name": "DistinctUntilChangedOperator" - }, - { - "name": "DistinctUntilChangedSubscriber" - }, { "name": "DomAdapter" }, @@ -173,15 +167,24 @@ { "name": "EMAIL_REGEXP" }, + { + "name": "EMPTY" + }, { "name": "EMPTY_ARRAY" }, { "name": "EMPTY_OBJ" }, + { + "name": "EMPTY_OBSERVER" + }, { "name": "EMPTY_PAYLOAD" }, + { + "name": "EMPTY_SUBSCRIPTION" + }, { "name": "ENVIRONMENT_INITIALIZER" }, @@ -296,18 +299,6 @@ { "name": "MOVED_VIEWS" }, - { - "name": "MapOperator" - }, - { - "name": "MapSubscriber" - }, - { - "name": "MergeMapOperator" - }, - { - "name": "MergeMapSubscriber" - }, { "name": "NAMESPACE_URIS" }, @@ -440,6 +431,9 @@ { "name": "Observable" }, + { + "name": "OperatorSubscriber" + }, { "name": "Optional" }, @@ -485,12 +479,6 @@ { "name": "ReactiveFormsModule" }, - { - "name": "RefCountOperator" - }, - { - "name": "RefCountSubscriber" - }, { "name": "Renderer2" }, @@ -527,36 +515,18 @@ { "name": "SimpleChange" }, - { - "name": "SimpleInnerSubscriber" - }, - { - "name": "SimpleOuterSubscriber" - }, { "name": "SkipSelf" }, { "name": "Subject" }, - { - "name": "SubjectSubscriber" - }, - { - "name": "SubjectSubscription" - }, { "name": "Subscriber" }, { "name": "Subscription" }, - { - "name": "SwitchMapOperator" - }, - { - "name": "SwitchMapSubscriber" - }, { "name": "TESTABILITY" }, @@ -590,9 +560,6 @@ { "name": "UnsubscriptionError" }, - { - "name": "VERSION" - }, { "name": "VE_ViewContainerRef" }, @@ -626,6 +593,12 @@ { "name": "_NullComponentFactoryResolver" }, + { + "name": "__asyncValues" + }, + { + "name": "__await" + }, { "name": "__forward_ref__" }, @@ -633,10 +606,10 @@ "name": "_applyRootElementTransformImpl" }, { - "name": "_currentInjector" + "name": "_bind" }, { - "name": "_enable_super_gross_mode_that_will_cause_bad_things" + "name": "_currentInjector" }, { "name": "_ensureDirtyViewsAreAlwaysReachable" @@ -731,6 +704,9 @@ { "name": "applyViewChange" }, + { + "name": "arrRemove" + }, { "name": "assertAllValuesPresent" }, @@ -749,6 +725,9 @@ { "name": "baseElement" }, + { + "name": "bind" + }, { "name": "bindingUpdated" }, @@ -815,15 +794,15 @@ { "name": "configureViewWithDirective" }, - { - "name": "connectableObservableDescriptor" - }, { "name": "consumerIsLive" }, { "name": "consumerPollProducersForChange" }, + { + "name": "context" + }, { "name": "controlNameBinding" }, @@ -842,12 +821,18 @@ { "name": "createElementRef" }, + { + "name": "createErrorClass" + }, { "name": "createInjector" }, { "name": "createInjectorWithoutInjectorInstances" }, + { + "name": "createInvalidObservableTypeError" + }, { "name": "createLContainer" }, @@ -860,6 +845,15 @@ { "name": "createNodeInjector" }, + { + "name": "createNotification" + }, + { + "name": "createObject" + }, + { + "name": "createOperatorSubscriber" + }, { "name": "createPlatformFactory" }, @@ -872,6 +866,9 @@ { "name": "deepForEachProvider" }, + { + "name": "defaultCompare" + }, { "name": "defaultIterableDiffersFactory" }, @@ -903,19 +900,19 @@ "name": "diPublicInInjector" }, { - "name": "empty" + "name": "enterDI" }, { - "name": "empty2" + "name": "enterView" }, { - "name": "enterDI" + "name": "epoch" }, { - "name": "enterView" + "name": "errorContext" }, { - "name": "epoch" + "name": "execFinalizer" }, { "name": "executeCheckHooks" @@ -929,6 +926,9 @@ { "name": "executeListenerWithErrorHandling" }, + { + "name": "executeSchedule" + }, { "name": "executeTemplate" }, @@ -953,14 +953,11 @@ { "name": "findStylingValue" }, - { - "name": "flattenUnsubscriptionErrors" - }, { "name": "forEachSingleProvider" }, { - "name": "forkJoinInternal" + "name": "forkJoin" }, { "name": "formArrayNameProvider" @@ -981,7 +978,7 @@ "name": "from" }, { - "name": "fromArray" + "name": "fromAsyncIterable" }, { "name": "generateInitialInputs" @@ -1148,6 +1145,15 @@ { "name": "handleError" }, + { + "name": "handleReset" + }, + { + "name": "handleStoppedNotification" + }, + { + "name": "handleUnhandledError" + }, { "name": "hasInSkipHydrationBlockFlag" }, @@ -1163,9 +1169,6 @@ { "name": "hasValidator" }, - { - "name": "hostReportError" - }, { "name": "icuContainerIterate" }, @@ -1224,7 +1227,7 @@ "name": "injectableDefOrInjectorDefFactory" }, { - "name": "innerSubscribe" + "name": "innerFrom" }, { "name": "insertBloom" @@ -1248,10 +1251,10 @@ "name": "isAbstractControlOptions" }, { - "name": "isArray" + "name": "isArrayLike" }, { - "name": "isArrayLike" + "name": "isAsyncIterable" }, { "name": "isComponentDef" @@ -1289,6 +1292,12 @@ { "name": "isInlineTemplate" }, + { + "name": "isInteropObservable" + }, + { + "name": "isIterable" + }, { "name": "isLContainer" }, @@ -1304,9 +1313,6 @@ { "name": "isNodeMatchingSelectorList" }, - { - "name": "isObject" - }, { "name": "isOptionsObj" }, @@ -1326,7 +1332,7 @@ "name": "isPromise2" }, { - "name": "isScheduler" + "name": "isReadableStreamLike" }, { "name": "isStableFactory" @@ -1337,6 +1343,9 @@ { "name": "isStylingValuePresent" }, + { + "name": "isSubscription" + }, { "name": "isTemplateNode" }, @@ -1358,6 +1367,9 @@ { "name": "keyValueArraySet" }, + { + "name": "last" + }, { "name": "lastNodeWasCreated" }, @@ -1410,7 +1422,7 @@ "name": "maybeWrapInNotSelector" }, { - "name": "mergeAll" + "name": "merge" }, { "name": "mergeErrors" @@ -1469,6 +1481,9 @@ { "name": "noop" }, + { + "name": "noop2" + }, { "name": "normalizeValidators" }, @@ -1481,12 +1496,18 @@ { "name": "observable" }, + { + "name": "observeOn" + }, { "name": "onEnter" }, { "name": "onLeave" }, + { + "name": "operate" + }, { "name": "optionsReducer" }, @@ -1502,6 +1523,9 @@ { "name": "platformCore" }, + { + "name": "popScheduler" + }, { "name": "processInjectorTypesWithProviders" }, @@ -1518,7 +1542,7 @@ "name": "providerToFactory" }, { - "name": "refCount" + "name": "readableStreamLikeToAsyncGenerator" }, { "name": "refreshContentQueries" @@ -1556,6 +1580,9 @@ { "name": "renderView" }, + { + "name": "reportUnhandledError" + }, { "name": "requiresRefreshOrTraversal" }, @@ -1574,9 +1601,6 @@ { "name": "retrieveHydrationInfo" }, - { - "name": "rxSubscriber" - }, { "name": "saveNameToExportMap" }, @@ -1584,7 +1608,7 @@ "name": "saveResolvedLocalsInData" }, { - "name": "scheduleArray" + "name": "scheduleAsyncIterable" }, { "name": "searchTokensOnInjector" @@ -1652,9 +1676,6 @@ { "name": "setupStaticAttributes" }, - { - "name": "shareSubjectFactory" - }, { "name": "shimStylesContent" }, @@ -1671,16 +1692,13 @@ "name": "stringifyCSSSelector" }, { - "name": "subscribeTo" + "name": "subscribeOn" }, { - "name": "subscribeToArray" + "name": "throwProviderNotFoundError" }, { - "name": "switchMap" - }, - { - "name": "throwProviderNotFoundError" + "name": "timeoutProvider" }, { "name": "toObservable" @@ -1727,6 +1745,15 @@ { "name": "writeToDirectiveInput" }, + { + "name": "{getPrototypeOf:getPrototypeOf,prototype:objectProto,keys:getKeys}" + }, + { + "name": "{isArray:isArray2}" + }, + { + "name": "{isArray:isArray}" + }, { "name": "ɵInternalFormsSharedModule" }, diff --git a/packages/core/test/bundling/forms_template_driven/bundle.golden_symbols.json b/packages/core/test/bundling/forms_template_driven/bundle.golden_symbols.json index 294827acbc288..e59db0e0b399b 100644 --- a/packages/core/test/bundling/forms_template_driven/bundle.golden_symbols.json +++ b/packages/core/test/bundling/forms_template_driven/bundle.golden_symbols.json @@ -80,6 +80,9 @@ { "name": "CIRCULAR" }, + { + "name": "COMPLETE_NOTIFICATION" + }, { "name": "COMPONENT_REGEX" }, @@ -126,10 +129,7 @@ "name": "ComponentRef2" }, { - "name": "ConnectableObservable" - }, - { - "name": "ConnectableSubscriber" + "name": "ConsumerObserver" }, { "name": "ControlContainer" @@ -161,12 +161,6 @@ { "name": "DefaultValueAccessor" }, - { - "name": "DistinctUntilChangedOperator" - }, - { - "name": "DistinctUntilChangedSubscriber" - }, { "name": "DomAdapter" }, @@ -176,15 +170,24 @@ { "name": "DomRendererFactory2" }, + { + "name": "EMPTY" + }, { "name": "EMPTY_ARRAY" }, { "name": "EMPTY_OBJ" }, + { + "name": "EMPTY_OBSERVER" + }, { "name": "EMPTY_PAYLOAD" }, + { + "name": "EMPTY_SUBSCRIPTION" + }, { "name": "ENVIRONMENT_INITIALIZER" }, @@ -281,18 +284,6 @@ { "name": "MOVED_VIEWS" }, - { - "name": "MapOperator" - }, - { - "name": "MapSubscriber" - }, - { - "name": "MergeMapOperator" - }, - { - "name": "MergeMapSubscriber" - }, { "name": "NAMESPACE_URIS" }, @@ -431,6 +422,9 @@ { "name": "Observable" }, + { + "name": "OperatorSubscriber" + }, { "name": "Optional" }, @@ -470,12 +464,6 @@ { "name": "RadioControlRegistryModule" }, - { - "name": "RefCountOperator" - }, - { - "name": "RefCountSubscriber" - }, { "name": "Renderer2" }, @@ -515,36 +503,18 @@ { "name": "SimpleChange" }, - { - "name": "SimpleInnerSubscriber" - }, - { - "name": "SimpleOuterSubscriber" - }, { "name": "SkipSelf" }, { "name": "Subject" }, - { - "name": "SubjectSubscriber" - }, - { - "name": "SubjectSubscription" - }, { "name": "Subscriber" }, { "name": "Subscription" }, - { - "name": "SwitchMapOperator" - }, - { - "name": "SwitchMapSubscriber" - }, { "name": "TESTABILITY" }, @@ -584,9 +554,6 @@ { "name": "UnsubscriptionError" }, - { - "name": "VERSION" - }, { "name": "VE_ViewContainerRef" }, @@ -617,6 +584,12 @@ { "name": "_NullComponentFactoryResolver" }, + { + "name": "__asyncValues" + }, + { + "name": "__await" + }, { "name": "__forward_ref__" }, @@ -624,10 +597,10 @@ "name": "_applyRootElementTransformImpl" }, { - "name": "_currentInjector" + "name": "_bind" }, { - "name": "_enable_super_gross_mode_that_will_cause_bad_things" + "name": "_currentInjector" }, { "name": "_ensureDirtyViewsAreAlwaysReachable" @@ -719,6 +692,9 @@ { "name": "applyViewChange" }, + { + "name": "arrRemove" + }, { "name": "assertConsumerNode" }, @@ -731,6 +707,9 @@ { "name": "baseElement" }, + { + "name": "bind" + }, { "name": "bindingUpdated" }, @@ -788,15 +767,15 @@ { "name": "configureViewWithDirective" }, - { - "name": "connectableObservableDescriptor" - }, { "name": "consumerIsLive" }, { "name": "consumerPollProducersForChange" }, + { + "name": "context" + }, { "name": "controlPath" }, @@ -812,12 +791,18 @@ { "name": "createElementRef" }, + { + "name": "createErrorClass" + }, { "name": "createInjector" }, { "name": "createInjectorWithoutInjectorInstances" }, + { + "name": "createInvalidObservableTypeError" + }, { "name": "createLContainer" }, @@ -830,6 +815,15 @@ { "name": "createNodeInjector" }, + { + "name": "createNotification" + }, + { + "name": "createObject" + }, + { + "name": "createOperatorSubscriber" + }, { "name": "createPlatformFactory" }, @@ -842,6 +836,9 @@ { "name": "deepForEachProvider" }, + { + "name": "defaultCompare" + }, { "name": "defaultIterableDiffersFactory" }, @@ -873,19 +870,19 @@ "name": "diPublicInInjector" }, { - "name": "empty" + "name": "enterDI" }, { - "name": "empty2" + "name": "enterView" }, { - "name": "enterDI" + "name": "epoch" }, { - "name": "enterView" + "name": "errorContext" }, { - "name": "epoch" + "name": "execFinalizer" }, { "name": "executeCheckHooks" @@ -899,6 +896,9 @@ { "name": "executeListenerWithErrorHandling" }, + { + "name": "executeSchedule" + }, { "name": "executeTemplate" }, @@ -923,14 +923,11 @@ { "name": "findStylingValue" }, - { - "name": "flattenUnsubscriptionErrors" - }, { "name": "forEachSingleProvider" }, { - "name": "forkJoinInternal" + "name": "forkJoin" }, { "name": "formControlBinding" @@ -948,7 +945,7 @@ "name": "from" }, { - "name": "fromArray" + "name": "fromAsyncIterable" }, { "name": "generateInitialInputs" @@ -1112,6 +1109,15 @@ { "name": "handleError" }, + { + "name": "handleReset" + }, + { + "name": "handleStoppedNotification" + }, + { + "name": "handleUnhandledError" + }, { "name": "hasInSkipHydrationBlockFlag" }, @@ -1124,9 +1130,6 @@ { "name": "hasValidator" }, - { - "name": "hostReportError" - }, { "name": "icuContainerIterate" }, @@ -1188,7 +1191,7 @@ "name": "injectableDefOrInjectorDefFactory" }, { - "name": "innerSubscribe" + "name": "innerFrom" }, { "name": "insertBloom" @@ -1209,10 +1212,10 @@ "name": "invokeHostBindingsInCreationMode" }, { - "name": "isArray" + "name": "isArrayLike" }, { - "name": "isArrayLike" + "name": "isAsyncIterable" }, { "name": "isComponentDef" @@ -1247,6 +1250,12 @@ { "name": "isInlineTemplate" }, + { + "name": "isInteropObservable" + }, + { + "name": "isIterable" + }, { "name": "isLContainer" }, @@ -1262,9 +1271,6 @@ { "name": "isNodeMatchingSelectorList" }, - { - "name": "isObject" - }, { "name": "isOptionsObj" }, @@ -1284,7 +1290,7 @@ "name": "isPromise2" }, { - "name": "isScheduler" + "name": "isReadableStreamLike" }, { "name": "isStableFactory" @@ -1295,6 +1301,9 @@ { "name": "isStylingValuePresent" }, + { + "name": "isSubscription" + }, { "name": "isTemplateNode" }, @@ -1316,6 +1325,9 @@ { "name": "keyValueArraySet" }, + { + "name": "last" + }, { "name": "lastNodeWasCreated" }, @@ -1368,7 +1380,7 @@ "name": "maybeWrapInNotSelector" }, { - "name": "mergeAll" + "name": "merge" }, { "name": "mergeErrors" @@ -1433,6 +1445,9 @@ { "name": "noop" }, + { + "name": "noop2" + }, { "name": "normalizeValidators" }, @@ -1445,12 +1460,18 @@ { "name": "observable" }, + { + "name": "observeOn" + }, { "name": "onEnter" }, { "name": "onLeave" }, + { + "name": "operate" + }, { "name": "optionsReducer" }, @@ -1466,6 +1487,9 @@ { "name": "platformCore" }, + { + "name": "popScheduler" + }, { "name": "processInjectorTypesWithProviders" }, @@ -1482,7 +1506,7 @@ "name": "providerToFactory" }, { - "name": "refCount" + "name": "readableStreamLikeToAsyncGenerator" }, { "name": "refreshContentQueries" @@ -1523,6 +1547,9 @@ { "name": "renderView" }, + { + "name": "reportUnhandledError" + }, { "name": "requiredValidator" }, @@ -1550,9 +1577,6 @@ { "name": "retrieveHydrationInfo" }, - { - "name": "rxSubscriber" - }, { "name": "saveNameToExportMap" }, @@ -1560,7 +1584,7 @@ "name": "saveResolvedLocalsInData" }, { - "name": "scheduleArray" + "name": "scheduleAsyncIterable" }, { "name": "searchTokensOnInjector" @@ -1628,9 +1652,6 @@ { "name": "setupStaticAttributes" }, - { - "name": "shareSubjectFactory" - }, { "name": "shimStylesContent" }, @@ -1647,16 +1668,13 @@ "name": "stringifyCSSSelector" }, { - "name": "subscribeTo" + "name": "subscribeOn" }, { - "name": "subscribeToArray" + "name": "throwProviderNotFoundError" }, { - "name": "switchMap" - }, - { - "name": "throwProviderNotFoundError" + "name": "timeoutProvider" }, { "name": "toObservable" @@ -1703,6 +1721,15 @@ { "name": "writeToDirectiveInput" }, + { + "name": "{getPrototypeOf:getPrototypeOf,prototype:objectProto,keys:getKeys}" + }, + { + "name": "{isArray:isArray2}" + }, + { + "name": "{isArray:isArray}" + }, { "name": "ɵInternalFormsSharedModule" }, diff --git a/packages/core/test/bundling/hello_world/bundle.golden_symbols.json b/packages/core/test/bundling/hello_world/bundle.golden_symbols.json index 34f3abe685304..849d47edd29e3 100644 --- a/packages/core/test/bundling/hello_world/bundle.golden_symbols.json +++ b/packages/core/test/bundling/hello_world/bundle.golden_symbols.json @@ -35,6 +35,9 @@ { "name": "CIRCULAR" }, + { + "name": "COMPLETE_NOTIFICATION" + }, { "name": "CONTAINER_HEADER_OFFSET" }, @@ -60,22 +63,16 @@ "name": "ComponentRef2" }, { - "name": "ConnectableObservable" - }, - { - "name": "ConnectableSubscriber" + "name": "ConsumerObserver" }, { "name": "DOCUMENT2" }, { - "name": "DistinctUntilChangedOperator" - }, - { - "name": "DistinctUntilChangedSubscriber" + "name": "DomAdapter" }, { - "name": "DomAdapter" + "name": "EMPTY" }, { "name": "EMPTY_ARRAY" @@ -83,9 +80,15 @@ { "name": "EMPTY_OBJ" }, + { + "name": "EMPTY_OBSERVER" + }, { "name": "EMPTY_PAYLOAD" }, + { + "name": "EMPTY_SUBSCRIPTION" + }, { "name": "ENVIRONMENT_INITIALIZER" }, @@ -146,18 +149,6 @@ { "name": "MOVED_VIEWS" }, - { - "name": "MapOperator" - }, - { - "name": "MapSubscriber" - }, - { - "name": "MergeMapOperator" - }, - { - "name": "MergeMapSubscriber" - }, { "name": "NATIVE" }, @@ -248,6 +239,9 @@ { "name": "Observable" }, + { + "name": "OperatorSubscriber" + }, { "name": "PLATFORM_DESTROY_LISTENERS" }, @@ -269,12 +263,6 @@ { "name": "REACTIVE_LVIEW_CONSUMER_NODE" }, - { - "name": "RefCountOperator" - }, - { - "name": "RefCountSubscriber" - }, { "name": "RendererFactory2" }, @@ -293,33 +281,15 @@ { "name": "SimpleChange" }, - { - "name": "SimpleInnerSubscriber" - }, - { - "name": "SimpleOuterSubscriber" - }, { "name": "Subject" }, - { - "name": "SubjectSubscriber" - }, - { - "name": "SubjectSubscription" - }, { "name": "Subscriber" }, { "name": "Subscription" }, - { - "name": "SwitchMapOperator" - }, - { - "name": "SwitchMapSubscriber" - }, { "name": "TESTABILITY" }, @@ -338,9 +308,6 @@ { "name": "UnsubscriptionError" }, - { - "name": "VERSION" - }, { "name": "ViewEncapsulation" }, @@ -356,6 +323,12 @@ { "name": "_NullComponentFactoryResolver" }, + { + "name": "__asyncValues" + }, + { + "name": "__await" + }, { "name": "__forward_ref__" }, @@ -363,10 +336,10 @@ "name": "_applyRootElementTransformImpl" }, { - "name": "_currentInjector" + "name": "_bind" }, { - "name": "_enable_super_gross_mode_that_will_cause_bad_things" + "name": "_currentInjector" }, { "name": "_global" @@ -410,6 +383,9 @@ { "name": "applyView" }, + { + "name": "arrRemove" + }, { "name": "assertConsumerNode" }, @@ -419,6 +395,9 @@ { "name": "baseElement" }, + { + "name": "bind" + }, { "name": "bloomHasToken" }, @@ -452,27 +431,33 @@ { "name": "configureViewWithDirective" }, - { - "name": "connectableObservableDescriptor" - }, { "name": "consumerIsLive" }, { "name": "consumerPollProducersForChange" }, + { + "name": "context" + }, { "name": "convertToBitFlags" }, { "name": "createElementRef" }, + { + "name": "createErrorClass" + }, { "name": "createInjector" }, { "name": "createInjectorWithoutInjectorInstances" }, + { + "name": "createInvalidObservableTypeError" + }, { "name": "createLFrame" }, @@ -482,6 +467,12 @@ { "name": "createNodeInjector" }, + { + "name": "createNotification" + }, + { + "name": "createOperatorSubscriber" + }, { "name": "createPlatformFactory" }, @@ -494,6 +485,9 @@ { "name": "deepForEachProvider" }, + { + "name": "defaultCompare" + }, { "name": "detachMovedView" }, @@ -516,19 +510,19 @@ "name": "diPublicInInjector" }, { - "name": "empty" + "name": "enterDI" }, { - "name": "empty2" + "name": "enterView" }, { - "name": "enterDI" + "name": "epoch" }, { - "name": "enterView" + "name": "errorContext" }, { - "name": "epoch" + "name": "execFinalizer" }, { "name": "executeCheckHooks" @@ -537,13 +531,13 @@ "name": "executeInitAndCheckHooks" }, { - "name": "executeTemplate" + "name": "executeSchedule" }, { - "name": "executeViewQueryFn" + "name": "executeTemplate" }, { - "name": "flattenUnsubscriptionErrors" + "name": "executeViewQueryFn" }, { "name": "forEachSingleProvider" @@ -558,7 +552,7 @@ "name": "from" }, { - "name": "fromArray" + "name": "fromAsyncIterable" }, { "name": "generateInitialInputs" @@ -663,7 +657,13 @@ "name": "getTNodeFromLView" }, { - "name": "hostReportError" + "name": "handleReset" + }, + { + "name": "handleStoppedNotification" + }, + { + "name": "handleUnhandledError" }, { "name": "icuContainerIterate" @@ -699,7 +699,7 @@ "name": "injectableDefOrInjectorDefFactory" }, { - "name": "innerSubscribe" + "name": "innerFrom" }, { "name": "insertBloom" @@ -714,10 +714,10 @@ "name": "invokeHostBindingsInCreationMode" }, { - "name": "isArray" + "name": "isArrayLike" }, { - "name": "isArrayLike" + "name": "isAsyncIterable" }, { "name": "isComponentDef" @@ -732,13 +732,16 @@ "name": "isInlineTemplate" }, { - "name": "isLContainer" + "name": "isInteropObservable" }, { - "name": "isLView" + "name": "isIterable" + }, + { + "name": "isLContainer" }, { - "name": "isObject" + "name": "isLView" }, { "name": "isPositive" @@ -750,11 +753,14 @@ "name": "isPromise2" }, { - "name": "isScheduler" + "name": "isReadableStreamLike" }, { "name": "isStableFactory" }, + { + "name": "isSubscription" + }, { "name": "isTypeProvider" }, @@ -764,6 +770,9 @@ { "name": "iterator" }, + { + "name": "last" + }, { "name": "leaveDI" }, @@ -782,9 +791,6 @@ { "name": "makeRecord" }, - { - "name": "map" - }, { "name": "markAncestorsForTraversal" }, @@ -797,9 +803,6 @@ { "name": "maybeWrapInNotSelector" }, - { - "name": "mergeAll" - }, { "name": "mergeHostAttribute" }, @@ -824,18 +827,27 @@ { "name": "noop" }, + { + "name": "noop2" + }, { "name": "notFoundValueOrThrow" }, { "name": "observable" }, + { + "name": "observeOn" + }, { "name": "onEnter" }, { "name": "onLeave" }, + { + "name": "operate" + }, { "name": "optionsReducer" }, @@ -845,6 +857,9 @@ { "name": "platformCore" }, + { + "name": "popScheduler" + }, { "name": "processInjectorTypesWithProviders" }, @@ -858,7 +873,7 @@ "name": "profiler" }, { - "name": "refCount" + "name": "readableStreamLikeToAsyncGenerator" }, { "name": "refreshContentQueries" @@ -881,6 +896,9 @@ { "name": "renderView" }, + { + "name": "reportUnhandledError" + }, { "name": "requiresRefreshOrTraversal" }, @@ -893,14 +911,11 @@ { "name": "retrieveHydrationInfo" }, - { - "name": "rxSubscriber" - }, { "name": "saveNameToExportMap" }, { - "name": "scheduleArray" + "name": "scheduleAsyncIterable" }, { "name": "searchTokensOnInjector" @@ -932,9 +947,6 @@ { "name": "setUpAttributes" }, - { - "name": "shareSubjectFactory" - }, { "name": "shouldSearchParent" }, @@ -945,16 +957,13 @@ "name": "stringifyCSSSelector" }, { - "name": "subscribeTo" + "name": "subscribeOn" }, { - "name": "subscribeToArray" - }, - { - "name": "switchMap" + "name": "throwProviderNotFoundError" }, { - "name": "throwProviderNotFoundError" + "name": "timeoutProvider" }, { "name": "toRefArray" diff --git a/packages/core/test/bundling/hydration/bundle.golden_symbols.json b/packages/core/test/bundling/hydration/bundle.golden_symbols.json index f39ba4ebdf4a9..991d4eb214787 100644 --- a/packages/core/test/bundling/hydration/bundle.golden_symbols.json +++ b/packages/core/test/bundling/hydration/bundle.golden_symbols.json @@ -23,9 +23,6 @@ { "name": "ApplicationRef" }, - { - "name": "ArgumentOutOfRangeError" - }, { "name": "BLOOM_BUCKET_BITS" }, @@ -53,6 +50,9 @@ { "name": "CIRCULAR" }, + { + "name": "COMPLETE_NOTIFICATION" + }, { "name": "COMPONENT_REGEX" }, @@ -90,10 +90,7 @@ "name": "ComponentRef2" }, { - "name": "ConnectableObservable" - }, - { - "name": "ConnectableSubscriber" + "name": "ConsumerObserver" }, { "name": "DEFAULT_APP_ID" @@ -114,34 +111,28 @@ "name": "DefaultDomRenderer2" }, { - "name": "DefaultIfEmptyOperator" - }, - { - "name": "DefaultIfEmptySubscriber" - }, - { - "name": "DistinctUntilChangedOperator" + "name": "DomAdapter" }, { - "name": "DistinctUntilChangedSubscriber" + "name": "DomRendererFactory2" }, { - "name": "DoOperator" + "name": "EMPTY" }, { - "name": "DomAdapter" + "name": "EMPTY_ARRAY" }, { - "name": "DomRendererFactory2" + "name": "EMPTY_OBJ" }, { - "name": "EMPTY_ARRAY" + "name": "EMPTY_OBSERVER" }, { - "name": "EMPTY_OBJ" + "name": "EMPTY_PAYLOAD" }, { - "name": "EMPTY_PAYLOAD" + "name": "EMPTY_SUBSCRIPTION" }, { "name": "ENVIRONMENT_INITIALIZER" @@ -176,12 +167,6 @@ { "name": "EventManagerPlugin" }, - { - "name": "FilterOperator" - }, - { - "name": "FilterSubscriber" - }, { "name": "GenericBrowserDomAdapter" }, @@ -263,18 +248,6 @@ { "name": "MULTIPLIER" }, - { - "name": "MapOperator" - }, - { - "name": "MapSubscriber" - }, - { - "name": "MergeMapOperator" - }, - { - "name": "MergeMapSubscriber" - }, { "name": "NAMESPACE_URIS" }, @@ -377,6 +350,9 @@ { "name": "Observable" }, + { + "name": "OperatorSubscriber" + }, { "name": "PLATFORM_DESTROY_LISTENERS" }, @@ -410,12 +386,6 @@ { "name": "RESPONSE_TYPE" }, - { - "name": "RefCountOperator" - }, - { - "name": "RefCountSubscriber" - }, { "name": "RendererFactory2" }, @@ -455,36 +425,18 @@ { "name": "SimpleChange" }, - { - "name": "SimpleInnerSubscriber" - }, - { - "name": "SimpleOuterSubscriber" - }, { "name": "StandaloneService" }, { "name": "Subject" }, - { - "name": "SubjectSubscriber" - }, - { - "name": "SubjectSubscription" - }, { "name": "Subscriber" }, { "name": "Subscription" }, - { - "name": "SwitchMapOperator" - }, - { - "name": "SwitchMapSubscriber" - }, { "name": "TESTABILITY" }, @@ -497,21 +449,6 @@ { "name": "TYPE" }, - { - "name": "TakeOperator" - }, - { - "name": "TakeSubscriber" - }, - { - "name": "TapSubscriber" - }, - { - "name": "ThrowIfEmptyOperator" - }, - { - "name": "ThrowIfEmptySubscriber" - }, { "name": "TransferState" }, @@ -524,9 +461,6 @@ { "name": "UnsubscriptionError" }, - { - "name": "VERSION" - }, { "name": "ViewEncapsulation" }, @@ -542,6 +476,12 @@ { "name": "_NullComponentFactoryResolver" }, + { + "name": "__asyncValues" + }, + { + "name": "__await" + }, { "name": "__forward_ref__" }, @@ -549,10 +489,10 @@ "name": "_applyRootElementTransformImpl" }, { - "name": "_currentInjector" + "name": "_bind" }, { - "name": "_enable_super_gross_mode_that_will_cause_bad_things" + "name": "_currentInjector" }, { "name": "_getInsertInFrontOfRNodeWithI18n" @@ -617,6 +557,9 @@ { "name": "applyView" }, + { + "name": "arrRemove" + }, { "name": "assertConsumerNode" }, @@ -626,6 +569,9 @@ { "name": "baseElement" }, + { + "name": "bind" + }, { "name": "bloomHasToken" }, @@ -671,15 +617,15 @@ { "name": "configureViewWithDirective" }, - { - "name": "connectableObservableDescriptor" - }, { "name": "consumerIsLive" }, { "name": "consumerPollProducersForChange" }, + { + "name": "context" + }, { "name": "convertToBitFlags" }, @@ -689,9 +635,15 @@ { "name": "createElementRef" }, + { + "name": "createErrorClass" + }, { "name": "createInjector" }, + { + "name": "createInvalidObservableTypeError" + }, { "name": "createLFrame" }, @@ -701,6 +653,12 @@ { "name": "createNodeInjector" }, + { + "name": "createNotification" + }, + { + "name": "createOperatorSubscriber" + }, { "name": "createTView" }, @@ -713,6 +671,9 @@ { "name": "deepForEachProvider" }, + { + "name": "defaultCompare" + }, { "name": "defaultErrorFactory" }, @@ -737,12 +698,6 @@ { "name": "diPublicInInjector" }, - { - "name": "empty" - }, - { - "name": "empty3" - }, { "name": "enableHydrationRuntimeSupport" }, @@ -755,12 +710,21 @@ { "name": "epoch" }, + { + "name": "errorContext" + }, + { + "name": "execFinalizer" + }, { "name": "executeCheckHooks" }, { "name": "executeInitAndCheckHooks" }, + { + "name": "executeSchedule" + }, { "name": "executeTemplate" }, @@ -773,12 +737,6 @@ { "name": "extractDirectiveDef" }, - { - "name": "first" - }, - { - "name": "flattenUnsubscriptionErrors" - }, { "name": "forEachSingleProvider" }, @@ -792,7 +750,7 @@ "name": "from" }, { - "name": "fromArray" + "name": "fromAsyncIterable" }, { "name": "generateInitialInputs" @@ -920,6 +878,15 @@ { "name": "getTNodeFromLView" }, + { + "name": "handleReset" + }, + { + "name": "handleStoppedNotification" + }, + { + "name": "handleUnhandledError" + }, { "name": "hasInSkipHydrationBlockFlag" }, @@ -929,9 +896,6 @@ { "name": "hasSkipHydrationAttrOnTNode" }, - { - "name": "hostReportError" - }, { "name": "icuContainerIterate" }, @@ -969,7 +933,7 @@ "name": "injectableDefOrInjectorDefFactory" }, { - "name": "innerSubscribe" + "name": "innerFrom" }, { "name": "insertBloom" @@ -987,10 +951,10 @@ "name": "invokeHostBindingsInCreationMode" }, { - "name": "isArray" + "name": "isArrayLike" }, { - "name": "isArrayLike" + "name": "isAsyncIterable" }, { "name": "isComponentDef" @@ -1017,13 +981,16 @@ "name": "isInlineTemplate" }, { - "name": "isLContainer" + "name": "isInteropObservable" }, { - "name": "isLView" + "name": "isIterable" }, { - "name": "isObject" + "name": "isLContainer" + }, + { + "name": "isLView" }, { "name": "isPlatformBrowser" @@ -1041,14 +1008,17 @@ "name": "isPromise2" }, { - "name": "isRootView" + "name": "isReadableStreamLike" }, { - "name": "isScheduler" + "name": "isRootView" }, { "name": "isStableFactory" }, + { + "name": "isSubscription" + }, { "name": "isTemplateNode" }, @@ -1061,6 +1031,9 @@ { "name": "iterator" }, + { + "name": "last" + }, { "name": "lastNodeWasCreated" }, @@ -1091,9 +1064,6 @@ { "name": "makeRecord" }, - { - "name": "map" - }, { "name": "markAncestorsForTraversal" }, @@ -1109,9 +1079,6 @@ { "name": "maybeWrapInNotSelector" }, - { - "name": "mergeAll" - }, { "name": "mergeHostAttribute" }, @@ -1160,6 +1127,9 @@ { "name": "observable" }, + { + "name": "observeOn" + }, { "name": "of" }, @@ -1169,9 +1139,15 @@ { "name": "onLeave" }, + { + "name": "operate" + }, { "name": "performanceMarkFeature" }, + { + "name": "popScheduler" + }, { "name": "populateDehydratedViewsInLContainerImpl" }, @@ -1191,7 +1167,7 @@ "name": "provideZoneChangeDetection" }, { - "name": "refCount" + "name": "readableStreamLikeToAsyncGenerator" }, { "name": "refreshContentQueries" @@ -1220,6 +1196,9 @@ { "name": "renderView" }, + { + "name": "reportUnhandledError" + }, { "name": "requiresRefreshOrTraversal" }, @@ -1235,14 +1214,11 @@ { "name": "retrieveHydrationInfoImpl" }, - { - "name": "rxSubscriber" - }, { "name": "saveNameToExportMap" }, { - "name": "scheduleArray" + "name": "scheduleAsyncIterable" }, { "name": "searchTokensOnInjector" @@ -1280,9 +1256,6 @@ { "name": "setUpAttributes" }, - { - "name": "shareSubjectFactory" - }, { "name": "shimStylesContent" }, @@ -1299,13 +1272,7 @@ "name": "stringifyCSSSelector" }, { - "name": "subscribeTo" - }, - { - "name": "subscribeToArray" - }, - { - "name": "switchMap" + "name": "subscribeOn" }, { "name": "throwIfEmpty" @@ -1313,6 +1280,9 @@ { "name": "throwProviderNotFoundError" }, + { + "name": "timeoutProvider" + }, { "name": "toRefArray" }, diff --git a/packages/core/test/bundling/router/bundle.golden_symbols.json b/packages/core/test/bundling/router/bundle.golden_symbols.json index d780911f106e2..69d34116aef94 100644 --- a/packages/core/test/bundling/router/bundle.golden_symbols.json +++ b/packages/core/test/bundling/router/bundle.golden_symbols.json @@ -44,9 +44,6 @@ { "name": "ApplyRedirects" }, - { - "name": "ArgumentOutOfRangeError" - }, { "name": "BLOOM_BUCKET_BITS" }, @@ -80,6 +77,9 @@ { "name": "CIRCULAR" }, + { + "name": "COMPLETE_NOTIFICATION" + }, { "name": "COMPONENT_REGEX" }, @@ -98,12 +98,6 @@ { "name": "CanDeactivate" }, - { - "name": "CatchOperator" - }, - { - "name": "CatchSubscriber" - }, { "name": "ChainedInjector" }, @@ -122,12 +116,6 @@ { "name": "ChildrenOutletContexts" }, - { - "name": "CombineLatestOperator" - }, - { - "name": "CombineLatestSubscriber" - }, { "name": "Compiler" }, @@ -153,10 +141,10 @@ "name": "ConnectableObservable" }, { - "name": "ConnectableSubscriber" + "name": "Console" }, { - "name": "Console" + "name": "ConsumerObserver" }, { "name": "DEFAULT_APP_ID" @@ -173,12 +161,6 @@ { "name": "DefaultDomRenderer2" }, - { - "name": "DefaultIfEmptyOperator" - }, - { - "name": "DefaultIfEmptySubscriber" - }, { "name": "DefaultRouteReuseStrategy" }, @@ -191,15 +173,6 @@ { "name": "DefaultUrlSerializer" }, - { - "name": "DistinctUntilChangedOperator" - }, - { - "name": "DistinctUntilChangedSubscriber" - }, - { - "name": "DoOperator" - }, { "name": "DomAdapter" }, @@ -215,9 +188,15 @@ { "name": "EMPTY_OBJ" }, + { + "name": "EMPTY_OBSERVER" + }, { "name": "EMPTY_PAYLOAD" }, + { + "name": "EMPTY_SUBSCRIPTION" + }, { "name": "ENVIRONMENT_INITIALIZER" }, @@ -254,18 +233,6 @@ { "name": "EventType" }, - { - "name": "FilterOperator" - }, - { - "name": "FilterSubscriber" - }, - { - "name": "FinallyOperator" - }, - { - "name": "FinallySubscriber" - }, { "name": "GenericBrowserDomAdapter" }, @@ -314,9 +281,6 @@ { "name": "Injector" }, - { - "name": "InnerSubscriber" - }, { "name": "ItemComponent" }, @@ -359,24 +323,6 @@ { "name": "MOVED_VIEWS" }, - { - "name": "MapOperator" - }, - { - "name": "MapSubscriber" - }, - { - "name": "MapToOperator" - }, - { - "name": "MapToSubscriber" - }, - { - "name": "MergeMapOperator" - }, - { - "name": "MergeMapSubscriber" - }, { "name": "ModuleWithComponentFactories" }, @@ -428,9 +374,6 @@ { "name": "NG_TEMPLATE_SELECTOR" }, - { - "name": "NONE" - }, { "name": "NOT_FOUND" }, @@ -525,7 +468,7 @@ "name": "Observable" }, { - "name": "OuterSubscriber" + "name": "OperatorSubscriber" }, { "name": "OutletContext" @@ -602,12 +545,6 @@ { "name": "RedirectRequest" }, - { - "name": "RefCountOperator" - }, - { - "name": "RefCountSubscriber" - }, { "name": "Renderer2" }, @@ -683,12 +620,6 @@ { "name": "Sanitizer" }, - { - "name": "ScanOperator" - }, - { - "name": "ScanSubscriber" - }, { "name": "SecurityContext" }, @@ -701,12 +632,6 @@ { "name": "SimpleChange" }, - { - "name": "SimpleInnerSubscriber" - }, - { - "name": "SimpleOuterSubscriber" - }, { "name": "StandaloneService" }, @@ -716,24 +641,12 @@ { "name": "Subject" }, - { - "name": "SubjectSubscriber" - }, - { - "name": "SubjectSubscription" - }, { "name": "Subscriber" }, { "name": "Subscription" }, - { - "name": "SwitchMapOperator" - }, - { - "name": "SwitchMapSubscriber" - }, { "name": "TESTABILITY" }, @@ -755,36 +668,9 @@ { "name": "TYPE" }, - { - "name": "TakeLastOperator" - }, - { - "name": "TakeLastSubscriber" - }, - { - "name": "TakeOperator" - }, - { - "name": "TakeSubscriber" - }, - { - "name": "TakeUntilOperator" - }, - { - "name": "TakeUntilSubscriber" - }, - { - "name": "TapSubscriber" - }, { "name": "TemplateRef" }, - { - "name": "ThrowIfEmptyOperator" - }, - { - "name": "ThrowIfEmptySubscriber" - }, { "name": "Title" }, @@ -821,9 +707,6 @@ { "name": "UrlTree" }, - { - "name": "VERSION" - }, { "name": "VE_ViewContainerRef" }, @@ -851,6 +734,12 @@ { "name": "_NullComponentFactoryResolver" }, + { + "name": "__asyncValues" + }, + { + "name": "__await" + }, { "name": "__forward_ref__" }, @@ -858,10 +747,10 @@ "name": "_applyRootElementTransformImpl" }, { - "name": "_currentInjector" + "name": "_bind" }, { - "name": "_enable_super_gross_mode_that_will_cause_bad_things" + "name": "_currentInjector" }, { "name": "_ensureDirtyViewsAreAlwaysReachable" @@ -953,6 +842,9 @@ { "name": "applyView" }, + { + "name": "arrRemove" + }, { "name": "assertConsumerNode" }, @@ -962,6 +854,9 @@ { "name": "baseElement" }, + { + "name": "bind" + }, { "name": "bindingUpdated" }, @@ -1025,9 +920,6 @@ { "name": "configureViewWithDirective" }, - { - "name": "connectableObservableDescriptor" - }, { "name": "consumerIsLive" }, @@ -1043,6 +935,9 @@ { "name": "containsTree" }, + { + "name": "context" + }, { "name": "convertToBitFlags" }, @@ -1067,12 +962,18 @@ { "name": "createEnvironmentInjector" }, + { + "name": "createErrorClass" + }, { "name": "createInjector" }, { "name": "createInjectorWithoutInjectorInstances" }, + { + "name": "createInvalidObservableTypeError" + }, { "name": "createLFrame" }, @@ -1091,6 +992,12 @@ { "name": "createNodeInjector" }, + { + "name": "createNotification" + }, + { + "name": "createOperatorSubscriber" + }, { "name": "createResultForNode" }, @@ -1124,11 +1031,14 @@ { "name": "deepForEachProvider" }, + { + "name": "defaultCompare" + }, { "name": "defaultErrorFactory" }, { - "name": "defaultErrorHandler" + "name": "defaultErrorHandler2" }, { "name": "defaultIfEmpty" @@ -1166,18 +1076,6 @@ { "name": "diPublicInInjector" }, - { - "name": "dispatch" - }, - { - "name": "empty" - }, - { - "name": "empty2" - }, - { - "name": "empty3" - }, { "name": "emptyPathMatch" }, @@ -1208,9 +1106,15 @@ { "name": "equalPath" }, + { + "name": "errorContext" + }, { "name": "exactMatchOptions" }, + { + "name": "execFinalizer" + }, { "name": "executeCheckHooks" }, @@ -1223,6 +1127,9 @@ { "name": "executeListenerWithErrorHandling" }, + { + "name": "executeSchedule" + }, { "name": "executeTemplate" }, @@ -1256,9 +1163,6 @@ { "name": "flattenRouteTree" }, - { - "name": "flattenUnsubscriptionErrors" - }, { "name": "forEachSingleProvider" }, @@ -1272,7 +1176,7 @@ "name": "from" }, { - "name": "fromArray" + "name": "fromAsyncIterable" }, { "name": "generateInitialInputs" @@ -1466,12 +1370,24 @@ { "name": "handleError" }, + { + "name": "handleReset" + }, + { + "name": "handleStoppedNotification" + }, + { + "name": "handleUnhandledError" + }, { "name": "hasEmptyPathConfig" }, { "name": "hasInSkipHydrationBlockFlag" }, + { + "name": "hasLift" + }, { "name": "hasParentInjector" }, @@ -1481,9 +1397,6 @@ { "name": "hasTagAndTypeMatch" }, - { - "name": "hostReportError" - }, { "name": "icuContainerIterate" }, @@ -1533,7 +1446,7 @@ "name": "injectableDefOrInjectorDefFactory" }, { - "name": "innerSubscribe" + "name": "innerFrom" }, { "name": "insertBloom" @@ -1554,10 +1467,10 @@ "name": "invokeHostBindingsInCreationMode" }, { - "name": "isArray" + "name": "isArrayLike" }, { - "name": "isArrayLike" + "name": "isAsyncIterable" }, { "name": "isCommandWithOutlets" @@ -1598,6 +1511,12 @@ { "name": "isInlineTemplate" }, + { + "name": "isInteropObservable" + }, + { + "name": "isIterable" + }, { "name": "isLContainer" }, @@ -1619,9 +1538,6 @@ { "name": "isNodeMatchingSelectorList" }, - { - "name": "isObject" - }, { "name": "isPlatformServer" }, @@ -1635,11 +1551,14 @@ "name": "isPromise2" }, { - "name": "isScheduler" + "name": "isReadableStreamLike" }, { "name": "isStableFactory" }, + { + "name": "isSubscription" + }, { "name": "isTemplateNode" }, @@ -1659,7 +1578,10 @@ "name": "joinWithSlash" }, { - "name": "last2" + "name": "last" + }, + { + "name": "last3" }, { "name": "lastNodeWasCreated" @@ -1721,6 +1643,9 @@ { "name": "matrixParamsMatch" }, + { + "name": "maybeSchedule" + }, { "name": "maybeUnwrapDefaultExport" }, @@ -1802,6 +1727,9 @@ { "name": "observable" }, + { + "name": "observeOn" + }, { "name": "of" }, @@ -1811,6 +1739,9 @@ { "name": "onLeave" }, + { + "name": "operate" + }, { "name": "paramCompareMap" }, @@ -1823,6 +1754,9 @@ { "name": "policy" }, + { + "name": "popScheduler" + }, { "name": "prioritizedGuardValue" }, @@ -1841,6 +1775,9 @@ { "name": "provideZoneChangeDetection" }, + { + "name": "readableStreamLikeToAsyncGenerator" + }, { "name": "redirectIfUrlTree" }, @@ -1880,6 +1817,9 @@ { "name": "replaceSegment" }, + { + "name": "reportUnhandledError" + }, { "name": "requiresRefreshOrTraversal" }, @@ -1901,14 +1841,11 @@ { "name": "runInInjectionContext" }, - { - "name": "rxSubscriber" - }, { "name": "saveNameToExportMap" }, { - "name": "scheduleArray" + "name": "scheduleAsyncIterable" }, { "name": "searchTokensOnInjector" @@ -1973,9 +1910,6 @@ { "name": "shallowEqual" }, - { - "name": "shareSubjectFactory" - }, { "name": "shimStylesContent" }, @@ -2007,13 +1941,7 @@ "name": "stripTrailingSlash" }, { - "name": "subscribeTo" - }, - { - "name": "subscribeToArray" - }, - { - "name": "subscribeToResult" + "name": "subscribeOn" }, { "name": "subsetMatchOptions" @@ -2045,6 +1973,9 @@ { "name": "throwProviderNotFoundError" }, + { + "name": "timeoutProvider" + }, { "name": "toRefArray" }, @@ -2099,6 +2030,15 @@ { "name": "writeToDirectiveInput" }, + { + "name": "{getPrototypeOf:getPrototypeOf,prototype:objectProto,keys:getKeys}" + }, + { + "name": "{isArray:isArray2}" + }, + { + "name": "{isArray:isArray}" + }, { "name": "ɵEmptyOutletComponent" }, diff --git a/packages/core/test/bundling/standalone_bootstrap/bundle.golden_symbols.json b/packages/core/test/bundling/standalone_bootstrap/bundle.golden_symbols.json index 789274a735058..dfdb82119cb42 100644 --- a/packages/core/test/bundling/standalone_bootstrap/bundle.golden_symbols.json +++ b/packages/core/test/bundling/standalone_bootstrap/bundle.golden_symbols.json @@ -41,6 +41,9 @@ { "name": "CIRCULAR" }, + { + "name": "COMPLETE_NOTIFICATION" + }, { "name": "COMPONENT_REGEX" }, @@ -75,10 +78,7 @@ "name": "ComponentRef2" }, { - "name": "ConnectableObservable" - }, - { - "name": "ConnectableSubscriber" + "name": "ConsumerObserver" }, { "name": "DEFAULT_APP_ID" @@ -92,27 +92,30 @@ { "name": "DefaultDomRenderer2" }, - { - "name": "DistinctUntilChangedOperator" - }, - { - "name": "DistinctUntilChangedSubscriber" - }, { "name": "DomAdapter" }, { "name": "DomRendererFactory2" }, + { + "name": "EMPTY" + }, { "name": "EMPTY_ARRAY" }, { "name": "EMPTY_OBJ" }, + { + "name": "EMPTY_OBSERVER" + }, { "name": "EMPTY_PAYLOAD" }, + { + "name": "EMPTY_SUBSCRIPTION" + }, { "name": "ENVIRONMENT_INITIALIZER" }, @@ -194,18 +197,6 @@ { "name": "MOVED_VIEWS" }, - { - "name": "MapOperator" - }, - { - "name": "MapSubscriber" - }, - { - "name": "MergeMapOperator" - }, - { - "name": "MergeMapSubscriber" - }, { "name": "NAMESPACE_URIS" }, @@ -293,6 +284,9 @@ { "name": "Observable" }, + { + "name": "OperatorSubscriber" + }, { "name": "PLATFORM_DESTROY_LISTENERS" }, @@ -314,12 +308,6 @@ { "name": "REMOVE_STYLES_ON_COMPONENT_DESTROY" }, - { - "name": "RefCountOperator" - }, - { - "name": "RefCountSubscriber" - }, { "name": "RendererFactory2" }, @@ -347,36 +335,18 @@ { "name": "SimpleChange" }, - { - "name": "SimpleInnerSubscriber" - }, - { - "name": "SimpleOuterSubscriber" - }, { "name": "StandaloneService" }, { "name": "Subject" }, - { - "name": "SubjectSubscriber" - }, - { - "name": "SubjectSubscription" - }, { "name": "Subscriber" }, { "name": "Subscription" }, - { - "name": "SwitchMapOperator" - }, - { - "name": "SwitchMapSubscriber" - }, { "name": "TESTABILITY" }, @@ -395,9 +365,6 @@ { "name": "UnsubscriptionError" }, - { - "name": "VERSION" - }, { "name": "ViewEncapsulation" }, @@ -413,6 +380,12 @@ { "name": "_NullComponentFactoryResolver" }, + { + "name": "__asyncValues" + }, + { + "name": "__await" + }, { "name": "__forward_ref__" }, @@ -420,10 +393,10 @@ "name": "_applyRootElementTransformImpl" }, { - "name": "_currentInjector" + "name": "_bind" }, { - "name": "_enable_super_gross_mode_that_will_cause_bad_things" + "name": "_currentInjector" }, { "name": "_getInsertInFrontOfRNodeWithI18n" @@ -485,6 +458,9 @@ { "name": "applyView" }, + { + "name": "arrRemove" + }, { "name": "assertConsumerNode" }, @@ -494,6 +470,9 @@ { "name": "baseElement" }, + { + "name": "bind" + }, { "name": "bloomHasToken" }, @@ -527,24 +506,30 @@ { "name": "configureViewWithDirective" }, - { - "name": "connectableObservableDescriptor" - }, { "name": "consumerIsLive" }, { "name": "consumerPollProducersForChange" }, + { + "name": "context" + }, { "name": "convertToBitFlags" }, { "name": "createElementRef" }, + { + "name": "createErrorClass" + }, { "name": "createInjector" }, + { + "name": "createInvalidObservableTypeError" + }, { "name": "createLFrame" }, @@ -554,6 +539,12 @@ { "name": "createNodeInjector" }, + { + "name": "createNotification" + }, + { + "name": "createOperatorSubscriber" + }, { "name": "createTView" }, @@ -563,6 +554,9 @@ { "name": "deepForEachProvider" }, + { + "name": "defaultCompare" + }, { "name": "detachMovedView" }, @@ -585,19 +579,19 @@ "name": "diPublicInInjector" }, { - "name": "empty" + "name": "enterDI" }, { - "name": "empty2" + "name": "enterView" }, { - "name": "enterDI" + "name": "epoch" }, { - "name": "enterView" + "name": "errorContext" }, { - "name": "epoch" + "name": "execFinalizer" }, { "name": "executeCheckHooks" @@ -605,6 +599,9 @@ { "name": "executeInitAndCheckHooks" }, + { + "name": "executeSchedule" + }, { "name": "executeTemplate" }, @@ -617,9 +614,6 @@ { "name": "extractDirectiveDef" }, - { - "name": "flattenUnsubscriptionErrors" - }, { "name": "forEachSingleProvider" }, @@ -633,7 +627,7 @@ "name": "from" }, { - "name": "fromArray" + "name": "fromAsyncIterable" }, { "name": "generateInitialInputs" @@ -744,7 +738,13 @@ "name": "getTNodeFromLView" }, { - "name": "hostReportError" + "name": "handleReset" + }, + { + "name": "handleStoppedNotification" + }, + { + "name": "handleUnhandledError" }, { "name": "icuContainerIterate" @@ -780,7 +780,7 @@ "name": "injectableDefOrInjectorDefFactory" }, { - "name": "innerSubscribe" + "name": "innerFrom" }, { "name": "insertBloom" @@ -798,10 +798,10 @@ "name": "invokeHostBindingsInCreationMode" }, { - "name": "isArray" + "name": "isArrayLike" }, { - "name": "isArrayLike" + "name": "isAsyncIterable" }, { "name": "isComponentDef" @@ -816,13 +816,16 @@ "name": "isInlineTemplate" }, { - "name": "isLContainer" + "name": "isInteropObservable" }, { - "name": "isLView" + "name": "isIterable" }, { - "name": "isObject" + "name": "isLContainer" + }, + { + "name": "isLView" }, { "name": "isPlatformServer" @@ -837,11 +840,14 @@ "name": "isPromise2" }, { - "name": "isScheduler" + "name": "isReadableStreamLike" }, { "name": "isStableFactory" }, + { + "name": "isSubscription" + }, { "name": "isTemplateNode" }, @@ -854,6 +860,9 @@ { "name": "iterator" }, + { + "name": "last" + }, { "name": "leaveDI" }, @@ -872,9 +881,6 @@ { "name": "makeRecord" }, - { - "name": "map" - }, { "name": "markAncestorsForTraversal" }, @@ -890,9 +896,6 @@ { "name": "maybeWrapInNotSelector" }, - { - "name": "mergeAll" - }, { "name": "mergeHostAttribute" }, @@ -926,18 +929,30 @@ { "name": "noop" }, + { + "name": "noop2" + }, { "name": "notFoundValueOrThrow" }, { "name": "observable" }, + { + "name": "observeOn" + }, { "name": "onEnter" }, { "name": "onLeave" }, + { + "name": "operate" + }, + { + "name": "popScheduler" + }, { "name": "processInjectorTypesWithProviders" }, @@ -954,7 +969,7 @@ "name": "provideZoneChangeDetection" }, { - "name": "refCount" + "name": "readableStreamLikeToAsyncGenerator" }, { "name": "refreshContentQueries" @@ -977,6 +992,9 @@ { "name": "renderView" }, + { + "name": "reportUnhandledError" + }, { "name": "requiresRefreshOrTraversal" }, @@ -989,14 +1007,11 @@ { "name": "retrieveHydrationInfo" }, - { - "name": "rxSubscriber" - }, { "name": "saveNameToExportMap" }, { - "name": "scheduleArray" + "name": "scheduleAsyncIterable" }, { "name": "searchTokensOnInjector" @@ -1031,9 +1046,6 @@ { "name": "setUpAttributes" }, - { - "name": "shareSubjectFactory" - }, { "name": "shimStylesContent" }, @@ -1047,16 +1059,13 @@ "name": "stringifyCSSSelector" }, { - "name": "subscribeTo" + "name": "subscribeOn" }, { - "name": "subscribeToArray" - }, - { - "name": "switchMap" + "name": "throwProviderNotFoundError" }, { - "name": "throwProviderNotFoundError" + "name": "timeoutProvider" }, { "name": "toRefArray" diff --git a/packages/core/test/bundling/todo/bundle.golden_symbols.json b/packages/core/test/bundling/todo/bundle.golden_symbols.json index 5bc987d4e3eeb..4edf8b3c148e2 100644 --- a/packages/core/test/bundling/todo/bundle.golden_symbols.json +++ b/packages/core/test/bundling/todo/bundle.golden_symbols.json @@ -53,6 +53,9 @@ { "name": "CIRCULAR" }, + { + "name": "COMPLETE_NOTIFICATION" + }, { "name": "COMPONENT_REGEX" }, @@ -90,10 +93,7 @@ "name": "ComponentRef2" }, { - "name": "ConnectableObservable" - }, - { - "name": "ConnectableSubscriber" + "name": "ConsumerObserver" }, { "name": "DEFAULT_APP_ID" @@ -113,12 +113,6 @@ { "name": "DefaultIterableDifferFactory" }, - { - "name": "DistinctUntilChangedOperator" - }, - { - "name": "DistinctUntilChangedSubscriber" - }, { "name": "DomAdapter" }, @@ -128,15 +122,24 @@ { "name": "DomRendererFactory2" }, + { + "name": "EMPTY" + }, { "name": "EMPTY_ARRAY" }, { "name": "EMPTY_OBJ" }, + { + "name": "EMPTY_OBSERVER" + }, { "name": "EMPTY_PAYLOAD" }, + { + "name": "EMPTY_SUBSCRIPTION" + }, { "name": "ENVIRONMENT_INITIALIZER" }, @@ -221,18 +224,6 @@ { "name": "MOVED_VIEWS" }, - { - "name": "MapOperator" - }, - { - "name": "MapSubscriber" - }, - { - "name": "MergeMapOperator" - }, - { - "name": "MergeMapSubscriber" - }, { "name": "NAMESPACE_URIS" }, @@ -347,6 +338,9 @@ { "name": "Observable" }, + { + "name": "OperatorSubscriber" + }, { "name": "Optional" }, @@ -380,12 +374,6 @@ { "name": "REMOVE_STYLES_ON_COMPONENT_DESTROY" }, - { - "name": "RefCountOperator" - }, - { - "name": "RefCountSubscriber" - }, { "name": "RendererFactory2" }, @@ -416,36 +404,18 @@ { "name": "SimpleChange" }, - { - "name": "SimpleInnerSubscriber" - }, - { - "name": "SimpleOuterSubscriber" - }, { "name": "SkipSelf" }, { "name": "Subject" }, - { - "name": "SubjectSubscriber" - }, - { - "name": "SubjectSubscription" - }, { "name": "Subscriber" }, { "name": "Subscription" }, - { - "name": "SwitchMapOperator" - }, - { - "name": "SwitchMapSubscriber" - }, { "name": "TESTABILITY" }, @@ -509,9 +479,6 @@ { "name": "UnsubscriptionError" }, - { - "name": "VERSION" - }, { "name": "VE_ViewContainerRef" }, @@ -542,6 +509,12 @@ { "name": "_NullComponentFactoryResolver" }, + { + "name": "__asyncValues" + }, + { + "name": "__await" + }, { "name": "__forward_ref__" }, @@ -549,10 +522,10 @@ "name": "_applyRootElementTransformImpl" }, { - "name": "_currentInjector" + "name": "_bind" }, { - "name": "_enable_super_gross_mode_that_will_cause_bad_things" + "name": "_currentInjector" }, { "name": "_ensureDirtyViewsAreAlwaysReachable" @@ -644,6 +617,9 @@ { "name": "applyViewChange" }, + { + "name": "arrRemove" + }, { "name": "assertConsumerNode" }, @@ -659,6 +635,9 @@ { "name": "baseElement" }, + { + "name": "bind" + }, { "name": "bindingUpdated" }, @@ -707,15 +686,15 @@ { "name": "configureViewWithDirective" }, - { - "name": "connectableObservableDescriptor" - }, { "name": "consumerIsLive" }, { "name": "consumerPollProducersForChange" }, + { + "name": "context" + }, { "name": "convertToBitFlags" }, @@ -728,12 +707,18 @@ { "name": "createElementRef" }, + { + "name": "createErrorClass" + }, { "name": "createInjector" }, { "name": "createInjectorWithoutInjectorInstances" }, + { + "name": "createInvalidObservableTypeError" + }, { "name": "createLContainer" }, @@ -746,6 +731,12 @@ { "name": "createNodeInjector" }, + { + "name": "createNotification" + }, + { + "name": "createOperatorSubscriber" + }, { "name": "createPlatformFactory" }, @@ -758,6 +749,9 @@ { "name": "deepForEachProvider" }, + { + "name": "defaultCompare" + }, { "name": "defaultIterableDiffersFactory" }, @@ -789,19 +783,19 @@ "name": "diPublicInInjector" }, { - "name": "empty" + "name": "enterDI" }, { - "name": "empty2" + "name": "enterView" }, { - "name": "enterDI" + "name": "epoch" }, { - "name": "enterView" + "name": "errorContext" }, { - "name": "epoch" + "name": "execFinalizer" }, { "name": "executeCheckHooks" @@ -815,6 +809,9 @@ { "name": "executeListenerWithErrorHandling" }, + { + "name": "executeSchedule" + }, { "name": "executeTemplate" }, @@ -833,9 +830,6 @@ { "name": "findStylingValue" }, - { - "name": "flattenUnsubscriptionErrors" - }, { "name": "forEachSingleProvider" }, @@ -849,7 +843,7 @@ "name": "from" }, { - "name": "fromArray" + "name": "fromAsyncIterable" }, { "name": "generateInitialInputs" @@ -1010,6 +1004,15 @@ { "name": "handleError" }, + { + "name": "handleReset" + }, + { + "name": "handleStoppedNotification" + }, + { + "name": "handleUnhandledError" + }, { "name": "hasInSkipHydrationBlockFlag" }, @@ -1019,9 +1022,6 @@ { "name": "hasTagAndTypeMatch" }, - { - "name": "hostReportError" - }, { "name": "icuContainerIterate" }, @@ -1068,7 +1068,7 @@ "name": "injectableDefOrInjectorDefFactory" }, { - "name": "innerSubscribe" + "name": "innerFrom" }, { "name": "insertBloom" @@ -1089,10 +1089,10 @@ "name": "invokeHostBindingsInCreationMode" }, { - "name": "isArray" + "name": "isArrayLike" }, { - "name": "isArrayLike" + "name": "isAsyncIterable" }, { "name": "isComponentDef" @@ -1121,6 +1121,12 @@ { "name": "isInlineTemplate" }, + { + "name": "isInteropObservable" + }, + { + "name": "isIterable" + }, { "name": "isLContainer" }, @@ -1136,9 +1142,6 @@ { "name": "isNodeMatchingSelectorList" }, - { - "name": "isObject" - }, { "name": "isPlatformServer" }, @@ -1152,7 +1155,7 @@ "name": "isPromise2" }, { - "name": "isScheduler" + "name": "isReadableStreamLike" }, { "name": "isStableFactory" @@ -1163,6 +1166,9 @@ { "name": "isStylingValuePresent" }, + { + "name": "isSubscription" + }, { "name": "isTemplateNode" }, @@ -1184,6 +1190,9 @@ { "name": "keyValueArraySet" }, + { + "name": "last" + }, { "name": "lastNodeWasCreated" }, @@ -1208,9 +1217,6 @@ { "name": "makeRecord" }, - { - "name": "map" - }, { "name": "markAncestorsForTraversal" }, @@ -1229,9 +1235,6 @@ { "name": "maybeWrapInNotSelector" }, - { - "name": "mergeAll" - }, { "name": "mergeHostAttribute" }, @@ -1274,18 +1277,27 @@ { "name": "noop" }, + { + "name": "noop2" + }, { "name": "notFoundValueOrThrow" }, { "name": "observable" }, + { + "name": "observeOn" + }, { "name": "onEnter" }, { "name": "onLeave" }, + { + "name": "operate" + }, { "name": "optionsReducer" }, @@ -1295,6 +1307,9 @@ { "name": "platformCore" }, + { + "name": "popScheduler" + }, { "name": "processInjectorTypesWithProviders" }, @@ -1308,7 +1323,7 @@ "name": "profiler" }, { - "name": "refCount" + "name": "readableStreamLikeToAsyncGenerator" }, { "name": "refreshContentQueries" @@ -1337,6 +1352,9 @@ { "name": "renderView" }, + { + "name": "reportUnhandledError" + }, { "name": "requiresRefreshOrTraversal" }, @@ -1352,9 +1370,6 @@ { "name": "retrieveHydrationInfo" }, - { - "name": "rxSubscriber" - }, { "name": "saveNameToExportMap" }, @@ -1362,7 +1377,7 @@ "name": "saveResolvedLocalsInData" }, { - "name": "scheduleArray" + "name": "scheduleAsyncIterable" }, { "name": "searchTokensOnInjector" @@ -1421,9 +1436,6 @@ { "name": "setupStaticAttributes" }, - { - "name": "shareSubjectFactory" - }, { "name": "shimStylesContent" }, @@ -1440,16 +1452,13 @@ "name": "stringifyCSSSelector" }, { - "name": "subscribeTo" + "name": "subscribeOn" }, { - "name": "subscribeToArray" - }, - { - "name": "switchMap" + "name": "throwProviderNotFoundError" }, { - "name": "throwProviderNotFoundError" + "name": "timeoutProvider" }, { "name": "toRefArray" diff --git a/packages/router/src/navigation_transition.ts b/packages/router/src/navigation_transition.ts index 1d05b557ed949..cfed13acbbe58 100644 --- a/packages/router/src/navigation_transition.ts +++ b/packages/router/src/navigation_transition.ts @@ -599,7 +599,7 @@ export class NavigationTransitions { return loaders; }; return combineLatest(loadComponents(t.targetSnapshot!.root)) - .pipe(defaultIfEmpty(), take(1)); + .pipe(defaultIfEmpty(null), take(1)); }), switchTap(() => this.afterPreactivation()), diff --git a/packages/router/test/create_router_state.spec.ts b/packages/router/test/create_router_state.spec.ts index 1622dbeb18779..d515db5cecf16 100644 --- a/packages/router/test/create_router_state.spec.ts +++ b/packages/router/test/create_router_state.spec.ts @@ -154,8 +154,8 @@ async function createState(config: Routes, url: string): Promise result.state)) - .toPromise(); + .pipe(map(result => result.state)) + .toPromise() as Promise; } function checkActivatedRoute( diff --git a/packages/router/test/recognize.spec.ts b/packages/router/test/recognize.spec.ts index 1bf24593125d1..d539fd6016b1f 100644 --- a/packages/router/test/recognize.spec.ts +++ b/packages/router/test/recognize.spec.ts @@ -675,7 +675,7 @@ async function recognize( RootComponent, config, tree(url), paramsInheritanceStrategy, serializer) .recognize() .toPromise(); - return result.state; + return result!.state; } function checkActivatedRoute( diff --git a/packages/router/test/router_scroller.spec.ts b/packages/router/test/router_scroller.spec.ts index 16303d4e7d65f..356c7f1470a8b 100644 --- a/packages/router/test/router_scroller.spec.ts +++ b/packages/router/test/router_scroller.spec.ts @@ -40,7 +40,8 @@ describe('RouterScroller', () => { }); function nextScrollEvent(events: Subject): Promise { - return events.pipe(filter((e): e is Scroll => e instanceof Scroll), take(1)).toPromise(); + return events.pipe(filter((e): e is Scroll => e instanceof Scroll), take(1)).toPromise() as + Promise; } describe('scroll to top', () => { diff --git a/packages/service-worker/src/low_level.ts b/packages/service-worker/src/low_level.ts index e3ebfea73b933..9c4606ef2dfb5 100644 --- a/packages/service-worker/src/low_level.ts +++ b/packages/service-worker/src/low_level.ts @@ -193,13 +193,13 @@ export class NgswCommChannel { waitForOperationCompleted(nonce: number): Promise { return this.eventsOfType('OPERATION_COMPLETED') - .pipe(filter(event => event.nonce === nonce), take(1), map(event => { - if (event.result !== undefined) { - return event.result; - } - throw new Error(event.error!); - })) - .toPromise(); + .pipe(filter(event => event.nonce === nonce), take(1), map(event => { + if (event.result !== undefined) { + return event.result; + } + throw new Error(event.error!); + })) + .toPromise() as Promise; } get isEnabled(): boolean { diff --git a/packages/service-worker/src/push.ts b/packages/service-worker/src/push.ts index 92597e6152872..5dc1697cc68d1 100644 --- a/packages/service-worker/src/push.ts +++ b/packages/service-worker/src/push.ts @@ -176,8 +176,8 @@ export class SwPush { return this.pushManager.pipe(switchMap(pm => pm.subscribe(pushOptions)), take(1)) .toPromise() .then(sub => { - this.subscriptionChanges.next(sub); - return sub; + this.subscriptionChanges.next(sub!); + return sub!; }); } diff --git a/packages/service-worker/test/integration_spec.ts b/packages/service-worker/test/integration_spec.ts index 83c6f31aeeacd..2016fd71dfea2 100644 --- a/packages/service-worker/test/integration_spec.ts +++ b/packages/service-worker/test/integration_spec.ts @@ -31,7 +31,7 @@ const dist = new MockFileSystemBuilder().addFile('/only.txt', 'this is only').bu const distUpdate = new MockFileSystemBuilder().addFile('/only.txt', 'this is only v2').build(); function obsToSinglePromise(obs: Observable): Promise { - return obs.pipe(take(1)).toPromise(); + return obs.pipe(take(1)).toPromise() as Promise; } const manifest: Manifest = { diff --git a/packages/zone.js/lib/common/events.ts b/packages/zone.js/lib/common/events.ts index 58f60f77ed115..0c27767e785a3 100644 --- a/packages/zone.js/lib/common/events.ts +++ b/packages/zone.js/lib/common/events.ts @@ -394,6 +394,14 @@ export function patchEventTarget( const passive = passiveSupported && !!passiveEvents && passiveEvents.indexOf(eventName) !== -1; const options = buildEventListenerOptions(arguments[2], passive); + const signal = options && typeof options === 'object' && options.signal && + typeof options.signal === 'object' ? + options.signal : + undefined; + if (signal?.aborted) { + // the signal is an aborted one, just return without attaching the event listener. + return; + } if (unpatchedEvents) { // check unpatched list @@ -465,9 +473,23 @@ export function patchEventTarget( (data as any).taskData = taskData; } + if (signal) { + // if addEventListener with signal options, we don't pass it to + // native addEventListener, instead we keep the signal setting + // and handle ourselves. + taskData.options.signal = undefined; + } const task: any = zone.scheduleEventTask(source, delegate, data, customScheduleFn, customCancelFn); + if (signal) { + // after task is scheduled, we need to store the signal back to task.options + taskData.options.signal = signal; + nativeListener.call(signal, 'abort', () => { + task.zone.cancelTask(task); + }, {once: true}); + } + // should clear taskData.target to avoid memory leak // issue, https://github.com/angular/angular/issues/20442 taskData.target = null; diff --git a/packages/zone.js/lib/common/fetch.ts b/packages/zone.js/lib/common/fetch.ts index 9c2c064d8a13e..2ff4a56843705 100644 --- a/packages/zone.js/lib/common/fetch.ts +++ b/packages/zone.js/lib/common/fetch.ts @@ -26,31 +26,22 @@ Zone.__load_patch('fetch', (global: any, Zone: ZoneType, api: _ZonePrivate) => { const ZoneAwarePromise = global.Promise; const symbolThenPatched = api.symbol('thenPatched'); const fetchTaskScheduling = api.symbol('fetchTaskScheduling'); - const fetchTaskAborting = api.symbol('fetchTaskAborting'); - const OriginalAbortController = global['AbortController']; - const supportAbort = typeof OriginalAbortController === 'function'; - let abortNative: Function|null = null; - if (supportAbort) { - global['AbortController'] = function() { - const abortController = new OriginalAbortController(); - const signal = abortController.signal; - signal.abortController = abortController; - return abortController; - }; - abortNative = api.patchMethod( - OriginalAbortController.prototype, 'abort', - (delegate: Function) => (self: any, args: any) => { - if (self.task) { - return self.task.zone.cancelTask(self.task); - } - return delegate.apply(self, args); - }); - } const placeholder = function() {}; global['fetch'] = function() { const args = Array.prototype.slice.call(arguments); - const options = args.length > 1 ? args[1] : null; + const options = args.length > 1 ? args[1] : {}; const signal = options && options.signal; + const ac = new AbortController(); + const fetchSignal = ac.signal; + options.signal = fetchSignal; + args[1] = options; + if (signal) { + const nativeAddEventListener = + signal[Zone.__symbol__('addEventListener')] || signal.addEventListener; + nativeAddEventListener.call(signal, 'abort', function() { + ac!.abort(); + }, {once: true}); + } return new Promise((res, rej) => { const task = Zone.current.scheduleMacroTask( 'fetch', placeholder, {fetchArgs: args} as FetchTaskData, @@ -88,25 +79,8 @@ Zone.__load_patch('fetch', (global: any, Zone: ZoneType, api: _ZonePrivate) => { }); }, () => { - if (!supportAbort) { - rej('No AbortController supported, can not cancel fetch'); - return; - } - if (signal && signal.abortController && !signal.aborted && - typeof signal.abortController.abort === 'function' && abortNative) { - try { - (Zone.current as any)[fetchTaskAborting] = true; - abortNative.call(signal.abortController); - } finally { - (Zone.current as any)[fetchTaskAborting] = false; - } - } else { - rej('cancel fetch need a AbortController.signal'); - } + ac.abort(); }); - if (signal && signal.abortController) { - signal.abortController.task = task; - } }); }; }); diff --git a/packages/zone.js/test/browser/browser.spec.ts b/packages/zone.js/test/browser/browser.spec.ts index 39c60e9229ae7..974d2d4ce44fc 100644 --- a/packages/zone.js/test/browser/browser.spec.ts +++ b/packages/zone.js/test/browser/browser.spec.ts @@ -1762,6 +1762,194 @@ describe('Zone', function() { expect(logs).toEqual(['click2']); }); + it('should support remove event listeners via AbortController', function() { + let logs: string[] = []; + const ac = new AbortController(); + + button.addEventListener('click', function() { + logs.push('click1'); + }, {signal: ac.signal}); + button.addEventListener('click', function() { + logs.push('click2'); + }); + button.addEventListener('click', function() { + logs.push('click3'); + }, {signal: ac.signal}); + let listeners = button.eventListeners!('click'); + expect(listeners.length).toBe(3); + + button.dispatchEvent(clickEvent); + expect(logs.length).toBe(3); + expect(logs).toEqual(['click1', 'click2', 'click3']); + ac.abort(); + logs = []; + + listeners = button.eventListeners!('click'); + button.dispatchEvent(clickEvent); + expect(logs.length).toBe(1); + expect(listeners.length).toBe(1); + expect(logs).toEqual(['click2']); + }); + + it('should support remove event listeners with AbortController', function() { + let logs: string[] = []; + const ac = new AbortController(); + + const listener1 = function() { + logs.push('click1'); + }; + button.addEventListener('click', listener1, {signal: ac.signal}); + button.addEventListener('click', function() { + logs.push('click2'); + }); + let listeners = button.eventListeners!('click'); + expect(listeners.length).toBe(2); + + button.dispatchEvent(clickEvent); + expect(logs.length).toBe(2); + expect(logs).toEqual(['click1', 'click2']); + + ac.abort(); + listeners = button.eventListeners!('click'); + expect(listeners.length).toBe(1); + + logs = []; + + listeners = button.eventListeners!('click'); + button.dispatchEvent(clickEvent); + expect(logs.length).toBe(1); + expect(listeners.length).toBe(1); + expect(logs).toEqual(['click2']); + }); + + it('should not break remove event listeners with AbortController', function() { + let logs: string[] = []; + const ac = new AbortController(); + + const listener1 = function() { + logs.push('click1'); + }; + button.addEventListener('click', listener1, {signal: ac.signal}); + button.addEventListener('click', function() { + logs.push('click2'); + }); + let listeners = button.eventListeners!('click'); + expect(listeners.length).toBe(2); + + button.dispatchEvent(clickEvent); + expect(logs.length).toBe(2); + expect(logs).toEqual(['click1', 'click2']); + + button.removeEventListener('click', listener1); + listeners = button.eventListeners!('click'); + expect(listeners.length).toBe(1); + + logs = []; + + listeners = button.eventListeners!('click'); + button.dispatchEvent(clickEvent); + expect(logs.length).toBe(1); + expect(listeners.length).toBe(1); + expect(logs).toEqual(['click2']); + }); + + it('should support remove multiple event listeners with the same AbortController', + function() { + let logs: string[] = []; + const ac = new AbortController(); + const button1 = document.createElement('button'); + const keyEvent: any = document.createEvent('KeyboardEvent'); + keyEvent.initKeyboardEvent( + 'keypress', // typeArg, + true, // canBubbleArg, + true, // cancelableArg, + null, // viewArg, Specifies UIEvent.view. This value may be null. + '', + 0, + false, // ctrlKeyArg, + false, // altKeyArg, + false, // shiftKeyArg, + false, // metaKeyArg, + ); + document.body.appendChild(button1); + + const listener1 = function() { + logs.push('click1'); + }; + button.addEventListener('click', listener1, {signal: ac.signal}); + button.addEventListener('click', function() { + logs.push('click2'); + }); + button1.addEventListener('keypress', () => logs.push('click3'), {signal: ac.signal}); + button1.addEventListener('keypress', function() { + logs.push('click4'); + }); + let listeners = button.eventListeners!('click'); + expect(listeners.length).toBe(2); + + button.dispatchEvent(clickEvent); + expect(logs.length).toBe(2); + expect(logs).toEqual(['click1', 'click2']); + button1.dispatchEvent(keyEvent); + expect(logs.length).toBe(4); + expect(logs).toEqual(['click1', 'click2', 'click3', 'click4']); + + logs = []; + ac.abort(); + listeners = button.eventListeners!('click'); + button.dispatchEvent(clickEvent); + expect(logs.length).toBe(1); + expect(listeners.length).toBe(1); + expect(logs).toEqual(['click2']); + button1.dispatchEvent(keyEvent); + expect(logs.length).toBe(2); + expect(logs).toEqual(['click2', 'click4']); + }); + + it('should not add event listeners with aborted signal', function() { + let logs: string[] = []; + + button.addEventListener('click', function() { + logs.push('click1'); + }, {signal: AbortSignal.abort()}); + button.addEventListener('click', function() { + logs.push('click2'); + }); + let listeners = button.eventListeners!('click'); + expect(listeners.length).toBe(1); + + button.dispatchEvent(clickEvent); + expect(logs.length).toBe(1); + expect(logs).toEqual(['click2']); + }); + + it('should remove event listeners with timeout signal', + ifEnvSupportsWithDone( + () => typeof AbortSignal.timeout === 'function', function(done: DoneFn) { + let logs: string[] = []; + + button.addEventListener('click', function() { + logs.push('click1'); + }, {signal: AbortSignal.timeout(1)}); + button.addEventListener('click', function() { + logs.push('click2'); + }); + let listeners = button.eventListeners!('click'); + expect(listeners.length).toBe(2); + + button.dispatchEvent(clickEvent); + expect(logs.length).toBe(2); + expect(logs).toEqual(['click1', 'click2']); + + setTimeout(() => { + logs = []; + button.dispatchEvent(clickEvent); + expect(logs.length).toBe(1); + expect(logs).toEqual(['click2']); + done(); + }, 10); + })); + it('should support reschedule eventTask', ifEnvSupports(supportEventListenerOptions, function() { let hookSpy1 = jasmine.createSpy('spy1'); diff --git a/yarn.lock b/yarn.lock index 6ac680e95886b..af464736b8c3b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14845,20 +14845,13 @@ rx@4.1.0: resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782" integrity sha512-CiaiuN6gapkdl+cZUr67W6I8jquN4lkak3vtIsIWCl4XIPP8ffsoyN6/+PuGXnQy8Cu8W2y9Xxh31Rq4M6wUug== -rxjs@7.8.1, rxjs@^7.2.0, rxjs@^7.5.5, rxjs@^7.8.1: +rxjs@7.8.1, rxjs@^7.0.0, rxjs@^7.2.0, rxjs@^7.5.5, rxjs@^7.8.1: version "7.8.1" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== dependencies: tslib "^2.1.0" -rxjs@^6.6.7: - version "6.6.7" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" - integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ== - dependencies: - tslib "^1.9.0" - safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" @@ -16312,7 +16305,7 @@ tslib@2.6.2, tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3. resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== -tslib@^1.13.0, tslib@^1.8.1, tslib@^1.9.0: +tslib@^1.13.0, tslib@^1.8.1: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==