csspool 3.0.2 → 4.0.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/Gemfile.lock +4 -4
  2. data/Manifest.txt +13 -0
  3. data/README.rdoc +1 -1
  4. data/lib/csspool/css/document.rb +6 -0
  5. data/lib/csspool/css/document_handler.rb +41 -7
  6. data/lib/csspool/css/document_query.rb +14 -0
  7. data/lib/csspool/css/import_rule.rb +8 -4
  8. data/lib/csspool/css/keyframes_block.rb +14 -0
  9. data/lib/csspool/css/keyframes_rule.rb +14 -0
  10. data/lib/csspool/css/media.rb +5 -3
  11. data/lib/csspool/css/namespace_rule.rb +13 -0
  12. data/lib/csspool/css/parser.rb +970 -425
  13. data/lib/csspool/css/parser.y +227 -30
  14. data/lib/csspool/css/tokenizer.rb +31 -7
  15. data/lib/csspool/css/tokenizer.rex +36 -7
  16. data/lib/csspool/css.rb +4 -0
  17. data/lib/csspool/selector.rb +5 -1
  18. data/lib/csspool/selectors/attribute.rb +6 -1
  19. data/lib/csspool/selectors/pseudo.rb +17 -0
  20. data/lib/csspool/selectors/pseudo_element.rb +13 -0
  21. data/lib/csspool/selectors/simple.rb +0 -4
  22. data/lib/csspool/selectors/type.rb +7 -0
  23. data/lib/csspool/selectors/universal.rb +7 -0
  24. data/lib/csspool/selectors.rb +1 -1
  25. data/lib/csspool/terms/math.rb +18 -0
  26. data/lib/csspool/terms.rb +1 -0
  27. data/lib/csspool/visitors/children.rb +1 -1
  28. data/lib/csspool/visitors/comparable.rb +8 -2
  29. data/lib/csspool/visitors/iterator.rb +1 -1
  30. data/lib/csspool/visitors/to_css.rb +41 -21
  31. data/lib/csspool.rb +1 -1
  32. data/test/_local_helper.rb +2 -0
  33. data/test/css/test_document_query.rb +76 -0
  34. data/test/css/test_import_rule.rb +1 -1
  35. data/test/css/test_keyframes_rule.rb +93 -0
  36. data/test/css/test_namespace_rule.rb +54 -0
  37. data/test/css/test_parser.rb +46 -1
  38. data/test/css/test_tokenizer.rb +0 -45
  39. data/test/helper.rb +6 -1
  40. data/test/sac/test_parser.rb +16 -3
  41. data/test/test_declaration.rb +39 -0
  42. data/test/test_parser.rb +26 -13
  43. data/test/test_selector.rb +205 -5
  44. data/test/test_term.rb +23 -0
  45. data/test/visitors/test_to_css.rb +34 -23
  46. 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
@@ -5,3 +5,4 @@ require 'csspool/terms/function'
5
5
  require 'csspool/terms/uri'
6
6
  require 'csspool/terms/rgb'
7
7
  require 'csspool/terms/hash'
8
+ require 'csspool/terms/math'
@@ -10,7 +10,7 @@ module CSSPool
10
10
  end
11
11
 
12
12
  visitor_for CSS::ImportRule do |target|
13
- target.media
13
+ target.media_list
14
14
  end
15
15
 
16
16
  visitor_for CSS::Media,
@@ -27,7 +27,7 @@ module CSSPool
27
27
  end
28
28
 
29
29
  visitor_for CSS::ImportRule do |target|
30
- [:uri, :namespace, :media].all? { |m|
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, Selectors::Id, Selectors::Class do |target|
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
 
@@ -26,7 +26,7 @@ module CSSPool
26
26
  end
27
27
 
28
28
  visitor_for CSS::ImportRule do |target|
29
- target.media.each do |node|
29
+ target.media_list.each do |node|
30
30
  node.accept self
31
31
  end
32
32
  @block.call target
@@ -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.name.value
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.media.map do |medium|
61
- escape_css_identifier medium.name.value
62
- end.join(', ') if target.media.length > 0
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 = target.name == '*' ? '*' : escape_css_identifier(target.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
@@ -13,7 +13,7 @@ require 'csspool/visitors'
13
13
  require 'csspool/collection'
14
14
 
15
15
  module CSSPool
16
- VERSION = "3.0.2"
16
+ VERSION = "4.0.0"
17
17
 
18
18
  def self.CSS doc
19
19
  CSSPool::CSS::Document.parse doc
@@ -0,0 +1,2 @@
1
+ gem "minitest"
2
+ require "minitest/autorun"
@@ -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
@@ -33,7 +33,7 @@ module CSSPool
33
33
  "div { background: red; }"
34
34
  end
35
35
  new_doc.rule_sets.each do |rs|
36
- assert_equal ir.media, rs.media
36
+ assert_equal ir.media_list, rs.media.media_list
37
37
  end
38
38
  end
39
39
  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
@@ -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.foo[a] { }'
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
@@ -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
@@ -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