csspool 0.2.6 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.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
|