Fork me on GitHub
#squint
<
2023-11-27
>
jeroenvandijk14:11:18

Maybe something like this will be an interesting application for Squint. Nothing fancy, just tiny PoC https://jsfiddle.net/jeroenvandijk/ygrnpx8h/8/

❤️ 2
👍 1
1
jeroenvandijk14:11:19

<div hc-on:click="(-> el (_closest :div) _remove)">
      click to remove me ....
    </div>
TLDR; hyperscript/htmx like with squint. See fiddle for live demo

borkdude14:11:24

shouldn't be too difficult

borkdude14:11:38

the fiddle doesn't work yet right?

jeroenvandijk14:11:43

it should work

borkdude14:11:01

show/?editor_console=:183 Uncaught ReferenceError: htmx is not defined at show/?editor_console=:183:24

jeroenvandijk14:11:19

can't see what is off. Works here in a fresh incognito browser window. Tried Chrome and Brave

jeroenvandijk14:11:28

before and after 🙈

borkdude14:11:01

ah yes, it does work in another browser for me

borkdude14:11:29

don't know what the difference is

borkdude14:11:42

it works now, very cool!

jeroenvandijk14:11:50

Yeah it think so too :face_with_hand_over_mouth: Probably needs some good API design and real life testing. But I like the idea i think

borkdude14:11:06

where can I see the source of this in the jsdiffle?

jeroenvandijk14:11:43

It should be below the html. I was hiding it for the wow effect

jeroenvandijk14:11:07

Here is the whole snippet

borkdude14:11:12

old squint version ;)

jeroenvandijk14:11:24

haha oh oops 😅

jeroenvandijk14:11:56

I also didn't know a better way to expose an api to the squint context, but it works this way. Maybe it would be good to have some namespaces for the htmx functions and maybe a threading macro to not having to repeat that namespace. Maybe some experienced htmx users have an opinion, i'm not there yet

borkdude14:11:23

you can use the repl output in the newest squint versions to emit "namespaces" as global objects

👍 1
borkdude14:11:05

anyway, let me know if you have any concrete questions, happy to help

jeroenvandijk14:11:46

not yet, thanks! now just sharing this brainfart. Maybe I'll try it a bit for real later

martinklepsch15:11:57

I was also thinking about this a few days ago! The idea I had also involved something like the following on the server side

[:button {:onclick (squint (js/alert "test")))} "test"]
I.e. the squint code lives inside the server code and gets compiled on the fly. That way you have full syntax support (no code in a string stuff) and with clj-kondo we there could even be a linter that has a special understanding of those forms

❤️ 3
martinklepsch15:11:45

And then there could be a tiny support lib like what you used in your example @U0FT7SRLP

jeroenvandijk16:11:01

Nice @U050TNB9F! I think the native onclick cannot be used nicely because the element is not passed to the function (so you don't know where you are without hacks). I think that's why hyperscript has an edge for instance. But yeah lot of options

jeroenvandijk16:11:57

Also, a custom attribute also has the advantage of allowing a custom treatment. So you can assume a certain format, context etc. With onclick it has to be javascript. I guess some tradeoffs here

borkdude16:11:27

"I think the native onclick cannot be used nicely" I guess you could make a convention of what the el thing is or so

martinklepsch16:11:40

Ah yeah, totally could use a different attribute, I didn't really think to far about it. I just really liked the prospect of having an actual syntax in your editor (and lint that even)

borkdude16:11:06

yes and to compile it on the backend has the benefit of reduction in JS size

jeroenvandijk16:11:48

Yeah sounds good, i think it is nice that squint allows to experiment with both. So it would also work for people that don't have a clojure(script) setup

jeroenvandijk16:11:11

> I guess you could make a convention of what the el thing is or so Yeah in case you mean the naming, for sure. But I could not find a way to get access to the current dom element with the normal onclick . this seems to be the window in e.g. <button onclick="console.log(this)">click</button> from the top of my head

jeroenvandijk16:11:51

With addEventListener you can do this.target and get the element from which you can to the parent etc

jeroenvandijk16:11:08

sorry i mean the argument to the function, not this

martinklepsch17:11:25

[:div {:on {:click (some-squint-code)}}]
😀

😎 1
👌 1
martinklepsch17:11:20

now only a question of how to compile that 😄

borkdude17:11:54

why not just [:div {:onclick (squint ...)] which is regular hiccup where squint can be the macro?

jeroenvandijk17:11:21

This is what this does here

[:div {:onclick "function(e){console.log(e)}"}  "hi"] 
->
<div onclick="function(e){console.log(e)}">hi</div>
->
Uncaught SyntaxError: Function statements require a function name (at squint.html:31:231)

borkdude17:11:14

yes, this is true, why pass a function there though?

jeroenvandijk17:11:17

ah but i ran into this before 🙂

borkdude17:11:21

you have to write function foo () {}

borkdude17:11:27

as in, give it a name

jeroenvandijk17:11:37

you can wrap it with another function and then it works too

borkdude17:11:51

I think I'm missing a couple of points here

borkdude17:11:08

onclick doesn't support a function expression, right?

borkdude17:11:20

it just supports a snippet of JS that it will execute?

jeroenvandijk17:11:28

yeah i think that's the problem. I was just verifying if i missed something, but yeah that's the reason

jeroenvandijk17:11:56

so the snippet doesn't give you the current element. Which is what you want often. Maybe you could do a lookup, but that might be expensive?

jeroenvandijk17:11:12

(like parsing and searching for it?)

borkdude17:11:59

Perhaps you could compile to:

(fn [this] (-> ...)) => (this-as this ((fn [this] ...) this)

borkdude17:11:01

which should work

borkdude17:11:13

and I think this points to the target element there

jeroenvandijk17:11:45

yeah indeed. But this only works if you add if via node.addEventListener('click', function(this) { ... }) I think

borkdude17:11:09

first transform to (this-as this ((fn [this] ...) this)) and then compile that

borkdude17:11:14

this is just an ordinary expression

jeroenvandijk17:11:28

ok this is something I don't know I guess

jeroenvandijk17:11:38

but would be nice

jeroenvandijk17:11:31

this-as comes from clojurescript? It feels familiar

martinklepsch17:11:58

I think in the end the squint macro or whatever would need to inject compiled JS into the runtime, it probably won't work to emit the compiled JS into an HTML attribute 😄

borkdude17:11:22

sure it will ;)

borkdude17:11:36

with the right pre/post-processing

jeroenvandijk17:11:53

ok maybe i just missed something or missed one step. I was wrong you have access to this in the onclick . Never mind the above 🙈

borkdude17:11:46

right, so you could have:

{:onclick "(this-as this ((fn [this] ...) this))"}
but generate the this-as wrapping for the user so the user only writes:
(fn [this] ...)

martinklepsch17:11:59

maybe, but it'll hurt readability, probably makes it hard to debug etc. no? I'd think emitting a <script> tag would be a bit more "in line"

borkdude17:11:29

fine, but then why use inline expressions at all and not just use squint normally

borkdude17:11:56

<script>(squint ...)</script>

jeroenvandijk17:11:00

if you compile it with squint you could wrap this in the context? No need for this-as ? We don't need the function wrapping at all i think. I was wrong here

borkdude17:11:20

you need this-as since this is renamed

borkdude17:11:33

since it can be a normal function argument which doesn't clash with JS's this

borkdude17:11:43

(fn [x y this whatever])

jeroenvandijk17:11:44

ah maybe that's what I ran into

borkdude17:11:00

this is why you HAVE TO use this-as if you want to access JS's this

borkdude17:11:15

or you can fuck around with (js* "this")

jeroenvandijk17:11:45

I had the wrong assumption that htmx and hyperscript were using custom attributes because of the lack of access to this, but that is not the case. But a custom attribute does allow custom treatment, with onclick it needs to be valid javacript. So maybe custom still gives nicer syntax options

jeroenvandijk17:11:56

(have to go, thanks for your enthusiasm 🙂 )

jeroenvandijk17:11:07

> fine, but then why use inline expressions at all and not just use squint normally btw, that would be this argument https://htmx.org/essays/locality-of-behaviour/

borkdude17:11:04

my point wasn't to argue for or against locality, but if you're using local snippets, why compile to JS that behaves different, was my question to Martin

👍 1
borkdude17:11:08

gotta go too

martinklepsch17:11:54

> fine, but then why use inline expressions at all and not just use squint normally Mostly to not have a compiler on the client and be able to provide some wrapping constructs for handlers... but maybe that can be achieved in other ways as well 🙂

👍 1
borkdude18:11:37

So maybe just wrapping the ="..." expressions in a (this-as el ...) would be enough, then the user could write:

(-> el ...)

borkdude20:11:23

I just merged a PR which downloads clojure-mode, a big project which was ported to squint and it's tested with every squint commit. There was an issue with CI on Windows though. If someone feels like helping out, feel free to look into that

borkdude20:11:44

One issue was that npx didn't work on Windows, another one is that yarn somehow didn't work