diff --git a/integration/_payload-limits.json b/integration/_payload-limits.json index 6b6bcef962..be104d8e49 100644 --- a/integration/_payload-limits.json +++ b/integration/_payload-limits.json @@ -12,7 +12,7 @@ "master": { "uncompressed": { "runtime": 1440, - "main": 13019, + "main": 13659, "polyfills": 38390 } } @@ -34,4 +34,4 @@ } } } -} +} \ No newline at end of file diff --git a/packages/core/src/render3/component.ts b/packages/core/src/render3/component.ts index a784d1ebca..566b57d76e 100644 --- a/packages/core/src/render3/component.ts +++ b/packages/core/src/render3/component.ts @@ -22,9 +22,10 @@ import {ComponentDef, ComponentType, RenderFlags} from './interfaces/definition' import {TElementNode, TNode, TNodeFlags, TNodeType} from './interfaces/node'; import {PlayerHandler} from './interfaces/player'; import {RElement, Renderer3, RendererFactory3, domRendererFactory3} from './interfaces/renderer'; -import {CONTEXT, FLAGS, HEADER_OFFSET, LView, LViewFlags, RootContext, RootContextFlags, TVIEW} from './interfaces/view'; +import {CONTEXT, FLAGS, HEADER_OFFSET, HOST, LView, LViewFlags, RENDERER, RootContext, RootContextFlags, TVIEW} from './interfaces/view'; import {applyOnCreateInstructions} from './node_util'; import {enterView, getPreviousOrParentTNode, leaveView, resetComponentState, setCurrentDirectiveDef} from './state'; +import {renderInitialClasses, renderInitialStyles} from './styling/class_and_style_bindings'; import {publishDefaultGlobalUtils} from './util/global_utils'; import {defaultScheduler, renderStringify} from './util/misc_utils'; import {getRootContext, getRootView} from './util/view_traversal_utils'; @@ -201,14 +202,20 @@ export function createRootComponent( hostFeatures && hostFeatures.forEach((feature) => feature(component, componentDef)); + const rootTNode = getPreviousOrParentTNode(); if (tView.firstTemplatePass && componentDef.hostBindings) { - const rootTNode = getPreviousOrParentTNode(); const expando = tView.expandoInstructions !; invokeHostBindingsInCreationMode( componentDef, expando, component, rootTNode, tView.firstTemplatePass); rootTNode.onElementCreationFns && applyOnCreateInstructions(rootTNode); } + if (rootTNode.stylingTemplate) { + const native = componentView[HOST] !as RElement; + renderInitialClasses(native, rootTNode.stylingTemplate, componentView[RENDERER]); + renderInitialStyles(native, rootTNode.stylingTemplate, componentView[RENDERER]); + } + return component; } diff --git a/packages/core/test/acceptance/integration_spec.ts b/packages/core/test/acceptance/integration_spec.ts index e5d05b75b3..da36e55537 100644 --- a/packages/core/test/acceptance/integration_spec.ts +++ b/packages/core/test/acceptance/integration_spec.ts @@ -97,4 +97,18 @@ describe('acceptance integration tests', () => { expect(subInstance.dirs.first).toBeAnInstanceOf(SomeDir); }); + it('should render host class and style on the root component', () => { + @Component({template: '...', host: {class: 'foo', style: 'color: red'}}) + class MyApp { + } + + TestBed.configureTestingModule({declarations: [MyApp]}); + const fixture = TestBed.createComponent(MyApp); + const element = fixture.nativeElement; + fixture.detectChanges(); + + expect(element.style['color']).toEqual('red'); + expect(element.classList.contains('foo')).toBeTruthy(); + }); + }); diff --git a/packages/core/test/bundling/hello_world/bundle.golden_symbols.json b/packages/core/test/bundling/hello_world/bundle.golden_symbols.json index 089b50c895..a1a9302bfd 100644 --- a/packages/core/test/bundling/hello_world/bundle.golden_symbols.json +++ b/packages/core/test/bundling/hello_world/bundle.golden_symbols.json @@ -98,6 +98,9 @@ { "name": "RENDERER_FACTORY" }, + { + "name": "RendererStyleFlags3" + }, { "name": "SANITIZER" }, @@ -410,6 +413,15 @@ { "name": "renderEmbeddedTemplate" }, + { + "name": "renderInitialClasses" + }, + { + "name": "renderInitialStyles" + }, + { + "name": "renderInitialStylingValues" + }, { "name": "renderStringify" }, @@ -419,6 +431,9 @@ { "name": "setBindingRoot" }, + { + "name": "setClass" + }, { "name": "setCurrentDirectiveDef" }, @@ -440,6 +455,9 @@ { "name": "setPreviousOrParentTNode" }, + { + "name": "setStyle" + }, { "name": "setTNodeAndViewData" }, diff --git a/tools/material-ci/angular_material_test_blocklist.js b/tools/material-ci/angular_material_test_blocklist.js index 03ff9d394e..386edcb4cf 100644 --- a/tools/material-ci/angular_material_test_blocklist.js +++ b/tools/material-ci/angular_material_test_blocklist.js @@ -621,46 +621,10 @@ window.testBlocklist = { "error": "TypeError: Cannot read property 'nativeElement' of null", "notes": "FW-1059: DebugNode.query should query nodes in the logical tree" }, - "MatDatepicker with MatNativeDateModule standard datepicker should open datepicker if opened input is set to true": { - "error": "Error: Expected null not to be null.", - "notes": "Unknown" - }, - "MatDatepicker with MatNativeDateModule datepicker inside mat-form-field should pass the form field theme color to the overlay": { - "error": "TypeError: Cannot read property 'classList' of null", - "notes": "Unknown" - }, - "MatDatepicker with MatNativeDateModule datepicker inside mat-form-field should prefer the datepicker color over the form field one": { - "error": "TypeError: Cannot read property 'classList' of null", - "notes": "Unknown" - }, "MatDialog should set the proper animation states": { "error": "TypeError: Cannot read property 'componentInstance' of null", "notes": "FW-1059: DebugNode.query should query nodes in the logical tree" }, - "MatDialog dialog content elements inside component dialog should close the dialog when clicking on the close button": { - "error": "Error: Expected 0 to be 1.", - "notes": "FW-1097: Static host classes and styles don't work on root component" - }, - "MatDialog dialog content elements inside component dialog should not close if [mat-dialog-close] is applied on a non-button node": { - "error": "Error: Expected 0 to be 1.", - "notes": "FW-1097: Static host classes and styles don't work on root component" - }, - "MatDialog dialog content elements inside template portal should close the dialog when clicking on the close button": { - "error": "Error: Expected 0 to be 1.", - "notes": "FW-1097: Static host classes and styles don't work on root component" - }, - "MatDialog dialog content elements inside template portal should not close if [mat-dialog-close] is applied on a non-button node": { - "error": "Error: Expected 0 to be 1.", - "notes": "FW-1097: Static host classes and styles don't work on root component" - }, - "MatDialog dialog content elements inside template portal should return the [mat-dialog-close] result when clicking the close button": { - "error": "Uncaught TypeError: Cannot read property 'close' of null thrown", - "notes": "FW-1097: Static host classes and styles don't work on root component" - }, - "MatDialog dialog content elements inside template portal should set the aria-labelledby attribute to the id of the title": { - "error": "Error: Expected null to be 'mat-dialog-title-12', 'Expected the aria-labelledby to match the title id.'.", - "notes": "FW-1097: Static host classes and styles don't work on root component" - }, "MatMenu should close the menu when using the CloseScrollStrategy": { "error": "TypeError: Cannot read property 'openMenu' of undefined", "notes": "Unknown"