News for hackers. Stuff that matters.
Re:TinyJS – Shorten JavaScript QuerySelect with $ and $$ by tomp on Wednesday October 02, 2024 @04:06PM (#41724525)
Why would this make any sense?

    const myDiv = div(
      {id: 'container', className: 'my-class'}, 
      h1('Hello World'), 
      p('This is a dynamically generated paragraph.')
    );
    document.body.appendChild(myDiv);
That's completely unnecessary these days with template strings. It's gonna be much faster as well to use browser's native parsing.

    const div = document.createElement('div');
    let text = 'This is a dynamically generated paragraph';
    
    div.innerHTML = `
      <div id="container" class="my-class">
        <h1>Hello world</h1>
        <p>${text}</p>
      </div>
    `;
    document.body.append(...div.children);

Keep it simple!
Re:TinyJS – Shorten JavaScript QuerySelect with $ and $$ by franciscop on Wednesday October 02, 2024 @04:11PM (#41724562)
One big difference and why I've been experimenting with JSX[1] is that in that example, if the `text` comes from an untrusted source it can lead to XSS, which TinyJS prevents (I checked)!

[1] https://x.com/FPresencia/status/1838176000267452704

Re:TinyJS – Shorten JavaScript QuerySelect with $ and $$ by wruza on Wednesday October 02, 2024 @04:19PM (#41724630)
Even if it comes from a trusted source, you usually want a good distinction between html interpolation and just-text chunks.
Re:TinyJS – Shorten JavaScript QuerySelect with $ and $$ by spullara on Wednesday October 02, 2024 @04:18PM (#41724614)
you should probably worry about untrusted data in text and use a tagged template function that sanitizes its inputs for insertion in html.
Re:TinyJS – Shorten JavaScript QuerySelect with $ and $$ by nikeee on Wednesday October 02, 2024 @04:34PM (#41724730)
You can use tagged template functions to escape `${text}`. The result is pretty close to lit-html [1].

[1]: https://lit.dev/docs/v1/lit-html/introduction/

Re:TinyJS – Shorten JavaScript QuerySelect with $ and $$ by tomp on Wednesday October 02, 2024 @04:38PM (#41724760)
beautiful!
Re:TinyJS – Shorten JavaScript QuerySelect with $ and $$ by Nickersf on Wednesday October 02, 2024 @04:35PM (#41724739)
This is exactly what I was thinking. I'm always trying to have fewer third-party dependencies in my codebase no matter how tiny, especially if it's solving problems that already have platform/system native solutions.
Re:TinyJS – Shorten JavaScript QuerySelect with $ and $$ by rikafurude21 on Wednesday October 02, 2024 @04:45PM (#41724809)
Makes sense to me, looks better. writing html strings like that is annoying
Re:TinyJS – Shorten JavaScript QuerySelect with $ and $$ by TimTheTinker on Wednesday October 02, 2024 @04:51PM (#41724867)
Generally, I would recommend avoiding directly setting the innerHTML property, since it's vulnerable to XSS and other injection attacks. If you do, make sure you HTML-escape each variable you interpolate.

Here's a way to do that with a tagged template function (named it `htmlFragment` to make it super clear what it's for):

    // a couple of functions to help
    
    const sanitizeHTML = (unsafeStr) => {
        const div = document.createElement('div');
        div.textContent = unsafeStr;
        return div.innerHTML;
    };
    
    const htmlFragment = (fragments, ...variables) => {
        const result = variables.map((variable, i) => fragments[i] + sanitizeHTML(variable));
        result.push(fragments[fragments.length-1]);
        return result.join('');
    };
    
    // updated your code here
    
    const div = document.createElement('div');
    let text = 'This is a dynamically generated paragraph';
    
    div.innerHTML = htmlFragment`
      <div id="container" class="my-class">
        <h1>Hello world</h1>
        <p>${text}</p>
      </div>
    `;
    document.body.append(...div.children);
Unfortunately, to my knowledge there isn't yet a close-to-the-metal solution for templating and data binding in HTML/JS, although several proposals are currently being discussed.
Re:TinyJS – Shorten JavaScript QuerySelect with $ and $$ by meiraleal on Wednesday October 02, 2024 @05:22PM (#41725087)
> Unfortunately, to my knowledge there isn't yet a close-to-the-metal solution for templating and data binding in HTML/JS

I'm hoping for this one:

https://github.com/WICG/webcomponents/issues/1069

Re:TinyJS – Shorten JavaScript QuerySelect with $ and $$ by makingstuffs on Thursday October 03, 2024 @02:06AM (#41727753)
Would you not just be able to do the following:

    const div = document.createElement('div');
    const text = 'This is a dynamically generated paragraph';


    div.insertAdjacentHTML("beforeend", `<div id="container" class="my-class">
        <h1>Hello world</h1>
        <p>${text}</p>
      </div>`);

    document.body.append(...div.children);
Edit, figured I'd add the docs: https://developer.mozilla.org/en-US/docs/Web/API/Element/ins...
Re:TinyJS – Shorten JavaScript QuerySelect with $ and $$ by TimTheTinker on Thursday October 03, 2024 @09:01AM (#41730398)
That's certainly better than innerHTML, but it has the same security implications as setting innerHTML.

From the MDN page:

> When inserting HTML into a page by using insertAdjacentHTML(), be careful not to use user input that hasn't been escaped.

Re:TinyJS – Shorten JavaScript QuerySelect with $ and $$ by spencerchubb on Wednesday October 02, 2024 @07:37PM (#41725947)
how would you add listeners if you were doing an html string? the first approach allows you to do something like this

``` const myButton = button({ onclick: e => console.log(e), textContent: "Click me" }) ```

Re:TinyJS – Shorten JavaScript QuerySelect with $ and $$ by TimTheTinker on Wednesday October 02, 2024 @10:31PM (#41726789)
Use topElement.querySelector('button'), then add the listener programmatically.