-
Notifications
You must be signed in to change notification settings - Fork 88
feat: implemented JSX support as text/jsx+xml #96
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
base: main
Are you sure you want to change the base?
Conversation
@@ -40,9 +40,10 @@ export class Attr extends Node { | |||
} | |||
|
|||
toString() { | |||
const {name, [VALUE]: value} = this; | |||
const {ownerDocument, name, [VALUE]: value} = this; | |||
const doubleQuote = ownerDocument[MIME].unquotedJsonAttributes && /^\{(.[\s\S]?)+\}$/.test(value) ? '' : '"' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is /^\{(.[\s\S]?)+\}$/
for? if it's about starting with {
and ending with }
I believe /^\{[\s\S]*\}$/
is what you are after?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, I'll try that; should be more precise than my code there. It was late when I wrote that RegExp :)
return emptyAttributes.has(name) && !value ? | ||
name : `${name}="${value.replace(QUOTE, '"')}"`; | ||
name : `${name}=${doubleQuote}${value.replace(QUOTE, doubleQuote ? '"' : '"')}${doubleQuote}`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would have instead:
const useQuote = ownerDocument[MIME].unquotedJsonAttributes && /^\{(.[\s\S]?)+\}$/.test(value);
const quote = useQuote ? '"' : '';
// ...
`${name}=${quote}${value.replace(QUOTE, useQuote ? '"' : '"')}${quote}`
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is def. more readable. Good point.
docType: '<?xml version="1.0" encoding="utf-8"?>', | ||
ignoreCase: false, | ||
escapeHtmlEntities: false, | ||
unquotedJsonAttributes: true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2 things I'd rather change here, or discuss:
- I don't like checking emptiness ... all objects here are homogeneous, if we add a single boolean field somewhere I want it to be explicitly boolean field somewhere else too, as it is for
escapeHtmlEntities
... so, I'd addunquotedJsonAttributes: flase
in other cases - I don't unrestand why it's called
unquotedJsonAttributes
... I understand it's virtually JSON, but practically that's an unquoted attribute ... so ... since we want to allow only JSON which results into being unquoted, I think a field name such asjsonAttributes
would better reflect the intent/purpose? ... 'cause of course those gotta be unquoted, otherwise it'd be invalid JSON, does it make sense?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- agreed, that makes sense to me
- I think that
jsonAttributes
would describe the purpose what should be achieved, whileunquotedJsonAttributes
is describing what it is happening. I like both ways of naming. Lets go withjsonAttributes
then
@kyr0 beside my comments as review, I am not sure I like where this is going or, to be more precise, I don't understand what is this adding, compared to jsx2tag, which allows real JSX out of the box, without really needing to change much. Most notably, I don't understand how you would address Thank you! |
@WebReflection I see. First of all, thank you for taking so much time to review, give me good feedback on my code and pointing me to potential alternatives! Very much appreciated! So, what I'm doing is pre-processing JSX/HTML markup before transpiling it in a second step. The pre-processing step mutates elements and its CDATA based on certain rules; especially As
as well as Of course, there is no need to address that specifically in I think having JSX/TSX support for linkedom in that way is a nice feature for the library that fits in very well to the existing supported XML(-like) grammar variations. Of course this is just my opinion and subjective. |
@kyr0 do you have any example of how this would actually work? The test just shows that JSX can be outputted, but what would you do/use that output? Anyway, because the mime is a non-existent one, I don't have particular problems in enabling this use case too, I just need to approve those changes and see if there's any relevant performance issue, but on a quick look it doesn't look like there should be one. |
@WebReflection Thank you. Well, I pre-filter the HTML comments; then, using One thing that happens in the evaluation is that a custom Well; yesterday night, I was re-thinking my implementation of step (1) because I found some issues with more complex JSX use-cases in the Locally I have the test running almost 100% green now and am almost ready for PR; but there is still a bit of complexity to solve; well, its quite a patch on But now, after this introduces so much change in the ecosystem I'm asking myself if it is really still wanted by everyone involved? Let's see -- I'll open a PR in Until then, I also have an alternative solution for myself, as I rewrote my code for step (1) last night, replacing So... I think it would still be nice to have JSX support in linkedom, but it requires change in htmlparser2 and a dependency version bump later as well. I'll open that PR there and update this one today/tomorrow anyway... |
@kyr0 fair enough, and thanks for the update. I'll wait for your changes/future updates then, and keep this open for the time being. |
I am not against JSX but this feels a bit stale and with conflicts ... I'd love to see an updated version of this PR if possible, otherwise I will close it. |
Hi Andrea,
...hope you're doing well! I remember reading your emails on the ES mailing list years ago :)
Well... fast-forward; a few days ago I discovered your beautiful DOM implementation here and I really love it. It's so elegant! Since I'm working on a new SSG concept, I use it to parse and (post-)process markup for static site generation. As my tool supports JSX/TSX as the primary input templating format, using
linkedom
showed extremely well performance and a beautiful API but of course, JSX/TSX support is still lacking in this lib and it caused some trouble for full JSX/TSX feature support -- until today :)So, I've just implemented support for that;
text/jsx+xml
:<
,>
etc. into entities, gives hickups here as the grammar doesn't support that obviously<foo bar={callFn()} />
-- of course, wrapping it in quotes would lead to wrong interpretation in further parse steps in the transpilerdocument.toString()
For the implementation, I just followed the code style and architecture given. Another mime type has been added and you'll find some additional branching logic in certain
toString()
implementations.The reason why I introduced the
escapeHtmlEntities
flag to all mime types and not inverting that control logic was, that the assumption to activate the feature by default, seems logical to me - so it's more like: "you can deactivate it, if really needed". However, I think this is a flag the user might want to have more flexible control over. I had the idea to pass an optional argument to theparseFromString()
so that details could be controlled more precisely (overriding default mime type config); however I think that this would be a change worth another PR -- and I also actually don't really need this right now.I've also added all necessary tests. You'll find the PR to build with 100% test coverage, checking for all changed/added behavior as well.
I'd love if you'd find time to review and maybe merge this one + release a new version.
I've the package linked locally with my changes, but would love to release an alpha version of my SSG concept soon -- but of course I don't want to fork/release this lib for that.
Thank you in advance!
Aron