sass 3.3.0 → 3.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (151) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +1 -1
  3. data/README.md +58 -50
  4. data/Rakefile +1 -4
  5. data/VERSION +1 -1
  6. data/VERSION_DATE +1 -1
  7. data/VERSION_NAME +1 -1
  8. data/bin/sass +1 -1
  9. data/bin/scss +1 -1
  10. data/lib/sass/cache_stores/filesystem.rb +6 -2
  11. data/lib/sass/css.rb +1 -3
  12. data/lib/sass/engine.rb +37 -46
  13. data/lib/sass/environment.rb +13 -17
  14. data/lib/sass/error.rb +6 -9
  15. data/lib/sass/exec/base.rb +187 -0
  16. data/lib/sass/exec/sass_convert.rb +264 -0
  17. data/lib/sass/exec/sass_scss.rb +424 -0
  18. data/lib/sass/exec.rb +5 -771
  19. data/lib/sass/features.rb +7 -0
  20. data/lib/sass/importers/base.rb +7 -2
  21. data/lib/sass/importers/filesystem.rb +9 -25
  22. data/lib/sass/importers.rb +0 -1
  23. data/lib/sass/media.rb +1 -4
  24. data/lib/sass/plugin/compiler.rb +200 -83
  25. data/lib/sass/plugin/staleness_checker.rb +1 -1
  26. data/lib/sass/plugin.rb +3 -3
  27. data/lib/sass/script/css_lexer.rb +1 -1
  28. data/lib/sass/script/functions.rb +622 -268
  29. data/lib/sass/script/lexer.rb +99 -34
  30. data/lib/sass/script/parser.rb +24 -23
  31. data/lib/sass/script/tree/funcall.rb +1 -1
  32. data/lib/sass/script/tree/interpolation.rb +20 -2
  33. data/lib/sass/script/tree/selector.rb +26 -0
  34. data/lib/sass/script/tree/string_interpolation.rb +1 -1
  35. data/lib/sass/script/tree.rb +1 -0
  36. data/lib/sass/script/value/base.rb +7 -5
  37. data/lib/sass/script/value/bool.rb +0 -5
  38. data/lib/sass/script/value/color.rb +39 -21
  39. data/lib/sass/script/value/helpers.rb +107 -0
  40. data/lib/sass/script/value/list.rb +0 -15
  41. data/lib/sass/script/value/null.rb +0 -5
  42. data/lib/sass/script/value/number.rb +62 -14
  43. data/lib/sass/script/value/string.rb +59 -11
  44. data/lib/sass/script/value.rb +0 -1
  45. data/lib/sass/scss/css_parser.rb +8 -2
  46. data/lib/sass/scss/parser.rb +190 -328
  47. data/lib/sass/scss/rx.rb +15 -6
  48. data/lib/sass/scss/static_parser.rb +298 -1
  49. data/lib/sass/selector/abstract_sequence.rb +28 -13
  50. data/lib/sass/selector/comma_sequence.rb +92 -13
  51. data/lib/sass/selector/pseudo.rb +256 -0
  52. data/lib/sass/selector/sequence.rb +94 -24
  53. data/lib/sass/selector/simple.rb +14 -25
  54. data/lib/sass/selector/simple_sequence.rb +97 -33
  55. data/lib/sass/selector.rb +57 -194
  56. data/lib/sass/shared.rb +1 -1
  57. data/lib/sass/source/map.rb +26 -12
  58. data/lib/sass/stack.rb +0 -6
  59. data/lib/sass/supports.rb +2 -3
  60. data/lib/sass/tree/at_root_node.rb +1 -0
  61. data/lib/sass/tree/charset_node.rb +1 -1
  62. data/lib/sass/tree/directive_node.rb +8 -2
  63. data/lib/sass/tree/error_node.rb +18 -0
  64. data/lib/sass/tree/extend_node.rb +1 -1
  65. data/lib/sass/tree/function_node.rb +4 -0
  66. data/lib/sass/tree/keyframe_rule_node.rb +15 -0
  67. data/lib/sass/tree/prop_node.rb +1 -1
  68. data/lib/sass/tree/rule_node.rb +12 -7
  69. data/lib/sass/tree/visitors/check_nesting.rb +38 -10
  70. data/lib/sass/tree/visitors/convert.rb +16 -18
  71. data/lib/sass/tree/visitors/cssize.rb +29 -29
  72. data/lib/sass/tree/visitors/deep_copy.rb +5 -0
  73. data/lib/sass/tree/visitors/perform.rb +45 -33
  74. data/lib/sass/tree/visitors/set_options.rb +14 -0
  75. data/lib/sass/tree/visitors/to_css.rb +15 -14
  76. data/lib/sass/util/subset_map.rb +1 -1
  77. data/lib/sass/util.rb +222 -99
  78. data/lib/sass/version.rb +5 -5
  79. data/lib/sass.rb +0 -5
  80. data/test/sass/cache_test.rb +62 -20
  81. data/test/sass/callbacks_test.rb +1 -1
  82. data/test/sass/compiler_test.rb +19 -10
  83. data/test/sass/conversion_test.rb +58 -1
  84. data/test/sass/css2sass_test.rb +23 -4
  85. data/test/sass/encoding_test.rb +219 -0
  86. data/test/sass/engine_test.rb +136 -199
  87. data/test/sass/exec_test.rb +2 -2
  88. data/test/sass/extend_test.rb +236 -19
  89. data/test/sass/functions_test.rb +295 -253
  90. data/test/sass/importer_test.rb +31 -21
  91. data/test/sass/logger_test.rb +1 -1
  92. data/test/sass/more_results/more_import.css +1 -1
  93. data/test/sass/plugin_test.rb +14 -13
  94. data/test/sass/results/compact.css +1 -1
  95. data/test/sass/results/complex.css +4 -4
  96. data/test/sass/results/expanded.css +1 -1
  97. data/test/sass/results/import.css +1 -1
  98. data/test/sass/results/import_charset_ibm866.css +2 -2
  99. data/test/sass/results/mixins.css +17 -17
  100. data/test/sass/results/nested.css +1 -1
  101. data/test/sass/results/parent_ref.css +2 -2
  102. data/test/sass/results/script.css +3 -3
  103. data/test/sass/results/scss_import.css +1 -1
  104. data/test/sass/script_conversion_test.rb +10 -7
  105. data/test/sass/script_test.rb +288 -74
  106. data/test/sass/scss/css_test.rb +141 -24
  107. data/test/sass/scss/rx_test.rb +4 -4
  108. data/test/sass/scss/scss_test.rb +457 -18
  109. data/test/sass/source_map_test.rb +115 -25
  110. data/test/sass/superselector_test.rb +191 -0
  111. data/test/sass/templates/scss_import.scss +2 -1
  112. data/test/sass/test_helper.rb +1 -1
  113. data/test/sass/util/multibyte_string_scanner_test.rb +1 -1
  114. data/test/sass/util/normalized_map_test.rb +1 -1
  115. data/test/sass/util/subset_map_test.rb +2 -2
  116. data/test/sass/util_test.rb +31 -1
  117. data/test/sass/value_helpers_test.rb +5 -7
  118. data/test/test_helper.rb +2 -2
  119. data/vendor/listen/CHANGELOG.md +1 -228
  120. data/vendor/listen/Gemfile +5 -15
  121. data/vendor/listen/README.md +111 -77
  122. data/vendor/listen/Rakefile +0 -42
  123. data/vendor/listen/lib/listen/adapter.rb +195 -82
  124. data/vendor/listen/lib/listen/adapters/bsd.rb +27 -64
  125. data/vendor/listen/lib/listen/adapters/darwin.rb +21 -58
  126. data/vendor/listen/lib/listen/adapters/linux.rb +23 -55
  127. data/vendor/listen/lib/listen/adapters/polling.rb +25 -34
  128. data/vendor/listen/lib/listen/adapters/windows.rb +50 -46
  129. data/vendor/listen/lib/listen/directory_record.rb +96 -61
  130. data/vendor/listen/lib/listen/listener.rb +135 -37
  131. data/vendor/listen/lib/listen/turnstile.rb +9 -5
  132. data/vendor/listen/lib/listen/version.rb +1 -1
  133. data/vendor/listen/lib/listen.rb +33 -19
  134. data/vendor/listen/listen.gemspec +6 -0
  135. data/vendor/listen/spec/listen/adapter_spec.rb +43 -77
  136. data/vendor/listen/spec/listen/adapters/polling_spec.rb +8 -8
  137. data/vendor/listen/spec/listen/directory_record_spec.rb +81 -56
  138. data/vendor/listen/spec/listen/listener_spec.rb +128 -39
  139. data/vendor/listen/spec/listen_spec.rb +15 -21
  140. data/vendor/listen/spec/spec_helper.rb +4 -0
  141. data/vendor/listen/spec/support/adapter_helper.rb +52 -15
  142. data/vendor/listen/spec/support/directory_record_helper.rb +7 -5
  143. data/vendor/listen/spec/support/listeners_helper.rb +30 -7
  144. metadata +25 -22
  145. data/ext/mkrf_conf.rb +0 -27
  146. data/lib/sass/importers/deprecated_path.rb +0 -51
  147. data/lib/sass/script/value/deprecated_false.rb +0 -55
  148. data/vendor/listen/lib/listen/dependency_manager.rb +0 -126
  149. data/vendor/listen/lib/listen/multi_listener.rb +0 -143
  150. data/vendor/listen/spec/listen/dependency_manager_spec.rb +0 -107
  151. data/vendor/listen/spec/listen/multi_listener_spec.rb +0 -174
@@ -43,11 +43,16 @@ module Sass
43
43
  end
44
44
 
45
45
  def pseudo_elements
46
- @pseudo_elements ||= (members - [base]).
47
- select {|sel| sel.is_a?(Pseudo) && sel.type == :element}
46
+ @pseudo_elements ||= members.select {|sel| sel.is_a?(Pseudo) && sel.type == :element}
48
47
  end
49
48
 
50
- # Returns the non-base, non-pseudo-class selectors in this sequence.
49
+ def selector_pseudo_classes
50
+ @selector_pseudo_classes ||= members.
51
+ select {|sel| sel.is_a?(Pseudo) && sel.type == :class && sel.selector}.
52
+ group_by {|sel| sel.normalized_name}
53
+ end
54
+
55
+ # Returns the non-base, non-pseudo-element selectors in this sequence.
51
56
  #
52
57
  # @return [Set<Simple>]
53
58
  def rest
@@ -86,18 +91,18 @@ module Sass
86
91
  return CommaSequence.new([Sequence.new([self])])
87
92
  end
88
93
 
89
- return super_cseq if @members.size == 1 && parent.suffix.empty?
94
+ return super_cseq if @members.size == 1 && parent.suffix.nil?
90
95
 
91
96
  CommaSequence.new(super_cseq.members.map do |super_seq|
92
97
  members = super_seq.members.dup
93
98
  newline = members.pop if members.last == "\n"
94
99
  unless members.last.is_a?(SimpleSequence)
95
100
  raise Sass::SyntaxError.new("Invalid parent selector for \"#{self}\": \"" +
96
- super_seq.to_a.join + '"')
101
+ super_seq.to_s + '"')
97
102
  end
98
103
 
99
104
  parent_sub = members.last.members
100
- unless parent.suffix.empty?
105
+ unless parent.suffix.nil?
101
106
  parent_sub = parent_sub.dup
102
107
  parent_sub[-1] = parent_sub.last.dup
103
108
  case parent_sub.last
@@ -108,17 +113,17 @@ module Sass
108
113
  parent_sub.last.name + parent.suffix,
109
114
  parent_sub.last.namespace)
110
115
  when Sass::Selector::Pseudo
111
- if parent_sub.last.arg
116
+ if parent_sub.last.arg || parent_sub.last.selector
112
117
  raise Sass::SyntaxError.new("Invalid parent selector for \"#{self}\": \"" +
113
- super_seq.to_a.join + '"')
118
+ super_seq.to_s + '"')
114
119
  end
115
- parent_sub[-1] = parent_sub.last.class.new(
120
+ parent_sub[-1] = Sass::Selector::Pseudo.new(
116
121
  parent_sub.last.type,
117
122
  parent_sub.last.name + parent.suffix,
118
- nil)
123
+ nil, nil)
119
124
  else
120
125
  raise Sass::SyntaxError.new("Invalid parent selector for \"#{self}\": \"" +
121
- super_seq.to_a.join + '"')
126
+ super_seq.to_s + '"')
122
127
  end
123
128
  end
124
129
 
@@ -128,19 +133,38 @@ module Sass
128
133
  end)
129
134
  end
130
135
 
131
- # Non-destrucively extends this selector with the extensions specified in a hash
136
+ # Non-destructively extends this selector with the extensions specified in a hash
132
137
  # (which should come from {Sass::Tree::Visitors::Cssize}).
133
138
  #
134
- # @overload def do_extend(extends, parent_directives)
135
139
  # @param extends [{Selector::Simple =>
136
140
  # Sass::Tree::Visitors::Cssize::Extend}]
137
141
  # The extensions to perform on this selector
138
142
  # @param parent_directives [Array<Sass::Tree::DirectiveNode>]
139
143
  # The directives containing this selector.
144
+ # @param seen [Set<Array<Selector::Simple>>]
145
+ # The set of simple sequences that are currently being replaced.
146
+ # @param original [Boolean]
147
+ # Whether this is the original selector being extended, as opposed to
148
+ # the result of a previous extension that's being re-extended.
140
149
  # @return [Array<Sequence>] A list of selectors generated
141
150
  # by extending this selector with `extends`.
142
151
  # @see CommaSequence#do_extend
143
- def do_extend(extends, parent_directives, seen = Set.new)
152
+ def do_extend(extends, parent_directives, replace, seen)
153
+ seen_with_pseudo_selectors = seen.dup
154
+
155
+ modified_original = false
156
+ members = Sass::Util.enum_with_index(self.members).map do |sel, i|
157
+ next sel unless sel.is_a?(Pseudo) && sel.selector
158
+ next sel if seen.include?([sel])
159
+ extended = sel.selector.do_extend(extends, parent_directives, replace, seen, !:original)
160
+ next sel if extended == sel.selector
161
+ extended.members.reject! {|seq| seq.has_placeholder?}
162
+ modified_original = true
163
+ result = sel.with_selector(extended)
164
+ seen_with_pseudo_selectors << [result]
165
+ result
166
+ end
167
+
144
168
  groups = Sass::Util.group_by_to_a(extends[members.to_set]) {|ex| ex.extender}
145
169
  groups.map! do |seq, group|
146
170
  sels = group.map {|e| e.target}.flatten
@@ -149,7 +173,7 @@ module Sass
149
173
 
150
174
  self_without_sel = Sass::Util.array_minus(members, sels)
151
175
  group.each {|e| e.result = :failed_to_unify unless e.result == :succeeded}
152
- unified = seq.members.last.unify(self_without_sel, subject?)
176
+ unified = seq.members.last.unify(SimpleSequence.new(self_without_sel, subject?))
153
177
  next unless unified
154
178
  group.each {|e| e.result = :succeeded}
155
179
  group.each {|e| check_directives_match!(e, parent_directives)}
@@ -159,19 +183,30 @@ module Sass
159
183
  end
160
184
  groups.compact!
161
185
  groups.map! do |sels, seq|
162
- seen.include?(sels) ? [] : seq.do_extend(extends, parent_directives, seen + [sels])
186
+ next [] if seen.include?(sels)
187
+ seq.do_extend(
188
+ extends, parent_directives, !:replace, seen_with_pseudo_selectors + [sels], !:original)
163
189
  end
164
190
  groups.flatten!
191
+
192
+ if modified_original || !replace || groups.empty?
193
+ # First Law of Extend: the result of extending a selector should
194
+ # (almost) always contain the base selector.
195
+ #
196
+ # See https://github.com/nex3/sass/issues/324.
197
+ original = Sequence.new([SimpleSequence.new(members, @subject, source_range)])
198
+ original.add_sources! sources
199
+ groups.unshift original
200
+ end
165
201
  groups.uniq!
166
202
  groups
167
203
  end
168
204
 
169
- # Unifies this selector with another {SimpleSequence}'s
170
- # {SimpleSequence#members members array}, returning another `SimpleSequence`
171
- # that matches both this selector and the input selector.
205
+ # Unifies this selector with another {SimpleSequence}, returning
206
+ # another `SimpleSequence` that is a subselector of both input
207
+ # selectors.
172
208
  #
173
- # @param sels [Array<Simple>] A {SimpleSequence}'s {SimpleSequence#members members array}
174
- # @param other_subject [Boolean] Whether the other {SimpleSequence} being merged is a subject.
209
+ # @param other [SimpleSequence]
175
210
  # @return [SimpleSequence, nil] A {SimpleSequence} matching both `sels` and this selector,
176
211
  # or `nil` if this is impossible (e.g. unifying `#foo` and `#bar`)
177
212
  # @raise [Sass::SyntaxError] If this selector cannot be unified.
@@ -180,13 +215,13 @@ module Sass
180
215
  # Since these selectors should be resolved
181
216
  # by the time extension and unification happen,
182
217
  # this exception will only ever be raised as a result of programmer error
183
- def unify(sels, other_subject)
184
- sseq = members.inject(sels) do |member, sel|
218
+ def unify(other)
219
+ sseq = members.inject(other.members) do |member, sel|
185
220
  return unless member
186
221
  sel.unify(member)
187
222
  end
188
223
  return unless sseq
189
- SimpleSequence.new(sseq, other_subject || subject?)
224
+ SimpleSequence.new(sseq, other.subject? || subject?)
190
225
  end
191
226
 
192
227
  # Returns whether or not this selector matches all elements
@@ -195,17 +230,44 @@ module Sass
195
230
  # @example
196
231
  # (.foo).superselector?(.foo.bar) #=> true
197
232
  # (.foo).superselector?(.bar) #=> false
198
- # @param sseq [SimpleSequence]
233
+ # @param their_sseq [SimpleSequence]
234
+ # @param parents [Array<SimpleSequence, String>] The parent selectors of `their_sseq`, if any.
199
235
  # @return [Boolean]
200
- def superselector?(sseq)
201
- (base.nil? || base.eql?(sseq.base)) &&
202
- pseudo_elements.eql?(sseq.pseudo_elements) &&
203
- rest.subset?(sseq.rest)
236
+ def superselector?(their_sseq, parents = [])
237
+ return false unless base.nil? || base.eql?(their_sseq.base)
238
+ return false unless pseudo_elements.eql?(their_sseq.pseudo_elements)
239
+ our_spcs = selector_pseudo_classes
240
+ their_spcs = their_sseq.selector_pseudo_classes
241
+
242
+ # Some psuedo-selectors can be subselectors of non-pseudo selectors.
243
+ # Pull those out here so we can efficiently check against them below.
244
+ their_subselector_pseudos = %w[matches any nth-child nth-last-child].
245
+ map {|name| their_spcs[name] || []}.flatten
246
+
247
+ # If `self`'s non-pseudo simple selectors aren't a subset of `their_sseq`'s,
248
+ # it's definitely not a superselector. This also considers being matched
249
+ # by `:matches` or `:any`.
250
+ return false unless rest.all? do |our_sel|
251
+ next true if our_sel.is_a?(Pseudo) && our_sel.selector
252
+ next true if their_sseq.rest.include?(our_sel)
253
+ their_subselector_pseudos.any? do |their_pseudo|
254
+ their_pseudo.selector.members.all? do |their_seq|
255
+ next false unless their_seq.members.length == 1
256
+ their_sseq = their_seq.members.first
257
+ next false unless their_sseq.is_a?(SimpleSequence)
258
+ their_sseq.rest.include?(our_sel)
259
+ end
260
+ end
261
+ end
262
+
263
+ our_spcs.all? do |name, pseudos|
264
+ pseudos.all? {|pseudo| pseudo.superselector?(their_sseq, parents)}
265
+ end
204
266
  end
205
267
 
206
- # @see Simple#to_a
207
- def to_a
208
- res = @members.map {|sel| sel.to_a}.flatten
268
+ # @see Simple#to_s
269
+ def to_s
270
+ res = @members.join
209
271
  res << '!' if subject?
210
272
  res
211
273
  end
@@ -215,7 +277,9 @@ module Sass
215
277
  #
216
278
  # @return [String]
217
279
  def inspect
218
- members.map {|m| m.inspect}.join
280
+ res = members.map {|m| m.inspect}.join
281
+ res << '!' if subject?
282
+ res
219
283
  end
220
284
 
221
285
  # Return a copy of this simple sequence with `sources` merged into the
data/lib/sass/selector.rb CHANGED
@@ -1,13 +1,14 @@
1
1
  require 'sass/selector/simple'
2
2
  require 'sass/selector/abstract_sequence'
3
3
  require 'sass/selector/comma_sequence'
4
+ require 'sass/selector/pseudo'
4
5
  require 'sass/selector/sequence'
5
6
  require 'sass/selector/simple_sequence'
6
7
 
7
8
  module Sass
8
9
  # A namespace for nodes in the parse tree for selectors.
9
10
  #
10
- # {CommaSequence} is the toplevel seelctor,
11
+ # {CommaSequence} is the toplevel selector,
11
12
  # representing a comma-separated sequence of {Sequence}s,
12
13
  # such as `foo bar, baz bang`.
13
14
  # {Sequence} is the next level,
@@ -27,19 +28,19 @@ module Sass
27
28
  # The function of this is to be replaced by the parent selector
28
29
  # in the nested hierarchy.
29
30
  class Parent < Simple
30
- # The identifier following the `&`. Often empty.
31
+ # The identifier following the `&`. `nil` indicates no suffix.
31
32
  #
32
- # @return [Array<String, Sass::Script::Tree::Node>]
33
+ # @return [String, nil]
33
34
  attr_reader :suffix
34
35
 
35
- # @param name [Array<String, Sass::Script::Tree::Node>] See \{#suffix}
36
- def initialize(suffix = [])
36
+ # @param name [String, nil] See \{#suffix}
37
+ def initialize(suffix = nil)
37
38
  @suffix = suffix
38
39
  end
39
40
 
40
- # @see Selector#to_a
41
- def to_a
42
- ["&", *@suffix]
41
+ # @see Selector#to_s
42
+ def to_s
43
+ "&" + (@suffix || '')
43
44
  end
44
45
 
45
46
  # Always raises an exception.
@@ -55,17 +56,17 @@ module Sass
55
56
  class Class < Simple
56
57
  # The class name.
57
58
  #
58
- # @return [Array<String, Sass::Script::Tree::Node>]
59
+ # @return [String]
59
60
  attr_reader :name
60
61
 
61
- # @param name [Array<String, Sass::Script::Tree::Node>] The class name
62
+ # @param name [String] The class name
62
63
  def initialize(name)
63
64
  @name = name
64
65
  end
65
66
 
66
- # @see Selector#to_a
67
- def to_a
68
- [".", *@name]
67
+ # @see Selector#to_s
68
+ def to_s
69
+ "." + @name
69
70
  end
70
71
 
71
72
  # @see AbstractSequence#specificity
@@ -78,17 +79,17 @@ module Sass
78
79
  class Id < Simple
79
80
  # The id name.
80
81
  #
81
- # @return [Array<String, Sass::Script::Tree::Node>]
82
+ # @return [String]
82
83
  attr_reader :name
83
84
 
84
- # @param name [Array<String, Sass::Script::Tree::Node>] The id name
85
+ # @param name [String] The id name
85
86
  def initialize(name)
86
87
  @name = name
87
88
  end
88
89
 
89
- # @see Selector#to_a
90
- def to_a
91
- ["#", *@name]
90
+ # @see Selector#to_s
91
+ def to_s
92
+ "#" + @name
92
93
  end
93
94
 
94
95
  # Returns `nil` if `sels` contains an {Id} selector
@@ -113,17 +114,17 @@ module Sass
113
114
  class Placeholder < Simple
114
115
  # The placeholder name.
115
116
  #
116
- # @return [Array<String, Sass::Script::Tree::Node>]
117
+ # @return [String]
117
118
  attr_reader :name
118
119
 
119
- # @param name [Array<String, Sass::Script::Tree::Node>] The placeholder name
120
+ # @param name [String] The placeholder name
120
121
  def initialize(name)
121
122
  @name = name
122
123
  end
123
124
 
124
- # @see Selector#to_a
125
- def to_a
126
- ["%", *@name]
125
+ # @see Selector#to_s
126
+ def to_s
127
+ "%" + @name
127
128
  end
128
129
 
129
130
  # @see AbstractSequence#specificity
@@ -134,22 +135,20 @@ module Sass
134
135
 
135
136
  # A universal selector (`*` in CSS).
136
137
  class Universal < Simple
137
- # The selector namespace.
138
- # `nil` means the default namespace,
139
- # `[""]` means no namespace,
140
- # `["*"]` means any namespace.
138
+ # The selector namespace. `nil` means the default namespace, `""` means no
139
+ # namespace, `"*"` means any namespace.
141
140
  #
142
- # @return [Array<String, Sass::Script::Tree::Node>, nil]
141
+ # @return [String, nil]
143
142
  attr_reader :namespace
144
143
 
145
- # @param namespace [Array<String, Sass::Script::Tree::Node>, nil] See \{#namespace}
144
+ # @param namespace [String, nil] See \{#namespace}
146
145
  def initialize(namespace)
147
146
  @namespace = namespace
148
147
  end
149
148
 
150
- # @see Selector#to_a
151
- def to_a
152
- @namespace ? @namespace + ["|*"] : ["*"]
149
+ # @see Selector#to_s
150
+ def to_s
151
+ @namespace ? "#{@namespace}|*" : "*"
153
152
  end
154
153
 
155
154
  # Unification of a universal selector is somewhat complicated,
@@ -183,7 +182,7 @@ module Sass
183
182
  when Universal; :universal
184
183
  when Element; sels.first.name
185
184
  else
186
- return [self] + sels unless namespace.nil? || namespace == ['*']
185
+ return [self] + sels unless namespace.nil? || namespace == '*'
187
186
  return sels unless sels.empty?
188
187
  return [self]
189
188
  end
@@ -203,27 +202,25 @@ module Sass
203
202
  class Element < Simple
204
203
  # The element name.
205
204
  #
206
- # @return [Array<String, Sass::Script::Tree::Node>]
205
+ # @return [String]
207
206
  attr_reader :name
208
207
 
209
- # The selector namespace.
210
- # `nil` means the default namespace,
211
- # `[""]` means no namespace,
212
- # `["*"]` means any namespace.
208
+ # The selector namespace. `nil` means the default namespace, `""` means no
209
+ # namespace, `"*"` means any namespace.
213
210
  #
214
- # @return [Array<String, Sass::Script::Tree::Node>, nil]
211
+ # @return [String, nil]
215
212
  attr_reader :namespace
216
213
 
217
- # @param name [Array<String, Sass::Script::Tree::Node>] The element name
218
- # @param namespace [Array<String, Sass::Script::Tree::Node>, nil] See \{#namespace}
214
+ # @param name [String] The element name
215
+ # @param namespace [String, nil] See \{#namespace}
219
216
  def initialize(name, namespace)
220
217
  @name = name
221
218
  @namespace = namespace
222
219
  end
223
220
 
224
- # @see Selector#to_a
225
- def to_a
226
- @namespace ? @namespace + ["|"] + @name : @name
221
+ # @see Selector#to_s
222
+ def to_s
223
+ @namespace ? "#{@namespace}|#{@name}" : @name
227
224
  end
228
225
 
229
226
  # Unification of an element selector is somewhat complicated,
@@ -266,32 +263,6 @@ module Sass
266
263
  end
267
264
  end
268
265
 
269
- # Selector interpolation (`#{}` in Sass).
270
- class Interpolation < Simple
271
- # The script to run.
272
- #
273
- # @return [Sass::Script::Tree::Node]
274
- attr_reader :script
275
-
276
- # @param script [Sass::Script::Tree::Node] The script to run
277
- def initialize(script)
278
- @script = script
279
- end
280
-
281
- # @see Selector#to_a
282
- def to_a
283
- [@script]
284
- end
285
-
286
- # Always raises an exception.
287
- #
288
- # @raise [Sass::SyntaxError] Interpolation selectors should be resolved before unification
289
- # @see Selector#unify
290
- def unify(sels)
291
- raise Sass::SyntaxError.new("[BUG] Cannot unify interpolation selectors.")
292
- end
293
- end
294
-
295
266
  # An attribute selector (e.g. `[href^="http://"]`).
296
267
  class Attribute < Simple
297
268
  # The attribute name.
@@ -299,12 +270,10 @@ module Sass
299
270
  # @return [Array<String, Sass::Script::Tree::Node>]
300
271
  attr_reader :name
301
272
 
302
- # The attribute namespace.
303
- # `nil` means the default namespace,
304
- # `[""]` means no namespace,
305
- # `["*"]` means any namespace.
273
+ # The attribute namespace. `nil` means the default namespace, `""` means
274
+ # no namespace, `"*"` means any namespace.
306
275
  #
307
- # @return [Array<String, Sass::Script::Tree::Node>, nil]
276
+ # @return [String, nil]
308
277
  attr_reader :namespace
309
278
 
310
279
  # The matching operator, e.g. `"="` or `"^="`.
@@ -314,19 +283,19 @@ module Sass
314
283
 
315
284
  # The right-hand side of the operator.
316
285
  #
317
- # @return [Array<String, Sass::Script::Tree::Node>]
286
+ # @return [String]
318
287
  attr_reader :value
319
288
 
320
289
  # Flags for the attribute selector (e.g. `i`).
321
290
  #
322
- # @return [Array<String, Sass::Script::Tree::Node>]
291
+ # @return [String]
323
292
  attr_reader :flags
324
293
 
325
- # @param name [Array<String, Sass::Script::Tree::Node>] The attribute name
326
- # @param namespace [Array<String, Sass::Script::Tree::Node>, nil] See \{#namespace}
294
+ # @param name [String] The attribute name
295
+ # @param namespace [String, nil] See \{#namespace}
327
296
  # @param operator [String] The matching operator, e.g. `"="` or `"^="`
328
- # @param value [Array<String, Sass::Script::Tree::Node>] See \{#value}
329
- # @param flags [Array<String, Sass::Script::Tree::Node>] See \{#flags}
297
+ # @param value [String] See \{#value}
298
+ # @param flags [String] See \{#flags}
330
299
  # @comment
331
300
  # rubocop:disable ParameterLists
332
301
  def initialize(name, namespace, operator, value, flags)
@@ -338,13 +307,13 @@ module Sass
338
307
  @flags = flags
339
308
  end
340
309
 
341
- # @see Selector#to_a
342
- def to_a
343
- res = ["["]
344
- res.concat(@namespace) << "|" if @namespace
345
- res.concat @name
346
- (res << @operator).concat @value if @value
347
- (res << " ").concat @flags if @flags
310
+ # @see Selector#to_s
311
+ def to_s
312
+ res = "["
313
+ res << @namespace << "|" if @namespace
314
+ res << @name
315
+ res << @operator << @value if @value
316
+ res << " " << @flags if @flags
348
317
  res << "]"
349
318
  end
350
319
 
@@ -353,111 +322,5 @@ module Sass
353
322
  SPECIFICITY_BASE
354
323
  end
355
324
  end
356
-
357
- # A pseudoclass (e.g. `:visited`) or pseudoelement (e.g. `::first-line`) selector.
358
- # It can have arguments (e.g. `:nth-child(2n+1)`).
359
- class Pseudo < Simple
360
- # Some psuedo-class-syntax selectors are actually considered
361
- # pseudo-elements and must be treated differently. This is a list of such
362
- # selectors
363
- #
364
- # @return [Array<String>]
365
- ACTUALLY_ELEMENTS = %w[after before first-line first-letter]
366
-
367
- # Like \{#type}, but returns the type of selector this looks like, rather
368
- # than the type it is semantically. This only differs from type for
369
- # selectors in \{ACTUALLY\_ELEMENTS}.
370
- #
371
- # @return [Symbol]
372
- attr_reader :syntactic_type
373
-
374
- # The name of the selector.
375
- #
376
- # @return [Array<String, Sass::Script::Tree::Node>]
377
- attr_reader :name
378
-
379
- # The argument to the selector,
380
- # or `nil` if no argument was given.
381
- #
382
- # This may include SassScript nodes that will be run during resolution.
383
- # Note that this should not include SassScript nodes
384
- # after resolution has taken place.
385
- #
386
- # @return [Array<String, Sass::Script::Tree::Node>, nil]
387
- attr_reader :arg
388
-
389
- # @param type [Symbol] See \{#type}
390
- # @param name [Array<String, Sass::Script::Tree::Node>] The name of the selector
391
- # @param arg [nil, Array<String, Sass::Script::Tree::Node>] The argument to the selector,
392
- # or nil if no argument was given
393
- def initialize(type, name, arg)
394
- @syntactic_type = type
395
- @name = name
396
- @arg = arg
397
- end
398
-
399
- # The type of the selector. `:class` if this is a pseudoclass selector,
400
- # `:element` if it's a pseudoelement.
401
- #
402
- # @return [Symbol]
403
- def type
404
- ACTUALLY_ELEMENTS.include?(name.first) ? :element : syntactic_type
405
- end
406
-
407
- # @see Selector#to_a
408
- def to_a
409
- res = [syntactic_type == :class ? ":" : "::"] + @name
410
- (res << "(").concat(Sass::Util.strip_string_array(@arg)) << ")" if @arg
411
- res
412
- end
413
-
414
- # Returns `nil` if this is a pseudoelement selector
415
- # and `sels` contains a pseudoelement selector different than this one.
416
- #
417
- # @see Selector#unify
418
- def unify(sels)
419
- return if type == :element && sels.any? do |sel|
420
- sel.is_a?(Pseudo) && sel.type == :element &&
421
- (sel.name != name || sel.arg != arg)
422
- end
423
- super
424
- end
425
-
426
- # @see AbstractSequence#specificity
427
- def specificity
428
- type == :class ? SPECIFICITY_BASE : 1
429
- end
430
- end
431
-
432
- # A pseudoclass selector whose argument is itself a selector
433
- # (e.g. `:not(.foo)` or `:-moz-all(.foo, .bar)`).
434
- class SelectorPseudoClass < Simple
435
- # The name of the pseudoclass.
436
- #
437
- # @return [String]
438
- attr_reader :name
439
-
440
- # The selector argument.
441
- #
442
- # @return [Selector::Sequence]
443
- attr_reader :selector
444
-
445
- # @param name [String] The name of the pseudoclass
446
- # @param selector [Selector::CommaSequence] The selector argument
447
- def initialize(name, selector)
448
- @name = name
449
- @selector = selector
450
- end
451
-
452
- # @see Selector#to_a
453
- def to_a
454
- [":", @name, "("] + @selector.to_a + [")"]
455
- end
456
-
457
- # @see AbstractSequence#specificity
458
- def specificity
459
- SPECIFICITY_BASE
460
- end
461
- end
462
325
  end
463
326
  end
data/lib/sass/shared.rb CHANGED
@@ -44,7 +44,7 @@ module Sass
44
44
  str << scanner.matched
45
45
  count += 1 if scanner.matched[-1] == start
46
46
  count -= 1 if scanner.matched[-1] == finish
47
- return [str.strip, scanner.rest] if count == 0
47
+ return [str, scanner.rest] if count == 0
48
48
  end
49
49
  end
50
50