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