1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
open Base
open Js_of_ocaml
include Ui_effect
let visibility_handlers : (unit -> unit) list ref = ref []
module type Visibility_handler = sig
val handle : unit -> unit
end
module Define_visibility (VH : Visibility_handler) = struct
let () = visibility_handlers := VH.handle :: !visibility_handlers
end
type _ t +=
| Viewport_changed
| Stop_propagation
| Stop_immediate_propagation
| Prevent_default
let sequence_as_sibling left ~unless_stopped =
let rec contains_stop = function
| Many es -> List.exists es ~f:contains_stop
| Stop_immediate_propagation -> true
| _ -> false
in
if contains_stop left then left else Ui_effect.Many [ left; unless_stopped () ]
;;
let current_dom_event = ref None
let () =
Hashtbl.add_exn
Expert.handlers
~key:Stdlib.Obj.Extension_constructor.(id (of_val Viewport_changed))
~data:(fun _ -> List.iter !visibility_handlers ~f:(fun f -> f ()))
;;
let () =
Hashtbl.add_exn
Expert.handlers
~key:Stdlib.Obj.Extension_constructor.(id (of_val Stop_propagation))
~data:(fun _ -> Option.iter !current_dom_event ~f:Dom_html.stopPropagation)
;;
let () =
Hashtbl.add_exn
Expert.handlers
~key:Stdlib.Obj.Extension_constructor.(id (of_val Prevent_default))
~data:(fun _ -> Option.iter !current_dom_event ~f:Dom.preventDefault)
;;
module Expert = struct
let handle_non_dom_event_exn = Expert.handle
let handle dom_event event =
let old = !current_dom_event in
current_dom_event := Some (dom_event :> Dom_html.element Dom.event Js.t);
Expert.handle event;
current_dom_event := old
;;
end