From 57b737b3bc060c889b2081b56f5d4869d1d0fcbb Mon Sep 17 00:00:00 2001 From: Conduitry Date: Sat, 20 Jan 2018 11:42:19 -0500 Subject: [PATCH] fix handling of boolean attributes in SSR (#1109) --- .../server-side-rendering/visitors/Element.ts | 21 ++++++++++++------- .../attribute-boolean-false/_config.js | 7 +++++++ .../samples/attribute-boolean-false/main.html | 1 + .../samples/attribute-boolean-true/_config.js | 7 +++++++ .../samples/attribute-boolean-true/main.html | 1 + 5 files changed, 30 insertions(+), 7 deletions(-) create mode 100644 test/runtime/samples/attribute-boolean-false/_config.js create mode 100644 test/runtime/samples/attribute-boolean-false/main.html create mode 100644 test/runtime/samples/attribute-boolean-true/_config.js create mode 100644 test/runtime/samples/attribute-boolean-true/main.html diff --git a/src/generators/server-side-rendering/visitors/Element.ts b/src/generators/server-side-rendering/visitors/Element.ts index 5978813c0f..486f0f01a3 100644 --- a/src/generators/server-side-rendering/visitors/Element.ts +++ b/src/generators/server-side-rendering/visitors/Element.ts @@ -9,6 +9,9 @@ import { Node } from '../../../interfaces'; import stringifyAttributeValue from './shared/stringifyAttributeValue'; import { escape } from '../../../utils/stringify'; +// source: https://gist.github.com/ArjanSchouten/0b8574a6ad7f5065a5e7 +const booleanAttributes = new Set('async autocomplete autofocus autoplay border challenge checked compact contenteditable controls default defer disabled formnovalidate frameborder hidden indeterminate ismap loop multiple muted nohref noresize noshade novalidate nowrap open readonly required reversed scoped scrolling seamless selected sortable spellcheck translate'.split(' ')); + export default function visitElement( generator: SsrGenerator, block: Block, @@ -36,14 +39,18 @@ export default function visitElement( if (attribute.name === 'value' && node.name === 'textarea') { textareaContents = stringifyAttributeValue(block, attribute.value); + } else if (attribute.value === true) { + openingTag += ` ${attribute.name}`; + } else if ( + booleanAttributes.has(attribute.name) && + attribute.value.length === 1 && + attribute.value[0].type !== 'Text' + ) { + // a boolean attribute with one non-Text chunk + block.contextualise(attribute.value[0].expression); + openingTag += '${' + attribute.value[0].metadata.snippet + ' ? " ' + attribute.name + '" : "" }'; } else { - let str = ` ${attribute.name}`; - - if (attribute.value !== true) { - str += `="${stringifyAttributeValue(block, attribute.value)}"`; - } - - openingTag += str; + openingTag += ` ${attribute.name}="${stringifyAttributeValue(block, attribute.value)}"`; } }); diff --git a/test/runtime/samples/attribute-boolean-false/_config.js b/test/runtime/samples/attribute-boolean-false/_config.js new file mode 100644 index 0000000000..4c0fd0221c --- /dev/null +++ b/test/runtime/samples/attribute-boolean-false/_config.js @@ -0,0 +1,7 @@ +export default { + html: ``, + test (assert, component, target) { + const textarea = target.querySelector('textarea'); + assert.ok(textarea.readOnly === false); + }, +}; diff --git a/test/runtime/samples/attribute-boolean-false/main.html b/test/runtime/samples/attribute-boolean-false/main.html new file mode 100644 index 0000000000..29b8b87d80 --- /dev/null +++ b/test/runtime/samples/attribute-boolean-false/main.html @@ -0,0 +1 @@ + diff --git a/test/runtime/samples/attribute-boolean-true/_config.js b/test/runtime/samples/attribute-boolean-true/_config.js new file mode 100644 index 0000000000..860867b60f --- /dev/null +++ b/test/runtime/samples/attribute-boolean-true/_config.js @@ -0,0 +1,7 @@ +export default { + html: ``, + test (assert, component, target) { + const textarea = target.querySelector('textarea'); + assert.ok(textarea.readOnly); + }, +}; diff --git a/test/runtime/samples/attribute-boolean-true/main.html b/test/runtime/samples/attribute-boolean-true/main.html new file mode 100644 index 0000000000..0630681a4b --- /dev/null +++ b/test/runtime/samples/attribute-boolean-true/main.html @@ -0,0 +1 @@ +