aboutsummaryrefslogtreecommitdiff
path: root/editor/storage.ml
blob: 0d74a05e428d4659939854713a3c79d90824363c (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
open Brr
module PM = Prosemirror
module Js = Js_of_ocaml.Js

let storage_key = (Jstr.v "editor")

let storage = Brr_io.Storage.local G.window

let create_new_state pm mySchema content =
  let module PM = Prosemirror in

  let doc = PM.Model.(
      DOMParser.parse
        (DOMParser.from_schema pm mySchema)
        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 page_id
  : unit -> Jstr.t option
  = fun () ->
    let uri = Brr.Window.location Brr.G.window in
    let query = Brr.Uri.query uri in
    let params = Brr.Uri.Params.of_jstr query in
    Brr.Uri.Params.find (Jstr.v "page") params

(** [load' pm schema content key] will load the content stored in the local
    storage for the [key].
*)
let load'
  : PM.t -> PM.Model.schema Js.t -> El.t -> Jstr.t -> PM.State.editor_state Js.t
  = fun pm schema content key ->

    let opt_data = Brr_io.Storage.get_item 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

(** Save the view *)
let save'
  : PM.View.editor_view Js.t -> Jstr.t -> unit
  = fun view key ->
    let contents = view##.state##toJSON () in
    let storage = Brr_io.Storage.local G.window in
    Brr_io.Storage.set_item
      storage
      key
      (Json.encode @@ contents)
    |> Console.log_if_error ~use:()


(** [load pm schema content f] will try load the content stored in the local
    storage. The right key is given by the result of the function [f]
*)
let load
  : PM.t -> PM.Model.schema Js.t -> El.t -> (unit -> Jstr.t option) -> PM.State.editor_state Js.t
  = fun pm schema content f ->
    match f () with
    | None -> load' pm schema content storage_key
    | Some value ->
      let key = Jstr.concat
          ~sep:(Jstr.v "_")
          [storage_key ;  value] in
      load' pm schema content key

let save
  : PM.View.editor_view Js.t -> (unit -> Jstr.t option) -> unit
  = fun view f ->
    match f () with
    | None -> save' view storage_key
    | Some value ->
      let key = Jstr.concat
          ~sep:(Jstr.v "_")
          [storage_key ;  value] in
      save' view key

let delete
  : (unit -> Jstr.t option) -> unit
  = fun f ->
    match f () with
    | None -> ()
    | Some key ->
      let storage = Brr_io.Storage.local G.window in
      let () = Brr_io.Storage.remove_item storage key in
      (* Reload the page *)
      Brr.Window.reload G.window

let get_ids
  : unit -> Jstr.t list
  = fun () ->
    let open Brr_io in
    let storage = Storage.local G.window in
    let items = Storage.length storage in

    let sub = Jstr.( storage_key + (v "_") ) in
    let start = Jstr.length sub in

    let rec add_element acc = function
      | 0 -> acc
      | nb ->
        begin match Storage.key storage nb with
          | Some key when (Jstr.starts_with ~sub key) ->

            let key_name = Jstr.sub key
                ~start in
            add_element (key_name::acc) (nb -1)
          | _ -> add_element acc (nb -1)
        end

    in
    add_element [] items