mithril.js icon indicating copy to clipboard operation
mithril.js copied to clipboard

Add a special vnode that allows manipulating attributes on a raw event target reference

Open dead-claudia opened this issue 4 years ago • 2 comments
trafficstars

Mithril version:

Platform and OS:

Project:

Is this something you're interested in implementing yourself? Yes

Description

We should add a special primitive, say m.link(value, {...}), that lets us simply set attributes on the element. Examples:

  • m.link(window, {onscroll() { ... }}) for scroll
  • m.link(document, {onmouseup() { ... }, onmousemove() { ... }}) for drag and drop
  • m.link(document, {title: ...})
  • m.link(window, {scrollX, scrollY})

The event handlers would of course autoredraw as existing Mithril-tracked event handlers do.

Why

I find myself so often wanting to mount and unmount event handlers within UI trees. This would make it such that I could just do it declaratively. It'd also provide a clean way to set the document's title and so on as well.

Edit: Here's a couple userland implementations of the events component of this.

It's actually surprisingly complex in practice to wire up, even for just events. This proposal suggests a superset, and in total would probably be at worst around the size of the full events implementation above.

Possible Implementation

  1. Add a condition to setAttr to avoid the setAttribute fallback and just always set the value for event targets that don't extend Node, and update removeAttr as appropriate as well.
  2. Add logic for the node to simply invoke setAttrs/removeAttrs as appropriate.
  3. The factory is obvious.

Open Questions

  • Should we even add this? It's pretty easy for us, and provides a large amount of functionality for very little cost, but of course it's also entirely doable in userland.
  • The name is kinda loaded. I thought of m.bind, but that's even worse, and I don't want some long, unwieldy name for this, either. I could totally use some more ideas in this department.

dead-claudia avatar May 05 '21 23:05 dead-claudia

what about just m(body, { ... }) 🙈

StephanHoyer avatar May 06 '21 06:05 StephanHoyer

I considered that, but I was hoping to avoid discussions on how children should be added/removed from existing nodes that are already live with potential children. Edit: I would be okay with opening up that prospect, though. (I could see React Helmet-like use cases for one. I could also see the value of adding inline style sheets linked to components, in effect using Mithril as a resource loader.)

dead-claudia avatar May 06 '21 16:05 dead-claudia