diff options
author | bptato <nincsnevem662@gmail.com> | 2025-02-18 22:40:50 +0100 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2025-02-18 22:45:48 +0100 |
commit | 8318e22e30b78a21fb75e9bc796d58daea024a5f (patch) | |
tree | e3b7fa29a3ae4c160c9e2f251e6c4f6cdfa7cb83 /src | |
parent | 1f13d09b73562616d092d38c8d4807fef729799b (diff) | |
download | chawan-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.nim | 3 | ||||
-rw-r--r-- | src/css/cssvalues.nim | 2 | ||||
-rw-r--r-- | src/css/sheet.nim | 102 |
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) |