fix(ivy): DebugNode.properties not preserving type of values (#29914)
Fixes the `DebugNode.properties` casting all of the values to a string. This PR resolves FW-1253. PR Close #29914
This commit is contained in:
parent
ca755a6b72
commit
5d824c4153
@ -538,23 +538,26 @@ function collectPropertyBindings(
|
|||||||
let bindingIndex = getFirstBindingIndex(tNode.propertyMetadataStartIndex, tData);
|
let bindingIndex = getFirstBindingIndex(tNode.propertyMetadataStartIndex, tData);
|
||||||
|
|
||||||
while (bindingIndex < tNode.propertyMetadataEndIndex) {
|
while (bindingIndex < tNode.propertyMetadataEndIndex) {
|
||||||
let value = '';
|
let value: any;
|
||||||
let propMetadata = tData[bindingIndex] as string;
|
let propMetadata = tData[bindingIndex] as string;
|
||||||
while (!isPropMetadataString(propMetadata)) {
|
while (!isPropMetadataString(propMetadata)) {
|
||||||
// This is the first value for an interpolation. We need to build up
|
// This is the first value for an interpolation. We need to build up
|
||||||
// the full interpolation by combining runtime values in LView with
|
// the full interpolation by combining runtime values in LView with
|
||||||
// the static interstitial values stored in TData.
|
// the static interstitial values stored in TData.
|
||||||
value += renderStringify(lView[bindingIndex]) + tData[bindingIndex];
|
value = (value || '') + renderStringify(lView[bindingIndex]) + tData[bindingIndex];
|
||||||
propMetadata = tData[++bindingIndex] as string;
|
propMetadata = tData[++bindingIndex] as string;
|
||||||
}
|
}
|
||||||
value += lView[bindingIndex];
|
value = value === undefined ? lView[bindingIndex] : value += lView[bindingIndex];
|
||||||
// Property metadata string has 3 parts: property name, prefix, and suffix
|
// Property metadata string has 3 parts: property name, prefix, and suffix
|
||||||
const metadataParts = propMetadata.split(INTERPOLATION_DELIMITER);
|
const metadataParts = propMetadata.split(INTERPOLATION_DELIMITER);
|
||||||
const propertyName = metadataParts[0];
|
const propertyName = metadataParts[0];
|
||||||
// Attr bindings don't have property names and should be skipped
|
// Attr bindings don't have property names and should be skipped
|
||||||
if (propertyName) {
|
if (propertyName) {
|
||||||
// Wrap value with prefix and suffix (will be '' for normal bindings)
|
// Wrap value with prefix and suffix (will be '' for normal bindings), if they're defined.
|
||||||
properties[propertyName] = metadataParts[1] + value + metadataParts[2];
|
// Avoid wrapping for normal bindings so that the value doesn't get cast to a string.
|
||||||
|
properties[propertyName] = (metadataParts[1] && metadataParts[2]) ?
|
||||||
|
metadataParts[1] + value + metadataParts[2] :
|
||||||
|
value;
|
||||||
}
|
}
|
||||||
bindingIndex++;
|
bindingIndex++;
|
||||||
}
|
}
|
||||||
|
@ -195,6 +195,20 @@ class TestCmptWithViewContainerRef {
|
|||||||
constructor(private vcref: ViewContainerRef) {}
|
constructor(private vcref: ViewContainerRef) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
template: `
|
||||||
|
<button
|
||||||
|
[disabled]="disabled"
|
||||||
|
[tabIndex]="tabIndex"
|
||||||
|
[title]="title">Click me</button>
|
||||||
|
`
|
||||||
|
})
|
||||||
|
class TestCmptWithPropBindings {
|
||||||
|
disabled = true;
|
||||||
|
tabIndex = 1337;
|
||||||
|
title = 'hello';
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
describe('debug element', () => {
|
describe('debug element', () => {
|
||||||
let fixture: ComponentFixture<any>;
|
let fixture: ComponentFixture<any>;
|
||||||
@ -218,6 +232,7 @@ class TestCmptWithViewContainerRef {
|
|||||||
HostClassBindingCmp,
|
HostClassBindingCmp,
|
||||||
TestCmptWithViewContainerRef,
|
TestCmptWithViewContainerRef,
|
||||||
SimpleContentComp,
|
SimpleContentComp,
|
||||||
|
TestCmptWithPropBindings,
|
||||||
],
|
],
|
||||||
providers: [Logger],
|
providers: [Logger],
|
||||||
schemas: [NO_ERRORS_SCHEMA],
|
schemas: [NO_ERRORS_SCHEMA],
|
||||||
@ -566,6 +581,14 @@ class TestCmptWithViewContainerRef {
|
|||||||
expect(debugElement.properties.className).toBeFalsy();
|
expect(debugElement.properties.className).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should preserve the type of the property values', () => {
|
||||||
|
const fixture = TestBed.createComponent(TestCmptWithPropBindings);
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
const button = fixture.debugElement.query(By.css('button'));
|
||||||
|
expect(button.properties).toEqual({disabled: true, tabIndex: 1337, title: 'hello'});
|
||||||
|
});
|
||||||
|
|
||||||
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', () => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user