From ffbc547bdb509c25e92fa57f97063e5e39c32571 Mon Sep 17 00:00:00 2001 From: Joel Lienhard <71709264+choltreppe@users.noreply.github.com> Date: Fri, 20 Oct 2023 17:26:08 +0200 Subject: [PATCH] propper svg/math elements (#271) * propper svg/math elements * make namespaces var * simplify toTag/toEventName defs, and dont uppercase toTag * fix class-name update of svg elements --- karax.nimble | 2 +- karax/karax.nim | 21 ++++++++++++++++++--- karax/vdom.nim | 37 +++++++++++++++++++------------------ 3 files changed, 38 insertions(+), 22 deletions(-) diff --git a/karax.nimble b/karax.nimble index 0098564..b2da147 100644 --- a/karax.nimble +++ b/karax.nimble @@ -1,6 +1,6 @@ # Package -version = "1.3.0" +version = "1.3.1" author = "Andreas Rumpf" description = "Karax is a framework for developing single page applications in Nim." license = "MIT" diff --git a/karax/karax.nim b/karax/karax.nim index 3634093..385dc18 100644 --- a/karax/karax.nim +++ b/karax/karax.nim @@ -7,6 +7,9 @@ export kdom.Event, kdom.Blob when defined(nimNoNil): {.experimental: "notnil".} +proc createElementNS(document: Document, namespace, tag: cstring): Node {.importjs: "#.createElementNS(@)".} +proc `classBaseVal=`(n: Node, v: cstring) {.importjs: "#.className.baseVal = #".} + proc kout*[T](x: T) {.importc: "console.log", varargs.} ## The preferred way of debugging karax applications. @@ -196,7 +199,13 @@ proc toDom*(n: VNode; useAttachedNode: bool; kxi: KaraxInstance = nil): Node = attach n return result else: - result = document.createElement(toTag[n.kind]) + result = + if n.kind in svgElements: + document.createElementNS(svgNamespace, toTag[n.kind]) + elif n.kind in mathElements: + document.createElementNS(mathNamespace, toTag[n.kind]) + else: + document.createElement(toTag[n.kind]) attach n for k in n: appendChild(result, toDom(k, useAttachedNode, kxi)) @@ -206,7 +215,10 @@ proc toDom*(n: VNode; useAttachedNode: bool; kxi: KaraxInstance = nil): Node = if n.id != nil: result.id = n.id if n.class != nil: - result.class = n.class + if n.kind in svgElements: + result.classBaseVal = n.class.cstring + else: + result.class = n.class #if n.key >= 0: # result.key = n.key for k, v in attrs(n): @@ -329,7 +341,10 @@ proc updateStyles(newNode, oldNode: VNode) = applyStyle(oldNode.dom, newNode.style) newNode.styleVersion = newNode.style.version else: oldNode.dom.style = Style() - oldNode.dom.class = newNode.class + if oldNode.kind in svgElements: + oldNode.dom.classBaseVal = newNode.class + else: + oldNode.dom.class = newNode.class oldNode.style = newNode.style oldNode.class = newNode.class diff --git a/karax/vdom.nim b/karax/vdom.nim index 5afc2a0..72732f3 100644 --- a/karax/vdom.nim +++ b/karax/vdom.nim @@ -68,6 +68,13 @@ const selfClosing = {area, base, br, col, embed, hr, img, input, link, meta, param, source, track, wbr} + svgElements* = {animate .. view} + mathElements* = {maction .. semantics} + +var + svgNamespace* = "http://www.w3.org/2000/svg" + mathNamespace* = "http://www.w3.org/1998/Math/MathML" + type EventKind* {.pure.} = enum ## The events supported by the virtual DOM. onclick, ## An element is clicked. @@ -123,24 +130,18 @@ type onwheel ## fires when the user rotates a wheel button on a pointing device. -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("kstring", newLit(y))) - var e = newTree(nnkBracket) - for i in low(EventKind)..high(EventKind): - e.add(newCall("kstring", newLit(substr($i, 2)))) - - template tmpl(a, e) {.dirty.} = - const - toTag*: array[VNodeKind, kstring] = a - toEventName*: array[EventKind, kstring] = e - - result = getAst tmpl(a, e) - -buildLookupTables() +const + toTag* = block: + var res: array[VNodeKind, kstring] + for kind in VNodeKind: + res[kind] = kstring($kind) + res + + toEventName* = block: + var res: array[EventKind, kstring] + for kind in EventKind: + res[kind] = kstring(($kind)[2..^1]) + res type EventHandler* = proc (ev: Event; target: VNode) {.closure.}