about summary refs log tree commit diff stats
path: root/src/css/sheet.nim
diff options
context:
space:
mode:
Diffstat (limited to 'src/css/sheet.nim')
-rw-r--r--src/css/sheet.nim60
1 files changed, 35 insertions, 25 deletions
diff --git a/src/css/sheet.nim b/src/css/sheet.nim
index 2db7b47a..4990d991 100644
--- a/src/css/sheet.nim
+++ b/src/css/sheet.nim
@@ -2,11 +2,10 @@ import std/algorithm
 import std/streams
 import std/tables
 
-import css/mediaquery
 import css/cssparser
+import css/mediaquery
 import css/selectorparser
-
-import chame/tags
+import html/catom
 
 type
   CSSRuleBase* = ref object of RootObj
@@ -26,23 +25,27 @@ type
 
   CSSStylesheet* = ref object
     mqList*: seq[CSSMediaQueryDef]
-    tagTable: array[TagType, seq[CSSRuleDef]]
+    #TODO maybe just array[TagType] would be more efficient
+    tagTable: Table[CAtom, seq[CSSRuleDef]]
     idTable: Table[string, seq[CSSRuleDef]]
     classTable: Table[string, seq[CSSRuleDef]]
     generalList: seq[CSSRuleDef]
     len: int
+    factory: CAtomFactory
 
 type SelectorHashes = object
-  tag: TagType
+  tag: CAtom
   id: string
   class: string
 
-func newStylesheet*(cap: int): CSSStylesheet =
+func newStylesheet*(cap: int, factory: CAtomFactory): CSSStylesheet =
   let bucketsize = cap div 2
   return CSSStylesheet(
+    tagTable: initTable[CAtom, seq[CSSRuleDef]](bucketsize),
     idTable: initTable[string, seq[CSSRuleDef]](bucketsize),
     classTable: initTable[string, seq[CSSRuleDef]](bucketsize),
-    generalList: newSeqOfCap[CSSRuleDef](bucketsize)
+    generalList: newSeqOfCap[CSSRuleDef](bucketsize),
+    factory: factory
   )
 
 proc getSelectorIds(hashes: var SelectorHashes, sel: Selector): bool
@@ -66,7 +69,7 @@ proc getSelectorIds(hashes: var SelectorHashes, sel: Selector): bool =
   of ID_SELECTOR:
     hashes.id = sel.id
     return true
-  of ATTR_SELECTOR, PSELEM_SELECTOR, UNIVERSAL_SELECTOR, UNKNOWN_TYPE_SELECTOR:
+  of ATTR_SELECTOR, PSELEM_SELECTOR, UNIVERSAL_SELECTOR:
     return false
   of PSEUDO_SELECTOR:
     if sel.pseudo.t in {PSEUDO_IS, PSEUDO_WHERE}:
@@ -88,9 +91,9 @@ proc getSelectorIds(hashes: var SelectorHashes, sel: Selector): bool =
       while i < sel.pseudo.fsels.len:
         var nhashes: SelectorHashes
         nhashes.getSelectorIds(sel.pseudo.fsels[i])
-        if hashes.tag == TAG_UNKNOWN:
+        if hashes.tag == CAtomNull:
           hashes.tag = nhashes.tag
-        elif not cancel_tag and nhashes.tag != TAG_UNKNOWN and nhashes.tag != hashes.tag:
+        elif not cancel_tag and nhashes.tag != CAtomNull and nhashes.tag != hashes.tag:
           cancel_tag = true
 
         if hashes.id == "":
@@ -106,23 +109,24 @@ proc getSelectorIds(hashes: var SelectorHashes, sel: Selector): bool =
         inc i
 
       if cancel_tag:
-        hashes.tag = TAG_UNKNOWN
+        hashes.tag = CAtomNull
       if cancel_id:
         hashes.id = ""
       if cancel_class:
         hashes.class = ""
 
-      if hashes.tag != TAG_UNKNOWN or hashes.id != "" or hashes.class != "":
+      if hashes.tag != CAtomNull or hashes.id != "" or hashes.class != "":
         return true
 
 proc ruleDefCmp(a, b: CSSRuleDef): int =
   cmp(a.idx, b.idx)
 
-iterator genRules*(sheet: CSSStylesheet, tag: TagType, id: string,
+iterator genRules*(sheet: CSSStylesheet, tag: CAtom, id: string,
     classes: seq[string]): CSSRuleDef =
   var rules: seq[CSSRuleDef]
-  for rule in sheet.tagTable[tag]:
-    rules.add(rule)
+  sheet.tagTable.withValue(tag, v):
+    for rule in v[]:
+      rules.add(rule)
   if id != "":
     sheet.idTable.withValue(id, v):
       for rule in v[]:
@@ -141,8 +145,11 @@ proc add(sheet: var CSSStylesheet, rule: CSSRuleDef) =
   var hashes: SelectorHashes
   for cxsel in rule.sels:
     hashes.getSelectorIds(cxsel)
-    if hashes.tag != TAG_UNKNOWN:
-      sheet.tagTable[hashes.tag].add(rule)
+    if hashes.tag != CAtomNull:
+      sheet.tagTable.withValue(hashes.tag, p):
+        p[].add(rule)
+      do:
+        sheet.tagTable[hashes.tag] = @[rule]
     elif hashes.id != "":
       sheet.idTable.withValue(hashes.id, p):
         p[].add(rule)
@@ -158,8 +165,11 @@ proc add(sheet: var CSSStylesheet, rule: CSSRuleDef) =
 
 proc add*(sheet: var CSSStylesheet, sheet2: CSSStylesheet) =
   sheet.generalList.add(sheet2.generalList)
-  for tag in TagType:
-    sheet.tagTable[tag].add(sheet2.tagTable[tag])
+  for key, value in sheet2.tagTable.pairs:
+    sheet.tagTable.withValue(key, p):
+      p[].add(value)
+    do:
+      sheet.tagTable[key] = value
   for key, value in sheet2.idTable.pairs:
     sheet.idTable.withValue(key, p):
       p[].add(value)
@@ -172,7 +182,7 @@ proc add*(sheet: var CSSStylesheet, sheet2: CSSStylesheet) =
       sheet.classTable[key] = value
 
 proc addRule(stylesheet: var CSSStylesheet, rule: CSSQualifiedRule) =
-  let sels = parseSelectors(rule.prelude)
+  let sels = parseSelectors(rule.prelude, stylesheet.factory)
   if sels.len > 0:
     let r = CSSRuleDef(
       sels: sels,
@@ -192,7 +202,7 @@ proc addAtRule(stylesheet: var CSSStylesheet, atrule: CSSAtRule) =
     let rules = atrule.oblock.value.parseListOfRules()
     if rules.len > 0:
       var media = CSSMediaQueryDef()
-      media.children = newStylesheet(rules.len)
+      media.children = newStylesheet(rules.len, stylesheet.factory)
       media.children.len = stylesheet.len
       media.query = query
       for rule in rules:
@@ -204,13 +214,13 @@ proc addAtRule(stylesheet: var CSSStylesheet, atrule: CSSAtRule) =
       stylesheet.len = media.children.len
   else: discard #TODO
 
-proc parseStylesheet*(s: Stream): CSSStylesheet =
+proc parseStylesheet*(s: Stream, factory: CAtomFactory): CSSStylesheet =
   let css = parseCSS(s)
-  result = newStylesheet(css.value.len)
+  result = newStylesheet(css.value.len, factory)
   for v in css.value:
     if v of CSSAtRule: result.addAtRule(CSSAtRule(v))
     else: result.addRule(CSSQualifiedRule(v))
   s.close()
 
-proc parseStylesheet*(s: string): CSSStylesheet =
-  return newStringStream(s).parseStylesheet()
+proc parseStylesheet*(s: string, factory: CAtomFactory): CSSStylesheet =
+  return newStringStream(s).parseStylesheet(factory)