oreorenasass 3.4.4 → 3.4.5

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 (176) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +1 -1
  3. data/README.md +50 -70
  4. data/Rakefile +5 -26
  5. data/VERSION +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 +12 -19
  10. data/lib/sass/cache_stores/base.rb +2 -2
  11. data/lib/sass/cache_stores/chain.rb +1 -2
  12. data/lib/sass/cache_stores/filesystem.rb +5 -1
  13. data/lib/sass/cache_stores/memory.rb +1 -1
  14. data/lib/sass/cache_stores/null.rb +2 -2
  15. data/lib/sass/callbacks.rb +0 -1
  16. data/lib/sass/css.rb +13 -11
  17. data/lib/sass/engine.rb +173 -424
  18. data/lib/sass/environment.rb +58 -148
  19. data/lib/sass/error.rb +14 -11
  20. data/lib/sass/exec.rb +703 -5
  21. data/lib/sass/importers/base.rb +6 -49
  22. data/lib/sass/importers/filesystem.rb +19 -44
  23. data/lib/sass/logger.rb +4 -1
  24. data/lib/sass/logger/base.rb +4 -2
  25. data/lib/sass/logger/log_level.rb +7 -3
  26. data/lib/sass/media.rb +23 -20
  27. data/lib/sass/plugin.rb +7 -7
  28. data/lib/sass/plugin/compiler.rb +145 -304
  29. data/lib/sass/plugin/configuration.rb +23 -18
  30. data/lib/sass/plugin/merb.rb +1 -1
  31. data/lib/sass/plugin/staleness_checker.rb +3 -3
  32. data/lib/sass/repl.rb +3 -3
  33. data/lib/sass/script.rb +8 -35
  34. data/lib/sass/script/{value/arg_list.rb → arg_list.rb} +25 -9
  35. data/lib/sass/script/bool.rb +18 -0
  36. data/lib/sass/script/color.rb +606 -0
  37. data/lib/sass/script/css_lexer.rb +4 -8
  38. data/lib/sass/script/css_parser.rb +2 -5
  39. data/lib/sass/script/funcall.rb +245 -0
  40. data/lib/sass/script/functions.rb +408 -1491
  41. data/lib/sass/script/interpolation.rb +79 -0
  42. data/lib/sass/script/lexer.rb +68 -172
  43. data/lib/sass/script/list.rb +85 -0
  44. data/lib/sass/script/literal.rb +221 -0
  45. data/lib/sass/script/{tree/node.rb → node.rb} +12 -22
  46. data/lib/sass/script/{value/null.rb → null.rb} +7 -14
  47. data/lib/sass/script/{value/number.rb → number.rb} +75 -152
  48. data/lib/sass/script/{tree/operation.rb → operation.rb} +24 -17
  49. data/lib/sass/script/parser.rb +110 -245
  50. data/lib/sass/script/string.rb +51 -0
  51. data/lib/sass/script/{tree/string_interpolation.rb → string_interpolation.rb} +4 -5
  52. data/lib/sass/script/{tree/unary_operation.rb → unary_operation.rb} +6 -6
  53. data/lib/sass/script/variable.rb +58 -0
  54. data/lib/sass/scss/css_parser.rb +3 -9
  55. data/lib/sass/scss/parser.rb +421 -450
  56. data/lib/sass/scss/rx.rb +11 -19
  57. data/lib/sass/scss/static_parser.rb +7 -321
  58. data/lib/sass/selector.rb +194 -68
  59. data/lib/sass/selector/abstract_sequence.rb +14 -29
  60. data/lib/sass/selector/comma_sequence.rb +25 -108
  61. data/lib/sass/selector/sequence.rb +66 -159
  62. data/lib/sass/selector/simple.rb +25 -23
  63. data/lib/sass/selector/simple_sequence.rb +63 -173
  64. data/lib/sass/shared.rb +1 -1
  65. data/lib/sass/supports.rb +15 -13
  66. data/lib/sass/tree/charset_node.rb +1 -1
  67. data/lib/sass/tree/comment_node.rb +3 -3
  68. data/lib/sass/tree/css_import_node.rb +11 -11
  69. data/lib/sass/tree/debug_node.rb +2 -2
  70. data/lib/sass/tree/directive_node.rb +4 -21
  71. data/lib/sass/tree/each_node.rb +8 -8
  72. data/lib/sass/tree/extend_node.rb +7 -14
  73. data/lib/sass/tree/for_node.rb +4 -4
  74. data/lib/sass/tree/function_node.rb +4 -9
  75. data/lib/sass/tree/if_node.rb +1 -1
  76. data/lib/sass/tree/import_node.rb +5 -4
  77. data/lib/sass/tree/media_node.rb +14 -4
  78. data/lib/sass/tree/mixin_def_node.rb +4 -4
  79. data/lib/sass/tree/mixin_node.rb +8 -21
  80. data/lib/sass/tree/node.rb +12 -54
  81. data/lib/sass/tree/prop_node.rb +20 -39
  82. data/lib/sass/tree/return_node.rb +2 -3
  83. data/lib/sass/tree/root_node.rb +3 -19
  84. data/lib/sass/tree/rule_node.rb +22 -35
  85. data/lib/sass/tree/supports_node.rb +13 -0
  86. data/lib/sass/tree/trace_node.rb +1 -2
  87. data/lib/sass/tree/variable_node.rb +3 -9
  88. data/lib/sass/tree/visitors/base.rb +8 -5
  89. data/lib/sass/tree/visitors/check_nesting.rb +19 -49
  90. data/lib/sass/tree/visitors/convert.rb +56 -74
  91. data/lib/sass/tree/visitors/cssize.rb +74 -202
  92. data/lib/sass/tree/visitors/deep_copy.rb +5 -10
  93. data/lib/sass/tree/visitors/extend.rb +7 -7
  94. data/lib/sass/tree/visitors/perform.rb +185 -278
  95. data/lib/sass/tree/visitors/set_options.rb +6 -20
  96. data/lib/sass/tree/visitors/to_css.rb +81 -234
  97. data/lib/sass/tree/warn_node.rb +2 -2
  98. data/lib/sass/tree/while_node.rb +2 -2
  99. data/lib/sass/util.rb +152 -522
  100. data/lib/sass/util/multibyte_string_scanner.rb +0 -2
  101. data/lib/sass/util/subset_map.rb +3 -4
  102. data/lib/sass/util/test.rb +1 -0
  103. data/lib/sass/version.rb +22 -20
  104. data/test/Gemfile +3 -0
  105. data/test/Gemfile.lock +10 -0
  106. data/test/sass/cache_test.rb +20 -62
  107. data/test/sass/callbacks_test.rb +1 -1
  108. data/test/sass/conversion_test.rb +2 -296
  109. data/test/sass/css2sass_test.rb +4 -23
  110. data/test/sass/engine_test.rb +354 -411
  111. data/test/sass/exec_test.rb +2 -2
  112. data/test/sass/extend_test.rb +145 -324
  113. data/test/sass/functions_test.rb +86 -873
  114. data/test/sass/importer_test.rb +21 -241
  115. data/test/sass/logger_test.rb +1 -1
  116. data/test/sass/more_results/more_import.css +1 -1
  117. data/test/sass/plugin_test.rb +26 -16
  118. data/test/sass/results/compact.css +1 -1
  119. data/test/sass/results/complex.css +4 -4
  120. data/test/sass/results/expanded.css +1 -1
  121. data/test/sass/results/import.css +1 -1
  122. data/test/sass/results/import_charset_ibm866.css +2 -2
  123. data/test/sass/results/mixins.css +17 -17
  124. data/test/sass/results/nested.css +1 -1
  125. data/test/sass/results/parent_ref.css +2 -2
  126. data/test/sass/results/script.css +3 -3
  127. data/test/sass/results/scss_import.css +1 -1
  128. data/test/sass/script_conversion_test.rb +7 -36
  129. data/test/sass/script_test.rb +53 -485
  130. data/test/sass/scss/css_test.rb +28 -143
  131. data/test/sass/scss/rx_test.rb +4 -4
  132. data/test/sass/scss/scss_test.rb +325 -2119
  133. data/test/sass/templates/scss_import.scss +1 -2
  134. data/test/sass/test_helper.rb +1 -1
  135. data/test/sass/util/multibyte_string_scanner_test.rb +1 -1
  136. data/test/sass/util/subset_map_test.rb +2 -2
  137. data/test/sass/util_test.rb +1 -86
  138. data/test/test_helper.rb +8 -37
  139. metadata +19 -66
  140. data/lib/sass/exec/base.rb +0 -187
  141. data/lib/sass/exec/sass_convert.rb +0 -264
  142. data/lib/sass/exec/sass_scss.rb +0 -424
  143. data/lib/sass/features.rb +0 -47
  144. data/lib/sass/script/tree.rb +0 -16
  145. data/lib/sass/script/tree/funcall.rb +0 -306
  146. data/lib/sass/script/tree/interpolation.rb +0 -118
  147. data/lib/sass/script/tree/list_literal.rb +0 -77
  148. data/lib/sass/script/tree/literal.rb +0 -45
  149. data/lib/sass/script/tree/map_literal.rb +0 -64
  150. data/lib/sass/script/tree/selector.rb +0 -26
  151. data/lib/sass/script/tree/variable.rb +0 -57
  152. data/lib/sass/script/value.rb +0 -11
  153. data/lib/sass/script/value/base.rb +0 -240
  154. data/lib/sass/script/value/bool.rb +0 -35
  155. data/lib/sass/script/value/color.rb +0 -680
  156. data/lib/sass/script/value/helpers.rb +0 -262
  157. data/lib/sass/script/value/list.rb +0 -113
  158. data/lib/sass/script/value/map.rb +0 -70
  159. data/lib/sass/script/value/string.rb +0 -97
  160. data/lib/sass/selector/pseudo.rb +0 -256
  161. data/lib/sass/source/map.rb +0 -210
  162. data/lib/sass/source/position.rb +0 -39
  163. data/lib/sass/source/range.rb +0 -41
  164. data/lib/sass/stack.rb +0 -120
  165. data/lib/sass/tree/at_root_node.rb +0 -83
  166. data/lib/sass/tree/error_node.rb +0 -18
  167. data/lib/sass/tree/keyframe_rule_node.rb +0 -15
  168. data/lib/sass/util/cross_platform_random.rb +0 -19
  169. data/lib/sass/util/normalized_map.rb +0 -130
  170. data/lib/sass/util/ordered_hash.rb +0 -192
  171. data/test/sass/compiler_test.rb +0 -232
  172. data/test/sass/encoding_test.rb +0 -219
  173. data/test/sass/source_map_test.rb +0 -977
  174. data/test/sass/superselector_test.rb +0 -191
  175. data/test/sass/util/normalized_map_test.rb +0 -51
  176. data/test/sass/value_helpers_test.rb +0 -179
@@ -14,18 +14,29 @@ module Sass
14
14
  # @return [String, nil]
15
15
  attr_accessor :filename
16
16
 
17
- # @see #to_s
17
+ # Returns a representation of the node
18
+ # as an array of strings and potentially {Sass::Script::Node}s
19
+ # (if there's interpolation in the selector).
20
+ # When the interpolation is resolved and the strings are joined together,
21
+ # this will be the string representation of this node.
22
+ #
23
+ # @return [Array<String, Sass::Script::Node>]
24
+ def to_a
25
+ Sass::Util.abstract(self)
26
+ end
27
+
28
+ # Returns a string representation of the node.
29
+ # This is basically the selector string.
18
30
  #
19
31
  # @return [String]
20
32
  def inspect
21
- to_s
33
+ to_a.map {|e| e.is_a?(Sass::Script::Node) ? "\#{#{e.to_sass}}" : e}.join
22
34
  end
23
35
 
24
- # Returns the selector string.
25
- #
36
+ # @see \{#inspect}
26
37
  # @return [String]
27
38
  def to_s
28
- Sass::Util.abstract(self)
39
+ inspect
29
40
  end
30
41
 
31
42
  # Returns a hash code for this selector object.
@@ -36,7 +47,7 @@ module Sass
36
47
  #
37
48
  # @return [Fixnum]
38
49
  def hash
39
- @_hash ||= equality_key.hash
50
+ @_hash ||= to_a.hash
40
51
  end
41
52
 
42
53
  # Checks equality between this and another object.
@@ -48,7 +59,7 @@ module Sass
48
59
  # @param other [Object] The object to test equality against
49
60
  # @return [Boolean] Whether or not this is equal to `other`
50
61
  def eql?(other)
51
- other.class == self.class && other.hash == hash && other.equality_key == equality_key
62
+ other.class == self.class && other.hash == self.hash && other.to_a.eql?(to_a)
52
63
  end
53
64
  alias_method :==, :eql?
54
65
 
@@ -73,26 +84,17 @@ module Sass
73
84
  return sels if sels.any? {|sel2| eql?(sel2)}
74
85
  sels_with_ix = Sass::Util.enum_with_index(sels)
75
86
  _, i =
76
- if is_a?(Pseudo)
87
+ if self.is_a?(Pseudo) || self.is_a?(SelectorPseudoClass)
77
88
  sels_with_ix.find {|sel, _| sel.is_a?(Pseudo) && (sels.last.type == :element)}
78
89
  else
79
- sels_with_ix.find {|sel, _| sel.is_a?(Pseudo)}
90
+ sels_with_ix.find {|sel, _| sel.is_a?(Pseudo) || sel.is_a?(SelectorPseudoClass)}
80
91
  end
81
92
  return sels + [self] unless i
82
- sels[0...i] + [self] + sels[i..-1]
93
+ return sels[0...i] + [self] + sels[i..-1]
83
94
  end
84
95
 
85
96
  protected
86
97
 
87
- # Returns the key used for testing whether selectors are equal.
88
- #
89
- # This is a cached version of \{#to\_s}.
90
- #
91
- # @return [String]
92
- def equality_key
93
- @equality_key ||= to_s
94
- end
95
-
96
98
  # Unifies two namespaces,
97
99
  # returning a namespace that works for both of them if possible.
98
100
  #
@@ -107,10 +109,10 @@ module Sass
107
109
  # could be found at all.
108
110
  # If the second value is `false`, the first should be ignored.
109
111
  def unify_namespaces(ns1, ns2)
110
- return nil, false unless ns1 == ns2 || ns1.nil? || ns1 == '*' || ns2.nil? || ns2 == '*'
111
- return ns2, true if ns1 == '*'
112
- return ns1, true if ns2 == '*'
113
- [ns1 || ns2, true]
112
+ return nil, false unless ns1 == ns2 || ns1.nil? || ns1 == ['*'] || ns2.nil? || ns2 == ['*']
113
+ return ns2, true if ns1 == ['*']
114
+ return ns1, true if ns2 == ['*']
115
+ return ns1 || ns2, true
114
116
  end
115
117
  end
116
118
  end
@@ -21,16 +21,11 @@ module Sass
21
21
  # and the generated selector `c.foo.bar.baz` has `{b.bar, c.baz}` as its
22
22
  # `sources` set.
23
23
  #
24
- # This is populated during the {Sequence#do_extend} process.
24
+ # This is populated during the {#do_extend} process.
25
25
  #
26
26
  # @return {Set<Sequence>}
27
27
  attr_accessor :sources
28
28
 
29
- # This sequence source range.
30
- #
31
- # @return [Sass::Source::Range]
32
- attr_accessor :source_range
33
-
34
29
  # @see \{#subject?}
35
30
  attr_writer :subject
36
31
 
@@ -43,16 +38,11 @@ module Sass
43
38
  end
44
39
 
45
40
  def pseudo_elements
46
- @pseudo_elements ||= members.select {|sel| sel.is_a?(Pseudo) && sel.type == :element}
47
- end
48
-
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}
41
+ @pseudo_elements ||= (members - [base]).
42
+ select {|sel| sel.is_a?(Pseudo) && sel.type == :element}
53
43
  end
54
44
 
55
- # Returns the non-base, non-pseudo-element selectors in this sequence.
45
+ # Returns the non-base, non-pseudo-class selectors in this sequence.
56
46
  #
57
47
  # @return [Set<Simple>]
58
48
  def rest
@@ -70,143 +60,74 @@ module Sass
70
60
 
71
61
  # @param selectors [Array<Simple>] See \{#members}
72
62
  # @param subject [Boolean] See \{#subject?}
73
- # @param source_range [Sass::Source::Range]
74
- def initialize(selectors, subject, source_range = nil)
63
+ # @param sources [Set<Sequence>]
64
+ def initialize(selectors, subject, sources = Set.new)
75
65
  @members = selectors
76
66
  @subject = subject
77
- @sources = Set.new
78
- @source_range = source_range
67
+ @sources = sources
79
68
  end
80
69
 
81
70
  # Resolves the {Parent} selectors within this selector
82
71
  # by replacing them with the given parent selector,
83
72
  # handling commas appropriately.
84
73
  #
85
- # @param super_cseq [CommaSequence] The parent selector
86
- # @return [CommaSequence] This selector, with parent references resolved
74
+ # @param super_seq [Sequence] The parent selector sequence
75
+ # @return [Array<SimpleSequence>] This selector, with parent references resolved.
76
+ # This is an array because the parent selector is itself a {Sequence}
87
77
  # @raise [Sass::SyntaxError] If a parent selector is invalid
88
- def resolve_parent_refs(super_cseq)
78
+ def resolve_parent_refs(super_seq)
89
79
  # Parent selector only appears as the first selector in the sequence
90
- unless (parent = @members.first).is_a?(Parent)
91
- return CommaSequence.new([Sequence.new([self])])
92
- end
80
+ return [self] unless @members.first.is_a?(Parent)
93
81
 
94
- return super_cseq if @members.size == 1 && parent.suffix.nil?
95
-
96
- CommaSequence.new(super_cseq.members.map do |super_seq|
97
- members = super_seq.members.dup
98
- newline = members.pop if members.last == "\n"
99
- unless members.last.is_a?(SimpleSequence)
100
- raise Sass::SyntaxError.new("Invalid parent selector for \"#{self}\": \"" +
101
- super_seq.to_s + '"')
102
- end
103
-
104
- parent_sub = members.last.members
105
- unless parent.suffix.nil?
106
- parent_sub = parent_sub.dup
107
- parent_sub[-1] = parent_sub.last.dup
108
- case parent_sub.last
109
- when Sass::Selector::Class, Sass::Selector::Id, Sass::Selector::Placeholder
110
- parent_sub[-1] = parent_sub.last.class.new(parent_sub.last.name + parent.suffix)
111
- when Sass::Selector::Element
112
- parent_sub[-1] = parent_sub.last.class.new(
113
- parent_sub.last.name + parent.suffix,
114
- parent_sub.last.namespace)
115
- when Sass::Selector::Pseudo
116
- if parent_sub.last.arg || parent_sub.last.selector
117
- raise Sass::SyntaxError.new("Invalid parent selector for \"#{self}\": \"" +
118
- super_seq.to_s + '"')
119
- end
120
- parent_sub[-1] = Sass::Selector::Pseudo.new(
121
- parent_sub.last.type,
122
- parent_sub.last.name + parent.suffix,
123
- nil, nil)
124
- else
125
- raise Sass::SyntaxError.new("Invalid parent selector for \"#{self}\": \"" +
126
- super_seq.to_s + '"')
127
- end
128
- end
82
+ members = super_seq.members.dup
83
+ newline = members.pop if members.last == "\n"
84
+ return members if @members.size == 1
85
+ unless members.last.is_a?(SimpleSequence)
86
+ raise Sass::SyntaxError.new("Invalid parent selector: " + super_seq.to_a.join)
87
+ end
129
88
 
130
- Sequence.new(members[0...-1] +
131
- [SimpleSequence.new(parent_sub + @members[1..-1], subject?)] +
132
- [newline].compact)
133
- end)
89
+ members[0...-1] +
90
+ [SimpleSequence.new(members.last.members + @members[1..-1], subject?)] +
91
+ [newline].compact
134
92
  end
135
93
 
136
- # Non-destructively extends this selector with the extensions specified in a hash
94
+ # Non-destrucively extends this selector with the extensions specified in a hash
137
95
  # (which should come from {Sass::Tree::Visitors::Cssize}).
138
96
  #
97
+ # @overload def do_extend(extends, parent_directives)
139
98
  # @param extends [{Selector::Simple =>
140
99
  # Sass::Tree::Visitors::Cssize::Extend}]
141
100
  # The extensions to perform on this selector
142
101
  # @param parent_directives [Array<Sass::Tree::DirectiveNode>]
143
102
  # 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.
149
103
  # @return [Array<Sequence>] A list of selectors generated
150
104
  # by extending this selector with `extends`.
151
105
  # @see CommaSequence#do_extend
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
-
168
- groups = Sass::Util.group_by_to_a(extends[members.to_set]) {|ex| ex.extender}
169
- groups.map! do |seq, group|
170
- sels = group.map {|e| e.target}.flatten
106
+ def do_extend(extends, parent_directives, seen = Set.new)
107
+ Sass::Util.group_by_to_a(extends.get(members.to_set)) {|ex, _| ex.extender}.map do |seq, group|
108
+ sels = group.map {|_, s| s}.flatten
171
109
  # If A {@extend B} and C {...},
172
110
  # seq is A, sels is B, and self is C
173
111
 
174
- self_without_sel = Sass::Util.array_minus(members, sels)
175
- group.each {|e| e.result = :failed_to_unify unless e.result == :succeeded}
176
- unified = seq.members.last.unify(SimpleSequence.new(self_without_sel, subject?))
177
- next unless unified
178
- group.each {|e| e.result = :succeeded}
179
- group.each {|e| check_directives_match!(e, parent_directives)}
112
+ self_without_sel = Sass::Util.array_minus(self.members, sels)
113
+ group.each {|e, _| e.result = :failed_to_unify unless e.result == :succeeded}
114
+ next unless unified = seq.members.last.unify(self_without_sel, subject?)
115
+ group.each {|e, _| e.result = :succeeded}
116
+ next if group.map {|e, _| check_directives_match!(e, parent_directives)}.none?
180
117
  new_seq = Sequence.new(seq.members[0...-1] + [unified])
181
118
  new_seq.add_sources!(sources + [seq])
182
119
  [sels, new_seq]
183
- end
184
- groups.compact!
185
- groups.map! do |sels, seq|
186
- next [] if seen.include?(sels)
187
- seq.do_extend(
188
- extends, parent_directives, !:replace, seen_with_pseudo_selectors + [sels], !:original)
189
- end
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
201
- groups.uniq!
202
- groups
120
+ end.compact.map do |sels, seq|
121
+ seen.include?(sels) ? [] : seq.do_extend(extends, parent_directives, seen + [sels])
122
+ end.flatten.uniq
203
123
  end
204
124
 
205
- # Unifies this selector with another {SimpleSequence}, returning
206
- # another `SimpleSequence` that is a subselector of both input
207
- # selectors.
125
+ # Unifies this selector with another {SimpleSequence}'s {SimpleSequence#members members array},
126
+ # returning another `SimpleSequence`
127
+ # that matches both this selector and the input selector.
208
128
  #
209
- # @param other [SimpleSequence]
129
+ # @param sels [Array<Simple>] A {SimpleSequence}'s {SimpleSequence#members members array}
130
+ # @param subject [Boolean] Whether the {SimpleSequence} being merged is a subject.
210
131
  # @return [SimpleSequence, nil] A {SimpleSequence} matching both `sels` and this selector,
211
132
  # or `nil` if this is impossible (e.g. unifying `#foo` and `#bar`)
212
133
  # @raise [Sass::SyntaxError] If this selector cannot be unified.
@@ -215,13 +136,12 @@ module Sass
215
136
  # Since these selectors should be resolved
216
137
  # by the time extension and unification happen,
217
138
  # this exception will only ever be raised as a result of programmer error
218
- def unify(other)
219
- sseq = members.inject(other.members) do |member, sel|
139
+ def unify(sels, other_subject)
140
+ return unless sseq = members.inject(sels) do |member, sel|
220
141
  return unless member
221
142
  sel.unify(member)
222
143
  end
223
- return unless sseq
224
- SimpleSequence.new(sseq, other.subject? || subject?)
144
+ SimpleSequence.new(sseq, other_subject || subject?)
225
145
  end
226
146
 
227
147
  # Returns whether or not this selector matches all elements
@@ -230,44 +150,17 @@ module Sass
230
150
  # @example
231
151
  # (.foo).superselector?(.foo.bar) #=> true
232
152
  # (.foo).superselector?(.bar) #=> false
233
- # @param their_sseq [SimpleSequence]
234
- # @param parents [Array<SimpleSequence, String>] The parent selectors of `their_sseq`, if any.
153
+ # @param sseq [SimpleSequence]
235
154
  # @return [Boolean]
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
155
+ def superselector?(sseq)
156
+ (base.nil? || base.eql?(sseq.base)) &&
157
+ pseudo_elements.eql?(sseq.pseudo_elements) &&
158
+ rest.subset?(sseq.rest)
266
159
  end
267
160
 
268
- # @see Simple#to_s
269
- def to_s
270
- res = @members.join
161
+ # @see Simple#to_a
162
+ def to_a
163
+ res = @members.map {|sel| sel.to_a}.flatten
271
164
  res << '!' if subject?
272
165
  res
273
166
  end
@@ -277,13 +170,11 @@ module Sass
277
170
  #
278
171
  # @return [String]
279
172
  def inspect
280
- res = members.map {|m| m.inspect}.join
281
- res << '!' if subject?
282
- res
173
+ members.map {|m| m.inspect}.join
283
174
  end
284
175
 
285
176
  # Return a copy of this simple sequence with `sources` merged into the
286
- # {SimpleSequence#sources} set.
177
+ # {#sources} set.
287
178
  #
288
179
  # @param sources [Set<Sequence>]
289
180
  # @return [SimpleSequence]
@@ -299,17 +190,16 @@ module Sass
299
190
  def check_directives_match!(extend, parent_directives)
300
191
  dirs1 = extend.directives.map {|d| d.resolved_value}
301
192
  dirs2 = parent_directives.map {|d| d.resolved_value}
302
- return if Sass::Util.subsequence?(dirs1, dirs2)
303
- line = extend.node.line
304
- filename = extend.node.filename
193
+ return true if Sass::Util.subsequence?(dirs1, dirs2)
305
194
 
306
- # TODO(nweiz): this should use the Sass stack trace of the extend node,
307
- # not the selector.
308
- raise Sass::SyntaxError.new(<<MESSAGE)
309
- You may not @extend an outer selector from within #{extend.directives.last.name}.
310
- You may only @extend selectors within the same directive.
311
- From "@extend #{extend.target.join(', ')}" on line #{line}#{" of #{filename}" if filename}.
312
- MESSAGE
195
+ Sass::Util.sass_warn <<WARNING
196
+ DEPRECATION WARNING on line #{extend.node.line}#{" of #{extend.node.filename}" if extend.node.filename}:
197
+ @extending an outer selector from within #{extend.directives.last.name} is deprecated.
198
+ You may only @extend selectors within the same directive.
199
+ This will be an error in Sass 3.3.
200
+ It can only work once @extend is supported natively in the browser.
201
+ WARNING
202
+ return false
313
203
  end
314
204
 
315
205
  def _hash
@@ -317,8 +207,8 @@ MESSAGE
317
207
  end
318
208
 
319
209
  def _eql?(other)
320
- other.base.eql?(base) && other.pseudo_elements == pseudo_elements &&
321
- Sass::Util.set_eql?(other.rest, rest) && other.subject? == subject?
210
+ other.base.eql?(self.base) && other.pseudo_elements == pseudo_elements &&
211
+ Sass::Util.set_eql?(other.rest, self.rest) && other.subject? == self.subject?
322
212
  end
323
213
  end
324
214
  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, scanner.rest] if count == 0
47
+ return [str.strip, scanner.rest] if count == 0
48
48
  end
49
49
  end
50
50
 
data/lib/sass/supports.rb CHANGED
@@ -4,7 +4,7 @@ module Sass::Supports
4
4
  class Condition
5
5
  # Runs the SassScript in the supports condition.
6
6
  #
7
- # @param environment [Sass::Environment] The environment in which to run the script.
7
+ # @param env [Sass::Environment] The environment in which to run the script.
8
8
  def perform(environment); Sass::Util.abstract(self); end
9
9
 
10
10
  # Returns the CSS for this condition.
@@ -81,12 +81,12 @@ module Sass::Supports
81
81
 
82
82
  def left_parens(str)
83
83
  return "(#{str})" if @left.is_a?(Negation)
84
- str
84
+ return str
85
85
  end
86
86
 
87
87
  def right_parens(str)
88
88
  return "(#{str})" if @right.is_a?(Negation) || @right.is_a?(Operator)
89
- str
89
+ return str
90
90
  end
91
91
  end
92
92
 
@@ -127,25 +127,26 @@ module Sass::Supports
127
127
 
128
128
  def parens(str)
129
129
  return "(#{str})" if @condition.is_a?(Negation) || @condition.is_a?(Operator)
130
- str
130
+ return str
131
131
  end
132
132
  end
133
133
 
134
134
  # A declaration condition (e.g. `(feature: value)`).
135
135
  class Declaration < Condition
136
- # @return [Sass::Script::Tree::Node] The feature name.
136
+ # The feature name.
137
+ #
138
+ # @param [Sass::Script::Node]
137
139
  attr_accessor :name
138
140
 
139
- # @!attribute resolved_name
140
- # The name of the feature after any SassScript has been resolved.
141
- # Only set once \{Tree::Visitors::Perform} has been run.
141
+ # The name of the feature after any SassScript has been resolved.
142
+ # Only set once \{Tree::Visitors::Perform} has been run.
142
143
  #
143
- # @return [String]
144
+ # @return [String]
144
145
  attr_accessor :resolved_name
145
146
 
146
147
  # The feature value.
147
148
  #
148
- # @return [Sass::Script::Tree::Node]
149
+ # @param [Sass::Script::Node]
149
150
  attr_accessor :value
150
151
 
151
152
  # The value of the feature after any SassScript has been resolved.
@@ -189,7 +190,7 @@ module Sass::Supports
189
190
  class Interpolation < Condition
190
191
  # The SassScript expression in the interpolation.
191
192
  #
192
- # @return [Sass::Script::Tree::Node]
193
+ # @param [Sass::Script::Node]
193
194
  attr_accessor :value
194
195
 
195
196
  # The value of the expression after it's been resolved.
@@ -203,7 +204,8 @@ module Sass::Supports
203
204
  end
204
205
 
205
206
  def perform(env)
206
- @resolved_value = value.perform(env).to_s(:quote => :none)
207
+ val = value.perform(env)
208
+ @resolved_value = val.is_a?(Sass::Script::String) ? val.value : val.to_s
207
209
  end
208
210
 
209
211
  def to_css
@@ -211,7 +213,7 @@ module Sass::Supports
211
213
  end
212
214
 
213
215
  def to_src(options)
214
- @value.to_sass(options)
216
+ "\#{#{@value.to_sass(options)}}"
215
217
  end
216
218
 
217
219
  def deep_copy