-
-
Notifications
You must be signed in to change notification settings - Fork 328
-
There's been a lengthy discussion about changes to how HTML elements are constructed. I'd like to take a step back and consider the initial motivations for the changes, what assumptions may have been unfounded, correct them, and then move forward from there.
Let's take a look at the issue that spawned these changes. It states that...
Currently the vdom element constructor and component constructors have different interfaces... The fact that these two constructors have different interfaces won't play well with this jimbaker/tagstr#9.
In short, this issue anticipates a future in which most code written for IDOM use a JSX-like syntax. As such, it posits that in that future IDOM would need a way to help enforce or encourage component authors to handle children in some standardized way. As part of doing that, we would make the standard HTML constructors have the same signature that we would expect user-authored components to have when used with this hypothetical JSX syntax. The issue proposes that the signature for these constructors should be:
constructor(*children, key=..., **attributes)
I see a number of different ways in which the assumptions of this issue may have been wrong. Those being that...
- We should optimize for a JSX-like syntax that doesn't exist yet.
- Components being used in JSX had anything to do with
html.*(...)element declarations in the first place. - There was any real way to make component authors treat positional arguments like "children"
- Making positional arguments be children was a good idea in the first place
If we can agree that these were false assumptions then it probably makes sense to revert the changes from #841 with the exception of those that allow attribute names to be snake_case. From there, we can have a separate debate about whether there is a better way to declare HTML elements in pure Python.
Beta Was this translation helpful? Give feedback.
All reactions
Replies: 2 comments 7 replies
-
Why not implement a few variants (in a cross-compatible and extensible way) and let the user/team choose according to general preference and particular usecase? This may aid transitioning from other frameworks and allow for the "wisdom of the crowd", at some peril of syntactic cacophony.
Beta Was this translation helpful? Give feedback.
All reactions
-
Given that the VDOM Spec is currently documented, it's already possible for third party packages to exist that use different syntaxes.
Also the docs would get really ugly if we support more than one syntax in core. Having more than one syntax is ironically the same issue ReactJS is going through with their new docs.
Beta Was this translation helpful? Give feedback.
All reactions
-
It might be a little generous to say the VDOM spec is documented, but yes, I think it's stable enough for thirdy party packages to build on. Specifically, IDOM's rendering logic expects elements to conform to the VdomDict type.
And yes, from a documentation perspective, it would be best if there was one canonical way of writing things.
Beta Was this translation helpful? Give feedback.
All reactions
-
I see a number of different ways in which the assumptions of this issue may have been wrong. Those being that...
- We should optimize for a JSX-like syntax that doesn't exist yet.
- Components being used in JSX had anything to do with
html.*(...)element declarations in the first place.- There was any real way to make component authors treat positional arguments like "children"
Agreed. If jimbaker needs a specific python interface, he could always make a third party VDOM generator. But the JSX syntax doesn't seem to relate to our Python syntax to be honest.
It would be fun to play around with a JSX alternative at some point though. We might want to work on a PySX syntax highlighter in the future? Or to be honest, jinja could be a pretty good drop-in replacement.
- Making positional arguments be children was a good idea in the first place
As mentioned in the previous discussion, the new interface is less visually HTML-like and harder to read/write/translate/modify. There are better ways to do this IMO.
If we can agree that these were false assumptions then it probably makes sense to revert the changes from #841 with the exception of those that allow attribute names to be snake_case. From there, we can have a separate debate about whether there is a better way to declare HTML elements in pure Python.
Reminder that if we decide to stay on the old syntax, we probably want to allow raw dashes - to be allowed on any HTML attribute.
Is it still worth considering alternative syntaxes? And do we want to have that debate in this or another thread?
I've updated the interface guidelines with the new direction.
Beta Was this translation helpful? Give feedback.
All reactions
-
If jimbaker needs a specific python interface...
BTW I'm also involved in developing that PEP.
It would be fun to play around with a JSX alternative at some point though.
I just posted an issue on that tagstr repo about implementing an import-time transpiler. We could use that in IDOM to make the following possible:
view: VdomDict = html @ f"<button onClick={lambda event: ...}>Click me!</button>"
Is it still worth considering alternative syntaxes?
Given this is probably the last opportunity we have to consider this, it seems reasonable to do so, but probably in a separate discussion.
Beta Was this translation helpful? Give feedback.
All reactions
-
It's going to be really important to make sure tagstr brackets can't be interpreted as raw HTML by default. Otherwise, tagstr would be non-viable for web dev.
See here for more details.
Beta Was this translation helpful? Give feedback.
All reactions
-
Since we use React on the frontend and they already escape values we should be fine. With that said, do we do this in vdom_to_html?
Beta Was this translation helpful? Give feedback.
All reactions
-
The concept of escaping values only really applies to initially rendering something with user inputs.
Since vdom_to_html and html_to_vdom aren't used for initial renders (the vdom/HTML gotta come from somewhere, right?), we should be alright.
If we adopt the JSX syntax, we may want to add some XSS tests. For example...
# This is normal my_val = "dog" html @ f"<div className={my_val}> </div>" # This is malicious use. # We should ensure the input value can't create a new h1 my_val = "dog> </div>" + "<h1> This is malicious </h1>" html @ f"<div class={my_val}> </div>"
Beta Was this translation helpful? Give feedback.
All reactions
-
Whether this is a problem would depend on the implementation of html, but as it's implemented here, my_val would never be interpreted. Thus it would be impossible to inject any HTML accidentally. We can discuss this in a separate thread if needed though.
Beta Was this translation helpful? Give feedback.