aboutsummaryrefslogtreecommitdiff
path: root/editor/editor.ml
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