csspool 2.0.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. data/.gemtest +0 -0
  2. data/CHANGELOG.rdoc +6 -0
  3. data/Manifest.txt +10 -14
  4. data/README.rdoc +8 -21
  5. data/Rakefile +36 -2
  6. data/lib/csspool/collection.rb +2 -2
  7. data/lib/csspool/css/charset.rb +8 -2
  8. data/lib/csspool/css/declaration.rb +13 -2
  9. data/lib/csspool/css/document_handler.rb +3 -3
  10. data/lib/csspool/css/import_rule.rb +15 -3
  11. data/lib/csspool/css/media.rb +8 -2
  12. data/lib/csspool/css/parser.rb +1090 -0
  13. data/lib/csspool/css/parser.y +347 -0
  14. data/lib/csspool/css/rule_set.rb +8 -3
  15. data/lib/csspool/css/tokenizer.rb +228 -0
  16. data/lib/csspool/css/tokenizer.rex +96 -0
  17. data/lib/csspool/css.rb +1 -0
  18. data/lib/csspool/node.rb +29 -1
  19. data/lib/csspool/sac/document.rb +3 -3
  20. data/lib/csspool/sac/parser.rb +6 -112
  21. data/lib/csspool/terms/function.rb +1 -1
  22. data/lib/csspool/terms/ident.rb +1 -1
  23. data/lib/csspool/terms/number.rb +1 -1
  24. data/lib/csspool/terms/rgb.rb +1 -4
  25. data/lib/csspool/terms/string.rb +1 -1
  26. data/lib/csspool/visitors/children.rb +50 -0
  27. data/lib/csspool/visitors/comparable.rb +9 -3
  28. data/lib/csspool/visitors/iterator.rb +80 -0
  29. data/lib/csspool/visitors/to_css.rb +61 -45
  30. data/lib/csspool/visitors.rb +2 -0
  31. data/lib/csspool.rb +6 -3
  32. data/test/css/test_parser.rb +412 -0
  33. data/test/css/test_tokenizer.rb +320 -0
  34. data/test/helper.rb +2 -2
  35. data/test/sac/test_parser.rb +3 -8
  36. data/test/sac/test_terms.rb +128 -34
  37. data/test/test_collection.rb +1 -1
  38. data/test/test_parser.rb +1 -1
  39. data/test/visitors/test_children.rb +20 -0
  40. data/test/visitors/test_comparable.rb +31 -1
  41. data/test/visitors/test_each.rb +19 -0
  42. data/test/visitors/test_to_css.rb +125 -1
  43. metadata +90 -68
  44. data/lib/csspool/lib_croco/cr_additional_sel.rb +0 -46
  45. data/lib/csspool/lib_croco/cr_attr_sel.rb +0 -16
  46. data/lib/csspool/lib_croco/cr_doc_handler.rb +0 -24
  47. data/lib/csspool/lib_croco/cr_num.rb +0 -13
  48. data/lib/csspool/lib_croco/cr_parser.rb +0 -11
  49. data/lib/csspool/lib_croco/cr_parsing_location.rb +0 -17
  50. data/lib/csspool/lib_croco/cr_pseudo.rb +0 -14
  51. data/lib/csspool/lib_croco/cr_rgb.rb +0 -18
  52. data/lib/csspool/lib_croco/cr_selector.rb +0 -34
  53. data/lib/csspool/lib_croco/cr_simple_sel.rb +0 -54
  54. data/lib/csspool/lib_croco/cr_term.rb +0 -97
  55. data/lib/csspool/lib_croco/glist.rb +0 -21
  56. data/lib/csspool/lib_croco.rb +0 -78
  57. data/lib/csspool/visitable.rb +0 -18
data/lib/csspool/node.rb CHANGED
@@ -1,5 +1,33 @@
1
1
  module CSSPool
2
2
  class Node
3
- include CSSPool::Visitable
3
+ include Enumerable
4
+
5
+ def accept target
6
+ target.accept self
7
+ end
8
+
9
+ def to_css
10
+ accept Visitors::ToCSS.new
11
+ end
12
+ alias :to_s :to_css
13
+
14
+ def == other
15
+ return false unless self.class == other.class
16
+
17
+ accept Visitors::Comparable.new other
18
+ end
19
+ alias :eql? :==
20
+
21
+ def each &block
22
+ Visitors::Iterator.new(block).accept self
23
+ end
24
+
25
+ def children
26
+ accept Visitors::Children.new
27
+ end
28
+
29
+ def hash
30
+ @hash ||= children.map { |child| child.hash }.hash
31
+ end
4
32
  end
5
33
  end
@@ -10,7 +10,7 @@ module CSSPool
10
10
  def charset name, location
11
11
  end
12
12
 
13
- def import_style media_list, uri, default_ns, location
13
+ def import_style media_list, uri, default_ns = nil, location = {}
14
14
  end
15
15
 
16
16
  def start_selector selector_list
@@ -25,10 +25,10 @@ module CSSPool
25
25
  def comment comment
26
26
  end
27
27
 
28
- def start_media media_list, parse_location
28
+ def start_media media_list, parse_location = {}
29
29
  end
30
30
 
31
- def end_media media_list, parse_location
31
+ def end_media media_list, parse_location = {}
32
32
  end
33
33
  end
34
34
  end
@@ -1,121 +1,15 @@
1
1
  module CSSPool
2
2
  module SAC
3
- class Parser
4
- attr_accessor :document
3
+ class Parser < CSSPool::CSS::Tokenizer
4
+ attr_accessor :handler
5
5
 
6
- def initialize document = CSSPool::SAC::Document.new
7
- @document = document
8
- @selector_stack = []
6
+ def initialize handler = CSSPool::CSS::DocumentHandler.new
7
+ @handler = handler
9
8
  end
10
9
 
11
10
  def parse string
12
- parse_memory(string, 5)
13
- end
14
-
15
- private
16
- def push selectors
17
- @selector_stack << selectors
18
- end
19
-
20
- def pop
21
- @selector_stack.pop
22
- end
23
-
24
- def parse_memory string, encoding
25
- parser = LibCroco::CRParser.new(
26
- LibCroco.cr_parser_new_from_buf(
27
- string,
28
- string.length,
29
- 5,
30
- 0
31
- )
32
- )
33
- sac_handler =
34
- LibCroco::CRDocHandler.new(LibCroco.cr_doc_handler_new)
35
-
36
- selector_stack = []
37
- media_stack = []
38
-
39
- sac_handler[:start_document] = lambda { |parser|
40
- @document.start_document
41
- }
42
- sac_handler[:end_document] = lambda { |parser|
43
- @document.end_document
44
- }
45
- sac_handler[:charset] = lambda { |dh, name, location|
46
- @document.charset(
47
- LibCroco.cr_string_peek_raw_str(name).read_string,
48
- LibCroco::CRParsingLocation.new(location).to_h
49
- )
50
- }
51
-
52
- sac_handler[:import_style] = lambda { |dh, media_list, uri, ns, loc|
53
- media_list = media_list.null? ? [] : LibCroco::GList.new(media_list)
54
- media_list = media_list.to_a.map { |data|
55
- LibCroco.cr_string_peek_raw_str(data).read_string
56
- }
57
- uri = uri.null? ? nil :
58
- LibCroco.cr_string_peek_raw_str(uri).read_string
59
-
60
- ns = ns.null? ? nil : LibCroco.cr_string_peek_raw_str(ns).read_string
61
-
62
- @document.import_style(
63
- media_list,
64
- uri,
65
- ns,
66
- LibCroco::CRParsingLocation.new(loc).to_h
67
- )
68
- }
69
-
70
- sac_handler[:start_selector] = lambda { |dh, list|
71
- list = [LibCroco::CRSelector.new(list)]
72
- pointer = list.last[:next]
73
- until pointer.null?
74
- list << LibCroco::CRSelector.new(pointer)
75
- pointer = list.last[:next]
76
- end
77
- selector_stack.push list.map { |l| l.to_selector }
78
- @document.start_selector selector_stack.last
79
- }
80
-
81
- sac_handler[:end_selector] = lambda { |dh, list|
82
- @document.end_selector selector_stack.pop
83
- }
84
-
85
- sac_handler[:property] = lambda { |dh, name, expr, important|
86
- expr_list = []
87
- until expr.null?
88
- expr_list << LibCroco::CRTerm.new(expr)
89
- expr = expr_list.last[:next]
90
- end
91
- @document.property(
92
- LibCroco.cr_string_peek_raw_str(name).read_string,
93
- expr_list.map { |ex| ex.to_term },
94
- important == 1
95
- )
96
- }
97
-
98
- sac_handler[:comment] = lambda { |dh, comment|
99
- @document.comment(
100
- LibCroco.cr_string_peek_raw_str(comment).read_string
101
- )
102
- }
103
-
104
- sac_handler[:start_media] = lambda { |dh,media_list,location|
105
- media_list = LibCroco::GList.new(media_list)
106
- media_stack << [media_list.to_a.map { |data|
107
- LibCroco.cr_string_peek_raw_str(data).read_string
108
- }, LibCroco::CRParsingLocation.new(location).to_h]
109
- @document.start_media(*media_stack.last)
110
- }
111
-
112
- sac_handler[:end_media] = lambda { |dh,media_list|
113
- @document.end_media(*media_stack.pop)
114
- }
115
-
116
- LibCroco.cr_parser_set_sac_handler(parser, sac_handler)
117
- LibCroco.cr_parser_parse(parser)
118
- LibCroco.cr_doc_handler_destroy(sac_handler)
11
+ scan_str string
12
+ @handler.document
119
13
  end
120
14
  end
121
15
  end
@@ -6,7 +6,7 @@ module CSSPool
6
6
  attr_accessor :parse_location
7
7
  attr_accessor :operator
8
8
 
9
- def initialize name, params, operator, parse_location
9
+ def initialize name, params, operator = nil, parse_location = nil
10
10
  @name = name
11
11
  @params = params
12
12
  @operator = operator
@@ -5,7 +5,7 @@ module CSSPool
5
5
  attr_accessor :operator
6
6
  attr_accessor :parse_location
7
7
 
8
- def initialize value, operator, parse_location
8
+ def initialize value, operator = nil, parse_location = {}
9
9
  @value = value
10
10
  @operator = operator
11
11
  @parse_location = parse_location
@@ -4,7 +4,7 @@ module CSSPool
4
4
  attr_accessor :type
5
5
  attr_accessor :unary_operator
6
6
 
7
- def initialize type, unary_operator, value, operator, parse_location
7
+ def initialize value, unary_operator = nil, type = nil, operator = nil, parse_location = {}
8
8
  @type = type
9
9
  @unary_operator = unary_operator
10
10
  super(value, operator, parse_location)
@@ -4,17 +4,14 @@ module CSSPool
4
4
  attr_accessor :red
5
5
  attr_accessor :green
6
6
  attr_accessor :blue
7
- attr_accessor :percentage
8
7
  attr_accessor :parse_location
9
8
  attr_accessor :operator
10
- alias :percentage? :percentage
11
9
 
12
- def initialize red, green, blue, percentage, operator, parse_location
10
+ def initialize red, green, blue, operator = nil, parse_location = {}
13
11
  super()
14
12
  @red = red
15
13
  @green = green
16
14
  @blue = blue
17
- @percentage = percentage
18
15
  @operator = operator
19
16
  @parse_location = parse_location
20
17
  end
@@ -1,6 +1,6 @@
1
1
  module CSSPool
2
2
  module Terms
3
- class String < Ident
3
+ class String < CSSPool::Terms::Ident
4
4
  end
5
5
  end
6
6
  end
@@ -0,0 +1,50 @@
1
+ module CSSPool
2
+ module Visitors
3
+ class Children < Visitor
4
+ visitor_for CSS::Document do |target|
5
+ children = []
6
+ [:charsets, :import_rules, :rule_sets].each do |member|
7
+ children += target.send(member)
8
+ end
9
+ children
10
+ end
11
+
12
+ visitor_for CSS::ImportRule do |target|
13
+ target.media
14
+ end
15
+
16
+ visitor_for CSS::Media,
17
+ CSS::Charset,
18
+ Selectors::Id,
19
+ Selectors::Class,
20
+ Selectors::PseudoClass,
21
+ Selectors::Attribute,
22
+ Terms::Ident,
23
+ Terms::String,
24
+ Terms::URI,
25
+ Terms::Number,
26
+ Terms::Hash,
27
+ Terms::Function,
28
+ Terms::Rgb do |target|
29
+ []
30
+ end
31
+
32
+ visitor_for CSS::Declaration do |target|
33
+ target.expressions
34
+ end
35
+
36
+ visitor_for CSS::RuleSet do |target|
37
+ target.selectors + target.declarations
38
+ end
39
+
40
+ visitor_for Selector do |target|
41
+ target.simple_selectors
42
+ end
43
+
44
+ visitor_for Selectors::Type, Selectors::Universal, Selectors::Simple do |target|
45
+ target.additional_selectors
46
+ end
47
+ end
48
+ end
49
+ end
50
+
@@ -32,11 +32,18 @@ module CSSPool
32
32
  }
33
33
  end
34
34
 
35
- visitor_for CSS::Media do |target|
35
+ visitor_for Selectors::PseudoClass do |target|
36
+ [:name, :extra].all? { |m|
37
+ target.send(m) == @other.send(m)
38
+ }
39
+ end
40
+
41
+ visitor_for CSS::Media, Selectors::Id, Selectors::Class do |target|
36
42
  target.name == @other.name
37
43
  end
38
44
 
39
- visitor_for Selectors::Type do |target|
45
+ visitor_for Selectors::Type, Selectors::Universal,
46
+ Selectors::Simple do |target|
40
47
  [:name, :combinator, :additional_selectors].all? { |m|
41
48
  target.send(m) == @other.send(m)
42
49
  }
@@ -69,7 +76,6 @@ module CSSPool
69
76
  :red,
70
77
  :green,
71
78
  :blue,
72
- :percentage,
73
79
  :operator
74
80
  ].all? { |m| target.send(m) == @other.send(m) }
75
81
  end
@@ -0,0 +1,80 @@
1
+ module CSSPool
2
+ module Visitors
3
+ class Iterator < Visitor
4
+ def initialize block
5
+ @block = block
6
+ end
7
+
8
+ visitor_for CSS::Document do |target|
9
+ [:charsets, :import_rules, :rule_sets].each do |member|
10
+ target.send(member).each do |node|
11
+ node.accept self
12
+ end
13
+ end
14
+ @block.call target
15
+ end
16
+
17
+ visitor_for Selectors::Universal, Selectors::Simple do |target|
18
+ target.children.each do |node|
19
+ node.accept self
20
+ end
21
+ @block.call target
22
+ end
23
+
24
+ visitor_for CSS::Charset do |target|
25
+ @block.call target
26
+ end
27
+
28
+ visitor_for CSS::ImportRule do |target|
29
+ target.media.each do |node|
30
+ node.accept self
31
+ end
32
+ @block.call target
33
+ end
34
+
35
+ visitor_for CSS::Media,
36
+ Selectors::Id,
37
+ Selectors::Class,
38
+ Selectors::PseudoClass,
39
+ Selectors::Attribute,
40
+ Terms::Ident,
41
+ Terms::String,
42
+ Terms::URI,
43
+ Terms::Number,
44
+ Terms::Hash,
45
+ Terms::Function,
46
+ Terms::Rgb do |target|
47
+ @block.call target
48
+ end
49
+
50
+ visitor_for CSS::Declaration do |target|
51
+ target.expressions.each do |node|
52
+ node.accept self
53
+ end
54
+ @block.call target
55
+ end
56
+
57
+ visitor_for CSS::RuleSet do |target|
58
+ target.selectors.each do |node|
59
+ node.accept self
60
+ end
61
+ target.declarations.each do |node|
62
+ node.accept self
63
+ end
64
+ @block.call target
65
+ end
66
+
67
+ visitor_for Selector do |target|
68
+ target.simple_selectors.each { |ss| ss.accept self }
69
+ @block.call target
70
+ end
71
+
72
+ visitor_for Selectors::Type do |target|
73
+ target.additional_selectors.each do |node|
74
+ node.accept self
75
+ end
76
+ @block.call target
77
+ end
78
+ end
79
+ end
80
+ end
@@ -1,14 +1,23 @@
1
1
  module CSSPool
2
2
  module Visitors
3
3
  class ToCSS < Visitor
4
+
5
+ CSS_IDENTIFIER_ILLEGAL_CHARACTERS =
6
+ (0..255).to_a.pack('U*').gsub(/[a-zA-Z0-9_-]/, '')
7
+ CSS_STRING_ESCAPE_MAP = {
8
+ "\\" => "\\\\",
9
+ "\"" => "\\\"",
10
+ "\n" => "\\a ", # CSS2 4.1.3 p3.2
11
+ "\r" => "\\\r",
12
+ "\f" => "\\\f"
13
+ }
14
+
4
15
  def initialize
5
16
  @indent_level = 0
6
17
  @indent_space = ' '
7
18
  end
8
19
 
9
20
  visitor_for CSS::Document do |target|
10
- media_hash = {}
11
-
12
21
  # Default media list is []
13
22
  current_media_type = []
14
23
 
@@ -24,7 +33,10 @@ module CSSPool
24
33
 
25
34
  target.rule_sets.each { |rs|
26
35
  if rs.media != current_media_type
27
- tokens << "#{indent}@media #{rs.media.map { |x| x.name }.join(", ")} {"
36
+ media = " " + rs.media.map do |medium|
37
+ escape_css_identifier medium.name.value
38
+ end.join(', ')
39
+ tokens << "#{indent}@media#{media} {"
28
40
  @indent_level += 1
29
41
  end
30
42
 
@@ -40,16 +52,16 @@ module CSSPool
40
52
  end
41
53
 
42
54
  visitor_for CSS::Charset do |target|
43
- "@charset \"#{target.name}\";"
55
+ "@charset \"#{escape_css_string target.name}\";"
44
56
  end
45
57
 
46
58
  visitor_for CSS::ImportRule do |target|
47
59
  media = ''
48
- media = " " + target.media.map { |x|
49
- x.name
50
- }.join(', ') if target.media.length > 0
60
+ media = " " + target.media.map do |medium|
61
+ escape_css_identifier medium.name.value
62
+ end.join(', ') if target.media.length > 0
51
63
 
52
- "#{indent}@import url(\"#{target.uri}\")#{media};"
64
+ "#{indent}@import #{target.uri.accept(self)}#{media};"
53
65
  end
54
66
 
55
67
  visitor_for CSS::RuleSet do |target|
@@ -63,7 +75,7 @@ module CSSPool
63
75
  important = target.important? ? ' !important' : ''
64
76
 
65
77
  indent {
66
- "#{indent}#{target.property}: " + target.expressions.map { |exp|
78
+ "#{indent}#{escape_css_identifier target.property}: " + target.expressions.map { |exp|
67
79
 
68
80
  op = '/' == exp.operator ? ' /' : exp.operator
69
81
 
@@ -76,7 +88,7 @@ module CSSPool
76
88
  end
77
89
 
78
90
  visitor_for Terms::Ident do |target|
79
- target.value
91
+ escape_css_identifier target.value
80
92
  end
81
93
 
82
94
  visitor_for Terms::Hash do |target|
@@ -90,11 +102,11 @@ module CSSPool
90
102
  end
91
103
 
92
104
  visitor_for Terms::URI do |target|
93
- "url(#{target.value})"
105
+ "url(\"#{escape_css_string target.value}\")"
94
106
  end
95
107
 
96
108
  visitor_for Terms::Function do |target|
97
- "#{target.name}(" +
109
+ "#{escape_css_identifier target.name}(" +
98
110
  target.params.map { |x|
99
111
  [
100
112
  x.operator,
@@ -108,13 +120,15 @@ module CSSPool
108
120
  target.red,
109
121
  target.green,
110
122
  target.blue
111
- ].map { |c| target.percentage? ? "#{c}%" : c }.join(',')
123
+ ].map { |c|
124
+ c.accept(self)
125
+ }.join ', '
112
126
 
113
127
  %{rgb(#{params})}
114
128
  end
115
129
 
116
130
  visitor_for Terms::String do |target|
117
- "\"#{target.value}\""
131
+ "\"#{escape_css_string target.value}\""
118
132
  end
119
133
 
120
134
  visitor_for Selector do |target|
@@ -123,64 +137,50 @@ module CSSPool
123
137
 
124
138
  visitor_for Selectors::Type do |target|
125
139
  combo = {
126
- 0 => nil,
127
- 1 => ' ',
128
- 2 => ' + ',
129
- 3 => ' > '
140
+ :s => ' ',
141
+ :+ => ' + ',
142
+ :> => ' > '
130
143
  }[target.combinator]
131
144
 
132
- [combo, target.name].compact.join +
145
+ name = target.name == '*' ? '*' : escape_css_identifier(target.name)
146
+ [combo, name].compact.join +
133
147
  target.additional_selectors.map { |as| as.accept self }.join
134
148
  end
135
149
 
136
150
  visitor_for Terms::Number do |target|
137
- units = {
138
- 2 => 'em',
139
- 3 => 'ex',
140
- 4 => 'px',
141
- 5 => 'in',
142
- 6 => 'cm',
143
- 7 => 'mm',
144
- 8 => 'pt',
145
- 9 => 'pc',
146
- 10 => 'deg',
147
- 11 => 'rad',
148
- 12 => 'grad',
149
- 13 => 'ms',
150
- 14 => 's',
151
- 15 => 'Hz',
152
- 16 => 'kHz',
153
- 17 => '%',
154
- }[target.type]
155
151
  [
156
152
  target.unary_operator == :minus ? '-' : nil,
157
153
  target.value,
158
- units
154
+ target.type
159
155
  ].compact.join
160
156
  end
161
157
 
162
158
  visitor_for Selectors::Id do |target|
163
- "##{target.name}"
159
+ "##{escape_css_identifier target.name}"
164
160
  end
165
161
 
166
162
  visitor_for Selectors::Class do |target|
167
- ".#{target.name}"
163
+ ".#{escape_css_identifier target.name}"
168
164
  end
169
165
 
170
166
  visitor_for Selectors::PseudoClass do |target|
171
- ":#{target.name}"
167
+ if target.extra.nil?
168
+ ":#{escape_css_identifier target.name}"
169
+ else
170
+ ":#{escape_css_identifier target.name}(#{escape_css_identifier target.extra})"
171
+ end
172
172
  end
173
173
 
174
174
  visitor_for Selectors::Attribute do |target|
175
175
  case target.match_way
176
176
  when Selectors::Attribute::SET
177
- "[#{target.name}]"
177
+ "[#{escape_css_identifier target.name}]"
178
178
  when Selectors::Attribute::EQUALS
179
- "[#{target.name}=\"#{target.value}\"]"
179
+ "[#{escape_css_identifier target.name}=\"#{escape_css_string target.value}\"]"
180
180
  when Selectors::Attribute::INCLUDES
181
- "[#{target.name} ~= \"#{target.value}\"]"
181
+ "[#{escape_css_identifier target.name} ~= \"#{escape_css_string target.value}\"]"
182
182
  when Selectors::Attribute::DASHMATCH
183
- "[#{target.name} |= \"#{target.value}\"]"
183
+ "[#{escape_css_identifier target.name} |= \"#{escape_css_string target.value}\"]"
184
184
  else
185
185
  raise "no matching matchway"
186
186
  end
@@ -196,6 +196,22 @@ module CSSPool
196
196
  end
197
197
  "#{@indent_space * @indent_level}"
198
198
  end
199
+
200
+ def escape_css_identifier text
201
+ # CSS2 4.1.3 p2
202
+ unsafe_chars = /[#{Regexp.escape CSS_IDENTIFIER_ILLEGAL_CHARACTERS}]/
203
+ text.gsub(/^\d|^\-(?=\-|\d)|#{unsafe_chars}/um) do |char|
204
+ if ':()-\\ ='.include? char
205
+ "\\#{char}"
206
+ else # I don't trust others to handle space termination well.
207
+ "\\#{char.unpack('U').first.to_s(16).rjust(6, '0')}"
208
+ end
209
+ end
210
+ end
211
+
212
+ def escape_css_string text
213
+ text.gsub(/[\\"\n\r\f]/) {CSS_STRING_ESCAPE_MAP[$&]}
214
+ end
199
215
  end
200
216
  end
201
217
  end
@@ -1,3 +1,5 @@
1
1
  require 'csspool/visitors/visitor'
2
2
  require 'csspool/visitors/to_css'
3
3
  require 'csspool/visitors/comparable'
4
+ require 'csspool/visitors/iterator'
5
+ require 'csspool/visitors/children'
data/lib/csspool.rb CHANGED
@@ -1,16 +1,19 @@
1
- require 'csspool/visitable'
2
1
  require 'csspool/node'
3
2
  require 'csspool/selectors'
4
3
  require 'csspool/terms'
5
4
  require 'csspool/selector'
5
+ old = $-w
6
+ $-w = false
7
+ require 'csspool/css/parser'
8
+ $-w = old
9
+ require 'csspool/css/tokenizer'
6
10
  require 'csspool/sac'
7
- require 'csspool/lib_croco'
8
11
  require 'csspool/css'
9
12
  require 'csspool/visitors'
10
13
  require 'csspool/collection'
11
14
 
12
15
  module CSSPool
13
- VERSION = "2.0.0"
16
+ VERSION = "3.0.0"
14
17
 
15
18
  def self.CSS doc
16
19
  CSSPool::CSS::Document.parse doc