csspool 4.0.0.pre → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|