From 568140fb038726639fbee3e4408392414ed04a1d Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Mon, 25 Mar 2019 21:39:10 +0100 Subject: [PATCH] fix(ivy): include className in DebugNode.properties (#29488) Fixes the node's class bindings not being included under `DebugNode.properties.className` like in ViewEngine. This PR resolves FW-1196. PR Close #29488 --- packages/core/src/debug/debug_node.ts | 23 ++++++++++++++++- packages/core/test/debug/debug_node_spec.ts | 28 ++++++++++++++++++++- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/packages/core/src/debug/debug_node.ts b/packages/core/src/debug/debug_node.ts index 2317d315f0..5ba74e1e18 100644 --- a/packages/core/src/debug/debug_node.ts +++ b/packages/core/src/debug/debug_node.ts @@ -257,7 +257,14 @@ class DebugElement__POST_R3__ extends DebugNode__POST_R3__ implements DebugEleme const properties = collectPropertyBindings(tNode, lView, tData); const hostProperties = collectHostPropertyBindings(tNode, lView, tData); - return {...properties, ...hostProperties}; + const className = collectClassNames(this); + const output = {...properties, ...hostProperties}; + + if (className) { + output['className'] = output['className'] ? output['className'] + ` ${className}` : className; + } + + return output; } get attributes(): {[key: string]: string | null;} { @@ -481,6 +488,20 @@ function collectHostPropertyBindings( } +function collectClassNames(debugElement: DebugElement__POST_R3__): string { + const classes = debugElement.classes; + let output = ''; + + for (const className of Object.keys(classes)) { + if (classes[className]) { + output = output ? output + ` ${className}` : className; + } + } + + return output; +} + + // Need to keep the nodes in a global Map so that multiple angular apps are supported. const _nativeNodeToDebugNode = new Map(); diff --git a/packages/core/test/debug/debug_node_spec.ts b/packages/core/test/debug/debug_node_spec.ts index 24c31459af..29df30db85 100644 --- a/packages/core/test/debug/debug_node_spec.ts +++ b/packages/core/test/debug/debug_node_spec.ts @@ -7,7 +7,7 @@ */ -import {Component, Directive, EventEmitter, Injectable, Input, NO_ERRORS_SCHEMA} from '@angular/core'; +import {Component, Directive, EventEmitter, HostBinding, Injectable, Input, NO_ERRORS_SCHEMA} from '@angular/core'; import {ComponentFixture, TestBed, async} from '@angular/core/testing'; import {By} from '@angular/platform-browser/src/dom/debug/by'; import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter'; @@ -175,6 +175,12 @@ class TestApp { class TestCmpt { } +@Component({selector: 'host-class-binding', template: ''}) +class HostClassBindingCmp { + @HostBinding('class') + hostClasses = 'class-one class-two'; +} + { describe('debug element', () => { let fixture: ComponentFixture; @@ -195,6 +201,7 @@ class TestCmpt { UsingFor, BankAccount, TestCmpt, + HostClassBindingCmp, ], providers: [Logger], schemas: [NO_ERRORS_SCHEMA], @@ -408,6 +415,25 @@ class TestCmpt { }); + it('should include classes in properties.className', () => { + fixture = TestBed.createComponent(HostClassBindingCmp); + fixture.detectChanges(); + + const debugElement = fixture.debugElement; + + expect(debugElement.properties.className).toBe('class-one class-two'); + + fixture.componentInstance.hostClasses = 'class-three'; + fixture.detectChanges(); + + expect(debugElement.properties.className).toBe('class-three'); + + fixture.componentInstance.hostClasses = ''; + fixture.detectChanges(); + + expect(debugElement.properties.className).toBeFalsy(); + }); + describe('componentInstance on DebugNode', () => { it('should return component associated with a node if a node is a component host', () => {