about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2025-01-06 22:16:33 +0100
committerbptato <nincsnevem662@gmail.com>2025-01-06 23:21:49 +0100
commit30a933adb2bade2ceee08a9b36371cecf554d648 (patch)
tree9bf070955c26c9aa2b9610a2ce8c3c2c018af6e9 /src
parent48db2527dfb3496d85e4b797a3196ffa7f21baa3 (diff)
downloadchawan-30a933adb2bade2ceee08a9b36371cecf554d648.tar.gz
mediaquery: add serialization
also, reduce the number of types named MediaQueryList by 50%
Diffstat (limited to 'src')
-rw-r--r--src/css/mediaquery.nim84
-rw-r--r--src/css/sheet.nim6
-rw-r--r--src/html/env.nim2
3 files changed, 49 insertions, 43 deletions
diff --git a/src/css/mediaquery.nim b/src/css/mediaquery.nim
index 83b8fd64..88b9e0ed 100644
--- a/src/css/mediaquery.nim
+++ b/src/css/mediaquery.nim
@@ -13,17 +13,17 @@ type
     cvals: seq[CSSComponentValue]
     attrs: ptr WindowAttributes
 
-  MediaType* = enum
+  MediaType = enum
     mtAll = "all"
     mtPrint = "print"
     mtScreen = "screen"
     mtSpeech = "speech"
     mtTty = "tty"
 
-  MediaConditionType* = enum
+  MediaConditionType = enum
     mctNot, mctAnd, mctOr, mctFeature, mctMedia
 
-  MediaFeatureType* = enum
+  MediaFeatureType = enum
     mftColor = "color"
     mftGrid = "grid"
     mftHover = "hover"
@@ -32,34 +32,31 @@ type
     mftHeight = "height"
     mftScripting = "scripting"
 
-  LengthRange* = object
-    s*: Slice[CSSLength]
-    aeq*: bool
-    beq*: bool
+  LengthRange = object
+    s: Slice[CSSLength]
+    aeq: bool
+    beq: bool
 
-  MediaFeature* = object
-    case t*: MediaFeatureType
+  MediaFeature = object
+    case t: MediaFeatureType
     of mftColor:
-      range*: Slice[int]
-    of mftGrid, mftHover, mftPrefersColorScheme,
-        mftScripting:
-      b*: bool
+      range: Slice[int]
+    of mftGrid, mftHover, mftPrefersColorScheme, mftScripting:
+      b: bool
     of mftWidth, mftHeight:
       lengthrange*: LengthRange
 
   MediaQuery* = ref object
-    case t*: MediaConditionType
+    case t: MediaConditionType
     of mctMedia:
-      media*: MediaType
+      media: MediaType
     of mctFeature:
-      feature*: MediaFeature
+      feature: MediaFeature
     of mctNot:
-      n*: MediaQuery
+      n: MediaQuery
     of mctOr, mctAnd:
-      left*: MediaQuery
-      right*: MediaQuery
-
-  MediaQueryList* = seq[MediaQuery]
+      left: MediaQuery
+      right: MediaQuery
 
   MediaQueryComparison = enum
     mqcEq, mqcGt, mqcLt, mqcGe, mqcLe
@@ -68,31 +65,31 @@ type
 proc parseMediaCondition(parser: var MediaQueryParser; non = false;
   noor = false): Opt[MediaQuery]
 
-# for debugging
-func `$`*(mf: MediaFeature): string =
+# Serializer.
+# As usual, the spec is incomplete, so it's hard to say if it's
+# compliant.  What can you do :/
+func `$`(mf: MediaFeature): string =
   case mf.t
   of mftColor:
-    return "color: " & $mf.range.a & ".." & $mf.range.b
+    return $mf.range.a & " <= " & $mf.t & " <= " & $mf.range.b
   of mftGrid:
-    return "grid: " & $mf.b
+    return "grid: " & $int(mf.b)
   of mftHover:
-    return "hover: " & $mf.b
+    return "hover: " & [false: "none", true: "hover"][mf.b]
   of mftPrefersColorScheme:
-    return "prefers-color-scheme: " & $mf.b
+    return "prefers-color-scheme: " & [false: "light", true: "dark"][mf.b]
   of mftWidth, mftHeight:
-    result &= $mf.lengthrange.s.a
-    result &= " <"
+    result = $mf.lengthrange.s.a & " <"
     if mf.lengthrange.aeq:
-      result &= "="
+      result &= '='
     result &= ' ' & $mf.t & " <"
     if mf.lengthrange.beq:
-      result &= "="
-    result &= " "
-    result &= $mf.lengthrange.s.b
+      result &= '='
+    result &= ' ' & $mf.lengthrange.s.b
   of mftScripting:
-    return "scripting: " & (if mf.b: "enabled" else: "none")
+    return "scripting: " & [false: "none", true: "enabled"][mf.b]
 
-func `$`*(mq: MediaQuery): string =
+func `$`(mq: MediaQuery): string =
   case mq.t
   of mctMedia: return $mq.media
   of mctFeature: return $mq.feature
@@ -100,6 +97,13 @@ func `$`*(mq: MediaQuery): string =
   of mctOr: return "(" & $mq.left & ") or (" & $mq.right & ")"
   of mctAnd: return "(" & $mq.left & ") or (" & $mq.right & ")"
 
+func `$`*(mqlist: seq[MediaQuery]): string =
+  result = ""
+  for it in mqlist:
+    if result.len > 0:
+      result &= ", "
+    result &= $it
+
 const RangeFeatures = {mftColor, mftWidth, mftHeight}
 
 proc has(parser: MediaQueryParser; i = 0): bool =
@@ -404,7 +408,7 @@ proc parseMediaQuery(parser: var MediaQueryParser): Opt[MediaQuery] =
     return err()
 
 proc parseMediaQueryList*(cvals: seq[CSSComponentValue];
-    attrs: ptr WindowAttributes): MediaQueryList =
+    attrs: ptr WindowAttributes): seq[MediaQuery] =
   result = @[]
   let cseplist = cvals.parseCommaSepComponentValues()
   for list in cseplist:
@@ -412,6 +416,10 @@ proc parseMediaQueryList*(cvals: seq[CSSComponentValue];
     let query = parser.parseMediaQuery()
     if query.isSome:
       result.add(query.get)
+    else:
+      # sadly, the standard doesn't let us skip this :/
+      let all = MediaQuery(t: mctMedia, media: mtAll)
+      result.add(MediaQuery(t: mctNot, n: all))
 
 type
   MediaApplyContext = object
@@ -459,13 +467,13 @@ func applies(ctx: MediaApplyContext; mq: MediaQuery): bool =
   of mctFeature:
     return ctx.applies(mq.feature)
 
-func applies(ctx: MediaApplyContext; mqlist: MediaQueryList): bool =
+func applies(ctx: MediaApplyContext; mqlist: seq[MediaQuery]): bool =
   for mq in mqlist:
     if ctx.applies(mq):
       return true
   return false
 
-func applies*(mqlist: MediaQueryList; scripting: ScriptingMode;
+func applies*(mqlist: seq[MediaQuery]; scripting: ScriptingMode;
     attrsp: ptr WindowAttributes): bool =
   let ctx = MediaApplyContext(scripting: scripting, attrsp: attrsp)
   return ctx.applies(mqlist)
diff --git a/src/css/sheet.nim b/src/css/sheet.nim
index 818e30f8..b0ac970b 100644
--- a/src/css/sheet.nim
+++ b/src/css/sheet.nim
@@ -21,11 +21,9 @@ type
     # retrieval from the cache.
     idx: int
 
-  CSSConditionalDef* = ref object of CSSRuleBase
+  CSSMediaQueryDef* = ref object of CSSRuleBase
     children*: CSSStylesheet
-
-  CSSMediaQueryDef* = ref object of CSSConditionalDef
-    query*: MediaQueryList
+    query*: seq[MediaQuery]
 
   CSSStylesheet* = ref object
     mqList*: seq[CSSMediaQueryDef]
diff --git a/src/html/env.nim b/src/html/env.nim
index 63ae6e21..5f0cc192 100644
--- a/src/html/env.nim
+++ b/src/html/env.nim
@@ -304,7 +304,7 @@ proc matchMedia(window: Window; s: string): MediaQueryList {.jsfunc.} =
   let mqlist = parseMediaQueryList(cvals, window.scriptAttrsp)
   return MediaQueryList(
     matches: mqlist.applies(window.settings.scripting, window.scriptAttrsp),
-    media: s #TODO this should be serialized from mqlist
+    media: $mqlist
   )
 
 proc postMessage(window: Window) {.jsfunc.} =