js_of_ocaml
js_of_ocaml copied to clipboard
Add mutation observers in Lwt_js_events
Hum, What is it ? Why ? How ? ^^'
https://developer.mozilla.org/fr/docs/Web/API/MutationObserver
Mutation events ( https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Mutation_events ) are marked as deprecated. This patch adds support of replacement. Looks like it will be required in the nearest future.
@johnlepikhin, is there a patch somewhere?
@balat, while it looks useful generally, do we have a concrete immediate application?
Also, would a React layer over this be of service?
An example of practical use is with Material Design Lite ( http://www.getmdl.io ). When you use this framework with dynamic DOM, you have to register new elements ( http://www.getmdl.io/started/index.html#dynamic and http://quaintous.com/2015/07/09/react-components-with-mdl/ ). A trick to do that is to use MutationObserver to automagically call the MDL javascript function upgradeDom ( https://github.com/google/material-design-lite/issues/917 ) :
var observer = new MutationObserver(function(mutations) {
var upgrade = false;
for (var i = 0; i < mutations.length; i++) {
if (mutations[i].addedNodes.length > 0) {
upgrade = true;
break;
}
}
if (upgrade) {
// If there is at least a new element, upgrade the DOM.
// Note: upgrading elements one by one seems to insert bugs in MDL
window.componentHandler.upgradeDom();
}
});
observer.observe(document, {
childList : true,
subtree : true
});
I'm using this for example with a reactive list of comments, when I want to keep it scrolled to the bottom.
Bs_lib.content_changes %d (fun mutations -> Bs_lib.scroll_to_bottom %d);
Another use: If you want to implement custom scrollbars (which is useful as braowser scrollbars are not customizable and horrible), you want the scrollbar position to get updated automatically when the contents change.
A basic implmentation of this is Lwt_js_events would be something like:
(* Content change observer: *)
let content_changes elt f =
let observer =
jsnew (Js.Unsafe.global##_MutationObserver)(Js.wrap_callback f)
in
observer##observe(To_dom.of_element elt,
Js.Unsafe.obj [|("childList", Js.Unsafe.inject Js._true);
("subtree", Js.Unsafe.inject Js._true)|]);
()
(Note that with a reactive implementation, it is difficult to scroll to the bottom without this ...)
mutationObserver.ml was added in 2016
It is still not in Lwt_js_events if I'm right.
I've now updated the title