aboutsummaryrefslogtreecommitdiff
path: root/src/Dom
diff options
context:
space:
mode:
authorJoris2020-03-03 10:44:35 +0100
committerJoris2020-03-03 10:44:35 +0100
commit5c636f11cdfed82634ee572645d765b704941b68 (patch)
tree51e11a0cfbbab284985e98fcb558d2975209a9b2 /src/Dom
parenta2880850a78fc36e2612215c83cbdeac0c980a5b (diff)
downloadtabata-5c636f11cdfed82634ee572645d765b704941b68.tar.gz
tabata-5c636f11cdfed82634ee572645d765b704941b68.tar.bz2
tabata-5c636f11cdfed82634ee572645d765b704941b68.zip
Initialize views from JavaScript
Diffstat (limited to 'src/Dom')
-rw-r--r--src/Dom/CreateElement.ml72
-rw-r--r--src/Dom/Document.ml14
-rw-r--r--src/Dom/Element.ml32
-rw-r--r--src/Dom/EventTarget.ml5
4 files changed, 119 insertions, 4 deletions
diff --git a/src/Dom/CreateElement.ml b/src/Dom/CreateElement.ml
new file mode 100644
index 0000000..8183a02
--- /dev/null
+++ b/src/Dom/CreateElement.ml
@@ -0,0 +1,72 @@
+(* Element creation *)
+
+let h tag ?(attributes = [||]) ?(eventListeners = [||]) ?(children = [||]) () :
+ Dom.element =
+ let element =
+ if tag == "svg" || tag == "path" then
+ Document.createElementNS "http://www.w3.org/2000/svg" tag
+ else Document.createElement tag
+ in
+ let () =
+ Js.Array.forEach
+ (fun (name, value) -> Element.setAttribute element name value)
+ attributes
+ in
+ let () =
+ Js.Array.forEach
+ (fun (name, eventListener) ->
+ Element.addEventListener element name eventListener)
+ eventListeners
+ in
+ let () =
+ Js.Array.forEach (fun child -> Element.appendChild element child) children
+ in
+ element
+
+(* Node creation *)
+
+let text = Document.createTextNode
+
+let div = h "div"
+
+let span = h "span"
+
+let header = h "header"
+
+let button = h "button"
+
+let section = h "section"
+
+let svg = h "svg"
+
+let path = h "path"
+
+let form = h "form"
+
+let label = h "label"
+
+let input_ = h "input"
+
+(* Attribute creation *)
+
+let id v = ("id", v)
+
+let className v = ("class", v)
+
+let viewBox v = ("viewBox", v)
+
+let d v = ("d", v)
+
+let type_ v = ("type", v)
+
+let min_ v = ("min", v)
+
+let value v = ("value", v)
+
+(* Event listeners *)
+
+let onClick f = ("click", f)
+
+let onInput f = ("input", f)
+
+let onSubmit f = ("submit", f)
diff --git a/src/Dom/Document.ml b/src/Dom/Document.ml
index afd1a84..867e28c 100644
--- a/src/Dom/Document.ml
+++ b/src/Dom/Document.ml
@@ -1,4 +1,14 @@
-external querySelector : string -> Dom.element option = "querySelector"
+external createElement : string -> Dom.element = "createElement"
[@@bs.val] [@@bs.scope "document"]
-let querySelectorUnsafe id = querySelector id |> Js.Option.getExn
+external createElementNS : string -> string -> Dom.element = "createElementNS"
+ [@@bs.val] [@@bs.scope "document"]
+
+external querySelector : string -> Dom.element Js.Nullable.t = "querySelector"
+ [@@bs.val] [@@bs.scope "document"]
+
+let querySelectorUnsafe id =
+ querySelector id |> Js.Nullable.toOption |> Js.Option.getExn
+
+external createTextNode : string -> Dom.element = "createTextNode"
+ [@@bs.val] [@@bs.scope "document"]
diff --git a/src/Dom/Element.ml b/src/Dom/Element.ml
index 4b38fa9..0b6c0bd 100644
--- a/src/Dom/Element.ml
+++ b/src/Dom/Element.ml
@@ -1,14 +1,44 @@
external setValue : Dom.element -> string -> unit = "value" [@@bs.set]
-external setInnerText : Dom.element -> string -> unit = "innerText" [@@bs.set]
+external setTextContent : Dom.element -> string -> unit = "textContent"
+ [@@bs.set]
external setStyle : Dom.element -> string -> unit = "style" [@@bs.set]
external setClassName : Dom.element -> string -> unit = "className" [@@bs.set]
+external setScrollTop : Dom.element -> int -> unit = "scrollTop" [@@bs.set]
+
external setAttribute : Dom.element -> string -> string -> unit = "setAttribute"
[@@bs.send]
+external setAttributeNS : Dom.element -> string -> string -> string -> unit
+ = "setAttributeNS"
+ [@@bs.send]
+
external addEventListener : Dom.element -> string -> (Dom.event -> unit) -> unit
= "addEventListener"
[@@bs.send]
+
+external appendChild : Dom.element -> Dom.element -> unit = "appendChild"
+ [@@bs.send]
+
+external firstChild : Dom.element -> Dom.element Js.Nullable.t = "firstChild"
+ [@@bs.get]
+
+external removeChild : Dom.element -> Dom.element -> unit = "removeChild"
+ [@@bs.send]
+
+let removeFirstChild element =
+ match Js.toOption (firstChild element) with
+ | Some child ->
+ let () = removeChild element child in
+ true
+ | _ -> false
+
+let rec removeChildren element =
+ if removeFirstChild element then removeChildren element else ()
+
+let mountOn base element =
+ let () = removeChildren base in
+ appendChild base element
diff --git a/src/Dom/EventTarget.ml b/src/Dom/EventTarget.ml
index 946a518..d1b0c02 100644
--- a/src/Dom/EventTarget.ml
+++ b/src/Dom/EventTarget.ml
@@ -1 +1,4 @@
-external value : Dom.eventTarget -> string option = "value" [@@bs.get]
+external nullableValue : Dom.eventTarget -> string Js.Nullable.t = "value"
+ [@@bs.get]
+
+let value eventTarget = nullableValue eventTarget |> Js.Nullable.toOption