about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2025-01-30 00:35:59 +0100
committerbptato <nincsnevem662@gmail.com>2025-01-30 00:47:15 +0100
commit52aba81c301cb4db3a9c34ca2aa285c407d1d848 (patch)
tree06fee381bb98d0c7c1dc9bcdbf9b526fcc35d18b
parentdfb3453b3c1220f0efa50aff8d57c27da86a543f (diff)
downloadchawan-52aba81c301cb4db3a9c34ca2aa285c407d1d848.tar.gz
mediaquery: fix some parser bugs
<media-condition-without-or> works correctly once again.

ref. https://todo.sr.ht/~bptato/chawan/46
-rw-r--r--src/css/mediaquery.nim17
-rw-r--r--test/layout/media-query.color.expected1
-rw-r--r--test/layout/media-query.html22
3 files changed, 28 insertions, 12 deletions
diff --git a/src/css/mediaquery.nim b/src/css/mediaquery.nim
index 7b466d84..8149bb64 100644
--- a/src/css/mediaquery.nim
+++ b/src/css/mediaquery.nim
@@ -343,9 +343,9 @@ proc parseMediaOr(parser: var MediaQueryParser; left: MediaQuery):
   let right = ?parser.parseMediaCondition()
   return ok(MediaQuery(t: mctOr, left: left, right: right))
 
-proc parseMediaAnd(parser: var MediaQueryParser; left: MediaQuery):
-    Opt[MediaQuery] =
-  let right = ?parser.parseMediaCondition()
+proc parseMediaAnd(parser: var MediaQueryParser; left: MediaQuery;
+    noor = false): Opt[MediaQuery] =
+  let right = ?parser.parseMediaCondition(noor = noor)
   return ok(MediaQuery(t: mctAnd, left: left, right: right))
 
 func negateIf(mq: MediaQuery; non: bool): MediaQuery =
@@ -370,7 +370,7 @@ proc parseMediaCondition(parser: var MediaQueryParser; non = false;
   let tok = ?parser.consumeIdent()
   parser.skipBlanks()
   if tok.value.equalsIgnoreCase("and"):
-    return parser.parseMediaAnd(res)
+    return parser.parseMediaAnd(res, noor)
   elif tok.value.equalsIgnoreCase("or"):
     if noor:
       return err()
@@ -401,11 +401,10 @@ proc parseMediaQuery(parser: var MediaQueryParser): Opt[MediaQuery] =
     let res = MediaQuery(t: mctMedia, media: x.get)
     if parser.skipBlanksCheckHas().isNone:
       return ok(res)
-    if (let tokx = parser.consumeIdent(); tokx.isSome):
-      return parser.parseMediaAnd(res)
-    return parser.parseMediaCondition()
-  else:
-    return err()
+    let tok = ?parser.consumeIdent()
+    if tok.value.equalsIgnoreCase("and"):
+      return parser.parseMediaAnd(res, noor = true)
+  return err()
 
 proc parseMediaQueryList*(cvals: seq[CSSComponentValue];
     attrs: ptr WindowAttributes): seq[MediaQuery] =
diff --git a/test/layout/media-query.color.expected b/test/layout/media-query.color.expected
index 1b2d4beb..d5d999e1 100644
--- a/test/layout/media-query.color.expected
+++ b/test/layout/media-query.color.expected
@@ -1,3 +1,4 @@
 red
 green
 purple
+blue
diff --git a/test/layout/media-query.html b/test/layout/media-query.html
index 28a2ee04..bf4ca27b 100644
--- a/test/layout/media-query.html
+++ b/test/layout/media-query.html
@@ -1,17 +1,33 @@
 <style>
+/* valid */
 @mediA (WiDtH >= 1px) and (HeiGhT < 10000px) {
 	#red { color: red }
 }
 @media screen and (WiDtH >= 1px) {
 	#green { color: green }
 }
-@media (width >= 1px 2px) {
-	#red { color: blue }
-}
 @media (grid: 1) {
 	#purple { color: purple }
 }
+@media screen and (min-width: 2px) {
+	#blue { color: blue }
+}
+
+/* invalid */
+@media (width >= 1px 2px) {
+	#red { color: blue !important }
+}
+@media screen yahoo{
+	#purple { color: red !important }
+}
+@media screen or (min-width: 2px) {
+	#blue { color: red !important }
+}
+@media screen and (min-width: 2px) or (min-width: 2px) {
+	#blue { color: red !important }
+}
 </style>
 <div id=red>red</div>
 <div id=green>green</div>
 <div id=purple>purple</div>
+<div id=blue>blue</div>