Skip to content

Commit

Permalink
fix non-boolean attributes value
Browse files Browse the repository at this point in the history
  • Loading branch information
pveyes committed Aug 5, 2021
1 parent 80404b7 commit 3fa6941
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 13 deletions.
35 changes: 33 additions & 2 deletions src/mapAttribute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export default function mapAttribute(
}

const name = getPropName(originalTag, attributeName);
const isBooleanAttribute = BOOLEAN_ATTRIBUTES.includes(name);
if (name === 'style') {
// if there's an attribute called style, this means that the value must be exists
// even if it's an empty string
Expand All @@ -48,10 +49,10 @@ export default function mapAttribute(
const value = attrs[attr];
// Convert attribute value to boolean attribute if needed
// https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#boolean-attributes
const isBooleanAttribute =
const booleanAttrributeValue =
value === '' ||
String(value).toLowerCase() === attributeName.toLowerCase();
result[name] = isBooleanAttribute ? true : value;
result[name] = isBooleanAttribute ? booleanAttrributeValue : value;
}

return result;
Expand Down Expand Up @@ -111,3 +112,33 @@ function hypenColonToCamelCase(str: string): string {
return char.toUpperCase();
});
}

const BOOLEAN_ATTRIBUTES = [
// https://github.com/facebook/react/blob/cae635054e17a6f107a39d328649137b83f25972/packages/react-dom/src/shared/DOMProperty.js#L319
'allowFullScreen',
'async',
// Note: there is a special case that prevents it from being written to the DOM
// on the client side because the browsers are inconsistent. Instead we call focus().
'autoFocus',
'autoPlay',
'controls',
'default',
'defer',
'disabled',
'disablePictureInPicture',
'disableRemotePlayback',
'formNoValidate',
'hidden',
'loop',
'noModule',
'noValidate',
'open',
'playsInline',
'readOnly',
'required',
'reversed',
'scoped',
'seamless',
// Microdata
'itemScope',
];
6 changes: 3 additions & 3 deletions test/__snapshots__/htmr.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ exports[`attributes correctly map HTML attributes to react props 1`] = `
exports[`attributes correctly map HTML attributes to react props 2`] = `
<div
aria-describedby="info"
contentEditable={true}
contentEditable="true"
data-type="calendar"
id="test"
spellCheck="true"
Expand Down Expand Up @@ -121,8 +121,8 @@ exports[`attributes correctly map HTML attributes to react props 9`] = `

exports[`attributes correctly map HTML attributes to react props 10`] = `
<img
alt="true"
className={true}
alt="alt"
className=""
/>
`;

Expand Down
16 changes: 8 additions & 8 deletions test/htmr.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ describe('attributes', () => {
test('correctly map HTML attributes to react props', () => {
testRender('<label class="input-text" for="name"></label>');
testRender(
'<div id="test" data-type="calendar" aria-describedby="info" spellcheck="true" contenteditable></div>'
'<div id="test" data-type="calendar" aria-describedby="info" spellcheck="true" contenteditable="true"></div>'
);
testRender('<link xml:lang="en" xlink:actuate="other" />');
testRender(oneLineTrim`
Expand All @@ -74,20 +74,20 @@ describe('attributes', () => {
);
testRender('<button accesskey="s">Stress reliever</button>');
testRender('<time datetime="2018-07-07">July 7</time>');
testRender('<img alt="true" class="" />');
testRender('<img alt="alt" class="" />');
});

// https://github.com/pveyes/htmr/issues/103
test('correctly handle boolean attributes', () => {
const { container } = render(htmrBrowser('<iframe allowfullscreen />'));
expect(
container.querySelector('iframe').getAttribute('allowfullscreen')
).toEqual('');
expect(container.querySelector('iframe').allowFullscreen).toBe(true);
});

test('can pass boolean string as is', () => {
const { container } = render(htmrBrowser('<img alt="true" />'));
expect(container.querySelector('img').getAttribute('alt')).toEqual('true');
// https://github.com/pveyes/htmr/issues/137
test('pass non-boolean attributes as is', () => {
const { container } = render(htmrBrowser('<img alt="alt" class="" />'));
expect(container.querySelector('img').alt).toEqual('alt');
expect(container.querySelector('img').className).toEqual('');
});

test('correctly convert multiple style values', () => {
Expand Down

0 comments on commit 3fa6941

Please sign in to comment.