From 3f5e3dd53755dd67c24721afc62e32d2187e3583 Mon Sep 17 00:00:00 2001 From: Sébastien Dailly Date: Wed, 24 Feb 2021 20:51:43 +0100 Subject: Update editor code --- editor/editor.ml | 164 +++++++++++++++++++++---------------------------------- 1 file changed, 63 insertions(+), 101 deletions(-) (limited to 'editor/editor.ml') 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]) -- cgit v1.2.3