about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2024-12-02 18:55:52 +0100
committerbptato <nincsnevem662@gmail.com>2024-12-02 18:55:52 +0100
commitd6ab3a44c5909b5aca9e75b0e833c4c53a5490d0 (patch)
tree2e166f277568e619f9433e5f0964ccb6a1a27318
parentf6031abdc296df0977740f3c0b5238c03ab164d8 (diff)
downloadchawan-d6ab3a44c5909b5aca9e75b0e833c4c53a5490d0.tar.gz
cascade, cssvalues: clean up a bit more
-rw-r--r--src/css/cascade.nim70
-rw-r--r--src/css/cssvalues.nim74
2 files changed, 76 insertions, 68 deletions
diff --git a/src/css/cascade.nim b/src/css/cascade.nim
index a946c8e7..f510d105 100644
--- a/src/css/cascade.nim
+++ b/src/css/cascade.nim
@@ -118,63 +118,63 @@ func calcRules(styledNode: StyledNode; sheet: CSSStylesheet): RuleList =
     for item in tosorts[i]:
       result[i].add(item[1])
 
-func calcPresentationalHints(element: Element): CSSComputedValues =
-  template set_cv(a, b: untyped) =
-    if result == nil:
-      new(result)
-    result{a} = b
+func calcPresHints(element: Element): seq[CSSComputedEntry] =
+  result = @[]
+  template set_cv(t, x, b: untyped) =
+    const v = valueType(t)
+    result.add(makeEntry(t, CSSComputedValue(v: v, x: b)))
   template map_width =
     let s = parseDimensionValues(element.attr(satWidth))
     if s.isSome:
-      set_cv "width", s.get
+      set_cv cptWidth, length, s.get
   template map_height =
     let s = parseDimensionValues(element.attr(satHeight))
     if s.isSome:
-      set_cv "height", s.get
+      set_cv cptHeight, length, s.get
   template map_width_nozero =
     let s = parseDimensionValues(element.attr(satWidth))
     if s.isSome and s.get.num != 0:
-      set_cv "width", s.get
+      set_cv cptWidth, length, s.get
   template map_height_nozero =
     let s = parseDimensionValues(element.attr(satHeight))
     if s.isSome and s.get.num != 0:
-      set_cv "height", s.get
+      set_cv cptHeight, length, s.get
   template map_bgcolor =
     let s = element.attr(satBgcolor)
     if s != "":
       let c = parseLegacyColor(s)
       if c.isSome:
-        set_cv "background-color", c.get.cssColor()
+        set_cv cptBackgroundColor, color, c.get.cssColor()
   template map_size =
     let s = element.attrul(satSize)
     if s.isSome:
-      set_cv "width", CSSLength(num: float64(s.get), u: cuCh)
+      set_cv cptWidth, length, CSSLength(num: float64(s.get), u: cuCh)
   template map_text =
     let s = element.attr(satText)
     if s != "":
       let c = parseLegacyColor(s)
       if c.isSome:
-        set_cv "color", c.get.cssColor()
+        set_cv cptColor, color, c.get.cssColor()
   template map_color =
     let s = element.attr(satColor)
     if s != "":
       let c = parseLegacyColor(s)
       if c.isSome:
-        set_cv "color", c.get.cssColor()
+        set_cv cptColor, color, c.get.cssColor()
   template map_colspan =
     let colspan = element.attrulgz(satColspan)
     if colspan.isSome:
       let i = colspan.get
       if i <= 1000:
-        set_cv "-cha-colspan", int(i)
+        set_cv cptChaColspan, integer, int(i)
   template map_rowspan =
     let rowspan = element.attrul(satRowspan)
     if rowspan.isSome:
       let i = rowspan.get
       if i <= 65534:
-        set_cv "-cha-rowspan", int(i)
+        set_cv cptChaRowspan, integer, int(i)
   template set_bgcolor_is_canvas =
-    set_cv "-cha-bgcolor-is-canvas", true
+    set_cv cptBgcolorIsCanvas, bgcolorIsCanvas, true
 
   case element.tagType
   of TAG_TABLE:
@@ -208,8 +208,8 @@ func calcPresentationalHints(element: Element): CSSComputedValues =
     let textarea = HTMLTextAreaElement(element)
     let cols = textarea.attrul(satCols).get(20)
     let rows = textarea.attrul(satRows).get(1)
-    set_cv "width", CSSLength(u: cuCh, num: float64(cols))
-    set_cv "height", CSSLength(u: cuEm, num: float64(rows))
+    set_cv cptWidth, length, CSSLength(u: cuCh, num: float64(cols))
+    set_cv cptHeight, length, CSSLength(u: cuEm, num: float64(rows))
   of TAG_FONT:
     map_color
   of TAG_INPUT:
@@ -225,31 +225,29 @@ type
 
   CSSValueEntryMap = array[CSSOrigin, CSSValueEntryObj]
 
-func buildComputedValues(rules: CSSValueEntryMap; presHints, parent:
-    CSSComputedValues): CSSComputedValues =
+func buildComputedValues(rules: CSSValueEntryMap;
+    presHints: openArray[CSSComputedEntry]; parent: CSSComputedValues):
+    CSSComputedValues =
   new(result)
-  var previousOrigins: array[CSSOrigin, CSSComputedValues]
   for entry in rules[coUserAgent].normal: # user agent
     result.applyValue(entry, parent, nil)
-  previousOrigins[coUserAgent] = result.copyProperties()
+  let uaProperties = result.copyProperties()
   # Presentational hints override user agent style, but respect user/author
   # style.
-  if presHints != nil:
-    for prop in CSSPropertyType:
-      if presHints[prop] != nil:
-        result[prop] = presHints[prop]
+  for entry in presHints:
+    result.applyValue(entry, nil, nil)
   for entry in rules[coUser].normal: # user
-    result.applyValue(entry, parent, previousOrigins[coUserAgent])
-  # save user origins so author can use them
-  previousOrigins[coUser] = result.copyProperties()
+    result.applyValue(entry, parent, uaProperties)
+  # save user properties so author can use them
+  let userProperties = result.copyProperties()
   for entry in rules[coAuthor].normal: # author
-    result.applyValue(entry, parent, previousOrigins[coUser])
+    result.applyValue(entry, parent, userProperties)
   # no need to save user origins
   for entry in rules[coAuthor].important: # author important
-    result.applyValue(entry, parent, previousOrigins[coUser])
+    result.applyValue(entry, parent, userProperties)
   # important, so no need to save origins
   for entry in rules[coUser].important: # user important
-    result.applyValue(entry, parent, previousOrigins[coUserAgent])
+    result.applyValue(entry, parent, uaProperties)
   # important, so no need to save origins
   for entry in rules[coUserAgent].important: # user agent important
     result.applyValue(entry, parent, nil)
@@ -257,7 +255,7 @@ func buildComputedValues(rules: CSSValueEntryMap; presHints, parent:
   # set defaults
   for prop in CSSPropertyType:
     if result[prop] == nil:
-      if prop.inherited and parent != nil and parent[prop] != nil:
+      if prop.inherited and parent != nil:
         result[prop] = parent[prop]
       else:
         result[prop] = getDefault(prop)
@@ -275,7 +273,7 @@ proc add(map: var CSSValueEntryObj; rules: seq[CSSRuleDef]) =
 proc applyDeclarations(styledNode: StyledNode; parent: CSSComputedValues;
     map: RuleListMap; styling: bool) =
   var rules: CSSValueEntryMap
-  var presHints: CSSComputedValues = nil
+  var presHints: seq[CSSComputedEntry] = @[]
   rules[coUserAgent].add(map.ua[peNone])
   rules[coUser].add(map.user[peNone])
   for rule in map.author:
@@ -290,7 +288,7 @@ proc applyDeclarations(styledNode: StyledNode; parent: CSSComputedValues;
           rules[coAuthor].important.add(vals)
         else:
           rules[coAuthor].normal.add(vals)
-    presHints = element.calcPresentationalHints()
+    presHints = element.calcPresHints()
   styledNode.computed = rules.buildComputedValues(presHints, parent)
 
 func hasValues(rules: CSSValueEntryMap): bool =
@@ -308,7 +306,7 @@ proc applyDeclarations(pseudo: PseudoElem; styledParent: StyledNode;
   for rule in map.author:
     rules[coAuthor].add(rule[pseudo])
   if rules.hasValues():
-    let cvals = rules.buildComputedValues(nil, styledParent.computed)
+    let cvals = rules.buildComputedValues([], styledParent.computed)
     return styledParent.newStyledElement(pseudo, cvals)
   return nil
 
diff --git a/src/css/cssvalues.nim b/src/css/cssvalues.nim
index d9771917..0ee1a7ed 100644
--- a/src/css/cssvalues.nim
+++ b/src/css/cssvalues.nim
@@ -407,10 +407,10 @@ type
     coUser
     coAuthor
 
-  CSSComputedEntry* = tuple
-    t: CSSPropertyType
-    val: CSSComputedValue
-    global: CSSGlobalType
+  CSSComputedEntry* = object
+    t*: CSSPropertyType
+    obj*: CSSComputedValue
+    global*: CSSGlobalType
 
 const ValueTypes = [
   cptNone: cvtNone,
@@ -487,7 +487,7 @@ func shorthandType(s: string): CSSShorthandType =
 func propertyType(s: string): CSSPropertyType =
   return parseEnumNoCase[CSSPropertyType](s).get(cptNone)
 
-func valueType(prop: CSSPropertyType): CSSValueType =
+func valueType*(prop: CSSPropertyType): CSSValueType =
   return ValueTypes[prop]
 
 func isSupportedProperty*(s: string): bool =
@@ -1170,6 +1170,16 @@ func cssNumber(cval: CSSComponentValue; positive: bool): Opt[float64] =
         return ok(tok.nvalue)
   return err()
 
+proc makeEntry*(t: CSSPropertyType; obj: CSSComputedValue): CSSComputedEntry =
+  return CSSComputedEntry(t: t, obj: obj)
+
+proc makeEntry*(t: CSSPropertyType; global: CSSGlobalType): CSSComputedEntry =
+  return CSSComputedEntry(t: t, global: global)
+
+proc makeEntry*(t: CSSPropertyType; obj: CSSComputedValue;
+    global: CSSGlobalType): CSSComputedEntry =
+  return CSSComputedEntry(t: t, obj: obj, global: global)
+
 proc parseValue(cvals: openArray[CSSComponentValue]; t: CSSPropertyType):
     Opt[CSSComputedValue] =
   var i = 0
@@ -1302,7 +1312,7 @@ func lengthShorthand(cvals: openArray[CSSComponentValue];
   var res: seq[CSSComputedEntry] = @[]
   if global != cgtNone:
     for t in props:
-      res.add((t, nil, global))
+      res.add(makeEntry(t, global))
     return ok(res)
   var lengths: seq[CSSComputedValue] = @[]
   var i = 0
@@ -1315,10 +1325,10 @@ func lengthShorthand(cvals: openArray[CSSComponentValue];
   case lengths.len
   of 1: # top, bottom, left, right
     for i, t in props.mypairs:
-      res.add((t, lengths[0], cgtNone))
+      res.add(makeEntry(t, lengths[0]))
   of 2: # top, bottom | left, right
     for i, t in props.mypairs:
-      res.add((t, lengths[i mod 2], cgtNone))
+      res.add(makeEntry(t, lengths[i mod 2]))
   of 3: # top | left, right | bottom
     for i, t in props.mypairs:
       let j = if i == 0:
@@ -1327,10 +1337,10 @@ func lengthShorthand(cvals: openArray[CSSComponentValue];
         2 # bottom
       else:
         1 # left, right
-      res.add((t, lengths[j], cgtNone))
+      res.add(makeEntry(t, lengths[j]))
   of 4: # top | right | bottom | left
     for i, t in props.mypairs:
-      res.add((t, lengths[i], cgtNone))
+      res.add(makeEntry(t, lengths[i]))
   else:
     return err()
   return ok(res)
@@ -1354,14 +1364,14 @@ proc parseComputedValues*(res: var seq[CSSComputedEntry]; name: string;
   of cstNone:
     let t = propertyType(name)
     if global != cgtNone:
-      res.add((t, nil, global))
+      res.add(makeEntry(t, global))
     else:
-      res.add((t, ?cvals.parseValue(t), global))
+      res.add(makeEntry(t, ?cvals.parseValue(t)))
   of cstAll:
     if global == cgtNone:
       return err()
     for t in CSSPropertyType:
-      res.add((t, nil, global))
+      res.add(makeEntry(t, global))
   of cstMargin:
     res.add(?lengthShorthand(cvals, PropertyMarginSpec, global))
   of cstPadding:
@@ -1384,8 +1394,8 @@ proc parseComputedValues*(res: var seq[CSSComputedEntry]; name: string;
           #valid = false
           discard
     if valid:
-      res.add((cptBackgroundColor, bgcolorval, global))
-      res.add((cptBackgroundImage, bgimageval, global))
+      res.add(makeEntry(cptBackgroundColor, bgcolorval, global))
+      res.add(makeEntry(cptBackgroundImage, bgimageval, global))
   of cstListStyle:
     var positionVal = getDefault(cptListStylePosition)
     var typeVal = getDefault(cptListStyleType)
@@ -1409,8 +1419,8 @@ proc parseComputedValues*(res: var seq[CSSComputedEntry]; name: string;
           #valid = false
           discard
     if valid:
-      res.add((cptListStylePosition, positionVal, global))
-      res.add((cptListStyleType, typeVal, global))
+      res.add(makeEntry(cptListStylePosition, positionVal, global))
+      res.add(makeEntry(cptListStyleType, typeVal, global))
   of cstFlex:
     if global == cgtNone:
       var i = 0
@@ -1420,7 +1430,7 @@ proc parseComputedValues*(res: var seq[CSSComputedEntry]; name: string;
       if (let r = cssNumber(cvals[i], positive = true); r.isSome):
         # flex-grow
         let val = CSSComputedValue(v: cvtNumber, number: r.get)
-        res.add((cptFlexGrow, val, global))
+        res.add(makeEntry(cptFlexGrow, val))
         inc i
         cvals.skipWhitespace(i)
         if i < cvals.len:
@@ -1429,29 +1439,29 @@ proc parseComputedValues*(res: var seq[CSSComputedEntry]; name: string;
           if (let r = cssNumber(cvals[i], positive = true); r.isSome):
             # flex-shrink
             let val = CSSComputedValue(v: cvtNumber, number: r.get)
-            res.add((cptFlexShrink, val, global))
+            res.add(makeEntry(cptFlexShrink, val))
             inc i
             cvals.skipWhitespace(i)
       if res.len < 1: # flex-grow omitted, default to 1
         let val = CSSComputedValue(v: cvtNumber, number: 1)
-        res.add((cptFlexGrow, val, global))
+        res.add(makeEntry(cptFlexGrow, val))
       if res.len < 2: # flex-shrink omitted, default to 1
         let val = CSSComputedValue(v: cvtNumber, number: 1)
-        res.add((cptFlexShrink, val, global))
+        res.add(makeEntry(cptFlexShrink, val))
       if i < cvals.len:
         # flex-basis
         let val = CSSComputedValue(v: cvtLength, length: ?cssLength(cvals[i]))
-        res.add((cptFlexBasis, val, global))
+        res.add(makeEntry(cptFlexBasis, val))
       else: # omitted, default to 0px
         let val = CSSComputedValue(
           v: cvtLength,
           length: CSSLength(u: cuPx, num: 0)
         )
-        res.add((cptFlexBasis, val, global))
+        res.add(makeEntry(cptFlexBasis, val, global))
     else:
-      res.add((cptFlexGrow, getDefault(cptFlexGrow), global))
-      res.add((cptFlexShrink, getDefault(cptFlexShrink), global))
-      res.add((cptFlexBasis, getDefault(cptFlexBasis), global))
+      res.add(makeEntry(cptFlexGrow, global))
+      res.add(makeEntry(cptFlexShrink, global))
+      res.add(makeEntry(cptFlexBasis, global))
   of cstFlexFlow:
     if global == cgtNone:
       var i = 0
@@ -1461,16 +1471,16 @@ proc parseComputedValues*(res: var seq[CSSComputedEntry]; name: string;
       if (let dir = parseIdent[CSSFlexDirection](cvals[i]); dir.isSome):
         # flex-direction
         let val = CSSComputedValue(v: cvtFlexDirection, flexdirection: dir.get)
-        res.add((cptFlexDirection, val, global))
+        res.add(makeEntry(cptFlexDirection, val))
         inc i
         cvals.skipWhitespace(i)
       if i < cvals.len:
         let wrap = ?parseIdent[CSSFlexWrap](cvals[i])
         let val = CSSComputedValue(v: cvtFlexWrap, flexwrap: wrap)
-        res.add((cptFlexWrap, val, global))
+        res.add(makeEntry(cptFlexWrap, val))
     else:
-      res.add((cptFlexDirection, getDefault(cptFlexDirection), global))
-      res.add((cptFlexWrap, getDefault(cptFlexWrap), global))
+      res.add(makeEntry(cptFlexDirection, global))
+      res.add(makeEntry(cptFlexWrap, global))
   return ok()
 
 proc parseComputedValues*(name: string; value: seq[CSSComponentValue]):
@@ -1506,12 +1516,12 @@ proc applyValue*(vals: CSSComputedValues; entry: CSSComputedEntry;
     else:
       vals[entry.t] = getDefault(entry.t)
   of cgtNone:
-    vals[entry.t] = entry.val
+    vals[entry.t] = entry.obj
 
 func inheritProperties*(parent: CSSComputedValues): CSSComputedValues =
   new(result)
   for prop in CSSPropertyType:
-    if inherited(prop) and parent[prop] != nil:
+    if inherited(prop):
       result[prop] = parent[prop]
     else:
       result[prop] = getDefault(prop)