added support for all HTML5 tags and drag&drop events
This commit is contained in:
parent
21bb6a0311
commit
be0f9c9e08
3 changed files with 85 additions and 32 deletions
|
|
@ -9,6 +9,7 @@ var
|
|||
type
|
||||
ComponentKind* {.pure.} = enum
|
||||
None,
|
||||
Tag,
|
||||
VNode,
|
||||
Node
|
||||
|
||||
|
|
@ -18,6 +19,17 @@ var
|
|||
proc isComponent*(x: string): ComponentKind {.compileTime.} =
|
||||
allcomponents.getOrDefault(x)
|
||||
|
||||
proc addTags() {.compileTime.} =
|
||||
let x = (bindSym"VNodeKind").getTypeImpl
|
||||
expectKind(x, nnkEnumTy)
|
||||
for i in ord(VNodeKind.html)..ord(VNodeKind.high):
|
||||
# +1 because of empty node at the start of the enum AST:
|
||||
let tag = $x[i+1]
|
||||
allcomponents[tag] = ComponentKind.Tag
|
||||
|
||||
static:
|
||||
addTags()
|
||||
|
||||
proc unpack(symbolicType: NimNode; index: int): NimNode {.compileTime.} =
|
||||
#let t = symbolicType.getTypeImpl
|
||||
let t = repr(symbolicType)
|
||||
|
|
|
|||
|
|
@ -111,7 +111,6 @@ proc same(n: VNode, e: Node): bool =
|
|||
|
||||
var
|
||||
dorender: proc (): VNode {.closure.}
|
||||
drawTimeout: Timeout
|
||||
currentTree: VNode
|
||||
|
||||
proc setRenderer*(renderer: proc (): VNode) =
|
||||
|
|
@ -125,9 +124,8 @@ proc getElementById*(id: cstring): Element {.importc: "document.getElementById",
|
|||
|
||||
#proc getElementsByClassName*(cls: cstring): seq[Element] {.importc:
|
||||
# "document.getElementsByClassName", nodecl.}
|
||||
|
||||
proc textContent(e: Node): cstring {.
|
||||
importcpp: "#.textContent", nodecl.}
|
||||
#proc textContent(e: Node): cstring {.
|
||||
# importcpp: "#.textContent", nodecl.}
|
||||
|
||||
proc replaceById(id: cstring; newTree: Node) =
|
||||
let x = document.getElementById(id)
|
||||
|
|
@ -215,6 +213,8 @@ proc updateElement(parent, current: Node, newNode, oldNode: VNode) =
|
|||
for i in 0..oldPos-pos:
|
||||
current.removeChild(current.childNodes[pos])
|
||||
|
||||
when false:
|
||||
var drawTimeout: Timeout
|
||||
|
||||
proc dodraw() =
|
||||
let newtree = dorender()
|
||||
|
|
@ -316,9 +316,6 @@ proc setOnHashChange*(action: proc (hashPart: cstring)) =
|
|||
redraw()
|
||||
onhashchange = wrapper
|
||||
|
||||
proc getAttr(e: Node; key: cstring): cstring {.
|
||||
importcpp: "#.getAttribute(#)", nodecl.}
|
||||
|
||||
template nativeValue(ev): cstring = cast[Element](ev.target).value
|
||||
template setNativeValue(ev, val) = cast[Element](ev.target).value = val
|
||||
|
||||
|
|
|
|||
94
src/vdom.nim
94
src/vdom.nim
|
|
@ -1,37 +1,81 @@
|
|||
# Virtual DOM implementation
|
||||
## Virtual DOM implementation for Karax.
|
||||
|
||||
from dom import Event
|
||||
import shash
|
||||
import shash, macros
|
||||
from strutils import toUpperAscii
|
||||
|
||||
type
|
||||
VNodeKind* {.pure.} = enum
|
||||
text, int, bool, vthunk, dthunk,
|
||||
anchor,
|
||||
tdiv,
|
||||
table, tr, td, th, thead, tbody,
|
||||
link, span, label, br, select, option,
|
||||
fieldset, input, button, ul, li, section, header, footer,
|
||||
h1, h2, h3, h4, h5, strong
|
||||
text = "#text", int = "#int", bool = "#bool",
|
||||
vthunk = "#vthunk", dthunk = "#dthunk",
|
||||
|
||||
const
|
||||
toTag*: array[VNodeKind, cstring] = [
|
||||
cstring"#text", "#int", "#bool", "#vthunk", "#dthunk",
|
||||
"A", "DIV", "TABLE", "TR", "TD",
|
||||
"TH", "THEAD",
|
||||
"TBODY", "LINK",
|
||||
"SPAN", "LABEL", "BR", "SELECT", "OPTION", "FIELDSET", "INPUT", "BUTTON", "UL",
|
||||
"LI", "SECTION", "HEADER", "FOOTER", "H1", "H2", "H3", "H4", "H5", "STRONG"
|
||||
]
|
||||
html, head, title, base, link, meta, style,
|
||||
script, noscript,
|
||||
body, section, nav, article, aside,
|
||||
h1, h2, h3, h4, h5, h6,
|
||||
header, footer, address, main
|
||||
|
||||
p, hr, pre, blockquote, ol, ul, li,
|
||||
dl, dt, dd,
|
||||
figure, figcaption,
|
||||
|
||||
tdiv = "div",
|
||||
|
||||
anchor, em, strong, small,
|
||||
strikethrough = "s", cite, quote,
|
||||
dfn, abbr, data, time, code, `var` = "var", samp,
|
||||
kdb, sub, sup, italic = "i", bold = "b", underlined = "u",
|
||||
mark, ruby, rt, rp, bdi, dbo, span, br, wbr,
|
||||
ins, del, img, iframe, embed, `object` = "object",
|
||||
param, video, audio, source, track, canvas, map,
|
||||
area, svg, math,
|
||||
|
||||
table, caption, colgroup, col, tbody, thead,
|
||||
tfoot, tr, td, th,
|
||||
|
||||
form, fieldset, legend, label, input, button,
|
||||
select, datalist, optgroup, option, textarea,
|
||||
keygen, output, progress, meter,
|
||||
details, summary, command, menu
|
||||
|
||||
type
|
||||
EventKind* {.pure.} = enum
|
||||
onclick, ondblclick, onkeyup, onkeydown, onkeypressed, onblur, onchange, onscroll
|
||||
EventKind* {.pure.} = enum ## The events supported by the virtual DOM.
|
||||
onclick, ## An element is clicked.
|
||||
ondblclick, ## An element is double clicked.
|
||||
onkeyup, ## A key was released.
|
||||
onkeydown, ## A key is pressed.
|
||||
onkeypressed, # A key was pressed.
|
||||
onblur, ## An element lost the focus.
|
||||
onchange, ## The selected value of an element was changed.
|
||||
onscroll, ## The user scrolled within an element.
|
||||
ondrag, ## An element or text selection is being dragged (every 350ms).
|
||||
ondragend, ## A drag operation is being ended (by releasing a mouse button
|
||||
## or hitting the escape key).
|
||||
ondragenter, ## A dragged element or text selection enters a valid drop target.
|
||||
ondragleave, ## A dragged element or text selection leaves a valid drop target.
|
||||
ondragover, ## An element or text selection is being dragged over a valid
|
||||
## drop target (every 350ms).
|
||||
ondragstart, ## The user starts dragging an element or text selection.
|
||||
ondrop ## An element is dropped on a valid drop target.
|
||||
|
||||
const
|
||||
toEventName*: array[EventKind, cstring] = [
|
||||
cstring"click", "dblclick", "keyup", "keydown", "keypressed", "blur",
|
||||
"change", "scroll"
|
||||
]
|
||||
macro buildLookupTables(): untyped =
|
||||
var a = newTree(nnkBracket)
|
||||
for i in low(VNodeKind)..high(VNodeKind):
|
||||
let x = $i
|
||||
let y = if x[0] == '#': x else: toUpperAscii(x)
|
||||
a.add(newCall("cstring", newLit(y)))
|
||||
var e = newTree(nnkBracket)
|
||||
for i in low(EventKind)..high(EventKind):
|
||||
e.add(newCall("cstring", newLit(substr($i, 2))))
|
||||
|
||||
template tmpl(a, e) {.dirty.} =
|
||||
const
|
||||
toTag*: array[VNodeKind, cstring] = a
|
||||
toEventName*: array[EventKind, cstring] = e
|
||||
|
||||
result = getAst tmpl(a, e)
|
||||
|
||||
buildLookupTables()
|
||||
|
||||
type
|
||||
EventHandler* = proc (ev: Event; target: VNode) {.closure.}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue