oreorenasass 3.4.4 → 3.4.5

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -5,10 +5,10 @@ module Sass
5
5
  # @see Sass::Tree
6
6
  class WarnNode < Node
7
7
  # The expression to print.
8
- # @return [Script::Tree::Node]
8
+ # @return [Script::Node]
9
9
  attr_accessor :expr
10
10
 
11
- # @param expr [Script::Tree::Node] The expression to print
11
+ # @param expr [Script::Node] The expression to print
12
12
  def initialize(expr)
13
13
  @expr = expr
14
14
  super()
@@ -6,10 +6,10 @@ module Sass::Tree
6
6
  # @see Sass::Tree
7
7
  class WhileNode < Node
8
8
  # The parse tree for the continuation expression.
9
- # @return [Script::Tree::Node]
9
+ # @return [Script::Node]
10
10
  attr_accessor :expr
11
11
 
12
- # @param expr [Script::Tree::Node] See \{#expr}
12
+ # @param expr [Script::Node] See \{#expr}
13
13
  def initialize(expr)
14
14
  @expr = expr
15
15
  super()
data/lib/sass/util.rb CHANGED
@@ -1,12 +1,9 @@
1
- # -*- coding: utf-8 -*-
2
1
  require 'erb'
3
2
  require 'set'
4
3
  require 'enumerator'
5
4
  require 'stringio'
6
5
  require 'rbconfig'
7
- require 'uri'
8
6
  require 'thread'
9
- require 'pathname'
10
7
 
11
8
  require 'sass/root'
12
9
  require 'sass/util/subset_map'
@@ -18,7 +15,7 @@ module Sass
18
15
 
19
16
  # An array of ints representing the Ruby version number.
20
17
  # @api public
21
- RUBY_VERSION_COMPONENTS = RUBY_VERSION.split(".").map {|s| s.to_i}
18
+ RUBY_VERSION = ::RUBY_VERSION.split(".").map {|s| s.to_i}
22
19
 
23
20
  # The Ruby engine we're running under. Defaults to `"ruby"`
24
21
  # if the top-level constant is undefined.
@@ -41,7 +38,7 @@ module Sass
41
38
  # @param arr [Array<(Object, Object)>] An array of pairs
42
39
  # @return [Hash] A hash
43
40
  def to_hash(arr)
44
- ordered_hash(*arr.compact)
41
+ Hash[arr.compact]
45
42
  end
46
43
 
47
44
  # Maps the keys in a hash according to a block.
@@ -57,7 +54,7 @@ module Sass
57
54
  # @see #map_vals
58
55
  # @see #map_hash
59
56
  def map_keys(hash)
60
- map_hash(hash) {|k, v| [yield(k), v]}
57
+ to_hash(hash.map {|k, v| [yield(k), v]})
61
58
  end
62
59
 
63
60
  # Maps the values in a hash according to a block.
@@ -73,14 +70,7 @@ module Sass
73
70
  # @see #map_keys
74
71
  # @see #map_hash
75
72
  def map_vals(hash)
76
- # We don't delegate to map_hash for performance here
77
- # because map_hash does more than is necessary.
78
- rv = hash.class.new
79
- hash = hash.as_stored if hash.is_a?(NormalizedMap)
80
- hash.each do |k, v|
81
- rv[k] = yield(v)
82
- end
83
- rv
73
+ to_hash(hash.map {|k, v| [k, yield(v)]})
84
74
  end
85
75
 
86
76
  # Maps the key-value pairs of a hash according to a block.
@@ -97,15 +87,8 @@ module Sass
97
87
  # @see #map_keys
98
88
  # @see #map_vals
99
89
  def map_hash(hash)
100
- # Copy and modify is more performant than mapping to an array and using
101
- # to_hash on the result.
102
- rv = hash.class.new
103
- hash.each do |k, v|
104
- new_key, new_value = yield(k, v)
105
- new_key = hash.denormalize(new_key) if hash.is_a?(NormalizedMap) && new_key == k
106
- rv[new_key] = new_value
107
- end
108
- rv
90
+ # Using &block here completely hoses performance on 1.8.
91
+ to_hash(hash.map {|k, v| yield k, v})
109
92
  end
110
93
 
111
94
  # Computes the powerset of the given array.
@@ -163,43 +146,6 @@ module Sass
163
146
  end
164
147
  end
165
148
 
166
- # Non-destructively replaces all occurrences of a subsequence in an array
167
- # with another subsequence.
168
- #
169
- # @example
170
- # replace_subseq([1, 2, 3, 4, 5], [2, 3], [:a, :b])
171
- # #=> [1, :a, :b, 4, 5]
172
- #
173
- # @param arr [Array] The array whose subsequences will be replaced.
174
- # @param subseq [Array] The subsequence to find and replace.
175
- # @param replacement [Array] The sequence that `subseq` will be replaced with.
176
- # @return [Array] `arr` with `subseq` replaced with `replacement`.
177
- def replace_subseq(arr, subseq, replacement)
178
- new = []
179
- matched = []
180
- i = 0
181
- arr.each do |elem|
182
- if elem != subseq[i]
183
- new.push(*matched)
184
- matched = []
185
- i = 0
186
- new << elem
187
- next
188
- end
189
-
190
- if i == subseq.length - 1
191
- matched = []
192
- i = 0
193
- new.push(*replacement)
194
- else
195
- matched << elem
196
- i += 1
197
- end
198
- end
199
- new.push(*matched)
200
- new
201
- end
202
-
203
149
  # Intersperses a value in an enumerable, as would be done with `Array#join`
204
150
  # but without concatenating the array together afterwards.
205
151
  #
@@ -210,19 +156,6 @@ module Sass
210
156
  enum.inject([]) {|a, e| a << e << val}[0...-1]
211
157
  end
212
158
 
213
- def slice_by(enum)
214
- results = []
215
- enum.each do |value|
216
- key = yield(value)
217
- if !results.empty? && results.last.first == key
218
- results.last.last << value
219
- else
220
- results << [key, [value]]
221
- end
222
- end
223
- results
224
- end
225
-
226
159
  # Substitutes a sub-array of one array with another sub-array.
227
160
  #
228
161
  # @param ary [Array] The array in which to make the substitution
@@ -232,8 +165,8 @@ module Sass
232
165
  res = ary.dup
233
166
  i = 0
234
167
  while i < res.size
235
- if res[i...i + from.size] == from
236
- res[i...i + from.size] = to
168
+ if res[i...i+from.size] == from
169
+ res[i...i+from.size] = to
237
170
  end
238
171
  i += 1
239
172
  end
@@ -284,7 +217,7 @@ module Sass
284
217
  x = [nil, *x]
285
218
  y = [nil, *y]
286
219
  block ||= proc {|a, b| a == b && a}
287
- lcs_backtrace(lcs_table(x, y, &block), x, y, x.size - 1, y.size - 1, &block)
220
+ lcs_backtrace(lcs_table(x, y, &block), x, y, x.size-1, y.size-1, &block)
288
221
  end
289
222
 
290
223
  # Converts a Hash to an Array. This is usually identical to `Hash#to_a`,
@@ -298,28 +231,27 @@ module Sass
298
231
  # @return [Array]
299
232
  def hash_to_a(hash)
300
233
  return hash.to_a unless ruby1_8? || defined?(Test::Unit)
301
- hash.sort_by {|k, v| k}
234
+ return hash.sort_by {|k, v| k}
302
235
  end
303
236
 
304
237
  # Performs the equivalent of `enum.group_by.to_a`, but with a guaranteed
305
- # order. Unlike {Util#hash_to_a}, the resulting order isn't sorted key order;
238
+ # order. Unlike [#hash_to_a], the resulting order isn't sorted key order;
306
239
  # instead, it's the same order as `#group_by` has under Ruby 1.9 (key
307
240
  # appearance order).
308
241
  #
309
242
  # @param enum [Enumerable]
310
243
  # @return [Array<[Object, Array]>] An array of pairs.
311
- def group_by_to_a(enum)
312
- return enum.group_by {|e| yield(e)}.to_a unless ruby1_8?
244
+ def group_by_to_a(enum, &block)
245
+ return enum.group_by(&block).to_a unless ruby1_8?
313
246
  order = {}
314
247
  arr = []
315
- groups = enum.group_by do |e|
316
- res = yield(e)
248
+ enum.group_by do |e|
249
+ res = block[e]
317
250
  unless order.include?(res)
318
251
  order[res] = order.size
319
252
  end
320
253
  res
321
- end
322
- groups.each do |key, vals|
254
+ end.each do |key, vals|
323
255
  arr[order[key]] = [key, vals]
324
256
  end
325
257
  arr
@@ -327,7 +259,7 @@ module Sass
327
259
 
328
260
  # Returns a sub-array of `minuend` containing only elements that are also in
329
261
  # `subtrahend`. Ensures that the return value has the same order as
330
- # `minuend`, even on Rubinius where that's not guaranteed by `Array#-`.
262
+ # `minuend`, even on Rubinius where that's not guaranteed by {Array#-}.
331
263
  #
332
264
  # @param minuend [Array]
333
265
  # @param subtrahend [Array]
@@ -338,22 +270,10 @@ module Sass
338
270
  minuend.select {|e| set.include?(e)}
339
271
  end
340
272
 
341
- # Returns the maximum of `val1` and `val2`. We use this over \{Array.max} to
342
- # avoid unnecessary garbage collection.
343
- def max(val1, val2)
344
- val1 > val2 ? val1 : val2
345
- end
346
-
347
- # Returns the minimum of `val1` and `val2`. We use this over \{Array.min} to
348
- # avoid unnecessary garbage collection.
349
- def min(val1, val2)
350
- val1 <= val2 ? val1 : val2
351
- end
352
-
353
273
  # Returns a string description of the character that caused an
354
274
  # `Encoding::UndefinedConversionError`.
355
275
  #
356
- # @param e [Encoding::UndefinedConversionError]
276
+ # @param [Encoding::UndefinedConversionError]
357
277
  # @return [String]
358
278
  def undefined_conversion_error_char(e)
359
279
  # Rubinius (as of 2.0.0.rc1) pre-quotes the error character.
@@ -361,7 +281,7 @@ module Sass
361
281
  # JRuby (as of 1.7.2) doesn't have an error_char field on
362
282
  # Encoding::UndefinedConversionError.
363
283
  return e.error_char.dump unless jruby?
364
- e.message[/^"[^"]+"/] # "
284
+ e.message[/^"[^"]+"/] #"
365
285
  end
366
286
 
367
287
  # Asserts that `value` falls within `range` (inclusive), leaving
@@ -369,14 +289,14 @@ module Sass
369
289
  #
370
290
  # @param name [String] The name of the value. Used in the error message.
371
291
  # @param range [Range] The allowed range of values.
372
- # @param value [Numeric, Sass::Script::Value::Number] The value to check.
292
+ # @param value [Numeric, Sass::Script::Number] The value to check.
373
293
  # @param unit [String] The unit of the value. Used in error reporting.
374
294
  # @return [Numeric] `value` adjusted to fall within range, if it
375
295
  # was outside by a floating-point margin.
376
- def check_range(name, range, value, unit = '')
296
+ def check_range(name, range, value, unit='')
377
297
  grace = (-0.00001..0.00001)
378
298
  str = value.to_s
379
- value = value.value if value.is_a?(Sass::Script::Value::Number)
299
+ value = value.value if value.is_a?(Sass::Script::Number)
380
300
  return value if range.include?(value)
381
301
  return range.first if grace.include?(value - range.first)
382
302
  return range.last if grace.include?(value - range.last)
@@ -404,8 +324,7 @@ module Sass
404
324
  # Returns information about the caller of the previous method.
405
325
  #
406
326
  # @param entry [String] An entry in the `#caller` list, or a similarly formatted string
407
- # @return [[String, Fixnum, (String, nil)]]
408
- # An array containing the filename, line, and method name of the caller.
327
+ # @return [[String, Fixnum, (String, nil)]] An array containing the filename, line, and method name of the caller.
409
328
  # The method name may be nil
410
329
  def caller_info(entry = nil)
411
330
  # JRuby evaluates `caller` incorrectly when it's in an actual default argument.
@@ -463,17 +382,6 @@ module Sass
463
382
  raise NotImplementedError.new("#{obj.class} must implement ##{caller_info[2]}")
464
383
  end
465
384
 
466
- # Prints a deprecation warning for the caller method.
467
- #
468
- # @param obj [Object] `self`
469
- # @param message [String] A message describing what to do instead.
470
- def deprecated(obj, message = nil)
471
- obj_class = obj.is_a?(Class) ? "#{obj}." : "#{obj.class}#"
472
- full_message = "DEPRECATION WARNING: #{obj_class}#{caller_info[2]} " +
473
- "will be removed in a future version of Sass.#{("\n" + message) if message}"
474
- Sass::Util.sass_warn full_message
475
- end
476
-
477
385
  # Silence all output to STDERR within a block.
478
386
  #
479
387
  # @yield A block in which no output will be printed to STDERR
@@ -484,6 +392,7 @@ module Sass
484
392
  $stderr = the_real_stderr
485
393
  end
486
394
 
395
+ @@silence_warnings = false
487
396
  # Silences all Sass warnings within a block.
488
397
  #
489
398
  # @yield A block in which no Sass warnings will be printed
@@ -515,7 +424,7 @@ module Sass
515
424
  raise "ERROR: Rails.root is nil!"
516
425
  end
517
426
  return RAILS_ROOT.to_s if defined?(RAILS_ROOT)
518
- nil
427
+ return nil
519
428
  end
520
429
 
521
430
  # Returns the environment of the Rails application,
@@ -526,7 +435,7 @@ module Sass
526
435
  def rails_env
527
436
  return ::Rails.env.to_s if defined?(::Rails.env)
528
437
  return RAILS_ENV.to_s if defined?(RAILS_ENV)
529
- nil
438
+ return nil
530
439
  end
531
440
 
532
441
  # Returns whether this environment is using ActionPack
@@ -552,21 +461,6 @@ module Sass
552
461
  version_geq(ActionPack::VERSION::STRING, version)
553
462
  end
554
463
 
555
- # Returns whether this environment is using Listen
556
- # version 2.0.0 or greater.
557
- #
558
- # @return [Boolean]
559
- def listen_geq_2?
560
- return @listen_geq_2 unless @listen_geq_2.nil?
561
- @listen_geq_2 =
562
- begin
563
- require 'listen/version'
564
- version_geq(::Listen::VERSION, '2.0.0')
565
- rescue LoadError
566
- false
567
- end
568
- end
569
-
570
464
  # Returns an ActionView::Template* class.
571
465
  # In pre-3.0 versions of Rails, most of these classes
572
466
  # were of the form `ActionView::TemplateFoo`,
@@ -577,101 +471,52 @@ module Sass
577
471
  # or `ActionView::Template::Error`.
578
472
  def av_template_class(name)
579
473
  return ActionView.const_get("Template#{name}") if ActionView.const_defined?("Template#{name}")
580
- ActionView::Template.const_get(name.to_s)
474
+ return ActionView::Template.const_get(name.to_s)
581
475
  end
582
476
 
583
477
  ## Cross-OS Compatibility
584
- #
585
- # These methods are cached because some of them are called quite frequently
586
- # and even basic checks like String#== are too costly to be called repeatedly.
587
478
 
588
479
  # Whether or not this is running on Windows.
589
480
  #
590
481
  # @return [Boolean]
591
482
  def windows?
592
- return @windows if defined?(@windows)
593
- @windows = (RbConfig::CONFIG['host_os'] =~ /mswin|windows|mingw/i)
483
+ RbConfig::CONFIG['host_os'] =~ /mswin|windows|mingw/i
594
484
  end
595
485
 
596
486
  # Whether or not this is running on IronRuby.
597
487
  #
598
488
  # @return [Boolean]
599
489
  def ironruby?
600
- return @ironruby if defined?(@ironruby)
601
- @ironruby = RUBY_ENGINE == "ironruby"
490
+ RUBY_ENGINE == "ironruby"
602
491
  end
603
492
 
604
493
  # Whether or not this is running on Rubinius.
605
494
  #
606
495
  # @return [Boolean]
607
496
  def rbx?
608
- return @rbx if defined?(@rbx)
609
- @rbx = RUBY_ENGINE == "rbx"
497
+ RUBY_ENGINE == "rbx"
610
498
  end
611
499
 
612
500
  # Whether or not this is running on JRuby.
613
501
  #
614
502
  # @return [Boolean]
615
503
  def jruby?
616
- return @jruby if defined?(@jruby)
617
- @jruby = RUBY_PLATFORM =~ /java/
504
+ RUBY_PLATFORM =~ /java/
618
505
  end
619
506
 
620
507
  # Returns an array of ints representing the JRuby version number.
621
508
  #
622
509
  # @return [Array<Fixnum>]
623
510
  def jruby_version
624
- @jruby_version ||= ::JRUBY_VERSION.split(".").map {|s| s.to_i}
511
+ $jruby_version ||= ::JRUBY_VERSION.split(".").map {|s| s.to_i}
625
512
  end
626
513
 
627
514
  # Like `Dir.glob`, but works with backslash-separated paths on Windows.
628
515
  #
629
516
  # @param path [String]
630
- def glob(path)
517
+ def glob(path, &block)
631
518
  path = path.gsub('\\', '/') if windows?
632
- if block_given?
633
- Dir.glob(path) {|f| yield(f)}
634
- else
635
- Dir.glob(path)
636
- end
637
- end
638
-
639
- # Like `Pathname.new`, but normalizes Windows paths to always use backslash
640
- # separators.
641
- #
642
- # `Pathname#relative_path_from` can break if the two pathnames aren't
643
- # consistent in their slash style.
644
- #
645
- # @param path [String]
646
- # @return [Pathname]
647
- def pathname(path)
648
- path = path.tr("/", "\\") if windows?
649
- Pathname.new(path)
650
- end
651
-
652
- # Like `Pathname#cleanpath`, but normalizes Windows paths to always use
653
- # backslash separators. Normally, `Pathname#cleanpath` actually does the
654
- # reverse -- it will convert backslashes to forward slashes, which can break
655
- # `Pathname#relative_path_from`.
656
- #
657
- # @param path [String, Pathname]
658
- # @return [Pathname]
659
- def cleanpath(path)
660
- path = Pathname.new(path) unless path.is_a?(Pathname)
661
- pathname(path.cleanpath.to_s)
662
- end
663
-
664
- # Converts `path` to a "file:" URI. This handles Windows paths correctly.
665
- #
666
- # @param path [String, Pathname]
667
- # @return [String]
668
- def file_uri_from_path(path)
669
- path = path.to_s if path.is_a?(Pathname)
670
- path = Sass::Util.escape_uri(path)
671
- return path.start_with?('/') ? "file://" + path : path unless windows?
672
- return "file:///" + path.tr("\\", "/") if path =~ /^[a-zA-Z]:[\/\\]/
673
- return "file://" + path.tr("\\", "/") if path =~ /\\\\[^\\]+\\[^\\\/]+/
674
- path.tr("\\", "/")
519
+ Dir.glob(path, &block)
675
520
  end
676
521
 
677
522
  # Prepare a value for a destructuring assignment (e.g. `a, b =
@@ -693,8 +538,7 @@ module Sass
693
538
  #
694
539
  # @return [Boolean]
695
540
  def ruby1?
696
- return @ruby1 if defined?(@ruby1)
697
- @ruby1 = RUBY_VERSION_COMPONENTS[0] <= 1
541
+ Sass::Util::RUBY_VERSION[0] <= 1
698
542
  end
699
543
 
700
544
  # Whether or not this is running under Ruby 1.8 or lower.
@@ -706,9 +550,7 @@ module Sass
706
550
  def ruby1_8?
707
551
  # IronRuby says its version is 1.9, but doesn't support any of the encoding APIs.
708
552
  # We have to fall back to 1.8 behavior.
709
- return @ruby1_8 if defined?(@ruby1_8)
710
- @ruby1_8 = ironruby? ||
711
- (RUBY_VERSION_COMPONENTS[0] == 1 && RUBY_VERSION_COMPONENTS[1] < 9)
553
+ ironruby? || (Sass::Util::RUBY_VERSION[0] == 1 && Sass::Util::RUBY_VERSION[1] < 9)
712
554
  end
713
555
 
714
556
  # Whether or not this is running under Ruby 1.8.6 or lower.
@@ -716,132 +558,129 @@ module Sass
716
558
  #
717
559
  # @return [Boolean]
718
560
  def ruby1_8_6?
719
- return @ruby1_8_6 if defined?(@ruby1_8_6)
720
- @ruby1_8_6 = ruby1_8? && RUBY_VERSION_COMPONENTS[2] < 7
721
- end
722
-
723
- # Whether or not this is running under Ruby 1.9.2 exactly.
724
- #
725
- # @return [Boolean]
726
- def ruby1_9_2?
727
- return @ruby1_9_2 if defined?(@ruby1_9_2)
728
- @ruby1_9_2 = RUBY_VERSION_COMPONENTS == [1, 9, 2]
561
+ ruby1_8? && Sass::Util::RUBY_VERSION[2] < 7
729
562
  end
730
563
 
731
564
  # Wehter or not this is running under JRuby 1.6 or lower.
732
565
  def jruby1_6?
733
- return @jruby1_6 if defined?(@jruby1_6)
734
- @jruby1_6 = jruby? && jruby_version[0] == 1 && jruby_version[1] < 7
566
+ jruby? && jruby_version[0] == 1 && jruby_version[1] < 7
735
567
  end
736
568
 
737
569
  # Whether or not this is running under MacRuby.
738
570
  #
739
571
  # @return [Boolean]
740
572
  def macruby?
741
- return @macruby if defined?(@macruby)
742
- @macruby = RUBY_ENGINE == 'macruby'
573
+ RUBY_ENGINE == 'macruby'
743
574
  end
744
575
 
745
- require 'sass/util/ordered_hash' if ruby1_8?
746
-
747
- # Converts a hash or a list of pairs into an order-preserving hash.
748
- #
749
- # On Ruby 1.8.7, this uses the orderedhash gem to simulate an
750
- # order-preserving hash. On Ruby 1.9 and up, it just uses the native Hash
751
- # class, since that preserves the order itself.
752
- #
753
- # @overload ordered_hash(hash)
754
- # @param hash [Hash] a normal hash to convert to an ordered hash
755
- # @return [Hash]
756
- # @overload ordered_hash(*pairs)
757
- # @example
758
- # ordered_hash([:foo, "bar"], [:baz, "bang"])
759
- # #=> {:foo => "bar", :baz => "bang"}
760
- # ordered_hash #=> {}
761
- # @param pairs [Array<(Object, Object)>] the list of key/value pairs for
762
- # the hash.
763
- # @return [Hash]
764
- def ordered_hash(*pairs_or_hash)
765
- if pairs_or_hash.length == 1 && pairs_or_hash.first.is_a?(Hash)
766
- hash = pairs_or_hash.first
767
- return hash unless ruby1_8?
768
- return OrderedHash.new.merge hash
576
+ # Checks that the encoding of a string is valid in Ruby 1.9
577
+ # and cleans up potential encoding gotchas like the UTF-8 BOM.
578
+ # If it's not, yields an error string describing the invalid character
579
+ # and the line on which it occurrs.
580
+ #
581
+ # @param str [String] The string of which to check the encoding
582
+ # @yield [msg] A block in which an encoding error can be raised.
583
+ # Only yields if there is an encoding error
584
+ # @yieldparam msg [String] The error message to be raised
585
+ # @return [String] `str`, potentially with encoding gotchas like BOMs removed
586
+ def check_encoding(str)
587
+ if ruby1_8?
588
+ return str.gsub(/\A\xEF\xBB\xBF/, '') # Get rid of the UTF-8 BOM
589
+ elsif str.valid_encoding?
590
+ # Get rid of the Unicode BOM if possible
591
+ if str.encoding.name =~ /^UTF-(8|16|32)(BE|LE)?$/
592
+ return str.gsub(Regexp.new("\\A\uFEFF".encode(str.encoding.name)), '')
593
+ else
594
+ return str
595
+ end
769
596
  end
770
597
 
771
- return Hash[pairs_or_hash] unless ruby1_8?
772
- (pairs_or_hash.is_a?(NormalizedMap) ? NormalizedMap : OrderedHash)[*flatten(pairs_or_hash, 1)]
773
- end
774
-
775
- unless ruby1_8?
776
- CHARSET_REGEXP = /\A@charset "([^"]+)"/
777
- UTF_8_BOM = "\xEF\xBB\xBF".force_encoding('BINARY')
778
- UTF_16BE_BOM = "\xFE\xFF".force_encoding('BINARY')
779
- UTF_16LE_BOM = "\xFF\xFE".force_encoding('BINARY')
598
+ encoding = str.encoding
599
+ newlines = Regexp.new("\r\n|\r|\n".encode(encoding).force_encoding("binary"))
600
+ str.force_encoding("binary").split(newlines).each_with_index do |line, i|
601
+ begin
602
+ line.encode(encoding)
603
+ rescue Encoding::UndefinedConversionError => e
604
+ yield <<MSG.rstrip, i + 1
605
+ Invalid #{encoding.name} character #{undefined_conversion_error_char(e)}
606
+ MSG
607
+ end
608
+ end
609
+ return str
780
610
  end
781
611
 
782
612
  # Like {\#check\_encoding}, but also checks for a `@charset` declaration
783
613
  # at the beginning of the file and uses that encoding if it exists.
784
614
  #
785
- # Sass follows CSS's decoding rules.
615
+ # The Sass encoding rules are simple.
616
+ # If a `@charset` declaration exists,
617
+ # we assume that that's the original encoding of the document.
618
+ # Otherwise, we use whatever encoding Ruby has.
619
+ # Then we convert that to UTF-8 to process internally.
620
+ # The UTF-8 end result is what's returned by this method.
786
621
  #
787
622
  # @param str [String] The string of which to check the encoding
623
+ # @yield [msg] A block in which an encoding error can be raised.
624
+ # Only yields if there is an encoding error
625
+ # @yieldparam msg [String] The error message to be raised
788
626
  # @return [(String, Encoding)] The original string encoded as UTF-8,
789
627
  # and the source encoding of the string (or `nil` under Ruby 1.8)
790
628
  # @raise [Encoding::UndefinedConversionError] if the source encoding
791
629
  # cannot be converted to UTF-8
792
630
  # @raise [ArgumentError] if the document uses an unknown encoding with `@charset`
793
- # @raise [Sass::SyntaxError] If the document declares an encoding that
794
- # doesn't match its contents, or it doesn't declare an encoding and its
795
- # contents are invalid in the native encoding.
796
- def check_sass_encoding(str)
797
- # On Ruby 1.8 we can't do anything complicated with encodings.
798
- # Instead, we just strip out a UTF-8 BOM if it exists and
799
- # sanitize according to Section 3.3 of CSS Syntax Level 3. We
800
- # don't sanitize null characters since they might be components
801
- # of other characters.
802
- if ruby1_8?
803
- return str.gsub(/\A\xEF\xBB\xBF/, '').gsub(/\r\n?|\f/, "\n"), nil
804
- end
805
-
806
- # Determine the fallback encoding following section 3.2 of CSS Syntax Level 3 and Encodings:
807
- # http://www.w3.org/TR/2013/WD-css-syntax-3-20130919/#determine-the-fallback-encoding
808
- # http://encoding.spec.whatwg.org/#decode
809
- binary = str.dup.force_encoding("BINARY")
810
- if binary.start_with?(UTF_8_BOM)
811
- binary.slice! 0, UTF_8_BOM.length
812
- str = binary.force_encoding('UTF-8')
813
- elsif binary.start_with?(UTF_16BE_BOM)
814
- binary.slice! 0, UTF_16BE_BOM.length
815
- str = binary.force_encoding('UTF-16BE')
816
- elsif binary.start_with?(UTF_16LE_BOM)
817
- binary.slice! 0, UTF_16LE_BOM.length
818
- str = binary.force_encoding('UTF-16LE')
819
- elsif binary =~ CHARSET_REGEXP
820
- charset = $1.force_encoding('US-ASCII')
821
- # Ruby 1.9.2 doesn't recognize a UTF-16 encoding without an endian marker.
822
- if ruby1_9_2? && charset.downcase == 'utf-16'
823
- encoding = Encoding.find('UTF-8')
824
- else
825
- encoding = Encoding.find(charset)
826
- if encoding.name == 'UTF-16' || encoding.name == 'UTF-16BE'
827
- encoding = Encoding.find('UTF-8')
631
+ def check_sass_encoding(str, &block)
632
+ return check_encoding(str, &block), nil if ruby1_8?
633
+ # We allow any printable ASCII characters but double quotes in the charset decl
634
+ bin = str.dup.force_encoding("BINARY")
635
+ encoding = Sass::Util::ENCODINGS_TO_CHECK.find do |enc|
636
+ re = Sass::Util::CHARSET_REGEXPS[enc]
637
+ re && bin =~ re
638
+ end
639
+ charset, bom = $1, $2
640
+ if charset
641
+ charset = charset.force_encoding(encoding).encode("UTF-8")
642
+ if endianness = encoding[/[BL]E$/]
643
+ begin
644
+ Encoding.find(charset + endianness)
645
+ charset << endianness
646
+ rescue ArgumentError # Encoding charset + endianness doesn't exist
828
647
  end
829
648
  end
830
- str = binary.force_encoding(encoding)
831
- elsif str.encoding.name == "ASCII-8BIT"
832
- # Normally we want to fall back on believing the Ruby string
833
- # encoding, but if that's just binary we want to make sure
834
- # it's valid UTF-8.
835
- str = str.force_encoding('utf-8')
649
+ str.force_encoding(charset)
650
+ elsif bom
651
+ str.force_encoding(encoding)
836
652
  end
837
653
 
838
- find_encoding_error(str) unless str.valid_encoding?
654
+ str = check_encoding(str, &block)
655
+ return str.encode("UTF-8"), str.encoding
656
+ end
839
657
 
840
- begin
841
- # If the string is valid, preprocess it according to section 3.3 of CSS Syntax Level 3.
842
- return str.encode("UTF-8").gsub(/\r\n?|\f/, "\n").tr("\u0000", "�"), str.encoding
843
- rescue EncodingError
844
- find_encoding_error(str)
658
+ unless ruby1_8?
659
+ # @private
660
+ def _enc(string, encoding)
661
+ string.encode(encoding).force_encoding("BINARY")
662
+ end
663
+
664
+ # We could automatically add in any non-ASCII-compatible encodings here,
665
+ # but there's not really a good way to do that
666
+ # without manually checking that each encoding
667
+ # encodes all ASCII characters properly,
668
+ # which takes long enough to affect the startup time of the CLI.
669
+ ENCODINGS_TO_CHECK = %w[UTF-8 UTF-16BE UTF-16LE UTF-32BE UTF-32LE]
670
+
671
+ CHARSET_REGEXPS = Hash.new do |h, e|
672
+ h[e] =
673
+ begin
674
+ # /\A(?:\uFEFF)?@charset "(.*?)"|\A(\uFEFF)/
675
+ Regexp.new(/\A(?:#{_enc("\uFEFF", e)})?#{
676
+ _enc('@charset "', e)}(.*?)#{_enc('"', e)}|\A(#{
677
+ _enc("\uFEFF", e)})/)
678
+ rescue Encoding::ConverterNotFoundError => _
679
+ nil # JRuby on Java 5 doesn't support UTF-32
680
+ rescue
681
+ # /\A@charset "(.*?)"/
682
+ Regexp.new(/\A#{_enc('@charset "', e)}(.*?)#{_enc('"', e)}/)
683
+ end
845
684
  end
846
685
  end
847
686
 
@@ -926,24 +765,6 @@ module Sass
926
765
  arr.inject([]) {|res, e| e.is_a?(Array) ? res.concat(flatten(e, n - 1)) : res << e}
927
766
  end
928
767
 
929
- # Flattens the first level of nested arrays in `arrs`. Unlike
930
- # `Array#flatten`, this orders the result by taking the first
931
- # values from each array in order, then the second, and so on.
932
- #
933
- # @param arrs [Array] The array to flatten.
934
- # @return [Array] The flattened array.
935
- def flatten_vertically(arrs)
936
- result = []
937
- arrs = arrs.map {|sub| sub.is_a?(Array) ? sub.dup : Array(sub)}
938
- until arrs.empty?
939
- arrs.reject! do |arr|
940
- result << arr.shift
941
- arr.empty?
942
- end
943
- end
944
- result
945
- end
946
-
947
768
  # Returns the hash code for a set in a cross-version manner.
948
769
  # Aggravatingly, this is order-dependent in Ruby 1.8.6.
949
770
  #
@@ -965,15 +786,14 @@ module Sass
965
786
  set1.to_a.uniq.sort_by {|e| e.hash}.eql?(set2.to_a.uniq.sort_by {|e| e.hash})
966
787
  end
967
788
 
968
- # Like `Object#inspect`, but preserves non-ASCII characters rather than
969
- # escaping them under Ruby 1.9.2. This is necessary so that the
970
- # precompiled Haml template can be `#encode`d into `@options[:encoding]`
789
+ # Like `Object#inspect`, but preserves non-ASCII characters rather than escaping them under Ruby 1.9.2.
790
+ # This is necessary so that the precompiled Haml template can be `#encode`d into `@options[:encoding]`
971
791
  # before being evaluated.
972
792
  #
973
793
  # @param obj {Object}
974
794
  # @return {String}
975
795
  def inspect_obj(obj)
976
- return obj.inspect unless version_geq(RUBY_VERSION, "1.9.2")
796
+ return obj.inspect unless version_geq(::RUBY_VERSION, "1.9.2")
977
797
  return ':' + inspect_obj(obj.to_s) if obj.is_a?(Symbol)
978
798
  return obj.inspect unless obj.is_a?(String)
979
799
  '"' + obj.gsub(/[\x00-\x7F]+/) {|s| s.inspect[1...-1]} + '"'
@@ -993,12 +813,11 @@ module Sass
993
813
  # @return [(String, Array)] The resulting string, and an array of extracted values.
994
814
  def extract_values(arr)
995
815
  values = []
996
- mapped = arr.map do |e|
816
+ return arr.map do |e|
997
817
  next e.gsub('{', '{{') if e.is_a?(String)
998
818
  values << e
999
819
  next "{#{values.count - 1}}"
1000
- end
1001
- return mapped.join, values
820
+ end.join, values
1002
821
  end
1003
822
 
1004
823
  # Undoes \{#extract\_values} by transforming a string with escape sequences
@@ -1031,129 +850,6 @@ module Sass
1031
850
  inject_values(str, vals)
1032
851
  end
1033
852
 
1034
- # Builds a sourcemap file name given the generated CSS file name.
1035
- #
1036
- # @param css [String] The generated CSS file name.
1037
- # @return [String] The source map file name.
1038
- def sourcemap_name(css)
1039
- css + ".map"
1040
- end
1041
-
1042
- # Escapes certain characters so that the result can be used
1043
- # as the JSON string value. Returns the original string if
1044
- # no escaping is necessary.
1045
- #
1046
- # @param s [String] The string to be escaped
1047
- # @return [String] The escaped string
1048
- def json_escape_string(s)
1049
- return s if s !~ /["\\\b\f\n\r\t]/
1050
-
1051
- result = ""
1052
- s.split("").each do |c|
1053
- case c
1054
- when '"', "\\"
1055
- result << "\\" << c
1056
- when "\n" then result << "\\n"
1057
- when "\t" then result << "\\t"
1058
- when "\r" then result << "\\r"
1059
- when "\f" then result << "\\f"
1060
- when "\b" then result << "\\b"
1061
- else
1062
- result << c
1063
- end
1064
- end
1065
- result
1066
- end
1067
-
1068
- # Converts the argument into a valid JSON value.
1069
- #
1070
- # @param v [Fixnum, String, Array, Boolean, nil]
1071
- # @return [String]
1072
- def json_value_of(v)
1073
- case v
1074
- when Fixnum
1075
- v.to_s
1076
- when String
1077
- "\"" + json_escape_string(v) + "\""
1078
- when Array
1079
- "[" + v.map {|x| json_value_of(x)}.join(",") + "]"
1080
- when NilClass
1081
- "null"
1082
- when TrueClass
1083
- "true"
1084
- when FalseClass
1085
- "false"
1086
- else
1087
- raise ArgumentError.new("Unknown type: #{v.class.name}")
1088
- end
1089
- end
1090
-
1091
- VLQ_BASE_SHIFT = 5
1092
- VLQ_BASE = 1 << VLQ_BASE_SHIFT
1093
- VLQ_BASE_MASK = VLQ_BASE - 1
1094
- VLQ_CONTINUATION_BIT = VLQ_BASE
1095
-
1096
- BASE64_DIGITS = ('A'..'Z').to_a + ('a'..'z').to_a + ('0'..'9').to_a + ['+', '/']
1097
- BASE64_DIGIT_MAP = begin
1098
- map = {}
1099
- Sass::Util.enum_with_index(BASE64_DIGITS).map do |digit, i|
1100
- map[digit] = i
1101
- end
1102
- map
1103
- end
1104
-
1105
- # Encodes `value` as VLQ (http://en.wikipedia.org/wiki/VLQ).
1106
- #
1107
- # @param value [Fixnum]
1108
- # @return [String] The encoded value
1109
- def encode_vlq(value)
1110
- if value < 0
1111
- value = ((-value) << 1) | 1
1112
- else
1113
- value <<= 1
1114
- end
1115
-
1116
- result = ''
1117
- begin
1118
- digit = value & VLQ_BASE_MASK
1119
- value >>= VLQ_BASE_SHIFT
1120
- if value > 0
1121
- digit |= VLQ_CONTINUATION_BIT
1122
- end
1123
- result << BASE64_DIGITS[digit]
1124
- end while value > 0
1125
- result
1126
- end
1127
-
1128
- # This is a hack around the fact that you can't instantiate a URI parser on
1129
- # 1.8, so we have to have this hacky stuff to work around it. When 1.8
1130
- # support is dropped, we can remove this method.
1131
- #
1132
- # @private
1133
- URI_ESCAPE = URI.const_defined?("DEFAULT_PARSER") ? URI::DEFAULT_PARSER : URI
1134
-
1135
- # URI-escape `string`.
1136
- #
1137
- # @param string [String]
1138
- # @return [String]
1139
- def escape_uri(string)
1140
- URI_ESCAPE.escape string
1141
- end
1142
-
1143
- # A cross-platform implementation of `File.absolute_path`.
1144
- #
1145
- # @param path [String]
1146
- # @param dir_string [String] The directory to consider [path] relative to.
1147
- # @return [String] The absolute version of `path`.
1148
- def absolute_path(path, dir_string = nil)
1149
- # Ruby 1.8 doesn't support File.absolute_path.
1150
- return File.absolute_path(path, dir_string) unless ruby1_8?
1151
-
1152
- # File.expand_path expands "~", which we don't want.
1153
- return File.expand_path(path, dir_string) unless path[0] == ?~
1154
- File.expand_path(File.join(".", path), dir_string)
1155
- end
1156
-
1157
853
  ## Static Method Stuff
1158
854
 
1159
855
  # The context in which the ERB for \{#def\_static\_method} will be run.
@@ -1167,8 +863,8 @@ module Sass
1167
863
  #
1168
864
  # @param name [Symbol] The name of the variable
1169
865
  # @return [Boolean]
1170
- def method_missing(name, *args)
1171
- super unless args.empty? && !block_given?
866
+ def method_missing(name, *args, &block)
867
+ super unless args.empty? && block.nil?
1172
868
  @set.include?(name)
1173
869
  end
1174
870
  end
@@ -1176,6 +872,7 @@ module Sass
1176
872
  # @private
1177
873
  ATOMIC_WRITE_MUTEX = Mutex.new
1178
874
 
875
+
1179
876
  # This creates a temp file and yields it for writing. When the
1180
877
  # write is complete, the file is moved into the desired location.
1181
878
  # The atomicity of this operation is provided by the filesystem's
@@ -1193,14 +890,16 @@ module Sass
1193
890
  tmpfile = Tempfile.new(File.basename(filename), File.dirname(filename))
1194
891
  tmpfile.binmode if tmpfile.respond_to?(:binmode)
1195
892
  result = yield tmpfile
1196
- tmpfile.close
893
+ tmpfile.flush # ensure all writes are flushed to the OS
894
+ begin
895
+ tmpfile.fsync # ensure all buffered data in the OS is sync'd to disk.
896
+ rescue NotImplementedError
897
+ # Not all OSes support fsync
898
+ end
899
+ tmpfile.close # Windows cannot rename an open file.
900
+ # Make file readable and writeable to all but respect umask (usually 022).
901
+ File.chmod(perms & ~File.umask, tmpfile.path)
1197
902
  ATOMIC_WRITE_MUTEX.synchronize do
1198
- begin
1199
- File.chmod(perms & ~File.umask, tmpfile.path)
1200
- rescue Errno::EPERM
1201
- # If we don't have permissions to chmod the file, don't let that crash
1202
- # the compilation. See issue 1215.
1203
- end
1204
903
  File.rename tmpfile.path, filename
1205
904
  end
1206
905
  result
@@ -1211,74 +910,11 @@ module Sass
1211
910
  tmpfile.unlink if tmpfile
1212
911
  end
1213
912
 
1214
- def load_listen!
1215
- if defined?(gem)
1216
- begin
1217
- gem 'listen', '>= 1.1.0', '< 3.0.0'
1218
- require 'listen'
1219
- rescue Gem::LoadError
1220
- dir = scope("vendor/listen/lib")
1221
- $LOAD_PATH.unshift dir
1222
- begin
1223
- require 'listen'
1224
- rescue LoadError => e
1225
- if version_geq(RUBY_VERSION, "1.9.3")
1226
- version_constraint = "~> 2.7"
1227
- else
1228
- version_constraint = "~> 1.1"
1229
- end
1230
- e.message << "\n" <<
1231
- "Run \"gem install listen --version '#{version_constraint}'\" to get it."
1232
- raise e
1233
- end
1234
- end
1235
- else
1236
- begin
1237
- require 'listen'
1238
- rescue LoadError => e
1239
- dir = scope("vendor/listen/lib")
1240
- if $LOAD_PATH.include?(dir)
1241
- raise e unless File.exist?(scope(".git"))
1242
- e.message << "\n" <<
1243
- 'Run "git submodule update --init" to get the bundled version.'
1244
- else
1245
- $LOAD_PATH.unshift dir
1246
- retry
1247
- end
1248
- end
1249
- end
1250
- end
1251
-
1252
913
  private
1253
914
 
1254
- def find_encoding_error(str)
1255
- encoding = str.encoding
1256
- cr = Regexp.quote("\r".encode(encoding).force_encoding('BINARY'))
1257
- lf = Regexp.quote("\n".encode(encoding).force_encoding('BINARY'))
1258
- ff = Regexp.quote("\f".encode(encoding).force_encoding('BINARY'))
1259
- line_break = /#{cr}#{lf}?|#{ff}|#{lf}/
1260
-
1261
- str.force_encoding("binary").split(line_break).each_with_index do |line, i|
1262
- begin
1263
- line.encode(encoding)
1264
- rescue Encoding::UndefinedConversionError => e
1265
- raise Sass::SyntaxError.new(
1266
- "Invalid #{encoding.name} character #{undefined_conversion_error_char(e)}",
1267
- :line => i + 1)
1268
- end
1269
- end
1270
-
1271
- # We shouldn't get here, but it's possible some weird encoding stuff causes it.
1272
- return str, str.encoding
1273
- end
1274
-
1275
- # rubocop:disable LineLength
1276
-
1277
915
  # Calculates the memoization table for the Least Common Subsequence algorithm.
1278
916
  # Algorithm from [Wikipedia](http://en.wikipedia.org/wiki/Longest_common_subsequence_problem#Computing_the_length_of_the_LCS)
1279
917
  def lcs_table(x, y)
1280
- # This method does not take a block as an explicit parameter for performance reasons.
1281
- # rubocop:enable LineLength
1282
918
  c = Array.new(x.size) {[]}
1283
919
  x.size.times {|i| c[i][0] = 0}
1284
920
  y.size.times {|j| c[0][j] = 0}
@@ -1286,33 +922,27 @@ module Sass
1286
922
  (1...y.size).each do |j|
1287
923
  c[i][j] =
1288
924
  if yield x[i], y[j]
1289
- c[i - 1][j - 1] + 1
925
+ c[i-1][j-1] + 1
1290
926
  else
1291
- [c[i][j - 1], c[i - 1][j]].max
927
+ [c[i][j-1], c[i-1][j]].max
1292
928
  end
1293
929
  end
1294
930
  end
1295
- c
931
+ return c
1296
932
  end
1297
- # rubocop:disable ParameterLists, LineLength
1298
933
 
1299
934
  # Computes a single longest common subsequence for arrays x and y.
1300
935
  # Algorithm from [Wikipedia](http://en.wikipedia.org/wiki/Longest_common_subsequence_problem#Reading_out_an_LCS)
1301
936
  def lcs_backtrace(c, x, y, i, j, &block)
1302
- # rubocop:enable ParameterList, LineLengths
1303
937
  return [] if i == 0 || j == 0
1304
- if (v = yield(x[i], y[j]))
1305
- return lcs_backtrace(c, x, y, i - 1, j - 1, &block) << v
938
+ if v = yield(x[i], y[j])
939
+ return lcs_backtrace(c, x, y, i-1, j-1, &block) << v
1306
940
  end
1307
941
 
1308
- return lcs_backtrace(c, x, y, i, j - 1, &block) if c[i][j - 1] > c[i - 1][j]
1309
- lcs_backtrace(c, x, y, i - 1, j, &block)
942
+ return lcs_backtrace(c, x, y, i, j-1, &block) if c[i][j-1] > c[i-1][j]
943
+ return lcs_backtrace(c, x, y, i-1, j, &block)
1310
944
  end
1311
-
1312
- singleton_methods.each {|method| module_function method}
1313
945
  end
1314
946
  end
1315
947
 
1316
948
  require 'sass/util/multibyte_string_scanner'
1317
- require 'sass/util/normalized_map'
1318
- require 'sass/util/cross_platform_random'