sass 3.2.7 → 3.3.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 (184) hide show
  1. data/MIT-LICENSE +2 -2
  2. data/README.md +14 -2
  3. data/Rakefile +25 -1
  4. data/VERSION +1 -1
  5. data/VERSION_DATE +1 -1
  6. data/VERSION_NAME +1 -1
  7. data/lib/sass/cache_stores/base.rb +4 -2
  8. data/lib/sass/cache_stores/chain.rb +2 -1
  9. data/lib/sass/cache_stores/filesystem.rb +2 -6
  10. data/lib/sass/cache_stores/memory.rb +1 -1
  11. data/lib/sass/cache_stores/null.rb +2 -2
  12. data/lib/sass/callbacks.rb +1 -0
  13. data/lib/sass/css.rb +10 -10
  14. data/lib/sass/engine.rb +403 -150
  15. data/lib/sass/environment.rb +136 -57
  16. data/lib/sass/error.rb +7 -7
  17. data/lib/sass/exec.rb +123 -39
  18. data/lib/sass/features.rb +41 -0
  19. data/lib/sass/importers/base.rb +33 -2
  20. data/lib/sass/importers/deprecated_path.rb +45 -0
  21. data/lib/sass/importers/filesystem.rb +25 -14
  22. data/lib/sass/importers.rb +1 -0
  23. data/lib/sass/logger/base.rb +3 -3
  24. data/lib/sass/logger/log_level.rb +4 -6
  25. data/lib/sass/media.rb +19 -19
  26. data/lib/sass/plugin/compiler.rb +141 -101
  27. data/lib/sass/plugin/configuration.rb +18 -22
  28. data/lib/sass/plugin/merb.rb +1 -1
  29. data/lib/sass/plugin/staleness_checker.rb +24 -8
  30. data/lib/sass/plugin.rb +4 -2
  31. data/lib/sass/repl.rb +3 -3
  32. data/lib/sass/script/css_lexer.rb +9 -4
  33. data/lib/sass/script/css_parser.rb +6 -2
  34. data/lib/sass/script/functions.rb +1343 -590
  35. data/lib/sass/script/lexer.rb +84 -52
  36. data/lib/sass/script/parser.rb +217 -97
  37. data/lib/sass/script/tree/funcall.rb +290 -0
  38. data/lib/sass/script/{interpolation.rb → tree/interpolation.rb} +34 -13
  39. data/lib/sass/script/tree/list_literal.rb +80 -0
  40. data/lib/sass/script/tree/literal.rb +47 -0
  41. data/lib/sass/script/tree/map_literal.rb +64 -0
  42. data/lib/sass/script/{node.rb → tree/node.rb} +22 -12
  43. data/lib/sass/script/{operation.rb → tree/operation.rb} +17 -25
  44. data/lib/sass/script/tree/selector.rb +30 -0
  45. data/lib/sass/script/{string_interpolation.rb → tree/string_interpolation.rb} +5 -4
  46. data/lib/sass/script/{unary_operation.rb → tree/unary_operation.rb} +14 -9
  47. data/lib/sass/script/tree/variable.rb +57 -0
  48. data/lib/sass/script/tree.rb +16 -0
  49. data/lib/sass/script/{arg_list.rb → value/arg_list.rb} +4 -24
  50. data/lib/sass/script/value/base.rb +248 -0
  51. data/lib/sass/script/value/bool.rb +36 -0
  52. data/lib/sass/script/{color.rb → value/color.rb} +239 -195
  53. data/lib/sass/script/value/helpers.rb +155 -0
  54. data/lib/sass/script/value/list.rb +119 -0
  55. data/lib/sass/script/value/map.rb +70 -0
  56. data/lib/sass/script/value/null.rb +45 -0
  57. data/lib/sass/script/{number.rb → value/number.rb} +91 -65
  58. data/lib/sass/script/{string.rb → value/string.rb} +9 -11
  59. data/lib/sass/script/value.rb +11 -0
  60. data/lib/sass/script.rb +35 -8
  61. data/lib/sass/scss/css_parser.rb +2 -1
  62. data/lib/sass/scss/parser.rb +338 -170
  63. data/lib/sass/scss/rx.rb +5 -6
  64. data/lib/sass/scss/script_lexer.rb +1 -0
  65. data/lib/sass/scss/script_parser.rb +1 -0
  66. data/lib/sass/scss/static_parser.rb +23 -6
  67. data/lib/sass/selector/abstract_sequence.rb +2 -2
  68. data/lib/sass/selector/comma_sequence.rb +21 -16
  69. data/lib/sass/selector/sequence.rb +60 -34
  70. data/lib/sass/selector/simple.rb +11 -12
  71. data/lib/sass/selector/simple_sequence.rb +55 -33
  72. data/lib/sass/selector.rb +52 -48
  73. data/lib/sass/source/map.rb +211 -0
  74. data/lib/sass/source/position.rb +39 -0
  75. data/lib/sass/source/range.rb +41 -0
  76. data/lib/sass/stack.rb +120 -0
  77. data/lib/sass/supports.rb +12 -13
  78. data/lib/sass/tree/at_root_node.rb +82 -0
  79. data/lib/sass/tree/comment_node.rb +3 -3
  80. data/lib/sass/tree/css_import_node.rb +11 -11
  81. data/lib/sass/tree/debug_node.rb +2 -2
  82. data/lib/sass/tree/directive_node.rb +13 -2
  83. data/lib/sass/tree/each_node.rb +8 -8
  84. data/lib/sass/tree/extend_node.rb +13 -6
  85. data/lib/sass/tree/for_node.rb +4 -4
  86. data/lib/sass/tree/function_node.rb +5 -4
  87. data/lib/sass/tree/if_node.rb +1 -1
  88. data/lib/sass/tree/import_node.rb +4 -5
  89. data/lib/sass/tree/media_node.rb +4 -14
  90. data/lib/sass/tree/mixin_def_node.rb +4 -4
  91. data/lib/sass/tree/mixin_node.rb +21 -8
  92. data/lib/sass/tree/node.rb +29 -12
  93. data/lib/sass/tree/prop_node.rb +38 -18
  94. data/lib/sass/tree/return_node.rb +3 -2
  95. data/lib/sass/tree/root_node.rb +19 -3
  96. data/lib/sass/tree/rule_node.rb +25 -17
  97. data/lib/sass/tree/supports_node.rb +0 -13
  98. data/lib/sass/tree/trace_node.rb +2 -1
  99. data/lib/sass/tree/variable_node.rb +9 -3
  100. data/lib/sass/tree/visitors/base.rb +6 -6
  101. data/lib/sass/tree/visitors/check_nesting.rb +12 -9
  102. data/lib/sass/tree/visitors/convert.rb +63 -38
  103. data/lib/sass/tree/visitors/cssize.rb +63 -23
  104. data/lib/sass/tree/visitors/deep_copy.rb +6 -5
  105. data/lib/sass/tree/visitors/extend.rb +7 -7
  106. data/lib/sass/tree/visitors/perform.rb +256 -151
  107. data/lib/sass/tree/visitors/set_options.rb +6 -6
  108. data/lib/sass/tree/visitors/to_css.rb +231 -81
  109. data/lib/sass/tree/warn_node.rb +2 -2
  110. data/lib/sass/tree/while_node.rb +2 -2
  111. data/lib/sass/util/multibyte_string_scanner.rb +2 -0
  112. data/lib/sass/util/normalized_map.rb +65 -0
  113. data/lib/sass/util/ordered_hash.rb +188 -0
  114. data/lib/sass/util/subset_map.rb +3 -2
  115. data/lib/sass/util/test.rb +9 -0
  116. data/lib/sass/util.rb +220 -34
  117. data/lib/sass/version.rb +9 -9
  118. data/lib/sass.rb +14 -7
  119. data/test/sass/compiler_test.rb +213 -0
  120. data/test/sass/conversion_test.rb +235 -9
  121. data/test/sass/engine_test.rb +230 -60
  122. data/test/sass/exec_test.rb +86 -0
  123. data/test/sass/extend_test.rb +215 -147
  124. data/test/sass/functions_test.rb +584 -99
  125. data/test/sass/importer_test.rb +165 -17
  126. data/test/sass/plugin_test.rb +19 -13
  127. data/test/sass/script_conversion_test.rb +40 -0
  128. data/test/sass/script_test.rb +231 -21
  129. data/test/sass/scss/css_test.rb +14 -5
  130. data/test/sass/scss/scss_test.rb +1266 -66
  131. data/test/sass/source_map_test.rb +879 -0
  132. data/test/sass/templates/bork5.sass +3 -0
  133. data/test/sass/util/normalized_map_test.rb +30 -0
  134. data/test/sass/util_test.rb +90 -0
  135. data/test/sass/value_helpers_test.rb +181 -0
  136. data/test/test_helper.rb +7 -2
  137. metadata +316 -291
  138. data/lib/sass/script/bool.rb +0 -18
  139. data/lib/sass/script/funcall.rb +0 -231
  140. data/lib/sass/script/list.rb +0 -84
  141. data/lib/sass/script/literal.rb +0 -239
  142. data/lib/sass/script/null.rb +0 -34
  143. data/lib/sass/script/variable.rb +0 -58
  144. data/test/Gemfile +0 -3
  145. data/vendor/listen/CHANGELOG.md +0 -221
  146. data/vendor/listen/CONTRIBUTING.md +0 -38
  147. data/vendor/listen/Gemfile +0 -30
  148. data/vendor/listen/Guardfile +0 -8
  149. data/vendor/listen/LICENSE +0 -20
  150. data/vendor/listen/README.md +0 -315
  151. data/vendor/listen/Rakefile +0 -47
  152. data/vendor/listen/Vagrantfile +0 -96
  153. data/vendor/listen/lib/listen/adapter.rb +0 -214
  154. data/vendor/listen/lib/listen/adapters/bsd.rb +0 -112
  155. data/vendor/listen/lib/listen/adapters/darwin.rb +0 -85
  156. data/vendor/listen/lib/listen/adapters/linux.rb +0 -113
  157. data/vendor/listen/lib/listen/adapters/polling.rb +0 -67
  158. data/vendor/listen/lib/listen/adapters/windows.rb +0 -87
  159. data/vendor/listen/lib/listen/dependency_manager.rb +0 -126
  160. data/vendor/listen/lib/listen/directory_record.rb +0 -371
  161. data/vendor/listen/lib/listen/listener.rb +0 -225
  162. data/vendor/listen/lib/listen/multi_listener.rb +0 -143
  163. data/vendor/listen/lib/listen/turnstile.rb +0 -28
  164. data/vendor/listen/lib/listen/version.rb +0 -3
  165. data/vendor/listen/lib/listen.rb +0 -40
  166. data/vendor/listen/listen.gemspec +0 -22
  167. data/vendor/listen/spec/listen/adapter_spec.rb +0 -183
  168. data/vendor/listen/spec/listen/adapters/bsd_spec.rb +0 -36
  169. data/vendor/listen/spec/listen/adapters/darwin_spec.rb +0 -37
  170. data/vendor/listen/spec/listen/adapters/linux_spec.rb +0 -47
  171. data/vendor/listen/spec/listen/adapters/polling_spec.rb +0 -68
  172. data/vendor/listen/spec/listen/adapters/windows_spec.rb +0 -30
  173. data/vendor/listen/spec/listen/dependency_manager_spec.rb +0 -107
  174. data/vendor/listen/spec/listen/directory_record_spec.rb +0 -1225
  175. data/vendor/listen/spec/listen/listener_spec.rb +0 -169
  176. data/vendor/listen/spec/listen/multi_listener_spec.rb +0 -174
  177. data/vendor/listen/spec/listen/turnstile_spec.rb +0 -56
  178. data/vendor/listen/spec/listen_spec.rb +0 -73
  179. data/vendor/listen/spec/spec_helper.rb +0 -21
  180. data/vendor/listen/spec/support/adapter_helper.rb +0 -629
  181. data/vendor/listen/spec/support/directory_record_helper.rb +0 -55
  182. data/vendor/listen/spec/support/fixtures_helper.rb +0 -29
  183. data/vendor/listen/spec/support/listeners_helper.rb +0 -156
  184. data/vendor/listen/spec/support/platform_helper.rb +0 -15
@@ -27,11 +27,20 @@ class Sass::Tree::Visitors::Cssize < Sass::Tree::Visitors::Base
27
27
  # Keeps track of the current parent node.
28
28
  def visit_children(parent)
29
29
  with_parent parent do
30
- parent.children = super.flatten
30
+ parent.children = visit_children_without_parent(parent)
31
31
  parent
32
32
  end
33
33
  end
34
34
 
35
+ # Like {#visit\_children}, but doesn't set {#parent}.
36
+ #
37
+ # @param node [Sass::Tree::Node]
38
+ # @return [Array<Sass::Tree::Node>] the flattened results of
39
+ # visiting all the children of `node`
40
+ def visit_children_without_parent(node)
41
+ node.children.map {|c| visit(c)}.flatten
42
+ end
43
+
35
44
  MERGEABLE_DIRECTIVES = [Sass::Tree::MediaNode]
36
45
 
37
46
  # Runs a block of code with the current parent node
@@ -81,7 +90,7 @@ class Sass::Tree::Visitors::Cssize < Sass::Tree::Visitors::Base
81
90
  node.children.each_with_index.find {|c, _| c.is_a?(Sass::Tree::CharsetNode)}
82
91
  if charset_and_index
83
92
  index = charset_and_index.last
84
- node.children = node.children[0..index] + imports + node.children[index+1..-1]
93
+ node.children = node.children[0..index] + imports + node.children[index + 1..-1]
85
94
  else
86
95
  node.children = imports + node.children
87
96
  end
@@ -94,7 +103,7 @@ class Sass::Tree::Visitors::Cssize < Sass::Tree::Visitors::Base
94
103
  end
95
104
 
96
105
  # A simple struct wrapping up information about a single `@extend` instance. A
97
- # single [ExtendNode] can have multiple Extends if either the parent node or
106
+ # single {ExtendNode} can have multiple Extends if either the parent node or
98
107
  # the extended selector is a comma sequence.
99
108
  #
100
109
  # @attr extender [Sass::Selector::Sequence]
@@ -124,12 +133,12 @@ class Sass::Tree::Visitors::Cssize < Sass::Tree::Visitors::Base
124
133
  end
125
134
 
126
135
  sel = sseq.members
127
- parent.resolved_rules.members.each do |seq|
128
- if !seq.members.last.is_a?(Sass::Selector::SimpleSequence)
129
- raise Sass::SyntaxError.new("#{seq} can't extend: invalid selector")
136
+ parent.resolved_rules.members.each do |member|
137
+ unless member.members.last.is_a?(Sass::Selector::SimpleSequence)
138
+ raise Sass::SyntaxError.new("#{member} can't extend: invalid selector")
130
139
  end
131
140
 
132
- @extends[sel] = Extend.new(seq, sel, node, @parent_directives.dup, :not_found)
141
+ @extends[sel] = Extend.new(member, sel, node, @parent_directives.dup, :not_found)
133
142
  end
134
143
  end
135
144
 
@@ -138,8 +147,7 @@ class Sass::Tree::Visitors::Cssize < Sass::Tree::Visitors::Base
138
147
 
139
148
  # Modifies exception backtraces to include the imported file.
140
149
  def visit_import(node)
141
- # Don't use #visit_children to avoid adding the import node to the list of parents.
142
- node.children.map {|c| visit(c)}.flatten
150
+ visit_children_without_parent(node)
143
151
  rescue Sass::SyntaxError => e
144
152
  e.modify_backtrace(:filename => node.children.first.filename)
145
153
  e.add_backtrace(:filename => node.filename, :line => node.line)
@@ -150,28 +158,46 @@ class Sass::Tree::Visitors::Cssize < Sass::Tree::Visitors::Base
150
158
  # and merges it with other `@media` directives.
151
159
  def visit_media(node)
152
160
  yield unless bubble(node)
153
- media = node.children.select {|c| c.is_a?(Sass::Tree::MediaNode)}
154
- node.children.reject! {|c| c.is_a?(Sass::Tree::MediaNode)}
155
- media = media.select {|n| n.resolved_query = n.resolved_query.merge(node.resolved_query)}
156
- (node.children.empty? ? [] : [node]) + media
161
+
162
+ bubbled = node.children.select do |n|
163
+ n.is_a?(Sass::Tree::AtRootNode) || n.is_a?(Sass::Tree::MediaNode)
164
+ end
165
+ node.children -= bubbled
166
+
167
+ bubbled = bubbled.map do |n|
168
+ next visit(n) if n.is_a?(Sass::Tree::AtRootNode)
169
+ # Otherwise, n should be a MediaNode.
170
+ next [] unless n.resolved_query = n.resolved_query.merge(node.resolved_query)
171
+ n
172
+ end.flatten
173
+
174
+ (node.children.empty? ? [] : [node]) + bubbled
157
175
  end
158
176
 
159
177
  # Bubbles the `@supports` directive up through RuleNodes.
160
178
  def visit_supports(node)
161
- yield unless bubble(node)
162
- node
179
+ visit_directive(node) {yield}
163
180
  end
164
181
 
165
182
  # Asserts that all the traced children are valid in their new location.
166
183
  def visit_trace(node)
167
- # Don't use #visit_children to avoid adding the trace node to the list of parents.
168
- node.children.map {|c| visit(c)}.flatten
184
+ visit_children_without_parent(node)
169
185
  rescue Sass::SyntaxError => e
170
186
  e.modify_backtrace(:mixin => node.name, :filename => node.filename, :line => node.line)
171
187
  e.add_backtrace(:filename => node.filename, :line => node.line)
172
188
  raise e
173
189
  end
174
190
 
191
+ # Bubbles a directive up through RuleNodes.
192
+ def visit_directive(node)
193
+ return yield unless node.has_children
194
+ yield unless (bubbled = bubble(node))
195
+ at_roots = node.children.select {|n| n.is_a?(Sass::Tree::AtRootNode)}
196
+ node.children -= at_roots
197
+ at_roots.map! {|n| visit(n)}.flatten
198
+ (bubbled && node.children.empty? ? [] : [node]) + at_roots
199
+ end
200
+
175
201
  # Converts nested properties into flat properties
176
202
  # and updates the indentation of the prop node based on the nesting level.
177
203
  def visit_prop(node)
@@ -191,18 +217,16 @@ class Sass::Tree::Visitors::Cssize < Sass::Tree::Visitors::Base
191
217
  result
192
218
  end
193
219
 
194
- # Resolves parent references and nested selectors,
195
- # and updates the indentation of the rule node based on the nesting level.
220
+ # Updates the indentation of the rule node based on the nesting
221
+ # level. The selectors were resolved in {Perform}.
196
222
  def visit_rule(node)
197
- parent_resolved_rules = parent.is_a?(Sass::Tree::RuleNode) ? parent.resolved_rules : nil
198
- # It's possible for resolved_rules to be set if we've duplicated this node during @media bubbling
199
- node.resolved_rules ||= node.parsed_rules.resolve_parent_refs(parent_resolved_rules)
200
-
201
223
  yield
202
224
 
203
225
  rules = node.children.select {|c| c.is_a?(Sass::Tree::RuleNode) || c.bubbles?}
204
226
  props = node.children.reject {|c| c.is_a?(Sass::Tree::RuleNode) || c.bubbles? || c.invisible?}
205
227
 
228
+ rules.map {|c| c.is_a?(Sass::Tree::AtRootNode) ? visit(c) : c}.flatten
229
+
206
230
  unless props.empty?
207
231
  node.children = props
208
232
  rules.each {|r| r.tabs += 1} if node.style == :nested
@@ -214,6 +238,22 @@ class Sass::Tree::Visitors::Cssize < Sass::Tree::Visitors::Base
214
238
  rules
215
239
  end
216
240
 
241
+ def visit_atroot(node)
242
+ if @parent_directives.any? {|n| node.exclude_node?(n)}
243
+ return node if node.exclude_node?(parent)
244
+
245
+ new_rule = parent.dup
246
+ new_rule.children = node.children
247
+ node.children = [new_rule]
248
+ return node
249
+ end
250
+
251
+ results = visit_children_without_parent(node)
252
+ results.each {|n| n.tabs += node.tabs}
253
+ results.last.group_end = node.group_end unless results.empty?
254
+ results
255
+ end
256
+
217
257
  private
218
258
 
219
259
  def bubble(node)
@@ -1,5 +1,6 @@
1
1
  # A visitor for copying the full structure of a Sass tree.
2
2
  class Sass::Tree::Visitors::DeepCopy < Sass::Tree::Visitors::Base
3
+
3
4
  protected
4
5
 
5
6
  def visit(node)
@@ -22,7 +23,7 @@ class Sass::Tree::Visitors::DeepCopy < Sass::Tree::Visitors::Base
22
23
  end
23
24
 
24
25
  def visit_extend(node)
25
- node.selector = node.selector.map {|c| c.is_a?(Sass::Script::Node) ? c.deep_copy : c}
26
+ node.selector = node.selector.map {|c| c.is_a?(Sass::Script::Tree::Node) ? c.deep_copy : c}
26
27
  yield
27
28
  end
28
29
 
@@ -55,7 +56,7 @@ class Sass::Tree::Visitors::DeepCopy < Sass::Tree::Visitors::Base
55
56
  end
56
57
 
57
58
  def visit_prop(node)
58
- node.name = node.name.map {|c| c.is_a?(Sass::Script::Node) ? c.deep_copy : c}
59
+ node.name = node.name.map {|c| c.is_a?(Sass::Script::Tree::Node) ? c.deep_copy : c}
59
60
  node.value = node.value.deep_copy
60
61
  yield
61
62
  end
@@ -66,7 +67,7 @@ class Sass::Tree::Visitors::DeepCopy < Sass::Tree::Visitors::Base
66
67
  end
67
68
 
68
69
  def visit_rule(node)
69
- node.rule = node.rule.map {|c| c.is_a?(Sass::Script::Node) ? c.deep_copy : c}
70
+ node.rule = node.rule.map {|c| c.is_a?(Sass::Script::Tree::Node) ? c.deep_copy : c}
70
71
  yield
71
72
  end
72
73
 
@@ -86,12 +87,12 @@ class Sass::Tree::Visitors::DeepCopy < Sass::Tree::Visitors::Base
86
87
  end
87
88
 
88
89
  def visit_directive(node)
89
- node.value = node.value.map {|c| c.is_a?(Sass::Script::Node) ? c.deep_copy : c}
90
+ node.value = node.value.map {|c| c.is_a?(Sass::Script::Tree::Node) ? c.deep_copy : c}
90
91
  yield
91
92
  end
92
93
 
93
94
  def visit_media(node)
94
- node.query = node.query.map {|c| c.is_a?(Sass::Script::Node) ? c.deep_copy : c}
95
+ node.query = node.query.map {|c| c.is_a?(Sass::Script::Tree::Node) ? c.deep_copy : c}
95
96
  yield
96
97
  end
97
98
 
@@ -49,7 +49,7 @@ class Sass::Tree::Visitors::Extend < Sass::Tree::Visitors::Base
49
49
  def self.check_extends_fired!(extends)
50
50
  extends.each_value do |ex|
51
51
  next if ex.result == :succeeded || ex.node.optional?
52
- warn = "\"#{ex.extender}\" failed to @extend \"#{ex.target.join}\"."
52
+ message = "\"#{ex.extender}\" failed to @extend \"#{ex.target.join}\"."
53
53
  reason =
54
54
  if ex.result == :not_found
55
55
  "The selector \"#{ex.target.join}\" was not found."
@@ -57,12 +57,12 @@ class Sass::Tree::Visitors::Extend < Sass::Tree::Visitors::Base
57
57
  "No selectors matching \"#{ex.target.join}\" could be unified with \"#{ex.extender}\"."
58
58
  end
59
59
 
60
- Sass::Util.sass_warn <<WARN
61
- WARNING on line #{ex.node.line}#{" of #{ex.node.filename}" if ex.node.filename}: #{warn}
62
- #{reason}
63
- This will be an error in future releases of Sass.
64
- Use "@extend #{ex.target.join} !optional" if the extend should be able to fail.
65
- WARN
60
+ # TODO(nweiz): this should use the Sass stack trace of the extend node.
61
+ raise Sass::SyntaxError.new(<<MESSAGE, :filename => ex.node.filename, :line => ex.node.line)
62
+ #{message}
63
+ #{reason}
64
+ Use "@extend #{ex.target.join} !optional" if the extend should be able to fail.
65
+ MESSAGE
66
66
  end
67
67
  end
68
68
  end