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
@@ -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'