Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transform attribute names to proper casing #199

Closed
wants to merge 10 commits into from

Conversation

gpoitch
Copy link
Contributor

@gpoitch gpoitch commented Jul 30, 2021

Makes sure attributes are converted to their proper casing when rendering to string. There was a similar attempt with #55 but it was never completed. Reviving it particularly because Safari is excessively downloading an img's src upon hydration due to srcSet casing mismatch between preact/preact-render-to-string. This also adds better support for attributes specific to SVG/RSS/XML.

Incorporated the concerns from the comments in the other attempts/issues.

Attribute list reference: https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes
React reference: https://github.com/facebook/react/blob/main/packages/react-dom/src/shared/possibleStandardNames.js

Closes #55
Closes #18

@gpoitch gpoitch closed this Aug 2, 2021
@marvinhagemeister
Copy link
Member

@gpoitch I think it's definitely something we should address. Regarding the closing: Did you ran into problems with this PR? I'm mainly curious to see if there is a way without changing the casing in the JSX renderer, but lowercase it in the default mode.

@gpoitch gpoitch reopened this Aug 2, 2021
@gpoitch
Copy link
Contributor Author

gpoitch commented Aug 2, 2021

@marvinhagemeister accidental auto-close referencing this PR in a private repo. Not familiar with default vs jsx mode - I'll have to read the source code more and circle back.

@gpoitch
Copy link
Contributor Author

gpoitch commented Aug 2, 2021

@marvinhagemeister I updated it so the jsx renderer is unaffected by applying the normalization after the attribute hook intercepts the standard rendering.

@gpoitch gpoitch changed the title Decamelize html attributes Transform attribute names to proper html casing Sep 29, 2021
@gpoitch gpoitch changed the title Transform attribute names to proper html casing Transform attribute names to proper casing Oct 22, 2021
src/index.js Outdated Show resolved Hide resolved
src/index.js Outdated Show resolved Hide resolved
src/index.js Outdated Show resolved Hide resolved
src/index.js Outdated
@@ -281,6 +287,8 @@ function _renderToString(vnode, context, opts, inner, isSvgMode, selectValue) {
// <textarea value="a&b"> --> <textarea>a&amp;b</textarea>
propChildren = v;
} else if ((v || v === 0 || v === '') && typeof v !== 'function') {
name = getAttributeNameInHtmlCase(name);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Likely faster if this is done on L310:

-				s += ` ${name}="${encodeEntities(v)}"`;
+				s += ` ${getAttributeNameInHtmlCase(name)}="${encodeEntities(v)}"`;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need the transformed name for the if (v === true || v === '') block

@changeset-bot
Copy link

changeset-bot bot commented Nov 12, 2021

🦋 Changeset detected

Latest commit: 61cd8c2

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
preact-render-to-string Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

src/index.js Outdated
Comment on lines 20 to 26
const DASHED_ATTRS = /^(acceptC|httpE|(clip|color|fill|font|glyph|marker|stop|stroke|text|vert)[A-Z])/;
const CAMEL_ATTRS = /^(isP|viewB)/;
const COLON_ATTRS = /^(xlink|xml|xmlns)([A-Z])/;

const CAPITAL_REGEXP = /([A-Z])/g;

const UNSAFE_NAME = /[\s\n\\/='"\0<>]/;
Copy link

@SukkaW SukkaW Dec 12, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can they cover all the attributes? react-dom has an entire file for possibleStandardNames:

https://github.com/facebook/react/blob/ca106a02d1648f4f0048b07c6b88f69aac175d3c/packages/react-dom/src/shared/possibleStandardNames.js

If they can, at least add a unit test case to cover them all. cc @gpoitch

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

srcSet not converted to srcset
5 participants