@@ -24,8 +24,30 @@ let rec node_in_document node =
2424 node == (Dom_html. document :> Dom.node Js.t ) ||
2525 Js.Opt. case (node##.parentNode) (fun () -> false ) node_in_document
2626
27+ let age = ref 0
2728let watched = ref []
2829
30+ (* We remove watched elements after two unload events to avoid memory
31+ leaks due to elements that are never inserted in the page. *)
32+ let active = ref false
33+ let remove_from_dead_pages () =
34+ let rec loop () =
35+ Eliom_client. onunload @@ fun () ->
36+ let (live, dead) =
37+ List. partition (fun (age' , _ , _ ) -> ! age = age') ! watched in
38+ watched := live;
39+ incr age;
40+ List. iter (fun (_ , _ , s ) -> Lwt. wakeup s () ) dead;
41+ if ! watched = [] then
42+ active := false
43+ else
44+ loop ()
45+ in
46+ if not ! active then begin
47+ active := true ;
48+ loop ()
49+ end
50+
2951let handler records observer =
3052 let changes = ref false in
3153 for i = 0 to records##.length - 1 do
@@ -34,10 +56,10 @@ let handler records observer =
3456 done ;
3557 if ! changes then begin
3658 let (ready, not_ready) =
37- List. partition (fun (n , _ ) -> node_in_document n) ! watched in
59+ List. partition (fun (_ , n , _ ) -> node_in_document n) ! watched in
3860 watched := not_ready;
3961 if not_ready = [] then observer##disconnect ;
40- List. iter (fun (_ , s ) -> Lwt. wakeup s () ) ready
62+ List. iter (fun (_ , _ , s ) -> Lwt. wakeup s () ) ready
4163 end
4264
4365let observer =
@@ -54,6 +76,7 @@ let nodeready node =
5476 if node_in_document node then Lwt. return_unit else begin
5577 let t, s = Lwt. wait () in
5678 if ! watched = [] then observer##observe Dom_html. document config;
57- watched := (node, s) :: ! watched;
79+ watched := (! age, node, s) :: ! watched;
80+ remove_from_dead_pages () ;
5881 t
5982 end
0 commit comments