google / incremental-dom

An in-place DOM diffing library
http://google.github.io/incremental-dom/
Apache License 2.0
3.54k stars 180 forks source link

Twing implementation #438

Open noel-schenk opened 5 years ago

noel-schenk commented 5 years ago

Started implementing incremental-dom into twing and now finished the first kinda working version (I know there are many things wrong with the current implementation). Let me know what you think about the concept of having twing/twig and incremental-dom combined.

Official Twing package: https://github.com/NightlyCommit/twing/ Modified Twing package: https://www.npmjs.com/package/@noelelias/twing or https://github.com/noelelias/twing/tree/noelelias/master Playground: https://github.com/noelelias/twing-playground

iteriani commented 5 years ago

Ooo server-side rendering using incremental dom. Fancy :P Are there any innate protections with twing around xss?

noel-schenk commented 5 years ago

@iteriani It actually works both in the browser and on the server (take a look at the web loader) so if you have a request for example from google or bing you can send an already rendered version to the client. But I started working on this because I really dislike the way react and co. works (everything in js instead of using html files).

Yes you can use the escape filter but if I'm honest I think you could just use any xss package: https://www.npmjs.com/package/xss ... As twig/twing is "just" a template engine it usually is not necessary.

For twig it's basically just another filter you add. After that you're able to modify it in js which then updates the document via incremental-dom.

ericmorand commented 5 years ago

Very interesting stuff. Not sure In understand everything though.

What form would it take in Twing? Is the dom filter doing all the work?

In the end, is your objective to use Twing as a templating language to write reactive applications using the incremental DOM library?

So that we could write usual Twig like this:

<div>
{% if (foo.bar) %}
    {{ foo.content }}
{% endif %}
<div>

And having it render to <div>This is the content of foo</div> when used with the classic environment and some static data (namely here template.render({foo:{bar: true, content:'This is the content of foo'}})) and to something like that when using the incremental DOM environment:

const {elementOpen, elementClose, text} = require('incremental-dom');

function render(data) {
  elementOpen('div', '', null);
    if (data.foo.bar) {
      text(data.foo.content);
    }
  elementClose('div');
}

I hope it's what you have in mind because I like it. A lot.

noel-schenk commented 5 years ago

Yes exactly. It's reactive and also doesn't require a virtual dom everything happens in the dom itself since this is the way incremental dom works. You basically add the "dom" filter to the element you want to be able to change later and give it a path like 'car.seat.color' or 'carSeatColor'. Then with the domRender function from TwingWebLoader you get an object where you can change those predefined objects. Like this:

let domTree = loader.domRender(res, document);
domTree.car.seat.color('car seat color split up');
domTree.carSeatColor('car seat color just as a name');

Oh wow I haven't thought of that:

And having it render to

This is the content of foo
when used with the classic environment and some static data (namely here template.render({foo:{bar: true, content:'This is the content of foo'}})) and to something like that when using the incremental DOM environment:

Yes now this is my goal that would be much easier for the user. Thank you :smiley:

ericmorand commented 5 years ago

Goooood.

Is your web loader parsing the Twig template and, for each encountered HTML tag, pushing it to the DOM tree?

If so then it is not a Twing loader in the sense of the API which explains why I was not understanding its implementation. But it would be very appropriate at the parser level. Let me think about it and let's talk about that on Slack if you prefer.

noel-schenk commented 5 years ago

Yes sure sounds good.