diff options
author | bptato <nincsnevem662@gmail.com> | 2024-07-29 20:26:48 +0200 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2024-07-29 23:24:34 +0200 |
commit | 83d119903270acc85110c291fe0b7a4d967a9052 (patch) | |
tree | aa9bdc680744fb2622486b84d6d5332af5d6498e /src/css | |
parent | 070e1e181f0efbd1aa4d760daa17fe2ad8e976e4 (diff) | |
download | chawan-83d119903270acc85110c291fe0b7a4d967a9052.tar.gz |
css: hash attribute names
Diffstat (limited to 'src/css')
-rw-r--r-- | src/css/cascade.nim | 25 | ||||
-rw-r--r-- | src/css/sheet.nim | 75 |
2 files changed, 56 insertions, 44 deletions
diff --git a/src/css/cascade.nim b/src/css/cascade.nim index a3039f15..8a8d8c44 100644 --- a/src/css/cascade.nim +++ b/src/css/cascade.nim @@ -1,6 +1,6 @@ import std/algorithm import std/options -import std/strutils +import std/tables import chame/tags import css/cssparser @@ -95,8 +95,27 @@ proc calcRule(tosorts: var ToSorts; styledNode: StyledNode; rule: CSSRuleDef) = func calcRules(styledNode: StyledNode; sheet: CSSStylesheet): RuleList = var tosorts: ToSorts - let elem = Element(styledNode.node) - for rule in sheet.genRules(elem.localName, elem.id, elem.classList.toks): + let element = Element(styledNode.node) + var rules: seq[CSSRuleDef] = @[] + sheet.tagTable.withValue(element.localName, v): + for rule in v[]: + rules.add(rule) + if element.id != CAtomNull: + sheet.idTable.withValue(element.id, v): + for rule in v[]: + rules.add(rule) + for class in element.classList.toks: + sheet.classTable.withValue(class, v): + for rule in v[]: + rules.add(rule) + for attr in element.attrs: + sheet.attrTable.withValue(attr.qualifiedName, v): + for rule in v[]: + rules.add(rule) + for rule in sheet.generalList: + rules.add(rule) + rules.sort(ruleDefCmp, order = Ascending) + for rule in rules: tosorts.calcRule(styledNode, rule) for i in PseudoElem: tosorts[i].sort((proc(x, y: (int, CSSRuleDef)): int = diff --git a/src/css/sheet.nim b/src/css/sheet.nim index eb11854e..579e7f9e 100644 --- a/src/css/sheet.nim +++ b/src/css/sheet.nim @@ -1,4 +1,3 @@ -import std/algorithm import std/tables import css/cssparser @@ -26,10 +25,11 @@ type CSSStylesheet* = ref object mqList*: seq[CSSMediaQueryDef] - tagTable: Table[CAtom, seq[CSSRuleDef]] - idTable: Table[CAtom, seq[CSSRuleDef]] - classTable: Table[CAtom, seq[CSSRuleDef]] - generalList: seq[CSSRuleDef] + tagTable*: Table[CAtom, seq[CSSRuleDef]] + idTable*: Table[CAtom, seq[CSSRuleDef]] + classTable*: Table[CAtom, seq[CSSRuleDef]] + attrTable*: Table[CAtom, seq[CSSRuleDef]] + generalList*: seq[CSSRuleDef] len: int factory: CAtomFactory @@ -37,6 +37,7 @@ type SelectorHashes = object tag: CAtom id: CAtom class: CAtom + attr: CAtom func newStylesheet*(cap: int; factory: CAtomFactory): CSSStylesheet = let bucketsize = cap div 2 @@ -44,6 +45,7 @@ func newStylesheet*(cap: int; factory: CAtomFactory): CSSStylesheet = tagTable: initTable[CAtom, seq[CSSRuleDef]](bucketsize), idTable: initTable[CAtom, seq[CSSRuleDef]](bucketsize), classTable: initTable[CAtom, seq[CSSRuleDef]](bucketsize), + attrTable: initTable[CAtom, seq[CSSRuleDef]](bucketsize), generalList: newSeqOfCap[CSSRuleDef](bucketsize), factory: factory ) @@ -69,43 +71,47 @@ proc getSelectorIds(hashes: var SelectorHashes; sel: Selector): bool = of stId: hashes.id = sel.id return true - of stAttr, stPseudoElement, stUniversal: + of stAttr: + hashes.attr = sel.attr + of stPseudoElement, stUniversal: return false of stPseudoClass: if sel.pseudo.t notin {pcIs, pcWhere}: 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 + # 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 cancelTag = false 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 + var nhashes = SelectorHashes() nhashes.getSelectorIds(sel.pseudo.fsels[i]) if hashes.tag == CAtomNull: hashes.tag = nhashes.tag - elif not cancelTag and nhashes.tag != CAtomNull and - nhashes.tag != hashes.tag: + elif nhashes.tag != CAtomNull and nhashes.tag != hashes.tag: cancelTag = true if hashes.id == CAtomNull: hashes.id = nhashes.id - elif not cancelId and nhashes.id != CAtomNull and - nhashes.id != hashes.id: + elif nhashes.id != CAtomNull and nhashes.id != hashes.id: cancelId = true if hashes.class == CAtomNull: hashes.class = nhashes.class - elif not cancelClass and nhashes.class != CAtomNull and - nhashes.class != hashes.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 cancelTag: hashes.tag = CAtomNull @@ -113,34 +119,16 @@ proc getSelectorIds(hashes: var SelectorHashes; sel: Selector): bool = hashes.id = CAtomNull if cancelClass: hashes.class = CAtomNull + if cancelAttr: + hashes.attr = CAtomNull return hashes.tag != CAtomNull or hashes.id != CAtomNull or hashes.class != CAtomNull -proc ruleDefCmp(a, b: CSSRuleDef): int = +proc ruleDefCmp*(a, b: CSSRuleDef): int = cmp(a.idx, b.idx) -iterator genRules*(sheet: CSSStylesheet; tag, id: CAtom; classes: seq[CAtom]): - CSSRuleDef = - var rules: seq[CSSRuleDef] - sheet.tagTable.withValue(tag, v): - for rule in v[]: - rules.add(rule) - if id != CAtomNull: - sheet.idTable.withValue(id, v): - for rule in v[]: - rules.add(rule) - for class in classes: - sheet.classTable.withValue(class, v): - for rule in v[]: - rules.add(rule) - for rule in sheet.generalList: - rules.add(rule) - rules.sort(ruleDefCmp, order = Ascending) - for rule in rules: - yield rule - proc add(sheet: CSSStylesheet; rule: CSSRuleDef) = - var hashes: SelectorHashes + var hashes = SelectorHashes() for cxsel in rule.sels: hashes.getSelectorIds(cxsel) if hashes.tag != CAtomNull: @@ -178,6 +166,11 @@ proc add*(sheet, sheet2: CSSStylesheet) = p[].add(value) do: sheet.classTable[key] = value + for key, value in sheet2.attrTable.pairs: + sheet.attrTable.withValue(key, p): + p[].add(value) + do: + sheet.attrTable[key] = value proc addRule(stylesheet: CSSStylesheet; rule: CSSQualifiedRule) = let sels = parseSelectors(rule.prelude, stylesheet.factory) |