HeinrichApfelmus / threepenny-gui

GUI framework that uses the web browser as a display.
https://heinrichapfelmus.github.io/threepenny-gui/
Other
437 stars 77 forks source link

Access a JSObject events #179

Closed pepeiborra closed 6 years ago

pepeiborra commented 7 years ago

Threepenny exposes the events of JSObjects that correspond to DOM elements only. Is there a design reason for this ?

Currently all the primitives (fromJSObject, getEvents, addEvents) are private, as is the Window event vendor, so the only way to implement this properly from user land is to bolt a StateT on top of UI to carry a new event vendor.

If I'm missing something, please point me in the right direction.

HeinrichApfelmus commented 7 years ago

The reason for this is garbage collection. The Haskell side tries to keep track of all Element in the DOM tree, and garbage collects them and their event handlers when they are no longer reachable. Tracking lifetimes for DOM elements is reasonably straightforward, in that they are usually only manipulated from the Haskell side, for instance by using getElementById or by using the children property.

This heuristic does not work for general JSObject (e.g. a JavaScript canvas object), because they can and will be manipulated by many different functions.

Note that it is common for an event handler to keep its element alive, which in turn keeps the handler alive, i.e. it is common that we have a circular reference. The only way to handle this properly is to use the Haskell garbage collector, because JavaScript garbage collector are impoverished.

What is your particular use case? I'm open to suggestion on how to incorporate more objects besides DOM elements.

pepeiborra commented 7 years ago

I am writing a Threepenny binding to a JS data grid for my employer. The data grid is a JS object that exposes several methods and events, and I want to use the Haskell garbage collector to manage its lifetime.

HeinrichApfelmus commented 7 years ago

Ah, I see. A JS data grid sounds like it could be treated as part of the DOM tree, like an Element. I haven't thought about integrating things like this yet. You will probably have to roll your own by mimicking the private API and using Foreign.JavaScript directly.

pepeiborra commented 7 years ago

Something to make this a bit less painful would be the ability to add reachable js objects to a threepenny Element.

Would you consider this for a 0.8.0.1 release ? I can send a pull request later today.

HeinrichApfelmus commented 7 years ago

Sure, why not! (Though the PVP requires that adding a function increases the minor version number, so this would be a 0.8.1.0 release.)

HeinrichApfelmus commented 6 years ago

Has this issue been resolved / worked around to your satisfaction?

pepeiborra commented 6 years ago

Looks good. I might have more feedback when we get to integrate 0.8.1.0, but if that is the case I will follow up in a new issue.