csspool 4.0.0.pre → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.rdoc +12 -0
- data/Gemfile.lock +6 -6
- data/Manifest.txt +10 -2
- data/Rakefile +1 -0
- data/lib/csspool/css/declaration.rb +1 -1
- data/lib/csspool/css/document.rb +5 -1
- data/lib/csspool/css/document_handler.rb +43 -11
- data/lib/csspool/css/fontface_rule.rb +13 -0
- data/lib/csspool/css/import_rule.rb +0 -5
- data/lib/csspool/css/media_feature.rb +14 -0
- data/lib/csspool/css/media_query.rb +19 -0
- data/lib/csspool/css/media_query_list.rb +41 -0
- data/lib/csspool/css/{media.rb → media_type.rb} +6 -4
- data/lib/csspool/css/parser.rb +1272 -671
- data/lib/csspool/css/parser.y +223 -53
- data/lib/csspool/css/rule_set.rb +4 -3
- data/lib/csspool/css/supports_rule.rb +14 -0
- data/lib/csspool/css/tokenizer.rb +92 -16
- data/lib/csspool/css/tokenizer.rex +42 -19
- data/lib/csspool/css.rb +6 -1
- data/lib/csspool/node.rb +22 -0
- data/lib/csspool/selector.rb +5 -4
- data/lib/csspool/selectors/pseudo.rb +2 -2
- data/lib/csspool/terms/function.rb +1 -1
- data/lib/csspool/terms/resolution.rb +13 -0
- data/lib/csspool/terms.rb +1 -0
- data/lib/csspool/visitors/children.rb +16 -2
- data/lib/csspool/visitors/comparable.rb +27 -8
- data/lib/csspool/visitors/iterator.rb +5 -3
- data/lib/csspool/visitors/to_css.rb +73 -20
- data/test/css/test_document_query.rb +37 -38
- data/test/css/test_font_face.rb +16 -0
- data/test/css/test_import_rule.rb +0 -3
- data/test/css/test_media_rule.rb +92 -0
- data/test/css/test_node_position.rb +81 -0
- data/test/css/test_parser.rb +12 -39
- data/test/css/test_supports_rule.rb +133 -0
- data/test/css/test_tokenizer.rb +4 -4
- data/test/css/test_variables.rb +33 -0
- data/test/helper.rb +3 -3
- data/test/sac/test_parser.rb +1 -0
- data/test/test_parser.rb +22 -9
- data/test/test_selector.rb +44 -4
- data/test/test_term.rb +29 -0
- data/test/visitors/test_comparable.rb +8 -0
- data/test/visitors/test_to_css.rb +89 -13
- metadata +54 -58
- data/test/_local_helper.rb +0 -2
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
# CSS @media - http://www.w3.org/TR/css3-mediaqueries/
|
4
|
+
module CSSPool
|
5
|
+
module CSS
|
6
|
+
class TestMediaRule < CSSPool::TestCase
|
7
|
+
|
8
|
+
def test_type
|
9
|
+
doc = CSSPool.CSS <<-eocss
|
10
|
+
@media print {
|
11
|
+
div { background: red, blue; }
|
12
|
+
}
|
13
|
+
eocss
|
14
|
+
assert_equal 1, doc.rule_sets.first.parent_rule.length
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_expression
|
18
|
+
doc = CSSPool.CSS <<-eocss
|
19
|
+
@media (min-width:400px) {
|
20
|
+
div { background: red, blue; }
|
21
|
+
}
|
22
|
+
eocss
|
23
|
+
assert_equal 1, doc.rule_sets.first.parent_rule.length
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_expression_no_space
|
27
|
+
doc = CSSPool.CSS <<-eocss
|
28
|
+
@media(min-width:400px) {
|
29
|
+
div { background: red, blue; }
|
30
|
+
}
|
31
|
+
eocss
|
32
|
+
assert_equal 1, doc.rule_sets.first.parent_rule.length
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_complex
|
36
|
+
doc = CSSPool.CSS <<-eocss
|
37
|
+
@media screen and (color), projection and (color) { }
|
38
|
+
eocss
|
39
|
+
assert_equal 2, doc.rule_sets.first.parent_rule.length
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_type_not
|
43
|
+
doc = CSSPool.CSS <<-eocss
|
44
|
+
@media not print {
|
45
|
+
div { background: red, blue; }
|
46
|
+
}
|
47
|
+
eocss
|
48
|
+
assert_equal 1, doc.rule_sets.first.parent_rule.length
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_type_only
|
52
|
+
doc = CSSPool.CSS <<-eocss
|
53
|
+
@media only print {
|
54
|
+
div { background: red, blue; }
|
55
|
+
}
|
56
|
+
eocss
|
57
|
+
assert_equal 1, doc.rule_sets.first.parent_rule.length
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_in_document_query
|
61
|
+
doc = CSSPool.CSS <<-eocss
|
62
|
+
@document domain(example.com) {
|
63
|
+
@media(max-height: 800px){.dashboard{position: absolute;}}
|
64
|
+
}
|
65
|
+
eocss
|
66
|
+
assert_equal 1, doc.rule_sets.first.parent_rule.length
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_invalid_media_query_list
|
70
|
+
# needs to have space after 'and'
|
71
|
+
css = <<-eocss
|
72
|
+
@media all and(color) {
|
73
|
+
div { background: red, blue; }
|
74
|
+
}
|
75
|
+
eocss
|
76
|
+
assert_raises Racc::ParseError do
|
77
|
+
CSSPool::CSS(css)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# "and" is a reserved word in @media, but not elsewhere
|
82
|
+
def test_other_use_of_keywords
|
83
|
+
doc = CSSPool.CSS <<-eocss
|
84
|
+
/* and */
|
85
|
+
.and { display: flexbox; content: " and ";}
|
86
|
+
and { and: and; }
|
87
|
+
eocss
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module CSSPool
|
4
|
+
module CSS
|
5
|
+
class TestNodePosition < CSSPool::TestCase
|
6
|
+
|
7
|
+
def test_no_whitespace
|
8
|
+
child_content = '* { color: blue !important }'
|
9
|
+
css = "@document url(\"http://www.example.com\") {#{child_content}}"
|
10
|
+
doc = CSSPool.CSS css
|
11
|
+
assert_equal 1, doc.document_queries.size
|
12
|
+
dq = doc.document_queries.first
|
13
|
+
assert !dq.outer_start_pos.nil?
|
14
|
+
assert !dq.inner_start_pos.nil?
|
15
|
+
assert !dq.inner_end_pos.nil?
|
16
|
+
assert !dq.outer_end_pos.nil?
|
17
|
+
assert_equal css, css[dq.outer_start_pos..dq.outer_end_pos-1]
|
18
|
+
assert_equal child_content, css[dq.inner_start_pos..dq.inner_end_pos-1]
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_whitespace
|
22
|
+
child_content = '
|
23
|
+
* { color: blue !important }
|
24
|
+
'
|
25
|
+
css = "
|
26
|
+
@document url(\"http://www.example.com\") {#{child_content}}
|
27
|
+
"
|
28
|
+
doc = CSSPool.CSS css
|
29
|
+
assert_equal 1, doc.document_queries.size
|
30
|
+
dq = doc.document_queries.first
|
31
|
+
assert !dq.outer_start_pos.nil?
|
32
|
+
assert !dq.inner_start_pos.nil?
|
33
|
+
assert !dq.inner_end_pos.nil?
|
34
|
+
assert !dq.outer_end_pos.nil?
|
35
|
+
# the whitespace on the "outside" should not be included
|
36
|
+
assert_equal css.strip, css[dq.outer_start_pos..dq.outer_end_pos-1]
|
37
|
+
# the whitespace on the "inside" should be retained
|
38
|
+
assert_equal child_content, css[dq.inner_start_pos..dq.inner_end_pos-1]
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_comments
|
42
|
+
child_content = ' /* comment two */
|
43
|
+
* { color: blue !important }
|
44
|
+
/* comment three */
|
45
|
+
'
|
46
|
+
css = " /* comment one */
|
47
|
+
@document url(\"http://www.example.com\") {#{child_content}}
|
48
|
+
/* comment four */
|
49
|
+
"
|
50
|
+
doc = CSSPool.CSS css
|
51
|
+
assert_equal 1, doc.document_queries.size
|
52
|
+
dq = doc.document_queries.first
|
53
|
+
assert !dq.outer_start_pos.nil?
|
54
|
+
assert !dq.inner_start_pos.nil?
|
55
|
+
assert !dq.inner_end_pos.nil?
|
56
|
+
assert !dq.outer_end_pos.nil?
|
57
|
+
# the comments and whitespace to the "outside" should not be retained
|
58
|
+
assert_equal css.sub('/* comment one */', '').sub('/* comment four */', '').strip, css[dq.outer_start_pos..dq.outer_end_pos-1]
|
59
|
+
# the comments and whitespace on the "inside" should be retained
|
60
|
+
assert_equal child_content, css[dq.inner_start_pos..dq.inner_end_pos-1]
|
61
|
+
end
|
62
|
+
|
63
|
+
# this only works in ruby 2+
|
64
|
+
def test_multibyte_characters
|
65
|
+
child_content = '/* â */ * { color: blue !important }'
|
66
|
+
css = "@document url(\"http://www.example.com\") {#{child_content}}"
|
67
|
+
doc = CSSPool.CSS css
|
68
|
+
assert_equal 1, doc.document_queries.size
|
69
|
+
dq = doc.document_queries.first
|
70
|
+
assert !dq.outer_start_pos.nil?
|
71
|
+
assert !dq.inner_start_pos.nil?
|
72
|
+
assert !dq.inner_end_pos.nil?
|
73
|
+
assert !dq.outer_end_pos.nil?
|
74
|
+
assert_equal css, css[dq.outer_start_pos..dq.outer_end_pos-1]
|
75
|
+
assert_equal child_content, css[dq.inner_start_pos..dq.inner_end_pos-1]
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
data/test/css/test_parser.rb
CHANGED
@@ -132,7 +132,7 @@ module CSSPool
|
|
132
132
|
@parser.scan_str css
|
133
133
|
property = @parser.handler.calls.find { |x|
|
134
134
|
x.first == :property
|
135
|
-
}[1][
|
135
|
+
}[1][0].expressions.first
|
136
136
|
|
137
137
|
term.each do |k,v|
|
138
138
|
assert_equal v, property.send(k)
|
@@ -159,7 +159,7 @@ module CSSPool
|
|
159
159
|
@parser.scan_str 'div { background: red; padding: 0; }'
|
160
160
|
names = @parser.handler.calls.find_all { |x|
|
161
161
|
x.first == :property
|
162
|
-
}.map { |y| y[1].first }
|
162
|
+
}.map { |y| y[1].first.property }
|
163
163
|
assert_equal %w{ background padding }, names
|
164
164
|
end
|
165
165
|
|
@@ -176,7 +176,7 @@ module CSSPool
|
|
176
176
|
declarations = @parser.handler.calls.find_all { |x|
|
177
177
|
x.first == :property
|
178
178
|
}
|
179
|
-
names = declarations.map { |y| y[1].first }
|
179
|
+
names = declarations.map { |y| y[1].first.property }
|
180
180
|
assert_equal %w{color color *color _color}, names
|
181
181
|
# values = declarations.map { |y| y[1][1].first.to_s }
|
182
182
|
# assert_equal %w{black green\\9 blue red}, values
|
@@ -284,7 +284,7 @@ module CSSPool
|
|
284
284
|
end
|
285
285
|
|
286
286
|
def test_ruleset_div_pseudo_function_with_arg
|
287
|
-
assert_attribute 'div:foo
|
287
|
+
assert_attribute 'div:foo(bar) { }'
|
288
288
|
end
|
289
289
|
|
290
290
|
def test_ruleset_div_pseudo_function
|
@@ -363,15 +363,15 @@ module CSSPool
|
|
363
363
|
def test_missing_semicolon
|
364
364
|
@parser.scan_str 'div { border: none }'
|
365
365
|
assert_equal 'div', doc.calls[1][1][0].join
|
366
|
-
assert_equal 'border', doc.calls[2][1][0]
|
367
|
-
assert_equal 'none', doc.calls[2][1][
|
366
|
+
assert_equal 'border', doc.calls[2][1][0].property
|
367
|
+
assert_equal 'none', doc.calls[2][1][0].expressions.first.value
|
368
368
|
end
|
369
369
|
|
370
370
|
def test_whitespaces
|
371
371
|
@parser.scan_str 'div { border : none }'
|
372
372
|
assert_equal 'div', doc.calls[1][1][0].join
|
373
|
-
assert_equal 'border', doc.calls[2][1][0]
|
374
|
-
assert_equal 'none', doc.calls[2][1][
|
373
|
+
assert_equal 'border', doc.calls[2][1][0].property
|
374
|
+
assert_equal 'none', doc.calls[2][1][0].expressions.first.value
|
375
375
|
end
|
376
376
|
|
377
377
|
def test_import_medium
|
@@ -389,33 +389,6 @@ module CSSPool
|
|
389
389
|
assert_equal 'print', doc.calls[1][1].first[1].value
|
390
390
|
end
|
391
391
|
|
392
|
-
def test_document_query_url
|
393
|
-
@parser.scan_str '@document url("http://example.com") { div {} }'
|
394
|
-
assert_equal :start_document_query, doc.calls[1].first
|
395
|
-
assert_equal 1, doc.calls[1][1][0].size
|
396
|
-
assert_equal CSSPool::Terms::URI, doc.calls[1][1][0][0].class
|
397
|
-
end
|
398
|
-
|
399
|
-
def test_document_query_function
|
400
|
-
@parser.scan_str '@document domain("example.com") { div {} }'
|
401
|
-
assert_equal :start_document_query, doc.calls[1].first
|
402
|
-
assert_equal 1, doc.calls[1][1][0].size
|
403
|
-
assert_equal CSSPool::Terms::Function, doc.calls[1][1][0][0].class
|
404
|
-
end
|
405
|
-
|
406
|
-
def test_document_query_function_no_quotes
|
407
|
-
@parser.scan_str '@document domain(example.com) { div {} }'
|
408
|
-
assert_equal :start_document_query, doc.calls[1].first
|
409
|
-
assert_equal 1, doc.calls[1][1][0].size
|
410
|
-
assert_equal CSSPool::Terms::Function, doc.calls[1][1][0][0].class
|
411
|
-
end
|
412
|
-
|
413
|
-
def test_document_query_multiple
|
414
|
-
@parser.scan_str '@document url("http://example.com"), domain("example.com") { div {} }'
|
415
|
-
assert_equal :start_document_query, doc.calls[1].first
|
416
|
-
assert_equal 2, doc.calls[1][1][0].size
|
417
|
-
end
|
418
|
-
|
419
392
|
def test_start_stop
|
420
393
|
@parser.scan_str "@import 'foo';"
|
421
394
|
assert_equal [:start_document, []], @doc.calls.first
|
@@ -441,12 +414,12 @@ module CSSPool
|
|
441
414
|
assert_equal :property, @parser.handler.calls[2].first
|
442
415
|
assert_equal :end_selector, @parser.handler.calls[3].first
|
443
416
|
|
444
|
-
|
445
|
-
assert_equal name, property
|
417
|
+
declaration = @parser.handler.calls[2][1].first
|
418
|
+
assert_equal name, declaration.property
|
446
419
|
|
447
|
-
assert_equal values,
|
420
|
+
assert_equal values, declaration.expressions.map { |x| x.value }
|
448
421
|
if ops
|
449
|
-
assert_equal ops,
|
422
|
+
assert_equal ops, declaration.expressions.map { |x| x.operator }
|
450
423
|
end
|
451
424
|
end
|
452
425
|
|
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module CSSPool
|
4
|
+
module CSS
|
5
|
+
class TestSupportsRule < CSSPool::TestCase
|
6
|
+
|
7
|
+
def test_basic
|
8
|
+
doc = CSSPool.CSS <<-eocss
|
9
|
+
@supports ( display: flexbox ) {
|
10
|
+
body { display: flexbox; }
|
11
|
+
}
|
12
|
+
eocss
|
13
|
+
assert_equal 1, doc.supports_rules.size
|
14
|
+
assert_match '( display: flexbox )', doc.supports_rules[0].conditions
|
15
|
+
assert_equal 1, doc.supports_rules[0].rule_sets.size
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_not
|
19
|
+
doc = CSSPool.CSS <<-eocss
|
20
|
+
@supports not ( display: flexbox ) {
|
21
|
+
body { display: flexbox; }
|
22
|
+
}
|
23
|
+
eocss
|
24
|
+
assert_equal 1, doc.supports_rules.size
|
25
|
+
assert_match 'not ( display: flexbox )', doc.supports_rules[0].conditions
|
26
|
+
assert_equal 1, doc.supports_rules[0].rule_sets.size
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_or
|
30
|
+
doc = CSSPool.CSS <<-eocss
|
31
|
+
@supports ( display: flexbox ) or ( display: block ) {
|
32
|
+
body { display: flexbox; }
|
33
|
+
}
|
34
|
+
eocss
|
35
|
+
assert_equal 1, doc.supports_rules.size
|
36
|
+
assert_match '( display: flexbox ) or ( display: block )', doc.supports_rules[0].conditions
|
37
|
+
assert_equal 1, doc.supports_rules[0].rule_sets.size
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_and
|
41
|
+
doc = CSSPool.CSS <<-eocss
|
42
|
+
@supports ( display: flexbox ) and ( display: block ) {
|
43
|
+
body { display: flexbox; }
|
44
|
+
}
|
45
|
+
eocss
|
46
|
+
assert_equal 1, doc.supports_rules.size
|
47
|
+
assert_match '( display: flexbox ) and ( display: block )', doc.supports_rules[0].conditions
|
48
|
+
assert_equal 1, doc.supports_rules[0].rule_sets.size
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_complex
|
52
|
+
doc = CSSPool.CSS <<-eocss
|
53
|
+
@supports ((display: inline) or (( display: flexbox ) and ( display: block ))) {
|
54
|
+
body { display: flexbox; }
|
55
|
+
}
|
56
|
+
eocss
|
57
|
+
assert_equal 1, doc.supports_rules.size
|
58
|
+
assert_match '((display: inline) or (( display: flexbox ) and ( display: block ))', doc.supports_rules[0].conditions
|
59
|
+
assert_equal 1, doc.supports_rules[0].rule_sets.size
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_double_parens
|
63
|
+
doc = CSSPool.CSS <<-eocss
|
64
|
+
@supports ((display: flexbox)) {
|
65
|
+
body { display: flexbox; }
|
66
|
+
}
|
67
|
+
eocss
|
68
|
+
assert_equal 1, doc.supports_rules.size
|
69
|
+
assert_match '((display: flexbox))', doc.supports_rules[0].conditions
|
70
|
+
assert_equal 1, doc.supports_rules[0].rule_sets.size
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_important
|
74
|
+
doc = CSSPool.CSS <<-eocss
|
75
|
+
@supports ( display: flexbox !important) {
|
76
|
+
body { display: flexbox; }
|
77
|
+
}
|
78
|
+
eocss
|
79
|
+
assert_equal 1, doc.supports_rules.size
|
80
|
+
assert_match '( display: flexbox !important)', doc.supports_rules[0].conditions
|
81
|
+
assert_equal 1, doc.supports_rules[0].rule_sets.size
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_other_use_of_keyword
|
85
|
+
doc = CSSPool.CSS <<-eocss
|
86
|
+
/* and */
|
87
|
+
.and { display: flexbox; content: " and ";}
|
88
|
+
and { and: and; }
|
89
|
+
eocss
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_invalid_keyword_in_place_of_and_or
|
93
|
+
exception_happened = false
|
94
|
+
begin
|
95
|
+
doc = CSSPool.CSS <<-eocss
|
96
|
+
@supports ( display: flexbox ) xor ( display: block ) {
|
97
|
+
body { display: flexbox; }
|
98
|
+
}
|
99
|
+
eocss
|
100
|
+
rescue
|
101
|
+
exception_happened = true
|
102
|
+
end
|
103
|
+
assert exception_happened
|
104
|
+
end
|
105
|
+
|
106
|
+
def test_invalid_keyword_in_place_of_not
|
107
|
+
exception_happened = false
|
108
|
+
begin
|
109
|
+
doc = CSSPool.CSS <<-eocss
|
110
|
+
@supports isnt ( display: flexbox ) {
|
111
|
+
body { display: flexbox; }
|
112
|
+
}
|
113
|
+
eocss
|
114
|
+
rescue
|
115
|
+
exception_happened = true
|
116
|
+
end
|
117
|
+
assert exception_happened
|
118
|
+
end
|
119
|
+
|
120
|
+
def test_with_parens
|
121
|
+
doc = CSSPool.CSS <<-eocss
|
122
|
+
@supports ( filter: url(http://example.com) ) {
|
123
|
+
body { filter: url(http://example.com) }
|
124
|
+
}
|
125
|
+
eocss
|
126
|
+
assert_equal 1, doc.supports_rules.size
|
127
|
+
assert_match 'filter: url("http://example.com")', doc.supports_rules[0].conditions
|
128
|
+
assert_equal 1, doc.supports_rules[0].rule_sets.size
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
data/test/css/test_tokenizer.rb
CHANGED
@@ -14,8 +14,8 @@ module CSSPool
|
|
14
14
|
end
|
15
15
|
|
16
16
|
{
|
17
|
-
'em' => :
|
18
|
-
'ex' => :
|
17
|
+
'em' => :LENGTH,
|
18
|
+
'ex' => :LENGTH,
|
19
19
|
'px' => :LENGTH,
|
20
20
|
'cm' => :LENGTH,
|
21
21
|
'mm' => :LENGTH,
|
@@ -206,7 +206,7 @@ module CSSPool
|
|
206
206
|
def test_scan_pseudo
|
207
207
|
@scanner.scan('a:visited')
|
208
208
|
assert_tokens([ [:IDENT, 'a'],
|
209
|
-
[
|
209
|
+
[:COLON, ':'],
|
210
210
|
[:IDENT, 'visited']
|
211
211
|
], @scanner)
|
212
212
|
end
|
@@ -256,7 +256,7 @@ module CSSPool
|
|
256
256
|
def test_scan_function_selector
|
257
257
|
@scanner.scan('x:eq(0)')
|
258
258
|
assert_tokens([ [:IDENT, 'x'],
|
259
|
-
[
|
259
|
+
[:COLON, ':'],
|
260
260
|
[:FUNCTION, 'eq('],
|
261
261
|
[:NUMBER, "0"],
|
262
262
|
[:RPAREN, ')'],
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
# CSS variables - http://dev.w3.org/csswg/css-variables/
|
4
|
+
module CSSPool
|
5
|
+
module CSS
|
6
|
+
class TestVariables < CSSPool::TestCase
|
7
|
+
|
8
|
+
# just checking that there's no parse error
|
9
|
+
def test_basic
|
10
|
+
doc = CSSPool.CSS <<-eocss
|
11
|
+
:root {
|
12
|
+
--main-bg-color: brown;
|
13
|
+
}
|
14
|
+
.one {
|
15
|
+
background-color: var(--main-bg-color);
|
16
|
+
}
|
17
|
+
eocss
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_var_in_calc
|
21
|
+
doc = CSSPool.CSS <<-eocss
|
22
|
+
:root {
|
23
|
+
--right-margin: 10px;
|
24
|
+
}
|
25
|
+
.one {
|
26
|
+
width: calc(100% + var(--right-margin));
|
27
|
+
}
|
28
|
+
eocss
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/test/helper.rb
CHANGED
@@ -12,7 +12,7 @@ module CSSPool
|
|
12
12
|
class MyDoc < CSSPool::CSS::DocumentHandler
|
13
13
|
attr_accessor :start_documents, :end_documents
|
14
14
|
attr_accessor :charsets, :import_styles, :document_queries, :comments, :start_selectors
|
15
|
-
attr_accessor :end_selectors, :properties
|
15
|
+
attr_accessor :end_selectors, :properties, :supports_rules
|
16
16
|
|
17
17
|
def initialize
|
18
18
|
@start_documents = []
|
@@ -26,8 +26,8 @@ module CSSPool
|
|
26
26
|
@properties = []
|
27
27
|
end
|
28
28
|
|
29
|
-
def property
|
30
|
-
@properties << [
|
29
|
+
def property declaration
|
30
|
+
@properties << [declaration.property, declaration.expressions]
|
31
31
|
end
|
32
32
|
|
33
33
|
def start_document
|
data/test/sac/test_parser.rb
CHANGED
@@ -90,6 +90,7 @@ module CSSPool
|
|
90
90
|
assert_nil simple_selector.additional_selectors.first.extra
|
91
91
|
end
|
92
92
|
|
93
|
+
# div#a, a.foo, a::hover, a[href][int="10"]{ background: red; }
|
93
94
|
def test_attribute_selector
|
94
95
|
selectors_for_rule = @doc.start_selectors[1]
|
95
96
|
selector = selectors_for_rule[3] # => a[href][int="10"]
|
data/test/test_parser.rb
CHANGED
@@ -29,15 +29,6 @@ module CSSPool
|
|
29
29
|
assert_equal 'background', rule_set.declarations.first.property
|
30
30
|
end
|
31
31
|
|
32
|
-
def test_media
|
33
|
-
doc = CSSPool.CSS <<-eocss
|
34
|
-
@media print {
|
35
|
-
div { background: red, blue; }
|
36
|
-
}
|
37
|
-
eocss
|
38
|
-
assert_equal 1, doc.rule_sets.first.media.media_list.length
|
39
|
-
end
|
40
|
-
|
41
32
|
def test_universal_to_css
|
42
33
|
doc = CSSPool.CSS <<-eocss
|
43
34
|
* { background: red, blue; }
|
@@ -120,5 +111,27 @@ module CSSPool
|
|
120
111
|
#assert_equal "http://\\\r\nexample.com/image.png", doc.rule_sets.first.declarations.first.expressions.first.value
|
121
112
|
end
|
122
113
|
|
114
|
+
def test_error_message_context
|
115
|
+
begin
|
116
|
+
doc = CSSPool.CSS "syntax } error"
|
117
|
+
# should not reach this
|
118
|
+
assert false
|
119
|
+
rescue ParseError => ex
|
120
|
+
# ensure the context around the failing token (the bracket) are included
|
121
|
+
assert_match 'syntax } error', ex.message
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_error_message_line
|
126
|
+
begin
|
127
|
+
doc = CSSPool.CSS "\n\n\nsyntax } error"
|
128
|
+
# should not reach this
|
129
|
+
assert false
|
130
|
+
rescue ParseError => ex
|
131
|
+
# ensure the context around the failing token (the bracket) are included
|
132
|
+
assert_match 'line 4', ex.message
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
123
136
|
end
|
124
137
|
end
|
data/test/test_selector.rb
CHANGED
@@ -4,14 +4,14 @@ module CSSPool
|
|
4
4
|
class TestSelector < CSSPool::TestCase
|
5
5
|
def test_specificity
|
6
6
|
doc = CSSPool.CSS <<-eocss
|
7
|
-
*, foo > bar, #hover, :hover, div#a, a.foo, a:hover, a[href][int="10"],
|
7
|
+
*, foo > bar, #hover, :hover, div#a, a.foo, a:hover, a[href][int="10"], p::selection { background: red; }
|
8
8
|
eocss
|
9
9
|
selectors = doc.rule_sets.first.selectors
|
10
10
|
specs = selectors.map do |sel|
|
11
11
|
sel.specificity
|
12
12
|
end
|
13
13
|
assert_equal [
|
14
|
-
[0, 0,
|
14
|
+
[0, 0, 0],
|
15
15
|
[0, 0, 2],
|
16
16
|
[1, 0, 0],
|
17
17
|
[0, 1, 0],
|
@@ -19,8 +19,7 @@ module CSSPool
|
|
19
19
|
[0, 1, 1],
|
20
20
|
[0, 1, 1],
|
21
21
|
[0, 2, 1],
|
22
|
-
[0, 0,
|
23
|
-
[0, 0, 1]
|
22
|
+
[0, 0, 2]
|
24
23
|
], specs
|
25
24
|
end
|
26
25
|
|
@@ -146,6 +145,47 @@ module CSSPool
|
|
146
145
|
assert_equal 'even', rs.selectors.first.simple_selectors.first.additional_selectors.first.extra
|
147
146
|
end
|
148
147
|
|
148
|
+
def test_mozilla_pseudo_element
|
149
|
+
doc = CSSPool.CSS <<-eocss
|
150
|
+
treechildren::-moz-tree-line { background: red; }
|
151
|
+
eocss
|
152
|
+
rs = doc.rule_sets.first
|
153
|
+
assert_equal '-moz-tree-line', rs.selectors.first.simple_selectors.first.additional_selectors.first.name
|
154
|
+
end
|
155
|
+
|
156
|
+
def test_mozilla_pseudo_element_brackets_without_parameters
|
157
|
+
doc = CSSPool.CSS <<-eocss
|
158
|
+
treechildren::-moz-tree-line() { background: red; }
|
159
|
+
eocss
|
160
|
+
rs = doc.rule_sets.first
|
161
|
+
assert_equal '-moz-tree-line', rs.selectors.first.simple_selectors.first.additional_selectors.first.name
|
162
|
+
end
|
163
|
+
|
164
|
+
def test_mozilla_pseudo_element_single_parameter
|
165
|
+
doc = CSSPool.CSS <<-eocss
|
166
|
+
treechildren::-moz-tree-line(one) { background: red; }
|
167
|
+
eocss
|
168
|
+
rs = doc.rule_sets.first
|
169
|
+
assert_equal '-moz-tree-line', rs.selectors.first.simple_selectors.first.additional_selectors.first.name
|
170
|
+
end
|
171
|
+
|
172
|
+
def test_mozilla_pseudo_element_multiple_parameters
|
173
|
+
doc = CSSPool.CSS <<-eocss
|
174
|
+
treechildren::-moz-tree-line(one, two, three) { background: red; }
|
175
|
+
eocss
|
176
|
+
rs = doc.rule_sets.first
|
177
|
+
assert_equal '-moz-tree-line', rs.selectors.first.simple_selectors.first.additional_selectors.first.name
|
178
|
+
end
|
179
|
+
|
180
|
+
# -moz-tree-cell and -moz-tree-cell-text are both mozilla pseudo-elements, make sure we don't stop at -moz-tree-cell
|
181
|
+
def test_mozilla_pseudo_element_name_within
|
182
|
+
doc = CSSPool.CSS <<-eocss
|
183
|
+
treechildren::-moz-tree-cell-text() { background: red; }
|
184
|
+
eocss
|
185
|
+
rs = doc.rule_sets.first
|
186
|
+
assert_equal '-moz-tree-cell-text', rs.selectors.first.simple_selectors.first.additional_selectors.first.name
|
187
|
+
end
|
188
|
+
|
149
189
|
def test_element_with_namespace
|
150
190
|
doc = CSSPool.CSS <<-eocss
|
151
191
|
a|b { background: red; }
|
data/test/test_term.rb
CHANGED
@@ -19,5 +19,34 @@ module CSSPool
|
|
19
19
|
assert_equal '100%/3 - 2*1em - 2*1px', rs.declarations.first.expressions.first.expression
|
20
20
|
end
|
21
21
|
|
22
|
+
def test_math_with_params
|
23
|
+
doc = CSSPool.CSS <<-eocss
|
24
|
+
a { top: calc((1em + 16px) / 2) }
|
25
|
+
eocss
|
26
|
+
rs = doc.rule_sets.first
|
27
|
+
assert_equal '(1em + 16px)/2', rs.declarations.first.expressions.first.expression
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_negative_multiplication
|
31
|
+
doc = CSSPool.CSS <<-eocss
|
32
|
+
a { top: calc(1.4 * -8px) }
|
33
|
+
eocss
|
34
|
+
rs = doc.rule_sets.first
|
35
|
+
assert_equal '1.4*-8px', rs.declarations.first.expressions.first.expression
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_two_in_a_row
|
39
|
+
doc = CSSPool.CSS <<-eocss
|
40
|
+
a { background-size: calc(-2px + 100%) calc(-2px + 100%); }
|
41
|
+
eocss
|
42
|
+
rs = doc.rule_sets.first
|
43
|
+
assert_equal '-2px + 100%', rs.declarations.first.expressions.first.expression
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_function_no_params
|
47
|
+
CSSPool.CSS <<-eocss
|
48
|
+
a { -webkit-filter: invert() }
|
49
|
+
eocss
|
50
|
+
end
|
22
51
|
end
|
23
52
|
end
|
@@ -97,6 +97,14 @@ module CSSPool
|
|
97
97
|
equalitest '@import "foo.css" screen, print;'
|
98
98
|
equalitest '@import "foo.css";'
|
99
99
|
end
|
100
|
+
|
101
|
+
def test_media_query_list_with_empty_body
|
102
|
+
equalitest "@media screen and (min-width:400px) and (max-width:600px) {}"
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_media_query_list_with_body
|
106
|
+
equalitest "@media screen and (min-width:400px) and (max-width:600px) { div { color: inherit; } }"
|
107
|
+
end
|
100
108
|
end
|
101
109
|
end
|
102
110
|
end
|