From c5619ca56ea4236d8de93907383212300c3b9683 Mon Sep 17 00:00:00 2001 From: JoostK Date: Sun, 29 Nov 2020 21:42:40 +0100 Subject: [PATCH] test(compiler-cli): convert styling compliance tests (#39881) This commit converts the DI compliance tests taken from `r3_view_compiler_styling_spec.ts` to the new test runner. PR Close #39881 --- .../binding_slots/GOLDEN_PARTIAL.js | 196 ++++++++ .../binding_slots/TEST_CASES.json | 47 ++ .../component_host_binding_slots.js | 9 + .../component_host_binding_slots.ts | 22 + .../directive_host_binding_slots.js | 8 + .../directive_host_binding_slots.ts | 12 + .../binding_slots/host_binding_slots.js | 10 + .../binding_slots/host_binding_slots.ts | 36 ++ .../chaining/GOLDEN_PARTIAL.js | 362 ++++++++++++++ .../chaining/TEST_CASES.json | 117 +++++ .../chaining/break_different_instructions.js | 14 + .../chaining/break_different_instructions.ts | 20 + ...ak_different_interpolation_instructions.js | 14 + ...ak_different_interpolation_instructions.ts | 18 + .../chaining/class_bindings.js | 11 + .../chaining/class_bindings.ts | 13 + .../chaining/host_bindings.js | 12 + .../chaining/host_bindings.ts | 21 + .../interpolations_different_arity.js | 13 + .../interpolations_different_arity.ts | 16 + .../chaining/interpolations_equal_arity.js | 11 + .../chaining/interpolations_equal_arity.ts | 11 + .../chaining/mixed_bindings.js | 12 + .../chaining/mixed_bindings.ts | 19 + .../chaining/style_bindings.js | 11 + .../chaining/style_bindings.ts | 13 + .../class_bindings/GOLDEN_PARTIAL.js | 185 +++++++ .../class_bindings/TEST_CASES.json | 61 +++ .../class_bindings/class_binding.js | 8 + .../class_bindings/class_binding.ts | 10 + .../class_bindings/class_ordering.js | 19 + .../class_bindings/class_ordering.ts | 20 + .../class_bindings/empty_class_bindings.js | 5 + .../class_bindings/empty_class_bindings.ts | 9 + .../class_bindings/static_bindings.js | 17 + .../class_bindings/static_bindings.ts | 16 + .../component_animations/GOLDEN_PARTIAL.js | 236 +++++++++ .../component_animations/TEST_CASES.json | 75 +++ .../animation_host_bindings.js | 13 + .../animation_host_bindings.ts | 24 + .../animation_listeners.js | 17 + .../animation_listeners.ts | 39 ++ .../animation_property_bindings.js | 21 + .../animation_property_bindings.ts | 16 + .../component_animations/metadata.js | 12 + .../component_animations/metadata.ts | 10 + .../component_animations/metadata_empty.js | 12 + .../component_animations/metadata_empty.ts | 9 + .../component_styles/GOLDEN_PARTIAL.js | 124 +++++ .../component_styles/TEST_CASES.json | 47 ++ .../component_styles/encapsulation_default.js | 1 + .../component_styles/encapsulation_default.ts | 15 + .../component_styles/encapsulation_none.js | 1 + .../component_styles/encapsulation_none.ts | 14 + .../encapsulation_shadow_dom.js | 5 + .../encapsulation_shadow_dom.ts | 14 + .../host_bindings/GOLDEN_PARTIAL.js | 471 ++++++++++++++++++ .../host_bindings/TEST_CASES.json | 101 ++++ .../host_bindings/class_interpolation.js | 24 + .../host_bindings/class_interpolation.ts | 31 ++ .../host_bindings/important.ts | 27 + .../host_bindings/important_host.js | 11 + .../host_bindings/important_template.js | 10 + .../host_bindings/multiple_directives.js | 24 + .../host_bindings/multiple_directives.ts | 31 ++ .../host_bindings/multiple_dynamic.js | 11 + .../host_bindings/multiple_dynamic.ts | 23 + .../host_bindings/static_and_dynamic.js | 12 + .../host_bindings/static_and_dynamic.ts | 20 + .../host_bindings/style_interpolation.js | 24 + .../host_bindings/style_interpolation.ts | 31 ++ .../interpolations/GOLDEN_PARTIAL.js | 251 ++++++++++ .../interpolations/TEST_CASES.json | 75 +++ .../interpolations/class_interpolations.js | 23 + .../interpolations/class_interpolations.ts | 27 + .../interpolations/style_binding_important.js | 5 + .../interpolations/style_binding_important.ts | 11 + .../interpolations/style_binding_sanitizer.js | 7 + .../interpolations/style_binding_sanitizer.ts | 17 + .../interpolations/style_binding_suffixed.js | 5 + .../interpolations/style_binding_suffixed.ts | 11 + .../interpolations/style_properties.js | 23 + .../interpolations/style_properties.ts | 27 + .../invalid/GOLDEN_PARTIAL.js | 27 + .../invalid/TEST_CASES.json | 21 + .../invalid/individual_class_binding.ts | 6 + .../mixed_style_and_class/GOLDEN_PARTIAL.js | 223 +++++++++ .../mixed_style_and_class/TEST_CASES.json | 61 +++ .../mixed_style_and_class/mixed.js | 9 + .../mixed_style_and_class/mixed.ts | 12 + .../multiple_elements.js | 13 + .../multiple_elements.ts | 21 + .../mixed_style_and_class/pipe_bindings.js | 12 + .../mixed_style_and_class/pipe_bindings.ts | 14 + .../pipe_bindings_slots.js | 19 + .../pipe_bindings_slots.ts | 24 + .../style_bindings/GOLDEN_PARTIAL.js | 319 ++++++++++++ .../style_bindings/TEST_CASES.json | 89 ++++ .../style_bindings/binding_slots.js | 33 ++ .../style_bindings/binding_slots.ts | 41 ++ .../binding_slots_interpolations.js | 19 + .../binding_slots_interpolations.ts | 19 + .../style_bindings/empty_style_bindings.js | 5 + .../style_bindings/empty_style_bindings.ts | 9 + .../style_bindings/style_binding.js | 8 + .../style_bindings/style_binding.ts | 10 + .../style_bindings/style_binding_suffixed.js | 9 + .../style_bindings/style_binding_suffixed.ts | 9 + .../style_bindings/style_ordering.js | 15 + .../style_bindings/style_ordering.ts | 10 + 110 files changed, 4493 insertions(+) create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/binding_slots/GOLDEN_PARTIAL.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/binding_slots/TEST_CASES.json create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/binding_slots/component_host_binding_slots.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/binding_slots/component_host_binding_slots.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/binding_slots/directive_host_binding_slots.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/binding_slots/directive_host_binding_slots.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/binding_slots/host_binding_slots.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/binding_slots/host_binding_slots.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/GOLDEN_PARTIAL.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/TEST_CASES.json create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/break_different_instructions.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/break_different_instructions.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/break_different_interpolation_instructions.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/break_different_interpolation_instructions.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/class_bindings.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/class_bindings.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/host_bindings.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/host_bindings.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/interpolations_different_arity.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/interpolations_different_arity.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/interpolations_equal_arity.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/interpolations_equal_arity.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/mixed_bindings.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/mixed_bindings.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/style_bindings.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/style_bindings.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/GOLDEN_PARTIAL.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/TEST_CASES.json create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/class_binding.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/class_binding.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/class_ordering.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/class_ordering.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/empty_class_bindings.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/empty_class_bindings.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/static_bindings.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/static_bindings.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/GOLDEN_PARTIAL.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/TEST_CASES.json create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/animation_host_bindings.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/animation_host_bindings.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/animation_listeners.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/animation_listeners.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/animation_property_bindings.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/animation_property_bindings.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/metadata.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/metadata.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/metadata_empty.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/metadata_empty.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_styles/GOLDEN_PARTIAL.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_styles/TEST_CASES.json create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_styles/encapsulation_default.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_styles/encapsulation_default.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_styles/encapsulation_none.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_styles/encapsulation_none.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_styles/encapsulation_shadow_dom.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_styles/encapsulation_shadow_dom.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/GOLDEN_PARTIAL.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/TEST_CASES.json create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/class_interpolation.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/class_interpolation.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/important.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/important_host.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/important_template.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/multiple_directives.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/multiple_directives.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/multiple_dynamic.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/multiple_dynamic.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/static_and_dynamic.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/static_and_dynamic.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/style_interpolation.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/style_interpolation.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/GOLDEN_PARTIAL.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/TEST_CASES.json create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/class_interpolations.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/class_interpolations.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/style_binding_important.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/style_binding_important.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/style_binding_sanitizer.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/style_binding_sanitizer.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/style_binding_suffixed.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/style_binding_suffixed.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/style_properties.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/style_properties.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/invalid/GOLDEN_PARTIAL.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/invalid/TEST_CASES.json create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/invalid/individual_class_binding.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/mixed_style_and_class/GOLDEN_PARTIAL.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/mixed_style_and_class/TEST_CASES.json create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/mixed_style_and_class/mixed.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/mixed_style_and_class/mixed.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/mixed_style_and_class/multiple_elements.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/mixed_style_and_class/multiple_elements.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/mixed_style_and_class/pipe_bindings.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/mixed_style_and_class/pipe_bindings.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/mixed_style_and_class/pipe_bindings_slots.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/mixed_style_and_class/pipe_bindings_slots.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/GOLDEN_PARTIAL.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/TEST_CASES.json create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/binding_slots.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/binding_slots.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/binding_slots_interpolations.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/binding_slots_interpolations.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/empty_style_bindings.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/empty_style_bindings.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/style_binding.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/style_binding.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/style_binding_suffixed.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/style_binding_suffixed.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/style_ordering.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/style_ordering.ts diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/binding_slots/GOLDEN_PARTIAL.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/binding_slots/GOLDEN_PARTIAL.js new file mode 100644 index 0000000000..f397314c05 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/binding_slots/GOLDEN_PARTIAL.js @@ -0,0 +1,196 @@ +/**************************************************************************************************** + * PARTIAL FILE: component_host_binding_slots.js + ****************************************************************************************************/ +import { Component, HostBinding, Input, NgModule } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { + constructor() { + this.myStyle = { width: '100px' }; + this.myClass = { bar: false }; + this.id = 'some id'; + this.title = 'some title'; + this.name = ''; + } +} +MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); }; +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "my-component", inputs: { name: "name" }, host: { attributes: { "title": "foo title" }, properties: { "style": "myStyle", "class": "myClass", "id": "id", "title": "title" }, styleAttribute: "width:200px; height:500px", classAttribute: "foo baz" }, ngImport: i0, template: { source: '', isInline: true } }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{ + type: Component, + args: [{ + selector: 'my-component', + template: '', + host: { 'style': 'width:200px; height:500px', 'class': 'foo baz', 'title': 'foo title' } + }] + }], null, { myStyle: [{ + type: HostBinding, + args: ['style'] + }], myClass: [{ + type: HostBinding, + args: ['class'] + }], id: [{ + type: HostBinding, + args: ['id'] + }], title: [{ + type: HostBinding, + args: ['title'] + }], name: [{ + type: Input, + args: ['name'] + }] }); })(); +export class MyModule { +} +MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule }); +MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } }); +(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyComponent] }); })(); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{ + type: NgModule, + args: [{ declarations: [MyComponent] }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: component_host_binding_slots.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + myStyle: { + width: string; + }; + myClass: { + bar: boolean; + }; + id: string; + title: string; + name: string; + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} +export declare class MyModule { + static ɵmod: i0.ɵɵNgModuleDefWithMeta; + static ɵinj: i0.ɵɵInjectorDef; +} + +/**************************************************************************************************** + * PARTIAL FILE: directive_host_binding_slots.js + ****************************************************************************************************/ +import { Directive, HostBinding } from '@angular/core'; +import * as i0 from "@angular/core"; +export class WidthDirective { + constructor() { + this.myWidth = 200; + this.myFooClass = true; + this.id = 'some id'; + this.title = 'some title'; + } +} +WidthDirective.ɵfac = function WidthDirective_Factory(t) { return new (t || WidthDirective)(); }; +WidthDirective.ɵdir = i0.ɵɵngDeclareDirective({ version: 1, type: WidthDirective, selector: "[myWidthDir]", host: { properties: { "style.width": "myWidth", "class.foo": "myFooClass", "id": "id", "title": "title" } }, ngImport: i0 }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(WidthDirective, [{ + type: Directive, + args: [{ selector: '[myWidthDir]' }] + }], null, { myWidth: [{ + type: HostBinding, + args: ['style.width'] + }], myFooClass: [{ + type: HostBinding, + args: ['class.foo'] + }], id: [{ + type: HostBinding, + args: ['id'] + }], title: [{ + type: HostBinding, + args: ['title'] + }] }); })(); + +/**************************************************************************************************** + * PARTIAL FILE: directive_host_binding_slots.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class WidthDirective { + myWidth: number; + myFooClass: boolean; + id: string; + title: string; + static ɵfac: i0.ɵɵFactoryDef; + static ɵdir: i0.ɵɵDirectiveDefWithMeta; +} + +/**************************************************************************************************** + * PARTIAL FILE: host_binding_slots.js + ****************************************************************************************************/ +import { Component, Directive, NgModule } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyDir { + constructor() { + this.title = ''; + this.foo = true; + this._animValue = null; + this._animParam1 = null; + this._animParam2 = null; + } +} +MyDir.ɵfac = function MyDir_Factory(t) { return new (t || MyDir)(); }; +MyDir.ɵdir = i0.ɵɵngDeclareDirective({ version: 1, type: MyDir, selector: "[my-dir]", host: { properties: { "title": "title", "class.foo": "foo", "@anim": "{\n value: _animValue,\n params: {\n param1: _animParam1,\n param2: _animParam2\n }\n }" } }, ngImport: i0 }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyDir, [{ + type: Directive, + args: [{ + selector: '[my-dir]', + host: { + '[title]': 'title', + '[class.foo]': 'foo', + '[@anim]': `{ + value: _animValue, + params: { + param1: _animParam1, + param2: _animParam2 + } + }` + } + }] + }], null, null); })(); +export class MyAppComp { +} +MyAppComp.ɵfac = function MyAppComp_Factory(t) { return new (t || MyAppComp)(); }; +MyAppComp.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyAppComp, selector: "my-app", ngImport: i0, template: { source: ` +
+ `, isInline: true }, directives: [{ type: MyDir, selector: "[my-dir]" }] }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyAppComp, [{ + type: Component, + args: [{ + selector: 'my-app', + template: ` +
+ ` + }] + }], null, null); })(); +export class MyModule { +} +MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule }); +MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } }); +(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyAppComp, MyDir] }); })(); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{ + type: NgModule, + args: [{ declarations: [MyAppComp, MyDir] }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: host_binding_slots.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyDir { + title: string; + foo: boolean; + _animValue: null; + _animParam1: null; + _animParam2: null; + static ɵfac: i0.ɵɵFactoryDef; + static ɵdir: i0.ɵɵDirectiveDefWithMeta; +} +export declare class MyAppComp { + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} +export declare class MyModule { + static ɵmod: i0.ɵɵNgModuleDefWithMeta; + static ɵinj: i0.ɵɵInjectorDef; +} + diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/binding_slots/TEST_CASES.json b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/binding_slots/TEST_CASES.json new file mode 100644 index 0000000000..b79da8c56b --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/binding_slots/TEST_CASES.json @@ -0,0 +1,47 @@ +{ + "$schema": "../../test_case_schema.json", + "cases": [ + { + "description": "should count only non-style and non-class host bindings on Components", + "inputFiles": [ + "component_host_binding_slots.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect template", + "files": [ + "component_host_binding_slots.js" + ] + } + ] + }, + { + "description": "should count only non-style and non-class host bindings on Directives", + "inputFiles": [ + "directive_host_binding_slots.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect template", + "files": [ + "directive_host_binding_slots.js" + ] + } + ] + }, + { + "description": "should generate the correct amount of host bindings when styling is present", + "inputFiles": [ + "host_binding_slots.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect template", + "files": [ + "host_binding_slots.js" + ] + } + ] + } + ] +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/binding_slots/component_host_binding_slots.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/binding_slots/component_host_binding_slots.js new file mode 100644 index 0000000000..8f5693e65c --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/binding_slots/component_host_binding_slots.js @@ -0,0 +1,9 @@ +hostAttrs: ["title", "foo title", __AttributeMarker.Classes__, "foo", "baz", __AttributeMarker.Styles__, "width", "200px", "height", "500px"], +hostVars: 6, +hostBindings: function MyComponent_HostBindings(rf, ctx) { + if (rf & 2) { + $r3$.ɵɵhostProperty("id", ctx.id)("title", ctx.title); + $r3$.ɵɵstyleMap(ctx.myStyle); + $r3$.ɵɵclassMap(ctx.myClass); + } +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/binding_slots/component_host_binding_slots.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/binding_slots/component_host_binding_slots.ts new file mode 100644 index 0000000000..18897252ce --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/binding_slots/component_host_binding_slots.ts @@ -0,0 +1,22 @@ +import {Component, HostBinding, Input, NgModule} from '@angular/core'; + +@Component({ + selector: 'my-component', + template: '', + host: {'style': 'width:200px; height:500px', 'class': 'foo baz', 'title': 'foo title'} +}) +export class MyComponent { + @HostBinding('style') myStyle = {width: '100px'}; + + @HostBinding('class') myClass = {bar: false}; + + @HostBinding('id') id = 'some id'; + + @HostBinding('title') title = 'some title'; + + @Input('name') name = ''; +} + +@NgModule({declarations: [MyComponent]}) +export class MyModule { +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/binding_slots/directive_host_binding_slots.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/binding_slots/directive_host_binding_slots.js new file mode 100644 index 0000000000..55f686cc84 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/binding_slots/directive_host_binding_slots.js @@ -0,0 +1,8 @@ +hostVars: 6, +hostBindings: function WidthDirective_HostBindings(rf, ctx) { + if (rf & 2) { + $r3$.ɵɵhostProperty("id", ctx.id)("title", ctx.title); + $r3$.ɵɵstyleProp("width", ctx.myWidth); + $r3$.ɵɵclassProp("foo", ctx.myFooClass); + } + } diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/binding_slots/directive_host_binding_slots.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/binding_slots/directive_host_binding_slots.ts new file mode 100644 index 0000000000..8b70489ef4 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/binding_slots/directive_host_binding_slots.ts @@ -0,0 +1,12 @@ +import {Directive, HostBinding} from '@angular/core'; + +@Directive({selector: '[myWidthDir]'}) +export class WidthDirective { + @HostBinding('style.width') myWidth = 200; + + @HostBinding('class.foo') myFooClass = true; + + @HostBinding('id') id = 'some id'; + + @HostBinding('title') title = 'some title'; +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/binding_slots/host_binding_slots.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/binding_slots/host_binding_slots.js new file mode 100644 index 0000000000..b6dc1fafa0 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/binding_slots/host_binding_slots.js @@ -0,0 +1,10 @@ +hostVars: 10, +hostBindings: function MyDir_HostBindings(rf, ctx) { + if (rf & 2) { + $r3$.ɵɵhostProperty("title", ctx.title); + $r3$.ɵɵsyntheticHostProperty("@anim", + $r3$.ɵɵpureFunction2(7, _c1, ctx._animValue, + $r3$.ɵɵpureFunction2(4, _c0, ctx._animParam1, ctx._animParam2))); + $r3$.ɵɵclassProp("foo", ctx.foo); + } +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/binding_slots/host_binding_slots.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/binding_slots/host_binding_slots.ts new file mode 100644 index 0000000000..4a9c33a8d9 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/binding_slots/host_binding_slots.ts @@ -0,0 +1,36 @@ +import {Component, Directive, NgModule} from '@angular/core'; + +@Directive({ + selector: '[my-dir]', + host: { + '[title]': 'title', + '[class.foo]': 'foo', + '[@anim]': `{ + value: _animValue, + params: { + param1: _animParam1, + param2: _animParam2 + } + }` + } +}) +export class MyDir { + title = ''; + foo = true; + _animValue = null; + _animParam1 = null; + _animParam2 = null; +} + +@Component({ + selector: 'my-app', + template: ` +
+ ` +}) +export class MyAppComp { +} + +@NgModule({declarations: [MyAppComp, MyDir]}) +export class MyModule { +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/GOLDEN_PARTIAL.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/GOLDEN_PARTIAL.js new file mode 100644 index 0000000000..da86d8f540 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/GOLDEN_PARTIAL.js @@ -0,0 +1,362 @@ +/**************************************************************************************************** + * PARTIAL FILE: class_bindings.js + ****************************************************************************************************/ +import { Component } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { + constructor() { + this.yesToApple = true; + this.yesToOrange = true; + this.yesToTomato = false; + } +} +MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); }; +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "ng-component", ngImport: i0, template: { source: `
`, isInline: true } }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{ + type: Component, + args: [{ + template: `
` + }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: class_bindings.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + yesToApple: boolean; + yesToOrange: boolean; + yesToTomato: boolean; + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} + +/**************************************************************************************************** + * PARTIAL FILE: style_bindings.js + ****************************************************************************************************/ +import { Component } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { + constructor() { + this.color = 'red'; + this.border = '1px solid purple'; + this.transition = 'all 1337ms ease'; + } +} +MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); }; +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "ng-component", ngImport: i0, template: { source: `
`, isInline: true } }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{ + type: Component, + args: [{ + template: `
` + }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: style_bindings.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + color: string; + border: string; + transition: string; + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} + +/**************************************************************************************************** + * PARTIAL FILE: mixed_bindings.js + ****************************************************************************************************/ +import { Component } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { + constructor() { + this.color = 'red'; + this.border = '1px solid purple'; + this.transition = 'all 1337ms ease'; + this.yesToApple = true; + this.yesToOrange = true; + this.yesToTomato = false; + } +} +MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); }; +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "ng-component", ngImport: i0, template: { source: `
`, isInline: true } }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{ + type: Component, + args: [{ + template: `
` + }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: mixed_bindings.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + color: string; + border: string; + transition: string; + yesToApple: boolean; + yesToOrange: boolean; + yesToTomato: boolean; + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} + +/**************************************************************************************************** + * PARTIAL FILE: interpolations_equal_arity.js + ****************************************************************************************************/ +import { Component } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { + constructor() { + this.one = ''; + } +} +MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); }; +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "ng-component", ngImport: i0, template: { source: `
`, isInline: true } }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{ + type: Component, + args: [{ + template: `
` + }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: interpolations_equal_arity.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + one: string; + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} + +/**************************************************************************************************** + * PARTIAL FILE: interpolations_different_arity.js + ****************************************************************************************************/ +import { Component } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { + constructor() { + this.one = ''; + this.two = ''; + this.three = ''; + } +} +MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); }; +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "ng-component", ngImport: i0, template: { source: `
`, isInline: true } }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{ + type: Component, + args: [{ + template: `
` + }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: interpolations_different_arity.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + one: string; + two: string; + three: string; + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} + +/**************************************************************************************************** + * PARTIAL FILE: break_different_instructions.js + ****************************************************************************************************/ +import { Component } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { + constructor() { + this.one = ''; + this.transition = 'all 1337ms ease'; + this.width = '42px'; + this.yesToApple = true; + this.yesToOrange = true; + } +} +MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); }; +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "ng-component", ngImport: i0, template: { source: `
`, isInline: true } }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{ + type: Component, + args: [{ + template: `
` + }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: break_different_instructions.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + one: string; + transition: string; + width: string; + yesToApple: boolean; + yesToOrange: boolean; + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} + +/**************************************************************************************************** + * PARTIAL FILE: break_different_interpolation_instructions.js + ****************************************************************************************************/ +import { Component } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { + constructor() { + this.one = ''; + this.two = ''; + this.three = ''; + this.transition = 'all 1337ms ease'; + this.width = '42px'; + } +} +MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); }; +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "ng-component", ngImport: i0, template: { source: `
`, isInline: true } }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{ + type: Component, + args: [{ + template: `
` + }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: break_different_interpolation_instructions.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + one: string; + two: string; + three: string; + transition: string; + width: string; + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} + +/**************************************************************************************************** + * PARTIAL FILE: host_bindings.js + ****************************************************************************************************/ +import { Component, HostBinding } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { + constructor() { + this.color = 'red'; + this.transition = 'all 1337ms ease'; + this.yesToApple = true; + this.yesToTomato = false; + this.border = '1px solid purple'; + this.yesToOrange = true; + } +} +MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); }; +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "ng-component", host: { properties: { "class.apple": "yesToApple", "style.color": "color", "class.tomato": "yesToTomato", "style.transition": "transition", "style.border": "border", "class.orange": "yesToOrange" } }, ngImport: i0, template: { source: '', isInline: true } }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{ + type: Component, + args: [{ + template: '', + host: { + '[class.apple]': 'yesToApple', + '[style.color]': 'color', + '[class.tomato]': 'yesToTomato', + '[style.transition]': 'transition' + } + }] + }], null, { border: [{ + type: HostBinding, + args: ['style.border'] + }], yesToOrange: [{ + type: HostBinding, + args: ['class.orange'] + }] }); })(); + +/**************************************************************************************************** + * PARTIAL FILE: host_bindings.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + color: string; + transition: string; + yesToApple: boolean; + yesToTomato: boolean; + border: string; + yesToOrange: boolean; + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} + diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/TEST_CASES.json b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/TEST_CASES.json new file mode 100644 index 0000000000..194caa405f --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/TEST_CASES.json @@ -0,0 +1,117 @@ +{ + "$schema": "../../test_case_schema.json", + "cases": [ + { + "description": "should chain classProp instruction calls", + "inputFiles": [ + "class_bindings.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect template", + "files": [ + "class_bindings.js" + ] + } + ] + }, + { + "description": "should chain styleProp instruction calls", + "inputFiles": [ + "style_bindings.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect template", + "files": [ + "style_bindings.js" + ] + } + ] + }, + { + "description": "should chain mixed styleProp and classProp calls", + "inputFiles": [ + "mixed_bindings.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect template", + "files": [ + "mixed_bindings.js" + ] + } + ] + }, + { + "description": "should chain style interpolations of the same kind", + "inputFiles": [ + "interpolations_equal_arity.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect template", + "files": [ + "interpolations_equal_arity.js" + ] + } + ] + }, + { + "description": "should chain style interpolations of multiple kinds", + "inputFiles": [ + "interpolations_different_arity.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect template", + "files": [ + "interpolations_different_arity.js" + ] + } + ] + }, + { + "description": "should break into multiple chains if there are other styling instructions in between", + "inputFiles": [ + "break_different_instructions.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect template", + "files": [ + "break_different_instructions.js" + ] + } + ] + }, + { + "description": "should break into multiple chains if there are other styling interpolation instructions in between", + "inputFiles": [ + "break_different_interpolation_instructions.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect template", + "files": [ + "break_different_interpolation_instructions.js" + ] + } + ] + }, + { + "description": "should chain styling instructions inside host bindings", + "inputFiles": [ + "host_bindings.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect template", + "files": [ + "host_bindings.js" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/break_different_instructions.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/break_different_instructions.js new file mode 100644 index 0000000000..7a545ed560 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/break_different_instructions.js @@ -0,0 +1,14 @@ +// ... +MyComponent.ɵcmp = $r3$.ɵɵdefineComponent({ + // ... + template: function MyComponent_Template(rf, $ctx$) { + // ... + if (rf & 2) { + $r3$.ɵɵstylePropInterpolate1("color", "a", ctx.one, "b")("border", "a", ctx.one, "b"); + $r3$.ɵɵstyleProp("transition", ctx.transition)("width", ctx.width); + $r3$.ɵɵstylePropInterpolate1("height", "a", ctx.one, "b")("top", "a", ctx.one, "b"); + $r3$.ɵɵclassProp("apple", ctx.yesToApple)("orange", ctx.yesToOrange); + } + }, + encapsulation: 2 +}); diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/break_different_instructions.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/break_different_instructions.ts new file mode 100644 index 0000000000..791efae724 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/break_different_instructions.ts @@ -0,0 +1,20 @@ +import {Component} from '@angular/core'; + +@Component({ + template: `
` +}) +export class MyComponent { + one = ''; + transition = 'all 1337ms ease'; + width = '42px'; + yesToApple = true; + yesToOrange = true; +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/break_different_interpolation_instructions.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/break_different_interpolation_instructions.js new file mode 100644 index 0000000000..2c5cb7763b --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/break_different_interpolation_instructions.js @@ -0,0 +1,14 @@ +// ... +MyComponent.ɵcmp = $r3$.ɵɵdefineComponent({ + // ... + template: function MyComponent_Template(rf, $ctx$) { + // ... + if (rf & 2) { + $r3$.ɵɵstylePropInterpolate1("color", "a", ctx.one, "b")("border", "a", ctx.one, "b"); + $r3$.ɵɵstylePropInterpolate2("transition", "a", ctx.one, "b", ctx.two, "c"); + $r3$.ɵɵstylePropInterpolate3("width", "a", ctx.one, "b", ctx.two, "c", ctx.three, "d"); + $r3$.ɵɵstylePropInterpolate1("height", "a", ctx.one, "b")("top", "a", ctx.one, "b"); + } + }, + encapsulation: 2 +}); diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/break_different_interpolation_instructions.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/break_different_interpolation_instructions.ts new file mode 100644 index 0000000000..10818dffd5 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/break_different_interpolation_instructions.ts @@ -0,0 +1,18 @@ +import {Component} from '@angular/core'; + +@Component({ + template: `
` +}) +export class MyComponent { + one = ''; + two = ''; + three = ''; + transition = 'all 1337ms ease'; + width = '42px'; +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/class_bindings.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/class_bindings.js new file mode 100644 index 0000000000..8a31dc30ed --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/class_bindings.js @@ -0,0 +1,11 @@ + // ... + MyComponent.ɵcmp = $r3$.ɵɵdefineComponent({ + // ... + template: function MyComponent_Template(rf, $ctx$) { + // ... + if (rf & 2) { + $r3$.ɵɵclassProp("apple", $ctx$.yesToApple)("orange", $ctx$.yesToOrange)("tomato", $ctx$.yesToTomato); + } + }, + encapsulation: 2 +}); diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/class_bindings.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/class_bindings.ts new file mode 100644 index 0000000000..d645bdddc8 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/class_bindings.ts @@ -0,0 +1,13 @@ +import {Component} from '@angular/core'; + +@Component({ + template: `
` +}) +export class MyComponent { + yesToApple = true; + yesToOrange = true; + yesToTomato = false; +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/host_bindings.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/host_bindings.js new file mode 100644 index 0000000000..413c939f8f --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/host_bindings.js @@ -0,0 +1,12 @@ + // ... + MyComponent.ɵcmp = $r3$.ɵɵdefineComponent({ + // ... + hostBindings: function MyComponent_HostBindings(rf, $ctx$) { + // ... + if (rf & 2) { + $r3$.ɵɵstyleProp("color", $ctx$.color)("transition", $ctx$.transition)("border", $ctx$.border); + $r3$.ɵɵclassProp("apple", $ctx$.yesToApple)("tomato", $ctx$.yesToTomato)("orange", $ctx$.yesToOrange); + } + }, + // ... +}); diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/host_bindings.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/host_bindings.ts new file mode 100644 index 0000000000..fe8f3ec7d9 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/host_bindings.ts @@ -0,0 +1,21 @@ +import {Component, HostBinding} from '@angular/core'; + +@Component({ + template: '', + host: { + '[class.apple]': 'yesToApple', + '[style.color]': 'color', + '[class.tomato]': 'yesToTomato', + '[style.transition]': 'transition' + } +}) +export class MyComponent { + color = 'red'; + transition = 'all 1337ms ease'; + yesToApple = true; + yesToTomato = false; + + @HostBinding('style.border') border = '1px solid purple'; + + @HostBinding('class.orange') yesToOrange = true; +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/interpolations_different_arity.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/interpolations_different_arity.js new file mode 100644 index 0000000000..606ac396d3 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/interpolations_different_arity.js @@ -0,0 +1,13 @@ +// ... +MyComponent.ɵcmp = $r3$.ɵɵdefineComponent({ + // ... + template: function MyComponent_Template(rf, $ctx$) { + // ... + if (rf & 2) { + $r3$.ɵɵstylePropInterpolate1("color", "a", ctx.one, "b")("border", "a", ctx.one, "b"); + $r3$.ɵɵstylePropInterpolate2("transition", "a", ctx.one, "b", ctx.two, "c")("width", "a", ctx.one, "b", ctx.two, "c"); + $r3$.ɵɵstylePropInterpolate3("height", "a", ctx.one, "b", ctx.two, "c", ctx.three, "d")("top", "a", ctx.one, "b", ctx.two, "c", ctx.three, "d"); + } + }, + encapsulation: 2 +}); diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/interpolations_different_arity.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/interpolations_different_arity.ts new file mode 100644 index 0000000000..fda27a39ac --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/interpolations_different_arity.ts @@ -0,0 +1,16 @@ +import {Component} from '@angular/core'; + +@Component({ + template: `
` +}) +export class MyComponent { + one = ''; + two = ''; + three = ''; +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/interpolations_equal_arity.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/interpolations_equal_arity.js new file mode 100644 index 0000000000..92d5efdad2 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/interpolations_equal_arity.js @@ -0,0 +1,11 @@ +// ... +MyComponent.ɵcmp = $r3$.ɵɵdefineComponent({ + // ... + template: function MyComponent_Template(rf, $ctx$) { + // ... + if (rf & 2) { + $r3$.ɵɵstylePropInterpolate1("color", "a", ctx.one, "b")("border", "a", ctx.one, "b")("transition", "a", ctx.one, "b"); + } + }, + encapsulation: 2 +}); diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/interpolations_equal_arity.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/interpolations_equal_arity.ts new file mode 100644 index 0000000000..cf97e6eca6 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/interpolations_equal_arity.ts @@ -0,0 +1,11 @@ +import {Component} from '@angular/core'; + +@Component({ + template: `
` +}) +export class MyComponent { + one = ''; +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/mixed_bindings.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/mixed_bindings.js new file mode 100644 index 0000000000..3bd05a2af1 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/mixed_bindings.js @@ -0,0 +1,12 @@ +// ... +MyComponent.ɵcmp = $r3$.ɵɵdefineComponent({ + // ... + template: function MyComponent_Template(rf, $ctx$) { + // ... + if (rf & 2) { + $r3$.ɵɵstyleProp("color", $ctx$.color)("border", $ctx$.border)("transition", $ctx$.transition); + $r3$.ɵɵclassProp("apple", $ctx$.yesToApple)("orange", $ctx$.yesToOrange)("tomato", $ctx$.yesToTomato); + } + }, + encapsulation: 2 +}); diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/mixed_bindings.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/mixed_bindings.ts new file mode 100644 index 0000000000..4d4db2322a --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/mixed_bindings.ts @@ -0,0 +1,19 @@ +import {Component} from '@angular/core'; + +@Component({ + template: `
` +}) +export class MyComponent { + color = 'red'; + border = '1px solid purple'; + transition = 'all 1337ms ease'; + yesToApple = true; + yesToOrange = true; + yesToTomato = false; +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/style_bindings.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/style_bindings.js new file mode 100644 index 0000000000..859fd0d809 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/style_bindings.js @@ -0,0 +1,11 @@ +// ... +MyComponent.ɵcmp = $r3$.ɵɵdefineComponent({ + // ... + template: function MyComponent_Template(rf, $ctx$) { + // ... + if (rf & 2) { + $r3$.ɵɵstyleProp("color", $ctx$.color)("border", $ctx$.border)("transition", $ctx$.transition); + } + }, + encapsulation: 2 +}); diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/style_bindings.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/style_bindings.ts new file mode 100644 index 0000000000..81d68d8135 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/chaining/style_bindings.ts @@ -0,0 +1,13 @@ +import {Component} from '@angular/core'; + +@Component({ + template: `
` +}) +export class MyComponent { + color = 'red'; + border = '1px solid purple'; + transition = 'all 1337ms ease'; +} 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 new file mode 100644 index 0000000000..d2601e4ba2 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/GOLDEN_PARTIAL.js @@ -0,0 +1,185 @@ +/**************************************************************************************************** + * PARTIAL FILE: class_binding.js + ****************************************************************************************************/ +import { Component, NgModule } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { + constructor() { + this.myClassExp = { 'foo': true }; + } +} +MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); }; +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "my-component", ngImport: i0, template: { source: `
`, isInline: true } }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{ + type: Component, + args: [{ selector: 'my-component', template: `
` }] + }], null, null); })(); +export class MyModule { +} +MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule }); +MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } }); +(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyComponent] }); })(); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{ + type: NgModule, + args: [{ declarations: [MyComponent] }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: class_binding.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + myClassExp: { + foo: boolean; + }; + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} +export declare class MyModule { + static ɵmod: i0.ɵɵNgModuleDefWithMeta; + static ɵinj: i0.ɵɵInjectorDef; +} + +/**************************************************************************************************** + * PARTIAL FILE: class_ordering.js + ****************************************************************************************************/ +import { Component, NgModule } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { + constructor() { + this.myClassExp = { a: true, b: true }; + this.yesToApple = true; + this.yesToOrange = true; + } +} +MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); }; +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "my-component", ngImport: i0, template: { source: `
`, isInline: true } }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{ + type: Component, + args: [{ + selector: 'my-component', + template: `
` + }] + }], null, null); })(); +export class MyModule { +} +MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule }); +MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } }); +(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyComponent] }); })(); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{ + type: NgModule, + args: [{ declarations: [MyComponent] }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: class_ordering.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + myClassExp: { + a: boolean; + b: boolean; + }; + yesToApple: boolean; + yesToOrange: boolean; + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} +export declare class MyModule { + static ɵmod: i0.ɵɵNgModuleDefWithMeta; + static ɵinj: i0.ɵɵInjectorDef; +} + +/**************************************************************************************************** + * PARTIAL FILE: static_bindings.js + ****************************************************************************************************/ +import { Component, NgModule } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { +} +MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); }; +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "my-component", ngImport: i0, template: { source: `
`, isInline: true } }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{ + type: Component, + args: [{ + selector: 'my-component', + template: `
` + }] + }], null, null); })(); +export class MyModule { +} +MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule }); +MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } }); +(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyComponent] }); })(); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{ + type: NgModule, + args: [{ declarations: [MyComponent] }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: static_bindings.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} +export declare class MyModule { + static ɵmod: i0.ɵɵNgModuleDefWithMeta; + static ɵinj: i0.ɵɵInjectorDef; +} + +/**************************************************************************************************** + * PARTIAL FILE: empty_class_bindings.js + ****************************************************************************************************/ +import { Component, NgModule } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { +} +MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); }; +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "my-component", ngImport: i0, template: { source: `
`, isInline: true } }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{ + type: Component, + args: [{ selector: 'my-component', template: `
` }] + }], null, null); })(); +export class MyModule { +} +MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule }); +MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } }); +(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyComponent] }); })(); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{ + type: NgModule, + args: [{ declarations: [MyComponent] }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: empty_class_bindings.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} +export declare class MyModule { + static ɵmod: i0.ɵɵNgModuleDefWithMeta; + static ɵinj: i0.ɵɵInjectorDef; +} + 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 new file mode 100644 index 0000000000..48a63da40c --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/TEST_CASES.json @@ -0,0 +1,61 @@ +{ + "$schema": "../../test_case_schema.json", + "cases": [ + { + "description": "should create class styling instructions on the element", + "inputFiles": [ + "class_binding.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect template", + "files": [ + "class_binding.js" + ] + } + ] + }, + { + "description": "should place initial, multi, singular and application followed by attribute class instructions in the template code in that order", + "inputFiles": [ + "class_ordering.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect template", + "files": [ + "class_ordering.js" + ] + } + ] + }, + { + "description": "should not generate the styling apply instruction if there are only static style/class attributes", + "inputFiles": [ + "static_bindings.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect template", + "files": [ + "static_bindings.js" + ] + } + ] + }, + { + "description": "should not create instructions for empty class bindings", + "inputFiles": [ + "empty_class_bindings.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect template", + "files": [ + "empty_class_bindings.js" + ] + } + ] + } + ] +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/class_binding.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/class_binding.js new file mode 100644 index 0000000000..f5147e4e48 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/class_binding.js @@ -0,0 +1,8 @@ +template: function MyComponent_Template(rf, $ctx$) { + if (rf & 1) { + $r3$.ɵɵelement(0, "div"); + } + if (rf & 2) { + $r3$.ɵɵclassMap($ctx$.myClassExp); + } +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/class_binding.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/class_binding.ts new file mode 100644 index 0000000000..863cfb66eb --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/class_binding.ts @@ -0,0 +1,10 @@ +import {Component, NgModule} from '@angular/core'; + +@Component({selector: 'my-component', template: `
`}) +export class MyComponent { + myClassExp = {'foo': true} +} + +@NgModule({declarations: [MyComponent]}) +export class MyModule { +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/class_ordering.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/class_ordering.js new file mode 100644 index 0000000000..d8ea38f6a9 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/class_ordering.js @@ -0,0 +1,19 @@ +// ... +MyComponent.ɵcmp = $r3$.ɵɵdefineComponent({ + type: MyComponent, + selectors:[["my-component"]], + decls: 1, + vars: 7, + consts: [[__AttributeMarker.Classes__, "grape"]], + template: function MyComponent_Template(rf, $ctx$) { + if (rf & 1) { + $r3$.ɵɵelement(0, "div", 0); + } + if (rf & 2) { + $r3$.ɵɵclassMap($ctx$.myClassExp); + $r3$.ɵɵclassProp("apple", $ctx$.yesToApple)("orange", $ctx$.yesToOrange); + $r3$.ɵɵattribute("class", "banana"); + } + }, + encapsulation: 2 + }); diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/class_ordering.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/class_ordering.ts new file mode 100644 index 0000000000..a0bf820bbd --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/class_ordering.ts @@ -0,0 +1,20 @@ +import {Component, NgModule} from '@angular/core'; + +@Component({ + selector: 'my-component', + template: `
` +}) +export class MyComponent { + myClassExp = {a: true, b: true}; + yesToApple = true; + yesToOrange = true; +} + +@NgModule({declarations: [MyComponent]}) +export class MyModule { +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/empty_class_bindings.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/empty_class_bindings.js new file mode 100644 index 0000000000..caf2cef02b --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/empty_class_bindings.js @@ -0,0 +1,5 @@ +template: function MyComponent_Template(rf, $ctx$) { + if (rf & 1) { + $r3$.ɵɵelement(0, "div", 0); + } +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/empty_class_bindings.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/empty_class_bindings.ts new file mode 100644 index 0000000000..bf2ca528f0 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/empty_class_bindings.ts @@ -0,0 +1,9 @@ +import {Component, NgModule} from '@angular/core'; + +@Component({selector: 'my-component', template: `
`}) +export class MyComponent { +} + +@NgModule({declarations: [MyComponent]}) +export class MyModule { +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/static_bindings.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/static_bindings.js new file mode 100644 index 0000000000..2fb0e87ba1 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/static_bindings.js @@ -0,0 +1,17 @@ +// ... +MyComponent.ɵcmp = $r3$.ɵɵdefineComponent({ + type: MyComponent, + selectors:[["my-component"]], + decls: 1, + vars: 2, + consts: [[__AttributeMarker.Classes__, "foo", __AttributeMarker.Styles__, "width", "100px"]], + template: function MyComponent_Template(rf, $ctx$) { + if (rf & 1) { + $r3$.ɵɵelement(0, "div", 0); + } + if (rf & 2) { + $r3$.ɵɵattribute("class", "round")("style", "height:100px", $r3$.ɵɵsanitizeStyle); + } + }, + encapsulation: 2 + }); diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/static_bindings.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/static_bindings.ts new file mode 100644 index 0000000000..ff7ac3f044 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/class_bindings/static_bindings.ts @@ -0,0 +1,16 @@ +import {Component, NgModule} from '@angular/core'; + +@Component({ + selector: 'my-component', + template: `
` +}) +export class MyComponent { +} + +@NgModule({declarations: [MyComponent]}) +export class MyModule { +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/GOLDEN_PARTIAL.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/GOLDEN_PARTIAL.js new file mode 100644 index 0000000000..b628f65bf8 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/GOLDEN_PARTIAL.js @@ -0,0 +1,236 @@ +/**************************************************************************************************** + * PARTIAL FILE: metadata.js + ****************************************************************************************************/ +import { Component, NgModule } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { +} +MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); }; +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "my-component", ngImport: i0, template: { source: '', isInline: true }, animations: [{ name: 'foo123' }, { name: 'trigger123' }] }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{ + type: Component, + args: [{ selector: 'my-component', animations: [{ name: 'foo123' }, { name: 'trigger123' }], template: '' }] + }], null, null); })(); +export class MyModule { +} +MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule }); +MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } }); +(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyComponent] }); })(); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{ + type: NgModule, + args: [{ declarations: [MyComponent] }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: metadata.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} +export declare class MyModule { + static ɵmod: i0.ɵɵNgModuleDefWithMeta; + static ɵinj: i0.ɵɵInjectorDef; +} + +/**************************************************************************************************** + * PARTIAL FILE: metadata_empty.js + ****************************************************************************************************/ +import { Component, NgModule } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { +} +MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); }; +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "my-component", ngImport: i0, template: { source: '', isInline: true }, animations: [] }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{ + type: Component, + args: [{ selector: 'my-component', animations: [], template: '' }] + }], null, null); })(); +export class MyModule { +} +MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule }); +MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } }); +(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyComponent] }); })(); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{ + type: NgModule, + args: [{ declarations: [MyComponent] }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: metadata_empty.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} +export declare class MyModule { + static ɵmod: i0.ɵɵNgModuleDefWithMeta; + static ɵinj: i0.ɵɵInjectorDef; +} + +/**************************************************************************************************** + * PARTIAL FILE: animation_property_bindings.js + ****************************************************************************************************/ +import { Component, NgModule } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { + constructor() { + this.exp = ''; + } +} +MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); }; +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "my-component", ngImport: i0, template: { source: ` +
+
+
`, isInline: true } }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{ + type: Component, + args: [{ + selector: 'my-component', + template: ` +
+
+
`, + }] + }], null, null); })(); +export class MyModule { +} +MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule }); +MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } }); +(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyComponent] }); })(); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{ + type: NgModule, + args: [{ declarations: [MyComponent] }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: animation_property_bindings.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + exp: string; + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} +export declare class MyModule { + static ɵmod: i0.ɵɵNgModuleDefWithMeta; + static ɵinj: i0.ɵɵInjectorDef; +} + +/**************************************************************************************************** + * PARTIAL FILE: animation_listeners.js + ****************************************************************************************************/ +import { Component, NgModule } from '@angular/core'; +import * as i0 from "@angular/core"; +class MyComponent { + onStart(event) { + this.startEvent = event; + } + onDone(event) { + this.doneEvent = event; + } +} +MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); }; +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "my-cmp", ngImport: i0, template: { source: ` +
+ `, isInline: true }, animations: [ + trigger('myAnimation', [ + transition('* => state', [style({ 'opacity': '0' }), animate(500, style({ 'opacity': '1' }))]), + ]), + ] }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{ + type: Component, + args: [{ + selector: 'my-cmp', + template: ` +
+ `, + animations: [ + trigger('myAnimation', [ + transition('* => state', [style({ 'opacity': '0' }), animate(500, style({ 'opacity': '1' }))]), + ]), + ], + }] + }], null, null); })(); +export class MyModule { +} +MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule }); +MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } }); +(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyComponent] }); })(); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{ + type: NgModule, + args: [{ declarations: [MyComponent] }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: animation_listeners.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyModule { + static ɵmod: i0.ɵɵNgModuleDefWithMeta; + static ɵinj: i0.ɵɵInjectorDef; +} + +/**************************************************************************************************** + * PARTIAL FILE: animation_host_bindings.js + ****************************************************************************************************/ +import { Component, Directive, NgModule } from '@angular/core'; +import * as i0 from "@angular/core"; +class MyAnimDir { + constructor() { + this.myAnimState = '123'; + } + onStart() { } + onDone() { } +} +MyAnimDir.ɵfac = function MyAnimDir_Factory(t) { return new (t || MyAnimDir)(); }; +MyAnimDir.ɵdir = i0.ɵɵngDeclareDirective({ version: 1, type: MyAnimDir, selector: "[my-anim-dir]", host: { listeners: { "@myAnim.start": "onStart()", "@myAnim.done": "onDone()" }, properties: { "@myAnim": "myAnimState" } }, ngImport: i0 }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyAnimDir, [{ + type: Directive, + args: [{ + selector: '[my-anim-dir]', + host: { '[@myAnim]': 'myAnimState', '(@myAnim.start)': 'onStart()', '(@myAnim.done)': 'onDone()' } + }] + }], null, null); })(); +class MyComponent { +} +MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); }; +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "my-cmp", ngImport: i0, template: { source: ` +
+ `, isInline: true }, directives: [{ type: MyAnimDir, selector: "[my-anim-dir]" }] }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{ + type: Component, + args: [{ + selector: 'my-cmp', + template: ` +
+ ` + }] + }], null, null); })(); +export class MyModule { +} +MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule }); +MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } }); +(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyComponent, MyAnimDir] }); })(); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{ + type: NgModule, + args: [{ declarations: [MyComponent, MyAnimDir] }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: animation_host_bindings.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyModule { + static ɵmod: i0.ɵɵNgModuleDefWithMeta; + static ɵinj: i0.ɵɵInjectorDef; +} + diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/TEST_CASES.json b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/TEST_CASES.json new file mode 100644 index 0000000000..b1379beebb --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/TEST_CASES.json @@ -0,0 +1,75 @@ +{ + "$schema": "../../test_case_schema.json", + "cases": [ + { + "description": "should pass in the component metadata animations into the component definition", + "inputFiles": [ + "metadata.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect template", + "files": [ + "metadata.js" + ] + } + ] + }, + { + "description": "should include animations even if the provided array is empty", + "inputFiles": [ + "metadata_empty.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect template", + "files": [ + "metadata_empty.js" + ] + } + ] + }, + { + "description": "should generate any animation triggers into the component template", + "inputFiles": [ + "animation_property_bindings.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect template", + "files": [ + "animation_property_bindings.js" + ] + } + ] + }, + { + "description": "should generate animation listeners", + "inputFiles": [ + "animation_listeners.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect template", + "files": [ + "animation_listeners.js" + ] + } + ] + }, + { + "description": "should generate animation host binding and listener code for directives", + "inputFiles": [ + "animation_host_bindings.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect template", + "files": [ + "animation_host_bindings.js" + ] + } + ] + } + ] +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/animation_host_bindings.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/animation_host_bindings.js new file mode 100644 index 0000000000..c669cd6331 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/animation_host_bindings.js @@ -0,0 +1,13 @@ +MyAnimDir.ɵdir = $r3$.ɵɵdefineDirective({ + // ... + hostVars: 1, + hostBindings: function MyAnimDir_HostBindings(rf, ctx) { + if (rf & 1) { + $r3$.ɵɵsyntheticHostListener("@myAnim.start", function MyAnimDir_animation_myAnim_start_HostBindingHandler() { return ctx.onStart(); })("@myAnim.done", function MyAnimDir_animation_myAnim_done_HostBindingHandler() { return ctx.onDone(); }); + } + if (rf & 2) { + $r3$.ɵɵsyntheticHostProperty("@myAnim", ctx.myAnimState); + } + } + // ... +}); diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/animation_host_bindings.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/animation_host_bindings.ts new file mode 100644 index 0000000000..bb44bcfd85 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/animation_host_bindings.ts @@ -0,0 +1,24 @@ +import {Component, Directive, NgModule} from '@angular/core'; + +@Directive({ + selector: '[my-anim-dir]', + host: {'[@myAnim]': 'myAnimState', '(@myAnim.start)': 'onStart()', '(@myAnim.done)': 'onDone()'} +}) +class MyAnimDir { + onStart() {} + onDone() {} + myAnimState = '123'; +} + +@Component({ + selector: 'my-cmp', + template: ` +
+ ` +}) +class MyComponent { +} + +@NgModule({declarations: [MyComponent, MyAnimDir]}) +export class MyModule { +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/animation_listeners.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/animation_listeners.js new file mode 100644 index 0000000000..ec4dda8d60 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/animation_listeners.js @@ -0,0 +1,17 @@ +// ... +MyComponent.ɵcmp = $r3$.ɵɵdefineComponent({ + // ... + decls: 1, + vars: 1, + template: function MyComponent_Template(rf, ctx) { + if (rf & 1) { + $r3$.ɵɵelementStart(0, "div"); + $r3$.ɵɵlistener("@myAnimation.start", function MyComponent_Template_div_animation_myAnimation_start_0_listener($event) { return ctx.onStart($event); })("@myAnimation.done", function MyComponent_Template_div_animation_myAnimation_done_0_listener($event) { return ctx.onDone($event); }); + $r3$.ɵɵelementEnd(); + } if (rf & 2) { + $r3$.ɵɵproperty("@myAnimation", ctx.exp); + } + }, + encapsulation: 2, + // ... +}); diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/animation_listeners.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/animation_listeners.ts new file mode 100644 index 0000000000..e843deaa9f --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/animation_listeners.ts @@ -0,0 +1,39 @@ +import {Component, NgModule} from '@angular/core'; + +declare const animate: any; +declare const style: any; +declare const trigger: any; +declare const transition: any; + +@Component({ + selector: 'my-cmp', + template: ` +
+ `, + animations: [ + trigger( + 'myAnimation', + [ + transition( + '* => state', [style({'opacity': '0'}), animate(500, style({'opacity': '1'}))]), + ]), + ], +}) +class MyComponent { + exp: any; + startEvent: any; + doneEvent: any; + onStart(event: any) { + this.startEvent = event; + } + onDone(event: any) { + this.doneEvent = event; + } +} + +@NgModule({declarations: [MyComponent]}) +export class MyModule { +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/animation_property_bindings.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/animation_property_bindings.js new file mode 100644 index 0000000000..00e059938c --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/animation_property_bindings.js @@ -0,0 +1,21 @@ +// ... +MyComponent.ɵcmp = $r3$.ɵɵdefineComponent({ + // ... + decls: 3, + vars: 3, + template: function MyComponent_Template(rf, $ctx$) { + if (rf & 1) { + $r3$.ɵɵelement(0, "div"); + $r3$.ɵɵelement(1, "div"); + $r3$.ɵɵelement(2, "div"); + } + if (rf & 2) { + $r3$.ɵɵproperty("@foo", ctx.exp); + $r3$.ɵɵadvance(1); + $r3$.ɵɵproperty("@bar", undefined); + $r3$.ɵɵadvance(1); + $r3$.ɵɵproperty("@baz", undefined); + } + }, + encapsulation: 2 +}); diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/animation_property_bindings.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/animation_property_bindings.ts new file mode 100644 index 0000000000..01856d75b4 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/animation_property_bindings.ts @@ -0,0 +1,16 @@ +import {Component, NgModule} from '@angular/core'; + +@Component({ + selector: 'my-component', + template: ` +
+
+
`, +}) +export class MyComponent { + exp = ''; +} + +@NgModule({declarations: [MyComponent]}) +export class MyModule { +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/metadata.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/metadata.js new file mode 100644 index 0000000000..ddcc79b916 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/metadata.js @@ -0,0 +1,12 @@ +MyComponent.ɵcmp = $r3$.ɵɵdefineComponent({ + type: MyComponent, + selectors:[["my-component"]], + decls: 0, + vars: 0, + template: function MyComponent_Template(rf, $ctx$) { + }, + encapsulation: 2, + data: { + animation: [{name: 'foo123'}, {name: 'trigger123'}] + } +}); diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/metadata.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/metadata.ts new file mode 100644 index 0000000000..a08eb566ba --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/metadata.ts @@ -0,0 +1,10 @@ +import {Component, NgModule} from '@angular/core'; + +@Component( + {selector: 'my-component', animations: [{name: 'foo123'}, {name: 'trigger123'}], template: ''}) +export class MyComponent { +} + +@NgModule({declarations: [MyComponent]}) +export class MyModule { +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/metadata_empty.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/metadata_empty.js new file mode 100644 index 0000000000..eee4ed6208 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/metadata_empty.js @@ -0,0 +1,12 @@ +MyComponent.ɵcmp = $r3$.ɵɵdefineComponent({ + type: MyComponent, + selectors:[["my-component"]], + decls: 0, + vars: 0, + template: function MyComponent_Template(rf, $ctx$) { + }, + encapsulation: 2, + data: { + animation: [] + } +}); diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/metadata_empty.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/metadata_empty.ts new file mode 100644 index 0000000000..d39cadde3e --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_animations/metadata_empty.ts @@ -0,0 +1,9 @@ +import {Component, NgModule} from '@angular/core'; + +@Component({selector: 'my-component', animations: [], template: ''}) +export class MyComponent { +} + +@NgModule({declarations: [MyComponent]}) +export class MyModule { +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_styles/GOLDEN_PARTIAL.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_styles/GOLDEN_PARTIAL.js new file mode 100644 index 0000000000..d9bafc8eae --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_styles/GOLDEN_PARTIAL.js @@ -0,0 +1,124 @@ +/**************************************************************************************************** + * PARTIAL FILE: encapsulation_default.js + ****************************************************************************************************/ +import { Component, NgModule } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { +} +MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); }; +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "my-component", ngImport: i0, template: { source: '...', isInline: true }, styles: ["div.foo { color: red; }", ":host p:nth-child(even) { --webkit-transition: 1s linear all; }"] }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{ + type: Component, + args: [{ + selector: 'my-component', + styles: [ + 'div.foo { color: red; }', ':host p:nth-child(even) { --webkit-transition: 1s linear all; }' + ], + template: '...' + }] + }], null, null); })(); +export class MyModule { +} +MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule }); +MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } }); +(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyComponent] }); })(); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{ + type: NgModule, + args: [{ declarations: [MyComponent] }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: encapsulation_default.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} +export declare class MyModule { + static ɵmod: i0.ɵɵNgModuleDefWithMeta; + static ɵinj: i0.ɵɵInjectorDef; +} + +/**************************************************************************************************** + * PARTIAL FILE: encapsulation_none.js + ****************************************************************************************************/ +import { Component, NgModule, ViewEncapsulation } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { +} +MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); }; +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "my-component", ngImport: i0, template: { source: '...', isInline: true }, styles: ["div.tall { height: 123px; }", ":host.small p { height:5px; }"], encapsulation: i0.ViewEncapsulation.None }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{ + type: Component, + args: [{ + selector: 'my-component', + encapsulation: ViewEncapsulation.None, + styles: ['div.tall { height: 123px; }', ':host.small p { height:5px; }'], + template: '...' + }] + }], null, null); })(); +export class MyModule { +} +MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule }); +MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } }); +(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyComponent] }); })(); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{ + type: NgModule, + args: [{ declarations: [MyComponent] }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: encapsulation_none.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} +export declare class MyModule { + static ɵmod: i0.ɵɵNgModuleDefWithMeta; + static ɵinj: i0.ɵɵInjectorDef; +} + +/**************************************************************************************************** + * PARTIAL FILE: encapsulation_shadow_dom.js + ****************************************************************************************************/ +import { Component, NgModule, ViewEncapsulation } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { +} +MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); }; +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "my-component", ngImport: i0, template: { source: '...', isInline: true }, styles: ["div.cool { color: blue; }", ":host.nice p { color: gold; }"], encapsulation: i0.ViewEncapsulation.ShadowDom }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{ + type: Component, + args: [{ + encapsulation: ViewEncapsulation.ShadowDom, + selector: 'my-component', + styles: ['div.cool { color: blue; }', ':host.nice p { color: gold; }'], + template: '...' + }] + }], null, null); })(); +export class MyModule { +} +MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule }); +MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } }); +(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyComponent] }); })(); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{ + type: NgModule, + args: [{ declarations: [MyComponent] }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: encapsulation_shadow_dom.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} +export declare class MyModule { + static ɵmod: i0.ɵɵNgModuleDefWithMeta; + static ɵinj: i0.ɵɵInjectorDef; +} + diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_styles/TEST_CASES.json b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_styles/TEST_CASES.json new file mode 100644 index 0000000000..5b8d3802b7 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_styles/TEST_CASES.json @@ -0,0 +1,47 @@ +{ + "$schema": "../../test_case_schema.json", + "cases": [ + { + "description": "should pass in the component metadata styles into the component definition and shim them using style encapsulation", + "inputFiles": [ + "encapsulation_default.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect template", + "files": [ + "encapsulation_default.js" + ] + } + ] + }, + { + "description": "should pass in styles, but skip shimming the styles if the view encapsulation signals not to", + "inputFiles": [ + "encapsulation_none.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect template", + "files": [ + "encapsulation_none.js" + ] + } + ] + }, + { + "description": "should pass in the component metadata styles into the component definition but skip shimming when style encapsulation is set to shadow dom", + "inputFiles": [ + "encapsulation_shadow_dom.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect template", + "files": [ + "encapsulation_shadow_dom.js" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_styles/encapsulation_default.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_styles/encapsulation_default.js new file mode 100644 index 0000000000..e3d79f87e1 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_styles/encapsulation_default.js @@ -0,0 +1 @@ +styles: ["div.foo[_ngcontent-%COMP%] { color: red; }", "[_nghost-%COMP%] p[_ngcontent-%COMP%]:nth-child(even) { --webkit-transition: 1s linear all; }"] \ No newline at end of file diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_styles/encapsulation_default.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_styles/encapsulation_default.ts new file mode 100644 index 0000000000..331f157f65 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_styles/encapsulation_default.ts @@ -0,0 +1,15 @@ +import {Component, NgModule} from '@angular/core'; + +@Component({ + selector: 'my-component', + styles: [ + 'div.foo { color: red; }', ':host p:nth-child(even) { --webkit-transition: 1s linear all; }' + ], + template: '...' +}) +export class MyComponent { +} + +@NgModule({declarations: [MyComponent]}) +export class MyModule { +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_styles/encapsulation_none.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_styles/encapsulation_none.js new file mode 100644 index 0000000000..9dcf56608a --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_styles/encapsulation_none.js @@ -0,0 +1 @@ +div.tall { height: 123px; }", ":host.small p { height:5px; } \ No newline at end of file diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_styles/encapsulation_none.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_styles/encapsulation_none.ts new file mode 100644 index 0000000000..23ed1b0a0a --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_styles/encapsulation_none.ts @@ -0,0 +1,14 @@ +import {Component, NgModule, ViewEncapsulation} from '@angular/core'; + +@Component({ + selector: 'my-component', + encapsulation: ViewEncapsulation.None, + styles: ['div.tall { height: 123px; }', ':host.small p { height:5px; }'], + template: '...' +}) +export class MyComponent { +} + +@NgModule({declarations: [MyComponent]}) +export class MyModule { +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_styles/encapsulation_shadow_dom.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_styles/encapsulation_shadow_dom.js new file mode 100644 index 0000000000..6d785c6484 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_styles/encapsulation_shadow_dom.js @@ -0,0 +1,5 @@ +MyComponent.ɵcmp = $r3$.ɵɵdefineComponent({ + // ... + styles: ["div.cool { color: blue; }", ":host.nice p { color: gold; }"], + encapsulation: 3 +}) diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_styles/encapsulation_shadow_dom.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_styles/encapsulation_shadow_dom.ts new file mode 100644 index 0000000000..275b131f59 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/component_styles/encapsulation_shadow_dom.ts @@ -0,0 +1,14 @@ +import {Component, NgModule, ViewEncapsulation} from '@angular/core'; + +@Component({ + encapsulation: ViewEncapsulation.ShadowDom, + selector: 'my-component', + styles: ['div.cool { color: blue; }', ':host.nice p { color: gold; }'], + template: '...' +}) +export class MyComponent { +} + +@NgModule({declarations: [MyComponent]}) +export class MyModule { +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/GOLDEN_PARTIAL.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/GOLDEN_PARTIAL.js new file mode 100644 index 0000000000..05d1cf7114 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/GOLDEN_PARTIAL.js @@ -0,0 +1,471 @@ +/**************************************************************************************************** + * PARTIAL FILE: static_and_dynamic.js + ****************************************************************************************************/ +import { Component, HostBinding, NgModule } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { + constructor() { + this.myStyle = { width: '100px' }; + this.myClass = { bar: false }; + this.myColorProp = 'red'; + this.myFooClass = 'red'; + } +} +MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); }; +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "my-component", host: { properties: { "style": "myStyle", "class": "myClass", "style.color": "myColorProp", "class.foo": "myFooClass" }, styleAttribute: "width:200px; height:500px", classAttribute: "foo baz" }, ngImport: i0, template: { source: '', isInline: true } }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{ + type: Component, + args: [{ + selector: 'my-component', + template: '', + host: { 'style': 'width:200px; height:500px', 'class': 'foo baz' } + }] + }], null, { myStyle: [{ + type: HostBinding, + args: ['style'] + }], myClass: [{ + type: HostBinding, + args: ['class'] + }], myColorProp: [{ + type: HostBinding, + args: ['style.color'] + }], myFooClass: [{ + type: HostBinding, + args: ['class.foo'] + }] }); })(); +export class MyModule { +} +MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule }); +MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } }); +(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyComponent] }); })(); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{ + type: NgModule, + args: [{ declarations: [MyComponent] }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: static_and_dynamic.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + myStyle: { + width: string; + }; + myClass: { + bar: boolean; + }; + myColorProp: string; + myFooClass: string; + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} +export declare class MyModule { + static ɵmod: i0.ɵɵNgModuleDefWithMeta; + static ɵinj: i0.ɵɵInjectorDef; +} + +/**************************************************************************************************** + * PARTIAL FILE: multiple_dynamic.js + ****************************************************************************************************/ +import { Component, HostBinding, NgModule } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { + constructor() { + this.myHeightProp = 20; + this.myBarClass = true; + this.myStyle = {}; + this.myWidthProp = '500px'; + this.myFooClass = true; + this.myClasses = { a: true, b: true }; + } +} +MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); }; +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "my-component", host: { properties: { "style.height.pt": "myHeightProp", "class.bar": "myBarClass", "style": "myStyle", "style.width": "myWidthProp", "class.foo": "myFooClass", "class": "myClasses" } }, ngImport: i0, template: { source: '', isInline: true } }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{ + type: Component, + args: [{ + selector: 'my-component', + template: '', + host: { '[style.height.pt]': 'myHeightProp', '[class.bar]': 'myBarClass' } + }] + }], null, { myStyle: [{ + type: HostBinding, + args: ['style'] + }], myWidthProp: [{ + type: HostBinding, + args: ['style.width'] + }], myFooClass: [{ + type: HostBinding, + args: ['class.foo'] + }], myClasses: [{ + type: HostBinding, + args: ['class'] + }] }); })(); +export class MyModule { +} +MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule }); +MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } }); +(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyComponent] }); })(); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{ + type: NgModule, + args: [{ declarations: [MyComponent] }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: multiple_dynamic.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + myHeightProp: number; + myBarClass: boolean; + myStyle: {}; + myWidthProp: string; + myFooClass: boolean; + myClasses: { + a: boolean; + b: boolean; + }; + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} +export declare class MyModule { + static ɵmod: i0.ɵɵNgModuleDefWithMeta; + static ɵinj: i0.ɵɵInjectorDef; +} + +/**************************************************************************************************** + * PARTIAL FILE: important.js + ****************************************************************************************************/ +import { Component, HostBinding, NgModule } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { + constructor() { + this.myStyleExp = ''; + this.myClassExp = ''; + this.myFooClassExp = true; + this.myWidthExp = '100px'; + this.myBarClassExp = true; + this.myHeightExp = '200px'; + } +} +MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); }; +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "my-component", host: { properties: { "style!important": "myStyleExp", "class!important": "myClassExp", "class.foo!important": "myFooClassExp", "style.width!important": "myWidthExp" } }, ngImport: i0, template: { source: ` +
+ `, isInline: true } }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{ + type: Component, + args: [{ + selector: 'my-component', + template: ` +
+ `, + host: { '[style!important]': 'myStyleExp', '[class!important]': 'myClassExp' } + }] + }], null, { myFooClassExp: [{ + type: HostBinding, + args: ['class.foo!important'] + }], myWidthExp: [{ + type: HostBinding, + args: ['style.width!important'] + }] }); })(); +export class MyModule { +} +MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule }); +MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } }); +(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyComponent] }); })(); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{ + type: NgModule, + args: [{ declarations: [MyComponent] }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: important.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + myStyleExp: string; + myClassExp: string; + myFooClassExp: boolean; + myWidthExp: string; + myBarClassExp: boolean; + myHeightExp: string; + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} +export declare class MyModule { + static ɵmod: i0.ɵɵNgModuleDefWithMeta; + static ɵinj: i0.ɵɵInjectorDef; +} + +/**************************************************************************************************** + * PARTIAL FILE: class_interpolation.js + ****************************************************************************************************/ +import { Component, NgModule } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { + constructor() { + this.p1 = 100; + this.p2 = 100; + this.p3 = 100; + this.p4 = 100; + this.p5 = 100; + this.p6 = 100; + this.p7 = 100; + this.p8 = 100; + this.p9 = 100; + } +} +MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); }; +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "my-component", ngImport: i0, template: { source: ` +
+
+
+
+
+
+
+
+
+ `, isInline: true } }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{ + type: Component, + args: [{ + selector: 'my-component', + template: ` +
+
+
+
+
+
+
+
+
+ `, + }] + }], null, null); })(); +export class MyModule { +} +MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule }); +MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } }); +(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyComponent] }); })(); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{ + type: NgModule, + args: [{ declarations: [MyComponent] }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: class_interpolation.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + p1: number; + p2: number; + p3: number; + p4: number; + p5: number; + p6: number; + p7: number; + p8: number; + p9: number; + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} +export declare class MyModule { + static ɵmod: i0.ɵɵNgModuleDefWithMeta; + static ɵinj: i0.ɵɵInjectorDef; +} + +/**************************************************************************************************** + * PARTIAL FILE: style_interpolation.js + ****************************************************************************************************/ +import { Component, NgModule } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { + constructor() { + this.p1 = 100; + this.p2 = 100; + this.p3 = 100; + this.p4 = 100; + this.p5 = 100; + this.p6 = 100; + this.p7 = 100; + this.p8 = 100; + this.p9 = 100; + } +} +MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); }; +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "my-component", ngImport: i0, template: { source: ` +
+
+
+
+
+
+
+
+
+ `, isInline: true } }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{ + type: Component, + args: [{ + selector: 'my-component', + template: ` +
+
+
+
+
+
+
+
+
+ `, + }] + }], null, null); })(); +export class MyModule { +} +MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule }); +MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } }); +(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyComponent] }); })(); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{ + type: NgModule, + args: [{ declarations: [MyComponent] }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: style_interpolation.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + p1: number; + p2: number; + p3: number; + p4: number; + p5: number; + p6: number; + p7: number; + p8: number; + p9: number; + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} +export declare class MyModule { + static ɵmod: i0.ɵɵNgModuleDefWithMeta; + static ɵinj: i0.ɵɵInjectorDef; +} + +/**************************************************************************************************** + * PARTIAL FILE: multiple_directives.js + ****************************************************************************************************/ +import { Component, Directive, HostBinding, NgModule } from '@angular/core'; +import * as i0 from "@angular/core"; +export class ClassDirective { + constructor() { + this.myClassMap = { red: true }; + } +} +ClassDirective.ɵfac = function ClassDirective_Factory(t) { return new (t || ClassDirective)(); }; +ClassDirective.ɵdir = i0.ɵɵngDeclareDirective({ version: 1, type: ClassDirective, selector: "[myClassDir]", host: { properties: { "class": "myClassMap" } }, ngImport: i0 }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(ClassDirective, [{ + type: Directive, + args: [{ selector: '[myClassDir]' }] + }], null, { myClassMap: [{ + type: HostBinding, + args: ['class'] + }] }); })(); +export class WidthDirective { + constructor() { + this.myWidth = 200; + this.myFooClass = true; + } +} +WidthDirective.ɵfac = function WidthDirective_Factory(t) { return new (t || WidthDirective)(); }; +WidthDirective.ɵdir = i0.ɵɵngDeclareDirective({ version: 1, type: WidthDirective, selector: "[myWidthDir]", host: { properties: { "style.width": "myWidth", "class.foo": "myFooClass" } }, ngImport: i0 }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(WidthDirective, [{ + type: Directive, + args: [{ selector: '[myWidthDir]' }] + }], null, { myWidth: [{ + type: HostBinding, + args: ['style.width'] + }], myFooClass: [{ + type: HostBinding, + args: ['class.foo'] + }] }); })(); +export class HeightDirective { + constructor() { + this.myHeight = 200; + this.myBarClass = true; + } +} +HeightDirective.ɵfac = function HeightDirective_Factory(t) { return new (t || HeightDirective)(); }; +HeightDirective.ɵdir = i0.ɵɵngDeclareDirective({ version: 1, type: HeightDirective, selector: "[myHeightDir]", host: { properties: { "style.height": "myHeight", "class.bar": "myBarClass" } }, ngImport: i0 }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(HeightDirective, [{ + type: Directive, + args: [{ selector: '[myHeightDir]' }] + }], null, { myHeight: [{ + type: HostBinding, + args: ['style.height'] + }], myBarClass: [{ + type: HostBinding, + args: ['class.bar'] + }] }); })(); +export class MyComponent { +} +MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); }; +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "my-component", ngImport: i0, template: { source: '
', isInline: true }, directives: [{ type: WidthDirective, selector: "[myWidthDir]" }, { type: HeightDirective, selector: "[myHeightDir]" }, { type: ClassDirective, selector: "[myClassDir]" }] }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{ + type: Component, + args: [{ + selector: 'my-component', + template: '
', + }] + }], null, null); })(); +export class MyModule { +} +MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule }); +MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } }); +(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyComponent, WidthDirective, HeightDirective, ClassDirective] }); })(); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{ + type: NgModule, + args: [{ declarations: [MyComponent, WidthDirective, HeightDirective, ClassDirective] }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: multiple_directives.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class ClassDirective { + myClassMap: { + red: boolean; + }; + static ɵfac: i0.ɵɵFactoryDef; + static ɵdir: i0.ɵɵDirectiveDefWithMeta; +} +export declare class WidthDirective { + myWidth: number; + myFooClass: boolean; + static ɵfac: i0.ɵɵFactoryDef; + static ɵdir: i0.ɵɵDirectiveDefWithMeta; +} +export declare class HeightDirective { + myHeight: number; + myBarClass: boolean; + static ɵfac: i0.ɵɵFactoryDef; + static ɵdir: i0.ɵɵDirectiveDefWithMeta; +} +export declare class MyComponent { + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} +export declare class MyModule { + static ɵmod: i0.ɵɵNgModuleDefWithMeta; + static ɵinj: i0.ɵɵInjectorDef; +} + diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/TEST_CASES.json b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/TEST_CASES.json new file mode 100644 index 0000000000..32333d7a61 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/TEST_CASES.json @@ -0,0 +1,101 @@ +{ + "$schema": "../../test_case_schema.json", + "cases": [ + { + "description": "should generate style/class instructions for a host component creation definition", + "inputFiles": [ + "static_and_dynamic.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect template", + "files": [ + "static_and_dynamic.js" + ] + } + ] + }, + { + "description": "should generate style/class instructions for multiple host binding definitions", + "inputFiles": [ + "multiple_dynamic.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect template", + "files": [ + "multiple_dynamic.js" + ] + } + ] + }, + { + "description": "should generate override instructions for only single-level styling bindings when !important is present", + "inputFiles": [ + "important.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect template", + "files": [ + { + "expected": "important_template.js", + "generated": "important.js" + } + ] + }, + { + "failureMessage": "Incorrect host", + "files": [ + { + "expected": "important_host.js", + "generated": "important.js" + } + ] + } + ] + }, + { + "description": "should support class interpolation", + "inputFiles": [ + "class_interpolation.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect template", + "files": [ + "class_interpolation.js" + ] + } + ] + }, + { + "description": "should support style interpolation", + "inputFiles": [ + "style_interpolation.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect template", + "files": [ + "style_interpolation.js" + ] + } + ] + }, + { + "description": "should generate styling instructions for multiple directives that contain host binding definitions", + "inputFiles": [ + "multiple_directives.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect template", + "files": [ + "multiple_directives.js" + ] + } + ] + } + ] +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/class_interpolation.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/class_interpolation.js new file mode 100644 index 0000000000..8bc77db5c8 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/class_interpolation.js @@ -0,0 +1,24 @@ +function MyComponent_Template(rf, ctx) { + if (rf & 1) { + // ... + } + if (rf & 2) { + $r3$.ɵɵclassMapInterpolate1("A", ctx.p1, "B"); + $r3$.ɵɵadvance(1); + $r3$.ɵɵclassMapInterpolate2("A", ctx.p1, "B", ctx.p2, "C"); + $r3$.ɵɵadvance(1); + $r3$.ɵɵclassMapInterpolate3("A", ctx.p1, "B", ctx.p2, "C", ctx.p3, "D"); + $r3$.ɵɵadvance(1); + $r3$.ɵɵclassMapInterpolate4("A", ctx.p1, "B", ctx.p2, "C", ctx.p3, "D", ctx.p4, "E"); + $r3$.ɵɵadvance(1); + $r3$.ɵɵclassMapInterpolate5("A", ctx.p1, "B", ctx.p2, "C", ctx.p3, "D", ctx.p4, "E", ctx.p5, "F"); + $r3$.ɵɵadvance(1); + $r3$.ɵɵclassMapInterpolate6("A", ctx.p1, "B", ctx.p2, "C", ctx.p3, "D", ctx.p4, "E", ctx.p5, "F", ctx.p6, "G"); + $r3$.ɵɵadvance(1); + $r3$.ɵɵclassMapInterpolate7("A", ctx.p1, "B", ctx.p2, "C", ctx.p3, "D", ctx.p4, "E", ctx.p5, "F", ctx.p6, "G", ctx.p7, "H"); + $r3$.ɵɵadvance(1); + $r3$.ɵɵclassMapInterpolate8("A", ctx.p1, "B", ctx.p2, "C", ctx.p3, "D", ctx.p4, "E", ctx.p5, "F", ctx.p6, "G", ctx.p7, "H", ctx.p8, "I"); + $r3$.ɵɵadvance(1); + $r3$.ɵɵclassMapInterpolateV(["A", ctx.p1, "B", ctx.p2, "C", ctx.p3, "D", ctx.p4, "E", ctx.p5, "F", ctx.p6, "G", ctx.p7, "H", ctx.p8, "I", ctx.p9, "J"]); + } +}, diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/class_interpolation.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/class_interpolation.ts new file mode 100644 index 0000000000..b8a6a4283d --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/class_interpolation.ts @@ -0,0 +1,31 @@ +import {Component, NgModule} from '@angular/core'; + +@Component({ + selector: 'my-component', + template: ` +
+
+
+
+
+
+
+
+
+ `, +}) +export class MyComponent { + p1 = 100; + p2 = 100; + p3 = 100; + p4 = 100; + p5 = 100; + p6 = 100; + p7 = 100; + p8 = 100; + p9 = 100; +} + +@NgModule({declarations: [MyComponent]}) +export class MyModule { +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/important.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/important.ts new file mode 100644 index 0000000000..15ddd97110 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/important.ts @@ -0,0 +1,27 @@ +import {Component, HostBinding, NgModule} from '@angular/core'; + +@Component({ + selector: 'my-component', + template: ` +
+ `, + host: {'[style!important]': 'myStyleExp', '[class!important]': 'myClassExp'} +}) +export class MyComponent { + myStyleExp = ''; + myClassExp = ''; + + @HostBinding('class.foo!important') myFooClassExp = true; + + @HostBinding('style.width!important') myWidthExp = '100px'; + + myBarClassExp = true; + myHeightExp = '200px'; +} + +@NgModule({declarations: [MyComponent]}) +export class MyModule { +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/important_host.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/important_host.js new file mode 100644 index 0000000000..b5c96ca28d --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/important_host.js @@ -0,0 +1,11 @@ +function MyComponent_Template(rf, ctx) { + if (rf & 1) { + $r3$.ɵɵelement(0, "div"); + } + if (rf & 2) { + $r3$.ɵɵstyleMap(ctx.myStyleExp); + $r3$.ɵɵclassMap(ctx.myClassExp); + $r3$.ɵɵstyleProp("height", ctx.myHeightExp); + $r3$.ɵɵclassProp("bar", ctx.myBarClassExp); + } +}, diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/important_template.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/important_template.js new file mode 100644 index 0000000000..3e6efb395c --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/important_template.js @@ -0,0 +1,10 @@ + +hostVars: 8, +hostBindings: function MyComponent_HostBindings(rf, ctx) { + if (rf & 2) { + $r3$.ɵɵstyleMap(ctx.myStyleExp); + $r3$.ɵɵclassMap(ctx.myClassExp); + $r3$.ɵɵstyleProp("width", ctx.myWidthExp); + $r3$.ɵɵclassProp("foo", ctx.myFooClassExp); + } +}, diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/multiple_directives.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/multiple_directives.js new file mode 100644 index 0000000000..fc4ee5cbf0 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/multiple_directives.js @@ -0,0 +1,24 @@ +// ... +hostVars: 2, +hostBindings: function ClassDirective_HostBindings(rf, ctx) { + if (rf & 2) { + $r3$.ɵɵclassMap(ctx.myClassMap); + } +} +// ... +hostVars: 4, +hostBindings: function WidthDirective_HostBindings(rf, ctx) { + if (rf & 2) { + $r3$.ɵɵstyleProp("width", ctx.myWidth); + $r3$.ɵɵclassProp("foo", ctx.myFooClass); + } +} +// ... +hostVars: 4, +hostBindings: function HeightDirective_HostBindings(rf, ctx) { + if (rf & 2) { + $r3$.ɵɵstyleProp("height", ctx.myHeight); + $r3$.ɵɵclassProp("bar", ctx.myBarClass); + } +} +// ... diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/multiple_directives.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/multiple_directives.ts new file mode 100644 index 0000000000..8ac7090fc6 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/multiple_directives.ts @@ -0,0 +1,31 @@ +import {Component, Directive, HostBinding, NgModule} from '@angular/core'; + +@Directive({selector: '[myClassDir]'}) +export class ClassDirective { + @HostBinding('class') myClassMap = {red: true}; +} + +@Directive({selector: '[myWidthDir]'}) +export class WidthDirective { + @HostBinding('style.width') myWidth = 200; + + @HostBinding('class.foo') myFooClass = true; +} + +@Directive({selector: '[myHeightDir]'}) +export class HeightDirective { + @HostBinding('style.height') myHeight = 200; + + @HostBinding('class.bar') myBarClass = true; +} + +@Component({ + selector: 'my-component', + template: '
', +}) +export class MyComponent { +} + +@NgModule({declarations: [MyComponent, WidthDirective, HeightDirective, ClassDirective]}) +export class MyModule { +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/multiple_dynamic.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/multiple_dynamic.js new file mode 100644 index 0000000000..dbc6e71f40 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/multiple_dynamic.js @@ -0,0 +1,11 @@ +hostVars: 12, +hostBindings: function MyComponent_HostBindings(rf, ctx) { + if (rf & 2) { + $r3$.ɵɵstyleMap(ctx.myStyle); + $r3$.ɵɵclassMap(ctx.myClasses); + $r3$.ɵɵstyleProp("height", ctx.myHeightProp, "pt")("width", ctx.myWidthProp); + $r3$.ɵɵclassProp("bar", ctx.myBarClass)("foo", ctx.myFooClass); + } +}, +decls: 0, +vars: 0, diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/multiple_dynamic.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/multiple_dynamic.ts new file mode 100644 index 0000000000..ea2af92327 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/multiple_dynamic.ts @@ -0,0 +1,23 @@ +import {Component, HostBinding, NgModule} from '@angular/core'; + +@Component({ + selector: 'my-component', + template: '', + host: {'[style.height.pt]': 'myHeightProp', '[class.bar]': 'myBarClass'} +}) +export class MyComponent { + myHeightProp = 20; + myBarClass = true; + + @HostBinding('style') myStyle = {}; + + @HostBinding('style.width') myWidthProp = '500px'; + + @HostBinding('class.foo') myFooClass = true; + + @HostBinding('class') myClasses = {a: true, b: true}; +} + +@NgModule({declarations: [MyComponent]}) +export class MyModule { +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/static_and_dynamic.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/static_and_dynamic.js new file mode 100644 index 0000000000..8f36c1da5c --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/static_and_dynamic.js @@ -0,0 +1,12 @@ +hostAttrs: [__AttributeMarker.Classes__, "foo", "baz", __AttributeMarker.Styles__, "width", "200px", "height", "500px"], +hostVars: 8, +hostBindings: function MyComponent_HostBindings(rf, ctx) { + if (rf & 2) { + $r3$.ɵɵstyleMap(ctx.myStyle); + $r3$.ɵɵclassMap(ctx.myClass); + $r3$.ɵɵstyleProp("color", ctx.myColorProp); + $r3$.ɵɵclassProp("foo", ctx.myFooClass); + } +}, +decls: 0, +vars: 0, diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/static_and_dynamic.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/static_and_dynamic.ts new file mode 100644 index 0000000000..e6c26a82b7 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/static_and_dynamic.ts @@ -0,0 +1,20 @@ +import {Component, HostBinding, NgModule} from '@angular/core'; + +@Component({ + selector: 'my-component', + template: '', + host: {'style': 'width:200px; height:500px', 'class': 'foo baz'} +}) +export class MyComponent { + @HostBinding('style') myStyle = {width: '100px'}; + + @HostBinding('class') myClass = {bar: false}; + + @HostBinding('style.color') myColorProp = 'red'; + + @HostBinding('class.foo') myFooClass = 'red'; +} + +@NgModule({declarations: [MyComponent]}) +export class MyModule { +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/style_interpolation.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/style_interpolation.js new file mode 100644 index 0000000000..0e3f5369ef --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/style_interpolation.js @@ -0,0 +1,24 @@ +function MyComponent_Template(rf, ctx) { + if (rf & 1) { + // ... + } + if (rf & 2) { + $r3$.ɵɵstyleMapInterpolate1("p1:", ctx.p1, ";"); + $r3$.ɵɵadvance(1); + $r3$.ɵɵstyleMapInterpolate2("p1:", ctx.p1, ";p2:", ctx.p2, ";"); + $r3$.ɵɵadvance(1); + $r3$.ɵɵstyleMapInterpolate3("p1:", ctx.p1, ";p2:", ctx.p2, ";p3:", ctx.p3, ";"); + $r3$.ɵɵadvance(1); + $r3$.ɵɵstyleMapInterpolate4("p1:", ctx.p1, ";p2:", ctx.p2, ";p3:", ctx.p3, ";p4:", ctx.p4, ";"); + $r3$.ɵɵadvance(1); + $r3$.ɵɵstyleMapInterpolate5("p1:", ctx.p1, ";p2:", ctx.p2, ";p3:", ctx.p3, ";p4:", ctx.p4, ";p5:", ctx.p5, ";"); + $r3$.ɵɵadvance(1); + $r3$.ɵɵstyleMapInterpolate6("p1:", ctx.p1, ";p2:", ctx.p2, ";p3:", ctx.p3, ";p4:", ctx.p4, ";p5:", ctx.p5, ";p6:", ctx.p6, ";"); + $r3$.ɵɵadvance(1); + $r3$.ɵɵstyleMapInterpolate7("p1:", ctx.p1, ";p2:", ctx.p2, ";p3:", ctx.p3, ";p4:", ctx.p4, ";p5:", ctx.p5, ";p6:", ctx.p6, ";p7:", ctx.p7, ";"); + $r3$.ɵɵadvance(1); + $r3$.ɵɵstyleMapInterpolate8("p1:", ctx.p1, ";p2:", ctx.p2, ";p3:", ctx.p3, ";p4:", ctx.p4, ";p5:", ctx.p5, ";p6:", ctx.p6, ";p7:", ctx.p7, ";p8:", ctx.p8, ";"); + $r3$.ɵɵadvance(1); + $r3$.ɵɵstyleMapInterpolateV(["p1:", ctx.p1, ";p2:", ctx.p2, ";p3:", ctx.p3, ";p4:", ctx.p4, ";p5:", ctx.p5, ";p6:", ctx.p6, ";p7:", ctx.p7, ";p8:", ctx.p8, ";p9:", ctx.p9, ";"]); + } +}, diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/style_interpolation.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/style_interpolation.ts new file mode 100644 index 0000000000..0da5babf65 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/style_interpolation.ts @@ -0,0 +1,31 @@ +import {Component, NgModule} from '@angular/core'; + +@Component({ + selector: 'my-component', + template: ` +
+
+
+
+
+
+
+
+
+ `, +}) +export class MyComponent { + p1 = 100; + p2 = 100; + p3 = 100; + p4 = 100; + p5 = 100; + p6 = 100; + p7 = 100; + p8 = 100; + p9 = 100; +} + +@NgModule({declarations: [MyComponent]}) +export class MyModule { +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/GOLDEN_PARTIAL.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/GOLDEN_PARTIAL.js new file mode 100644 index 0000000000..eb50a17cb2 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/GOLDEN_PARTIAL.js @@ -0,0 +1,251 @@ +/**************************************************************************************************** + * PARTIAL FILE: class_interpolations.js + ****************************************************************************************************/ +import { Component } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { + constructor() { + this.one = ''; + this.two = ''; + this.three = ''; + this.four = ''; + this.five = ''; + this.six = ''; + this.seven = ''; + this.eight = ''; + this.nine = ''; + } +} +MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); }; +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "ng-component", ngImport: i0, template: { source: ` +
+
+
+
+
+
+
+
+
+
+ `, isInline: true } }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{ + type: Component, + args: [{ + template: ` +
+
+
+
+
+
+
+
+
+
+ ` + }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: class_interpolations.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + one: string; + two: string; + three: string; + four: string; + five: string; + six: string; + seven: string; + eight: string; + nine: string; + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} + +/**************************************************************************************************** + * PARTIAL FILE: style_properties.js + ****************************************************************************************************/ +import { Component } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { + constructor() { + this.one = ''; + this.two = ''; + this.three = ''; + this.four = ''; + this.five = ''; + this.six = ''; + this.seven = ''; + this.eight = ''; + this.nine = ''; + } +} +MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); }; +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "ng-component", ngImport: i0, template: { source: ` +
+
+
+
+
+
+
+
+
+
+ `, isInline: true } }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{ + type: Component, + args: [{ + template: ` +
+
+
+
+
+
+
+
+
+
+ ` + }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: style_properties.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + one: string; + two: string; + three: string; + four: string; + five: string; + six: string; + seven: string; + eight: string; + nine: string; + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} + +/**************************************************************************************************** + * PARTIAL FILE: style_binding_suffixed.js + ****************************************************************************************************/ +import { Component } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { + constructor() { + this.one = ''; + this.two = ''; + } +} +MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); }; +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "ng-component", ngImport: i0, template: { source: ` +
+ `, isInline: true } }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{ + type: Component, + args: [{ + template: ` +
+ ` + }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: style_binding_suffixed.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + one: string; + two: string; + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} + +/**************************************************************************************************** + * PARTIAL FILE: style_binding_sanitizer.js + ****************************************************************************************************/ +import { Component } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { + constructor() { + this.myUrl1 = '...'; + this.myUrl2 = '...'; + this.myBoxX = '0px'; + this.myBoxY = '0px'; + this.myBoxWidth = '100px'; + this.myRepeat = 'no-repeat'; + } +} +MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); }; +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "ng-component", ngImport: i0, template: { source: ` +
+ `, isInline: true } }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{ + type: Component, + args: [{ + template: ` +
+ ` + }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: style_binding_sanitizer.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + myUrl1: string; + myUrl2: string; + myBoxX: string; + myBoxY: string; + myBoxWidth: string; + myRepeat: string; + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} + +/**************************************************************************************************** + * PARTIAL FILE: style_binding_important.js + ****************************************************************************************************/ +import { Component } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { + constructor() { + this.one = ''; + this.two = ''; + } +} +MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); }; +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "ng-component", ngImport: i0, template: { source: ` +
+ `, isInline: true } }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{ + type: Component, + args: [{ + template: ` +
+ ` + }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: style_binding_important.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + one: string; + two: string; + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} + diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/TEST_CASES.json b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/TEST_CASES.json new file mode 100644 index 0000000000..1aa4d5320e --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/TEST_CASES.json @@ -0,0 +1,75 @@ +{ + "$schema": "../../test_case_schema.json", + "cases": [ + { + "description": "should generate the proper update instructions for interpolated classes", + "inputFiles": [ + "class_interpolations.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect handling of interpolated classes", + "files": [ + "class_interpolations.js" + ] + } + ] + }, + { + "description": "should generate the proper update instructions for interpolated style properties", + "inputFiles": [ + "style_properties.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect handling of interpolated style properties", + "files": [ + "style_properties.js" + ] + } + ] + }, + { + "description": "should generate update instructions for interpolated style properties with a suffix", + "inputFiles": [ + "style_binding_suffixed.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect handling of interpolated style properties", + "files": [ + "style_binding_suffixed.js" + ] + } + ] + }, + { + "description": "should generate update instructions for interpolated style properties with a sanitizer", + "inputFiles": [ + "style_binding_sanitizer.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect handling of interpolated style properties", + "files": [ + "style_binding_sanitizer.js" + ] + } + ] + }, + { + "description": "should generate update instructions for interpolated style properties with !important", + "inputFiles": [ + "style_binding_important.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect handling of interpolated style properties", + "files": [ + "style_binding_important.js" + ] + } + ] + } + ] +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/class_interpolations.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/class_interpolations.js new file mode 100644 index 0000000000..e22a64509a --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/class_interpolations.js @@ -0,0 +1,23 @@ +// ... + if (rf & 2) { + $r3$.ɵɵclassMapInterpolateV(["a", ctx.one, "b", ctx.two, "c", ctx.three, "d", ctx.four, "e", ctx.five, "f", ctx.six, "g", ctx.seven, "h", ctx.eight, "i", ctx.nine, "j"]); + $r3$.ɵɵadvance(1); + $r3$.ɵɵclassMapInterpolate8("a", ctx.one, "b", ctx.two, "c", ctx.three, "d", ctx.four, "e", ctx.five, "f", ctx.six, "g", ctx.seven, "h", ctx.eight, "i"); + $r3$.ɵɵadvance(1); + $r3$.ɵɵclassMapInterpolate7("a", ctx.one, "b", ctx.two, "c", ctx.three, "d", ctx.four, "e", ctx.five, "f", ctx.six, "g", ctx.seven, "h"); + $r3$.ɵɵadvance(1); + $r3$.ɵɵclassMapInterpolate6("a", ctx.one, "b", ctx.two, "c", ctx.three, "d", ctx.four, "e", ctx.five, "f", ctx.six, "g"); + $r3$.ɵɵadvance(1); + $r3$.ɵɵclassMapInterpolate5("a", ctx.one, "b", ctx.two, "c", ctx.three, "d", ctx.four, "e", ctx.five, "f"); + $r3$.ɵɵadvance(1); + $r3$.ɵɵclassMapInterpolate4("a", ctx.one, "b", ctx.two, "c", ctx.three, "d", ctx.four, "e"); + $r3$.ɵɵadvance(1); + $r3$.ɵɵclassMapInterpolate3("a", ctx.one, "b", ctx.two, "c", ctx.three, "d"); + $r3$.ɵɵadvance(1); + $r3$.ɵɵclassMapInterpolate2("a", ctx.one, "b", ctx.two, "c"); + $r3$.ɵɵadvance(1); + $r3$.ɵɵclassMapInterpolate1("a", ctx.one, "b"); + $r3$.ɵɵadvance(1); + $r3$.ɵɵclassMap(ctx.one); +} +// ... diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/class_interpolations.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/class_interpolations.ts new file mode 100644 index 0000000000..141e1113f4 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/class_interpolations.ts @@ -0,0 +1,27 @@ +import {Component} from '@angular/core'; + +@Component({ + template: ` +
+
+
+
+
+
+
+
+
+
+ ` +}) +export class MyComponent { + one = ''; + two = ''; + three = ''; + four = ''; + five = ''; + six = ''; + seven = ''; + eight = ''; + nine = ''; +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/style_binding_important.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/style_binding_important.js new file mode 100644 index 0000000000..d748dcfaba --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/style_binding_important.js @@ -0,0 +1,5 @@ +// ... +if (rf & 2) { + $r3$.ɵɵstylePropInterpolate2("width", "a", ctx.one, "b", ctx.two, "c"); +} +// ... diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/style_binding_important.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/style_binding_important.ts new file mode 100644 index 0000000000..ac0c293508 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/style_binding_important.ts @@ -0,0 +1,11 @@ +import {Component} from '@angular/core'; + +@Component({ + template: ` +
+ ` +}) +export class MyComponent { + one = ''; + two = ''; +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/style_binding_sanitizer.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/style_binding_sanitizer.js new file mode 100644 index 0000000000..1202601777 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/style_binding_sanitizer.js @@ -0,0 +1,7 @@ +// ... +if (rf & 2) { + $r3$.ɵɵstylePropInterpolate1("background", "url(", ctx.myUrl1, ")"); + $r3$.ɵɵstylePropInterpolate2("border-image", "url(", ctx.myUrl2, ") ", ctx.myRepeat, " auto"); + $r3$.ɵɵstylePropInterpolate3("box-shadow", "", ctx.myBoxX, " ", ctx.myBoxY, " ", ctx.myBoxWidth, " black"); +} +// ... diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/style_binding_sanitizer.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/style_binding_sanitizer.ts new file mode 100644 index 0000000000..d0354fd51c --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/style_binding_sanitizer.ts @@ -0,0 +1,17 @@ +import {Component} from '@angular/core'; + +@Component({ + template: ` +
+ ` +}) +export class MyComponent { + myUrl1 = '...'; + myUrl2 = '...'; + myBoxX = '0px'; + myBoxY = '0px'; + myBoxWidth = '100px'; + myRepeat = 'no-repeat'; +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/style_binding_suffixed.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/style_binding_suffixed.js new file mode 100644 index 0000000000..fbb1d7413b --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/style_binding_suffixed.js @@ -0,0 +1,5 @@ +// ... +if (rf & 2) { + $r3$.ɵɵstylePropInterpolate2("width", "a", ctx.one, "b", ctx.two, "c", "px"); +} +// ... diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/style_binding_suffixed.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/style_binding_suffixed.ts new file mode 100644 index 0000000000..e27e079c51 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/style_binding_suffixed.ts @@ -0,0 +1,11 @@ +import {Component} from '@angular/core'; + +@Component({ + template: ` +
+ ` +}) +export class MyComponent { + one = ''; + two = ''; +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/style_properties.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/style_properties.js new file mode 100644 index 0000000000..8000411f3d --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/style_properties.js @@ -0,0 +1,23 @@ +// ... + if (rf & 2) { + $r3$.ɵɵstylePropInterpolateV("color", ["a", ctx.one, "b", ctx.two, "c", ctx.three, "d", ctx.four, "e", ctx.five, "f", ctx.six, "g", ctx.seven, "h", ctx.eight, "i", ctx.nine, "j"]); + $r3$.ɵɵadvance(1); + $r3$.ɵɵstylePropInterpolate8("color", "a", ctx.one, "b", ctx.two, "c", ctx.three, "d", ctx.four, "e", ctx.five, "f", ctx.six, "g", ctx.seven, "h", ctx.eight, "i"); + $r3$.ɵɵadvance(1); + $r3$.ɵɵstylePropInterpolate7("color", "a", ctx.one, "b", ctx.two, "c", ctx.three, "d", ctx.four, "e", ctx.five, "f", ctx.six, "g", ctx.seven, "h"); + $r3$.ɵɵadvance(1); + $r3$.ɵɵstylePropInterpolate6("color", "a", ctx.one, "b", ctx.two, "c", ctx.three, "d", ctx.four, "e", ctx.five, "f", ctx.six, "g"); + $r3$.ɵɵadvance(1); + $r3$.ɵɵstylePropInterpolate5("color", "a", ctx.one, "b", ctx.two, "c", ctx.three, "d", ctx.four, "e", ctx.five, "f"); + $r3$.ɵɵadvance(1); + $r3$.ɵɵstylePropInterpolate4("color", "a", ctx.one, "b", ctx.two, "c", ctx.three, "d", ctx.four, "e"); + $r3$.ɵɵadvance(1); + $r3$.ɵɵstylePropInterpolate3("color", "a", ctx.one, "b", ctx.two, "c", ctx.three, "d"); + $r3$.ɵɵadvance(1); + $r3$.ɵɵstylePropInterpolate2("color", "a", ctx.one, "b", ctx.two, "c"); + $r3$.ɵɵadvance(1); + $r3$.ɵɵstylePropInterpolate1("color", "a", ctx.one, "b"); + $r3$.ɵɵadvance(1); + $r3$.ɵɵstyleProp("color", ctx.one); +} +// ... diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/style_properties.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/style_properties.ts new file mode 100644 index 0000000000..81727d993a --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/interpolations/style_properties.ts @@ -0,0 +1,27 @@ +import {Component} from '@angular/core'; + +@Component({ + template: ` +
+
+
+
+
+
+
+
+
+
+ ` +}) +export class MyComponent { + one = ''; + two = ''; + three = ''; + four = ''; + five = ''; + six = ''; + seven = ''; + eight = ''; + nine = ''; +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/invalid/GOLDEN_PARTIAL.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/invalid/GOLDEN_PARTIAL.js new file mode 100644 index 0000000000..7d2a6f1064 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/invalid/GOLDEN_PARTIAL.js @@ -0,0 +1,27 @@ +/**************************************************************************************************** + * PARTIAL FILE: individual_class_binding.js + ****************************************************************************************************/ +import { Component } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { + constructor() { + this.isEnabled = true; + } +} +MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); }; +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "ng-component", ngImport: i0, template: { source: '
', isInline: true } }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{ + type: Component, + args: [{ template: '
' }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: individual_class_binding.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + isEnabled: boolean; + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} + diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/invalid/TEST_CASES.json b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/invalid/TEST_CASES.json new file mode 100644 index 0000000000..da0acdeaae --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/invalid/TEST_CASES.json @@ -0,0 +1,21 @@ +{ + "$schema": "../../test_case_schema.json", + "cases": [ + { + "description": "should throw for interpolations inside individual class bindings", + "inputFiles": [ + "individual_class_binding.ts" + ], + "expectations": [ + { + "expectedErrors": [ + { + "message": "Unexpected interpolation" + } + ] + } + ], + "excludeFromPartialTests": true + } + ] +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/invalid/individual_class_binding.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/invalid/individual_class_binding.ts new file mode 100644 index 0000000000..540d3e0045 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/invalid/individual_class_binding.ts @@ -0,0 +1,6 @@ +import {Component} from '@angular/core'; + +@Component({template: '
'}) +export class MyComponent { + isEnabled = true; +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/mixed_style_and_class/GOLDEN_PARTIAL.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/mixed_style_and_class/GOLDEN_PARTIAL.js new file mode 100644 index 0000000000..149ff7eccb --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/mixed_style_and_class/GOLDEN_PARTIAL.js @@ -0,0 +1,223 @@ +/**************************************************************************************************** + * PARTIAL FILE: mixed.js + ****************************************************************************************************/ +import { Component, NgModule } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { + constructor() { + this.myStyleExp = [{ color: 'red' }, { color: 'blue', duration: 1000 }]; + this.myClassExp = 'foo bar apple'; + } +} +MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); }; +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "my-component", ngImport: i0, template: { source: `
`, isInline: true } }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{ + type: Component, + args: [{ selector: 'my-component', template: `
` }] + }], null, null); })(); +export class MyModule { +} +MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule }); +MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } }); +(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyComponent] }); })(); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{ + type: NgModule, + args: [{ declarations: [MyComponent] }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: mixed.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + myStyleExp: ({ + color: string; + duration?: undefined; + } | { + color: string; + duration: number; + })[]; + myClassExp: string; + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} +export declare class MyModule { + static ɵmod: i0.ɵɵNgModuleDefWithMeta; + static ɵinj: i0.ɵɵInjectorDef; +} + +/**************************************************************************************************** + * PARTIAL FILE: pipe_bindings.js + ****************************************************************************************************/ +import { Component, NgModule } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { + constructor() { + this.myStyleExp = [{ color: 'red' }, { color: 'blue', duration: 1000 }]; + this.myClassExp = 'foo bar apple'; + } +} +MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); }; +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "my-component", ngImport: i0, template: { source: `
`, isInline: true } }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{ + type: Component, + args: [{ + selector: 'my-component', + template: `
` + }] + }], null, null); })(); +export class MyModule { +} +MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule }); +MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } }); +(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyComponent] }); })(); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{ + type: NgModule, + args: [{ declarations: [MyComponent] }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: pipe_bindings.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + myStyleExp: ({ + color: string; + duration?: undefined; + } | { + color: string; + duration: number; + })[]; + myClassExp: string; + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} +export declare class MyModule { + static ɵmod: i0.ɵɵNgModuleDefWithMeta; + static ɵinj: i0.ɵɵInjectorDef; +} + +/**************************************************************************************************** + * PARTIAL FILE: pipe_bindings_slots.js + ****************************************************************************************************/ +import { Component, NgModule } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { + constructor() { + this.myStyleExp = {}; + this.fooExp = 'foo'; + this.barExp = 'bar'; + this.bazExp = 'baz'; + this.items = [1, 2, 3]; + this.item = 1; + } +} +MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); }; +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "my-component", ngImport: i0, template: { source: ` +
+ {{ item }}
`, isInline: true } }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{ + type: Component, + args: [{ + selector: 'my-component', + template: ` +
+ {{ item }}
` + }] + }], null, null); })(); +export class MyModule { +} +MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule }); +MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } }); +(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyComponent] }); })(); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{ + type: NgModule, + args: [{ declarations: [MyComponent] }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: pipe_bindings_slots.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + myStyleExp: {}; + fooExp: string; + barExp: string; + bazExp: string; + items: number[]; + item: number; + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} +export declare class MyModule { + static ɵmod: i0.ɵɵNgModuleDefWithMeta; + static ɵinj: i0.ɵɵInjectorDef; +} + +/**************************************************************************************************** + * PARTIAL FILE: multiple_elements.js + ****************************************************************************************************/ +import { Component, NgModule } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { + constructor() { + this.w1 = '100px'; + this.h1 = '100px'; + this.a1 = true; + this.r1 = true; + } +} +MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); }; +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "my-component", ngImport: i0, template: { source: ` +
+
+
+
+ `, isInline: true } }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{ + type: Component, + args: [{ + selector: 'my-component', + template: ` +
+
+
+
+ ` + }] + }], null, null); })(); +export class MyModule { +} +MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule }); +MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } }); +(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyComponent] }); })(); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{ + type: NgModule, + args: [{ declarations: [MyComponent] }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: multiple_elements.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + w1: string; + h1: string; + a1: boolean; + r1: boolean; + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} +export declare class MyModule { + static ɵmod: i0.ɵɵNgModuleDefWithMeta; + static ɵinj: i0.ɵɵInjectorDef; +} + diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/mixed_style_and_class/TEST_CASES.json b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/mixed_style_and_class/TEST_CASES.json new file mode 100644 index 0000000000..7e7e03f718 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/mixed_style_and_class/TEST_CASES.json @@ -0,0 +1,61 @@ +{ + "$schema": "../../test_case_schema.json", + "cases": [ + { + "description": "should split [style] and [class] bindings into a separate instructions", + "inputFiles": [ + "mixed.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect template", + "files": [ + "mixed.js" + ] + } + ] + }, + { + "description": "should stamp out pipe definitions in the creation block if used by styling bindings", + "inputFiles": [ + "pipe_bindings.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect template", + "files": [ + "pipe_bindings.js" + ] + } + ] + }, + { + "description": "should properly offset multiple style pipe references for styling bindings", + "inputFiles": [ + "pipe_bindings_slots.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect template", + "files": [ + "pipe_bindings_slots.js" + ] + } + ] + }, + { + "description": "should always generate advance() statements before any styling instructions", + "inputFiles": [ + "multiple_elements.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect template", + "files": [ + "multiple_elements.js" + ] + } + ] + } + ] +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/mixed_style_and_class/mixed.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/mixed_style_and_class/mixed.js new file mode 100644 index 0000000000..919c9e05c0 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/mixed_style_and_class/mixed.js @@ -0,0 +1,9 @@ +template: function MyComponent_Template(rf, $ctx$) { + if (rf & 1) { + $r3$.ɵɵelement(0, "div"); + } + if (rf & 2) { + $r3$.ɵɵstyleMap($ctx$.myStyleExp); + $r3$.ɵɵclassMap($ctx$.myClassExp); + } +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/mixed_style_and_class/mixed.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/mixed_style_and_class/mixed.ts new file mode 100644 index 0000000000..9c8372859d --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/mixed_style_and_class/mixed.ts @@ -0,0 +1,12 @@ +import {Component, NgModule} from '@angular/core'; + +@Component( + {selector: 'my-component', template: `
`}) +export class MyComponent { + myStyleExp = [{color: 'red'}, {color: 'blue', duration: 1000}] + myClassExp = 'foo bar apple'; +} + +@NgModule({declarations: [MyComponent]}) +export class MyModule { +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/mixed_style_and_class/multiple_elements.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/mixed_style_and_class/multiple_elements.js new file mode 100644 index 0000000000..90497f6b5b --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/mixed_style_and_class/multiple_elements.js @@ -0,0 +1,13 @@ +// ... +template: function MyComponent_Template(rf, $ctx$) { + // ... + if (rf & 2) { + $r3$.ɵɵstyleProp("width", $ctx$.w1); + $r3$.ɵɵadvance(1); + $r3$.ɵɵstyleProp("height", $ctx$.h1); + $r3$.ɵɵadvance(1); + $r3$.ɵɵclassProp("active", $ctx$.a1); + $r3$.ɵɵadvance(1); + $r3$.ɵɵclassProp("removed", $ctx$.r1); + } +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/mixed_style_and_class/multiple_elements.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/mixed_style_and_class/multiple_elements.ts new file mode 100644 index 0000000000..9fa9be406f --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/mixed_style_and_class/multiple_elements.ts @@ -0,0 +1,21 @@ +import {Component, NgModule} from '@angular/core'; + +@Component({ + selector: 'my-component', + template: ` +
+
+
+
+ ` +}) +export class MyComponent { + w1 = '100px'; + h1 = '100px'; + a1 = true; + r1 = true; +} + +@NgModule({declarations: [MyComponent]}) +export class MyModule { +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/mixed_style_and_class/pipe_bindings.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/mixed_style_and_class/pipe_bindings.js new file mode 100644 index 0000000000..8820feecad --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/mixed_style_and_class/pipe_bindings.js @@ -0,0 +1,12 @@ +template: function MyComponent_Template(rf, $ctx$) { + if (rf & 1) { + $r3$.ɵɵelementStart(0, "div"); + $r3$.ɵɵpipe(1, "stylePipe"); + $r3$.ɵɵpipe(2, "classPipe"); + $r3$.ɵɵelementEnd(); + } + if (rf & 2) { + $r3$.ɵɵstyleMap($r3$.ɵɵpipeBind1(1, 4, $ctx$.myStyleExp)); + $r3$.ɵɵclassMap($r3$.ɵɵpipeBind1(2, 6, $ctx$.myClassExp)); + } +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/mixed_style_and_class/pipe_bindings.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/mixed_style_and_class/pipe_bindings.ts new file mode 100644 index 0000000000..4694ab0481 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/mixed_style_and_class/pipe_bindings.ts @@ -0,0 +1,14 @@ +import {Component, NgModule} from '@angular/core'; + +@Component({ + selector: 'my-component', + template: `
` +}) +export class MyComponent { + myStyleExp = [{color: 'red'}, {color: 'blue', duration: 1000}] + myClassExp = 'foo bar apple'; +} + +@NgModule({declarations: [MyComponent]}) +export class MyModule { +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/mixed_style_and_class/pipe_bindings_slots.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/mixed_style_and_class/pipe_bindings_slots.js new file mode 100644 index 0000000000..43a9aba18a --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/mixed_style_and_class/pipe_bindings_slots.js @@ -0,0 +1,19 @@ +template: function MyComponent_Template(rf, $ctx$) { + if (rf & 1) { + $r3$.ɵɵelementStart(0, "div"); + $r3$.ɵɵpipe(1, "pipe"); + $r3$.ɵɵpipe(2, "pipe"); + $r3$.ɵɵpipe(3, "pipe"); + $r3$.ɵɵpipe(4, "pipe"); + $r3$.ɵɵtext(5); + $r3$.ɵɵelementEnd(); + } + if (rf & 2) { + $r3$.ɵɵstyleMap($r3$.ɵɵpipeBind2(1, 11, $ctx$.myStyleExp, 1000)); + $r3$.ɵɵclassMap($r3$.ɵɵpureFunction0(23, _c0)); + $r3$.ɵɵstyleProp("bar", $r3$.ɵɵpipeBind2(2, 14, $ctx$.barExp, 3000))("baz", $r3$.ɵɵpipeBind2(3, 17, $ctx$.bazExp, 4000)); + $r3$.ɵɵclassProp("foo", $r3$.ɵɵpipeBind2(4, 20, $ctx$.fooExp, 2000)); + $r3$.ɵɵadvance(5); + $r3$.ɵɵtextInterpolate1(" ", $ctx$.item, ""); + } +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/mixed_style_and_class/pipe_bindings_slots.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/mixed_style_and_class/pipe_bindings_slots.ts new file mode 100644 index 0000000000..fffe666492 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/mixed_style_and_class/pipe_bindings_slots.ts @@ -0,0 +1,24 @@ +import {Component, NgModule} from '@angular/core'; + +@Component({ + selector: 'my-component', + template: ` +
+ {{ item }}
` +}) +export class MyComponent { + myStyleExp = {}; + fooExp = 'foo'; + barExp = 'bar'; + bazExp = 'baz'; + items = [1, 2, 3]; + item = 1; +} + +@NgModule({declarations: [MyComponent]}) +export class MyModule { +} 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 new file mode 100644 index 0000000000..3ef4038c3e --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/GOLDEN_PARTIAL.js @@ -0,0 +1,319 @@ +/**************************************************************************************************** + * PARTIAL FILE: style_binding.js + ****************************************************************************************************/ +import { Component, NgModule } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { + constructor() { + this.myStyleExp = [{ color: 'red' }, { color: 'blue', duration: 1000 }]; + } +} +MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); }; +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "my-component", ngImport: i0, template: { source: `
`, isInline: true } }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{ + type: Component, + args: [{ selector: 'my-component', template: `
` }] + }], null, null); })(); +export class MyModule { +} +MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule }); +MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } }); +(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyComponent] }); })(); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{ + type: NgModule, + args: [{ declarations: [MyComponent] }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: style_binding.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + myStyleExp: ({ + color: string; + duration?: undefined; + } | { + color: string; + duration: number; + })[]; + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} +export declare class MyModule { + static ɵmod: i0.ɵɵNgModuleDefWithMeta; + static ɵinj: i0.ɵɵInjectorDef; +} + +/**************************************************************************************************** + * PARTIAL FILE: binding_slots.js + ****************************************************************************************************/ +import { Component, NgModule } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponentWithInterpolation { + constructor() { + this.fooId = '123'; + } +} +MyComponentWithInterpolation.ɵfac = function MyComponentWithInterpolation_Factory(t) { return new (t || MyComponentWithInterpolation)(); }; +MyComponentWithInterpolation.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponentWithInterpolation, selector: "my-component-with-interpolation", ngImport: i0, template: { source: ` +
+ `, isInline: true } }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponentWithInterpolation, [{ + type: Component, + args: [{ + selector: 'my-component-with-interpolation', + template: ` +
+ ` + }] + }], null, null); })(); +export class MyComponentWithMuchosInterpolation { + constructor() { + this.fooId = '123'; + this.fooUsername = 'superfoo'; + } +} +MyComponentWithMuchosInterpolation.ɵfac = function MyComponentWithMuchosInterpolation_Factory(t) { return new (t || MyComponentWithMuchosInterpolation)(); }; +MyComponentWithMuchosInterpolation.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponentWithMuchosInterpolation, selector: "my-component-with-muchos-interpolation", ngImport: i0, template: { source: ` +
+ `, isInline: true } }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponentWithMuchosInterpolation, [{ + type: Component, + args: [{ + selector: 'my-component-with-muchos-interpolation', + template: ` +
+ ` + }] + }], null, null); })(); +export class MyComponentWithoutInterpolation { + constructor() { + this.exp = 'bar'; + } +} +MyComponentWithoutInterpolation.ɵfac = function MyComponentWithoutInterpolation_Factory(t) { return new (t || MyComponentWithoutInterpolation)(); }; +MyComponentWithoutInterpolation.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponentWithoutInterpolation, selector: "my-component-without-interpolation", ngImport: i0, template: { source: ` +
+ `, isInline: true } }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponentWithoutInterpolation, [{ + type: Component, + args: [{ + selector: 'my-component-without-interpolation', + template: ` +
+ ` + }] + }], null, null); })(); +export class MyModule { +} +MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule }); +MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } }); +(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyComponentWithInterpolation, MyComponentWithMuchosInterpolation, MyComponentWithoutInterpolation] }); })(); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{ + type: NgModule, + args: [{ + declarations: [ + MyComponentWithInterpolation, MyComponentWithMuchosInterpolation, + MyComponentWithoutInterpolation + ] + }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: binding_slots.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponentWithInterpolation { + fooId: string; + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} +export declare class MyComponentWithMuchosInterpolation { + fooId: string; + fooUsername: string; + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} +export declare class MyComponentWithoutInterpolation { + exp: string; + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} +export declare class MyModule { + static ɵmod: i0.ɵɵNgModuleDefWithMeta; + static ɵinj: i0.ɵɵInjectorDef; +} + +/**************************************************************************************************** + * PARTIAL FILE: binding_slots_interpolations.js + ****************************************************************************************************/ +import { Component, NgModule } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { + constructor() { + this.myStyleExp = [{ color: 'red' }, { color: 'blue', duration: 1000 }]; + this.myWidth = '100px'; + this.myHeight = '100px'; + } +} +MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); }; +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "my-component", ngImport: i0, template: { source: `
`, isInline: true } }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{ + type: Component, + args: [{ + selector: 'my-component', + template: `
` + }] + }], null, null); })(); +export class MyModule { +} +MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule }); +MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } }); +(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyComponent] }); })(); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{ + type: NgModule, + args: [{ declarations: [MyComponent] }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: binding_slots_interpolations.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + myStyleExp: ({ + color: string; + duration?: undefined; + } | { + color: string; + duration: number; + })[]; + myWidth: string; + myHeight: string; + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} +export declare class MyModule { + static ɵmod: i0.ɵɵNgModuleDefWithMeta; + static ɵinj: i0.ɵɵInjectorDef; +} + +/**************************************************************************************************** + * PARTIAL FILE: style_ordering.js + ****************************************************************************************************/ +import { Component, NgModule } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { + constructor() { + this.myImage = 'url(foo.jpg)'; + } +} +MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); }; +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "my-component", ngImport: i0, template: { source: `
`, isInline: true } }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{ + type: Component, + args: [{ selector: 'my-component', template: `
` }] + }], null, null); })(); +export class MyModule { +} +MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule }); +MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } }); +(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyComponent] }); })(); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{ + type: NgModule, + args: [{ declarations: [MyComponent] }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: style_ordering.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + myImage: string; + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} +export declare class MyModule { + static ɵmod: i0.ɵɵNgModuleDefWithMeta; + static ɵinj: i0.ɵɵInjectorDef; +} + +/**************************************************************************************************** + * PARTIAL FILE: style_binding_suffixed.js + ****************************************************************************************************/ +import { Component, NgModule } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { +} +MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); }; +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "my-component", ngImport: i0, template: { source: `
`, isInline: true } }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{ + type: Component, + args: [{ selector: 'my-component', template: `
` }] + }], null, null); })(); +export class MyModule { +} +MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule }); +MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } }); +(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyComponent] }); })(); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{ + type: NgModule, + args: [{ declarations: [MyComponent] }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: style_binding_suffixed.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} +export declare class MyModule { + static ɵmod: i0.ɵɵNgModuleDefWithMeta; + static ɵinj: i0.ɵɵInjectorDef; +} + +/**************************************************************************************************** + * PARTIAL FILE: empty_style_bindings.js + ****************************************************************************************************/ +import { Component, NgModule } from '@angular/core'; +import * as i0 from "@angular/core"; +export class MyComponent { +} +MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); }; +MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "my-component", ngImport: i0, template: { source: `
`, isInline: true } }); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{ + type: Component, + args: [{ selector: 'my-component', template: `
` }] + }], null, null); })(); +export class MyModule { +} +MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule }); +MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } }); +(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyComponent] }); })(); +/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{ + type: NgModule, + args: [{ declarations: [MyComponent] }] + }], null, null); })(); + +/**************************************************************************************************** + * PARTIAL FILE: empty_style_bindings.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class MyComponent { + static ɵfac: i0.ɵɵFactoryDef; + static ɵcmp: i0.ɵɵComponentDefWithMeta; +} +export declare class MyModule { + static ɵmod: i0.ɵɵNgModuleDefWithMeta; + static ɵinj: i0.ɵɵInjectorDef; +} + 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 new file mode 100644 index 0000000000..2ae1690a2c --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/TEST_CASES.json @@ -0,0 +1,89 @@ +{ + "$schema": "../../test_case_schema.json", + "cases": [ + { + "description": "should create style instructions on the element", + "inputFiles": [ + "style_binding.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect template", + "files": [ + "style_binding.js" + ] + } + ] + }, + { + "description": "should correctly count the total slots required when style/class bindings include interpolation", + "inputFiles": [ + "binding_slots.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect template", + "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" + ], + "expectations": [ + { + "failureMessage": "Incorrect template", + "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" + ], + "expectations": [ + { + "failureMessage": "Incorrect template", + "files": [ + "style_ordering.js" + ] + } + ] + }, + { + "description": "should support [style.foo.suffix] style bindings with a suffix", + "inputFiles": [ + "style_binding_suffixed.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect template", + "files": [ + "style_binding_suffixed.js" + ] + } + ] + }, + { + "description": "should not create instructions for empty style bindings", + "inputFiles": [ + "empty_style_bindings.ts" + ], + "expectations": [ + { + "failureMessage": "Incorrect template", + "files": [ + "empty_style_bindings.js" + ] + } + ] + } + ] +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/binding_slots.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/binding_slots.js new file mode 100644 index 0000000000..60ae1681cf --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/binding_slots.js @@ -0,0 +1,33 @@ +// ... + decls: 1, + vars: 3, + template: function MyComponentWithInterpolation_Template(rf, $ctx$) { + if (rf & 1) { + $r3$.ɵɵelement(0, "div"); + } + if (rf & 2) { + $r3$.ɵɵclassMapInterpolate1("foo foo-", $ctx$.fooId, ""); + } + } +// ... + decls: 1, + vars: 4, + template: function MyComponentWithMuchosInterpolation_Template(rf, $ctx$) { + if (rf & 1) { + $r3$.ɵɵelement(0, "div"); + } + if (rf & 2) { + $r3$.ɵɵclassMapInterpolate2("foo foo-", $ctx$.fooId, "-", $ctx$.fooUsername, ""); + } + } +// ... + decls: 1, + vars: 2, + template: function MyComponentWithoutInterpolation_Template(rf, $ctx$) { + if (rf & 1) { + $r3$.ɵɵelement(0, "div"); + } + if (rf & 2) { + $r3$.ɵɵclassMap($ctx$.exp); + } + } diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/binding_slots.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/binding_slots.ts new file mode 100644 index 0000000000..cdd5e8207b --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/binding_slots.ts @@ -0,0 +1,41 @@ +import {Component, NgModule} from '@angular/core'; + +@Component({ + selector: 'my-component-with-interpolation', + template: ` +
+ ` +}) +export class MyComponentWithInterpolation { + fooId = '123'; +} + +@Component({ + selector: 'my-component-with-muchos-interpolation', + template: ` +
+ ` +}) +export class MyComponentWithMuchosInterpolation { + fooId = '123'; + fooUsername = 'superfoo'; +} + +@Component({ + selector: 'my-component-without-interpolation', + template: ` +
+ ` +}) +export class MyComponentWithoutInterpolation { + exp = 'bar'; +} + +@NgModule({ + declarations: [ + MyComponentWithInterpolation, MyComponentWithMuchosInterpolation, + MyComponentWithoutInterpolation + ] +}) +export class MyModule { +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/binding_slots_interpolations.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/binding_slots_interpolations.js new file mode 100644 index 0000000000..f0dfaa4a7a --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/binding_slots_interpolations.js @@ -0,0 +1,19 @@ +// ... +MyComponent.ɵcmp = $r3$.ɵɵdefineComponent({ + type: MyComponent, + selectors:[["my-component"]], + decls: 1, + vars: 7, + consts: [[__AttributeMarker.Styles__, "opacity", "1"]], + template: function MyComponent_Template(rf, $ctx$) { + if (rf & 1) { + $r3$.ɵɵelement(0, "div", 0); + } + if (rf & 2) { + $r3$.ɵɵstyleMap($ctx$.myStyleExp); + $r3$.ɵɵstyleProp("width", $ctx$.myWidth)("height", $ctx$.myHeight); + $r3$.ɵɵattribute("style", "border-width: 10px", $r3$.ɵɵsanitizeStyle); + } + }, + encapsulation: 2 + }); diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/binding_slots_interpolations.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/binding_slots_interpolations.ts new file mode 100644 index 0000000000..6c113534bf --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/binding_slots_interpolations.ts @@ -0,0 +1,19 @@ +import {Component, NgModule} from '@angular/core'; + +@Component({ + selector: 'my-component', + template: `
` +}) +export class MyComponent { + myStyleExp = [{color: 'red'}, {color: 'blue', duration: 1000}] + myWidth = '100px'; + myHeight = '100px'; +} + +@NgModule({declarations: [MyComponent]}) +export class MyModule { +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/empty_style_bindings.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/empty_style_bindings.js new file mode 100644 index 0000000000..caf2cef02b --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/empty_style_bindings.js @@ -0,0 +1,5 @@ +template: function MyComponent_Template(rf, $ctx$) { + if (rf & 1) { + $r3$.ɵɵelement(0, "div", 0); + } +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/empty_style_bindings.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/empty_style_bindings.ts new file mode 100644 index 0000000000..bf2ca528f0 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/empty_style_bindings.ts @@ -0,0 +1,9 @@ +import {Component, NgModule} from '@angular/core'; + +@Component({selector: 'my-component', template: `
`}) +export class MyComponent { +} + +@NgModule({declarations: [MyComponent]}) +export class MyModule { +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/style_binding.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/style_binding.js new file mode 100644 index 0000000000..7a555e99d2 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/style_binding.js @@ -0,0 +1,8 @@ +template: function MyComponent_Template(rf, $ctx$) { + if (rf & 1) { + $r3$.ɵɵelement(0, "div"); + } + if (rf & 2) { + $r3$.ɵɵstyleMap($ctx$.myStyleExp); + } +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/style_binding.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/style_binding.ts new file mode 100644 index 0000000000..bb75e85f7a --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/style_binding.ts @@ -0,0 +1,10 @@ +import {Component, NgModule} from '@angular/core'; + +@Component({selector: 'my-component', template: `
`}) +export class MyComponent { + myStyleExp = [{color: 'red'}, {color: 'blue', duration: 1000}] +} + +@NgModule({declarations: [MyComponent]}) +export class MyModule { +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/style_binding_suffixed.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/style_binding_suffixed.js new file mode 100644 index 0000000000..c3b339d3db --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/style_binding_suffixed.js @@ -0,0 +1,9 @@ + +template: function MyComponent_Template(rf, ctx) { + if (rf & 1) { + $r3$.ɵɵelement(0, "div"); + } + if (rf & 2) { + $r3$.ɵɵstyleProp("font-size", 12, "px"); + } +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/style_binding_suffixed.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/style_binding_suffixed.ts new file mode 100644 index 0000000000..5e2b12f9f0 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/style_binding_suffixed.ts @@ -0,0 +1,9 @@ +import {Component, NgModule} from '@angular/core'; + +@Component({selector: 'my-component', template: `
`}) +export class MyComponent { +} + +@NgModule({declarations: [MyComponent]}) +export class MyModule { +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/style_ordering.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/style_ordering.js new file mode 100644 index 0000000000..f8d969968a --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/style_ordering.js @@ -0,0 +1,15 @@ +MyComponent.ɵcmp = $r3$.ɵɵdefineComponent({ + type: MyComponent, + selectors: [["my-component"]], + decls: 1, + vars: 2, + template: function MyComponent_Template(rf, ctx) { + if (rf & 1) { + $r3$.ɵɵelement(0, "div"); + } + if (rf & 2) { + $r3$.ɵɵstyleProp("background-image", ctx.myImage); + } + }, + encapsulation: 2 +}); diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/style_ordering.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/style_ordering.ts new file mode 100644 index 0000000000..67d690cccd --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/style_bindings/style_ordering.ts @@ -0,0 +1,10 @@ +import {Component, NgModule} from '@angular/core'; + +@Component({selector: 'my-component', template: `
`}) +export class MyComponent { + myImage = 'url(foo.jpg)'; +} + +@NgModule({declarations: [MyComponent]}) +export class MyModule { +}