about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2025-02-18 22:40:50 +0100
committerbptato <nincsnevem662@gmail.com>2025-02-18 22:45:48 +0100
commit8318e22e30b78a21fb75e9bc796d58daea024a5f (patch)
treee3b7fa29a3ae4c160c9e2f251e6c4f6cdfa7cb83 /src
parent1f13d09b73562616d092d38c8d4807fef729799b (diff)
downloadchawan-8318e22e30b78a21fb75e9bc796d58daea024a5f.tar.gz
sheet: hash :root, :link pseudo classes
:root is used on the UA sheet, so it's quite important.
:link, :visited can be treated as shortcuts (although :visited never
matches right now).
Diffstat (limited to 'src')
-rw-r--r--src/css/cascade.nim3
-rw-r--r--src/css/cssvalues.nim2
-rw-r--r--src/css/sheet.nim102
3 files changed, 66 insertions, 41 deletions
diff --git a/src/css/cascade.nim b/src/css/cascade.nim
index bd6027d1..39e92cc5 100644
--- a/src/css/cascade.nim
+++ b/src/css/cascade.nim
@@ -84,6 +84,9 @@ proc calcRules(map: var RuleListMap; element: Element;
   for attr in element.attrs:
     sheet.attrTable.withValue(attr.qualifiedName, v):
       rules.add(v[])
+  if element.parentElement == nil:
+    for rule in sheet.rootList:
+      rules.add(rule)
   for rule in sheet.generalList:
     rules.add(rule)
   var tosorts = ToSorts.default
diff --git a/src/css/cssvalues.nim b/src/css/cssvalues.nim
index 51d3fd1e..468b3298 100644
--- a/src/css/cssvalues.nim
+++ b/src/css/cssvalues.nim
@@ -642,7 +642,7 @@ func `$`(counterreset: seq[CSSCounterSet]): string =
 
 func `$`(zIndex: CSSZIndex): string =
   if zIndex.auto:
-    return $auto
+    return "auto"
   return $zIndex.num
 
 func serialize(val: CSSValue): string =
diff --git a/src/css/sheet.nim b/src/css/sheet.nim
index b1abfa5e..438b3f77 100644
--- a/src/css/sheet.nim
+++ b/src/css/sheet.nim
@@ -2,6 +2,7 @@ import std/options
 import std/strutils
 import std/tables
 
+import chame/tags
 import css/cssparser
 import css/cssvalues
 import css/mediaquery
@@ -36,6 +37,7 @@ type
     idTable*: Table[CAtom, seq[CSSRuleDef]]
     classTable*: Table[CAtom, seq[CSSRuleDef]]
     attrTable*: Table[CAtom, seq[CSSRuleDef]]
+    rootList*: seq[CSSRuleDef]
     generalList*: seq[CSSRuleDef]
     importList*: seq[URL]
     len: int
@@ -46,6 +48,7 @@ type SelectorHashes = object
   id: CAtom
   class: CAtom
   attr: CAtom
+  root: bool
 
 func newStylesheet*(cap: int; attrs: ptr WindowAttributes): CSSStylesheet =
   let bucketsize = cap div 2
@@ -85,47 +88,63 @@ proc getSelectorIds(hashes: var SelectorHashes; sel: Selector): bool =
   of stPseudoElement, stUniversal:
     return false
   of stPseudoClass:
-    if sel.pseudo.t notin {pcIs, pcWhere}:
+    case sel.pseudo.t
+    of pcRoot:
+      hashes.root = true
+      return true
+    of pcLink, pcVisited:
+      hashes.tags.add(TAG_A.toAtom())
+      hashes.tags.add(TAG_AREA.toAtom())
+      hashes.attr = satHref.toAtom()
+      return true
+    of pcIs, pcWhere:
+      # Hash whatever the selectors have in common:
+      # 1. get the hashable values of selector 1
+      # 2. for each other selector x:
+      # 3.   get hashable values of selector x
+      # 4.   store hashable values of selector x that aren't stored yet
+      # 5.   for each hashable value of selector 1 that doesn't match selector x
+      # 6.     cancel hashable value
+      var cancelId = false
+      var cancelClass = false
+      var cancelAttr = false
+      var cancelRoot = false
+      var i = 0
+      if i < sel.pseudo.fsels.len:
+        hashes.getSelectorIds(sel.pseudo.fsels[i])
+        inc i
+      while i < sel.pseudo.fsels.len:
+        var nhashes = SelectorHashes()
+        nhashes.getSelectorIds(sel.pseudo.fsels[i])
+        hashes.tags.add(nhashes.tags)
+        if hashes.id == CAtomNull:
+          hashes.id = nhashes.id
+        elif nhashes.id != CAtomNull and nhashes.id != hashes.id:
+          cancelId = true
+        if hashes.class == CAtomNull:
+          hashes.class = nhashes.class
+        elif nhashes.class != CAtomNull and nhashes.class != hashes.class:
+          cancelClass = true
+        if hashes.attr == CAtomNull:
+          hashes.attr = nhashes.attr
+        elif nhashes.attr != CAtomNull and nhashes.attr != hashes.attr:
+          cancelAttr = true
+        if hashes.root != nhashes.root:
+          cancelRoot = true
+        inc i
+      if cancelId:
+        hashes.id = CAtomNull
+      if cancelClass:
+        hashes.class = CAtomNull
+      if cancelAttr:
+        hashes.attr = CAtomNull
+      if cancelRoot:
+        hashes.root = false
+      return hashes.tags.len > 0 or hashes.id != CAtomNull or
+        hashes.class != CAtomNull or hashes.attr != CAtomNull or
+        hashes.root
+    else:
       return false
-    # Basically just hash whatever the selectors have in common:
-    # 1. get the hashable values of selector 1
-    # 2. for every other selector x:
-    # 3.   get hashable values of selector x
-    # 4.   store hashable values of selector x that aren't stored yet
-    # 5.   for every hashable value of selector 1 that doesn't match selector x
-    # 6.     cancel hashable value
-    var cancelId = false
-    var cancelClass = false
-    var cancelAttr = false
-    var i = 0
-    if i < sel.pseudo.fsels.len:
-      hashes.getSelectorIds(sel.pseudo.fsels[i])
-      inc i
-    while i < sel.pseudo.fsels.len:
-      var nhashes = SelectorHashes()
-      nhashes.getSelectorIds(sel.pseudo.fsels[i])
-      hashes.tags.add(nhashes.tags)
-      if hashes.id == CAtomNull:
-        hashes.id = nhashes.id
-      elif nhashes.id != CAtomNull and nhashes.id != hashes.id:
-        cancelId = true
-      if hashes.class == CAtomNull:
-        hashes.class = nhashes.class
-      elif nhashes.class != CAtomNull and nhashes.class != hashes.class:
-        cancelClass = true
-      if hashes.attr == CAtomNull:
-        hashes.attr = nhashes.attr
-      elif nhashes.attr != CAtomNull and nhashes.attr != hashes.attr:
-        cancelAttr = true
-      inc i
-    if cancelId:
-      hashes.id = CAtomNull
-    if cancelClass:
-      hashes.class = CAtomNull
-    if cancelAttr:
-      hashes.attr = CAtomNull
-    return hashes.tags.len > 0 or hashes.id != CAtomNull or
-      hashes.class != CAtomNull or hashes.attr != CAtomNull
 
 proc add(sheet: CSSStylesheet; rule: CSSRuleDef) =
   for cxsel in rule.sels:
@@ -153,11 +172,14 @@ proc add(sheet: CSSStylesheet; rule: CSSRuleDef) =
         p[].add(rule)
       do:
         sheet.attrTable[hashes.attr] = @[rule]
+    elif hashes.root:
+      sheet.rootList.add(rule)
     else:
       sheet.generalList.add(rule)
 
 proc add*(sheet, sheet2: CSSStylesheet) =
   sheet.generalList.add(sheet2.generalList)
+  sheet.rootList.add(sheet2.rootList)
   for key, value in sheet2.tagTable.pairs:
     sheet.tagTable.withValue(key, p):
       p[].add(value)