aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Matt Kane <m@mk.gg> 2024-12-02 14:37:00 +0000
committerGravatar GitHub <noreply@github.com> 2024-12-02 14:37:00 +0000
commitfa07002352147d45da193f28fd6e02d2d42dc67a (patch)
tree66492ef4ace0908eecbce5e2f85283acca055cb8
parent15f000c3e7bc5308c39107095e5af4258c2373a5 (diff)
downloadastro-fa07002352147d45da193f28fd6e02d2d42dc67a.tar.gz
astro-fa07002352147d45da193f28fd6e02d2d42dc67a.tar.zst
astro-fa07002352147d45da193f28fd6e02d2d42dc67a.zip
fix(markdoc): correctly render boolean HTML attributes (#12584)
-rw-r--r--.changeset/twenty-lobsters-think.md5
-rw-r--r--packages/integrations/markdoc/src/html/tagdefs/html.tag.ts39
-rw-r--r--packages/integrations/markdoc/test/fixtures/render-html/src/content/blog/simple.mdoc4
-rw-r--r--packages/integrations/markdoc/test/render-html.test.js5
4 files changed, 53 insertions, 0 deletions
diff --git a/.changeset/twenty-lobsters-think.md b/.changeset/twenty-lobsters-think.md
new file mode 100644
index 000000000..de52155c1
--- /dev/null
+++ b/.changeset/twenty-lobsters-think.md
@@ -0,0 +1,5 @@
+---
+'@astrojs/markdoc': patch
+---
+
+Correctly renders boolean HTML attributes
diff --git a/packages/integrations/markdoc/src/html/tagdefs/html.tag.ts b/packages/integrations/markdoc/src/html/tagdefs/html.tag.ts
index 92d086d1a..0c094227d 100644
--- a/packages/integrations/markdoc/src/html/tagdefs/html.tag.ts
+++ b/packages/integrations/markdoc/src/html/tagdefs/html.tag.ts
@@ -1,6 +1,37 @@
import type { Config, Schema } from '@markdoc/markdoc';
import Markdoc from '@markdoc/markdoc';
+const booleanAttributes = new Set([
+ 'allowfullscreen',
+ 'async',
+ 'autofocus',
+ 'autoplay',
+ 'checked',
+ 'controls',
+ 'default',
+ 'defer',
+ 'disabled',
+ 'disablepictureinpicture',
+ 'disableremoteplayback',
+ 'download',
+ 'formnovalidate',
+ 'hidden',
+ 'inert',
+ 'ismap',
+ 'itemscope',
+ 'loop',
+ 'multiple',
+ 'muted',
+ 'nomodule',
+ 'novalidate',
+ 'open',
+ 'playsinline',
+ 'readonly',
+ 'required',
+ 'reversed',
+ 'selected',
+]);
+
// local
import { parseInlineCSSToReactLikeObject } from '../css/parse-inline-css-to-react.js';
@@ -18,6 +49,14 @@ export const htmlTag: Schema<Config, never> = {
// pull out any "unsafe" attributes which need additional processing
const { style, ...safeAttributes } = unsafeAttributes as Record<string, unknown>;
+ // Convert boolean attributes to boolean literals
+ for (const [key, value] of Object.entries(safeAttributes)) {
+ if (booleanAttributes.has(key)) {
+ // If the attribute exists, ensure its value is a boolean
+ safeAttributes[key] = value === '' || value === true || value === 'true';
+ }
+ }
+
// if the inline "style" attribute is present we need to parse the HTML into a react-like React.CSSProperties object
if (typeof style === 'string') {
const styleObject = parseInlineCSSToReactLikeObject(style);
diff --git a/packages/integrations/markdoc/test/fixtures/render-html/src/content/blog/simple.mdoc b/packages/integrations/markdoc/test/fixtures/render-html/src/content/blog/simple.mdoc
index eaea6646a..30b9b7f8f 100644
--- a/packages/integrations/markdoc/test/fixtures/render-html/src/content/blog/simple.mdoc
+++ b/packages/integrations/markdoc/test/fixtures/render-html/src/content/blog/simple.mdoc
@@ -9,3 +9,7 @@ This is a simple Markdoc <span class="post-class" style="color: hotpink;">post</
<p>This is a paragraph!</p>
<p>This is a <span class="inside-p">span</span> inside a paragraph!</p>
+
+<video
+ src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExejZnbmN6ODlxOWk2djVmcnFkMjIwbmFnZGFtZ2J4aG52dzVvbjJlaCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/H1vJZzQAiILUUq0FUL/giphy.mp4"
+ autoplay muted></video> \ No newline at end of file
diff --git a/packages/integrations/markdoc/test/render-html.test.js b/packages/integrations/markdoc/test/render-html.test.js
index 6f877d1e5..5bf7fe5ce 100644
--- a/packages/integrations/markdoc/test/render-html.test.js
+++ b/packages/integrations/markdoc/test/render-html.test.js
@@ -123,6 +123,11 @@ function renderSimpleChecks(html) {
const p3 = document.querySelector('article > p:nth-of-type(3)');
assert.equal(p3.children.length, 1);
assert.equal(p3.textContent, 'This is a span inside a paragraph!');
+
+ const video = document.querySelector('video');
+ assert.ok(video, 'A video element should exist');
+ assert.ok(video.hasAttribute('autoplay'), 'The video element should have the autoplay attribute');
+ assert.ok(video.hasAttribute('muted'), 'The video element should have the muted attribute');
}
/** @param {string} html */