diff options
author | bptato <nincsnevem662@gmail.com> | 2025-01-06 22:16:33 +0100 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2025-01-06 23:21:49 +0100 |
commit | 30a933adb2bade2ceee08a9b36371cecf554d648 (patch) | |
tree | 9bf070955c26c9aa2b9610a2ce8c3c2c018af6e9 /src | |
parent | 48db2527dfb3496d85e4b797a3196ffa7f21baa3 (diff) | |
download | chawan-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.nim | 84 | ||||
-rw-r--r-- | src/css/sheet.nim | 6 | ||||
-rw-r--r-- | src/html/env.nim | 2 |
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.} = |