maca-fork-csspool 2.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +72 -0
- data/History.txt +4 -0
- data/Manifest.txt +70 -0
- data/README.rdoc +78 -0
- data/Rakefile +35 -0
- data/lib/csspool.rb +20 -0
- data/lib/csspool/collection.rb +50 -0
- data/lib/csspool/css.rb +7 -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/lib_croco.rb +78 -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 +33 -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/node.rb +5 -0
- data/lib/csspool/sac.rb +2 -0
- data/lib/csspool/sac/document.rb +35 -0
- data/lib/csspool/sac/parser.rb +122 -0
- data/lib/csspool/selector.rb +35 -0
- data/lib/csspool/selectors.rb +8 -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/terms.rb +7 -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/visitable.rb +30 -0
- data/lib/csspool/visitors.rb +5 -0
- data/lib/csspool/visitors/children.rb +50 -0
- data/lib/csspool/visitors/comparable.rb +85 -0
- data/lib/csspool/visitors/iterator.rb +80 -0
- data/lib/csspool/visitors/to_css.rb +188 -0
- data/lib/csspool/visitors/visitor.rb +17 -0
- data/test/css/test_document.rb +13 -0
- data/test/css/test_import_rule.rb +42 -0
- data/test/helper.rb +67 -0
- 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 +91 -0
- data/test/test_selector.rb +47 -0
- data/test/visitors/test_children.rb +20 -0
- data/test/visitors/test_comparable.rb +103 -0
- data/test/visitors/test_each.rb +19 -0
- data/test/visitors/test_to_css.rb +200 -0
- metadata +173 -0
@@ -0,0 +1,30 @@
|
|
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
|
+
accept Visitors::Comparable.new(other)
|
15
|
+
end
|
16
|
+
alias :eql? :==
|
17
|
+
|
18
|
+
def each &block
|
19
|
+
accept Visitors::Iterator.new(block)
|
20
|
+
end
|
21
|
+
|
22
|
+
def children
|
23
|
+
accept Visitors::Children.new
|
24
|
+
end
|
25
|
+
|
26
|
+
def hash
|
27
|
+
@hash ||= children.map { |child| child.hash }.hash
|
28
|
+
end
|
29
|
+
end
|
30
|
+
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
|
+
|
@@ -0,0 +1,85 @@
|
|
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 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|
|
42
|
+
target.name == @other.name
|
43
|
+
end
|
44
|
+
|
45
|
+
visitor_for Selectors::Type, Selectors::Universal,
|
46
|
+
Selectors::Simple do |target|
|
47
|
+
[:name, :combinator, :additional_selectors].all? { |m|
|
48
|
+
target.send(m) == @other.send(m)
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
visitor_for CSS::Declaration do |target|
|
53
|
+
[:property, :expressions, :important].all? { |m|
|
54
|
+
target.send(m) == @other.send(m)
|
55
|
+
}
|
56
|
+
end
|
57
|
+
|
58
|
+
visitor_for Terms::Function do |target|
|
59
|
+
[:name, :params, :operator].all? { |m|
|
60
|
+
target.send(m) == @other.send(m)
|
61
|
+
}
|
62
|
+
end
|
63
|
+
|
64
|
+
visitor_for Terms::Number do |target|
|
65
|
+
[:type, :unary_operator, :value, :operator].all? { |m|
|
66
|
+
target.send(m) == @other.send(m)
|
67
|
+
}
|
68
|
+
end
|
69
|
+
|
70
|
+
visitor_for Terms::URI,Terms::String,Terms::Ident,Terms::Hash do |target|
|
71
|
+
[:value, :operator].all? { |m| target.send(m) == @other.send(m) }
|
72
|
+
end
|
73
|
+
|
74
|
+
visitor_for Terms::Rgb do |target|
|
75
|
+
[
|
76
|
+
:red,
|
77
|
+
:green,
|
78
|
+
:blue,
|
79
|
+
:percentage,
|
80
|
+
:operator
|
81
|
+
].all? { |m| target.send(m) == @other.send(m) }
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
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
|
@@ -0,0 +1,188 @@
|
|
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, Selectors::Type do |target|
|
87
|
+
"#{ Selector::COMBINATORS[target.combinator] }#{ target.name }" +
|
88
|
+
target.additional_selectors.map{ |x| x.accept self }.join
|
89
|
+
end
|
90
|
+
|
91
|
+
visitor_for Terms::URI do |target|
|
92
|
+
"url(#{target.value})"
|
93
|
+
end
|
94
|
+
|
95
|
+
visitor_for Terms::Function do |target|
|
96
|
+
"#{target.name}(" +
|
97
|
+
target.params.map { |x|
|
98
|
+
[
|
99
|
+
x.operator,
|
100
|
+
x.accept(self)
|
101
|
+
].compact.join(' ')
|
102
|
+
}.join + ')'
|
103
|
+
end
|
104
|
+
|
105
|
+
visitor_for Terms::Rgb do |target|
|
106
|
+
params = [
|
107
|
+
target.red,
|
108
|
+
target.green,
|
109
|
+
target.blue
|
110
|
+
].map { |c| target.percentage? ? "#{c}%" : c }.join(',')
|
111
|
+
|
112
|
+
%{rgb(#{params})}
|
113
|
+
end
|
114
|
+
|
115
|
+
visitor_for Terms::String do |target|
|
116
|
+
"\"#{target.value}\""
|
117
|
+
end
|
118
|
+
|
119
|
+
visitor_for Selector do |target|
|
120
|
+
target.simple_selectors.map { |ss| ss.accept self }.join
|
121
|
+
end
|
122
|
+
|
123
|
+
visitor_for Terms::Number do |target|
|
124
|
+
units = {
|
125
|
+
2 => 'em',
|
126
|
+
3 => 'ex',
|
127
|
+
4 => 'px',
|
128
|
+
5 => 'in',
|
129
|
+
6 => 'cm',
|
130
|
+
7 => 'mm',
|
131
|
+
8 => 'pt',
|
132
|
+
9 => 'pc',
|
133
|
+
10 => 'deg',
|
134
|
+
11 => 'rad',
|
135
|
+
12 => 'grad',
|
136
|
+
13 => 'ms',
|
137
|
+
14 => 's',
|
138
|
+
15 => 'Hz',
|
139
|
+
16 => 'kHz',
|
140
|
+
17 => '%',
|
141
|
+
}[target.type]
|
142
|
+
[
|
143
|
+
target.unary_operator == :minus ? '-' : nil,
|
144
|
+
target.value,
|
145
|
+
units
|
146
|
+
].compact.join
|
147
|
+
end
|
148
|
+
|
149
|
+
visitor_for Selectors::Id do |target|
|
150
|
+
"##{target.name}"
|
151
|
+
end
|
152
|
+
|
153
|
+
visitor_for Selectors::Class do |target|
|
154
|
+
".#{target.name}"
|
155
|
+
end
|
156
|
+
|
157
|
+
visitor_for Selectors::PseudoClass do |target|
|
158
|
+
":#{target.name}"
|
159
|
+
end
|
160
|
+
|
161
|
+
visitor_for Selectors::Attribute do |target|
|
162
|
+
case target.match_way
|
163
|
+
when Selectors::Attribute::SET
|
164
|
+
"[#{target.name}]"
|
165
|
+
when Selectors::Attribute::EQUALS
|
166
|
+
"[#{target.name}=\"#{target.value}\"]"
|
167
|
+
when Selectors::Attribute::INCLUDES
|
168
|
+
"[#{target.name} ~= \"#{target.value}\"]"
|
169
|
+
when Selectors::Attribute::DASHMATCH
|
170
|
+
"[#{target.name} |= \"#{target.value}\"]"
|
171
|
+
else
|
172
|
+
raise "no matching matchway"
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
private
|
177
|
+
def indent
|
178
|
+
if block_given?
|
179
|
+
@indent_level += 1
|
180
|
+
result = yield
|
181
|
+
@indent_level -= 1
|
182
|
+
return result
|
183
|
+
end
|
184
|
+
"#{@indent_space * @indent_level}"
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|