sass 3.3.14 → 3.4.0.rc.1

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 (110) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +1 -1
  3. data/README.md +5 -5
  4. data/VERSION +1 -1
  5. data/VERSION_DATE +1 -1
  6. data/VERSION_NAME +1 -1
  7. data/bin/sass +1 -1
  8. data/bin/scss +1 -1
  9. data/lib/sass.rb +0 -5
  10. data/lib/sass/css.rb +1 -3
  11. data/lib/sass/engine.rb +28 -39
  12. data/lib/sass/environment.rb +13 -17
  13. data/lib/sass/error.rb +6 -9
  14. data/lib/sass/exec.rb +5 -771
  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 +419 -0
  18. data/lib/sass/features.rb +6 -0
  19. data/lib/sass/importers.rb +0 -1
  20. data/lib/sass/importers/base.rb +5 -1
  21. data/lib/sass/importers/filesystem.rb +4 -21
  22. data/lib/sass/media.rb +1 -4
  23. data/lib/sass/plugin/compiler.rb +32 -136
  24. data/lib/sass/script/css_lexer.rb +1 -1
  25. data/lib/sass/script/functions.rb +363 -39
  26. data/lib/sass/script/lexer.rb +68 -50
  27. data/lib/sass/script/parser.rb +29 -14
  28. data/lib/sass/script/tree.rb +1 -0
  29. data/lib/sass/script/tree/funcall.rb +1 -1
  30. data/lib/sass/script/tree/interpolation.rb +19 -1
  31. data/lib/sass/script/tree/selector.rb +26 -0
  32. data/lib/sass/script/value.rb +0 -1
  33. data/lib/sass/script/value/bool.rb +0 -5
  34. data/lib/sass/script/value/color.rb +32 -12
  35. data/lib/sass/script/value/helpers.rb +107 -0
  36. data/lib/sass/script/value/list.rb +0 -15
  37. data/lib/sass/script/value/null.rb +0 -5
  38. data/lib/sass/script/value/number.rb +60 -14
  39. data/lib/sass/script/value/string.rb +53 -9
  40. data/lib/sass/scss/css_parser.rb +8 -2
  41. data/lib/sass/scss/parser.rb +175 -319
  42. data/lib/sass/scss/rx.rb +14 -5
  43. data/lib/sass/scss/static_parser.rb +298 -1
  44. data/lib/sass/selector.rb +56 -193
  45. data/lib/sass/selector/abstract_sequence.rb +28 -13
  46. data/lib/sass/selector/comma_sequence.rb +91 -12
  47. data/lib/sass/selector/pseudo.rb +256 -0
  48. data/lib/sass/selector/sequence.rb +99 -31
  49. data/lib/sass/selector/simple.rb +14 -25
  50. data/lib/sass/selector/simple_sequence.rb +101 -37
  51. data/lib/sass/shared.rb +1 -1
  52. data/lib/sass/source/map.rb +23 -9
  53. data/lib/sass/stack.rb +0 -6
  54. data/lib/sass/supports.rb +1 -1
  55. data/lib/sass/tree/at_root_node.rb +1 -0
  56. data/lib/sass/tree/directive_node.rb +7 -1
  57. data/lib/sass/tree/error_node.rb +18 -0
  58. data/lib/sass/tree/keyframe_rule_node.rb +15 -0
  59. data/lib/sass/tree/prop_node.rb +1 -1
  60. data/lib/sass/tree/rule_node.rb +11 -6
  61. data/lib/sass/tree/visitors/check_nesting.rb +3 -4
  62. data/lib/sass/tree/visitors/convert.rb +8 -17
  63. data/lib/sass/tree/visitors/cssize.rb +12 -24
  64. data/lib/sass/tree/visitors/deep_copy.rb +5 -0
  65. data/lib/sass/tree/visitors/perform.rb +43 -28
  66. data/lib/sass/tree/visitors/set_options.rb +5 -0
  67. data/lib/sass/tree/visitors/to_css.rb +14 -13
  68. data/lib/sass/util.rb +94 -90
  69. data/test/sass/cache_test.rb +1 -1
  70. data/test/sass/callbacks_test.rb +1 -1
  71. data/test/sass/compiler_test.rb +5 -14
  72. data/test/sass/conversion_test.rb +47 -1
  73. data/test/sass/css2sass_test.rb +3 -3
  74. data/test/sass/encoding_test.rb +219 -0
  75. data/test/sass/engine_test.rb +128 -191
  76. data/test/sass/exec_test.rb +2 -2
  77. data/test/sass/extend_test.rb +234 -17
  78. data/test/sass/functions_test.rb +268 -213
  79. data/test/sass/importer_test.rb +31 -21
  80. data/test/sass/logger_test.rb +1 -1
  81. data/test/sass/more_results/more_import.css +1 -1
  82. data/test/sass/plugin_test.rb +12 -11
  83. data/test/sass/results/compact.css +1 -1
  84. data/test/sass/results/complex.css +4 -4
  85. data/test/sass/results/expanded.css +1 -1
  86. data/test/sass/results/import.css +1 -1
  87. data/test/sass/results/import_charset_ibm866.css +2 -2
  88. data/test/sass/results/mixins.css +17 -17
  89. data/test/sass/results/nested.css +1 -1
  90. data/test/sass/results/parent_ref.css +2 -2
  91. data/test/sass/results/script.css +3 -3
  92. data/test/sass/results/scss_import.css +1 -1
  93. data/test/sass/script_conversion_test.rb +7 -4
  94. data/test/sass/script_test.rb +202 -79
  95. data/test/sass/scss/css_test.rb +95 -25
  96. data/test/sass/scss/rx_test.rb +4 -4
  97. data/test/sass/scss/scss_test.rb +363 -19
  98. data/test/sass/source_map_test.rb +48 -41
  99. data/test/sass/superselector_test.rb +191 -0
  100. data/test/sass/templates/scss_import.scss +2 -1
  101. data/test/sass/test_helper.rb +1 -1
  102. data/test/sass/util/multibyte_string_scanner_test.rb +1 -1
  103. data/test/sass/util/normalized_map_test.rb +1 -1
  104. data/test/sass/util/subset_map_test.rb +2 -2
  105. data/test/sass/util_test.rb +1 -1
  106. data/test/sass/value_helpers_test.rb +3 -3
  107. data/test/test_helper.rb +2 -2
  108. metadata +30 -7
  109. data/lib/sass/importers/deprecated_path.rb +0 -51
  110. data/lib/sass/script/value/deprecated_false.rb +0 -55
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  module Sass
2
3
  module SCSS
3
4
  # A module containing regular expressions used
@@ -63,9 +64,9 @@ module Sass
63
64
  STRING1 = /\"((?:[^\n\r\f\\"]|\\#{NL}|#{ESCAPE})*)\"/
64
65
  STRING2 = /\'((?:[^\n\r\f\\']|\\#{NL}|#{ESCAPE})*)\'/
65
66
 
66
- IDENT = /-?#{NMSTART}#{NMCHAR}*/
67
+ IDENT = /-*#{NMSTART}#{NMCHAR}*/
67
68
  NAME = /#{NMCHAR}+/
68
- NUM = /[0-9]+|[0-9]*\.[0-9]+/
69
+ NUM = //
69
70
  STRING = /#{STRING1}|#{STRING2}/
70
71
  URLCHAR = /[#%&*-~]|#{NONASCII}|#{ESCAPE}/
71
72
  URL = /(#{URLCHAR}*)/
@@ -95,7 +96,9 @@ module Sass
95
96
 
96
97
  IMPORTANT = /!#{W}important/i
97
98
 
98
- NUMBER = /#{NUM}(?:#{IDENT}|%)?/
99
+ UNITLESS_NUMBER = /(?:[0-9]+|[0-9]*\.[0-9]+)(?:[eE][+-]?\d+)?/
100
+ NUMBER = /#{UNITLESS_NUMBER}(?:#{IDENT}|%)?/
101
+ PERCENTAGE = /#{UNITLESS_NUMBER}%/
99
102
 
100
103
  URI = /url\(#{W}(?:#{STRING}|#{URL})#{W}\)/i
101
104
  FUNCTION = /#{IDENT}\(/
@@ -118,10 +121,16 @@ module Sass
118
121
  INTERP_START = /#\{/
119
122
  ANY = /:(-[-\w]+-)?any\(/i
120
123
  OPTIONAL = /!#{W}optional/i
124
+ IDENT_START = /-|#{NMSTART}/
125
+
126
+ # A unit is like an IDENT, but disallows a hyphen followed by a digit.
127
+ # This allows "1px-2px" to be interpreted as subtraction rather than "1"
128
+ # with the unit "px-2px". It also allows "%".
129
+ UNIT = /-?#{NMSTART}(?:[a-zA-Z0-9_]|#{NONASCII}|#{ESCAPE}|-(?!\d))*|%/
121
130
 
122
131
  IDENT_HYPHEN_INTERP = /-(#\{)/
123
- STRING1_NOINTERP = /\"((?:[^\n\r\f\\"#]|#(?!\{)|\\#{NL}|#{ESCAPE})*)\"/
124
- STRING2_NOINTERP = /\'((?:[^\n\r\f\\'#]|#(?!\{)|\\#{NL}|#{ESCAPE})*)\'/
132
+ STRING1_NOINTERP = /\"((?:[^\n\r\f\\"#]|#(?!\{)|#{ESCAPE})*)\"/
133
+ STRING2_NOINTERP = /\'((?:[^\n\r\f\\'#]|#(?!\{)|#{ESCAPE})*)\'/
125
134
  STRING_NOINTERP = /#{STRING1_NOINTERP}|#{STRING2_NOINTERP}/
126
135
 
127
136
  STATIC_COMPONENT = /#{IDENT}|#{STRING_NOINTERP}|#{HEXCOLOR}|[+-]?#{NUMBER}|\!important/i
@@ -41,6 +41,24 @@ module Sass
41
41
  return type, directives
42
42
  end
43
43
 
44
+ def parse_keyframes_selector
45
+ init_scanner!
46
+ sel = expr!(:keyframes_selector)
47
+ expected("keyframes selector") unless @scanner.eos?
48
+ sel
49
+ end
50
+
51
+ # @see Parser#initialize
52
+ # @param allow_parent_ref [Boolean] Whether to allow the
53
+ # parent-reference selector, `&`, when parsing the document.
54
+ # @comment
55
+ # rubocop:disable ParameterLists
56
+ def initialize(str, filename, importer, line = 1, offset = 1, allow_parent_ref = true)
57
+ # rubocop:enable ParameterLists
58
+ super(str, filename, importer, line, offset)
59
+ @allow_parent_ref = allow_parent_ref
60
+ end
61
+
44
62
  private
45
63
 
46
64
  def moz_document_function
@@ -52,7 +70,7 @@ module Sass
52
70
 
53
71
  def variable; nil; end
54
72
  def script_value; nil; end
55
- def interpolation; nil; end
73
+ def interpolation(warn_for_color = false); nil; end
56
74
  def var_expr; nil; end
57
75
  def interp_string; (s = tok(STRING)) && [s]; end
58
76
  def interp_uri; (s = tok(URI)) && [s]; end
@@ -64,6 +82,285 @@ module Sass
64
82
  super
65
83
  end
66
84
 
85
+ def selector_comma_sequence
86
+ sel = selector
87
+ return unless sel
88
+ selectors = [sel]
89
+ ws = ''
90
+ while tok(/,/)
91
+ ws << str {ss}
92
+ if (sel = selector)
93
+ selectors << sel
94
+ if ws.include?("\n")
95
+ selectors[-1] = Selector::Sequence.new(["\n"] + selectors.last.members)
96
+ end
97
+ ws = ''
98
+ end
99
+ end
100
+ Selector::CommaSequence.new(selectors)
101
+ end
102
+
103
+ def selector_string
104
+ sel = selector
105
+ return unless sel
106
+ sel.to_s
107
+ end
108
+
109
+ def selector
110
+ start_pos = source_position
111
+ # The combinator here allows the "> E" hack
112
+ val = combinator || simple_selector_sequence
113
+ return unless val
114
+ nl = str {ss}.include?("\n")
115
+ res = []
116
+ res << val
117
+ res << "\n" if nl
118
+
119
+ while (val = combinator || simple_selector_sequence)
120
+ res << val
121
+ res << "\n" if str {ss}.include?("\n")
122
+ end
123
+ seq = Selector::Sequence.new(res.compact)
124
+
125
+ if seq.members.any? {|sseq| sseq.is_a?(Selector::SimpleSequence) && sseq.subject?}
126
+ location = " of #{@filename}" if @filename
127
+ Sass::Util.sass_warn <<MESSAGE
128
+ DEPRECATION WARNING on line #{start_pos.line}, column #{start_pos.offset}#{location}:
129
+ The subject selector operator "!" is deprecated and will be removed in a future release.
130
+ This operator has been replaced by ":has()" in the CSS spec.
131
+ For example: #{seq.subjectless}
132
+ MESSAGE
133
+ end
134
+
135
+ seq
136
+ end
137
+
138
+ def combinator
139
+ tok(PLUS) || tok(GREATER) || tok(TILDE) || reference_combinator
140
+ end
141
+
142
+ def reference_combinator
143
+ return unless tok(/\//)
144
+ res = '/'
145
+ ns, name = expr!(:qualified_name)
146
+ res << ns << '|' if ns
147
+ res << name << tok!(/\//)
148
+ res
149
+ end
150
+
151
+ def simple_selector_sequence
152
+ start_pos = source_position
153
+ e = element_name || id_selector || class_selector || placeholder_selector || attrib ||
154
+ pseudo || parent_selector
155
+ return unless e
156
+ res = [e]
157
+
158
+ # The tok(/\*/) allows the "E*" hack
159
+ while (v = id_selector || class_selector || placeholder_selector ||
160
+ attrib || pseudo || (tok(/\*/) && Selector::Universal.new(nil)))
161
+ res << v
162
+ end
163
+
164
+ pos = @scanner.pos
165
+ line = @line
166
+ if (sel = str? {simple_selector_sequence})
167
+ @scanner.pos = pos
168
+ @line = line
169
+ begin
170
+ # If we see "*E", don't force a throw because this could be the
171
+ # "*prop: val" hack.
172
+ expected('"{"') if res.length == 1 && res[0].is_a?(Selector::Universal)
173
+ throw_error {expected('"{"')}
174
+ rescue Sass::SyntaxError => e
175
+ e.message << "\n\n\"#{sel}\" may only be used at the beginning of a compound selector."
176
+ raise e
177
+ end
178
+ end
179
+
180
+ Selector::SimpleSequence.new(res, tok(/!/), range(start_pos))
181
+ end
182
+
183
+ def parent_selector
184
+ return unless @allow_parent_ref && tok(/&/)
185
+ Selector::Parent.new(tok(NAME))
186
+ end
187
+
188
+ def class_selector
189
+ return unless tok(/\./)
190
+ @expected = "class name"
191
+ Selector::Class.new(tok!(IDENT))
192
+ end
193
+
194
+ def id_selector
195
+ return unless tok(/#(?!\{)/)
196
+ @expected = "id name"
197
+ Selector::Id.new(tok!(NAME))
198
+ end
199
+
200
+ def placeholder_selector
201
+ return unless tok(/%/)
202
+ @expected = "placeholder name"
203
+ Selector::Placeholder.new(tok!(IDENT))
204
+ end
205
+
206
+ def element_name
207
+ ns, name = Sass::Util.destructure(qualified_name(:allow_star_name))
208
+ return unless ns || name
209
+
210
+ if name == '*'
211
+ Selector::Universal.new(ns)
212
+ else
213
+ Selector::Element.new(name, ns)
214
+ end
215
+ end
216
+
217
+ def qualified_name(allow_star_name = false)
218
+ name = tok(IDENT) || tok(/\*/) || (tok?(/\|/) && "")
219
+ return unless name
220
+ return nil, name unless tok(/\|/)
221
+
222
+ return name, tok!(IDENT) unless allow_star_name
223
+ @expected = "identifier or *"
224
+ return name, tok(IDENT) || tok!(/\*/)
225
+ end
226
+
227
+ def attrib
228
+ return unless tok(/\[/)
229
+ ss
230
+ ns, name = attrib_name!
231
+ ss
232
+
233
+ op = tok(/=/) ||
234
+ tok(INCLUDES) ||
235
+ tok(DASHMATCH) ||
236
+ tok(PREFIXMATCH) ||
237
+ tok(SUFFIXMATCH) ||
238
+ tok(SUBSTRINGMATCH)
239
+ if op
240
+ @expected = "identifier or string"
241
+ ss
242
+ val = tok(IDENT) || tok!(STRING)
243
+ ss
244
+ end
245
+ flags = tok(IDENT) || tok(STRING)
246
+ tok!(/\]/)
247
+
248
+ Selector::Attribute.new(name, ns, op, val, flags)
249
+ end
250
+
251
+ def attrib_name!
252
+ if (name_or_ns = tok(IDENT))
253
+ # E, E|E
254
+ if tok(/\|(?!=)/)
255
+ ns = name_or_ns
256
+ name = tok(IDENT)
257
+ else
258
+ name = name_or_ns
259
+ end
260
+ else
261
+ # *|E or |E
262
+ ns = tok(/\*/) || ""
263
+ tok!(/\|/)
264
+ name = tok!(IDENT)
265
+ end
266
+ return ns, name
267
+ end
268
+
269
+ SELECTOR_PSEUDO_CLASSES = %w[not matches current any has host host-context].to_set
270
+
271
+ PREFIXED_SELECTOR_PSEUDO_CLASSES = %w[nth-child nth-last-child].to_set
272
+
273
+ def pseudo
274
+ s = tok(/::?/)
275
+ return unless s
276
+ @expected = "pseudoclass or pseudoelement"
277
+ name = tok!(IDENT)
278
+ if tok(/\(/)
279
+ ss
280
+ deprefixed = deprefix(name)
281
+ if s == ':' && SELECTOR_PSEUDO_CLASSES.include?(deprefixed)
282
+ sel = selector_comma_sequence
283
+ elsif s == ':' && PREFIXED_SELECTOR_PSEUDO_CLASSES.include?(deprefixed)
284
+ arg, sel = prefixed_selector_pseudo
285
+ else
286
+ arg = expr!(:pseudo_args)
287
+ end
288
+
289
+ tok!(/\)/)
290
+ end
291
+ Selector::Pseudo.new(s == ':' ? :class : :element, name, arg, sel)
292
+ end
293
+
294
+ def pseudo_args
295
+ arg = expr!(:pseudo_expr)
296
+ while tok(/,/)
297
+ arg << ',' << str {ss}
298
+ arg.concat expr!(:pseudo_expr)
299
+ end
300
+ arg
301
+ end
302
+
303
+ def pseudo_expr
304
+ res = pseudo_expr_token
305
+ return unless res
306
+ res << str {ss}
307
+ while (e = pseudo_expr_token)
308
+ res << e << str {ss}
309
+ end
310
+ res
311
+ end
312
+
313
+ def pseudo_expr_token
314
+ tok(PLUS) || tok(/[-*]/) || tok(NUMBER) || tok(STRING) || tok(IDENT)
315
+ end
316
+
317
+ def prefixed_selector_pseudo
318
+ prefix = str do
319
+ expr = str {expr!(:a_n_plus_b)}
320
+ ss
321
+ return expr, nil unless tok(/of/)
322
+ ss
323
+ end
324
+ return prefix, expr!(:selector_comma_sequence)
325
+ end
326
+
327
+ def a_n_plus_b
328
+ if (parity = tok(/even|odd/i))
329
+ return parity
330
+ end
331
+
332
+ if tok(/[+-]?[0-9]+/)
333
+ ss
334
+ return true unless tok(/n/)
335
+ else
336
+ return unless tok(/[+-]?n/i)
337
+ end
338
+ ss
339
+
340
+ return true unless tok(/[+-]/)
341
+ ss
342
+ @expected = "number"
343
+ tok!(/[0-9]+/)
344
+ true
345
+ end
346
+
347
+ def keyframes_selector
348
+ ss
349
+ str do
350
+ return unless keyframes_selector_component
351
+ ss
352
+ while tok(/,/)
353
+ ss
354
+ expr!(:keyframes_selector_component)
355
+ ss
356
+ end
357
+ end
358
+ end
359
+
360
+ def keyframes_selector_component
361
+ tok(/from|to/i) || tok(PERCENTAGE)
362
+ end
363
+
67
364
  @sass_script_parser = Class.new(Sass::Script::CssParser)
68
365
  @sass_script_parser.send(:include, ScriptParser)
69
366
  end
@@ -1,6 +1,7 @@
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
 
@@ -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