Hi folks,
Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixir (here). Finally, first beta has been released!
In the meantime I’ve changed the API, so it is - I believe - easier to remember. If you think about webpage as a database which contains DOM objects, it is natural to query:
select(:text, from: "p:first") to get text of the first paragraph or
select(attr: :href, from: "a") for all links in the document,
update some object(s) with
update(css: :border, set: "3px solid red", on: this(sender)),
add new nodes or attributes
insert("<b>IMPORTANT</b>", before: "p:first"),
or remove something with
delete(class: "btn", from: "#the_button"),
and more, like synchronous modal which - launched on the server side - waits for user input.
Do I understand it well if I say that this allows you to basically ‘remote control’ what a user sees on their webpage?
This is very interesting, as I feel myself writing similar javascript over and over again to manage these kinds of tasks.
If this would be combined with a JS library managing a virtual DOM, we might even be able to write nearly all browser-UI management on the server, FRP-style!
Good job! It’s awesome for all projects that do not care about support as many connections as possible as fast as possible
What do you think about shourtcut method to toggle actions (delete or insert something or update with keep prevoous value)?
This looks fascinating and could simplify code! A question though, how does it work with a shadow DOM (which makes custom elements internal parts invisible to normal DOM methods) as the site I work on is almost entirely Shadow Dom (which is faked on Firefox and such but a real shadow DOM on Chrome)?
Would it be possible to generalize drab to call a particular function on javascript land? That would allow us to have a callback say in a polymer component or a react one and let them be called from elixir via drab. I just found about your library yesterday, but I’m willing to play with it today, and will explore this, as I’d be interested in using it to command an existing react-native app (where no jquery is available, so I’d really like to call a generic js function, perhaps use my app tree state as a queriable thing, as drab treats the client side as a database).
It is already done - in fact, all the query functions just build the javascript and call it on the client side by running execjs/2 or broadcastjs/2. This functions just run any JS you give. At the beginning there were private, but I decided to open it to public as they may be useful in cases like yours
Nice ! so I guess drab is not actually tied to having a DOM, that was my biggest concern about using with react-native. Thanks for the links, and for drab, it looks just awesome!
But it still requires jQuery on the client-side, as it was easier for me to develop it in early sandbox/proof-of-concept stage. Removing jQuery is on the todo list, but not on the top priority for now.
Still not commanding react properly but was able to execute a console log and a random js.
Here’s what I did
created a bare-bones react native app
copied just the essential parts of your drab.js template into it (removed most of the modal, and other stuff)
called it DrabNative perhaps DrabHeadless could be better name, as it should be generic. Just included
the parts for connecting and sending events with payload.
bundled phoenix.js in it
removed the Phoenix.Token validation and hardcoded my demo to Elixir.DrabPoc.PageController#index
created another method in the commander:
def native_uppercase(socket, sender) do
socket |> console("Hey DrabNative, this is PageCommander from the server side!")
socket |> execjs("console.log(1+1)")
end
Maybe it would be a good idea to extract the Drab core (so functions execjs and broadcastjs) and treat jquery/DOM part as a kind of a plugin? Thus you could build your own non-DOM add-on, like helper functions for React or whatever you want
use Drab.Commander, plugins: [Drab.Query, Drab.Call]