1
1
import { parse } from '../../css/reworkcss' ;
2
+ import { Screen } from '../../platform' ;
2
3
import { createSelector , RuleSet , StyleSheetSelectorScope , fromAstNode , Node , Changes } from './css-selector' ;
4
+ import { _populateRules } from './style-scope' ;
3
5
4
6
describe ( 'css-selector' , ( ) => {
5
7
it ( 'button[attr]' , ( ) => {
@@ -17,20 +19,23 @@ describe('css-selector', () => {
17
19
) . toBeFalsy ( ) ;
18
20
} ) ;
19
21
20
- function create ( css : string , source = 'css-selectors.ts@test' ) : { rules : RuleSet [ ] ; map : StyleSheetSelectorScope < any > } {
22
+ function create ( css : string , source = 'css-selectors.ts@test' ) : { rulesets : RuleSet [ ] ; selectorScope : StyleSheetSelectorScope < any > } {
21
23
const parsed = parse ( css , { source } ) ;
22
- const rulesAst = parsed . stylesheet . rules . filter ( ( n ) => n . type === 'rule' ) ;
23
- const rules = rulesAst . map ( ( rule ) => fromAstNode ( rule ) ) ;
24
- const map = new StyleSheetSelectorScope ( rules ) ;
24
+ const rulesAst = parsed . stylesheet . rules ;
25
+ const rulesets = [ ] ;
25
26
26
- return { rules, map } ;
27
+ _populateRules ( rulesAst , rulesets , [ ] ) ;
28
+
29
+ const selectorScope = new StyleSheetSelectorScope ( rulesets ) ;
30
+
31
+ return { rulesets, selectorScope } ;
27
32
}
28
33
29
34
function createOne ( css : string , source = 'css-selectors.ts@test' ) : RuleSet {
30
- const { rules } = create ( css , source ) ;
31
- expect ( rules . length ) . toBe ( 1 ) ;
35
+ const { rulesets } = create ( css , source ) ;
36
+ expect ( rulesets . length ) . toBe ( 1 ) ;
32
37
33
- return rules [ 0 ] ;
38
+ return rulesets [ 0 ] ;
34
39
}
35
40
36
41
it ( 'single selector' , ( ) => {
@@ -48,21 +53,21 @@ describe('css-selector', () => {
48
53
} ) ;
49
54
50
55
it ( 'narrow selection' , ( ) => {
51
- const { map } = create ( `
56
+ const { selectorScope } = create ( `
52
57
.login { color: blue; }
53
58
button { color: red; }
54
59
image { color: green; }
55
60
` ) ;
56
61
57
- const buttonQuerry = map . query ( { cssType : 'button' } ) . selectors ;
58
- expect ( buttonQuerry . length ) . toBe ( 1 ) ;
59
- expect ( buttonQuerry [ 0 ] . ruleset . declarations ) . toEqual ( [ { property : 'color' , value : 'red' } ] ) ;
62
+ const buttonQuery = selectorScope . query ( { cssType : 'button' } ) . selectors ;
63
+ expect ( buttonQuery . length ) . toBe ( 1 ) ;
64
+ expect ( buttonQuery [ 0 ] . ruleset . declarations ) . toEqual ( [ { property : 'color' , value : 'red' } ] ) ;
60
65
61
- const imageQuerry = map . query ( { cssType : 'image' , cssClasses : new Set ( [ 'login' ] ) } ) . selectors ;
62
- expect ( imageQuerry . length ) . toBe ( 2 ) ;
66
+ const imageQuery = selectorScope . query ( { cssType : 'image' , cssClasses : new Set ( [ 'login' ] ) } ) . selectors ;
67
+ expect ( imageQuery . length ) . toBe ( 2 ) ;
63
68
// Note class before type
64
- expect ( imageQuerry [ 0 ] . ruleset . declarations ) . toEqual ( [ { property : 'color' , value : 'blue' } ] ) ;
65
- expect ( imageQuerry [ 1 ] . ruleset . declarations ) . toEqual ( [ { property : 'color' , value : 'green' } ] ) ;
69
+ expect ( imageQuery [ 0 ] . ruleset . declarations ) . toEqual ( [ { property : 'color' , value : 'blue' } ] ) ;
70
+ expect ( imageQuery [ 1 ] . ruleset . declarations ) . toEqual ( [ { property : 'color' , value : 'green' } ] ) ;
66
71
} ) ;
67
72
68
73
const positiveMatches = {
@@ -271,10 +276,93 @@ describe('css-selector', () => {
271
276
} ,
272
277
} ) ,
273
278
) . toBe ( false ) ;
274
- // TODO: Re-add this when decorators actually work with ts-jest
279
+ // TODO: Re-add this when decorators actually work properly on ts-jest
275
280
//expect(rule.selectors[0].specificity).toEqual(0);
276
281
} ) ;
277
282
283
+ describe ( 'media queries' , ( ) => {
284
+ const { widthDIPs } = Screen . mainScreen ;
285
+
286
+ it ( 'should apply css rules of matching media query' , ( ) => {
287
+ const { selectorScope } = create ( `
288
+ @media only screen and (max-width: ${ widthDIPs } ) {
289
+ .login { color: blue; }
290
+ button { color: red; }
291
+ image { color: green; }
292
+ }
293
+ ` ) ;
294
+
295
+ const { selectors : buttonSelectors } = selectorScope . query ( { cssType : 'button' } ) ;
296
+ expect ( buttonSelectors . length ) . toBe ( 1 ) ;
297
+ expect ( buttonSelectors [ 0 ] . ruleset . declarations ) . toEqual ( [ { property : 'color' , value : 'red' } ] ) ;
298
+
299
+ const { selectors : imageSelectors } = selectorScope . query ( { cssType : 'image' , cssClasses : new Set ( [ 'login' ] ) } ) ;
300
+ expect ( imageSelectors . length ) . toBe ( 2 ) ;
301
+ // Note class before type
302
+ expect ( imageSelectors [ 0 ] . ruleset . declarations ) . toEqual ( [ { property : 'color' , value : 'blue' } ] ) ;
303
+ expect ( imageSelectors [ 1 ] . ruleset . declarations ) . toEqual ( [ { property : 'color' , value : 'green' } ] ) ;
304
+ } ) ;
305
+
306
+ it ( 'should not apply css rules of non-matching media query' , ( ) => {
307
+ const { selectorScope } = create ( `
308
+ @media only screen and (max-width: ${ widthDIPs - 1 } ) {
309
+ .login { color: blue; }
310
+ button { color: red; }
311
+ image { color: green; }
312
+ }
313
+ ` ) ;
314
+
315
+ const { selectors : buttonSelectors } = selectorScope . query ( { cssType : 'button' } ) ;
316
+ expect ( buttonSelectors . length ) . toBe ( 0 ) ;
317
+
318
+ const { selectors : imageSelectors } = selectorScope . query ( { cssType : 'image' , cssClasses : new Set ( [ 'login' ] ) } ) ;
319
+ expect ( imageSelectors . length ) . toBe ( 0 ) ;
320
+ } ) ;
321
+
322
+ it ( 'should apply css rules of matching media and nested media queries' , ( ) => {
323
+ const { selectorScope } = create ( `
324
+ @media only screen and (max-width: ${ widthDIPs } ) {
325
+ .login { color: blue; }
326
+ button { color: red; }
327
+ @media only screen and (orientation: portrait) {
328
+ image { color: green; }
329
+ }
330
+ }
331
+ ` ) ;
332
+
333
+ const { selectors : buttonSelectors } = selectorScope . query ( { cssType : 'button' } ) ;
334
+ expect ( buttonSelectors . length ) . toBe ( 1 ) ;
335
+ expect ( buttonSelectors [ 0 ] . ruleset . declarations ) . toEqual ( [ { property : 'color' , value : 'red' } ] ) ;
336
+
337
+ const { selectors : imageSelectors } = selectorScope . query ( { cssType : 'image' , cssClasses : new Set ( [ 'login' ] ) } ) ;
338
+ expect ( imageSelectors . length ) . toBe ( 2 ) ;
339
+ // Note class before type
340
+ expect ( imageSelectors [ 0 ] . ruleset . declarations ) . toEqual ( [ { property : 'color' , value : 'blue' } ] ) ;
341
+ expect ( imageSelectors [ 1 ] . ruleset . declarations ) . toEqual ( [ { property : 'color' , value : 'green' } ] ) ;
342
+ } ) ;
343
+
344
+ it ( 'should apply css rules of matching media queries but not non-matching nested media queries' , ( ) => {
345
+ const { selectorScope } = create ( `
346
+ @media only screen and (max-width: ${ widthDIPs } ) {
347
+ .login { color: blue; }
348
+
349
+ @media only screen and (orientation: none) {
350
+ button { color: red; }
351
+ image { color: green; }
352
+ }
353
+ }
354
+ ` ) ;
355
+
356
+ const { selectors : buttonSelectors } = selectorScope . query ( { cssType : 'button' } ) ;
357
+ expect ( buttonSelectors . length ) . toBe ( 0 ) ;
358
+
359
+ const { selectors : imageSelectors } = selectorScope . query ( { cssType : 'image' , cssClasses : new Set ( [ 'login' ] ) } ) ;
360
+ expect ( imageSelectors . length ) . toBe ( 1 ) ;
361
+
362
+ expect ( imageSelectors [ 0 ] . ruleset . declarations ) . toEqual ( [ { property : 'color' , value : 'blue' } ] ) ;
363
+ } ) ;
364
+ } ) ;
365
+
278
366
function toString ( ) {
279
367
return this . cssType ;
280
368
}
0 commit comments