diff options
| author | Sébastien Dailly <sebastien@chimrod.com> | 2021-02-24 20:51:43 +0100 | 
|---|---|---|
| committer | Sébastien Dailly <sebastien@dailly.me> | 2022-02-07 16:43:33 +0100 | 
| commit | 3f5e3dd53755dd67c24721afc62e32d2187e3583 (patch) | |
| tree | 16d4e694a1adeb83abcaea12da8fb0a16a11ed00 /editor/editor.ml | |
| parent | 274789e733c46e7e20fc1dc918a7251b0206b3d2 (diff) | |
Update editor code
Diffstat (limited to 'editor/editor.ml')
| -rwxr-xr-x | editor/editor.ml | 164 | 
1 files changed, 63 insertions, 101 deletions
diff --git a/editor/editor.ml b/editor/editor.ml index d32288c..5aecef0 100755 --- a/editor/editor.ml +++ b/editor/editor.ml @@ -2,72 +2,6 @@ open Js_of_ocaml  open Brr  module PM = Prosemirror -let change_level -  : PM.t -> PM.Model.resolved_pos Js.t -> int -> (int -> bool) -> PM.State.command -  = fun pm res incr pred state dispatch -> -    let parent = res##.parent in -    let attributes = parent##.attrs in - -    let current_level = if Jv.is_none attributes##.level then -        0 -      else -        attributes##.level in -    let t, props = match pred current_level with -      | false -> -        (PM.O.get state##.schema##.nodes "heading" -        , (object%js -          val level = current_level + incr -        end :> < > Js.t )) -      | true -> -        ( PM.O.get state##.schema##.nodes "paragraph" -        , object%js end) in -    match t with -    | None -> Js._false -    | Some t -> -      PM.Commands.set_block_type pm t props state dispatch - -(** Increase the title level by one when pressing # at the begining of a line *) -let handle_sharp pm state dispatch = - -  let res = PM.State.selection_to (state##.selection) in -  match Js.Opt.to_option res##.nodeBefore with -  | Some _ -> Js._false -  | None -> (* Line start *) -    begin match Jstr.to_string res##.parent##._type##.name with -      | "heading"   -> change_level pm res 1 (fun x -> x > 5) state dispatch -      | "paragraph" -> change_level pm res 1 (fun _ -> false) state dispatch -      | _ -> Js._false -    end - -let handle_backspace pm state dispatch = - -  let res = PM.State.selection_to (state##.selection) in -  match Js.Opt.to_option res##.nodeBefore with -  | Some _ -> Js._false -  | None -> (* Line start *) -    begin match Jstr.to_string res##.parent##._type##.name with -      | "heading" -> change_level pm res (-1) (fun x -> x <= 1) state dispatch -      | _ -> Js._false -    end - -let default_plugins pm schema = - -  let props = PM.Example.options schema in -  props##.menuBar := Js.some Js._true; -  props##.floatingMenu := Js.some Js._true; -  let setup = PM.Example.example_setup pm props in - -  let keymaps = -    PM.Keymap.keymap pm -      [| "Backspace", (handle_backspace pm) -       ; "#", (handle_sharp pm) -      |] in - -  (* Add the custom keymaps in the list *) -  let _ = setup##unshift keymaps in - -  Js.some setup -  let create_new_state pm mySchema content =    let module PM = Prosemirror in @@ -78,13 +12,45 @@ let create_new_state pm mySchema content =    let props = PM.State.creation_prop () in    props##.doc := Js.some doc; -  props##.plugins := default_plugins pm mySchema; +  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 -> @@ -100,61 +66,57 @@ let prosemirror id content =               (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 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 mySchema content -        | Some contents -> -          (* Try to load from the storage *) -          begin match Json.decode contents with -            | Error _ -> create_new_state pm mySchema content -            | Ok json -> -              Console.(log [Jstr.v "Loading json"]); - -              let history = PM.History.(history pm (history_prop ()) ) in -              let _ = history in - -              let obj = PM.State.configuration_prop () in -              obj##.plugins := default_plugins pm mySchema; -              obj##.schema := Js.some mySchema; -              PM.State.fromJSON pm obj json -          end -      in +      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 _out_event = Brr_note.Evr.on_el +      let _ = 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:() +(* +             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])  | 
