ClojureScript DOM-manipulation library?

821 views
Skip to first unread message

Shantanu Kumar

unread,
Jan 6, 2012, 3:16:01 AM1/6/12
to Clojure
Is anybody working on a DOM-manipulation library for ClojureScript?

There are several JavaScript libraries that can probably be wrapped,
but a ClojureScript library should be great. I noticed a short
comparative list of jQuery basic operations vs JavaScript equivalent
that looks interesting: http://sharedfil.es/js-48hIfQE4XK.html

Shantanu

Mark Rathwell

unread,
Jan 6, 2012, 3:23:03 AM1/6/12
to clo...@googlegroups.com
Pinot [1] provides some dom manipulation [2], mostly wrapping goog.dom
stuff. Were you thinking more than that?

[1] https://github.com/ibdknox/pinot
[2] https://github.com/ibdknox/pinot/blob/master/src/pinot/dom.cljs

> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clo...@googlegroups.com
> Note that posts from new members are moderated - please be patient with your first post.
> To unsubscribe from this group, send email to
> clojure+u...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en

Shantanu Kumar

unread,
Jan 6, 2012, 5:01:26 AM1/6/12
to Clojure


On Jan 6, 1:23 pm, Mark Rathwell <mark.rathw...@gmail.com> wrote:
> Pinot [1] provides some dom manipulation [2], mostly wrapping goog.dom
> stuff.  Were you thinking more than that?

Thanks for mentioning. I will take a deeper look.

Shantanu

ckirkendall

unread,
Jan 6, 2012, 12:12:48 PM1/6/12
to Clojure
I have written dom manipulation library for ClojureScript. I just
finished it up but haven't announced it yet. It started out as a port
of enlive to ClojureScript but has evolved into something much more
powerful. I covers everything from event handling, effects and
standard transformations. Below are links to the github and demo
site.

Demo Site:
http://ckirkendall.github.com/enfocus-site/

Github:
https://github.com/ckirkendall/enfocus

Creightion Kirkendall

kovas boguta

unread,
Jan 6, 2012, 12:18:58 PM1/6/12
to clo...@googlegroups.com
Yes.

I've created a jquery wrapper conveniently called cljs-jquery ,
however there is no documentation, tests, or general housekeeping yet
so haven't announced it. If you are brave,
https://github.com/kovasb/cljs-jquery

Previous libraries have followed the lead of the initial Clojurescript
examples, and tried to wrap gclosure to make it more
clojure-idiomatic.

I think this whole approach is a mistake.

This is not a generic data processing problem, so we shouldn't be
converting the dom into verbose generic clojure structures with
namespace prefixes everywhere.

DOM manipulation is ideally suited to a DSL. JQuery already defines
the primitives, and provides the implementation. Lets just wrap it.

The idea of my library is trivial. Just have a macro that expands into
a jquery call chain:

$(selector).f(a,b).g(c,d)
is represented by
($ selector (f a b) (g c d))

(note that f and g don't need buzz-killing namespace prefixes)

For bonus points, selector can be a hiccup structure (or a hiccup
structure with embedded dom objects) which ends up saving a huge
amount of code when creating new elements.

In general this is far more concise and easier to code than any other
approach I've seen thus far.

On Fri, Jan 6, 2012 at 3:16 AM, Shantanu Kumar <kumar.s...@gmail.com> wrote:

Chris Granger

unread,
Jan 6, 2012, 1:37:40 PM1/6/12
to Clojure
So there's pinot, but I've come to a relatively similar conclusion to
Kovas that wrapping the goog libs aren't really the way to go. For
one, I was basically replicating aspects of jQuery (like event
delegation).

Recently I started on doing some thing that makes jQuery play in the
Clojure world really nicely. I'll get this onto github soon.

Cheers,
Chris.

On Jan 6, 5:18 pm, kovas boguta <kovas.bog...@gmail.com> wrote:
> Yes.
>
> I've created a jquery wrapper conveniently called cljs-jquery ,
> however there is no documentation, tests, or general housekeeping yet
> so haven't announced it. If you are brave,https://github.com/kovasb/cljs-jquery

kovas boguta

unread,
Jan 6, 2012, 3:02:34 PM1/6/12
to clo...@googlegroups.com
Great, looking forward to see what Chris has come up with. I'm not
enough of a JS pro to be the one doing this.

I think what matters is the design. Jquery is an accessible
implementation target, but if someone wants to retarget the design to
gclosure, thats fine too (just more work than is need to get started)

On the design front, there is a fundamental difference between a DSL
and the "standalone generic function" style. So I want to point this
out and advocate for other design decisions I made, to stir the pot
here.

Generic function style treats dom manipulations as stand-alone functions, like
dom/append, events/on, etc

The theoretical benefit is 1) you can use generic clojure functions to
manipulate these datastructures, and 2) you can insert your own
functions into the call tree at any point, like

(dom/append (events/on (your-function (dom/query X)) Y) Z)

However the set of useful dom manipulations is a well-understood, and
is closed set (dom in, dom out). So there is not much benefit in this.

And in fact it tends of obfuscate the code, due to the namespace
prefixing, and also because the dom manipulation sequence is not
clearly set apart from other code. You have to remember how
clojure-like a given return value is.

Better to have a clear sequence like

($ X (click Y) (append Z))

This also has the additional advantage that $ can do a variety of
important tasks, including taking care that "this" is properly
handled. In my library ($ :this) is its javascript equivalent at the
current evaluation context, so handling events is easy.

There are other extensions worth considering. Things like

($ <selector> (css <attribute> <atom>))

could wire an atom to a css (or other) dom attribute, by placing a
watcher on the atom and automatically updating the dom on change.

In general, a high-level cljs dom manipulation framework can consume
atoms (in addition to values) in a variety of places, thus creating
auto-updating views.

We can also leverage clojure maps to aggregate attribute-value pairs, like

($ <selector> (css {<a1> <v1> <a2> <v2}))

Finally, I'm just gonna reiterate that I am a major fan of allowing
<selector> to be an arbitrary hiccup structure, with the extension
that dom/jquery objects are allowed as entries in the hiccup vector.
This makes composing things easy.

ckirkendall

unread,
Jan 6, 2012, 3:12:24 PM1/6/12
to Clojure
Chris,
I am interested in your challenges. For Enfocus I had to implement
several features that existed in jquery around events (mouseenter,
mouseleave, window resize) but I wanted to keep the stack pure without
any external dependencies. Enfocus might have been easier to
implement if I had chosen JQuery but I was afraid that requiring an
external dependency might be problem. I was able to port all of
enlive transformation and quite a bit more. It provides similar model
as JQuery where I have selector -> action. Overall, I did not find it
overly difficult to use the goog libraries for this.

CK

Shantanu Kumar

unread,
Jan 6, 2012, 4:20:40 PM1/6/12
to Clojure
Thanks everybody for responding. I will look at the mentioned
projects.

Shantanu

Takahiro Hozumi

unread,
Jan 6, 2012, 5:01:18 PM1/6/12
to Clojure
> ($ <selector> (css <attribute> <atom>))> > could wire an atom to a css (or other) dom attribute, by placing a> watcher on the atom and automatically updating the dom on change.Interesting idea!

Ryan Waters

unread,
Jan 7, 2012, 11:08:46 AM1/7/12
to clo...@googlegroups.com
On Fri, Jan 6, 2012 at 2:02 PM, kovas boguta <kovas....@gmail.com> wrote:
> I think what matters is the design. Jquery is an accessible
> implementation target, but if someone wants to retarget the design to
> gclosure, thats fine too (just more work than is need to get started)
>

Chris and Kovas -

By going with jquery how well does your clojurescript compile-time
check and minify? Have you written anything that sufficiently tests
compatibility with the gclosure compiler?

- Ryan

Dave Sann

unread,
Jan 8, 2012, 5:15:25 AM1/8/12
to clo...@googlegroups.com
Ryan,

JQuery cannot be compiled by the closure compiler.

If you use advanced mode compilation - you must include the minified jquery lib in your pages and an externs file when compiling clojurescript.

If you are using simple optimisations you can include jquery as a "foreign lib" as documented here: http://lukevanderhart.com/2011/09/30/using-javascript-and-clojurescript.html

some externs files are found here (including jquery to 1.7)


As well as:


The overhead of including the jquery minified js is probably not a major issue.

I expect jquery plugins will generally not work if using advanced compilation. I may be wrong.

Cheers

Dave



Bobby Calderwood

unread,
Jan 6, 2012, 11:58:39 AM1/6/12
to Clojure
There is Luke VanderHart's excellent library, domina [https://
github.com/levand/domina]. I'm using it in a project now with great
success.

On Jan 6, 3:16 am, Shantanu Kumar <kumar.shant...@gmail.com> wrote:

Xavier Tapia

unread,
Jan 6, 2012, 1:41:25 PM1/6/12
to Clojure
Isn't domina a good library for dom manipulation ? https://github.com/levand/domina
Reply all
Reply to author
Forward
0 new messages