blob: 63dcad17c4e43e67712a43c6224f78b5a828386c (
plain)
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
open Brr
module Js = Js_of_ocaml.Js
module PM = Prosemirror
type binded_field =
{ field: El.t
; button: El.t
}
(** Set the element position just above the selection *)
let set_position
: start:int -> end':int -> PM.View.editor_view Js.t -> El.t -> unit
= fun ~start ~end' view el ->
El.set_inline_style El.Style.display (Jstr.v "") el;
(* These are in screen coordinates *)
let start = view##coordsAtPos start Js.null
and end' = view##coordsAtPos end' Js.null in
let offsetParent = Jv.(Id.of_jv @@ get (Jv.Id.to_jv el) "offsetParent") in
(* The box in which the tooltip is positioned, to use as base *)
let box = Jv.(Id.of_jv @@ call (Jv.Id.to_jv offsetParent) "getBoundingClientRect" [||]) in
let box_left = Jv.(Id.of_jv @@ get (Jv.Id.to_jv box) "left") in
let box_bottom = Jv.(Id.of_jv @@ get (Jv.Id.to_jv box) "bottom") in
(* Find a center-ish x position from the selection endpoints (when
crossing lines, end may be more to the left) *)
let left = (start##.left +. end'##.left) /. 2. in
El.set_inline_style (Jstr.v "left")
Jstr.( (of_float ( left -. box_left )) + (v "px") )
el;
El.set_inline_style (Jstr.v "bottom")
Jstr.( (of_float ( box_bottom -. start##.top )) + (v "px") )
el
(** Build a button which allow to activate or desactivate the given Element.
The function f is called when the user validate the input.
*)
let build_field
: El.t -> (Jstr.t -> bool) -> binded_field
= fun field f ->
let button_content =
[ El.i []
~at:At.[ class' (Jstr.v "fas")
; class' (Jstr.v "fa-pen") ]
] in
let button = El.button
button_content
in
Ev.listen Ev.click
(fun _ ->
match El.at (Jstr.v "contenteditable") field with
| Some value when (Jstr.equal value (Jstr.v "true")) ->
let new_value = El.prop
(El.Prop.jstr (Jstr.v "textContent"))
field in
begin match f new_value with
| true ->
El.set_at (Jstr.v "contenteditable") None field;
El.set_children button button_content
| false -> ()
end
| _ ->
El.set_at (Jstr.v "contenteditable")
(Some (Jstr.v "true")) field;
El.set_children button
[ El.i
~at:At.[ class' (Jstr.v "fas")
; class' (Jstr.v "fa-check") ]
[]
]
)
(El.as_target button);
{ field
; button = button
}
|