added vstyles karax module for inline CSS support

This commit is contained in:
Araq 2017-05-18 15:53:58 +02:00
commit d6c7be7106
6 changed files with 175 additions and 5 deletions

View file

@ -1,5 +1,5 @@
import vdom, components, karax, karaxdsl, jdict, jstrutils, dom
import vdom, vstyles, components, karax, karaxdsl, jdict, jstrutils, dom
var
images: seq[cstring] = @[cstring"a", "b", "c", "d"]
@ -24,10 +24,20 @@ proc carousel*(key: VKey): VNode {.component.} =
clearTimeout(timer)
timer = setTimeout(docount, 30)
let col =
case counter
of 0: cstring"#4d4d4d"
of 1: cstring"#ff00ff"
of 2: cstring"#00ffff"
of 3: cstring"#ffff00"
else: cstring"red"
result = buildHtml(tdiv(key=key)):
text images[counter]
button(onclick = next):
text "Next"
tdiv(style = style(StyleAttr.color, col)):
text "This changes its color."
if cntdown != 5:
text &cntdown

View file

@ -188,7 +188,7 @@ type
vspace*: int
width*: int
Style = ref StyleObj
Style* = ref StyleObj
StyleObj {.importc.} = object of RootObj
background*: cstring
backgroundAttachment*: cstring

View file

@ -1,6 +1,6 @@
## Karax -- Single page applications for Nim.
import dom, vdom, jstrutils, components, jdict
import dom, vdom, jstrutils, components, jdict, vstyles
export dom.Event
@ -104,6 +104,7 @@ proc vnodeToDom(n: VNode): Node =
wrapEvent(result, n, e, h)
if n == toFocusV and toFocus.isNil:
toFocus = result
if not n.style.isNil: applyStyle(result, n.style)
proc same(n: VNode, e: Node): bool =
if toTag[n.kind] == e.nodename:
@ -135,6 +136,7 @@ proc equalsShallow(a, b: VNode): bool =
if not equalsShallow(a[i], b[i]): return false
if not sameAttrs(a, b): return false
if a.class != b.class: return false
if a.style != b.style: return false
# XXX test event listeners here?
return true

View file

@ -4,7 +4,7 @@ from strutils import startsWith, toLowerAscii
const
StmtContext = ["kout", "inc", "echo", "dec", "!"]
SpecialAttrs = ["id", "class", "value", "key"]
SpecialAttrs = ["id", "class", "value", "key", "style"]
proc getName(n: NimNode): string =
case n.kind

View file

@ -1,7 +1,7 @@
## Virtual DOM implementation for Karax.
from dom import Event, Node
import shash, macros
import shash, macros, vstyles
from strutils import toUpperAscii
type
@ -77,6 +77,7 @@ type
onkeyuplater ## vdom extension: a key was pressed and some time
## passed (useful for on-the-fly text completions)
macro buildLookupTables(): untyped =
var a = newTree(nnkBracket)
for i in low(VNodeKind)..high(VNodeKind):
@ -99,6 +100,7 @@ buildLookupTables()
type
EventHandler* = proc (ev: Event; target: VNode) {.closure.}
VKey* = int
VNode* = ref object
kind*: VNodeKind
key*: VKey
@ -109,6 +111,7 @@ type
events*: seq[(EventKind, EventHandler)]
hash*: Hash
validHash*: bool
style*: VStyle ## the style that should be applied to the virtual node.
dom*: Node ## the attached real DOM node. Can be 'nil' if the virtual node
## is not part of the virtual DOM anymore.
@ -143,6 +146,7 @@ proc eq*(a, b: VNode): bool =
if a.attrs.len != b.attrs.len: return false
for i in 0..<a.attrs.len:
if a.attrs[i] != b.attrs[i]: return false
if a.style != b.style: return false
result = true
proc setAttr*(n: VNode; key: cstring; val: cstring = "") =

154
src/vstyles.nim Normal file
View file

@ -0,0 +1,154 @@
import dom, macros
type
StyleAttr* {.pure.} = enum ## the style attributes supported by the virtual DOM.
background
backgroundAttachment
backgroundColor
backgroundImage
backgroundPosition
backgroundRepeat
border
borderBottom
borderBottomColor
borderBottomStyle
borderBottomWidth
borderColor
borderLeft
borderLeftColor
borderLeftStyle
borderLeftWidth
borderRight
borderRightColor
borderRightStyle
borderRightWidth
borderStyle
borderTop
borderTopColor
borderTopStyle
borderTopWidth
borderWidth
bottom
captionSide
clear
clip
color
cursor
direction
display
emptyCells
cssFloat
font
fontFamily
fontSize
fontStretch
fontStyle
fontVariant
fontWeight
height
left
letterSpacing
lineHeight
listStyle
listStyleImage
listStylePosition
listStyleType
margin
marginBottom
marginLeft
marginRight
marginTop
maxHeight
maxWidth
minHeight
minWidth
overflow
padding
paddingBottom
paddingLeft
paddingRight
paddingTop
pageBreakAfter
pageBreakBefore
position
right
scrollbar3dLightColor
scrollbarArrowColor
scrollbarBaseColor
scrollbarDarkshadowColor
scrollbarFaceColor
scrollbarHighlightColor
scrollbarShadowColor
scrollbarTrackColor
tableLayout
textAlign
textDecoration
textIndent
textTransform
top
verticalAlign
visibility
width
wordSpacing
zIndex
macro buildLookupTables(): untyped =
var e = newTree(nnkBracket)
for i in low(StyleAttr)..high(StyleAttr):
e.add(newCall("cstring", newLit($i)))
template tmpl(e) {.dirty.} =
const
toStyleAttrName: array[StyleAttr, cstring] = e
result = getAst tmpl(e)
buildLookupTables()
type
VStyle* = ref object
attrs: array[StyleAttr, cstring]
mask: set[StyleAttr]
proc `==`*(a, b: VStyle): bool =
if a.isNil:
if b.isNil: return true
else: return false
elif b.isNil: return false
if a.mask != b.mask: return false
for x in a.mask:
if a.attrs[x] != b.attrs[x]: return false
return true
proc setAttr*(s: VStyle; attr: StyleAttr, value: cstring) =
assert value != nil, "value must not be nil"
s.attrs[attr] = value
incl(s.mask, attr)
proc getAttr*(s: VStyle; attr: StyleAttr): cstring =
## returns 'nil' if the attribute has not been set.
result = s.attrs[attr]
proc style*(pairs: varargs[(StyleAttr, cstring)]): VStyle =
## constructs a VStyle object from a list of (attribute, value)-pairs.
result = VStyle(mask: {})
for x in pairs:
result.setAttr x[0], x[1]
proc style*(a: StyleAttr; val: cstring): VStyle =
## constructs a VStyle object from a single (attribute, value)-pair.
result = VStyle(mask: {})
result.setAttr a, val
proc setStyle(d: Style; key, val: cstring) {.importcpp: "#[#] = #".}
proc merge*(a, b: VStyle): VStyle =
## merges two styles. ``b`` takes precedence over ``a``.
result = VStyle(mask: a.mask + b.mask)
for i in low(StyleAttr)..high(StyleAttr):
result.attrs[i] = if b.attrs[i].isNil: a.attrs[i] else: b.attrs[i]
proc applyStyle*(n: Node; s: VStyle) =
## apply the style to the real DOM node ``n``.
n.style = Style()
for x in s.mask:
n.style.setStyle(toStyleAttrName[x], s.attrs[x])