mirror of
https://github.com/withastro/astro.git
synced 2024-12-30 22:03:56 -05:00
fix(markdoc): correctly render boolean HTML attributes (#12584)
This commit is contained in:
parent
15f000c3e7
commit
fa07002352
4 changed files with 53 additions and 0 deletions
5
.changeset/twenty-lobsters-think.md
Normal file
5
.changeset/twenty-lobsters-think.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'@astrojs/markdoc': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Correctly renders boolean HTML attributes
|
|
@ -1,6 +1,37 @@
|
||||||
import type { Config, Schema } from '@markdoc/markdoc';
|
import type { Config, Schema } from '@markdoc/markdoc';
|
||||||
import Markdoc 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
|
// local
|
||||||
import { parseInlineCSSToReactLikeObject } from '../css/parse-inline-css-to-react.js';
|
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
|
// pull out any "unsafe" attributes which need additional processing
|
||||||
const { style, ...safeAttributes } = unsafeAttributes as Record<string, unknown>;
|
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 the inline "style" attribute is present we need to parse the HTML into a react-like React.CSSProperties object
|
||||||
if (typeof style === 'string') {
|
if (typeof style === 'string') {
|
||||||
const styleObject = parseInlineCSSToReactLikeObject(style);
|
const styleObject = parseInlineCSSToReactLikeObject(style);
|
||||||
|
|
|
@ -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 paragraph!</p>
|
||||||
|
|
||||||
<p>This is a <span class="inside-p">span</span> inside 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>
|
|
@ -123,6 +123,11 @@ function renderSimpleChecks(html) {
|
||||||
const p3 = document.querySelector('article > p:nth-of-type(3)');
|
const p3 = document.querySelector('article > p:nth-of-type(3)');
|
||||||
assert.equal(p3.children.length, 1);
|
assert.equal(p3.children.length, 1);
|
||||||
assert.equal(p3.textContent, 'This is a span inside a paragraph!');
|
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 */
|
/** @param {string} html */
|
||||||
|
|
Loading…
Reference in a new issue