Naddiseo / babel-plugin-mjsx

Mithril precompilation JSX plugin for babel
BSD 3-Clause "New" or "Revised" License
29 stars 7 forks source link

camelCasing conventions in DOM nodes #9

Closed bdchauvette closed 8 years ago

bdchauvette commented 8 years ago

The current JSX convention (cf. 1 & 2) is to use camelCasing for all attributes, even ones for regular DOM nodes.

I'm probably wrong here, but I believe react takes care of converting camelCased props to normal DOM attributes (e.g. onClick -> onclick) so the babel-plugin-syntax-jsx transformer doesn't modify the casing used in props.

mithril, however, passes all non-mithril attributes directly to the DOM node, so if you camelCase DOM node attributes in your jsx-flavored mithril components, they won't be passed correctly to the DOM.

This is problematic in event handlers like onInput, where the following JSX:

<input onInput={() => console.log('foo')} />

is transformed into:

{ tag: 'input', attrs: { onInput: [Function] } }

... which doesn't actually work in the browser.

I think it would be better if this plugin transformed the above JSX into:

{ tag: 'input', attrs: { oninput: [Function] } }

This would allow us to follow current JSX conventions while still having attributes like event handlers be passed directly to the DOM nodes via mithril.

tl;dr: Perhaps attribute names in regular DOM nodes should be converted from the camelCase expected by JSX to the casing expected by the DOM?

Naddiseo commented 8 years ago

I'm conflicted about this. I see the value in it, and the argument is valid. My plugin is supposed to be a JSX to mithril template converter, thus you should be able to write whatever the current JSX convention is, and expect it to work. However, this argument only holds up if you know what the output is supposed to be (HTML, SVG, XML, something else...), so, in the context of HTML, converting the attributes to the correct casing makes sense, but, I'm not so sure that assumption can be made.

It's been a while since I had a look at the documentation, but if babel 6 allow you to pass options into the plugin, I could add something like this to be enabled by an option.

bdchauvette commented 8 years ago

Great point about outputting to things other than HTML. I hadn't considered those use cases!

I don't have any experience writing babel plugins, but the babel-handbook says that plugin options can be accessed through the opts property of the state object.

The no-unknown-property rule from eslint-plugin-react seems to have a good list of DOM attributes / properties that should be transformed from JSX.

ianmetcalf commented 8 years ago

Just ran into this when using this linting rule

+1 on converting camelCase to known DOM attributes via an option flag

Naddiseo commented 8 years ago

Only thing that might break is that I use native Map, so I think the change will only work on node >= 4. Let me know if you run into this problem, and I'll switch it to a plain object.

ianmetcalf commented 8 years ago

Thanks for adding this. Waiting on https://github.com/Naddiseo/babel-plugin-mjsx/issues/11 to try this out