Browse Source

Allow media queries as ruleset children

master
Dylan Baker 5 years ago
parent
commit
bd43c50913
3 changed files with 41 additions and 20 deletions
  1. 1
    1
      src/ast.ts
  2. 6
    7
      src/parser.ts
  3. 34
    12
      src/tests/parser.test.ts

+ 1
- 1
src/ast.ts View File

@@ -10,7 +10,7 @@ import { Property } from './ast/property';
10 10
 import { Rule } from './ast/rule';
11 11
 import { RuleSet } from './ast/ruleSet';
12 12
 
13
-export type Child = Rule | RuleSet | Application;
13
+export type Child = Rule | RuleSet | Application | MediaQuery;
14 14
 export type Value = Literal | Identifier | Application;
15 15
 export type Node
16 16
   = Application

+ 6
- 7
src/parser.ts View File

@@ -245,7 +245,7 @@ export default class Parser {
245 245
       selectors.push(selector);
246 246
     }
247 247
 
248
-    const children: (AST.Application | AST.Rule | AST.RuleSet)[] = [];
248
+    const children: (AST.Child)[] = [];
249 249
 
250 250
     while (
251 251
       [TokenTypes.PROPERTY, TokenTypes.LPAREN].includes(
@@ -317,13 +317,12 @@ export default class Parser {
317 317
       return new AST.Rule(property, value);
318 318
     } else if (this.currentToken().type === TokenTypes.LPAREN) {
319 319
       if (this.nextToken().type === TokenTypes.LITERAL) {
320
-        const ruleSet = this.ruleSet(parents);
321
-        if (ruleSet instanceof ParserError) return ruleSet;
322
-        return ruleSet;
320
+        return this.ruleSet(parents);
323 321
       } else if (this.nextToken().type === TokenTypes.FUNCTION_NAME) {
324
-        const application = this.application();
325
-        if (application instanceof ParserError) return application;
326
-        return application;
322
+        if (this.nextToken().value === 'media') {
323
+          return this.mediaQuery();
324
+        }
325
+        return this.application();
327 326
       }
328 327
     }
329 328
 

+ 34
- 12
src/tests/parser.test.ts View File

@@ -347,13 +347,9 @@ test('parse mixin application', (t) => {
347 347
       result.tree[0],
348 348
       new AST.RuleSet(
349 349
         [new AST.Selector(literalToken('div'))],
350
-        [
351
-          new AST.Application(functionName('border'), [
352
-            literalNode('#000000'),
353
-          ]),
354
-        ]
350
+        [new AST.Application(functionName('border'), [literalNode('#000000')])]
355 351
       )
356
-    )
352
+    );
357 353
   }
358 354
 });
359 355
 
@@ -369,13 +365,39 @@ test('parse mixin with children', (t) => {
369 365
         [],
370 366
         [
371 367
           new AST.RuleSet(
372
-            [
373
-              new AST.Selector(literalToken('div')),
374
-            ],
368
+            [new AST.Selector(literalToken('div'))],
375 369
             [new AST.Rule(property('color'), literalNode('blue'))]
376
-          )
370
+          ),
377 371
         ]
378
-      ),
379
-    )
372
+      )
373
+    );
374
+  }
375
+});
376
+
377
+test('media query as child', (t) => {
378
+  t.plan(2);
379
+  const result = parse('(div (@media :min-width 1000px (& :color blue)))');
380
+  t.false(result instanceof ParserError);
381
+  if (!(result instanceof LexerError) && !(result instanceof ParserError)) {
382
+    t.deepEqual(
383
+      result.tree[0],
384
+      new AST.RuleSet(
385
+        [new AST.Selector(literalToken('div'))],
386
+        [
387
+          new AST.MediaQuery(
388
+            new AST.MediaQueryPredicate(
389
+              property('min-width'),
390
+              literalNode('1000px')
391
+            ),
392
+            [
393
+              new AST.RuleSet(
394
+                [new AST.Selector(literalToken('&'))],
395
+                [new AST.Rule(property('color'), literalNode('blue'))]
396
+              ),
397
+            ]
398
+          ),
399
+        ]
400
+      )
401
+    );
380 402
   }
381 403
 });

Loading…
Cancel
Save