about summary refs log tree commit diff stats
path: root/src/css/cssvalues.nim
diff options
context:
space:
mode:
Diffstat (limited to 'src/css/cssvalues.nim')
-rw-r--r--src/css/cssvalues.nim105
1 files changed, 80 insertions, 25 deletions
diff --git a/src/css/cssvalues.nim b/src/css/cssvalues.nim
index fa24b39b..a2c661d6 100644
--- a/src/css/cssvalues.nim
+++ b/src/css/cssvalues.nim
@@ -7,14 +7,13 @@ import std/tables
 import css/cssparser
 import css/lunit
 import css/selectorparser
+import html/catom
 import types/bitmap
 import types/color
 import types/opt
 import types/winattrs
 import utils/twtstr
 
-export selectorparser.PseudoElem
-
 type
   CSSPropertyType* = enum
     # primitive/enum properties: stored as byte
@@ -410,13 +409,26 @@ type
     coUser
     coAuthor
 
+  CSSEntryType* = enum
+    ceBit, ceObject, ceWord, ceVar
+
   CSSComputedEntry* = object
     t*: CSSPropertyType
     global*: CSSGlobalType
-    #TODO case on t?
-    bit*: uint8
-    word*: CSSValueWord
-    obj*: CSSValue
+    case et*: CSSEntryType
+    of ceBit:
+      bit*: uint8
+    of ceWord:
+      word*: CSSValueWord
+    of ceObject:
+      obj*: CSSValue
+    of ceVar:
+      cvar*: CAtom
+
+  CSSVariable* = ref object
+    name*: CAtom
+    cvals*: seq[CSSComponentValue]
+    resolved: seq[tuple[v: CSSValueType; entry: CSSComputedEntry]]
 
 static:
   doAssert sizeof(CSSValueBit) == 1
@@ -1247,34 +1259,66 @@ func cssNumber(cval: CSSComponentValue; positive: bool): Opt[float32] =
 
 proc makeEntry*(t: CSSPropertyType; obj: CSSValue; global = cgtNone):
     CSSComputedEntry =
-  return CSSComputedEntry(t: t, obj: obj, global: global)
+  return CSSComputedEntry(et: ceObject, t: t, obj: obj, global: global)
 
 proc makeEntry*(t: CSSPropertyType; word: CSSValueWord; global = cgtNone):
     CSSComputedEntry =
-  return CSSComputedEntry(t: t, word: word, global: global)
+  return CSSComputedEntry(et: ceWord, t: t, word: word, global: global)
 
 proc makeEntry*(t: CSSPropertyType; bit: CSSValueBit; global = cgtNone):
     CSSComputedEntry =
-  return CSSComputedEntry(t: t, bit: bit.dummy, global: global)
+  return CSSComputedEntry(et: ceBit, t: t, bit: bit.dummy, global: global)
 
 proc makeEntry*(t: CSSPropertyType; global: CSSGlobalType): CSSComputedEntry =
-  return CSSComputedEntry(t: t, global: global)
+  return CSSComputedEntry(et: ceObject, t: t, global: global)
+
+proc parseVar(fun: CSSFunction; entry: var CSSComputedEntry;
+    attrs: WindowAttributes; factory: CAtomFactory): Opt[void] =
+  let i = fun.value.skipBlanks(0)
+  if i >= fun.value.len or fun.value.skipBlanks(i + 1) < fun.value.len:
+    return err()
+  let cval = fun.value[i]
+  if not (cval of CSSToken):
+    return err()
+  let tok = CSSToken(fun.value[i])
+  if tok.t != cttIdent:
+    return err()
+  entry = CSSComputedEntry(
+    et: ceVar,
+    cvar: factory.toAtom(tok.value.substr(2))
+  )
+  return ok()
 
 proc parseValue(cvals: openArray[CSSComponentValue];
-    entry: var CSSComputedEntry; attrs: WindowAttributes): Opt[void] =
+    entry: var CSSComputedEntry; attrs: WindowAttributes;
+    factory: CAtomFactory): Opt[void] =
   var i = cvals.skipBlanks(0)
   if i >= cvals.len:
     return err()
   let cval = cvals[i]
-  let t = entry.t
   inc i
+  if cval of CSSFunction:
+    let fun = CSSFunction(cval)
+    if fun.name.equalsIgnoreCase("var"):
+      if cvals.skipBlanks(i) < cvals.len:
+        return err()
+      return fun.parseVar(entry, attrs, factory)
+  let t = entry.t
   let v = valueType(t)
   template set_new(prop, val: untyped) =
-    entry.obj = CSSValue(v: v, prop: val)
+    entry = CSSComputedEntry(
+      t: entry.t,
+      et: ceObject,
+      obj: CSSValue(v: v, prop: val)
+    )
   template set_word(prop, val: untyped) =
-    entry.word = CSSValueWord(prop: val)
+    entry = CSSComputedEntry(
+      t: entry.t,
+      et: ceWord,
+      word: CSSValueWord(prop: val)
+    )
   template set_bit(prop, val: untyped) =
-    entry.bit = cast[uint8](val)
+    entry = CSSComputedEntry(t: entry.t, et: ceBit, bit: cast[uint8](val))
   case v
   of cvtDisplay: set_bit display, ?parseIdent[CSSDisplay](cval)
   of cvtWhiteSpace: set_bit whiteSpace, ?parseIdent[CSSWhiteSpace](cval)
@@ -1426,7 +1470,8 @@ const PropertyPaddingSpec = [
 ]
 
 proc parseComputedValues*(res: var seq[CSSComputedEntry]; name: string;
-    cvals: openArray[CSSComponentValue]; attrs: WindowAttributes): Err[void] =
+    cvals: openArray[CSSComponentValue]; attrs: WindowAttributes;
+    factory: CAtomFactory): Err[void] =
   var i = cvals.skipBlanks(0)
   if i >= cvals.len:
     return err()
@@ -1439,8 +1484,12 @@ proc parseComputedValues*(res: var seq[CSSComputedEntry]; name: string;
       if global != cgtNone:
         res.add(makeEntry(t, global))
       else:
-        var entry = CSSComputedEntry(t: t)
-        ?cvals.parseValue(entry, attrs)
+        let et = case t.reprType
+        of cprtBit: ceBit
+        of cprtObject: ceObject
+        of cprtWord: ceWord
+        var entry = CSSComputedEntry(t: t, et: et)
+        ?cvals.parseValue(entry, attrs, factory)
         res.add(entry)
   of cstAll:
     if global == cgtNone:
@@ -1561,9 +1610,9 @@ proc parseComputedValues*(res: var seq[CSSComputedEntry]; name: string;
   return ok()
 
 proc parseComputedValues*(name: string; value: seq[CSSComponentValue];
-    attrs: WindowAttributes): seq[CSSComputedEntry] =
+    attrs: WindowAttributes; factory: CAtomFactory): seq[CSSComputedEntry] =
   var res: seq[CSSComputedEntry] = @[]
-  if res.parseComputedValues(name, value, attrs).isSome:
+  if res.parseComputedValues(name, value, attrs, factory).isSome:
     return res
   return @[]
 
@@ -1591,8 +1640,13 @@ type
 
   InitMap* = array[CSSPropertyType, set[InitType]]
 
+  CSSVariableMap* = ref object
+    parent*: CSSVariableMap
+    vars*: seq[CSSVariable]
+
 proc applyValue*(vals: CSSValues; entry: CSSComputedEntry;
-    parent, previousOrigin: CSSValues; inited: InitMap; initType: InitType) =
+    varMap: CSSVariableMap; parent, previousOrigin: CSSValues; inited: InitMap;
+    initType: InitType) =
   case entry.global
   of cgtInherit:
     if parent != nil:
@@ -1609,10 +1663,11 @@ proc applyValue*(vals: CSSValues; entry: CSSComputedEntry;
     else:
       vals.initialOrInheritFrom(parent, entry.t)
   of cgtNone:
-    case entry.t.reprType
-    of cprtBit: vals.bits[entry.t].dummy = entry.bit
-    of cprtWord: vals.words[entry.t] = entry.word
-    of cprtObject: vals.objs[entry.t] = entry.obj
+    case entry.et
+    of ceBit: vals.bits[entry.t].dummy = entry.bit
+    of ceWord: vals.words[entry.t] = entry.word
+    of ceObject: vals.objs[entry.t] = entry.obj
+    of ceVar: discard #eprint "TODO"
 
 func inheritProperties*(parent: CSSValues): CSSValues =
   result = CSSValues()