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.
- checksums.yaml +4 -4
- data/MIT-LICENSE +1 -1
- data/README.md +50 -70
- data/Rakefile +5 -26
- data/VERSION +1 -1
- data/VERSION_NAME +1 -1
- data/bin/sass +1 -1
- data/bin/scss +1 -1
- data/lib/sass.rb +12 -19
- data/lib/sass/cache_stores/base.rb +2 -2
- data/lib/sass/cache_stores/chain.rb +1 -2
- data/lib/sass/cache_stores/filesystem.rb +5 -1
- data/lib/sass/cache_stores/memory.rb +1 -1
- data/lib/sass/cache_stores/null.rb +2 -2
- data/lib/sass/callbacks.rb +0 -1
- data/lib/sass/css.rb +13 -11
- data/lib/sass/engine.rb +173 -424
- data/lib/sass/environment.rb +58 -148
- data/lib/sass/error.rb +14 -11
- data/lib/sass/exec.rb +703 -5
- data/lib/sass/importers/base.rb +6 -49
- data/lib/sass/importers/filesystem.rb +19 -44
- data/lib/sass/logger.rb +4 -1
- data/lib/sass/logger/base.rb +4 -2
- data/lib/sass/logger/log_level.rb +7 -3
- data/lib/sass/media.rb +23 -20
- data/lib/sass/plugin.rb +7 -7
- data/lib/sass/plugin/compiler.rb +145 -304
- data/lib/sass/plugin/configuration.rb +23 -18
- data/lib/sass/plugin/merb.rb +1 -1
- data/lib/sass/plugin/staleness_checker.rb +3 -3
- data/lib/sass/repl.rb +3 -3
- data/lib/sass/script.rb +8 -35
- data/lib/sass/script/{value/arg_list.rb → arg_list.rb} +25 -9
- data/lib/sass/script/bool.rb +18 -0
- data/lib/sass/script/color.rb +606 -0
- data/lib/sass/script/css_lexer.rb +4 -8
- data/lib/sass/script/css_parser.rb +2 -5
- data/lib/sass/script/funcall.rb +245 -0
- data/lib/sass/script/functions.rb +408 -1491
- data/lib/sass/script/interpolation.rb +79 -0
- data/lib/sass/script/lexer.rb +68 -172
- data/lib/sass/script/list.rb +85 -0
- data/lib/sass/script/literal.rb +221 -0
- data/lib/sass/script/{tree/node.rb → node.rb} +12 -22
- data/lib/sass/script/{value/null.rb → null.rb} +7 -14
- data/lib/sass/script/{value/number.rb → number.rb} +75 -152
- data/lib/sass/script/{tree/operation.rb → operation.rb} +24 -17
- data/lib/sass/script/parser.rb +110 -245
- data/lib/sass/script/string.rb +51 -0
- data/lib/sass/script/{tree/string_interpolation.rb → string_interpolation.rb} +4 -5
- data/lib/sass/script/{tree/unary_operation.rb → unary_operation.rb} +6 -6
- data/lib/sass/script/variable.rb +58 -0
- data/lib/sass/scss/css_parser.rb +3 -9
- data/lib/sass/scss/parser.rb +421 -450
- data/lib/sass/scss/rx.rb +11 -19
- data/lib/sass/scss/static_parser.rb +7 -321
- data/lib/sass/selector.rb +194 -68
- data/lib/sass/selector/abstract_sequence.rb +14 -29
- data/lib/sass/selector/comma_sequence.rb +25 -108
- data/lib/sass/selector/sequence.rb +66 -159
- data/lib/sass/selector/simple.rb +25 -23
- data/lib/sass/selector/simple_sequence.rb +63 -173
- data/lib/sass/shared.rb +1 -1
- data/lib/sass/supports.rb +15 -13
- data/lib/sass/tree/charset_node.rb +1 -1
- data/lib/sass/tree/comment_node.rb +3 -3
- data/lib/sass/tree/css_import_node.rb +11 -11
- data/lib/sass/tree/debug_node.rb +2 -2
- data/lib/sass/tree/directive_node.rb +4 -21
- data/lib/sass/tree/each_node.rb +8 -8
- data/lib/sass/tree/extend_node.rb +7 -14
- data/lib/sass/tree/for_node.rb +4 -4
- data/lib/sass/tree/function_node.rb +4 -9
- data/lib/sass/tree/if_node.rb +1 -1
- data/lib/sass/tree/import_node.rb +5 -4
- data/lib/sass/tree/media_node.rb +14 -4
- data/lib/sass/tree/mixin_def_node.rb +4 -4
- data/lib/sass/tree/mixin_node.rb +8 -21
- data/lib/sass/tree/node.rb +12 -54
- data/lib/sass/tree/prop_node.rb +20 -39
- data/lib/sass/tree/return_node.rb +2 -3
- data/lib/sass/tree/root_node.rb +3 -19
- data/lib/sass/tree/rule_node.rb +22 -35
- data/lib/sass/tree/supports_node.rb +13 -0
- data/lib/sass/tree/trace_node.rb +1 -2
- data/lib/sass/tree/variable_node.rb +3 -9
- data/lib/sass/tree/visitors/base.rb +8 -5
- data/lib/sass/tree/visitors/check_nesting.rb +19 -49
- data/lib/sass/tree/visitors/convert.rb +56 -74
- data/lib/sass/tree/visitors/cssize.rb +74 -202
- data/lib/sass/tree/visitors/deep_copy.rb +5 -10
- data/lib/sass/tree/visitors/extend.rb +7 -7
- data/lib/sass/tree/visitors/perform.rb +185 -278
- data/lib/sass/tree/visitors/set_options.rb +6 -20
- data/lib/sass/tree/visitors/to_css.rb +81 -234
- data/lib/sass/tree/warn_node.rb +2 -2
- data/lib/sass/tree/while_node.rb +2 -2
- data/lib/sass/util.rb +152 -522
- data/lib/sass/util/multibyte_string_scanner.rb +0 -2
- data/lib/sass/util/subset_map.rb +3 -4
- data/lib/sass/util/test.rb +1 -0
- data/lib/sass/version.rb +22 -20
- data/test/Gemfile +3 -0
- data/test/Gemfile.lock +10 -0
- data/test/sass/cache_test.rb +20 -62
- data/test/sass/callbacks_test.rb +1 -1
- data/test/sass/conversion_test.rb +2 -296
- data/test/sass/css2sass_test.rb +4 -23
- data/test/sass/engine_test.rb +354 -411
- data/test/sass/exec_test.rb +2 -2
- data/test/sass/extend_test.rb +145 -324
- data/test/sass/functions_test.rb +86 -873
- data/test/sass/importer_test.rb +21 -241
- data/test/sass/logger_test.rb +1 -1
- data/test/sass/more_results/more_import.css +1 -1
- data/test/sass/plugin_test.rb +26 -16
- data/test/sass/results/compact.css +1 -1
- data/test/sass/results/complex.css +4 -4
- data/test/sass/results/expanded.css +1 -1
- data/test/sass/results/import.css +1 -1
- data/test/sass/results/import_charset_ibm866.css +2 -2
- data/test/sass/results/mixins.css +17 -17
- data/test/sass/results/nested.css +1 -1
- data/test/sass/results/parent_ref.css +2 -2
- data/test/sass/results/script.css +3 -3
- data/test/sass/results/scss_import.css +1 -1
- data/test/sass/script_conversion_test.rb +7 -36
- data/test/sass/script_test.rb +53 -485
- data/test/sass/scss/css_test.rb +28 -143
- data/test/sass/scss/rx_test.rb +4 -4
- data/test/sass/scss/scss_test.rb +325 -2119
- data/test/sass/templates/scss_import.scss +1 -2
- data/test/sass/test_helper.rb +1 -1
- data/test/sass/util/multibyte_string_scanner_test.rb +1 -1
- data/test/sass/util/subset_map_test.rb +2 -2
- data/test/sass/util_test.rb +1 -86
- data/test/test_helper.rb +8 -37
- metadata +19 -66
- data/lib/sass/exec/base.rb +0 -187
- data/lib/sass/exec/sass_convert.rb +0 -264
- data/lib/sass/exec/sass_scss.rb +0 -424
- data/lib/sass/features.rb +0 -47
- data/lib/sass/script/tree.rb +0 -16
- data/lib/sass/script/tree/funcall.rb +0 -306
- data/lib/sass/script/tree/interpolation.rb +0 -118
- data/lib/sass/script/tree/list_literal.rb +0 -77
- data/lib/sass/script/tree/literal.rb +0 -45
- data/lib/sass/script/tree/map_literal.rb +0 -64
- data/lib/sass/script/tree/selector.rb +0 -26
- data/lib/sass/script/tree/variable.rb +0 -57
- data/lib/sass/script/value.rb +0 -11
- data/lib/sass/script/value/base.rb +0 -240
- data/lib/sass/script/value/bool.rb +0 -35
- data/lib/sass/script/value/color.rb +0 -680
- data/lib/sass/script/value/helpers.rb +0 -262
- data/lib/sass/script/value/list.rb +0 -113
- data/lib/sass/script/value/map.rb +0 -70
- data/lib/sass/script/value/string.rb +0 -97
- data/lib/sass/selector/pseudo.rb +0 -256
- data/lib/sass/source/map.rb +0 -210
- data/lib/sass/source/position.rb +0 -39
- data/lib/sass/source/range.rb +0 -41
- data/lib/sass/stack.rb +0 -120
- data/lib/sass/tree/at_root_node.rb +0 -83
- data/lib/sass/tree/error_node.rb +0 -18
- data/lib/sass/tree/keyframe_rule_node.rb +0 -15
- data/lib/sass/util/cross_platform_random.rb +0 -19
- data/lib/sass/util/normalized_map.rb +0 -130
- data/lib/sass/util/ordered_hash.rb +0 -192
- data/test/sass/compiler_test.rb +0 -232
- data/test/sass/encoding_test.rb +0 -219
- data/test/sass/source_map_test.rb +0 -977
- data/test/sass/superselector_test.rb +0 -191
- data/test/sass/util/normalized_map_test.rb +0 -51
- data/test/sass/value_helpers_test.rb +0 -179
data/lib/sass/tree/warn_node.rb
CHANGED
@@ -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::
|
8
|
+
# @return [Script::Node]
|
9
9
|
attr_accessor :expr
|
10
10
|
|
11
|
-
# @param expr [Script::
|
11
|
+
# @param expr [Script::Node] The expression to print
|
12
12
|
def initialize(expr)
|
13
13
|
@expr = expr
|
14
14
|
super()
|
data/lib/sass/tree/while_node.rb
CHANGED
@@ -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::
|
9
|
+
# @return [Script::Node]
|
10
10
|
attr_accessor :expr
|
11
11
|
|
12
|
-
# @param expr [Script::
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
#
|
101
|
-
|
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
|
236
|
-
res[i...i
|
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
|
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
|
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
|
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
|
-
|
316
|
-
res =
|
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
|
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
|
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::
|
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::
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
742
|
-
@macruby = RUBY_ENGINE == 'macruby'
|
573
|
+
RUBY_ENGINE == 'macruby'
|
743
574
|
end
|
744
575
|
|
745
|
-
|
746
|
-
|
747
|
-
#
|
748
|
-
#
|
749
|
-
#
|
750
|
-
#
|
751
|
-
#
|
752
|
-
#
|
753
|
-
# @
|
754
|
-
#
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
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
|
-
|
772
|
-
(
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
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
|
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
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
if
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
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
|
831
|
-
elsif
|
832
|
-
|
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
|
-
|
654
|
+
str = check_encoding(str, &block)
|
655
|
+
return str.encode("UTF-8"), str.encoding
|
656
|
+
end
|
839
657
|
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
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
|
-
#
|
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
|
-
|
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? &&
|
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.
|
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
|
925
|
+
c[i-1][j-1] + 1
|
1290
926
|
else
|
1291
|
-
[c[i][j
|
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
|
1305
|
-
return lcs_backtrace(c, x, y, i
|
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
|
1309
|
-
lcs_backtrace(c, x, y, i
|
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'
|