about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2025-01-07 19:23:27 +0100
committerbptato <nincsnevem662@gmail.com>2025-01-07 19:26:17 +0100
commit01dfeb3100befabba9533bc83841dcea877ca3db (patch)
treebb836d0696f3bd79e9a6e65c1f1f58513fc1305a /src
parent78fe13f46af0939859586f888c7961a19b703623 (diff)
downloadchawan-01dfeb3100befabba9533bc83841dcea877ca3db.tar.gz
cssparser, mediaquery: factor out tflagb, fix a media query bug
@media (grid: 1) works again.
Diffstat (limited to 'src')
-rw-r--r--src/css/cssparser.nim66
-rw-r--r--src/css/cssvalues.nim29
-rw-r--r--src/css/mediaquery.nim2
3 files changed, 43 insertions, 54 deletions
diff --git a/src/css/cssparser.nim b/src/css/cssparser.nim
index 769ec5ac..e71a9286 100644
--- a/src/css/cssparser.nim
+++ b/src/css/cssparser.nim
@@ -6,10 +6,11 @@ import utils/twtstr
 
 type
   CSSTokenType* = enum
-    cttIdent, cttFunction, cttAtKeyword, cttHash, cttString, cttBadString,
-    cttUrl, cttBadUrl, cttDelim, cttNumber, cttPercentage, cttDimension,
-    cttWhitespace, cttCdo, cttCdc, cttColon, cttSemicolon, cttComma,
-    cttRbracket, cttLbracket, cttLparen, cttRparen, cttLbrace, cttRbrace
+    cttIdent, cttFunction, cttAtKeyword, cttHash, cttString,
+    cttBadString, cttUrl, cttBadUrl, cttDelim, cttNumber, cttINumber,
+    cttPercentage, cttDimension, cttIDimension, cttWhitespace, cttCdo,
+    cttCdc, cttColon, cttSemicolon, cttComma, cttRbracket, cttLbracket,
+    cttLparen, cttRparen, cttLbrace, cttRbrace
 
   CSSTokenizerState = object
     at: int
@@ -22,21 +23,17 @@ type
   tflaga = enum
     tflagaUnrestricted, tflagaId
 
-  tflagb* = enum
-    tflagbInteger, tflagbNumber
-
   CSSComponentValue* = ref object of RootObj
 
   CSSToken* = ref object of CSSComponentValue
     case t*: CSSTokenType
     of cttIdent, cttFunction, cttAtKeyword, cttHash, cttString, cttUrl:
-      value*: string
       tflaga*: tflaga
+      value*: string
     of cttDelim:
       cvalue*: char
-    of cttNumber, cttPercentage, cttDimension:
+    of cttNumber, cttINumber, cttPercentage, cttDimension, cttIDimension:
       nvalue*: float64
-      tflagb*: tflagb
       unit*: string
     else: discard
 
@@ -69,6 +66,7 @@ type
 
 # For debugging
 proc `$`*(c: CSSComponentValue): string =
+  result = ""
   if c of CSSToken:
     let c = CSSToken(c)
     case c.t:
@@ -87,13 +85,7 @@ proc `$`*(c: CSSComponentValue): string =
         result &= c.cvalue
       else:
         result &= "<UNICODE>"
-    of cttDimension:
-      case c.tflagb
-      of tflagbNumber:
-        result &= $c.nvalue & c.unit
-      of tflagbInteger:
-        result &= $int64(c.nvalue) & c.unit
-    of cttNumber:
+    of cttDimension, cttNumber, cttINumber, cttIDimension:
       result &= $c.nvalue & c.unit
     of cttPercentage:
       result &= $c.nvalue & "%"
@@ -270,8 +262,9 @@ proc consumeIdentSequence(state: var CSSTokenizerState): string =
       break
   return s
 
-proc consumeNumber(state: var CSSTokenizerState): (tflagb, float64) =
-  var t = tflagbInteger
+proc consumeNumber(state: var CSSTokenizerState):
+    tuple[isInt: bool; val: float64] =
+  var isInt = true
   var repr = ""
   if state.has() and state.peek() in {'+', '-'}:
     repr &= state.consume()
@@ -280,7 +273,7 @@ proc consumeNumber(state: var CSSTokenizerState): (tflagb, float64) =
   if state.has(1) and state.peek() == '.' and state.peek(1) in AsciiDigit:
     repr &= state.consume()
     repr &= state.consume()
-    t = tflagbNumber
+    isInt = false
     while state.has() and state.peek() in AsciiDigit:
       repr &= state.consume()
   if state.has(1) and state.peek() in {'E', 'e'} and
@@ -293,25 +286,25 @@ proc consumeNumber(state: var CSSTokenizerState): (tflagb, float64) =
       repr &= state.consume()
     else:
       repr &= state.consume()
-    t = tflagbNumber
+    isInt = false
     while state.has() and state.peek() in AsciiDigit:
       repr &= state.consume()
   let val = parseFloat64(repr)
-  return (t, val)
+  return (isInt, val)
 
 proc consumeNumericToken(state: var CSSTokenizerState): CSSToken =
-  let (t, val) = state.consumeNumber()
+  let (isInt, val) = state.consumeNumber()
   if state.startsWithIdentSequence():
-    return CSSToken(
-      t: cttDimension,
-      nvalue: val,
-      tflagb: t,
-      unit: state.consumeIdentSequence()
-    )
+    let unit = state.consumeIdentSequence()
+    if isInt:
+      return CSSToken(t: cttIDimension, nvalue: val, unit: unit)
+    return CSSToken(t: cttDimension, nvalue: val, unit: unit)
   if state.has() and state.peek() == '%':
     state.seek(1)
     return CSSToken(t: cttPercentage, nvalue: val)
-  return CSSToken(t: cttNumber, nvalue: val, tflagb: t)
+  if isInt:
+    return CSSToken(t: cttINumber, nvalue: val)
+  return CSSToken(t: cttNumber, nvalue: val)
 
 proc consumeBadURL(state: var CSSTokenizerState) =
   while state.has():
@@ -762,10 +755,7 @@ proc parseAnB*(state: var CSSParseState): Option[CSSAnB] =
       return none(CSSAnB)
     x.get
   template fail_non_integer(tok: CSSToken; res: Option[CSSAnB]) =
-    if tok.t != cttNumber:
-      state.reconsume()
-      return res
-    if tok.tflagb != tflagbInteger:
+    if tok.t != cttINumber:
       state.reconsume()
       return res
     if int64(tok.nvalue) > high(int):
@@ -837,20 +827,16 @@ proc parseAnB*(state: var CSSParseState): Option[CSSAnB] =
       return some((-1, -parse_sub_int(tok.value, "n-".len)))
     else:
       return none(CSSAnB)
-  of cttNumber:
+  of cttINumber:
     fail_plus
-    if tok.tflagb != tflagbInteger:
-      return none(CSSAnB)
     if int64(tok.nvalue) > high(int):
       return none(CSSAnB)
     # <integer>
     return some((0, int(tok.nvalue)))
-  of cttDimension:
+  of cttIDimension:
     fail_plus
     if int64(tok.nvalue) > high(int):
       return none(CSSAnB)
-    if tok.tflagb != tflagbInteger:
-      return none(CSSAnB)
     case tok.unit
     of "n", "N":
       # <n-dimension>
diff --git a/src/css/cssvalues.nim b/src/css/cssvalues.nim
index f97e35b8..5ddaf1bb 100644
--- a/src/css/cssvalues.nim
+++ b/src/css/cssvalues.nim
@@ -855,9 +855,12 @@ func parseARGB(value: openArray[CSSComponentValue]): Opt[CSSColor] =
   var commaMode = false
   template check_err(slash: bool) =
     #TODO calc, percentages, etc (cssnumber function or something)
-    if not slash and i >= value.len or i < value.len and
-        value[i] != cttNumber:
+    if not slash and i >= value.len:
       return err()
+    if i < value.len:
+      let x = value[i]
+      if not (x of CSSToken and CSSToken(x).t in {cttNumber, cttINumber}):
+        return err()
   template next_value(first = false, slash = false) =
     inc i
     value.skipWhitespace(i)
@@ -903,8 +906,8 @@ func parseANSI(value: openArray[CSSComponentValue]): Opt[CSSColor] =
     #TODO numeric functions
     return err()
   let tok = CSSToken(value[i])
-  if tok.t == cttNumber:
-    if tok.tflagb != tflagbInteger or int(tok.nvalue) notin 0..255:
+  if tok.t == cttINumber:
+    if int(tok.nvalue) notin 0..255:
       return err() # invalid numeric ANSI color
     return ok(ANSIColor(tok.nvalue).cssColor())
   elif tok.t == cttIdent:
@@ -961,14 +964,14 @@ func parseLength*(val: CSSComponentValue; attrs: WindowAttributes;
   if val of CSSToken:
     let tok = CSSToken(val)
     case tok.t
-    of cttNumber:
+    of cttNumber, cttINumber:
       if tok.nvalue == 0:
         return ok(cssLength(0))
     of cttPercentage:
       if not allowNegative and tok.nvalue < 0:
         return err()
       return parseLength(tok.nvalue, "%", attrs)
-    of cttDimension:
+    of cttDimension, cttIDimension:
       if not allowNegative and tok.nvalue < 0:
         return err()
       return parseLength(tok.nvalue, tok.unit, attrs)
@@ -983,10 +986,10 @@ func cssAbsoluteLength(val: CSSComponentValue; attrs: WindowAttributes):
   if val of CSSToken:
     let tok = CSSToken(val)
     case tok.t
-    of cttNumber:
+    of cttNumber, cttINumber:
       if tok.nvalue == 0:
         return ok(cssLength(0))
-    of cttDimension:
+    of cttDimension, cttIDimension:
       if tok.nvalue >= 0:
         return parseLength(tok.nvalue, tok.unit, attrs)
     else: discard
@@ -1063,7 +1066,7 @@ func cssFontWeight(cval: CSSComponentValue): Opt[int] =
       let i = FontWeightMap.parseIdent(cval)
       if i != -1:
         return ok(i)
-    elif tok.t == cttNumber:
+    elif tok.t in {cttNumber, cttINumber}:
       if tok.nvalue in 1f64..1000f64:
         return ok(int(tok.nvalue))
   return err()
@@ -1117,7 +1120,7 @@ func cssCounterReset(cvals: openArray[CSSComponentValue]):
           die
         r.name = tok.value
         s = true
-      of cttNumber:
+      of cttNumber, cttINumber:
         if not s:
           die
         r.num = int(tok.nvalue)
@@ -1135,7 +1138,7 @@ func cssMaxSize(cval: CSSComponentValue; attrs: WindowAttributes):
     of cttIdent:
       if tok.value.equalsIgnoreCase("none"):
         return ok(CSSLengthAuto)
-    of cttNumber, cttDimension, cttPercentage:
+    of cttNumber, cttINumber, cttDimension, cttIDimension, cttPercentage:
       return parseLength(tok, attrs, allowNegative = false)
     else: discard
   return err()
@@ -1180,7 +1183,7 @@ func cssImage(cval: CSSComponentValue): Opt[CSSContent] =
 func cssInteger(cval: CSSComponentValue; range: Slice[int]): Opt[int] =
   if cval of CSSToken:
     let tok = CSSToken(cval)
-    if tok.t == cttNumber:
+    if tok.t in {cttNumber, cttINumber}:
       if tok.nvalue in float64(range.a)..float64(range.b):
         return ok(int(tok.nvalue))
   return err()
@@ -1188,7 +1191,7 @@ func cssInteger(cval: CSSComponentValue; range: Slice[int]): Opt[int] =
 func cssNumber(cval: CSSComponentValue; positive: bool): Opt[float64] =
   if cval of CSSToken:
     let tok = CSSToken(cval)
-    if tok.t == cttNumber:
+    if tok.t in {cttNumber, cttINumber}:
       if not positive or tok.nvalue >= 0:
         return ok(tok.nvalue)
   return err()
diff --git a/src/css/mediaquery.nim b/src/css/mediaquery.nim
index 88b9e0ed..a31e049e 100644
--- a/src/css/mediaquery.nim
+++ b/src/css/mediaquery.nim
@@ -170,7 +170,7 @@ proc consumeIdent(parser: var MediaQueryParser): Opt[CSSToken] =
 
 proc consumeInt(parser: var MediaQueryParser): Opt[int] =
   let tok = ?parser.consumeToken()
-  if tok.t != cttNumber or tok.tflagb == tflagbInteger:
+  if tok.t != cttINumber:
     parser.reconsume()
     return err()
   return ok(int(tok.nvalue))