j2html icon indicating copy to clipboard operation
j2html copied to clipboard

Javascript html parser to generate j2html from snippets

Open PancakeInvaders2 opened this issue 1 year ago • 12 comments

If I embark on trying to create a js parser to parse html snippets into j2html code, would there be interest in adding that to the website ?

I'm thinking of doing that in kotlin using KSoup, and then compile that kotlin to javascript.

I hope this project is still active

PancakeInvaders2 avatar Feb 23 '24 09:02 PancakeInvaders2

If I embark on trying to create a js parser to parse html snippets into j2html code, would there be interest in adding that to the website ?

I could help with that :)

tipsy avatar Feb 23 '24 14:02 tipsy

Cool ! I'll get started this weekend then

PancakeInvaders2 avatar Feb 23 '24 14:02 PancakeInvaders2

I'm almost done with the parser, I'm doing some tests. In one test, I'm starting with some input html, translating it to j2html with the tool I wrote, executing and rendering the html in java, and looking in the browser if it looks the same as the input. But I'm having an issue where I have a spaces missing. I think it might be a bug/unintended behavior in j2html

render() and .renderFormatted() don't produce exactly the same page when viewed in a browser. There are single space differences body(div(label("First Name"), text(": Joe"))).render() shows as "First Name: Joe" in chrome and firefox but body(div(label("First Name"), text(": Joe"))).renderFormatted() shows as "First Name : Joe" in chrome and firefox

is this intended ?

PancakeInvaders2 avatar Mar 01 '24 09:03 PancakeInvaders2

Also a few attributes have small issues:

The attribute 'autocomplete', as in input().withCondAutocomplete(true), seems to be considered a boolean by j2html, it takes a boolean param. But the mozilla docs say it's not just a boolean: valid values are "off", "on", "name", "email", "new-password", etc. https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete

There is also an issue on the the attribute onvolumechange. Instead of a withOnvolumechange, j2html has audio().withOnvolumechanged("value"), with a d at the end, that doesn't exist in HTML5 https://www.w3schools.com/tags/att_onvolumechange.asp

These 2 issues weren't blocking for me, I let these two attributes be mapped to the default case attr("key", "value") in the code generator so that it works regardless of what the input contains

PancakeInvaders2 avatar Mar 01 '24 09:03 PancakeInvaders2

render() and .renderFormatted() don't produce exactly the same page when viewed in a browser. There are single space differences body(div(label("First Name"), text(": Joe"))).render() shows as "First Name: Joe" in chrome and firefox but body(div(label("First Name"), text(": Joe"))).renderFormatted() shows as "First Name : Joe" in chrome and firefox

The difference is likely the whitespace formatted rendering introduces:

<body><div><label>First Name</label>: Joe</div></body>

vs.

<body>
    <div>
        <label>
            First Name
        </label>
        : Joe
    </div>
</body>

That whitespace will be interpreted by the browser as the extra space that you see.

sembler avatar Mar 01 '24 15:03 sembler

The attribute 'autocomplete', as in input().withCondAutocomplete(true), seems to be considered a boolean by j2html, it takes a boolean param. But the mozilla docs say it's not just a boolean: valid values are "off", "on", "name", "email", "new-password", etc. https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete

There is also an issue on the the attribute onvolumechange. Instead of a withOnvolumechange, j2html has audio().withOnvolumechanged("value"), with a d at the end, that doesn't exist in HTML5 https://www.w3schools.com/tags/att_onvolumechange.asp

Thank you for pointing these out. I'll break these into separate issues to track for the next release.

sembler avatar Mar 01 '24 15:03 sembler

yes that seems to be what it is

that poses some questions in terms of code generation though

let's say I'm receiving the input

<main>
    <div>
        <p>
            Hello world
        </p>
    </div>
</main>

The text that I'm getting from KSoup is correctly "\n Hello world\n ", so if I don't do any sanitization I'll generate

main(div(p("\n            Hello world\n        ")))

which is fairly ugly, but would not make people html look different than what they inputed to the generator

Based on https://stackoverflow.com/questions/588356/why-does-the-browser-renders-a-newline-as-space

Browsers condense multiple whitespace characters (including newlines) to a single space when rendering. The only exception is within <pre> elements or those that have the CSS property white-space set to pre or pre-wrap set. (Or in XHTML, the xml:space="preserve" attribute.)

I could write some logic and replace the multiple whitespace characters by a single space in some cases, which would produce

main(div(p(" Hello world "))) 

which looks better, but is maybe more complex than we'd like

In my previous sanitization attempts, I would have generated

main(div(p("Hello world")))

and the results would look different depending on wether render() or renderFormatted() is used

Edit: fix github formatting

PancakeInvaders2 avatar Mar 03 '24 14:03 PancakeInvaders2

This is a tricky question that I don't have a perfect answer for. I'd suggest that you detect newline characters, which probably indicates that formatted rendering is desired, and strip out the unnecessary whitespace from the inputs. That whitespace will be added back in when using renderFormatted(). If you don't detect any newlines you might assume unformatted rendering and leave the excess whitespace.

sembler avatar Mar 11 '24 13:03 sembler

Thanks, I implemented that. I'm preparing the pull request

PancakeInvaders2 avatar Mar 14 '24 01:03 PancakeInvaders2

Is this work still under development and being worked upon? Do we expect this to be available as part of main release?

rohitdev avatar Aug 02 '24 09:08 rohitdev

The actual work is done, the code in the PR is usable

https://github.com/tipsy/j2html/pull/226

In the discussion it ended up being a lot of code to maintain, so the idea is that I make a separate repository to maintain it myself, and push the transpiled javascript to npm, so that it can be used in the website as a js dependency. So it won't be part of a release of j2html and the PR could be closed. Time and energy has been a bit scarce on my end since the birth of my daughter, I'll get around to set up the new repo and npm as soon as I can

PancakeInvaders2 avatar Aug 02 '24 19:08 PancakeInvaders2

Not sure if this is useful or even the same as intended here, but I've created a static site to convert html to j2html, hosted it at https://bvankatwijk.nl/j2html-converter/, sources at https://github.com/bvkatwijk/j2html-converter.

Still very minimal but it is a working concept. Currently it supports basic conversion, returns only the j2html expression (no wrapper classes/methods), and many utility functions are not yet built in but are easy to add (e.g. rendering id as withId)

If desired this could be ported over to this project, if so let me know :)

bvkatwijk avatar Feb 05 '25 09:02 bvkatwijk