about summary refs log tree commit diff stats
path: root/src/css
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2024-02-17 13:06:22 +0100
committerbptato <nincsnevem662@gmail.com>2024-02-17 13:06:22 +0100
commit4e264e9d75844382e81bd8315671ca7e2f7bade3 (patch)
tree6f12c6936d69e7e1c2f209831e9f60c5c52498af /src/css
parenta5ed422c2ceab87b174bae276bd10095bd6bed2e (diff)
downloadchawan-4e264e9d75844382e81bd8315671ca7e2f7bade3.tar.gz
css: reduce CSSComputedValue size
The `t' field was completely redundant, as it's already included in the
CSSComputedValues index.

+ removed some unused functions
Diffstat (limited to 'src/css')
-rw-r--r--src/css/cascade.nim8
-rw-r--r--src/css/values.nim206
2 files changed, 96 insertions, 118 deletions
diff --git a/src/css/cascade.nim b/src/css/cascade.nim
index 7741f80a..13282b4f 100644
--- a/src/css/cascade.nim
+++ b/src/css/cascade.nim
@@ -254,8 +254,7 @@ func calcPresentationalHints(element: Element): CSSComputedValues =
 proc applyDeclarations(styledNode: StyledNode, parent: CSSComputedValues,
     map: DeclarationListMap) =
   let pseudo = PSEUDO_NONE
-  var builder = newComputedValueBuilder(parent)
-
+  var builder = CSSComputedValuesBuilder(parent: parent)
   builder.addValues(map.ua[pseudo], ORIGIN_USER_AGENT)
   builder.addValues(map.user[pseudo], ORIGIN_USER)
   for rule in map.author:
@@ -266,19 +265,16 @@ proc applyDeclarations(styledNode: StyledNode, parent: CSSComputedValues,
     if style != nil:
       builder.addValues(style.decls, ORIGIN_AUTHOR)
     builder.preshints = element.calcPresentationalHints()
-
   styledNode.computed = builder.buildComputedValues()
 
 # Either returns a new styled node or nil.
 proc applyDeclarations(pseudo: PseudoElem, styledParent: StyledNode,
     map: DeclarationListMap): StyledNode =
-  var builder = newComputedValueBuilder(styledParent.computed)
-
+  var builder = CSSComputedValuesBuilder(parent: styledParent.computed)
   builder.addValues(map.ua[pseudo], ORIGIN_USER_AGENT)
   builder.addValues(map.user[pseudo], ORIGIN_USER)
   for rule in map.author:
     builder.addValues(rule[pseudo], ORIGIN_AUTHOR)
-
   if builder.hasValues():
     let cvals = builder.buildComputedValues()
     result = styledParent.newStyledElement(pseudo, cvals)
diff --git a/src/css/values.nim b/src/css/values.nim
index 93864212..bad8ef4a 100644
--- a/src/css/values.nim
+++ b/src/css/values.nim
@@ -172,7 +172,6 @@ type
     num*: int
 
   CSSComputedValue* = ref object
-    t*: CSSPropertyType
     case v*: CSSValueType
     of VALUE_COLOR:
       color*: RGBAColor
@@ -235,16 +234,17 @@ type
     ORIGIN_USER
     ORIGIN_AUTHOR
 
-  CSSComputedValueBuilder = object
-    global: CSSGlobalValueType
+  CSSComputedEntry = tuple
+    t: CSSPropertyType
     val: CSSComputedValue
+    global: CSSGlobalValueType
 
-  CSSComputedValueBuilders = seq[CSSComputedValueBuilder]
+  CSSComputedEntries = seq[CSSComputedEntry]
 
   CSSComputedValuesBuilder* = object
-    parent: CSSComputedValues
-    normalProperties: array[CSSOrigin, CSSComputedValueBuilders]
-    importantProperties: array[CSSOrigin, CSSComputedValueBuilders]
+    parent*: CSSComputedValues
+    normalProperties: array[CSSOrigin, CSSComputedEntries]
+    importantProperties: array[CSSOrigin, CSSComputedEntries]
     preshints*: CSSComputedValues
 
 const ShorthandNames = {
@@ -391,7 +391,8 @@ func isSupportedProperty*(s: string): bool =
 func `$`*(length: CSSLength): string =
   if length.auto:
     return "auto"
-  let us = ($length.unit).split('_')[1..^1].join('_').toLowerAscii()
+  let ss = ($length.unit).split('_')
+  let us = ss.toOpenArray(1, ss.high).join('_').toLowerAscii()
   return $length.num & us
 
 func `$`*(content: CSSContent): string =
@@ -400,7 +401,6 @@ func `$`*(content: CSSContent): string =
   return "none"
 
 func `$`*(val: CSSComputedValue): string =
-  result = ($val.t).toLowerAscii().split('_')[1..^1].join('-') & ": "
   case val.v
   of VALUE_COLOR:
     result &= $val.color
@@ -408,23 +408,26 @@ func `$`*(val: CSSComputedValue): string =
     result &= $val.image
   of VALUE_LENGTH:
     result &= $val.length
-  else: discard
+  else:
+    result = $val.v
 
 macro `{}`*(vals: CSSComputedValues, s: string): untyped =
   let t = propertyType($s)
   let vs = $valueType(t)
-  let s = vs.split('_')[1..^1].join('_').toLowerAscii()
-  result = newDotExpr(newTree(nnkBracketExpr, vals, newLit(t)), newIdentNode(s))
+  let vss = vs.split('_')
+  let s = vss.toOpenArray(1, vss.high).join('_').toLowerAscii()
+  return newDotExpr(newTree(nnkBracketExpr, vals, newLit(t)), newIdentNode(s))
 
 macro `{}=`*(vals: CSSComputedValues, s: string, val: typed) =
   let t = propertyType($s)
   let v = valueType(t)
   let vs = $v
-  let s = vs.split('_')[1..^1].join('_').toLowerAscii()
+  let vss = vs.split('_')
+  let s = vss.toOpenArray(1, vss.high).join('_').toLowerAscii()
   let id = ident(s)
   let expr = newTree(nnkBracketExpr, vals, newLit(t))
-  result = quote do:
-    `expr` = CSSComputedValue(t: CSSPropertyType(`t`), v: CSSValueType(`v`), `id`: `val`)
+  return quote do:
+    `expr` = CSSComputedValue(v: CSSValueType(`v`), `id`: `val`)
 
 func inherited(t: CSSPropertyType): bool =
   return InheritedArray[t]
@@ -443,7 +446,8 @@ func ic_to_px(ic: float64, window: WindowAttributes): LayoutUnit =
 func ex_to_px(ex: float64, window: WindowAttributes): LayoutUnit =
   ex * float64(window.ppc) / 2
 
-func px*(l: CSSLength, window: WindowAttributes, p: LayoutUnit): LayoutUnit {.inline.} =
+func px*(l: CSSLength, window: WindowAttributes, p: LayoutUnit): LayoutUnit
+    {.inline.} =
   case l.unit
   of UNIT_EM, UNIT_REM: em_to_px(l.num, window)
   of UNIT_CH: ch_to_px(l.num, window)
@@ -877,8 +881,7 @@ func cssWordBreak(cval: CSSComponentValue): Opt[CSSWordBreak] =
   }
   return cssIdent(WordBreakMap, cval)
 
-func cssListStyleType(cval: CSSComponentValue):
-    Opt[CSSListStyleType] =
+func cssListStyleType(cval: CSSComponentValue): Opt[CSSListStyleType] =
   const ListStyleMap = {
     "none": LIST_STYLE_TYPE_NONE,
     "disc": LIST_STYLE_TYPE_DISC,
@@ -904,8 +907,7 @@ func cssListStyleType(cval: CSSComponentValue):
   }
   return cssIdent(ListStyleMap, cval)
 
-func cssVerticalAlign(cval: CSSComponentValue):
-    Opt[CSSVerticalAlign] =
+func cssVerticalAlign(cval: CSSComponentValue): Opt[CSSVerticalAlign] =
   if isToken(cval):
     let tok = getToken(cval)
     if tok.tokenType == CSS_IDENT_TOKEN:
@@ -954,8 +956,7 @@ func cssTextAlign(cval: CSSComponentValue): Opt[CSSTextAlign] =
   }
   return cssIdent(TextAlignMap, cval)
 
-func cssListStylePosition(cval: CSSComponentValue):
-    Opt[CSSListStylePosition] =
+func cssListStylePosition(cval: CSSComponentValue): Opt[CSSListStylePosition] =
   const ListStylePositionMap = {
     "inside": LIST_STYLE_POSITION_INSIDE,
     "outside": LIST_STYLE_POSITION_OUTSIDE
@@ -985,8 +986,7 @@ func cssCaptionSide(cval: CSSComponentValue): Opt[CSSCaptionSide] =
   }
   return cssIdent(CaptionSideMap, cval)
 
-func cssBorderCollapse(cval: CSSComponentValue):
-    Opt[CSSBorderCollapse] =
+func cssBorderCollapse(cval: CSSComponentValue): Opt[CSSBorderCollapse] =
   const BorderCollapseMap = {
     "collapse": BORDER_COLLAPSE_COLLAPSE,
     "separate": BORDER_COLLAPSE_SEPARATE
@@ -1063,8 +1063,7 @@ func cssImage(cval: CSSComponentValue): Opt[CSSContent] =
     return ok(CSSContent(t: CONTENT_IMAGE, s: url.get))
   return err()
 
-func cssInteger(cval: CSSComponentValue, range: Slice[int]):
-    Opt[int] =
+func cssInteger(cval: CSSComponentValue, range: Slice[int]): Opt[int] =
   if isToken(cval):
     let tok = getToken(cval)
     if tok.tokenType == CSS_NUMBER_TOKEN:
@@ -1238,19 +1237,19 @@ func calcInitial(t: CSSPropertyType): CSSComputedValue =
   var nv: CSSComputedValue
   case v
   of VALUE_COLOR:
-    nv = CSSComputedValue(t: t, v: v, color: getInitialColor(t))
+    nv = CSSComputedValue(v: v, color: getInitialColor(t))
   of VALUE_DISPLAY:
-    nv = CSSComputedValue(t: t, v: v, display: DISPLAY_INLINE)
+    nv = CSSComputedValue(v: v, display: DISPLAY_INLINE)
   of VALUE_WORD_BREAK:
-    nv = CSSComputedValue(t: t, v: v, wordbreak: WORD_BREAK_NORMAL)
+    nv = CSSComputedValue(v: v, wordbreak: WORD_BREAK_NORMAL)
   of VALUE_LENGTH:
-    nv = CSSComputedValue(t: t, v: v, length: getInitialLength(t))
+    nv = CSSComputedValue(v: v, length: getInitialLength(t))
   of VALUE_INTEGER:
-    nv = CSSComputedValue(t: t, v: v, integer: getInitialInteger(t))
+    nv = CSSComputedValue(v: v, integer: getInitialInteger(t))
   of VALUE_QUOTES:
-    nv = CSSComputedValue(t: t, v: v, quotes: CSSQuotes(auto: true))
+    nv = CSSComputedValue(v: v, quotes: CSSQuotes(auto: true))
   else:
-    nv = CSSComputedValue(t: t, v: v)
+    nv = CSSComputedValue(v: v)
   return nv
 
 func getInitialTable(): array[CSSPropertyType, CSSComputedValue] =
@@ -1263,45 +1262,43 @@ template getDefault(t: CSSPropertyType): CSSComputedValue =
   {.cast(noSideEffect).}:
     defaultTable[t]
 
-type CSSComputedValueMaybeGlobal = (CSSComputedValue, CSSGlobalValueType)
-
 func getComputedValue(d: CSSDeclaration, ptype: CSSPropertyType,
-    vtype: CSSValueType): Opt[CSSComputedValueMaybeGlobal] =
+    vtype: CSSValueType): Opt[CSSComputedEntry] =
   let global = cssGlobal(d)
-  let val = CSSComputedValue(t: ptype, v: vtype)
+  let val = CSSComputedValue(v: vtype)
   if global != VALUE_NOGLOBAL:
-    return ok((val, global))
+    return ok((ptype, val, global))
   ?val.getValueFromDecl(d, vtype, ptype)
-  return ok((val, global))
+  return ok((ptype, val, global))
 
 func lengthShorthand(d: CSSDeclaration, props: array[4, CSSPropertyType]):
-    Opt[seq[(CSSComputedValue, CSSGlobalValueType)]] =
+    Opt[seq[CSSComputedEntry]] =
   var i = 0
   var cvals: seq[CSSComponentValue]
   while i < d.value.len:
     if d.value[i] != CSS_WHITESPACE_TOKEN:
       cvals.add(d.value[i])
     inc i
-  var res: seq[(CSSComputedValue, CSSGlobalValueType)]
+  var res: seq[CSSComputedEntry]
   case cvals.len
   of 1: # top, bottom, left, right
     for ptype in props:
       let vtype = valueType(ptype)
-      let val = CSSComputedValue(t: ptype, v: vtype)
+      let val = CSSComputedValue(v: vtype)
       ?val.getValueFromDecl(d, vtype, ptype)
-      res.add((val, cssGlobal(d)))
+      res.add((ptype, val, cssGlobal(d)))
   of 2: # top, bottom | left, right
     for i in 0 ..< props.len:
       let ptype = props[i]
       let vtype = valueType(ptype)
-      let val = CSSComputedValue(t: ptype, v: vtype)
+      let val = CSSComputedValue(v: vtype)
       val.length = ?cssLength(cvals[i mod 2])
-      res.add((val, cssGlobal(d)))
+      res.add((ptype, val, cssGlobal(d)))
   of 3: # top | left, right | bottom
     for i in 0 ..< props.len:
       let ptype = props[i]
       let vtype = valueType(ptype)
-      let val = CSSComputedValue(t: ptype, v: vtype)
+      let val = CSSComputedValue(v: vtype)
       let j = if i == 0:
         0 # top
       elif i == 3:
@@ -1309,14 +1306,14 @@ func lengthShorthand(d: CSSDeclaration, props: array[4, CSSPropertyType]):
       else:
         1 # left, right
       val.length = ?cssLength(cvals[j])
-      res.add((val, cssGlobal(d)))
+      res.add((ptype, val, cssGlobal(d)))
   of 4: # top | right | bottom | left
     for i in 0 ..< props.len:
       let ptype = props[i]
       let vtype = valueType(ptype)
-      let val = CSSComputedValue(t: ptype, v: vtype)
+      let val = CSSComputedValue(v: vtype)
       val.length = ?cssLength(cvals[i])
-      res.add((val, cssGlobal(d)))
+      res.add((ptype, val, cssGlobal(d)))
   else: discard
   return ok(res)
 
@@ -1330,13 +1327,11 @@ const PropertyPaddingSpec = [
   PROPERTY_PADDING_LEFT
 ]
 
-proc getComputedValues0(d: CSSDeclaration):
-    Opt[seq[(CSSComputedValue, CSSGlobalValueType)]] =
-  let name = d.name
-  var res: seq[(CSSComputedValue, CSSGlobalValueType)]
-  case shorthandType(name)
+proc getComputedValues0(res: var seq[CSSComputedEntry], d: CSSDeclaration):
+    Err[void] =
+  case shorthandType(d.name)
   of SHORTHAND_NONE:
-    let ptype = propertyType(name)
+    let ptype = propertyType(d.name)
     let vtype = valueType(ptype)
     res.add(?getComputedValue(d, ptype, vtype))
   of SHORTHAND_ALL:
@@ -1344,8 +1339,8 @@ proc getComputedValues0(d: CSSDeclaration):
     if global != VALUE_NOGLOBAL:
       for ptype in CSSPropertyType:
         let vtype = valueType(ptype)
-        let val = CSSComputedValue(t: ptype, v: vtype)
-        res.add((val, global))
+        let val = CSSComputedValue(v: vtype)
+        res.add((ptype, val, global))
   of SHORTHAND_MARGIN:
     res.add(?lengthShorthand(d, PropertyMarginSpec))
   of SHORTHAND_PADDING:
@@ -1353,9 +1348,9 @@ proc getComputedValues0(d: CSSDeclaration):
   of SHORTHAND_BACKGROUND:
     let global = cssGlobal(d)
     let bgcolorptype = PROPERTY_BACKGROUND_COLOR
-    let bgcolorval = CSSComputedValue(t: bgcolorptype, v: valueType(bgcolorptype))
+    let bgcolorval = CSSComputedValue(v: valueType(bgcolorptype))
     let bgimageptype = PROPERTY_BACKGROUND_IMAGE
-    let bgimageval = CSSComputedValue(t: bgimageptype, v: valueType(bgimageptype))
+    let bgimageval = CSSComputedValue(v: valueType(bgimageptype))
     if global == VALUE_NOGLOBAL:
       for tok in d.value:
         if tok == CSS_WHITESPACE_TOKEN:
@@ -1363,73 +1358,53 @@ proc getComputedValues0(d: CSSDeclaration):
         let r = cssImage(tok)
         if r.isOk:
           bgimageval.image = r.get
-          res.add((bgimageval, global))
+          res.add((bgimageptype, bgimageval, global))
         else:
           let r = cssColor(tok)
           if r.isOk:
             bgcolorval.color = r.get
-            res.add((bgcolorval, global))
+            res.add((bgcolorptype, bgcolorval, global))
     else:
-      res.add((bgcolorval, global))
+      res.add((bgcolorptype, bgcolorval, global))
   of SHORTHAND_LIST_STYLE:
     let global = cssGlobal(d)
     let positionptype = PROPERTY_LIST_STYLE_POSITION
-    let positionval = CSSComputedValue(t: positionptype, v: valueType(positionptype))
+    let positionval = CSSComputedValue(v: valueType(positionptype))
     let typeptype = PROPERTY_LIST_STYLE_TYPE
-    let typeval = CSSComputedValue(t: typeptype, v: valueType(typeptype))
+    let typeval = CSSComputedValue(v: valueType(typeptype))
     if global == VALUE_NOGLOBAL:
       for tok in d.value:
         let r = cssListStylePosition(tok)
         if r.isOk:
           positionval.liststyleposition = r.get
-          res.add((positionval, global))
+          res.add((positionptype, positionval, global))
         else:
           let r = cssListStyleType(tok)
           if r.isOk:
             typeval.liststyletype = r.get
-            res.add((typeval, global))
+            res.add((typeptype, typeval, global))
           else:
             #TODO list-style-image
             discard
-  return ok(res)
-
-proc getComputedValues(d: CSSDeclaration):
-    seq[(CSSComputedValue, CSSGlobalValueType)] =
-  return getComputedValues0(d).get(@[])
+  return ok()
 
-proc newComputedValueBuilder*(parent: CSSComputedValues): CSSComputedValuesBuilder =
-  return CSSComputedValuesBuilder(
-    parent: parent
-  )
+proc getComputedValues(d: CSSDeclaration): seq[CSSComputedEntry] =
+  var res: seq[CSSComputedEntry] = @[]
+  if res.getComputedValues0(d).isOk:
+    return res
+  return @[]
 
-proc addValuesImportant*(builder: var CSSComputedValuesBuilder, decls: seq[CSSDeclaration], origin: CSSOrigin) =
+proc addValues*(builder: var CSSComputedValuesBuilder,
+    decls: seq[CSSDeclaration], origin: CSSOrigin) =
   for decl in decls:
     if decl.important:
-      let vals = getComputedValues(decl)
-      for vg in vals:
-        let (val, global) = vg
-        builder.importantProperties[origin].add(CSSComputedValueBuilder(val: val, global: global))
-
-proc addValuesNormal*(builder: var CSSComputedValuesBuilder, decls: seq[CSSDeclaration], origin: CSSOrigin) =
-  for decl in decls:
-    if not decl.important:
-      let vals = getComputedValues(decl)
-      for vg in vals:
-        let (val, global) = vg
-        builder.normalProperties[origin].add(CSSComputedValueBuilder(val: val, global: global))
-
-proc addValues*(builder: var CSSComputedValuesBuilder, decls: seq[CSSDeclaration], origin: CSSOrigin) =
-  for decl in decls:
-    let vals = getComputedValues(decl)
-    for vg in vals:
-      let (val, global) = vg
-      if decl.important:
-        builder.importantProperties[origin].add(CSSComputedValueBuilder(val: val, global: global))
-      else:
-        builder.normalProperties[origin].add(CSSComputedValueBuilder(val: val, global: global))
+      builder.importantProperties[origin].add(getComputedValues(decl))
+    else:
+      builder.normalProperties[origin].add(getComputedValues(decl))
 
-proc applyValue(vals: CSSComputedValues, val: CSSComputedValue, global: CSSGlobalValueType, parent: CSSComputedValues, previousOrigin: CSSComputedValues) =
-  let prop = val.t
+proc applyValue(vals: CSSComputedValues, prop: CSSPropertyType,
+    val: CSSComputedValue, global: CSSGlobalValueType,
+    parent: CSSComputedValues, previousOrigin: CSSComputedValues) =
   let parentVal = if parent != nil:
     parent[prop]
   else:
@@ -1470,8 +1445,7 @@ func inheritProperties*(parent: CSSComputedValues): CSSComputedValues =
 
 func copyProperties*(props: CSSComputedValues): CSSComputedValues =
   new(result)
-  for prop in CSSPropertyType:
-    result[prop] = props[prop]
+  result[] = props[]
 
 func rootProperties*(): CSSComputedValues =
   new(result)
@@ -1486,15 +1460,17 @@ func hasValues*(builder: CSSComputedValuesBuilder): bool =
       return true
   return false
 
-func buildComputedValues*(builder: CSSComputedValuesBuilder): CSSComputedValues =
+func buildComputedValues*(builder: CSSComputedValuesBuilder):
+    CSSComputedValues =
   new(result)
   var previousOrigins: array[CSSOrigin, CSSComputedValues]
   block:
     let origin = ORIGIN_USER_AGENT
     for build in builder.normalProperties[origin]:
-      result.applyValue(build.val, build.global, builder.parent, nil)
+      result.applyValue(build.t, build.val, build.global, builder.parent, nil)
     previousOrigins[origin] = result.copyProperties()
-  # Presentational hints override user agent style, but respect user/author style.
+  # Presentational hints override user agent style, but respect user/author
+  # style.
   if builder.preshints != nil:
     for prop in CSSPropertyType:
       if builder.preshints[prop] != nil:
@@ -1503,35 +1479,41 @@ func buildComputedValues*(builder: CSSComputedValuesBuilder): CSSComputedValues
     let origin = ORIGIN_USER
     let prevOrigin = ORIGIN_USER_AGENT
     for build in builder.normalProperties[origin]:
-      result.applyValue(build.val, build.global, builder.parent, previousOrigins[prevOrigin])
-    previousOrigins[origin] = result.copyProperties() # save user origins so author can use them
+      result.applyValue(build.t, build.val, build.global, builder.parent,
+        previousOrigins[prevOrigin])
+    # save user origins so author can use them
+    previousOrigins[origin] = result.copyProperties()
   block:
     let origin = ORIGIN_AUTHOR
     let prevOrigin = ORIGIN_USER
     for build in builder.normalProperties[origin]:
-      result.applyValue(build.val, build.global, builder.parent, previousOrigins[prevOrigin])
+      result.applyValue(build.t, build.val, build.global, builder.parent,
+        previousOrigins[prevOrigin])
     # no need to save user origins
   block:
     let origin = ORIGIN_AUTHOR
     let prevOrigin = ORIGIN_USER
     for build in builder.importantProperties[origin]:
-      result.applyValue(build.val, build.global, builder.parent, previousOrigins[prevOrigin])
+      result.applyValue(build.t, build.val, build.global, builder.parent,
+        previousOrigins[prevOrigin])
     # important, so no need to save origins
   block:
     let origin = ORIGIN_USER
     let prevOrigin = ORIGIN_USER_AGENT
     for build in builder.importantProperties[origin]:
-      result.applyValue(build.val, build.global, builder.parent, previousOrigins[prevOrigin])
+      result.applyValue(build.t, build.val, build.global, builder.parent,
+        previousOrigins[prevOrigin])
     # important, so no need to save origins
   block:
     let origin = ORIGIN_USER_AGENT
     for build in builder.importantProperties[origin]:
-      result.applyValue(build.val, build.global, builder.parent, nil)
+      result.applyValue(build.t, build.val, build.global, builder.parent, nil)
     # important, so no need to save origins
   # set defaults
   for prop in CSSPropertyType:
     if result[prop] == nil:
-      if inherited(prop) and builder.parent != nil and builder.parent[prop] != nil:
+      if inherited(prop) and builder.parent != nil and
+          builder.parent[prop] != nil:
         result[prop] = builder.parent[prop]
       else:
         result[prop] = getDefault(prop)