sass 3.3.0 → 3.4.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.
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