wooorm / property-information

Info on the properties and attributes of the web platform
MIT License
38 stars 11 forks source link

Property names for event properties are incorrectly cased #18

Closed martypdx closed 11 months ago

martypdx commented 11 months ago

Issue: Library is using wrong values for Dom property event handlers.

Dom properties for property event handlers should be all lower case like:

node.onmouseenter = () => {};

Not like the example below which is currently what is returned for property name, as camel cased property names will fail silently and not work on web platform:

// creates a new property "onMouseEnter", won't call as handler on event
node.onMouseEnter = () => {}; 

There's no mentioned in the section in hast about property name differences about this.

(I asked on quora once and got this reply from Brendan Eich. He didn't address why all lowercase though...)

wooorm commented 11 months ago

What is the issue? The question?

martypdx commented 11 months ago

@wooorm The values returned for event property names are incorrect and will not work for Dom elements. Edited issue for more clarity

martypdx commented 11 months ago

Given event properties are not frequently used, I doubt this will trip up others, but for posterity here is example work-around:

import { html, find } from 'property-information';

function findInfo(value) {
    const info = find(html, value);
    // fix for incorrect property names for events
    const { property } = info;
    if(property.startsWith('on')) {
        info.property = property.toLowerCase();
    }
    return info;
}
wooorm commented 11 months ago

Ah. You mean that, in the DOM, events do not use a “cased” form. Which is different from say, React, which uses onClick, or hast.

In this project, the property values do not match the DOM. Particularly because, in the DOM, there are inconsistencies with how “properties” are cased, and well, some things aren’t present as “properties” in the DOM. It also doesn’t match React, for similar reasons. This is mentioned in the readme:

The names of the properties follow hast’s sensible naming scheme.

JavaScript-style camel-cased name, based on the DOM, but sometimes different (for example: 'ariaDescribedBy', 'allowFullScreen', 'xmlLang', 'htmlFor', 'charOff')

In your code, I recommend taking info.attribute instead of lowercasing. Should do the same to my knowledge but might be better if not. There is also a once attribute, which isn’t affected here, but in the if-condition you could use https://github.com/rehypejs/rehype-minify/blob/main/packages/hast-util-is-event-handler.

From what you seem to be doing with your actual root question, is that you are setting properties on DOM nodes, similar to what React or other VDOMs do. The DOM is finicky. Sometimes it works, but sometimes it doesn’t. Other than casing, you need another registry to know whether it would work or whether it has to be set as an attribute.

I would recommend using https://github.com/syntax-tree/hast-util-to-dom instead.

martypdx commented 11 months ago

Sorry for not starting with an explanation of what I am trying accomplish. I am building an ahead-of-time compiler and going from parsing template html to generating code for dom manipulation, but not dom itself.

Yes DOM can be finicky. I looked at the hast-to-dom code and I see using setAttribute to avoid the issue (outside of the form control attributes that have to be set via prop). Not sure that's the route I want to go.

Was looking for common place to put this info, do you know of any similar projects?

wooorm commented 10 months ago

Ahh, interesting!! Well, React used to have that info internally I think. It’s been ages though. They used to have a MUST_USE_PROPERTY flag. Searching that on GitHub finds for example https://github.com/TheWaWaR/react-neon-ssr/blob/0fb7191b5739bbd08bb449005a994190acf82558/native/src/util/html_dom_property_config.rs#L20. But the main problem is that not all attributes exist as properties. And that setting attributes and properties is different: the DOM is a JavaScript interface where setting particular things has particular effects.

Can you share more about what kinda input you have and what kinda output you want to turn it into?

martypdx commented 10 months ago

My use cases are to use the information to correctly code-generate the property, and to support linting/intellisense (more than just dom props, attributes, elements, etc.)

I had a thought last week that the information you already have could be run through a browser script/test to validate dom properties (the dom objects will return null vs undefined).

If it were purely additive, would you be opposed to having an empirically proven domProperty in the return data?

wooorm commented 10 months ago

Can you more practically show what you want to generate for, say, properties that have DOM equivalents, and properties that do not have DOM equivalents? What about datasets, aria, SVG, xmlLang, things that are removed from the platform in some browsers, non-standard values, etc?

I had a thought last week that the information you already have could be run through a browser script/test to validate dom properties (the dom objects will return null vs undefined).

I don’t really understand, out of curiosity, can you show how that would work?

If it were purely additive, would you be opposed to having an empirically proven domProperty in the return data?

I am still wondering about what you want to do for things that do not have DOM equivalents.

Given that hastToReact is already exposed, a hastToDom seems more in line with the existing project.

martypdx commented 10 months ago

I also found this project which backs the standard for whatwg. Let me look at this and think about it