added vstyles karax module for inline CSS support
This commit is contained in:
parent
68134abe3f
commit
d6c7be7106
6 changed files with 175 additions and 5 deletions
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
import vdom, components, karax, karaxdsl, jdict, jstrutils, dom
|
import vdom, vstyles, components, karax, karaxdsl, jdict, jstrutils, dom
|
||||||
|
|
||||||
var
|
var
|
||||||
images: seq[cstring] = @[cstring"a", "b", "c", "d"]
|
images: seq[cstring] = @[cstring"a", "b", "c", "d"]
|
||||||
|
|
@ -24,10 +24,20 @@ proc carousel*(key: VKey): VNode {.component.} =
|
||||||
clearTimeout(timer)
|
clearTimeout(timer)
|
||||||
timer = setTimeout(docount, 30)
|
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)):
|
result = buildHtml(tdiv(key=key)):
|
||||||
text images[counter]
|
text images[counter]
|
||||||
button(onclick = next):
|
button(onclick = next):
|
||||||
text "Next"
|
text "Next"
|
||||||
|
tdiv(style = style(StyleAttr.color, col)):
|
||||||
|
text "This changes its color."
|
||||||
if cntdown != 5:
|
if cntdown != 5:
|
||||||
text &cntdown
|
text &cntdown
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -188,7 +188,7 @@ type
|
||||||
vspace*: int
|
vspace*: int
|
||||||
width*: int
|
width*: int
|
||||||
|
|
||||||
Style = ref StyleObj
|
Style* = ref StyleObj
|
||||||
StyleObj {.importc.} = object of RootObj
|
StyleObj {.importc.} = object of RootObj
|
||||||
background*: cstring
|
background*: cstring
|
||||||
backgroundAttachment*: cstring
|
backgroundAttachment*: cstring
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
## Karax -- Single page applications for Nim.
|
## Karax -- Single page applications for Nim.
|
||||||
|
|
||||||
import dom, vdom, jstrutils, components, jdict
|
import dom, vdom, jstrutils, components, jdict, vstyles
|
||||||
|
|
||||||
export dom.Event
|
export dom.Event
|
||||||
|
|
||||||
|
|
@ -104,6 +104,7 @@ proc vnodeToDom(n: VNode): Node =
|
||||||
wrapEvent(result, n, e, h)
|
wrapEvent(result, n, e, h)
|
||||||
if n == toFocusV and toFocus.isNil:
|
if n == toFocusV and toFocus.isNil:
|
||||||
toFocus = result
|
toFocus = result
|
||||||
|
if not n.style.isNil: applyStyle(result, n.style)
|
||||||
|
|
||||||
proc same(n: VNode, e: Node): bool =
|
proc same(n: VNode, e: Node): bool =
|
||||||
if toTag[n.kind] == e.nodename:
|
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 equalsShallow(a[i], b[i]): return false
|
||||||
if not sameAttrs(a, b): return false
|
if not sameAttrs(a, b): return false
|
||||||
if a.class != b.class: return false
|
if a.class != b.class: return false
|
||||||
|
if a.style != b.style: return false
|
||||||
# XXX test event listeners here?
|
# XXX test event listeners here?
|
||||||
return true
|
return true
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ from strutils import startsWith, toLowerAscii
|
||||||
|
|
||||||
const
|
const
|
||||||
StmtContext = ["kout", "inc", "echo", "dec", "!"]
|
StmtContext = ["kout", "inc", "echo", "dec", "!"]
|
||||||
SpecialAttrs = ["id", "class", "value", "key"]
|
SpecialAttrs = ["id", "class", "value", "key", "style"]
|
||||||
|
|
||||||
proc getName(n: NimNode): string =
|
proc getName(n: NimNode): string =
|
||||||
case n.kind
|
case n.kind
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
## Virtual DOM implementation for Karax.
|
## Virtual DOM implementation for Karax.
|
||||||
|
|
||||||
from dom import Event, Node
|
from dom import Event, Node
|
||||||
import shash, macros
|
import shash, macros, vstyles
|
||||||
from strutils import toUpperAscii
|
from strutils import toUpperAscii
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
@ -77,6 +77,7 @@ type
|
||||||
onkeyuplater ## vdom extension: a key was pressed and some time
|
onkeyuplater ## vdom extension: a key was pressed and some time
|
||||||
## passed (useful for on-the-fly text completions)
|
## passed (useful for on-the-fly text completions)
|
||||||
|
|
||||||
|
|
||||||
macro buildLookupTables(): untyped =
|
macro buildLookupTables(): untyped =
|
||||||
var a = newTree(nnkBracket)
|
var a = newTree(nnkBracket)
|
||||||
for i in low(VNodeKind)..high(VNodeKind):
|
for i in low(VNodeKind)..high(VNodeKind):
|
||||||
|
|
@ -99,6 +100,7 @@ buildLookupTables()
|
||||||
type
|
type
|
||||||
EventHandler* = proc (ev: Event; target: VNode) {.closure.}
|
EventHandler* = proc (ev: Event; target: VNode) {.closure.}
|
||||||
VKey* = int
|
VKey* = int
|
||||||
|
|
||||||
VNode* = ref object
|
VNode* = ref object
|
||||||
kind*: VNodeKind
|
kind*: VNodeKind
|
||||||
key*: VKey
|
key*: VKey
|
||||||
|
|
@ -109,6 +111,7 @@ type
|
||||||
events*: seq[(EventKind, EventHandler)]
|
events*: seq[(EventKind, EventHandler)]
|
||||||
hash*: Hash
|
hash*: Hash
|
||||||
validHash*: bool
|
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
|
dom*: Node ## the attached real DOM node. Can be 'nil' if the virtual node
|
||||||
## is not part of the virtual DOM anymore.
|
## 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
|
if a.attrs.len != b.attrs.len: return false
|
||||||
for i in 0..<a.attrs.len:
|
for i in 0..<a.attrs.len:
|
||||||
if a.attrs[i] != b.attrs[i]: return false
|
if a.attrs[i] != b.attrs[i]: return false
|
||||||
|
if a.style != b.style: return false
|
||||||
result = true
|
result = true
|
||||||
|
|
||||||
proc setAttr*(n: VNode; key: cstring; val: cstring = "") =
|
proc setAttr*(n: VNode; key: cstring; val: cstring = "") =
|
||||||
|
|
|
||||||
154
src/vstyles.nim
Normal file
154
src/vstyles.nim
Normal 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])
|
||||||
Loading…
Add table
Add a link
Reference in a new issue