From 3536f41f001ea8a0ccb9114b7c2659e3627dadc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Tue, 15 Feb 2022 08:58:07 +0100 Subject: [PATCH] [FIX] blockdom: undefined properties are treated as empty strings --- src/blockdom/attributes.ts | 2 +- tests/blockdom/block_attributes.test.ts | 9 +++++++++ .../__snapshots__/t_model.test.ts.snap | 18 ++++++++++++++++++ tests/components/t_model.test.ts | 13 +++++++++++++ 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/blockdom/attributes.ts b/src/blockdom/attributes.ts index dac1ece6..b41a129b 100644 --- a/src/blockdom/attributes.ts +++ b/src/blockdom/attributes.ts @@ -139,7 +139,7 @@ export function updateClass(this: HTMLElement, val: any, oldVal: any) { export function makePropSetter(name: string): Setter { return function setProp(this: HTMLElement, value: any) { - (this as any)[name] = value; + (this as any)[name] = value || ""; }; } diff --git a/tests/blockdom/block_attributes.test.ts b/tests/blockdom/block_attributes.test.ts index 73e8417d..be053e35 100644 --- a/tests/blockdom/block_attributes.test.ts +++ b/tests/blockdom/block_attributes.test.ts @@ -169,6 +169,15 @@ describe("properties", () => { expect(input.value).toBe("potato"); }); + test("input with value attribute, and undefined given", () => { + const block = createBlock(``); + + const tree = block([undefined]); + mount(tree, fixture); + const input = fixture.querySelector("input")!; + expect(input.value).toBe(""); + }); + test("input type=checkbox with checked attribute", () => { // render input with initial value const block = createBlock(``); diff --git a/tests/components/__snapshots__/t_model.test.ts.snap b/tests/components/__snapshots__/t_model.test.ts.snap index 7ab33d0d..af4e6182 100644 --- a/tests/components/__snapshots__/t_model.test.ts.snap +++ b/tests/components/__snapshots__/t_model.test.ts.snap @@ -410,6 +410,24 @@ exports[`t-model directive on an textarea 1`] = ` }" `; +exports[`t-model directive t-model on an input with an undefined value 1`] = ` +"function anonymous(bdom, helpers +) { + let { text, createBlock, list, multi, html, toggler, component, comment } = bdom; + let { toNumber } = helpers; + + let block1 = createBlock(\`\`); + + return function template(ctx, node, key = \\"\\") { + const bExpr1 = ctx['state']; + const expr1 = 'text'; + let attr1 = bExpr1[expr1]; + let hdlr1 = [(ev) => { bExpr1[expr1] = ev.target.value; }]; + return block1([attr1, hdlr1]); + } +}" +`; + exports[`t-model directive t-model on select with static options 1`] = ` "function anonymous(bdom, helpers ) { diff --git a/tests/components/t_model.test.ts b/tests/components/t_model.test.ts index 04422a7a..a70afcd5 100644 --- a/tests/components/t_model.test.ts +++ b/tests/components/t_model.test.ts @@ -30,6 +30,19 @@ describe("t-model directive", () => { expect(fixture.innerHTML).toBe("
test
"); }); + test("t-model on an input with an undefined value", async () => { + class SomeComponent extends Component { + static template = xml``; + state = useState({ text: undefined }); + } + await mount(SomeComponent, fixture); + + expect(fixture.innerHTML).toBe(""); + + const input = fixture.querySelector("input")!; + expect(input.value).toBe(""); + }); + test("basic use, on an input with bracket expression", async () => { class SomeComponent extends Component { static template = xml`