From 02a187d80b1a44d5550b03d50df4ba6105e5ef3c Mon Sep 17 00:00:00 2001 From: Samuel Degueldre Date: Fri, 5 Aug 2022 08:56:59 +0200 Subject: [PATCH] [FIX] compiler: fix falsy values for properties not keeping input empty Recently, we made it so that when a component is rendered, it always updates the property values for computed properties. This was done by wrapping the value in a String or Boolean object. One issue with this is that wrapping a falsy value in a String doesn't yield an empty string, but a string containing the value as text (eg new String(undefined) -> "undefined"), which causes the value to not remain empty as per the spec. This commit fixes that by adding a fallback to the empty string for falsy values before converting to a String object. closes: #1236 --- src/compiler/code_generator.ts | 8 +++-- .../__snapshots__/attributes.test.ts.snap | 22 +++++++++++--- .../compiler/__snapshots__/misc.test.ts.snap | 2 +- tests/compiler/attributes.test.ts | 29 +++++++++++++++++++ 4 files changed, 54 insertions(+), 7 deletions(-) diff --git a/src/compiler/code_generator.ts b/src/compiler/code_generator.ts index d7f54ac4..1013d13f 100644 --- a/src/compiler/code_generator.ts +++ b/src/compiler/code_generator.ts @@ -584,8 +584,12 @@ export class CodeGenerator { expr = compileExpr(ast.attrs[key]); if (attrName && isProp(ast.tag, attrName)) { // we force a new string or new boolean to bypass the equality check in blockdom when patching same value - const C = attrName === "value" ? "String" : "Boolean"; - expr = `new ${C}(${expr})`; + if (attrName === "value") { + // When the expression is falsy, fall back to an empty string + expr = `new String((${expr}) || "")`; + } else { + expr = `new Boolean(${expr})`; + } } const idx = block!.insertData(expr, "attr"); if (key === "t-att") { diff --git a/tests/compiler/__snapshots__/attributes.test.ts.snap b/tests/compiler/__snapshots__/attributes.test.ts.snap index 4738f181..c536cefd 100644 --- a/tests/compiler/__snapshots__/attributes.test.ts.snap +++ b/tests/compiler/__snapshots__/attributes.test.ts.snap @@ -708,6 +708,20 @@ exports[`attributes updating classes (with obj notation) 1`] = ` }" `; +exports[`attributes updating property with falsy value 1`] = ` +"function anonymous(app, bdom, helpers +) { + let { text, createBlock, list, multi, html, toggler, comment } = bdom; + + let block1 = createBlock(\`\`); + + return function template(ctx, node, key = \\"\\") { + let attr1 = new String((ctx['v']) || \\"\\"); + return block1([attr1]); + } +}" +`; + exports[`attributes various escapes 1`] = ` "function anonymous(app, bdom, helpers ) { @@ -773,7 +787,7 @@ exports[`special cases for some specific html attributes/properties input with t let block1 = createBlock(\`\`); return function template(ctx, node, key = \\"\\") { - let attr1 = new String(ctx['v']); + let attr1 = new String((ctx['v']) || \\"\\"); return block1([attr1]); } }" @@ -787,7 +801,7 @@ exports[`special cases for some specific html attributes/properties input with t let block1 = createBlock(\`\`); return function template(ctx, node, key = \\"\\") { - let attr1 = new String(ctx['v']); + let attr1 = new String((ctx['v']) || \\"\\"); return block1([attr1]); } }" @@ -815,7 +829,7 @@ exports[`special cases for some specific html attributes/properties select with let block1 = createBlock(\`\`); return function template(ctx, node, key = \\"\\") { - let attr1 = new String(ctx['value']); + let attr1 = new String((ctx['value']) || \\"\\"); return block1([attr1]); } }" @@ -829,7 +843,7 @@ exports[`special cases for some specific html attributes/properties textarea wit let block1 = createBlock(\`