summaryrefslogtreecommitdiff
path: root/editor/prosemirror
diff options
context:
space:
mode:
authorSébastien Dailly <sebastien@chimrod.com>2021-02-14 19:32:36 +0100
committerSébastien Dailly <sebastien@dailly.me>2022-02-07 16:43:33 +0100
commite612a344629b999e90089710646e7a0bc68597d2 (patch)
tree8670b44572b827d251d13b0a3a8d65cdc3ddfd78 /editor/prosemirror
parentf4a59ed2811d4dca2daad58d083078c01488dd11 (diff)
Update prosemirror
Diffstat (limited to 'editor/prosemirror')
-rwxr-xr-xeditor/prosemirror/bindings.ml262
-rwxr-xr-xeditor/prosemirror/prosemirror.ml116
-rwxr-xr-xeditor/prosemirror/prosemirror.mli56
3 files changed, 390 insertions, 44 deletions
diff --git a/editor/prosemirror/bindings.ml b/editor/prosemirror/bindings.ml
index 08db819..f6d4223 100755
--- a/editor/prosemirror/bindings.ml
+++ b/editor/prosemirror/bindings.ml
@@ -1,5 +1,47 @@
open Js_of_ocaml.Js
+module TypedObject : sig
+
+ type 'a t
+
+ val get
+ : 'a t -> Jv.prop -> 'a option
+
+ val get'
+ : 'a t -> Jv.prop' -> 'a option
+
+ val set
+ : 'a t -> Jv.prop -> 'a -> unit
+
+ val set'
+ : 'a t -> Jv.prop' -> 'a -> unit
+
+end = struct
+
+ type 'a t = Jv.t
+
+ let get
+ : 'a t -> Jv.prop -> 'a
+ = fun t prop ->
+ Jv.to_option Jv.Id.of_jv (Jv.get t prop)
+
+ let get'
+ : 'a t -> Jv.prop' -> 'a
+ = fun t prop ->
+ Jv.to_option Jv.Id.of_jv (Jv.get' t prop)
+
+ let set
+ : 'a t -> Jv.prop -> 'a -> unit
+ = fun o prop v ->
+ Jv.set o prop (Jv.Id.to_jv v)
+
+ let set'
+ : 'a t -> Jv.prop' -> 'a -> unit
+ = fun o prop v ->
+ Jv.set' o prop (Jv.Id.to_jv v)
+
+end
+
class type ['a] ordered_map = object ('this)
method get:
@@ -21,63 +63,131 @@ end
module Model = struct
+ type domOutputSpec
+
+ class type _node_props = object ('this)
+
+ method inlineContent:
+ bool readonly_prop
+ (** True if this node type has inline content. *)
+
+ method isBlock:
+ bool readonly_prop
+
+ method isText:
+ bool readonly_prop
+
+ method isInline:
+ bool readonly_prop
+
+ method isTextblock:
+ bool readonly_prop
+
+ method isLeaf:
+ bool readonly_prop
+
+ method isAtom:
+ bool readonly_prop
+
+ end
+
+
type mark
type node_spec
- type mark_spec
+ type content_match
- class type schema_spec = object ('this)
+ type slice
- method nodes:
- node_spec ordered_map t readonly_prop
+ class type resolved_pos = object ('this)
+
+ method pos:
+ int readonly_prop
+
+ method depth:
+ int readonly_prop
+
+ method parent:
+ node t readonly_prop
+
+ method doc:
+ node t readonly_prop
+
+ method node:
+ int -> node t meth
+
+ method index:
+ int -> int meth
+
+ method nodeAfter:
+ node t opt readonly_prop
+
+ method nodeBefore:
+ node t opt readonly_prop
method marks:
- mark_spec ordered_map t readonly_prop
+ unit -> mark t js_array t meth
- method topNode:
- Jstr.t opt readonly_prop
+ method sameParent:
+ 'this -> bool t meth
+ method max:
+ 'this -> 'this t meth
+
+ method min:
+ 'this -> 'this t meth
end
- class type schema = object ('this)
+ and mark_spec = object ('this)
- method spec:
- schema_spec t prop
+ method toDOM:
+ (node t -> domOutputSpec t) callback writeonly_prop
+
+ method inclusive:
+ bool t prop
+
+ method spanning:
+ bool t prop
end
- type content_match
+ and schema_spec = object ('this)
- type slice
+ method nodes:
+ node_spec ordered_map t readonly_prop
- class type _node_props = object ('this)
+ method marks:
+ mark_spec ordered_map t readonly_prop
- method inlineContent:
- bool readonly_prop
- (** True if this node type has inline content. *)
+ method topNode:
+ Jstr.t opt readonly_prop
- method isBlock:
- bool readonly_prop
+ end
- method isText:
- bool readonly_prop
+ and schema = object ('this)
- method isInline:
- bool readonly_prop
+ method spec:
+ schema_spec t prop
- method isTextblock:
- bool readonly_prop
+ method nodes:
+ node_type t TypedObject.t readonly_prop
- method isLeaf:
- bool readonly_prop
+ method marks:
+ mark_type t TypedObject.t readonly_prop
- method isAtom:
- bool readonly_prop
+ method typoNodeType:
+ node_type t readonly_prop
+
+ method text:
+ Jstr.t -> node t meth
+
+ method node:
+ Jstr.t -> < .. > t opt -> fragment t opt -> mark t js_array t opt -> node t meth
end
- class type node_type = object ('this)
+ and node_type = object ('this)
inherit _node_props
@@ -96,13 +206,30 @@ module Model = struct
method hasRequiredAttrs:
unit -> bool meth
+ method create_withFragment:
+ < .. > t -> fragment t opt -> mark t opt -> node t meth
+
end
- class type mark_type = object ('this)
+ (** Signature for MarkType class
+
+ https://prosemirror.net/docs/ref/#model.MarkType
+ *)
+ and mark_type = object ('this)
+
+ method name:
+ Jstr.t readonly_prop
+
+ method schema:
+ schema t readonly_prop
+
+ method spec:
+ mark_spec t readonly_prop
+
end
(** Common signature between fragment and node *)
- class type _element = object ('this)
+ and _element = object ('this)
method childCount:
int readonly_prop
@@ -164,16 +291,29 @@ module Model = struct
node_type t readonly_prop
method attrs:
- < .. > t readonly_prop
+ < .. > t prop
method content:
- fragment t readonly_prop
+ fragment t prop
+
+ method copy:
+ fragment t -> 'this t meth
+
+ method resolve:
+ int -> resolved_pos t meth
+
+ method nodeAt:
+ int -> 'this t opt meth
method marks:
mark t js_array t readonly_prop
method sameMarkupd:
node t -> bool meth
+
+ method text:
+ Jstr.t opt prop
+
end
end
@@ -219,6 +359,12 @@ module Transform = struct
method step:
step t -> 'this t meth
+ method insert:
+ int -> Model.node t -> 'this t meth
+
+ method replaceRangeWith:
+ int -> int -> Model.node t -> 'this t meth
+
end
end
@@ -244,12 +390,33 @@ module State = struct
class type selection = object ('this)
+ method from:
+ int readonly_prop
+
+ method _to:
+ int readonly_prop
+
method content:
unit -> Model.slice t meth
method replace:
transaction t -> Model.slice t -> unit meth
+ method replaceWith:
+ transaction t -> Model.node t -> unit meth
+
+ end
+
+ and text_selection = object ('this)
+
+ inherit selection
+
+ end
+
+ and node_selection = object ('this)
+
+ inherit selection
+
end
and transaction = object ('this)
@@ -295,12 +462,19 @@ module State = struct
method replaceSelection:
Model.slice t -> 'this t meth
+ method replaceSelectionWith:
+ Model.node t -> bool t -> 'this t meth
+
method selectionSet:
bool readonly_prop
method before:
Model.node t readonly_prop
+ method scrollIntoView :
+ unit -> 'this t meth
+
+
end
class type configuration_prop = object ('this)
@@ -398,6 +572,9 @@ module View = struct
method updateState:
State.editor_state t -> unit meth
+ method dispatch:
+ State.transaction t -> unit meth
+
end
end
@@ -464,3 +641,22 @@ module History = struct
end
end
+
+module Example = struct
+
+ class type options = object ('this)
+
+ method schema:
+ Model.schema t prop
+
+ method menuBar:
+ bool opt prop
+
+ method floatingMenu:
+ bool opt prop
+
+ method history:
+ bool opt prop
+
+ end
+end
diff --git a/editor/prosemirror/prosemirror.ml b/editor/prosemirror/prosemirror.ml
index c19abe0..e97fa9b 100755
--- a/editor/prosemirror/prosemirror.ml
+++ b/editor/prosemirror/prosemirror.ml
@@ -8,12 +8,15 @@ let v
= fun () ->
Jv.get Jv.global "PM"
+module O = Bindings.TypedObject
+
module Model = struct
include Bindings.Model
module DOMParser = struct
+
type parser = Jv.t
let from_schema
@@ -63,6 +66,46 @@ module Model = struct
Jv.get fragment "empty"
|> Jv.Id.of_jv
+ module Dom_output_spec = struct
+
+ let v
+ : ?attrs:< .. > -> string -> domOutputSpec Js.t list -> domOutputSpec Js.t
+ = fun ?attrs name elems ->
+
+ let elems = match attrs with
+ | None -> elems
+ | Some v -> Jv.Id.(of_jv @@ to_jv @@ v)::elems in
+
+ let elems = (Jv.Id.of_jv @@ Jv.of_string name)::elems in
+ (Jv.of_list Jv.Id.to_jv elems)
+ |> Jv.Id.to_jv
+ |> Jv.Id.of_jv
+
+ let hole
+ : domOutputSpec Js.t
+ = 0
+ |> Jv.Id.to_jv
+ |> Jv.Id.of_jv
+
+ let of_
+ : 'a -> domOutputSpec Js.t
+ = fun elem ->
+ elem
+ |> Jv.Id.to_jv
+ |> Jv.Id.of_jv
+
+ let of_el
+ : Brr.El.t -> domOutputSpec Js.t
+ = of_
+
+ let of_jstr
+ : Jstr.t -> domOutputSpec Js.t
+ = of_
+
+ let of_obj
+ : < dom: node Js.t Js.readonly_prop ; contentDOM : node Js.t Js.opt Js.readonly_prop > Js.t -> domOutputSpec Js.t
+ = of_
+ end
end
module State = struct
@@ -92,6 +135,47 @@ module State = struct
let editor_state = Jv.get state "EditorState" in
Jv.call editor_state "fromJSON" [|Jv.Id.to_jv config ; json |]
|> Jv.Id.of_jv
+
+ let selection_to
+ : selection Js.t -> Model.resolved_pos Js.t
+ = fun selection ->
+ Jv.Id.(of_jv @@ Jv.get (to_jv selection) "$to")
+
+ let node_selection
+ : t -> Model.resolved_pos Js.t -> node_selection Js.t
+ = fun t pos ->
+ let state = Jv.get t "state" in
+ Jv.new' (Jv.get state "NodeSelection") [| Jv.Id.to_jv pos |]
+ |> Jv.Id.of_jv
+
+ let is_selectable
+ : t -> Model.node Js.t -> bool Js.t
+ = fun t node ->
+ let selection = Jv.get (Jv.get t "state") "NodeSelection" in
+ Jv.call selection "isSelectable" [|Jv.Id.to_jv node|]
+ |> Jv.Id.of_jv
+
+ let selection_at_start
+ : t-> Model.node Js.t -> selection Js.t
+ = fun t node ->
+ let selection = Jv.get (Jv.get t "state") "NodeSelection" in
+ Jv.call selection "atStart" [|Jv.Id.to_jv node|]
+ |> Jv.Id.of_jv
+
+
+ let create_node_selection
+ : t -> Model.node Js.t -> int -> node_selection Js.t
+ = fun t doc number ->
+ let state = Jv.get t "state" in
+ Jv.call (Jv.get state "NodeSelection") "create" Jv.Id.[|to_jv doc; Jv.of_int number|]
+ |> Jv.Id.of_jv
+
+ let create_text_selection
+ : t -> Model.node Js.t -> int -> node_selection Js.t
+ = fun t doc number ->
+ let state = Jv.get t "state" in
+ Jv.call (Jv.get state "TextSelection") "create" Jv.Id.[|to_jv doc; Jv.of_int number|]
+ |> Jv.Id.of_jv
end
(* Editor view *)
@@ -142,6 +226,12 @@ module SchemaBasic = struct
Jv.get (Jv.get t "schema_basic") "schema"
|> Jv.Id.of_jv
+ let nodes
+ : t -> nodes Js.t
+ = fun t ->
+ Jv.get (Jv.get t "schema_basic") "nodes"
+ |> Jv.Id.of_jv
+
end
module History = struct
@@ -174,7 +264,7 @@ end
module Keymap = struct
let keymap
- : t -> (string * (State.editor_state Js.t -> (State.transaction -> unit) -> bool)) array -> State.plugin Js.t
+ : t -> (string * (State.editor_state Js.t -> (State.transaction Js.t -> unit) -> bool)) array -> State.plugin Js.t
= fun t props ->
let props = Jv.obj @@ Array.map (fun (id, f) -> (id, Jv.repr f)) props in
Jv.call (Jv.get t "keymap") "keymap" [|props|]
@@ -194,10 +284,20 @@ end
(* Example Setup *)
-let example_setup
- : t -> Model.schema Js.t -> State.plugin Js.t Js.js_array Js.t
- = fun t schema ->
- let setup = Jv.get t "example_setup" in
- let props = Jv.obj [|("schema", Jv.Id.to_jv schema)|] in
- Jv.call setup "exampleSetup" [|props|]
- |> Jv.Id.of_jv
+module Example = struct
+
+ include Bindings.Example
+
+ let options
+ : Model.schema Js.t -> options Js.t
+ = fun schema ->
+ Jv.obj [|("schema", Jv.Id.to_jv schema)|]
+ |> Jv.Id.of_jv
+
+ let example_setup
+ : t -> options Js.t -> State.plugin Js.t Js.js_array Js.t
+ = fun t options ->
+ let setup = Jv.get t "example_setup" in
+ Jv.call setup "exampleSetup" [|Jv.Id.to_jv options|]
+ |> Jv.Id.of_jv
+end
diff --git a/editor/prosemirror/prosemirror.mli b/editor/prosemirror/prosemirror.mli
index aa27bf4..a4c5d35 100755
--- a/editor/prosemirror/prosemirror.mli
+++ b/editor/prosemirror/prosemirror.mli
@@ -6,6 +6,8 @@ type t
val v
: unit -> t
+module O = Bindings.TypedObject
+
module rec Model : sig
include module type of Bindings.Model
@@ -34,6 +36,24 @@ module rec Model : sig
val empty_fragment
: t -> fragment Js.t
+ module Dom_output_spec : sig
+
+ val v
+ : ?attrs:< .. > -> string -> domOutputSpec Js.t list -> domOutputSpec Js.t
+
+ (** Hole element inside an output_spec element *)
+ val hole
+ : domOutputSpec Js.t
+
+ val of_el
+ : Brr.El.t -> domOutputSpec Js.t
+
+ val of_jstr
+ : Jstr.t -> domOutputSpec Js.t
+
+ val of_obj
+ : < dom: node Js.t Js.readonly_prop ; contentDOM : node Js.t Js.opt Js.readonly_prop > Js.t -> domOutputSpec Js.t
+ end
end
@@ -62,6 +82,24 @@ and State : sig
val fromJSON
: t -> configuration_prop Js.t -> Brr.Json.t -> editor_state Js.t
+ val selection_to
+ : selection Js.t -> Model.resolved_pos Js.t
+
+ val selection_at_start
+ : t-> Model.node Js.t -> selection Js.t
+
+ val is_selectable
+ : t -> Model.node Js.t -> bool Js.t
+
+ val node_selection
+ : t -> Model.resolved_pos Js.t -> node_selection Js.t
+
+ val create_node_selection
+ : t -> Model.node Js.t -> int -> node_selection Js.t
+
+ val create_text_selection
+ : t -> Model.node Js.t -> int -> text_selection Js.t
+
end
(* Editor view *)
@@ -91,6 +129,10 @@ module SchemaBasic : sig
val schema
: t -> Model.schema Js.t
+ val nodes
+ : t -> nodes Js.t
+
+
end
module History : sig
@@ -113,7 +155,7 @@ end
module Keymap : sig
val keymap
- : t -> (string * (State.editor_state Js.t -> (State.transaction -> unit) -> bool)) array -> State.plugin Js.t
+ : t -> (string * (State.editor_state Js.t -> (State.transaction Js.t -> unit) -> bool)) array -> State.plugin Js.t
end
@@ -126,5 +168,13 @@ end
(* Example Setup *)
-val example_setup
- : t -> Model.schema Js.t -> State.plugin Js.t Js.js_array Js.t
+module Example : sig
+
+ include module type of Bindings.Example
+
+ val options
+ : Model.schema Js.t -> options Js.t
+
+ val example_setup
+ : t -> options Js.t -> State.plugin Js.t Js.js_array Js.t
+end