csspool-st 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. data/.autotest +16 -0
  2. data/.gemtest +0 -0
  3. data/CHANGELOG.rdoc +87 -0
  4. data/Manifest.txt +62 -0
  5. data/README.rdoc +65 -0
  6. data/Rakefile +50 -0
  7. data/lib/csspool/collection.rb +50 -0
  8. data/lib/csspool/css/charset.rb +13 -0
  9. data/lib/csspool/css/declaration.rb +19 -0
  10. data/lib/csspool/css/document.rb +34 -0
  11. data/lib/csspool/css/document_handler.rb +51 -0
  12. data/lib/csspool/css/import_rule.rb +27 -0
  13. data/lib/csspool/css/media.rb +13 -0
  14. data/lib/csspool/css/parser.rb +1298 -0
  15. data/lib/csspool/css/parser.y +398 -0
  16. data/lib/csspool/css/rule_set.rb +17 -0
  17. data/lib/csspool/css/tokenizer.rb +231 -0
  18. data/lib/csspool/css/tokenizer.rex +97 -0
  19. data/lib/csspool/css.rb +8 -0
  20. data/lib/csspool/node.rb +41 -0
  21. data/lib/csspool/sac/document.rb +35 -0
  22. data/lib/csspool/sac/parser.rb +16 -0
  23. data/lib/csspool/sac.rb +2 -0
  24. data/lib/csspool/selector.rb +36 -0
  25. data/lib/csspool/selectors/additional.rb +6 -0
  26. data/lib/csspool/selectors/attribute.rb +21 -0
  27. data/lib/csspool/selectors/class.rb +11 -0
  28. data/lib/csspool/selectors/id.rb +11 -0
  29. data/lib/csspool/selectors/pseudo_class.rb +13 -0
  30. data/lib/csspool/selectors/simple.rb +22 -0
  31. data/lib/csspool/selectors/type.rb +6 -0
  32. data/lib/csspool/selectors/universal.rb +6 -0
  33. data/lib/csspool/selectors.rb +9 -0
  34. data/lib/csspool/terms/function.rb +17 -0
  35. data/lib/csspool/terms/hash.rb +6 -0
  36. data/lib/csspool/terms/ident.rb +15 -0
  37. data/lib/csspool/terms/number.rb +14 -0
  38. data/lib/csspool/terms/rgb.rb +20 -0
  39. data/lib/csspool/terms/string.rb +6 -0
  40. data/lib/csspool/terms/uri.rb +6 -0
  41. data/lib/csspool/terms.rb +7 -0
  42. data/lib/csspool/visitors/children.rb +50 -0
  43. data/lib/csspool/visitors/comparable.rb +84 -0
  44. data/lib/csspool/visitors/iterator.rb +80 -0
  45. data/lib/csspool/visitors/to_css.rb +248 -0
  46. data/lib/csspool/visitors/visitor.rb +17 -0
  47. data/lib/csspool/visitors.rb +5 -0
  48. data/lib/csspool.rb +21 -0
  49. data/test/css/test_document.rb +13 -0
  50. data/test/css/test_import_rule.rb +42 -0
  51. data/test/css/test_parser.rb +462 -0
  52. data/test/css/test_tokenizer.rb +320 -0
  53. data/test/helper.rb +65 -0
  54. data/test/sac/test_parser.rb +123 -0
  55. data/test/sac/test_properties.rb +43 -0
  56. data/test/sac/test_terms.rb +228 -0
  57. data/test/test_collection.rb +81 -0
  58. data/test/test_parser.rb +91 -0
  59. data/test/test_selector.rb +51 -0
  60. data/test/visitors/test_children.rb +20 -0
  61. data/test/visitors/test_comparable.rb +102 -0
  62. data/test/visitors/test_each.rb +19 -0
  63. data/test/visitors/test_to_css.rb +309 -0
  64. metadata +214 -0
@@ -0,0 +1,97 @@
1
+ module CSSPool
2
+ module CSS
3
+ class Tokenizer < Parser
4
+
5
+ macro
6
+ nl \n|\r\n|\r|\f
7
+ w [\s]*
8
+ nonascii [^\0-\177]
9
+ num ([0-9]*\.[0-9]+|[0-9]+)
10
+ unicode \\[0-9A-Fa-f]{1,6}(\r\n|[\s])?
11
+
12
+ escape {unicode}|\\[^\n\r\f0-9A-Fa-f]
13
+ nmchar [_A-Za-z0-9-]|{nonascii}|{escape}
14
+ nmstart [_A-Za-z]|{nonascii}|{escape}
15
+ ident [-@]?({nmstart})({nmchar})*
16
+ func [-@]?({nmstart})({nmchar}|[.])*
17
+ name ({nmchar})+
18
+ string1 "([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*"
19
+ string2 '([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*'
20
+ string ({string1}|{string2})
21
+ invalid1 "([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*
22
+ invalid2 '([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*
23
+ invalid ({invalid1}|{invalid2})
24
+ comment \/\*(.|{w})*?\*\/
25
+
26
+ rule
27
+
28
+ # [:state] pattern [actions]
29
+
30
+ url\({w}{string}{w}\) { [:URI, st(text)] }
31
+ url\({w}([!#\$%&*-~]|{nonascii}|{escape})*{w}\) { [:URI, st(text)] }
32
+ U\+[0-9a-fA-F?]{1,6}(-[0-9a-fA-F]{1,6})? {[:UNICODE_RANGE, st(text)] }
33
+ {w}{comment}{w} { next_token }
34
+
35
+ {func}\(\s* { [:FUNCTION, st(text)] }
36
+ {w}@import{w} { [:IMPORT_SYM, st(text)] }
37
+ {w}@page{w} { [:PAGE_SYM, st(text)] }
38
+ {w}@charset{w} { [:CHARSET_SYM, st(text)] }
39
+ {w}@media{w} { [:MEDIA_SYM, st(text)] }
40
+ {w}!({w}|{w}{comment}{w})important{w} { [:IMPORTANT_SYM, st(text)] }
41
+ {ident} { [:IDENT, st(text)] }
42
+ \#{name} { [:HASH, st(text)] }
43
+ {w}~={w} { [:INCLUDES, st(text)] }
44
+ {w}\|={w} { [:DASHMATCH, st(text)] }
45
+ {w}\^={w} { [:PREFIXMATCH, st(text)] }
46
+ {w}\$={w} { [:SUFFIXMATCH, st(text)] }
47
+ {w}\*={w} { [:SUBSTRINGMATCH, st(text)] }
48
+ {w}!={w} { [:NOT_EQUAL, st(text)] }
49
+ {w}={w} { [:EQUAL, st(text)] }
50
+ {w}\) { [:RPAREN, st(text)] }
51
+ {w}\({w} { [:LPAREN, st(text)] }
52
+ \[{w} { [:LSQUARE, st(text)] }
53
+ {w}\] { [:RSQUARE, st(text)] }
54
+ {w}\+{w} { [:PLUS, st(text)] }
55
+ {w}\{{w} { [:LBRACE, st(text)] }
56
+ {w}\}{w} { [:RBRACE, st(text)] }
57
+ {w}>{w} { [:GREATER, st(text)] }
58
+ {w},{w} { [:COMMA, st(',')] }
59
+ {w};{w} { [:SEMI, st(';')] }
60
+ \* { [:STAR, st(text)] }
61
+ {w}~{w} { [:TILDE, st(text)] }
62
+ \:not\({w} { [:NOT, st(text)] }
63
+ {w}{num}em{w} { [:EMS, st(text)] }
64
+ {w}{num}ex{w} { [:EXS, st(text)] }
65
+
66
+ {w}{num}(px|cm|mm|in|pt|pc){w} { [:LENGTH, st(text)] }
67
+ {w}{num}(deg|rad|grad){w} { [:ANGLE, st(text)] }
68
+ {w}{num}(ms|s){w} { [:TIME, st(text)] }
69
+ {w}{num}[k]?hz{w} { [:FREQ, st(text)] }
70
+
71
+ {w}{num}%{w} { [:PERCENTAGE, st(text)] }
72
+ {w}{num}{w} { [:NUMBER, st(text)] }
73
+ {w}\/\/{w} { [:DOUBLESLASH, st(text)] }
74
+ {w}\/{w} { [:SLASH, st('/')] }
75
+ <!-- { [:CDO, st(text)] }
76
+ --> { [:CDC, st(text)] }
77
+ {w}\-(?!{ident}){w} { [:MINUS, st(text)] }
78
+ {w}\+{w} { [:PLUS, st(text)] }
79
+
80
+
81
+ [\s]+ { [:S, st(text)] }
82
+ {string} { [:STRING, st(text)] }
83
+ {invalid} { [:INVALID, st(text)] }
84
+ . { [st(text), st(text)] }
85
+
86
+ inner
87
+
88
+ def st o
89
+ @st ||= Hash.new { |h,k| h[k] = k }
90
+ @st[o]
91
+ end
92
+
93
+ end
94
+ end
95
+ end
96
+
97
+ # vim: syntax=lex
@@ -0,0 +1,8 @@
1
+ require 'csspool/css/tokenizer'
2
+ require 'csspool/css/charset'
3
+ require 'csspool/css/import_rule'
4
+ require 'csspool/css/media'
5
+ require 'csspool/css/rule_set'
6
+ require 'csspool/css/declaration'
7
+ require 'csspool/css/document'
8
+ require 'csspool/css/document_handler'
@@ -0,0 +1,41 @@
1
+ module CSSPool
2
+ class Node
3
+ include Enumerable
4
+
5
+ def accept target
6
+ target.accept self
7
+ end
8
+
9
+ def to_css options={}
10
+ if options[:minify]
11
+ to_minified_css
12
+ else
13
+ accept Visitors::ToCSS.new
14
+ end
15
+ end
16
+ alias :to_s :to_css
17
+
18
+ def to_minified_css
19
+ accept Visitors::ToMinifiedCSS.new
20
+ end
21
+
22
+ def == other
23
+ return false unless self.class == other.class
24
+
25
+ accept Visitors::Comparable.new other
26
+ end
27
+ alias :eql? :==
28
+
29
+ def each &block
30
+ Visitors::Iterator.new(block).accept self
31
+ end
32
+
33
+ def children
34
+ accept Visitors::Children.new
35
+ end
36
+
37
+ def hash
38
+ @hash ||= children.map { |child| child.hash }.hash
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,35 @@
1
+ module CSSPool
2
+ module SAC
3
+ class Document
4
+ def start_document
5
+ end
6
+
7
+ def end_document
8
+ end
9
+
10
+ def charset name, location
11
+ end
12
+
13
+ def import_style media_list, uri, default_ns = nil, location = {}
14
+ end
15
+
16
+ def start_selector selector_list
17
+ end
18
+
19
+ def end_selector selector_list
20
+ end
21
+
22
+ def property name, expression, important
23
+ end
24
+
25
+ def comment comment
26
+ end
27
+
28
+ def start_media media_list, parse_location = {}
29
+ end
30
+
31
+ def end_media media_list, parse_location = {}
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,16 @@
1
+ module CSSPool
2
+ module SAC
3
+ class Parser < CSSPool::CSS::Tokenizer
4
+ attr_accessor :handler
5
+
6
+ def initialize handler = CSSPool::CSS::DocumentHandler.new
7
+ @handler = handler
8
+ end
9
+
10
+ def parse string
11
+ scan_str string
12
+ @handler.document
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,2 @@
1
+ require 'csspool/sac/document'
2
+ require 'csspool/sac/parser'
@@ -0,0 +1,36 @@
1
+ module CSSPool
2
+ class Selector < CSSPool::Node
3
+ attr_accessor :simple_selectors
4
+ attr_accessor :parse_location
5
+ attr_accessor :rule_set
6
+
7
+ def initialize simple_selectors = [], parse_location = {}
8
+ @simple_selectors = simple_selectors
9
+ @parse_location = parse_location
10
+ @rule_set = nil
11
+ end
12
+
13
+ def declarations
14
+ @rule_set.declarations
15
+ end
16
+
17
+ def specificity
18
+ a = b = c = 0
19
+ simple_selectors.each do |s|
20
+ if !s.name.nil?
21
+ c += 1
22
+ end
23
+ s.additional_selectors.each do |additional_selector|
24
+ if Selectors::Id === additional_selector
25
+ a += 1
26
+ elsif Selectors::PseudoElement === additional_selector
27
+ c += 1
28
+ else
29
+ b += 1
30
+ end
31
+ end
32
+ end
33
+ [a, b, c]
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,6 @@
1
+ module CSSPool
2
+ module Selectors
3
+ class Additional < CSSPool::Node
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,21 @@
1
+ module CSSPool
2
+ module Selectors
3
+ class Attribute < CSSPool::Selectors::Additional
4
+ attr_accessor :name
5
+ attr_accessor :value
6
+ attr_accessor :match_way
7
+
8
+ NO_MATCH = 0
9
+ SET = 1
10
+ EQUALS = 2
11
+ INCLUDES = 3
12
+ DASHMATCH = 4
13
+
14
+ def initialize name, value, match_way
15
+ @name = name
16
+ @value = value
17
+ @match_way = match_way
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,11 @@
1
+ module CSSPool
2
+ module Selectors
3
+ class Class < CSSPool::Selectors::Additional
4
+ attr_accessor :name
5
+
6
+ def initialize name
7
+ @name = name
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module CSSPool
2
+ module Selectors
3
+ class Id < CSSPool::Selectors::Additional
4
+ attr_accessor :name
5
+
6
+ def initialize name
7
+ @name = name
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ module CSSPool
2
+ module Selectors
3
+ class PseudoClass < CSSPool::Selectors::Additional
4
+ attr_accessor :name
5
+ attr_accessor :extra
6
+
7
+ def initialize name, extra = nil
8
+ @name = name
9
+ @extra = extra
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,22 @@
1
+ module CSSPool
2
+ module Selectors
3
+ class Simple < CSSPool::Node
4
+ NO_COMBINATOR = 0
5
+ DESCENDENT = 1
6
+ PRECEDED_BY = 2
7
+ CHILD = 3
8
+
9
+ attr_accessor :name
10
+ attr_accessor :parse_location
11
+ attr_accessor :additional_selectors
12
+ attr_accessor :combinator
13
+
14
+ def initialize name, combinator = nil
15
+ @name = name
16
+ @combinator = combinator
17
+ @parse_location = nil
18
+ @additional_selectors = []
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,6 @@
1
+ module CSSPool
2
+ module Selectors
3
+ class Type < CSSPool::Selectors::Simple
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module CSSPool
2
+ module Selectors
3
+ class Universal < CSSPool::Selectors::Simple
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,9 @@
1
+ require 'csspool/selectors/simple'
2
+ require 'csspool/selectors/universal'
3
+ require 'csspool/selectors/type'
4
+ require 'csspool/selectors/additional'
5
+ require 'csspool/selectors/id'
6
+ require 'csspool/selectors/class'
7
+ require 'csspool/selectors/pseudo'
8
+ require 'csspool/selectors/attribute'
9
+ require 'csspool/selectors/media_expression'
@@ -0,0 +1,17 @@
1
+ module CSSPool
2
+ module Terms
3
+ class Function < CSSPool::Node
4
+ attr_accessor :name
5
+ attr_accessor :params
6
+ attr_accessor :parse_location
7
+ attr_accessor :operator
8
+
9
+ def initialize name, params, operator = nil, parse_location = nil
10
+ @name = name
11
+ @params = params
12
+ @operator = operator
13
+ @parse_location = parse_location
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,6 @@
1
+ module CSSPool
2
+ module Terms
3
+ class Hash < Ident
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,15 @@
1
+ module CSSPool
2
+ module Terms
3
+ class Ident < CSSPool::Node
4
+ attr_accessor :value
5
+ attr_accessor :operator
6
+ attr_accessor :parse_location
7
+
8
+ def initialize value, operator = nil, parse_location = {}
9
+ @value = value
10
+ @operator = operator
11
+ @parse_location = parse_location
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,14 @@
1
+ module CSSPool
2
+ module Terms
3
+ class Number < Ident
4
+ attr_accessor :type
5
+ attr_accessor :unary_operator
6
+
7
+ def initialize value, unary_operator = nil, type = nil, operator = nil, parse_location = {}
8
+ @type = type
9
+ @unary_operator = unary_operator
10
+ super(value, operator, parse_location)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,20 @@
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 :parse_location
8
+ attr_accessor :operator
9
+
10
+ def initialize red, green, blue, operator = nil, parse_location = {}
11
+ super()
12
+ @red = red
13
+ @green = green
14
+ @blue = blue
15
+ @operator = operator
16
+ @parse_location = parse_location
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,6 @@
1
+ module CSSPool
2
+ module Terms
3
+ class String < CSSPool::Terms::Ident
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module CSSPool
2
+ module Terms
3
+ class URI < Ident
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,7 @@
1
+ require 'csspool/terms/ident'
2
+ require 'csspool/terms/string'
3
+ require 'csspool/terms/number'
4
+ require 'csspool/terms/function'
5
+ require 'csspool/terms/uri'
6
+ require 'csspool/terms/rgb'
7
+ require 'csspool/terms/hash'
@@ -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,84 @@
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
+ :operator
80
+ ].all? { |m| target.send(m) == @other.send(m) }
81
+ end
82
+ end
83
+ end
84
+ 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