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
This commit is contained in:
Kristiyan Kostadinov 2019-03-25 21:39:10 +01:00 committed by Miško Hevery
parent 7951c4feb2
commit 568140fb03
2 changed files with 49 additions and 2 deletions

View File

@ -257,7 +257,14 @@ class DebugElement__POST_R3__ extends DebugNode__POST_R3__ implements DebugEleme
const properties = collectPropertyBindings(tNode, lView, tData); const properties = collectPropertyBindings(tNode, lView, tData);
const hostProperties = collectHostPropertyBindings(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;} { 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. // Need to keep the nodes in a global Map so that multiple angular apps are supported.
const _nativeNodeToDebugNode = new Map<any, DebugNode>(); const _nativeNodeToDebugNode = new Map<any, DebugNode>();

View File

@ -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 {ComponentFixture, TestBed, async} from '@angular/core/testing';
import {By} from '@angular/platform-browser/src/dom/debug/by'; import {By} from '@angular/platform-browser/src/dom/debug/by';
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter'; import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
@ -175,6 +175,12 @@ class TestApp {
class TestCmpt { class TestCmpt {
} }
@Component({selector: 'host-class-binding', template: ''})
class HostClassBindingCmp {
@HostBinding('class')
hostClasses = 'class-one class-two';
}
{ {
describe('debug element', () => { describe('debug element', () => {
let fixture: ComponentFixture<any>; let fixture: ComponentFixture<any>;
@ -195,6 +201,7 @@ class TestCmpt {
UsingFor, UsingFor,
BankAccount, BankAccount,
TestCmpt, TestCmpt,
HostClassBindingCmp,
], ],
providers: [Logger], providers: [Logger],
schemas: [NO_ERRORS_SCHEMA], 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', () => { describe('componentInstance on DebugNode', () => {
it('should return component associated with a node if a node is a component host', () => { it('should return component associated with a node if a node is a component host', () => {