summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.changeset/shy-brooms-tell.md7
-rw-r--r--packages/astro/src/runtime/server/index.ts17
2 files changed, 21 insertions, 3 deletions
diff --git a/.changeset/shy-brooms-tell.md b/.changeset/shy-brooms-tell.md
new file mode 100644
index 000000000..022423d3a
--- /dev/null
+++ b/.changeset/shy-brooms-tell.md
@@ -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`.
diff --git a/packages/astro/src/runtime/server/index.ts b/packages/astro/src/runtime/server/index.ts
index 9d9fd076a..4217330bf 100644
--- a/packages/astro/src/runtime/server/index.ts
+++ b/packages/astro/src/runtime/server/index.ts
@@ -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)}"`);