sass 3.5.0.pre.rc.1 → 3.5.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 (104) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -1
  3. data/README.md +1 -1
  4. data/Rakefile +40 -11
  5. data/VERSION +1 -1
  6. data/VERSION_DATE +1 -1
  7. data/extra/sass-spec-ref.sh +32 -0
  8. data/lib/sass.rb +3 -3
  9. data/lib/sass/css.rb +1 -1
  10. data/lib/sass/deprecation.rb +55 -0
  11. data/lib/sass/engine.rb +16 -12
  12. data/lib/sass/environment.rb +1 -1
  13. data/lib/sass/error.rb +3 -3
  14. data/lib/sass/exec/base.rb +1 -1
  15. data/lib/sass/plugin.rb +1 -1
  16. data/lib/sass/plugin/compiler.rb +1 -1
  17. data/lib/sass/plugin/configuration.rb +2 -2
  18. data/lib/sass/plugin/rack.rb +3 -3
  19. data/lib/sass/plugin/staleness_checker.rb +3 -3
  20. data/lib/sass/script.rb +3 -3
  21. data/lib/sass/script/functions.rb +23 -22
  22. data/lib/sass/script/lexer.rb +17 -8
  23. data/lib/sass/script/parser.rb +8 -7
  24. data/lib/sass/script/tree/node.rb +2 -2
  25. data/lib/sass/script/tree/operation.rb +43 -16
  26. data/lib/sass/script/value/base.rb +3 -3
  27. data/lib/sass/script/value/color.rb +15 -10
  28. data/lib/sass/script/value/helpers.rb +13 -2
  29. data/lib/sass/script/value/list.rb +2 -2
  30. data/lib/sass/script/value/number.rb +4 -4
  31. data/lib/sass/script/value/string.rb +5 -12
  32. data/lib/sass/scss/parser.rb +7 -4
  33. data/lib/sass/scss/rx.rb +1 -1
  34. data/lib/sass/scss/static_parser.rb +12 -24
  35. data/lib/sass/selector/abstract_sequence.rb +12 -11
  36. data/lib/sass/selector/comma_sequence.rb +18 -3
  37. data/lib/sass/selector/pseudo.rb +15 -2
  38. data/lib/sass/selector/sequence.rb +9 -7
  39. data/lib/sass/selector/simple.rb +5 -4
  40. data/lib/sass/selector/simple_sequence.rb +7 -3
  41. data/lib/sass/shared.rb +5 -3
  42. data/lib/sass/source/map.rb +2 -2
  43. data/lib/sass/source/position.rb +4 -4
  44. data/lib/sass/tree/comment_node.rb +1 -1
  45. data/lib/sass/tree/node.rb +3 -3
  46. data/lib/sass/tree/prop_node.rb +1 -1
  47. data/lib/sass/tree/rule_node.rb +15 -6
  48. data/lib/sass/tree/visitors/cssize.rb +3 -5
  49. data/lib/sass/tree/visitors/deep_copy.rb +1 -1
  50. data/lib/sass/tree/visitors/extend.rb +2 -8
  51. data/lib/sass/tree/visitors/perform.rb +3 -2
  52. data/lib/sass/tree/visitors/to_css.rb +3 -3
  53. data/lib/sass/util.rb +32 -5
  54. data/lib/sass/version.rb +2 -4
  55. data/test/sass/cache_test.rb +0 -1
  56. data/test/sass/callbacks_test.rb +0 -1
  57. data/test/sass/compiler_test.rb +0 -1
  58. data/test/sass/conversion_test.rb +3 -4
  59. data/test/sass/css2sass_test.rb +1 -2
  60. data/test/sass/css_variable_test.rb +0 -1
  61. data/test/sass/encoding_test.rb +0 -1
  62. data/test/sass/engine_test.rb +63 -60
  63. data/test/sass/exec_test.rb +0 -1
  64. data/test/sass/extend_test.rb +40 -81
  65. data/test/sass/functions_test.rb +8 -6
  66. data/test/sass/importer_test.rb +0 -1
  67. data/test/sass/logger_test.rb +0 -1
  68. data/test/sass/more_templates/more1.sass +10 -10
  69. data/test/sass/more_templates/more_import.sass +2 -2
  70. data/test/sass/plugin_test.rb +3 -4
  71. data/test/sass/results/script.css +1 -1
  72. data/test/sass/results/units.css +2 -2
  73. data/test/sass/script_conversion_test.rb +1 -2
  74. data/test/sass/script_test.rb +55 -47
  75. data/test/sass/scss/css_test.rb +2 -3
  76. data/test/sass/scss/rx_test.rb +0 -1
  77. data/test/sass/scss/scss_test.rb +26 -12
  78. data/test/sass/source_map_test.rb +13 -14
  79. data/test/sass/superselector_test.rb +0 -1
  80. data/test/sass/templates/_partial.sass +1 -1
  81. data/test/sass/templates/basic.sass +10 -10
  82. data/test/sass/templates/bork1.sass +1 -1
  83. data/test/sass/templates/bork5.sass +1 -1
  84. data/test/sass/templates/compact.sass +10 -10
  85. data/test/sass/templates/complex.sass +187 -187
  86. data/test/sass/templates/compressed.sass +10 -10
  87. data/test/sass/templates/expanded.sass +10 -10
  88. data/test/sass/templates/import.sass +2 -2
  89. data/test/sass/templates/importee.sass +3 -3
  90. data/test/sass/templates/mixins.sass +22 -22
  91. data/test/sass/templates/multiline.sass +4 -4
  92. data/test/sass/templates/nested.sass +13 -13
  93. data/test/sass/templates/parent_ref.sass +12 -12
  94. data/test/sass/templates/script.sass +70 -70
  95. data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +1 -1
  96. data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +2 -2
  97. data/test/sass/templates/subdir/subdir.sass +3 -3
  98. data/test/sass/templates/units.sass +10 -10
  99. data/test/sass/util/multibyte_string_scanner_test.rb +10 -3
  100. data/test/sass/util/normalized_map_test.rb +0 -1
  101. data/test/sass/util/subset_map_test.rb +0 -1
  102. data/test/sass/util_test.rb +4 -3
  103. data/test/sass/value_helpers_test.rb +0 -1
  104. metadata +15 -13
@@ -205,14 +205,25 @@ module Sass::Script::Value
205
205
  raise ArgumentError.new(err)
206
206
  end
207
207
 
208
- # Returns true when the literal is a string containing a calc()
208
+ # Returns true when the literal is a string containing a calc().
209
+ #
210
+ # Use \{#special_number?} in preference to this.
209
211
  #
210
212
  # @param literal [Sass::Script::Value::Base] The value to check
211
- # @return boolean
213
+ # @return Boolean
212
214
  def calc?(literal)
213
215
  literal.is_a?(Sass::Script::Value::String) && literal.value =~ /calc\(/
214
216
  end
215
217
 
218
+ # Returns whether the literal is a special CSS value that may evaluate to a
219
+ # number, such as `calc()` or `var()`.
220
+ #
221
+ # @param literal [Sass::Script::Value::Base] The value to check
222
+ # @return Boolean
223
+ def special_number?(literal)
224
+ literal.is_a?(Sass::Script::Value::String) && literal.value =~ /(calc|var)\(/
225
+ end
226
+
216
227
  private
217
228
 
218
229
  # Converts a user-provided selector into string form or throws an
@@ -40,11 +40,11 @@ module Sass::Script::Value
40
40
  def eq(other)
41
41
  Sass::Script::Value::Bool.new(
42
42
  other.is_a?(List) && value == other.value &&
43
- separator == other.separator)
43
+ separator == other.separator && bracketed == other.bracketed)
44
44
  end
45
45
 
46
46
  def hash
47
- @hash ||= [value, separator].hash
47
+ @hash ||= [value, separator, bracketed].hash
48
48
  end
49
49
 
50
50
  # @see Value#to_s
@@ -34,7 +34,7 @@ module Sass::Script::Value
34
34
  attr_accessor :original
35
35
 
36
36
  def self.precision
37
- Thread.current[:sass_numeric_precision] || Thread.main[:sass_numeric_precision] || 5
37
+ Thread.current[:sass_numeric_precision] || Thread.main[:sass_numeric_precision] || 10
38
38
  end
39
39
 
40
40
  # Sets the number of digits of precision
@@ -306,7 +306,7 @@ module Sass::Script::Value
306
306
  end
307
307
  alias_method :to_sass, :inspect
308
308
 
309
- # @return [Fixnum] The integer value of the number
309
+ # @return [Integer] The integer value of the number
310
310
  # @raise [Sass::SyntaxError] if the number isn't an integer
311
311
  def to_i
312
312
  super unless int?
@@ -510,8 +510,8 @@ module Sass::Script::Value
510
510
  },
511
511
  {
512
512
  'dpi' => Rational(1),
513
- 'dpcm' => Rational(1, 2.54),
514
- 'dppx' => Rational(1, 96)
513
+ 'dpcm' => Rational(254, 100),
514
+ 'dppx' => Rational(96)
515
515
  }
516
516
  ]
517
517
 
@@ -2,6 +2,8 @@
2
2
  module Sass::Script::Value
3
3
  # A SassScript object representing a CSS string *or* a CSS identifier.
4
4
  class String < Base
5
+ @@interpolation_deprecation = Sass::Deprecation.new
6
+
5
7
  # The Ruby value of the string.
6
8
  #
7
9
  # @return [String]
@@ -121,18 +123,9 @@ module Sass::Script::Value
121
123
  def check_deprecated_interp
122
124
  return unless @deprecated_interp_equivalent
123
125
 
124
- # rubocop:disable GlobalVars
125
- $_sass_deprecated_interp_warnings ||= Set.new
126
- key = [source_range.start_pos.line, source_range.file, @deprecated_interp_equivalent]
127
- return if $_sass_deprecated_interp_warnings.include?(key)
128
- $_sass_deprecated_interp_warnings << key
129
- # rubocop:enable GlobalVars
130
-
131
- location = "on line #{source_range.start_pos.line}"
132
- location << " of #{source_range.file}" if source_range.file
133
- Sass::Util.sass_warn <<WARNING
134
- DEPRECATION WARNING #{location}: \#{} interpolation near operators will be simplified
135
- in a future version of Sass. To preserve the current behavior, use quotes:
126
+ @@interpolation_deprecation.warn(source_range.file, source_range.start_pos.line, <<WARNING)
127
+ \#{} interpolation near operators will be simplified in a future version of Sass.
128
+ To preserve the current behavior, use quotes:
136
129
 
137
130
  #{@deprecated_interp_equivalent}
138
131
  WARNING
@@ -16,9 +16,9 @@ module Sass
16
16
  # warnings and source maps.
17
17
  # @param importer [Sass::Importers::Base] The importer used to import the
18
18
  # file being parsed. Used for source maps.
19
- # @param line [Fixnum] The 1-based line on which the source string appeared,
19
+ # @param line [Integer] The 1-based line on which the source string appeared,
20
20
  # if it's part of another document.
21
- # @param offset [Fixnum] The 1-based character (not byte) offset in the line on
21
+ # @param offset [Integer] The 1-based character (not byte) offset in the line on
22
22
  # which the source string starts. Used for error reporting and sourcemap
23
23
  # building.
24
24
  def initialize(str, filename, importer, line = 1, offset = 1)
@@ -863,6 +863,9 @@ module Sass
863
863
  |
864
864
  (?!url\()
865
865
  [^"'/\#!;\{\}] # "
866
+ |
867
+ # interp_uri will handle most url() calls, but not ones that take strings
868
+ url\(#{W}(?=")
866
869
  |
867
870
  /(?![/*])
868
871
  |
@@ -1090,7 +1093,7 @@ module Sass
1090
1093
  end
1091
1094
 
1092
1095
  def str
1093
- @strs.push ""
1096
+ @strs.push String.new("")
1094
1097
  yield
1095
1098
  @strs.last
1096
1099
  ensure
@@ -1152,7 +1155,7 @@ module Sass
1152
1155
  :media_expr => "media expression (e.g. (min-device-width: 800px))",
1153
1156
  :at_root_query => "@at-root query (e.g. (without: media))",
1154
1157
  :at_root_directive_list => '* or identifier',
1155
- :pseudo_args => "expression (e.g. fr, 2n+1)",
1158
+ :declaration_value => "expression (e.g. fr, 2n+1)",
1156
1159
  :interp_ident => "identifier",
1157
1160
  :qualified_name => "identifier",
1158
1161
  :expr => "expression (e.g. 1px, bold)",
@@ -40,7 +40,7 @@ module Sass
40
40
  # escaping all significant characters.
41
41
  #
42
42
  # @param str [String] The text of the regexp
43
- # @param flags [Fixnum] Flags for the created regular expression
43
+ # @param flags [Integer] Flags for the created regular expression
44
44
  # @return [Regexp]
45
45
  # @private
46
46
  def self.quote(str, flags = 0)
@@ -144,6 +144,13 @@ MESSAGE
144
144
  ns, name = expr!(:qualified_name)
145
145
  res << ns << '|' if ns
146
146
  res << name << tok!(%r{/})
147
+
148
+ location = " of #{@filename}" if @filename
149
+ Sass::Util.sass_warn <<MESSAGE
150
+ DEPRECATION WARNING on line #{@line}, column #{@offset}#{location}:
151
+ The reference combinator #{res} is deprecated and will be removed in a future release.
152
+ MESSAGE
153
+
147
154
  res
148
155
  end
149
156
 
@@ -269,6 +276,8 @@ MESSAGE
269
276
 
270
277
  PREFIXED_SELECTOR_PSEUDO_CLASSES = %w(nth-child nth-last-child).to_set
271
278
 
279
+ SELECTOR_PSEUDO_ELEMENTS = %w(slotted).to_set
280
+
272
281
  def pseudo
273
282
  s = tok(/::?/)
274
283
  return unless s
@@ -281,8 +290,10 @@ MESSAGE
281
290
  sel = selector_comma_sequence
282
291
  elsif s == ':' && PREFIXED_SELECTOR_PSEUDO_CLASSES.include?(deprefixed)
283
292
  arg, sel = prefixed_selector_pseudo
293
+ elsif s == '::' && SELECTOR_PSEUDO_ELEMENTS.include?(deprefixed)
294
+ sel = selector_comma_sequence
284
295
  else
285
- arg = expr!(:pseudo_args)
296
+ arg = expr!(:declaration_value).join
286
297
  end
287
298
 
288
299
  tok!(/\)/)
@@ -290,29 +301,6 @@ MESSAGE
290
301
  Selector::Pseudo.new(s == ':' ? :class : :element, name, arg, sel)
291
302
  end
292
303
 
293
- def pseudo_args
294
- arg = expr!(:pseudo_expr)
295
- while tok(/,/)
296
- arg << ',' << str {ss}
297
- arg.concat expr!(:pseudo_expr)
298
- end
299
- arg
300
- end
301
-
302
- def pseudo_expr
303
- res = pseudo_expr_token
304
- return unless res
305
- res << str {ss}
306
- while (e = pseudo_expr_token)
307
- res << e << str {ss}
308
- end
309
- res
310
- end
311
-
312
- def pseudo_expr_token
313
- tok(PLUS) || tok(/[-*]/) || tok(NUMBER) || tok(STRING) || tok(IDENT)
314
- end
315
-
316
304
  def prefixed_selector_pseudo
317
305
  prefix = str do
318
306
  expr = str {expr!(:a_n_plus_b)}
@@ -8,7 +8,7 @@ module Sass
8
8
  class AbstractSequence
9
9
  # The line of the Sass template on which this selector was declared.
10
10
  #
11
- # @return [Fixnum]
11
+ # @return [Integer]
12
12
  attr_reader :line
13
13
 
14
14
  # The name of the file in which this selector was declared.
@@ -19,8 +19,8 @@ module Sass
19
19
  # Sets the line of the Sass template on which this selector was declared.
20
20
  # This also sets the line for all child selectors.
21
21
  #
22
- # @param line [Fixnum]
23
- # @return [Fixnum]
22
+ # @param line [Integer]
23
+ # @return [Integer]
24
24
  def line=(line)
25
25
  members.each {|m| m.line = line}
26
26
  @line = line
@@ -42,7 +42,7 @@ module Sass
42
42
  # Subclasses should define `#_hash` rather than overriding this method,
43
43
  # which automatically handles memoizing the result.
44
44
  #
45
- # @return [Fixnum]
45
+ # @return [Integer]
46
46
  def hash
47
47
  @_hash ||= _hash
48
48
  end
@@ -59,12 +59,11 @@ module Sass
59
59
  end
60
60
  alias_method :==, :eql?
61
61
 
62
- # Whether or not this selector sequence contains a placeholder selector.
63
- # Checks recursively.
64
- def has_placeholder?
65
- @has_placeholder ||= members.any? do |m|
66
- next m.has_placeholder? if m.is_a?(AbstractSequence)
67
- next m.selector && m.selector.has_placeholder? if m.is_a?(Pseudo)
62
+ # Whether or not this selector should be hidden due to containing a
63
+ # placeholder.
64
+ def invisible?
65
+ @invisible ||= members.any? do |m|
66
+ next m.invisible? if m.is_a?(AbstractSequence) || m.is_a?(Pseudo)
68
67
  m.is_a?(Placeholder)
69
68
  end
70
69
  end
@@ -73,6 +72,8 @@ module Sass
73
72
  #
74
73
  # @param opts [Hash] rendering options.
75
74
  # @option opts [Symbol] :style The css rendering style.
75
+ # @option placeholders [Boolean] :placeholders
76
+ # Whether to include placeholder selectors. Defaults to `true`.
76
77
  # @return [String]
77
78
  def to_s(opts = {})
78
79
  Sass::Util.abstract(self)
@@ -83,7 +84,7 @@ module Sass
83
84
  # The base is given by {Sass::Selector::SPECIFICITY_BASE}. This can be a
84
85
  # number or a range representing possible specificities.
85
86
  #
86
- # @return [Fixnum, Range]
87
+ # @return [Integer, Range]
87
88
  def specificity
88
89
  _specificity(members)
89
90
  end
@@ -2,6 +2,8 @@ module Sass
2
2
  module Selector
3
3
  # A comma-separated sequence of selectors.
4
4
  class CommaSequence < AbstractSequence
5
+ @@compound_extend_deprecation = Sass::Deprecation.new
6
+
5
7
  # The comma-separated selector sequences
6
8
  # represented by this class.
7
9
  #
@@ -96,8 +98,11 @@ module Sass
96
98
  # The node that caused this extension.
97
99
  # @param parent_directives [Array<Sass::Tree::DirectiveNode>]
98
100
  # The parent directives containing `extend_node`.
101
+ # @param allow_compound_target [Boolean]
102
+ # Whether `extendee` is allowed to contain compound selectors.
99
103
  # @raise [Sass::SyntaxError] if this extension is invalid.
100
- def populate_extends(extends, extendee, extend_node = nil, parent_directives = [])
104
+ def populate_extends(extends, extendee, extend_node = nil, parent_directives = [],
105
+ allow_compound_target = false)
101
106
  extendee.members.each do |seq|
102
107
  if seq.members.size > 1
103
108
  raise Sass::SyntaxError.new("Can't extend #{seq}: can't extend nested selectors")
@@ -111,13 +116,20 @@ module Sass
111
116
  end
112
117
 
113
118
  sel = sseq.members
119
+ if !allow_compound_target && sel.length > 1
120
+ @@compound_extend_deprecation.warn(sseq.filename, sseq.line, <<WARNING)
121
+ Extending a compound selector, #{sseq}, is deprecated and will not be supported in a future release.
122
+ See https://github.com/sass/sass/issues/1599 for details.
123
+ WARNING
124
+ end
125
+
114
126
  members.each do |member|
115
127
  unless member.members.last.is_a?(Sass::Selector::SimpleSequence)
116
128
  raise Sass::SyntaxError.new("#{member} can't extend: invalid selector")
117
129
  end
118
130
 
119
131
  extends[sel] = Sass::Tree::Visitors::Cssize::Extend.new(
120
- member, sel, extend_node, parent_directives, :not_found)
132
+ member, sel, extend_node, parent_directives, false)
121
133
  end
122
134
  end
123
135
  end
@@ -160,7 +172,10 @@ module Sass
160
172
 
161
173
  # @see AbstractSequence#to_s
162
174
  def to_s(opts = {})
163
- @members.map {|m| m.to_s(opts)}.
175
+ @members.map do |m|
176
+ next if opts[:placeholder] == false && m.invisible?
177
+ m.to_s(opts)
178
+ end.compact.
164
179
  join(opts[:style] == :compressed ? "," : ", ").
165
180
  gsub(", \n", ",\n")
166
181
  end
@@ -1,3 +1,4 @@
1
+ # coding: utf-8
1
2
  module Sass
2
3
  module Selector
3
4
  # A pseudoclass (e.g. `:visited`) or pseudoelement (e.g. `::first-line`)
@@ -52,6 +53,14 @@ module Sass
52
53
  type == :class && normalized_name == 'root'
53
54
  end
54
55
 
56
+ # Whether or not this selector should be hidden due to containing a
57
+ # placeholder.
58
+ def invisible?
59
+ # :not() is a special case—if you eliminate all the placeholders from
60
+ # it, it should match anything.
61
+ name != 'not' && @selector && @selector.members.all? {|s| s.invisible?}
62
+ end
63
+
55
64
  # Returns a copy of this with \{#selector} set to \{#new\_selector}.
56
65
  #
57
66
  # @param new_selector [CommaSequence]
@@ -81,7 +90,7 @@ module Sass
81
90
  # more complex cases that likely aren't worth the pain.
82
91
  next [] unless sel.name == name && sel.arg == arg
83
92
  sel.selector.members
84
- when 'has', 'host', 'host-context'
93
+ when 'has', 'host', 'host-context', 'slotted'
85
94
  # We can't expand nested selectors here, because each layer adds an
86
95
  # additional layer of semantics. For example, `:has(:has(img))`
87
96
  # doesn't match `<div><img></div>` but `:has(img)` does.
@@ -118,6 +127,10 @@ module Sass
118
127
 
119
128
  # @see Selector#to_s
120
129
  def to_s(opts = {})
130
+ # :not() is a special case, because :not(<nothing>) should match
131
+ # everything.
132
+ return '' if name == 'not' && @selector && @selector.members.all? {|m| m.invisible?}
133
+
121
134
  res = (syntactic_type == :class ? ":" : "::") + @name
122
135
  if @arg || @selector
123
136
  res << "("
@@ -165,7 +178,7 @@ module Sass
165
178
  their_seq = Sequence.new(parents + [their_sseq])
166
179
  our_seq.superselector?(their_seq)
167
180
  end
168
- when 'has', 'host', 'host-context'
181
+ when 'has', 'host', 'host-context', 'slotted'
169
182
  # Like :matches, :has (et al) can be a superselector of another
170
183
  # selector if its constituent selectors are a superset of those of
171
184
  # another :has in the other selector. However, the :matches other case
@@ -6,8 +6,8 @@ module Sass
6
6
  # Sets the line of the Sass template on which this selector was declared.
7
7
  # This also sets the line for all child selectors.
8
8
  #
9
- # @param line [Fixnum]
10
- # @return [Fixnum]
9
+ # @param line [Integer]
10
+ # @return [Integer]
11
11
  def line=(line)
12
12
  members.each {|m| m.line = line if m.is_a?(SimpleSequence)}
13
13
  @line = line
@@ -66,10 +66,14 @@ module Sass
66
66
  next [sseq_or_op] unless sseq_or_op.is_a?(SimpleSequence)
67
67
  sseq_or_op.resolve_parent_refs(super_cseq).members
68
68
  end).map do |path|
69
- Sequence.new(path.map do |seq_or_op|
69
+ path_members = path.map do |seq_or_op|
70
70
  next seq_or_op unless seq_or_op.is_a?(Sequence)
71
71
  seq_or_op.members
72
- end.flatten)
72
+ end
73
+ if path_members.length == 2 && path_members[1][0] == "\n"
74
+ path_members[0].unshift path_members[1].shift
75
+ end
76
+ Sequence.new(path_members.flatten)
73
77
  end)
74
78
  end
75
79
 
@@ -115,7 +119,7 @@ module Sass
115
119
  # specificity greater than or equal to that of the original selector.
116
120
  # In order to ensure that, we record the original selector's
117
121
  # (`extended.first`) original specificity.
118
- extended.first.add_sources!([self]) if original && !has_placeholder?
122
+ extended.first.add_sources!([self]) if original && !invisible?
119
123
 
120
124
  extended.map {|seq| seq.members}
121
125
  end
@@ -624,8 +628,6 @@ module Sass
624
628
  other.members.reject {|m| m == "\n"}.eql?(members.reject {|m| m == "\n"})
625
629
  end
626
630
 
627
- private
628
-
629
631
  def path_has_two_subjects?(path)
630
632
  subject = false
631
633
  path.each do |sseq_or_op|
@@ -5,7 +5,7 @@ module Sass
5
5
  class Simple
6
6
  # The line of the Sass template on which this selector was declared.
7
7
  #
8
- # @return [Fixnum]
8
+ # @return [Integer]
9
9
  attr_accessor :line
10
10
 
11
11
  # The name of the file in which this selector was declared,
@@ -44,7 +44,7 @@ module Sass
44
44
  # so if that contains information irrelevant to the identity of the selector,
45
45
  # this should be overridden.
46
46
  #
47
- # @return [Fixnum]
47
+ # @return [Integer]
48
48
  def hash
49
49
  @_hash ||= equality_key.hash
50
50
  end
@@ -80,6 +80,7 @@ module Sass
80
80
  # by the time extension and unification happen,
81
81
  # this exception will only ever be raised as a result of programmer error
82
82
  def unify(sels)
83
+ return sels.first.unify([self]) if sels.length == 1 && sels.first.is_a?(Universal)
83
84
  return sels if sels.any? {|sel2| eql?(sel2)}
84
85
  if !is_a?(Pseudo) || (sels.last.is_a?(Pseudo) && sels.last.type == :element)
85
86
  _, i = sels.each_with_index.find {|sel, _| sel.is_a?(Pseudo)}
@@ -113,10 +114,10 @@ module Sass
113
114
  # could be found at all.
114
115
  # If the second value is `false`, the first should be ignored.
115
116
  def unify_namespaces(ns1, ns2)
116
- return nil, false unless ns1 == ns2 || ns1.nil? || ns1 == '*' || ns2.nil? || ns2 == '*'
117
117
  return ns2, true if ns1 == '*'
118
118
  return ns1, true if ns2 == '*'
119
- [ns1 || ns2, true]
119
+ return nil, false unless ns1 == ns2
120
+ [ns1, true]
120
121
  end
121
122
  end
122
123
  end