open Js_of_ocaml open Brr let create_new_state pm pm_model pm_state mySchema content = let module PM = Prosemirror in let doc = PM.Model.( DOMParser.parse (DOMParser.from_schema pm_model mySchema) (Jv.Id.of_jv content)) in let props = PM.State.creation_prop () in props##.doc := Js.some doc; props##.plugins := Js.some (PM.example_setup pm mySchema); PM.State.create pm_state props let storage_key = (Jstr.v "editor") 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 ( let+ ) o f = Option.iter f o and ( and+ ) a b = match a, b with | Some a, Some b -> Some (a, b) | _ -> None in let+ pm_state = J.get pm PM.state and+ pm_view = J.get pm PM.view and+ pm_model = J.get pm PM.model and+ schema_basic = J.get pm PM.schema_basic and+ schema_list = J.get pm PM.schema_list in let _ = schema_basic and _ = schema_list in let mySchema = Js_of_ocaml.Js.Unsafe.eval_string {|new PM.model.Schema({ nodes: PM.schema_list.addListNodes(PM.schema_basic.schema.spec.nodes, "paragraph block*", "block"), marks: PM.schema_basic.schema.spec.marks })|} in (* Create the initial state *) let storage = Brr_io.Storage.local G.window in let opt_data = Brr_io.Storage.get_item storage storage_key in let state = match opt_data with | None -> create_new_state pm pm_model pm_state mySchema content | Some contents -> (* Try to load from the storage *) begin match Json.decode contents with | Error _ -> create_new_state pm pm_model pm_state mySchema content | Ok json -> Console.(log [Jstr.v "Loading json"]); let history = PM.History.(history pm (history_prop ()) ) in Console.(log [history]); let _ = history in let obj = PM.State.configuration_prop () in obj##.plugins := Js.some (PM.example_setup pm mySchema); obj##.schema := mySchema; PM.State.fromJSON pm_state obj json end in let props = PM.View.direct_editor_props () in props##.dispatchTransaction := (Js.wrap_meth_callback (fun view transaction -> Console.(log [ Jstr.v "Document size went from" ; transaction##.before##.content##.size ]); let state = view##.state##apply transaction in view##updateState state )); props##.state := state; let view = PM.View.editor_view pm_view (Jv.Id.of_jv id) props in view##setProps props; (* Attach an event on focus out *) let _out_event = Brr_note.Evr.on_el (Ev.focusout) (fun _ -> 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:() ) (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