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.
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