about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2023-07-04 15:31:58 +0200
committerbptato <nincsnevem662@gmail.com>2023-07-04 15:38:05 +0200
commitc355c176863a930d2107254198749f420f272c06 (patch)
tree27bddabcbbe08030d03ea8247026abeb177184aa
parentba6ac8e07c6868c168a550f3d8ecbb2f8bf5c799 (diff)
downloadchawan-c355c176863a930d2107254198749f420f272c06.tar.gz
Fix bug in media-query parsing
This fixes interpretation of "@media (min/max-width: 1234px)".
-rw-r--r--src/css/cascade.nim22
-rw-r--r--src/css/mediaquery.nim18
-rw-r--r--src/css/values.nim8
-rw-r--r--src/layout/layoutunit.nim45
4 files changed, 61 insertions, 32 deletions
diff --git a/src/css/cascade.nim b/src/css/cascade.nim
index 7996f96e..888191c5 100644
--- a/src/css/cascade.nim
+++ b/src/css/cascade.nim
@@ -23,6 +23,20 @@ type
     user: DeclarationList
     author: seq[DeclarationList]
 
+func appliesLR(feature: MediaFeature, window: Window,
+    n: LayoutUnit): bool =
+  let a = px(feature.lengthrange.a, window.attrs, 0)
+  let b = px(feature.lengthrange.b, window.attrs, 0)
+  if not feature.lengthaeq and a == n:
+    return false
+  if a > n:
+    return false
+  if not feature.lengthbeq and b == n:
+    return false
+  if b < n:
+    return false
+  return true
+
 func applies(feature: MediaFeature, window: Window): bool =
   case feature.t
   of FEATURE_COLOR:
@@ -34,13 +48,9 @@ func applies(feature: MediaFeature, window: Window): bool =
   of FEATURE_PREFERS_COLOR_SCHEME:
     return feature.b
   of FEATURE_WIDTH:
-    let a = toInt(px(feature.lengthrange.a, window.attrs, 0))
-    let b = toInt(px(feature.lengthrange.b, window.attrs, 0))
-    return window.attrs.ppc * window.attrs.width in a .. b
+    return feature.appliesLR(window, toLayoutUnit(window.attrs.width_px))
   of FEATURE_HEIGHT:
-    let a = toInt(px(feature.lengthrange.a, window.attrs, 0))
-    let b = toInt(px(feature.lengthrange.b, window.attrs, 0))
-    return window.attrs.ppl * window.attrs.height in a .. b
+    return feature.appliesLR(window, toLayoutUnit(window.attrs.height_px))
 
 func applies(mq: MediaQuery, window: Window): bool =
   case mq.t
diff --git a/src/css/mediaquery.nim b/src/css/mediaquery.nim
index 3a594e6c..b9e0ed83 100644
--- a/src/css/mediaquery.nim
+++ b/src/css/mediaquery.nim
@@ -12,8 +12,12 @@ type
     cvals: seq[CSSComponentValue]
 
   MediaType* = enum
-    MEDIA_TYPE_UNKNOWN, MEDIA_TYPE_ALL, MEDIA_TYPE_PRINT, MEDIA_TYPE_SCREEN,
-    MEDIA_TYPE_SPEECH, MEDIA_TYPE_TTY
+    MEDIA_TYPE_UNKNOWN = "unknown"
+    MEDIA_TYPE_ALL = "all"
+    MEDIA_TYPE_PRINT = "print"
+    MEDIA_TYPE_SCREEN = "screen"
+    MEDIA_TYPE_SPEECH = "speech"
+    MEDIA_TYPE_TTY = "tty"
 
   MediaConditionType* = enum
     CONDITION_NOT, CONDITION_AND, CONDITION_OR, CONDITION_FEATURE,
@@ -54,6 +58,15 @@ type
   MediaQueryComparison = enum
     COMPARISON_EQ, COMPARISON_GT, COMPARISON_LT, COMPARISON_GE, COMPARISON_LE
 
+# for debugging
+func `$`*(mq: MediaQuery): string =
+  case mq.t
+  of CONDITION_MEDIA: return $mq.media
+  of CONDITION_FEATURE: return $mq.feature
+  of CONDITION_NOT: return "not " & $mq.n
+  of CONDITION_OR: return $mq.ora & " or " & $mq.orb
+  of CONDITION_AND: return $mq.anda & " or " & $mq.andb
+
 const MediaTypes = {
   "all": MEDIA_TYPE_ALL,
   "print": MEDIA_TYPE_PRINT,
@@ -353,6 +366,7 @@ proc parseMediaCondition(parser: var MediaQueryParser, non = false, noor = false
     else:
       parser.reconsume()
 
+  parser.skipBlanks()
   if not parser.has():
     return nil
 
diff --git a/src/css/values.nim b/src/css/values.nim
index e988333d..b9e9dc95 100644
--- a/src/css/values.nim
+++ b/src/css/values.nim
@@ -389,18 +389,18 @@ func inherited(t: CSSPropertyType): bool =
   return InheritedArray[t]
 
 func em_to_px(em: float64, window: WindowAttributes): LayoutUnit =
-  em * toLayoutUnit(window.ppl)
+  em * float64(window.ppl)
 
 func ch_to_px(ch: float64, window: WindowAttributes): LayoutUnit =
-  ch * toLayoutUnit(window.ppc)
+  ch * float64(window.ppc)
 
 # 水 width, we assume it's 2 chars
 func ic_to_px(ic: float64, window: WindowAttributes): LayoutUnit =
-  ic * toLayoutUnit(window.ppc) * 2
+  ic * float64(window.ppc) * 2
 
 # x-letter height, we assume it's em/2
 func ex_to_px(ex: float64, window: WindowAttributes): LayoutUnit =
-  ex * toLayoutUnit(window.ppc) / 2
+  ex * float64(window.ppc) / 2
 
 func px*(l: CSSLength, window: WindowAttributes, p: LayoutUnit): LayoutUnit {.inline.} =
   case l.unit
diff --git a/src/layout/layoutunit.nim b/src/layout/layoutunit.nim
index 1038e5ed..86f019f0 100644
--- a/src/layout/layoutunit.nim
+++ b/src/layout/layoutunit.nim
@@ -2,6 +2,27 @@
 
 type LayoutUnit* = distinct int32
 
+func `==`*(a, b: LayoutUnit): bool {.borrow.}
+func `<`*(a, b: LayoutUnit): bool {.borrow.}
+func `<=`*(a, b: LayoutUnit): bool {.borrow.}
+func `+`*(a, b: LayoutUnit): LayoutUnit {.borrow.}
+func `+=`*(a: var LayoutUnit, b: LayoutUnit) {.borrow.}
+func `-`*(a, b: LayoutUnit): LayoutUnit {.borrow.}
+func `-`*(a: LayoutUnit): LayoutUnit {.borrow.}
+func `-=`*(a: var LayoutUnit, b: LayoutUnit) {.borrow.}
+func `*`*(a, b: LayoutUnit): LayoutUnit {.inline.} =
+  LayoutUnit((int32(a) * int32(b)) shr 6)
+func `*=`*(a: var LayoutUnit, b: LayoutUnit) {.inline.} =
+  a = a * b
+func `/`*(a, b: LayoutUnit): LayoutUnit {.inline.} =
+  let a64 = int64(a)
+  let b64 = int64(b)
+  LayoutUnit(cast[int32](((a64 shl 12) div b64) shr 6))
+func `/=`*(a: var LayoutUnit, b: LayoutUnit) {.inline.} =
+  a = a / b
+func `div`*(a, b: LayoutUnit): LayoutUnit {.inline.} =
+  a / b
+
 func toInt*(a: LayoutUnit): int =
   return int32(a) shr 6
 
@@ -15,6 +36,10 @@ converter toLayoutUnit*(a: int): LayoutUnit =
   return toLayoutUnit(cast[int32](a))
 
 converter toLayoutUnit*(a: float64): LayoutUnit =
+  if unlikely(a == Inf):
+    return LayoutUnit(high(int32))
+  elif unlikely(a == -Inf):
+    return LayoutUnit(low(int32))
   return LayoutUnit(int32(a * 64))
 
 func toFloat64*(a: LayoutUnit): float64 =
@@ -23,26 +48,6 @@ func toFloat64*(a: LayoutUnit): float64 =
 func `$`*(a: LayoutUnit): string =
   $toFloat64(a)
 
-func `==`*(a, b: LayoutUnit): bool {.borrow.}
-func `<`*(a, b: LayoutUnit): bool {.borrow.}
-func `<=`*(a, b: LayoutUnit): bool {.borrow.}
-func `+`*(a, b: LayoutUnit): LayoutUnit {.borrow.}
-func `+=`*(a: var LayoutUnit, b: LayoutUnit) {.borrow.}
-func `-`*(a, b: LayoutUnit): LayoutUnit {.borrow.}
-func `-=`*(a: var LayoutUnit, b: LayoutUnit) {.borrow.}
-func `*`*(a, b: LayoutUnit): LayoutUnit {.inline.} =
-  LayoutUnit((int32(a) * int32(b)) shr 6)
-func `*=`*(a: var LayoutUnit, b: LayoutUnit) {.inline.} =
-  a = a * b
-func `/`*(a, b: LayoutUnit): LayoutUnit {.inline.} =
-  let a64 = int64(a)
-  let b64 = int64(b)
-  LayoutUnit(cast[int32](((a64 shl 12) div b64) shr 6))
-func `/=`*(a: var LayoutUnit, b: LayoutUnit) {.inline.} =
-  a = a / b
-func `div`*(a, b: LayoutUnit): LayoutUnit {.inline.} =
-  a / b
-
 func min*(a, b: LayoutUnit): LayoutUnit {.borrow.}
 func max*(a, b: LayoutUnit): LayoutUnit {.borrow.}
 func clamp*(x, a, b: LayoutUnit): LayoutUnit {.borrow.}