fix: HTML/SVG boolean attributes (#2538)

* fix: HTML/SVG boolean attributes

* fix: update case-sensitivity of attributes

* Update packages/astro/src/runtime/server/index.ts

Co-authored-by: Jonathan Neal <jonathantneal@hotmail.com>

Co-authored-by: Jonathan Neal <jonathantneal@hotmail.com>
This commit is contained in:
Nate Moore 2022-02-04 17:38:14 -06:00 committed by GitHub
parent 939886ff47
commit 16d532fe17
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 21 additions and 3 deletions

View file

@ -0,0 +1,7 @@
---
'astro': patch
---
Fix rendering of HTML boolean attributes like `open` and `async`.
Fix rendering of HTML and SVG enumerated attributes like `contenteditable` and `spellcheck`.

View file

@ -11,6 +11,10 @@ export { createMetadata } from './metadata.js';
export { escapeHTML, unescapeHTML } from './escape.js';
const voidElementNames = /^(area|base|br|col|command|embed|hr|img|input|keygen|link|meta|param|source|track|wbr)$/i;
const htmlBooleanAttributes = /^(allowfullscreen|async|autofocus|autoplay|controls|default|defer|disabled|disablepictureinpicture|disableremoteplayback|formnovalidate|hidden|loop|nomodule|novalidate|open|playsinline|readonly|required|reversed|scoped|seamless|itemscope)$/i;
const htmlEnumAttributes = /^(contenteditable|draggable|spellcheck|value)$/i;
// Note: SVG is case-sensitive!
const svgEnumAttributes = /^(autoReverse|externalResourcesRequired|focusable|preserveAlpha)$/i;
// INVESTIGATE:
// 2. Less anys when possible and make it well known when they are needed.
@ -327,10 +331,17 @@ const STATIC_DIRECTIVES = new Set(['set:html', 'set:text']);
// A helper used to turn expressions into attribute key/value
export function addAttribute(value: any, key: string) {
if (value == null || value === false) {
if (value == null) {
return '';
}
if (value === false) {
if (htmlEnumAttributes.test(key) || svgEnumAttributes.test(key)) {
return unescapeHTML(` ${key}="false"`);
}
return ''
}
// compiler directives cannot be applied dynamically, log a warning and ignore.
if (STATIC_DIRECTIVES.has(key)) {
// eslint-disable-next-line no-console
@ -345,8 +356,8 @@ Make sure to use the static attribute syntax (\`${key}={value}\`) instead of the
return unescapeHTML(` ${key.slice(0, -5)}="${toAttributeString(serializeListValue(value))}"`);
}
// Boolean only needs the key
if (value === true && key.startsWith('data-')) {
// Boolean values only need the key
if (value === true && (key.startsWith('data-') || htmlBooleanAttributes.test(key))) {
return unescapeHTML(` ${key}`);
} else {
return unescapeHTML(` ${key}="${toAttributeString(value)}"`);