about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2025-02-14 18:04:10 +0100
committerbptato <nincsnevem662@gmail.com>2025-02-14 18:04:10 +0100
commit99f85de667d18fb17b0357399e4005095b10a1b3 (patch)
treea19db43faf38ae3754379c8e834f6ce5f009f6ba
parent1ee2f67e1d7b2f8d164047a1250033de6aa7f3fb (diff)
downloadchawan-99f85de667d18fb17b0357399e4005095b10a1b3.tar.gz
dom: store pseudo-element computed values in a seq
A map isn't so bad with three pointers, but it won't be viable once we
start adding more pseudo-elements.
-rw-r--r--src/css/cascade.nim5
-rw-r--r--src/css/csstree.nim11
-rw-r--r--src/css/layout.nim1
-rw-r--r--src/html/dom.nim20
4 files changed, 20 insertions, 17 deletions
diff --git a/src/css/cascade.nim b/src/css/cascade.nim
index 996b335d..bb20ce16 100644
--- a/src/css/cascade.nim
+++ b/src/css/cascade.nim
@@ -378,9 +378,10 @@ proc applyStyle*(element: Element) =
       else:
         map[peNone][coAuthor].normal.add(vals)
   element.applyStyleDependencies(depends)
-  element.computedMap[peNone] =
+  element.computed =
     map[peNone].applyDeclarations(element.parentElement, element, window)
+  assert element.computedMap.len == 0
   for pseudo in peBefore..peAfter:
     if map[pseudo].hasValues() or window.settings.scripting == smApp:
       let computed = map[pseudo].applyDeclarations(element, nil, window)
-      element.computedMap[pseudo] = computed
+      element.computedMap.add((pseudo, computed))
diff --git a/src/css/csstree.nim b/src/css/csstree.nim
index 4f0e640a..ad7bb1a3 100644
--- a/src/css/csstree.nim
+++ b/src/css/csstree.nim
@@ -179,11 +179,6 @@ const DisplayNoneLike = {
   DisplayNone, DisplayTableColumn, DisplayTableColumnGroup
 }
 
-proc displayed(frame: TreeFrame; pseudo: PseudoElement): bool =
-  return frame.parent.computedMap[pseudo] != nil and
-    frame.parent.computedMap[pseudo]{"content"}.len > 0 and
-    frame.parent.computedMap[pseudo]{"display"} notin DisplayNoneLike
-
 proc displayed(frame: TreeFrame; element: Element): bool =
   return element.computed{"display"} notin DisplayNoneLike
 
@@ -339,12 +334,14 @@ proc addElement(frame: var TreeFrame; element: Element) =
     ))
 
 proc addPseudo(frame: var TreeFrame; pseudo: PseudoElement) =
-  if frame.displayed(pseudo):
+  let computed = frame.parent.getComputedStyle(pseudo)
+  if computed != nil and computed{"display"} notin DisplayNoneLike and
+      computed{"content"}.len > 0:
     frame.add(StyledNode(
       t: stElement,
       pseudo: pseudo,
       element: frame.parent,
-      computed: frame.parent.computedMap[pseudo]
+      computed: computed
     ))
 
 proc addText(frame: var TreeFrame; text: RefString) =
diff --git a/src/css/layout.nim b/src/css/layout.nim
index fb82aab7..2a4e33b8 100644
--- a/src/css/layout.nim
+++ b/src/css/layout.nim
@@ -4,7 +4,6 @@ import std/math
 import css/box
 import css/cssvalues
 import css/lunit
-import html/dom
 import types/bitmap
 import types/winattrs
 import utils/luwrap
diff --git a/src/html/dom.nim b/src/html/dom.nim
index 28859e27..cdfb0e9a 100644
--- a/src/html/dom.nim
+++ b/src/html/dom.nim
@@ -284,7 +284,8 @@ type
     attrs*: seq[AttrData] # sorted by int(qualifiedName)
     cachedAttributes: NamedNodeMap
     cachedStyle*: CSSStyleDeclaration
-    computedMap*: array[peNone..peAfter, CSSValues]
+    computed*: CSSValues
+    computedMap*: seq[tuple[pseudo: PseudoElement; computed: CSSValues]]
 
   AttrDummyElement = ref object of Element
 
@@ -3823,13 +3824,10 @@ proc delAttr(element: Element; i: int; keep = false) =
   element.invalidate()
 
 # Styles.
-template computed*(element: Element): CSSValues =
-  element.computedMap[peNone]
-
 proc invalidate*(element: Element) =
   let valid = element.computed != nil
-  for it in element.computedMap.mitems:
-    it = nil
+  element.computed = nil
+  element.computedMap.setLen(0)
   if element.document != nil:
     element.document.invalid = true
   if valid:
@@ -4032,6 +4030,14 @@ proc style*(element: Element): CSSStyleDeclaration {.jsfget.} =
     element.cachedStyle = newCSSStyleDeclaration(element, "")
   return element.cachedStyle
 
+proc getComputedStyle*(element: Element; pseudo: PseudoElement): CSSValues =
+  if pseudo == peNone:
+    return element.computed
+  for it in element.computedMap:
+    if it.pseudo == pseudo:
+      return it.computed
+  return nil
+
 proc getComputedStyle0*(window: Window; element: Element;
     pseudoElt: Option[string]): CSSStyleDeclaration =
   let pseudo = case pseudoElt.get("")
@@ -4041,7 +4047,7 @@ proc getComputedStyle0*(window: Window; element: Element;
   else: return newCSSStyleDeclaration(nil, "")
   if window.settings.scripting == smApp:
     window.maybeRestyle(element)
-    return newCSSStyleDeclaration(element, $element.computedMap[pseudo],
+    return newCSSStyleDeclaration(element, $element.getComputedStyle(pseudo),
       computed = true, readonly = true)
   # In lite mode, we just parse the "style" attribute and hope for
   # the best.