csspool 3.0.2 → 4.0.0.pre
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.
- data/Gemfile.lock +4 -4
- data/Manifest.txt +13 -0
- data/README.rdoc +1 -1
- data/lib/csspool/css/document.rb +6 -0
- data/lib/csspool/css/document_handler.rb +41 -7
- data/lib/csspool/css/document_query.rb +14 -0
- data/lib/csspool/css/import_rule.rb +8 -4
- data/lib/csspool/css/keyframes_block.rb +14 -0
- data/lib/csspool/css/keyframes_rule.rb +14 -0
- data/lib/csspool/css/media.rb +5 -3
- data/lib/csspool/css/namespace_rule.rb +13 -0
- data/lib/csspool/css/parser.rb +970 -425
- data/lib/csspool/css/parser.y +227 -30
- data/lib/csspool/css/tokenizer.rb +31 -7
- data/lib/csspool/css/tokenizer.rex +36 -7
- data/lib/csspool/css.rb +4 -0
- data/lib/csspool/selector.rb +5 -1
- data/lib/csspool/selectors/attribute.rb +6 -1
- data/lib/csspool/selectors/pseudo.rb +17 -0
- data/lib/csspool/selectors/pseudo_element.rb +13 -0
- data/lib/csspool/selectors/simple.rb +0 -4
- data/lib/csspool/selectors/type.rb +7 -0
- data/lib/csspool/selectors/universal.rb +7 -0
- data/lib/csspool/selectors.rb +1 -1
- data/lib/csspool/terms/math.rb +18 -0
- data/lib/csspool/terms.rb +1 -0
- data/lib/csspool/visitors/children.rb +1 -1
- data/lib/csspool/visitors/comparable.rb +8 -2
- data/lib/csspool/visitors/iterator.rb +1 -1
- data/lib/csspool/visitors/to_css.rb +41 -21
- data/lib/csspool.rb +1 -1
- data/test/_local_helper.rb +2 -0
- data/test/css/test_document_query.rb +76 -0
- data/test/css/test_import_rule.rb +1 -1
- data/test/css/test_keyframes_rule.rb +93 -0
- data/test/css/test_namespace_rule.rb +54 -0
- data/test/css/test_parser.rb +46 -1
- data/test/css/test_tokenizer.rb +0 -45
- data/test/helper.rb +6 -1
- data/test/sac/test_parser.rb +16 -3
- data/test/test_declaration.rb +39 -0
- data/test/test_parser.rb +26 -13
- data/test/test_selector.rb +205 -5
- data/test/test_term.rb +23 -0
- data/test/visitors/test_to_css.rb +34 -23
- metadata +136 -118
@@ -0,0 +1,18 @@
|
|
1
|
+
# http://dev.w3.org/csswg/css3-values/#calc-notation
|
2
|
+
module CSSPool
|
3
|
+
module Terms
|
4
|
+
class Math < CSSPool::Node
|
5
|
+
attr_accessor :name
|
6
|
+
attr_accessor :expression
|
7
|
+
attr_accessor :operator
|
8
|
+
attr_accessor :parse_location
|
9
|
+
|
10
|
+
def initialize name, expression, operator = nil, parse_location = {}
|
11
|
+
@name = name
|
12
|
+
@expression = expression
|
13
|
+
@operator = operator
|
14
|
+
@parse_location = parse_location
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/csspool/terms.rb
CHANGED
@@ -27,7 +27,7 @@ module CSSPool
|
|
27
27
|
end
|
28
28
|
|
29
29
|
visitor_for CSS::ImportRule do |target|
|
30
|
-
[:uri, :namespace, :
|
30
|
+
[:uri, :namespace, :media_list].all? { |m|
|
31
31
|
target.send(m) == @other.send(m)
|
32
32
|
}
|
33
33
|
end
|
@@ -38,7 +38,13 @@ module CSSPool
|
|
38
38
|
}
|
39
39
|
end
|
40
40
|
|
41
|
-
visitor_for CSS::Media
|
41
|
+
visitor_for CSS::Media do |target|
|
42
|
+
[:media_list].all? { |m|
|
43
|
+
target.send(m) == @other.send(m)
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
visitor_for Selectors::Id, Selectors::Class do |target|
|
42
48
|
target.name == @other.name
|
43
49
|
end
|
44
50
|
|
@@ -33,8 +33,8 @@ module CSSPool
|
|
33
33
|
|
34
34
|
target.rule_sets.each { |rs|
|
35
35
|
if rs.media != current_media_type
|
36
|
-
media = " " + rs.media.map do |medium|
|
37
|
-
escape_css_identifier medium.
|
36
|
+
media = " " + rs.media.media_list.map do |medium|
|
37
|
+
escape_css_identifier medium.value
|
38
38
|
end.join(', ')
|
39
39
|
tokens << "#{indent}@media#{media} {"
|
40
40
|
@indent_level += 1
|
@@ -57,13 +57,25 @@ module CSSPool
|
|
57
57
|
|
58
58
|
visitor_for CSS::ImportRule do |target|
|
59
59
|
media = ''
|
60
|
-
media = " " + target.
|
61
|
-
escape_css_identifier medium.
|
62
|
-
end.join(', ') if target.
|
60
|
+
media = " " + target.media_list.map do |medium|
|
61
|
+
escape_css_identifier medium.value
|
62
|
+
end.join(', ') if target.media_list.length > 0
|
63
63
|
|
64
64
|
"#{indent}@import #{target.uri.accept(self)}#{media};"
|
65
65
|
end
|
66
66
|
|
67
|
+
visitor_for CSS::DocumentQuery do |target|
|
68
|
+
"#{indent}@document #{target.url_functions.join(', ')} {}"
|
69
|
+
end
|
70
|
+
|
71
|
+
visitor_for CSS::NamespaceRule do |target|
|
72
|
+
if target.prefix.nil?
|
73
|
+
"#{indent}@namespace #{target.uri.accept(self)}"
|
74
|
+
else
|
75
|
+
"#{indent}@namespace #{target.prefix.value} #{target.uri.accept(self)}"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
67
79
|
visitor_for CSS::RuleSet do |target|
|
68
80
|
"#{indent}" +
|
69
81
|
target.selectors.map { |sel| sel.accept self }.join(", ") + " {#{line_break}" +
|
@@ -95,12 +107,6 @@ module CSSPool
|
|
95
107
|
"##{target.value}"
|
96
108
|
end
|
97
109
|
|
98
|
-
visitor_for Selectors::Simple, Selectors::Universal do |target|
|
99
|
-
([target.name] + target.additional_selectors.map { |x|
|
100
|
-
x.accept self
|
101
|
-
}).join
|
102
|
-
end
|
103
|
-
|
104
110
|
visitor_for Terms::URI do |target|
|
105
111
|
"url(\"#{escape_css_string target.value}\")"
|
106
112
|
end
|
@@ -131,30 +137,30 @@ module CSSPool
|
|
131
137
|
"\"#{escape_css_string target.value}\""
|
132
138
|
end
|
133
139
|
|
140
|
+
visitor_for Terms::Number do |target|
|
141
|
+
[
|
142
|
+
target.unary_operator == :minus ? '-' : nil,
|
143
|
+
target.value,
|
144
|
+
target.type
|
145
|
+
].compact.join
|
146
|
+
end
|
147
|
+
|
134
148
|
visitor_for Selector do |target|
|
135
149
|
target.simple_selectors.map { |ss| ss.accept self }.join
|
136
150
|
end
|
137
151
|
|
138
|
-
visitor_for Selectors::Type do |target|
|
152
|
+
visitor_for Selectors::Simple, Selectors::Universal, Selectors::Type do |target|
|
139
153
|
combo = {
|
140
154
|
:s => ' ',
|
141
155
|
:+ => ' + ',
|
142
156
|
:> => ' > '
|
143
157
|
}[target.combinator]
|
144
158
|
|
145
|
-
name =
|
159
|
+
name = [nil, '*'].include?(target.name) ? target.name : escape_css_identifier(target.name)
|
146
160
|
[combo, name].compact.join +
|
147
161
|
target.additional_selectors.map { |as| as.accept self }.join
|
148
162
|
end
|
149
163
|
|
150
|
-
visitor_for Terms::Number do |target|
|
151
|
-
[
|
152
|
-
target.unary_operator == :minus ? '-' : nil,
|
153
|
-
target.value,
|
154
|
-
target.type
|
155
|
-
].compact.join
|
156
|
-
end
|
157
|
-
|
158
164
|
visitor_for Selectors::Id do |target|
|
159
165
|
"##{escape_css_identifier target.name}"
|
160
166
|
end
|
@@ -171,6 +177,14 @@ module CSSPool
|
|
171
177
|
end
|
172
178
|
end
|
173
179
|
|
180
|
+
visitor_for Selectors::PseudoElement do |target|
|
181
|
+
if target.css2.nil?
|
182
|
+
"::#{escape_css_identifier target.name}"
|
183
|
+
else
|
184
|
+
":#{escape_css_identifier target.name}"
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
174
188
|
visitor_for Selectors::Attribute do |target|
|
175
189
|
case target.match_way
|
176
190
|
when Selectors::Attribute::SET
|
@@ -181,6 +195,12 @@ module CSSPool
|
|
181
195
|
"[#{escape_css_identifier target.name} ~= \"#{escape_css_string target.value}\"]"
|
182
196
|
when Selectors::Attribute::DASHMATCH
|
183
197
|
"[#{escape_css_identifier target.name} |= \"#{escape_css_string target.value}\"]"
|
198
|
+
when Selectors::Attribute::PREFIXMATCH
|
199
|
+
"[#{escape_css_identifier target.name} ^= \"#{escape_css_string target.value}\"]"
|
200
|
+
when Selectors::Attribute::SUFFIXMATCH
|
201
|
+
"[#{escape_css_identifier target.name} $= \"#{escape_css_string target.value}\"]"
|
202
|
+
when Selectors::Attribute::SUBSTRINGMATCH
|
203
|
+
"[#{escape_css_identifier target.name} *= \"#{escape_css_string target.value}\"]"
|
184
204
|
else
|
185
205
|
raise "no matching matchway"
|
186
206
|
end
|
data/lib/csspool.rb
CHANGED
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module CSSPool
|
4
|
+
module CSS
|
5
|
+
class TestDocumentQuery < CSSPool::TestCase
|
6
|
+
|
7
|
+
def test_function
|
8
|
+
doc = CSSPool.CSS <<-eocss
|
9
|
+
@document domain("example.com") {
|
10
|
+
* { color: blue; }
|
11
|
+
}
|
12
|
+
eocss
|
13
|
+
assert_equal 1, doc.document_queries.size
|
14
|
+
assert_equal 1, doc.document_queries[0].url_functions.size
|
15
|
+
assert_equal CSSPool::Terms::Function, doc.document_queries[0].url_functions[0].class
|
16
|
+
assert_equal 'domain', doc.document_queries[0].url_functions[0].name
|
17
|
+
assert_equal 'example.com', doc.document_queries[0].url_functions[0].params[0].value
|
18
|
+
assert_equal 1, doc.document_queries[0].rule_sets.size
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_function_no_quote
|
22
|
+
doc = CSSPool.CSS <<-eocss
|
23
|
+
@document domain(example.com) {
|
24
|
+
* { color: blue; }
|
25
|
+
}
|
26
|
+
eocss
|
27
|
+
assert_equal 1, doc.document_queries.size
|
28
|
+
assert_equal 1, doc.document_queries[0].url_functions.size
|
29
|
+
assert_equal CSSPool::Terms::Function, doc.document_queries[0].url_functions[0].class
|
30
|
+
assert_equal 'domain', doc.document_queries[0].url_functions[0].name
|
31
|
+
assert_equal 'example.com', doc.document_queries[0].url_functions[0].params[0].value
|
32
|
+
assert_equal 1, doc.document_queries[0].rule_sets.size
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_multiple
|
36
|
+
doc = CSSPool.CSS <<-eocss
|
37
|
+
@document domain(example.com), url-prefix(http://example.com) {
|
38
|
+
* { color: blue; }
|
39
|
+
}
|
40
|
+
eocss
|
41
|
+
assert_equal 1, doc.document_queries.size
|
42
|
+
assert_equal 2, doc.document_queries[0].url_functions.size
|
43
|
+
assert_equal CSSPool::Terms::Function, doc.document_queries[0].url_functions[0].class
|
44
|
+
assert_equal 'domain', doc.document_queries[0].url_functions[0].name
|
45
|
+
assert_equal 'example.com', doc.document_queries[0].url_functions[0].params[0].value
|
46
|
+
assert_equal CSSPool::Terms::Function, doc.document_queries[0].url_functions[1].class
|
47
|
+
assert_equal 'url-prefix', doc.document_queries[0].url_functions[1].name
|
48
|
+
assert_equal 'http://example.com', doc.document_queries[0].url_functions[1].params[0].value
|
49
|
+
assert_equal 1, doc.document_queries[0].rule_sets.size
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_url
|
53
|
+
doc = CSSPool.CSS <<-eocss
|
54
|
+
@document url("http://www.example.com") {
|
55
|
+
* { color: blue; }
|
56
|
+
}
|
57
|
+
eocss
|
58
|
+
assert_equal 1, doc.document_queries.size
|
59
|
+
assert_equal 1, doc.document_queries[0].url_functions.size
|
60
|
+
assert_equal CSSPool::Terms::URI, doc.document_queries[0].url_functions[0].class
|
61
|
+
assert_equal 'http://www.example.com', doc.document_queries[0].url_functions[0].value
|
62
|
+
assert_equal 1, doc.document_queries[0].rule_sets.size
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_empty
|
66
|
+
doc = CSSPool.CSS <<-eocss
|
67
|
+
@document url("http://www.example.com") {
|
68
|
+
}
|
69
|
+
eocss
|
70
|
+
assert_equal 1, doc.document_queries.size
|
71
|
+
assert_equal true, doc.document_queries[0].rule_sets.empty?
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
# CSS keyframes - http://dev.w3.org/csswg/css3-animations/#keyframes
|
4
|
+
module CSSPool
|
5
|
+
module CSS
|
6
|
+
class TestKeyframesRule < CSSPool::TestCase
|
7
|
+
|
8
|
+
def test_empty
|
9
|
+
doc = CSSPool.CSS <<-eocss
|
10
|
+
@keyframes id {}
|
11
|
+
eocss
|
12
|
+
assert_equal 1, doc.keyframes_rules.size
|
13
|
+
assert_equal 'id', doc.keyframes_rules.first.name
|
14
|
+
assert_equal 0, doc.keyframes_rules.first.rule_sets.size
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_from
|
18
|
+
doc = CSSPool.CSS <<-eocss
|
19
|
+
@keyframes id {
|
20
|
+
from {
|
21
|
+
top: 0;
|
22
|
+
}
|
23
|
+
}
|
24
|
+
eocss
|
25
|
+
assert_equal 1, doc.keyframes_rules.first.rule_sets.size
|
26
|
+
assert_equal 'from', doc.keyframes_rules.first.rule_sets.first.keyText
|
27
|
+
assert_equal 1, doc.keyframes_rules.first.rule_sets.first.declarations.size
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_to
|
31
|
+
doc = CSSPool.CSS <<-eocss
|
32
|
+
@keyframes id {
|
33
|
+
to {
|
34
|
+
top: 0;
|
35
|
+
}
|
36
|
+
}
|
37
|
+
eocss
|
38
|
+
assert_equal 1, doc.keyframes_rules.first.rule_sets.size
|
39
|
+
assert_equal 'to', doc.keyframes_rules.first.rule_sets.first.keyText
|
40
|
+
assert_equal 1, doc.keyframes_rules.first.rule_sets.first.declarations.size
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_percent
|
44
|
+
doc = CSSPool.CSS <<-eocss
|
45
|
+
@keyframes id {
|
46
|
+
50% {
|
47
|
+
top: 0;
|
48
|
+
}
|
49
|
+
}
|
50
|
+
eocss
|
51
|
+
assert_equal 1, doc.keyframes_rules.first.rule_sets.size
|
52
|
+
assert_equal '50%', doc.keyframes_rules.first.rule_sets.first.keyText
|
53
|
+
assert_equal 1, doc.keyframes_rules.first.rule_sets.first.declarations.size
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_multiple_selector
|
57
|
+
doc = CSSPool.CSS <<-eocss
|
58
|
+
@keyframes id {
|
59
|
+
from, to, 50% {
|
60
|
+
top: 0;
|
61
|
+
}
|
62
|
+
}
|
63
|
+
eocss
|
64
|
+
assert_equal 1, doc.keyframes_rules.first.rule_sets.size
|
65
|
+
assert_equal 'from, to, 50%', doc.keyframes_rules.first.rule_sets.first.keyText
|
66
|
+
assert_equal 1, doc.keyframes_rules.first.rule_sets.first.declarations.size
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_multiple_blocks
|
70
|
+
doc = CSSPool.CSS <<-eocss
|
71
|
+
@keyframes id {
|
72
|
+
from {
|
73
|
+
top: 0;
|
74
|
+
}
|
75
|
+
to {
|
76
|
+
top: 0;
|
77
|
+
}
|
78
|
+
}
|
79
|
+
eocss
|
80
|
+
assert_equal 2, doc.keyframes_rules.first.rule_sets.size
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_vendor_prefix
|
84
|
+
doc = CSSPool.CSS <<-eocss
|
85
|
+
@-moz-keyframes id {}
|
86
|
+
eocss
|
87
|
+
assert_equal 1, doc.keyframes_rules.size
|
88
|
+
assert_equal 'id', doc.keyframes_rules.first.name
|
89
|
+
assert_equal 0, doc.keyframes_rules.first.rule_sets.size
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
# CSS namespaces - http://www.w3.org/TR/css3-namespace/
|
4
|
+
module CSSPool
|
5
|
+
module CSS
|
6
|
+
class TestNamespaceRule < CSSPool::TestCase
|
7
|
+
|
8
|
+
def test_default_string
|
9
|
+
doc = CSSPool.CSS <<-eocss
|
10
|
+
@namespace "http://www.w3.org/1999/xhtml/";
|
11
|
+
eocss
|
12
|
+
assert_equal 1, doc.namespaces.size
|
13
|
+
assert_equal CSSPool::CSS::NamespaceRule, doc.namespaces[0].class
|
14
|
+
assert_equal nil, doc.namespaces[0].prefix
|
15
|
+
assert_equal CSSPool::Terms::String, doc.namespaces[0].uri.class
|
16
|
+
assert_equal 'http://www.w3.org/1999/xhtml/', doc.namespaces[0].uri.value
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_default_uri
|
20
|
+
doc = CSSPool.CSS <<-eocss
|
21
|
+
@namespace url("http://www.w3.org/1999/xhtml/");
|
22
|
+
eocss
|
23
|
+
assert_equal 1, doc.namespaces.size
|
24
|
+
assert_equal CSSPool::CSS::NamespaceRule, doc.namespaces[0].class
|
25
|
+
assert_equal nil, doc.namespaces[0].prefix
|
26
|
+
assert_equal CSSPool::Terms::URI, doc.namespaces[0].uri.class
|
27
|
+
assert_equal 'http://www.w3.org/1999/xhtml/', doc.namespaces[0].uri.value
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_prefix
|
31
|
+
doc = CSSPool.CSS <<-eocss
|
32
|
+
@namespace xhtml url("http://www.w3.org/1999/xhtml/");
|
33
|
+
eocss
|
34
|
+
assert_equal 1, doc.namespaces.size
|
35
|
+
assert_equal CSSPool::CSS::NamespaceRule, doc.namespaces[0].class
|
36
|
+
assert_equal CSSPool::Terms::Ident, doc.namespaces[0].prefix.class
|
37
|
+
assert_equal 'xhtml', doc.namespaces[0].prefix.value
|
38
|
+
assert_equal CSSPool::Terms::URI, doc.namespaces[0].uri.class
|
39
|
+
assert_equal 'http://www.w3.org/1999/xhtml/', doc.namespaces[0].uri.value
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_multiple
|
43
|
+
doc = CSSPool.CSS <<-eocss
|
44
|
+
@namespace url("http://www.w3.org/1999/xhtml/");
|
45
|
+
@namespace xul url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
|
46
|
+
eocss
|
47
|
+
assert_equal 2, doc.namespaces.size
|
48
|
+
assert_equal CSSPool::CSS::NamespaceRule, doc.namespaces[0].class
|
49
|
+
assert_equal CSSPool::CSS::NamespaceRule, doc.namespaces[1].class
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/test/css/test_parser.rb
CHANGED
@@ -193,7 +193,7 @@ module CSSPool
|
|
193
193
|
assert_attribute 'div:foo[a] { }'
|
194
194
|
assert_attribute 'div#foo[a] { }'
|
195
195
|
assert_attribute 'div.foo[a] { }'
|
196
|
-
assert_attribute 'div
|
196
|
+
assert_attribute 'div[a]::foo { }'
|
197
197
|
end
|
198
198
|
|
199
199
|
def test_additional_selectors_id_pesuedoclass
|
@@ -252,6 +252,10 @@ module CSSPool
|
|
252
252
|
{ Selectors::PseudoClass => 'foo' }, ':foo() { }')
|
253
253
|
assert_additional_selector(
|
254
254
|
{ Selectors::PseudoClass => 'foo' }, ':foo(a) { }')
|
255
|
+
assert_additional_selector(
|
256
|
+
{ Selectors::PseudoElement => 'foo' }, '::foo { }')
|
257
|
+
assert_additional_selector(
|
258
|
+
{ Selectors::PseudoElement => 'before' }, ':before { }')
|
255
259
|
end
|
256
260
|
|
257
261
|
def test_additional_selectors_id
|
@@ -356,6 +360,20 @@ module CSSPool
|
|
356
360
|
assert_equal :import_style, doc.calls[1].first
|
357
361
|
end
|
358
362
|
|
363
|
+
def test_missing_semicolon
|
364
|
+
@parser.scan_str 'div { border: none }'
|
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][1].join
|
368
|
+
end
|
369
|
+
|
370
|
+
def test_whitespaces
|
371
|
+
@parser.scan_str 'div { border : none }'
|
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][1].join
|
375
|
+
end
|
376
|
+
|
359
377
|
def test_import_medium
|
360
378
|
@parser.scan_str '@import "foo" page;'
|
361
379
|
assert_equal :import_style, doc.calls[1].first
|
@@ -371,6 +389,33 @@ module CSSPool
|
|
371
389
|
assert_equal 'print', doc.calls[1][1].first[1].value
|
372
390
|
end
|
373
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
|
+
|
374
419
|
def test_start_stop
|
375
420
|
@parser.scan_str "@import 'foo';"
|
376
421
|
assert_equal [:start_document, []], @doc.calls.first
|
data/test/css/test_tokenizer.rb
CHANGED
@@ -162,16 +162,6 @@ module CSSPool
|
|
162
162
|
], @scanner)
|
163
163
|
end
|
164
164
|
|
165
|
-
def test_negation
|
166
|
-
@scanner.scan("p:not(.a)")
|
167
|
-
assert_tokens([ [:IDENT, 'p'],
|
168
|
-
[:NOT, ':not('],
|
169
|
-
['.', '.'],
|
170
|
-
[:IDENT, 'a'],
|
171
|
-
[:RPAREN, ')'],
|
172
|
-
], @scanner)
|
173
|
-
end
|
174
|
-
|
175
165
|
def test_function
|
176
166
|
@scanner.scan("script comment()")
|
177
167
|
assert_tokens([ [:IDENT, 'script'],
|
@@ -273,41 +263,6 @@ module CSSPool
|
|
273
263
|
], @scanner)
|
274
264
|
end
|
275
265
|
|
276
|
-
def test_scan_an_plus_b
|
277
|
-
@scanner.scan('x:nth-child(5n+3)')
|
278
|
-
assert_tokens([ [:IDENT, 'x'],
|
279
|
-
[':', ':'],
|
280
|
-
[:FUNCTION, 'nth-child('],
|
281
|
-
[:NUMBER, '5'],
|
282
|
-
[:IDENT, 'n'],
|
283
|
-
[:PLUS, '+'],
|
284
|
-
[:NUMBER, '3'],
|
285
|
-
[:RPAREN, ')'],
|
286
|
-
], @scanner)
|
287
|
-
|
288
|
-
@scanner.scan('x:nth-child(-1n+3)')
|
289
|
-
assert_tokens([ [:IDENT, 'x'],
|
290
|
-
[':', ':'],
|
291
|
-
[:FUNCTION, 'nth-child('],
|
292
|
-
[:MINUS, '-'],
|
293
|
-
[:NUMBER, '1'],
|
294
|
-
[:IDENT, 'n'],
|
295
|
-
[:PLUS, '+'],
|
296
|
-
[:NUMBER, '3'],
|
297
|
-
[:RPAREN, ')'],
|
298
|
-
], @scanner)
|
299
|
-
|
300
|
-
@scanner.scan('x:nth-child(-n+3)')
|
301
|
-
assert_tokens([ [:IDENT, 'x'],
|
302
|
-
[':', ':'],
|
303
|
-
[:FUNCTION, 'nth-child('],
|
304
|
-
[:IDENT, '-n'],
|
305
|
-
[:PLUS, '+'],
|
306
|
-
[:NUMBER, '3'],
|
307
|
-
[:RPAREN, ')'],
|
308
|
-
], @scanner)
|
309
|
-
end
|
310
|
-
|
311
266
|
def assert_tokens(tokens, scanner)
|
312
267
|
toks = []
|
313
268
|
while tok = @scanner.next_token
|
data/test/helper.rb
CHANGED
@@ -11,7 +11,7 @@ module CSSPool
|
|
11
11
|
|
12
12
|
class MyDoc < CSSPool::CSS::DocumentHandler
|
13
13
|
attr_accessor :start_documents, :end_documents
|
14
|
-
attr_accessor :charsets, :import_styles, :comments, :start_selectors
|
14
|
+
attr_accessor :charsets, :import_styles, :document_queries, :comments, :start_selectors
|
15
15
|
attr_accessor :end_selectors, :properties
|
16
16
|
|
17
17
|
def initialize
|
@@ -19,6 +19,7 @@ module CSSPool
|
|
19
19
|
@end_documents = []
|
20
20
|
@charsets = []
|
21
21
|
@import_styles = []
|
22
|
+
@document_queries = []
|
22
23
|
@comments = []
|
23
24
|
@start_selectors = []
|
24
25
|
@end_selectors = []
|
@@ -45,6 +46,10 @@ module CSSPool
|
|
45
46
|
@import_styles << [media_list, uri, default_ns, location]
|
46
47
|
end
|
47
48
|
|
49
|
+
def document_query string
|
50
|
+
@document_queries << string
|
51
|
+
end
|
52
|
+
|
48
53
|
def namespace_declaration prefix, uri, location
|
49
54
|
@import_styles << [prefix, uri, location]
|
50
55
|
end
|
data/test/sac/test_parser.rb
CHANGED
@@ -12,6 +12,7 @@ module CSSPool
|
|
12
12
|
/* This is a comment */
|
13
13
|
div a.foo, #bar, * { background: red; }
|
14
14
|
div#a, a.foo, a:hover, a[href][int="10"]{ background: red; }
|
15
|
+
::selection, q:before { background: red; }
|
15
16
|
eocss
|
16
17
|
@parser = CSSPool::SAC::Parser.new(@doc)
|
17
18
|
@parser.parse(@css)
|
@@ -74,7 +75,6 @@ module CSSPool
|
|
74
75
|
assert_equal 'foo', foo_class.name
|
75
76
|
end
|
76
77
|
|
77
|
-
# div#a, a.foo, a:hover, a[href='watever'] { background: red; }
|
78
78
|
def test_id_additional_selector
|
79
79
|
selectors_for_rule = @doc.start_selectors[1]
|
80
80
|
selector = selectors_for_rule.first # => div#a
|
@@ -82,7 +82,6 @@ module CSSPool
|
|
82
82
|
assert_equal 'a', simple_selector.additional_selectors.first.name
|
83
83
|
end
|
84
84
|
|
85
|
-
# div#a, a.foo, a:hover, a[href][int="10"]{ background: red; }
|
86
85
|
def test_pseudo_additional_selector
|
87
86
|
selectors_for_rule = @doc.start_selectors[1]
|
88
87
|
selector = selectors_for_rule[2] # => 'a:hover'
|
@@ -91,7 +90,6 @@ module CSSPool
|
|
91
90
|
assert_nil simple_selector.additional_selectors.first.extra
|
92
91
|
end
|
93
92
|
|
94
|
-
# div#a, a.foo, a:hover, a[href][int="10"]{ background: red; }
|
95
93
|
def test_attribute_selector
|
96
94
|
selectors_for_rule = @doc.start_selectors[1]
|
97
95
|
selector = selectors_for_rule[3] # => a[href][int="10"]
|
@@ -105,6 +103,21 @@ module CSSPool
|
|
105
103
|
assert_equal '10', simple_selector.additional_selectors[1].value
|
106
104
|
assert_equal 2, simple_selector.additional_selectors[1].match_way
|
107
105
|
end
|
106
|
+
|
107
|
+
def test_pseudo_element_additional_selector
|
108
|
+
selectors_for_rule = @doc.start_selectors[2]
|
109
|
+
selector = selectors_for_rule[0]
|
110
|
+
|
111
|
+
simple_selector = selector.simple_selectors[0] # ::selection
|
112
|
+
assert_equal 'selection', simple_selector.additional_selectors.first.name
|
113
|
+
assert_nil simple_selector.additional_selectors.first.css2
|
114
|
+
|
115
|
+
selector = selectors_for_rule[1]
|
116
|
+
simple_selector = selector.simple_selectors[0] # q.before
|
117
|
+
assert_equal 'before', simple_selector.additional_selectors.first.name
|
118
|
+
assert_equal true, simple_selector.additional_selectors.first.css2
|
119
|
+
end
|
120
|
+
|
108
121
|
end
|
109
122
|
end
|
110
123
|
end
|