csspool 0.2.6 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.autotest +16 -0
- data/{CHANGELOG.txt → CHANGELOG.rdoc} +10 -0
- data/Manifest.txt +60 -72
- data/README.rdoc +78 -0
- data/Rakefile +9 -52
- data/lib/csspool/collection.rb +50 -0
- data/lib/csspool/css/charset.rb +7 -0
- data/lib/csspool/css/declaration.rb +8 -0
- data/lib/csspool/css/document.rb +34 -0
- data/lib/csspool/css/document_handler.rb +51 -0
- data/lib/csspool/css/import_rule.rb +15 -0
- data/lib/csspool/css/media.rb +7 -0
- data/lib/csspool/css/rule_set.rb +12 -0
- data/lib/csspool/css.rb +7 -0
- data/lib/csspool/lib_croco/cr_additional_sel.rb +46 -0
- data/lib/csspool/lib_croco/cr_attr_sel.rb +16 -0
- data/lib/csspool/lib_croco/cr_doc_handler.rb +24 -0
- data/lib/csspool/lib_croco/cr_num.rb +13 -0
- data/lib/csspool/lib_croco/cr_parser.rb +11 -0
- data/lib/csspool/lib_croco/cr_parsing_location.rb +17 -0
- data/lib/csspool/lib_croco/cr_pseudo.rb +14 -0
- data/lib/csspool/lib_croco/cr_rgb.rb +18 -0
- data/lib/csspool/lib_croco/cr_selector.rb +34 -0
- data/lib/csspool/lib_croco/cr_simple_sel.rb +54 -0
- data/lib/csspool/lib_croco/cr_term.rb +97 -0
- data/lib/csspool/lib_croco/glist.rb +21 -0
- data/lib/csspool/lib_croco.rb +78 -0
- data/lib/csspool/node.rb +5 -0
- data/lib/csspool/sac/document.rb +35 -0
- data/lib/csspool/sac/parser.rb +122 -0
- data/lib/csspool/sac.rb +2 -0
- data/lib/csspool/selector.rb +32 -0
- data/lib/csspool/selectors/additional.rb +6 -0
- data/lib/csspool/selectors/attribute.rb +21 -0
- data/lib/csspool/selectors/class.rb +11 -0
- data/lib/csspool/selectors/id.rb +11 -0
- data/lib/csspool/selectors/pseudo_class.rb +13 -0
- data/lib/csspool/selectors/simple.rb +22 -0
- data/lib/csspool/selectors/type.rb +6 -0
- data/lib/csspool/selectors/universal.rb +6 -0
- data/lib/csspool/selectors.rb +8 -0
- data/lib/csspool/terms/function.rb +17 -0
- data/lib/csspool/terms/hash.rb +6 -0
- data/lib/csspool/terms/ident.rb +15 -0
- data/lib/csspool/terms/number.rb +14 -0
- data/lib/csspool/terms/rgb.rb +23 -0
- data/lib/csspool/terms/string.rb +6 -0
- data/lib/csspool/terms/uri.rb +6 -0
- data/lib/csspool/terms.rb +7 -0
- data/lib/csspool/visitable.rb +18 -0
- data/lib/csspool/visitors/comparable.rb +78 -0
- data/lib/csspool/visitors/to_css.rb +201 -0
- data/lib/csspool/visitors/visitor.rb +17 -0
- data/lib/csspool/visitors.rb +3 -0
- data/lib/csspool.rb +18 -1
- data/test/css/test_document.rb +13 -0
- data/test/css/test_import_rule.rb +42 -0
- data/test/helper.rb +62 -6
- data/test/sac/test_parser.rb +115 -0
- data/test/sac/test_properties.rb +43 -0
- data/test/sac/test_terms.rb +134 -0
- data/test/test_collection.rb +81 -0
- data/test/test_parser.rb +75 -241
- data/test/test_selector.rb +45 -34
- data/test/visitors/test_comparable.rb +72 -0
- data/test/visitors/test_to_css.rb +141 -0
- metadata +98 -85
- data/README.txt +0 -79
- data/lib/css/sac/conditions/attribute_condition.rb +0 -56
- data/lib/css/sac/conditions/begin_hyphen_condition.rb +0 -22
- data/lib/css/sac/conditions/class_condition.rb +0 -22
- data/lib/css/sac/conditions/combinator_condition.rb +0 -40
- data/lib/css/sac/conditions/condition.rb +0 -35
- data/lib/css/sac/conditions/id_condition.rb +0 -27
- data/lib/css/sac/conditions/one_of_condition.rb +0 -22
- data/lib/css/sac/conditions/pseudo_class_condition.rb +0 -24
- data/lib/css/sac/conditions.rb +0 -5
- data/lib/css/sac/document_handler.rb +0 -67
- data/lib/css/sac/error_handler.rb +0 -14
- data/lib/css/sac/generated_parser.rb +0 -999
- data/lib/css/sac/generated_property_parser.rb +0 -9214
- data/lib/css/sac/lexeme.rb +0 -29
- data/lib/css/sac/lexical_unit.rb +0 -203
- data/lib/css/sac/parse_exception.rb +0 -6
- data/lib/css/sac/parser.rb +0 -115
- data/lib/css/sac/property_parser.rb +0 -47
- data/lib/css/sac/selectors/child_selector.rb +0 -40
- data/lib/css/sac/selectors/conditional_selector.rb +0 -49
- data/lib/css/sac/selectors/descendant_selector.rb +0 -40
- data/lib/css/sac/selectors/element_selector.rb +0 -39
- data/lib/css/sac/selectors/selector.rb +0 -31
- data/lib/css/sac/selectors/sibling_selector.rb +0 -39
- data/lib/css/sac/selectors/simple_selector.rb +0 -25
- data/lib/css/sac/selectors.rb +0 -5
- data/lib/css/sac/token.rb +0 -27
- data/lib/css/sac/tokenizer.rb +0 -187
- data/lib/css/sac/visitable.rb +0 -106
- data/lib/css/sac.rb +0 -14
- data/lib/css/stylesheet/rule.rb +0 -20
- data/lib/css/stylesheet/stylesheet.rb +0 -96
- data/lib/css/stylesheet.rb +0 -3
- data/lib/parser.y +0 -308
- data/lib/property_parser.y +0 -2346
- data/lib/property_parser.y.erb +0 -1321
- data/test/condition_test_case.rb +0 -6
- data/test/selector_test_case.rb +0 -20
- data/test/test_all.rb +0 -4
- data/test/test_attribute_condition.rb +0 -39
- data/test/test_begin_hyphen_condition.rb +0 -15
- data/test/test_child_selector.rb +0 -60
- data/test/test_class_condition.rb +0 -15
- data/test/test_combinator_condition.rb +0 -38
- data/test/test_condition.rb +0 -31
- data/test/test_conditional_selector.rb +0 -44
- data/test/test_descendant_selector.rb +0 -64
- data/test/test_element_selector.rb +0 -31
- data/test/test_error_recovery.rb +0 -28
- data/test/test_id_condition.rb +0 -16
- data/test/test_lexeme.rb +0 -39
- data/test/test_lexical_color.rb +0 -49
- data/test/test_lexical_function.rb +0 -31
- data/test/test_lexical_ident.rb +0 -30
- data/test/test_lexical_number.rb +0 -68
- data/test/test_lexical_string.rb +0 -23
- data/test/test_lexical_unit.rb +0 -106
- data/test/test_lexical_uri.rb +0 -28
- data/test/test_one_of_condition.rb +0 -15
- data/test/test_parse_error.rb +0 -199
- data/test/test_property_parser.rb +0 -593
- data/test/test_selector_as_string.rb +0 -94
- data/test/test_selector_parser.rb +0 -178
- data/test/test_sibling_selector.rb +0 -42
- data/test/test_simple_selector.rb +0 -9
- data/test/test_specificity.rb +0 -76
- data/test/test_stylesheet.rb +0 -95
- data/test/test_token.rb +0 -24
- data/test/test_tokenizer.rb +0 -127
- data/test/test_xpath.rb +0 -105
@@ -0,0 +1,23 @@
|
|
1
|
+
module CSSPool
|
2
|
+
module Terms
|
3
|
+
class Rgb < CSSPool::Node
|
4
|
+
attr_accessor :red
|
5
|
+
attr_accessor :green
|
6
|
+
attr_accessor :blue
|
7
|
+
attr_accessor :percentage
|
8
|
+
attr_accessor :parse_location
|
9
|
+
attr_accessor :operator
|
10
|
+
alias :percentage? :percentage
|
11
|
+
|
12
|
+
def initialize red, green, blue, percentage, operator, parse_location
|
13
|
+
super()
|
14
|
+
@red = red
|
15
|
+
@green = green
|
16
|
+
@blue = blue
|
17
|
+
@percentage = percentage
|
18
|
+
@operator = operator
|
19
|
+
@parse_location = parse_location
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module CSSPool
|
2
|
+
module Visitable
|
3
|
+
def accept target
|
4
|
+
target.accept self
|
5
|
+
end
|
6
|
+
|
7
|
+
def to_css
|
8
|
+
accept Visitors::ToCSS.new
|
9
|
+
end
|
10
|
+
alias :to_s :to_css
|
11
|
+
|
12
|
+
def == other
|
13
|
+
return false unless self.class == other.class
|
14
|
+
|
15
|
+
accept Visitors::Comparable.new other
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module CSSPool
|
2
|
+
module Visitors
|
3
|
+
class Comparable < Visitor
|
4
|
+
def initialize other
|
5
|
+
super()
|
6
|
+
@other = other
|
7
|
+
end
|
8
|
+
|
9
|
+
visitor_for CSS::Document do |target|
|
10
|
+
[
|
11
|
+
:parent,
|
12
|
+
:charsets,
|
13
|
+
:parent_import_rule,
|
14
|
+
:import_rules,
|
15
|
+
:rule_sets,
|
16
|
+
].all? { |m| target.send(m) == @other.send(m) }
|
17
|
+
end
|
18
|
+
|
19
|
+
visitor_for CSS::RuleSet do |target|
|
20
|
+
[:selectors, :declarations, :media].all? { |m|
|
21
|
+
target.send(m) == @other.send(m)
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
visitor_for Selector do |target|
|
26
|
+
target.simple_selectors == @other.simple_selectors
|
27
|
+
end
|
28
|
+
|
29
|
+
visitor_for CSS::ImportRule do |target|
|
30
|
+
[:uri, :namespace, :media].all? { |m|
|
31
|
+
target.send(m) == @other.send(m)
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
visitor_for CSS::Media do |target|
|
36
|
+
target.name == @other.name
|
37
|
+
end
|
38
|
+
|
39
|
+
visitor_for Selectors::Type do |target|
|
40
|
+
[:name, :combinator, :additional_selectors].all? { |m|
|
41
|
+
target.send(m) == @other.send(m)
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
visitor_for CSS::Declaration do |target|
|
46
|
+
[:property, :expressions, :important].all? { |m|
|
47
|
+
target.send(m) == @other.send(m)
|
48
|
+
}
|
49
|
+
end
|
50
|
+
|
51
|
+
visitor_for Terms::Function do |target|
|
52
|
+
[:name, :params, :operator].all? { |m|
|
53
|
+
target.send(m) == @other.send(m)
|
54
|
+
}
|
55
|
+
end
|
56
|
+
|
57
|
+
visitor_for Terms::Number do |target|
|
58
|
+
[:type, :unary_operator, :value, :operator].all? { |m|
|
59
|
+
target.send(m) == @other.send(m)
|
60
|
+
}
|
61
|
+
end
|
62
|
+
|
63
|
+
visitor_for Terms::URI,Terms::String,Terms::Ident,Terms::Hash do |target|
|
64
|
+
[:value, :operator].all? { |m| target.send(m) == @other.send(m) }
|
65
|
+
end
|
66
|
+
|
67
|
+
visitor_for Terms::Rgb do |target|
|
68
|
+
[
|
69
|
+
:red,
|
70
|
+
:green,
|
71
|
+
:blue,
|
72
|
+
:percentage,
|
73
|
+
:operator
|
74
|
+
].all? { |m| target.send(m) == @other.send(m) }
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,201 @@
|
|
1
|
+
module CSSPool
|
2
|
+
module Visitors
|
3
|
+
class ToCSS < Visitor
|
4
|
+
def initialize
|
5
|
+
@indent_level = 0
|
6
|
+
@indent_space = ' '
|
7
|
+
end
|
8
|
+
|
9
|
+
visitor_for CSS::Document do |target|
|
10
|
+
media_hash = {}
|
11
|
+
|
12
|
+
# Default media list is []
|
13
|
+
current_media_type = []
|
14
|
+
|
15
|
+
tokens = []
|
16
|
+
|
17
|
+
target.charsets.each do |char_set|
|
18
|
+
tokens << char_set.accept(self)
|
19
|
+
end
|
20
|
+
|
21
|
+
target.import_rules.each do |ir|
|
22
|
+
tokens << ir.accept(self)
|
23
|
+
end
|
24
|
+
|
25
|
+
target.rule_sets.each { |rs|
|
26
|
+
if rs.media != current_media_type
|
27
|
+
tokens << "#{indent}@media #{rs.media.map { |x| x.name }.join(", ")} {"
|
28
|
+
@indent_level += 1
|
29
|
+
end
|
30
|
+
|
31
|
+
tokens << rs.accept(self)
|
32
|
+
|
33
|
+
if rs.media != current_media_type
|
34
|
+
current_media_type = rs.media
|
35
|
+
@indent_level -= 1
|
36
|
+
tokens << "#{indent}}"
|
37
|
+
end
|
38
|
+
}
|
39
|
+
tokens.join("\n")
|
40
|
+
end
|
41
|
+
|
42
|
+
visitor_for CSS::Charset do |target|
|
43
|
+
"@charset \"#{target.name}\";"
|
44
|
+
end
|
45
|
+
|
46
|
+
visitor_for CSS::ImportRule do |target|
|
47
|
+
media = ''
|
48
|
+
media = " " + target.media.map { |x|
|
49
|
+
x.name
|
50
|
+
}.join(', ') if target.media.length > 0
|
51
|
+
|
52
|
+
"#{indent}@import url(\"#{target.uri}\")#{media};"
|
53
|
+
end
|
54
|
+
|
55
|
+
visitor_for CSS::RuleSet do |target|
|
56
|
+
"#{indent}" +
|
57
|
+
target.selectors.map { |sel| sel.accept self }.join(", ") + " {\n" +
|
58
|
+
target.declarations.map { |decl| decl.accept self }.join("\n") +
|
59
|
+
"\n#{indent}}"
|
60
|
+
end
|
61
|
+
|
62
|
+
visitor_for CSS::Declaration do |target|
|
63
|
+
important = target.important? ? ' !important' : ''
|
64
|
+
|
65
|
+
indent {
|
66
|
+
"#{indent}#{target.property}: " + target.expressions.map { |exp|
|
67
|
+
|
68
|
+
op = '/' == exp.operator ? ' /' : exp.operator
|
69
|
+
|
70
|
+
[
|
71
|
+
op,
|
72
|
+
exp.accept(self),
|
73
|
+
].join ' '
|
74
|
+
}.join.strip + "#{important};"
|
75
|
+
}
|
76
|
+
end
|
77
|
+
|
78
|
+
visitor_for Terms::Ident do |target|
|
79
|
+
target.value
|
80
|
+
end
|
81
|
+
|
82
|
+
visitor_for Terms::Hash do |target|
|
83
|
+
"##{target.value}"
|
84
|
+
end
|
85
|
+
|
86
|
+
visitor_for Selectors::Simple, Selectors::Universal do |target|
|
87
|
+
([target.name] + target.additional_selectors.map { |x|
|
88
|
+
x.accept self
|
89
|
+
}).join
|
90
|
+
end
|
91
|
+
|
92
|
+
visitor_for Terms::URI do |target|
|
93
|
+
"url(#{target.value})"
|
94
|
+
end
|
95
|
+
|
96
|
+
visitor_for Terms::Function do |target|
|
97
|
+
"#{target.name}(" +
|
98
|
+
target.params.map { |x|
|
99
|
+
[
|
100
|
+
x.operator,
|
101
|
+
x.accept(self)
|
102
|
+
].compact.join(' ')
|
103
|
+
}.join + ')'
|
104
|
+
end
|
105
|
+
|
106
|
+
visitor_for Terms::Rgb do |target|
|
107
|
+
params = [
|
108
|
+
target.red,
|
109
|
+
target.green,
|
110
|
+
target.blue
|
111
|
+
].map { |c| target.percentage? ? "#{c}%" : c }.join(',')
|
112
|
+
|
113
|
+
%{rgb(#{params})}
|
114
|
+
end
|
115
|
+
|
116
|
+
visitor_for Terms::String do |target|
|
117
|
+
"\"#{target.value}\""
|
118
|
+
end
|
119
|
+
|
120
|
+
visitor_for Selector do |target|
|
121
|
+
target.simple_selectors.map { |ss| ss.accept self }.join
|
122
|
+
end
|
123
|
+
|
124
|
+
visitor_for Selectors::Type do |target|
|
125
|
+
combo = {
|
126
|
+
0 => nil,
|
127
|
+
1 => ' ',
|
128
|
+
2 => ' + ',
|
129
|
+
3 => ' > '
|
130
|
+
}[target.combinator]
|
131
|
+
|
132
|
+
[combo, target.name].compact.join +
|
133
|
+
target.additional_selectors.map { |as| as.accept self }.join
|
134
|
+
end
|
135
|
+
|
136
|
+
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
|
+
[
|
156
|
+
target.unary_operator == :minus ? '-' : nil,
|
157
|
+
target.value,
|
158
|
+
units
|
159
|
+
].compact.join
|
160
|
+
end
|
161
|
+
|
162
|
+
visitor_for Selectors::Id do |target|
|
163
|
+
"##{target.name}"
|
164
|
+
end
|
165
|
+
|
166
|
+
visitor_for Selectors::Class do |target|
|
167
|
+
".#{target.name}"
|
168
|
+
end
|
169
|
+
|
170
|
+
visitor_for Selectors::PseudoClass do |target|
|
171
|
+
":#{target.name}"
|
172
|
+
end
|
173
|
+
|
174
|
+
visitor_for Selectors::Attribute do |target|
|
175
|
+
case target.match_way
|
176
|
+
when Selectors::Attribute::SET
|
177
|
+
"[#{target.name}]"
|
178
|
+
when Selectors::Attribute::EQUALS
|
179
|
+
"[#{target.name}=\"#{target.value}\"]"
|
180
|
+
when Selectors::Attribute::INCLUDES
|
181
|
+
"[#{target.name} ~= \"#{target.value}\"]"
|
182
|
+
when Selectors::Attribute::DASHMATCH
|
183
|
+
"[#{target.name} |= \"#{target.value}\"]"
|
184
|
+
else
|
185
|
+
raise "no matching matchway"
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
private
|
190
|
+
def indent
|
191
|
+
if block_given?
|
192
|
+
@indent_level += 1
|
193
|
+
result = yield
|
194
|
+
@indent_level -= 1
|
195
|
+
return result
|
196
|
+
end
|
197
|
+
"#{@indent_space * @indent_level}"
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module CSSPool
|
2
|
+
module Visitors
|
3
|
+
class Visitor
|
4
|
+
def self.visitor_for *klasses, &block
|
5
|
+
klasses.each do |klass|
|
6
|
+
method_name = klass.name.split('::').join('_')
|
7
|
+
define_method(:"visit_#{method_name}", block)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def accept target
|
12
|
+
method_name = target.class.name.split('::').join('_')
|
13
|
+
send(:"visit_#{method_name}", target)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/csspool.rb
CHANGED
@@ -1 +1,18 @@
|
|
1
|
-
require '
|
1
|
+
require 'csspool/visitable'
|
2
|
+
require 'csspool/node'
|
3
|
+
require 'csspool/selectors'
|
4
|
+
require 'csspool/terms'
|
5
|
+
require 'csspool/selector'
|
6
|
+
require 'csspool/sac'
|
7
|
+
require 'csspool/lib_croco'
|
8
|
+
require 'csspool/css'
|
9
|
+
require 'csspool/visitors'
|
10
|
+
require 'csspool/collection'
|
11
|
+
|
12
|
+
module CSSPool
|
13
|
+
VERSION = "2.0.0"
|
14
|
+
|
15
|
+
def self.CSS doc
|
16
|
+
CSSPool::CSS::Document.parse doc
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module CSSPool
|
4
|
+
module CSS
|
5
|
+
class TestDocument < CSSPool::TestCase
|
6
|
+
def test_search
|
7
|
+
doc = CSSPool.CSS('div > p { background: red; }')
|
8
|
+
assert_equal 1, doc['div > p'].length
|
9
|
+
assert_equal 1, doc['div > p'].first.declarations.length
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module CSSPool
|
4
|
+
module CSS
|
5
|
+
class TestImportRule < CSSPool::TestCase
|
6
|
+
def test_import
|
7
|
+
doc = CSSPool.CSS <<-eocss
|
8
|
+
@import "foo.css";
|
9
|
+
eocss
|
10
|
+
|
11
|
+
assert_equal 1, doc.import_rules.length
|
12
|
+
|
13
|
+
doc.import_rules.each do |ir|
|
14
|
+
new_doc = ir.load do |url|
|
15
|
+
assert_equal "foo.css", url
|
16
|
+
"div { background: red; }"
|
17
|
+
end
|
18
|
+
assert new_doc
|
19
|
+
assert_equal 1, new_doc.rule_sets.length
|
20
|
+
assert_equal ir, new_doc.parent_import_rule
|
21
|
+
assert_equal doc, new_doc.parent
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_import_with_media
|
26
|
+
doc = CSSPool.CSS <<-eocss
|
27
|
+
@import "foo.css" screen, print;
|
28
|
+
eocss
|
29
|
+
|
30
|
+
assert_equal 1, doc.import_rules.length
|
31
|
+
doc.import_rules.each do |ir|
|
32
|
+
new_doc = ir.load do |url|
|
33
|
+
"div { background: red; }"
|
34
|
+
end
|
35
|
+
new_doc.rule_sets.each do |rs|
|
36
|
+
assert_equal ir.media, rs.media
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/test/helper.rb
CHANGED
@@ -1,9 +1,65 @@
|
|
1
1
|
require "test/unit"
|
2
|
+
require "csspool"
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
|
4
|
+
module CSSPool
|
5
|
+
class TestCase < Test::Unit::TestCase
|
6
|
+
unless RUBY_VERSION >= '1.9'
|
7
|
+
undef :default_test
|
8
|
+
end
|
6
9
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
+
ASSET_DIR = File.join(File.dirname(__FILE__), 'files')
|
11
|
+
|
12
|
+
class MyDoc < CSSPool::SAC::Document
|
13
|
+
attr_accessor :start_documents, :end_documents
|
14
|
+
attr_accessor :charsets, :import_styles, :comments, :start_selectors
|
15
|
+
attr_accessor :end_selectors, :properties
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
@start_documents = []
|
19
|
+
@end_documents = []
|
20
|
+
@charsets = []
|
21
|
+
@import_styles = []
|
22
|
+
@comments = []
|
23
|
+
@start_selectors = []
|
24
|
+
@end_selectors = []
|
25
|
+
@properties = []
|
26
|
+
end
|
27
|
+
|
28
|
+
def property name, expression, important
|
29
|
+
@properties << [name, expression]
|
30
|
+
end
|
31
|
+
|
32
|
+
def start_document
|
33
|
+
@start_documents << true
|
34
|
+
end
|
35
|
+
|
36
|
+
def end_document
|
37
|
+
@end_documents << true
|
38
|
+
end
|
39
|
+
|
40
|
+
def charset name, location
|
41
|
+
@charsets << [name, location]
|
42
|
+
end
|
43
|
+
|
44
|
+
def import_style media_list, uri, default_ns, location
|
45
|
+
@import_styles << [media_list, uri, default_ns, location]
|
46
|
+
end
|
47
|
+
|
48
|
+
def namespace_declaration prefix, uri, location
|
49
|
+
@import_styles << [prefix, uri, location]
|
50
|
+
end
|
51
|
+
|
52
|
+
def comment string
|
53
|
+
@comments << string
|
54
|
+
end
|
55
|
+
|
56
|
+
def start_selector selectors
|
57
|
+
@start_selectors << selectors
|
58
|
+
end
|
59
|
+
|
60
|
+
def end_selector selectors
|
61
|
+
@end_selectors << selectors
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module CSSPool
|
4
|
+
module SAC
|
5
|
+
class TestParser < CSSPool::TestCase
|
6
|
+
def setup
|
7
|
+
super
|
8
|
+
@doc = MyDoc.new
|
9
|
+
@css = <<-eocss
|
10
|
+
@charset "UTF-8";
|
11
|
+
@import url("foo.css") screen;
|
12
|
+
/* This is a comment */
|
13
|
+
div a.foo, #bar, * { background: red; }
|
14
|
+
div#a, a.foo, a:hover, a[href][int="10"]{ background: red; }
|
15
|
+
eocss
|
16
|
+
@parser = CSSPool::SAC::Parser.new(@doc)
|
17
|
+
@parser.parse(@css)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_start_and_end_called_with_the_same
|
21
|
+
assert_equal @doc.start_selectors, @doc.end_selectors
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_parse_no_doc
|
25
|
+
parser = CSSPool::SAC::Parser.new
|
26
|
+
parser.parse(@css)
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_start_document
|
30
|
+
assert_equal [true], @doc.start_documents
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_end_document
|
34
|
+
assert_equal [true], @doc.end_documents
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_charset
|
38
|
+
assert_equal(
|
39
|
+
[["UTF-8", { :line => 1, :byte_offset => 10, :column => 11}]],
|
40
|
+
@doc.charsets)
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_import_style
|
44
|
+
styles = @doc.import_styles.first
|
45
|
+
assert_equal ["screen"], styles.first
|
46
|
+
assert_equal "foo.css", styles[1]
|
47
|
+
assert_nil styles[2]
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_start_selector
|
51
|
+
selectors_for_rule = @doc.start_selectors.first
|
52
|
+
assert selectors_for_rule
|
53
|
+
assert_equal 3, selectors_for_rule.length
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_simple_selector
|
57
|
+
selectors_for_rule = @doc.start_selectors.first
|
58
|
+
selector = selectors_for_rule.first # => div a.foo
|
59
|
+
assert_equal 2, selector.simple_selectors.length
|
60
|
+
selector.simple_selectors.each do |ss|
|
61
|
+
assert ss.parse_location
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_additional_selector_list
|
66
|
+
selectors_for_rule = @doc.start_selectors.first
|
67
|
+
selector = selectors_for_rule.first # => div a.foo
|
68
|
+
simple_selector = selector.simple_selectors[1] # => a.foo
|
69
|
+
assert additional_selectors = simple_selector.additional_selectors
|
70
|
+
assert_equal 1, additional_selectors.length
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_additional_selector_class_name
|
74
|
+
selectors_for_rule = @doc.start_selectors.first
|
75
|
+
selector = selectors_for_rule.first # => div a.foo
|
76
|
+
simple_selector = selector.simple_selectors[1] # => a.foo
|
77
|
+
assert additional_selectors = simple_selector.additional_selectors
|
78
|
+
foo_class = additional_selectors.first
|
79
|
+
assert_equal 'foo', foo_class.name
|
80
|
+
end
|
81
|
+
|
82
|
+
# div#a, a.foo, a:hover, a[href='watever'] { background: red; }
|
83
|
+
def test_id_additional_selector
|
84
|
+
selectors_for_rule = @doc.start_selectors[1]
|
85
|
+
selector = selectors_for_rule.first # => div#a
|
86
|
+
simple_selector = selector.simple_selectors.first # => div#a
|
87
|
+
assert_equal 'a', simple_selector.additional_selectors.first.name
|
88
|
+
end
|
89
|
+
|
90
|
+
# div#a, a.foo, a:hover, a[href][int="10"]{ background: red; }
|
91
|
+
def test_pseudo_additional_selector
|
92
|
+
selectors_for_rule = @doc.start_selectors[1]
|
93
|
+
selector = selectors_for_rule[2] # => 'a:hover'
|
94
|
+
simple_selector = selector.simple_selectors.first # => a:hover
|
95
|
+
assert_equal 'hover', simple_selector.additional_selectors.first.name
|
96
|
+
assert_nil simple_selector.additional_selectors.first.extra
|
97
|
+
end
|
98
|
+
|
99
|
+
# div#a, a.foo, a:hover, a[href][int="10"]{ background: red; }
|
100
|
+
def test_attribute_selector
|
101
|
+
selectors_for_rule = @doc.start_selectors[1]
|
102
|
+
selector = selectors_for_rule[3] # => a[href][int="10"]
|
103
|
+
simple_selector = selector.simple_selectors.first
|
104
|
+
|
105
|
+
assert_equal 'href', simple_selector.additional_selectors.first.name
|
106
|
+
assert_nil simple_selector.additional_selectors.first.value
|
107
|
+
assert_equal 1, simple_selector.additional_selectors.first.match_way
|
108
|
+
|
109
|
+
assert_equal 'int', simple_selector.additional_selectors[1].name
|
110
|
+
assert_equal '10', simple_selector.additional_selectors[1].value
|
111
|
+
assert_equal 2, simple_selector.additional_selectors[1].match_way
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module CSSPool
|
4
|
+
module SAC
|
5
|
+
class TestProperties < CSSPool::TestCase
|
6
|
+
def setup
|
7
|
+
super
|
8
|
+
@doc = MyDoc.new
|
9
|
+
@css = <<-eocss
|
10
|
+
@charset "UTF-8";
|
11
|
+
@import url("foo.css") screen;
|
12
|
+
/* This is a comment */
|
13
|
+
div a.foo, #bar, * { background: red; }
|
14
|
+
div#a, a.foo, a:hover, a[href][int="10"]{ background: red; }
|
15
|
+
eocss
|
16
|
+
@parser = CSSPool::SAC::Parser.new(@doc)
|
17
|
+
@parser.parse(@css)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_properties
|
21
|
+
assert_equal ['background'], @doc.properties.map { |x| x.first }.uniq
|
22
|
+
@doc.properties.each do |property|
|
23
|
+
assert_equal 1, property[1].length
|
24
|
+
end
|
25
|
+
assert_equal ['red'], @doc.properties.map { |x| x[1].first.value }.uniq
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_ident_with_comma
|
29
|
+
doc = MyDoc.new
|
30
|
+
parser = CSSPool::SAC::Parser.new(doc)
|
31
|
+
parser.parse <<-eocss
|
32
|
+
h1 { font-family: Verdana, sans-serif, monospace; }
|
33
|
+
eocss
|
34
|
+
assert_equal 1, doc.properties.length
|
35
|
+
values = doc.properties.first[1]
|
36
|
+
assert_equal 3, values.length
|
37
|
+
assert_equal [nil, ',', ','],
|
38
|
+
values.map { |value| value.operator }
|
39
|
+
values.each { |value| assert value.parse_location }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|