blob: 5aecef0de1d3818e39bfde7e20263ddc0371ad26 (
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
open Js_of_ocaml
open Brr
module PM = Prosemirror
let create_new_state pm mySchema content =
let module PM = Prosemirror in
let doc = PM.Model.(
DOMParser.parse
(DOMParser.from_schema pm mySchema)
(Jv.Id.of_jv content)) in
let props = PM.State.creation_prop () in
props##.doc := Js.some doc;
props##.plugins := Plugins.default pm mySchema;
PM.State.create
pm
props
let storage_key = (Jstr.v "editor")
let storage = Brr_io.Storage.local G.window
(** Read the state from the local storage, or load the content from the given
element *)
let load_storage
: PM.t -> PM.Model.schema Js.t -> Jv.t -> PM.State.editor_state Js.t
= fun pm schema content ->
let opt_data = Brr_io.Storage.get_item storage storage_key in
match opt_data with
| None -> create_new_state pm schema content
| Some contents ->
(* Try to load from the storage *)
match Json.decode contents with
| Error _ -> create_new_state pm schema content
| Ok json ->
let obj = PM.State.configuration_prop () in
obj##.plugins := Plugins.default pm schema;
obj##.schema := Js.some schema;
PM.State.fromJSON pm obj json
let save_storage
: PM.View.editor_view Js.t -> unit
= fun view ->
let contents = view##.state##toJSON () in
let storage = Brr_io.Storage.local G.window in
Brr_io.Storage.set_item
storage
storage_key
(Json.encode @@ contents)
|> Console.log_if_error ~use:()
let prosemirror id content =
begin match (Jv.is_none id), (Jv.is_none content) with
| false, false ->
let module PM = Prosemirror in
let pm = PM.v () in
let specs = PM.Model.schema_spec
(PM.SchemaList.add_list_nodes
pm
((PM.SchemaBasic.schema pm)##.spec##.nodes)
(Jstr.v "paragraph block*")
(Some (Jstr.v "block")))
(Some (PM.SchemaBasic.schema pm)##.spec##.marks)
None in
let mySchema = PM.Model.schema pm specs in
(* Create the initial state *)
let state = load_storage pm mySchema content in
let props = PM.View.direct_editor_props () in
props##.state := state;
(* Each time the state is update, handle the copy *)
props##.dispatchTransaction := Js.wrap_meth_callback @@ (fun view tr ->
let state = view##.state##apply tr in
view##updateState state
);
let view = PM.View.editor_view
pm
(Jv.Id.of_jv id)
props in
view##setProps props;
(* Attach an event on focus out *)
let _ = Brr_note.Evr.on_el
(Ev.focusout)
(fun _ ->
(*
let props = view##.props in
props##.editable := Js.wrap_callback (fun _ -> Js._false);
view##update props;
*)
save_storage view
)
(Jv.Id.of_jv id) in
(*
let default_editable = view##.props##.editable in
let _ = Brr_note.Evr.on_el
(Ev.dblclick)
(fun e ->
let target = Ev.target e in
let (el:El.t) = Jv.Id.(of_jv @@ to_jv target) in
if (view##.editable == Js._false && (El.tag_name el <> Jstr.v "a")) then (
let props = view##.props in
props##.editable := default_editable;
view##update props;
Console.(log [el]);
El.set_has_focus true (Jv.Id.of_jv id);
)
)
(Jv.Id.of_jv id) in
*)
()
| _, _-> Console.(error [str "No element with id '%s' '%s' found"; id ; content])
end
let () =
let open Jv in
let editor = obj
[| "attach_prosemirror", (repr prosemirror)
|] in
set global "editor" editor
|