Last active
June 24, 2017 10:09
-
-
Save dmitriid/4b8c787cbcad910ddf5443e675fcea5b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type any = Js.t {.}; | |
type key = | |
| String string | |
| Int int; | |
type hero = {id: string}; | |
type attach_data = Js.t {. placeholder : option any, real : option string}; /* TODO */ | |
type vnode = { | |
sel: option string, | |
data: option vnode_data, | |
children: option (list vnode), | |
text: option string, | |
elm: option string, | |
key: option key | |
} | |
and vnode_data = { | |
props: option any, | |
attrs: option any, | |
classes: option (list any), | |
style: option (list any), | |
dataset: option any, | |
on: option any, | |
hero: option hero, | |
attach_data: option attach_data, | |
hook: hooks, | |
key: option key, | |
ns: option string, | |
fn: option (unit => vnode), | |
args: option (list any) | |
} | |
and hooks = { | |
pre: option pre_hook, | |
init: option init_hook, | |
create: option create_hook, | |
insert: option insert_hook, | |
prepatch: option prepatch_hook, | |
update: option update_hook, | |
postpatch: option postpatch_hook, | |
destroy: option destroy_hook, | |
remove: option remove_hook, | |
post: option post_hook | |
} | |
and pre_hook = unit => any | |
and init_hook = vnode => any | |
and create_hook = vnode => vnode => any | |
and insert_hook = vnode => any | |
and prepatch_hook = vnode => vnode => any | |
and update_hook = vnode => vnode => any | |
and postpatch_hook = vnode => vnode => any | |
and destroy_hook = vnode => any | |
and remove_hook = vnode => (unit => unit) => any | |
and post_hook = unit => any; | |
type vnode_queue = list vnode; | |
/*module type VNode = { | |
let vnode: | |
option string => | |
option vnode_data => | |
option (list vnode) => | |
option string => | |
option string => | |
vnode; | |
}; | |
module VNode: VNode = { | |
let vnode sel (data: option vnode_data) children text elm => { | |
let key = | |
switch data { | |
| None => None | |
| Some data => data.key | |
}; | |
{sel, data, children, text, elm, key} | |
}; | |
}; | |
*/ | |
open ReasonJs.Dom; | |
let map f => | |
fun | |
| Some v => Some (f v) | |
| None => None; | |
let andThen (f: 'a => option 'b) => | |
fun | |
| Some v => f v | |
| None => None; | |
let unwrapUnsafely = | |
fun | |
| Some v => v | |
| None => raise (Invalid_argument "Passed `None` to unwrapUnsafely"); | |
module Snabbdom = { | |
let vnode | |
sel::(sel: option string)=? | |
data::(data: option vnode_data)=? | |
children::(children: option (list vnode))=? | |
text::(text: option string)=? | |
elm::(elm: option string)=? | |
() => { | |
sel, | |
data, | |
children, | |
text, | |
elm, | |
key: None | |
}; | |
let rec create_elm vnode :option Dom.element => | |
switch vnode.sel { | |
| None => None | |
| Some sel => | |
Some (document |> Document.createElement sel |> createTextNode vnode |> createChildren vnode) | |
} | |
and createTextNode vnode (elm: ReasonJs.Dom.Element.t) => | |
switch vnode.text { | |
| None => elm | |
| Some text => | |
Element.setInnerText elm text; | |
elm | |
} | |
and createChildren vnode (elm: ReasonJs.Dom.Element.t) => | |
switch vnode.children { | |
| None => elm | |
| Some children => | |
let append child => elm |> Element.appendChild (create_elm child |> unwrapUnsafely); | |
List.iter append children; | |
elm | |
}; | |
}; | |
let flushToDOM v => { | |
let elm = Snabbdom.create_elm v; | |
let unwrapped = elm |> unwrapUnsafely; | |
document |> Document.asHtmlDocument |> andThen HtmlDocument.body |> | |
map (Element.appendChild unwrapped) | |
}; | |
flushToDOM (Snabbdom.vnode sel::"div" text::"woot" ()); | |
flushToDOM (Snabbdom.vnode sel::"div" text::"woot1" ()); | |
flushToDOM (Snabbdom.vnode sel::"div" text::"woot2" ()); | |
flushToDOM (Snabbdom.vnode sel::"div" text::"woot3" ()); | |
flushToDOM (Snabbdom.vnode sel::"div" text::"woot4" ()); | |
let z = Snabbdom.vnode sel::"div" text::"z" (); | |
flushToDOM (Snabbdom.vnode sel::"div" text::"woot5" children::[z, z, z] ()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment