sass 3.4.25 → 3.5.0.pre.rc.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.yardopts +1 -1
- data/README.md +1 -1
- data/Rakefile +13 -157
- data/VERSION +1 -1
- data/VERSION_DATE +1 -1
- data/VERSION_NAME +1 -1
- data/lib/sass.rb +3 -10
- data/lib/sass/cache_stores/filesystem.rb +1 -1
- data/lib/sass/css.rb +2 -3
- data/lib/sass/engine.rb +46 -32
- data/lib/sass/environment.rb +27 -6
- data/lib/sass/error.rb +5 -5
- data/lib/sass/exec/base.rb +3 -12
- data/lib/sass/features.rb +1 -0
- data/lib/sass/importers/filesystem.rb +2 -2
- data/lib/sass/plugin.rb +1 -1
- data/lib/sass/plugin/compiler.rb +21 -51
- data/lib/sass/plugin/configuration.rb +1 -1
- data/lib/sass/plugin/rack.rb +3 -3
- data/lib/sass/plugin/staleness_checker.rb +3 -3
- data/lib/sass/railtie.rb +1 -1
- data/lib/sass/script.rb +3 -3
- data/lib/sass/script/functions.rb +238 -47
- data/lib/sass/script/lexer.rb +8 -6
- data/lib/sass/script/parser.rb +76 -75
- data/lib/sass/script/tree/funcall.rb +35 -30
- data/lib/sass/script/tree/list_literal.rb +23 -8
- data/lib/sass/script/tree/map_literal.rb +2 -2
- data/lib/sass/script/tree/node.rb +2 -10
- data/lib/sass/script/tree/operation.rb +16 -50
- data/lib/sass/script/value.rb +2 -0
- data/lib/sass/script/value/arg_list.rb +1 -1
- data/lib/sass/script/value/base.rb +20 -3
- data/lib/sass/script/value/callable.rb +25 -0
- data/lib/sass/script/value/color.rb +10 -10
- data/lib/sass/script/value/function.rb +19 -0
- data/lib/sass/script/value/helpers.rb +16 -7
- data/lib/sass/script/value/list.rb +33 -12
- data/lib/sass/script/value/map.rb +2 -2
- data/lib/sass/script/value/number.rb +3 -3
- data/lib/sass/script/value/string.rb +12 -5
- data/lib/sass/scss/parser.rb +101 -45
- data/lib/sass/scss/rx.rb +5 -11
- data/lib/sass/scss/static_parser.rb +0 -7
- data/lib/sass/selector.rb +4 -0
- data/lib/sass/selector/abstract_sequence.rb +5 -5
- data/lib/sass/selector/comma_sequence.rb +3 -15
- data/lib/sass/selector/pseudo.rb +4 -0
- data/lib/sass/selector/sequence.rb +30 -3
- data/lib/sass/selector/simple.rb +13 -7
- data/lib/sass/selector/simple_sequence.rb +1 -1
- data/lib/sass/shared.rb +3 -5
- data/lib/sass/source/map.rb +4 -4
- data/lib/sass/source/position.rb +4 -4
- data/lib/sass/stack.rb +21 -1
- data/lib/sass/tree/charset_node.rb +1 -1
- data/lib/sass/tree/comment_node.rb +1 -1
- data/lib/sass/tree/node.rb +3 -3
- data/lib/sass/tree/prop_node.rb +46 -54
- data/lib/sass/tree/rule_node.rb +7 -15
- data/lib/sass/tree/visitors/check_nesting.rb +1 -1
- data/lib/sass/tree/visitors/convert.rb +2 -3
- data/lib/sass/tree/visitors/cssize.rb +1 -10
- data/lib/sass/tree/visitors/deep_copy.rb +2 -2
- data/lib/sass/tree/visitors/perform.rb +23 -12
- data/lib/sass/tree/visitors/set_options.rb +1 -1
- data/lib/sass/tree/visitors/to_css.rb +46 -12
- data/lib/sass/util.rb +16 -321
- data/lib/sass/util/multibyte_string_scanner.rb +127 -131
- data/lib/sass/util/normalized_map.rb +1 -8
- data/lib/sass/version.rb +2 -2
- data/test/sass-spec.yml +1 -1
- data/test/sass/compiler_test.rb +4 -14
- data/test/sass/conversion_test.rb +113 -162
- data/test/sass/css2sass_test.rb +17 -19
- data/test/sass/css_variable_test.rb +176 -70
- data/test/sass/encoding_test.rb +2 -32
- data/test/sass/engine_test.rb +114 -65
- data/test/sass/extend_test.rb +37 -51
- data/test/sass/functions_test.rb +57 -15
- data/test/sass/importer_test.rb +2 -2
- data/test/sass/more_templates/more1.sass +10 -10
- data/test/sass/more_templates/more_import.sass +2 -2
- data/test/sass/plugin_test.rb +9 -12
- data/test/sass/script_conversion_test.rb +9 -0
- data/test/sass/script_test.rb +38 -48
- data/test/sass/scss/css_test.rb +5 -19
- data/test/sass/scss/scss_test.rb +58 -39
- data/test/sass/source_map_test.rb +26 -28
- data/test/sass/templates/_partial.sass +1 -1
- data/test/sass/templates/basic.sass +10 -10
- data/test/sass/templates/bork1.sass +1 -1
- data/test/sass/templates/bork5.sass +1 -1
- data/test/sass/templates/compact.sass +10 -10
- data/test/sass/templates/complex.sass +187 -187
- data/test/sass/templates/compressed.sass +10 -10
- data/test/sass/templates/expanded.sass +10 -10
- data/test/sass/templates/import.sass +2 -2
- data/test/sass/templates/importee.sass +3 -3
- data/test/sass/templates/mixins.sass +22 -22
- data/test/sass/templates/multiline.sass +4 -4
- data/test/sass/templates/nested.sass +13 -13
- data/test/sass/templates/parent_ref.sass +12 -12
- data/test/sass/templates/script.sass +70 -70
- data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +1 -1
- data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +2 -2
- data/test/sass/templates/subdir/subdir.sass +3 -3
- data/test/sass/templates/units.sass +10 -10
- data/test/sass/util/multibyte_string_scanner_test.rb +139 -149
- data/test/sass/util_test.rb +0 -36
- data/test/test_helper.rb +39 -0
- metadata +30 -57
- data/extra/sass-spec-ref.sh +0 -32
- data/lib/sass/deprecation.rb +0 -55
- data/lib/sass/script/css_variable_warning.rb +0 -52
- data/lib/sass/util/cross_platform_random.rb +0 -19
- data/lib/sass/util/ordered_hash.rb +0 -192
- data/test/sass/results/import_charset_1_8.css +0 -5
- data/test/sass/templates/import_charset_1_8.sass +0 -6
- data/vendor/listen/CHANGELOG.md +0 -1
- data/vendor/listen/CONTRIBUTING.md +0 -38
- data/vendor/listen/Gemfile +0 -20
- data/vendor/listen/Guardfile +0 -8
- data/vendor/listen/LICENSE +0 -20
- data/vendor/listen/README.md +0 -349
- data/vendor/listen/Rakefile +0 -5
- data/vendor/listen/Vagrantfile +0 -96
- data/vendor/listen/lib/listen.rb +0 -54
- data/vendor/listen/lib/listen/adapter.rb +0 -327
- data/vendor/listen/lib/listen/adapters/bsd.rb +0 -75
- data/vendor/listen/lib/listen/adapters/darwin.rb +0 -48
- data/vendor/listen/lib/listen/adapters/linux.rb +0 -81
- data/vendor/listen/lib/listen/adapters/polling.rb +0 -58
- data/vendor/listen/lib/listen/adapters/windows.rb +0 -91
- data/vendor/listen/lib/listen/directory_record.rb +0 -406
- data/vendor/listen/lib/listen/listener.rb +0 -323
- data/vendor/listen/lib/listen/turnstile.rb +0 -32
- data/vendor/listen/lib/listen/version.rb +0 -3
- data/vendor/listen/listen.gemspec +0 -28
- data/vendor/listen/spec/listen/adapter_spec.rb +0 -149
- data/vendor/listen/spec/listen/adapters/bsd_spec.rb +0 -36
- data/vendor/listen/spec/listen/adapters/darwin_spec.rb +0 -37
- data/vendor/listen/spec/listen/adapters/linux_spec.rb +0 -47
- data/vendor/listen/spec/listen/adapters/polling_spec.rb +0 -68
- data/vendor/listen/spec/listen/adapters/windows_spec.rb +0 -30
- data/vendor/listen/spec/listen/directory_record_spec.rb +0 -1250
- data/vendor/listen/spec/listen/listener_spec.rb +0 -258
- data/vendor/listen/spec/listen/turnstile_spec.rb +0 -56
- data/vendor/listen/spec/listen_spec.rb +0 -67
- data/vendor/listen/spec/spec_helper.rb +0 -25
- data/vendor/listen/spec/support/adapter_helper.rb +0 -666
- data/vendor/listen/spec/support/directory_record_helper.rb +0 -57
- data/vendor/listen/spec/support/fixtures_helper.rb +0 -29
- data/vendor/listen/spec/support/listeners_helper.rb +0 -179
- data/vendor/listen/spec/support/platform_helper.rb +0 -15
data/lib/sass/tree/rule_node.rb
CHANGED
@@ -40,7 +40,7 @@ module Sass::Tree
|
|
40
40
|
# * This is a child rule of another rule
|
41
41
|
# * The parent rule has properties, and thus will be rendered
|
42
42
|
#
|
43
|
-
# @return [
|
43
|
+
# @return [Fixnum]
|
44
44
|
attr_accessor :tabs
|
45
45
|
|
46
46
|
# The entire selector source range for this rule.
|
@@ -120,7 +120,8 @@ module Sass::Tree
|
|
120
120
|
#
|
121
121
|
# @return [{#to_s => #to_s}]
|
122
122
|
def debug_info
|
123
|
-
{:filename => filename &&
|
123
|
+
{:filename => filename &&
|
124
|
+
("file://" + URI::DEFAULT_PARSER.escape(File.expand_path(filename))),
|
124
125
|
:line => line}
|
125
126
|
end
|
126
127
|
|
@@ -137,19 +138,10 @@ module Sass::Tree
|
|
137
138
|
|
138
139
|
# We don't use real filename/line info because we don't have it yet.
|
139
140
|
# When we get it, we'll set it on the parsed rules if possible.
|
140
|
-
parser = nil
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
@parsed_rules = parser.parse_selector rescue nil
|
145
|
-
# rubocop:enable RescueModifier
|
146
|
-
|
147
|
-
$stderr.string
|
148
|
-
end
|
149
|
-
|
150
|
-
# If parsing produces a warning, throw away the result so we can parse
|
151
|
-
# later with the real filename info.
|
152
|
-
@parsed_rules = nil unless warnings.empty?
|
141
|
+
parser = Sass::SCSS::StaticParser.new(@rule.join.strip, nil, nil, 1)
|
142
|
+
# rubocop:disable RescueModifier
|
143
|
+
@parsed_rules = parser.parse_selector rescue nil
|
144
|
+
# rubocop:enable RescueModifier
|
153
145
|
end
|
154
146
|
end
|
155
147
|
end
|
@@ -31,7 +31,7 @@ class Sass::Tree::Visitors::CheckNesting < Sass::Tree::Visitors::Base
|
|
31
31
|
if parent.is_a?(Sass::Tree::AtRootNode) && parent.resolved_value
|
32
32
|
old_parents = @parents
|
33
33
|
@parents = @parents.reject {|p| parent.exclude_node?(p)}
|
34
|
-
@parent =
|
34
|
+
@parent = @parents.reverse.each_with_index.
|
35
35
|
find {|p, i| !transparent_parent?(p, @parents[-i - 2])}.first
|
36
36
|
|
37
37
|
begin
|
@@ -203,8 +203,7 @@ class Sass::Tree::Visitors::Convert < Sass::Tree::Visitors::Base
|
|
203
203
|
|
204
204
|
unless node.args.empty? && node.keywords.empty? && node.splat.nil?
|
205
205
|
args = node.args.map(&arg_to_sass)
|
206
|
-
keywords =
|
207
|
-
map {|k, v| "$#{dasherize(k)}: #{arg_to_sass[v]}"}
|
206
|
+
keywords = node.keywords.as_stored.to_a.map {|k, v| "$#{dasherize(k)}: #{arg_to_sass[v]}"}
|
208
207
|
|
209
208
|
if node.splat
|
210
209
|
splat = "#{arg_to_sass[node.splat]}..."
|
@@ -281,7 +280,7 @@ class Sass::Tree::Visitors::Convert < Sass::Tree::Visitors::Base
|
|
281
280
|
# Visit rule-level nodes and return their conversion with appropriate
|
282
281
|
# whitespace added.
|
283
282
|
def visit_rule_level(nodes)
|
284
|
-
|
283
|
+
(nodes + [nil]).each_cons(2).map do |child, nxt|
|
285
284
|
visit(child) +
|
286
285
|
if nxt &&
|
287
286
|
(child.is_a?(Sass::Tree::CommentNode) && child.line + child.lines + 1 == nxt.line) ||
|
@@ -56,8 +56,7 @@ class Sass::Tree::Visitors::Cssize < Sass::Tree::Visitors::Base
|
|
56
56
|
@parents.pop
|
57
57
|
end
|
58
58
|
|
59
|
-
#
|
60
|
-
# and that it's at the top of the document.
|
59
|
+
# Converts the entire document to CSS.
|
61
60
|
#
|
62
61
|
# @return [(Tree::Node, Sass::Util::SubsetMap)] The resulting tree of static nodes
|
63
62
|
# *and* the extensions defined for this tree
|
@@ -65,14 +64,6 @@ class Sass::Tree::Visitors::Cssize < Sass::Tree::Visitors::Base
|
|
65
64
|
yield
|
66
65
|
|
67
66
|
if parent.nil?
|
68
|
-
# In Ruby 1.9 we can make all @charset nodes invisible
|
69
|
-
# and infer the final @charset from the encoding of the final string.
|
70
|
-
if Sass::Util.ruby1_8?
|
71
|
-
charset = node.children.find {|c| c.is_a?(Sass::Tree::CharsetNode)}
|
72
|
-
node.children.reject! {|c| c.is_a?(Sass::Tree::CharsetNode)}
|
73
|
-
node.children.unshift charset if charset
|
74
|
-
end
|
75
|
-
|
76
67
|
imports_to_move = []
|
77
68
|
import_limit = nil
|
78
69
|
i = -1
|
@@ -55,13 +55,13 @@ class Sass::Tree::Visitors::DeepCopy < Sass::Tree::Visitors::Base
|
|
55
55
|
|
56
56
|
def visit_mixin(node)
|
57
57
|
node.args = node.args.map {|a| a.deep_copy}
|
58
|
-
node.keywords =
|
58
|
+
node.keywords = Hash[node.keywords.map {|k, v| [k, v.deep_copy]}]
|
59
59
|
yield
|
60
60
|
end
|
61
61
|
|
62
62
|
def visit_prop(node)
|
63
63
|
node.name = node.name.map {|c| c.is_a?(Sass::Script::Tree::Node) ? c.deep_copy : c}
|
64
|
-
node.value = node.value.deep_copy
|
64
|
+
node.value = node.value.map {|c| c.is_a?(Sass::Script::Tree::Node) ? c.deep_copy : c}
|
65
65
|
yield
|
66
66
|
end
|
67
67
|
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# A visitor for converting a dynamic Sass tree into a static Sass tree.
|
2
2
|
class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
|
3
|
-
@@function_name_deprecation = Sass::Deprecation.new
|
4
|
-
|
5
3
|
class << self
|
6
4
|
# @param root [Tree::Node] The root node of the tree to visit.
|
7
5
|
# @param environment [Sass::Environment] The lexical environment.
|
@@ -282,7 +280,8 @@ class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
|
|
282
280
|
|
283
281
|
if node.normalized_name == 'calc' || node.normalized_name == 'element' ||
|
284
282
|
node.name == 'expression' || node.name == 'url'
|
285
|
-
|
283
|
+
Sass::Util.sass_warn <<WARNING
|
284
|
+
DEPRECATION WARNING on line #{node.line}#{" of #{node.filename}" if node.filename}:
|
286
285
|
Naming a function "#{node.name}" is disallowed and will be an error in future versions of Sass.
|
287
286
|
This name conflicts with an existing CSS function with special parse rules.
|
288
287
|
WARNING
|
@@ -290,7 +289,7 @@ WARNING
|
|
290
289
|
|
291
290
|
@environment.set_local_function(node.name,
|
292
291
|
Sass::Callable.new(node.name, node.args, node.splat, env,
|
293
|
-
node.children, false, "function"))
|
292
|
+
node.children, false, "function", :stylesheet))
|
294
293
|
[]
|
295
294
|
end
|
296
295
|
|
@@ -341,7 +340,7 @@ WARNING
|
|
341
340
|
env = Sass::Environment.new(@environment, node.options)
|
342
341
|
@environment.set_local_mixin(node.name,
|
343
342
|
Sass::Callable.new(node.name, node.args, node.splat, env,
|
344
|
-
node.children, node.has_content, "mixin"))
|
343
|
+
node.children, node.has_content, "mixin", :stylesheet))
|
345
344
|
[]
|
346
345
|
end
|
347
346
|
|
@@ -395,9 +394,19 @@ WARNING
|
|
395
394
|
# Runs any SassScript that may be embedded in a property.
|
396
395
|
def visit_prop(node)
|
397
396
|
node.resolved_name = run_interp(node.name)
|
398
|
-
|
399
|
-
node
|
400
|
-
|
397
|
+
|
398
|
+
# If the node's value is just a variable or similar, we may get a useful
|
399
|
+
# source range from evaluating it.
|
400
|
+
if node.value.length == 1 && node.value.first.is_a?(Sass::Script::Tree::Node)
|
401
|
+
result = node.value.first.perform(@environment)
|
402
|
+
node.resolved_value = result.to_s
|
403
|
+
node.value_source_range = result.source_range if result.source_range
|
404
|
+
elsif node.custom_property?
|
405
|
+
node.resolved_value = run_interp_no_strip(node.value)
|
406
|
+
else
|
407
|
+
node.resolved_value = run_interp(node.value)
|
408
|
+
end
|
409
|
+
|
401
410
|
yield
|
402
411
|
end
|
403
412
|
|
@@ -483,9 +492,11 @@ WARNING
|
|
483
492
|
def visit_warn(node)
|
484
493
|
res = node.expr.perform(@environment)
|
485
494
|
res = res.value if res.is_a?(Sass::Script::Value::String)
|
486
|
-
|
487
|
-
|
488
|
-
|
495
|
+
@environment.stack.with_directive(node.filename, node.line, "@warn") do
|
496
|
+
msg = "WARNING: #{res}\n "
|
497
|
+
msg << @environment.stack.to_s.gsub("\n", "\n ") << "\n"
|
498
|
+
Sass::Util.sass_warn msg
|
499
|
+
end
|
489
500
|
[]
|
490
501
|
end
|
491
502
|
|
@@ -556,7 +567,7 @@ WARNING
|
|
556
567
|
end
|
557
568
|
|
558
569
|
files << node.filename << node.imported_file.options[:filename]
|
559
|
-
msg << "\n" <<
|
570
|
+
msg << "\n" << files.each_cons(2).map do |m1, m2|
|
560
571
|
" #{m1} imports #{m2}"
|
561
572
|
end.join("\n")
|
562
573
|
raise Sass::SyntaxError.new(msg)
|
@@ -88,7 +88,7 @@ class Sass::Tree::Visitors::SetOptions < Sass::Tree::Visitors::Base
|
|
88
88
|
|
89
89
|
def visit_prop(node)
|
90
90
|
node.name.each {|c| c.options = @options if c.is_a?(Sass::Script::Tree::Node)}
|
91
|
-
node.value.options = @options
|
91
|
+
node.value.each {|c| c.options = @options if c.is_a?(Sass::Script::Tree::Node)}
|
92
92
|
yield
|
93
93
|
end
|
94
94
|
|
@@ -12,7 +12,7 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
|
|
12
12
|
@tabs = 0
|
13
13
|
@line = 1
|
14
14
|
@offset = 1
|
15
|
-
@result =
|
15
|
+
@result = ""
|
16
16
|
@source_mapping = build_source_mapping ? Sass::Source::Map.new : nil
|
17
17
|
@lstrip = nil
|
18
18
|
@in_directive = false
|
@@ -135,7 +135,7 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
|
|
135
135
|
|
136
136
|
output "\n"
|
137
137
|
|
138
|
-
unless
|
138
|
+
unless @result.ascii_only?
|
139
139
|
if node.style == :compressed
|
140
140
|
# A byte order mark is sufficient to tell browsers that this
|
141
141
|
# file is UTF-8 encoded, and will override any other detection
|
@@ -261,18 +261,20 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
|
|
261
261
|
end
|
262
262
|
|
263
263
|
def visit_prop(node)
|
264
|
-
return if node.resolved_value.empty?
|
264
|
+
return if node.resolved_value.empty? && !node.custom_property?
|
265
265
|
tab_str = ' ' * (@tabs + node.tabs)
|
266
266
|
output(tab_str)
|
267
267
|
for_node(node, :name) {output(node.resolved_name)}
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
268
|
+
output(":")
|
269
|
+
output(" ") unless node.style == :compressed || node.custom_property?
|
270
|
+
for_node(node, :value) do
|
271
|
+
output(if node.custom_property?
|
272
|
+
format_custom_property_value(node)
|
273
|
+
else
|
274
|
+
node.resolved_value
|
275
|
+
end)
|
275
276
|
end
|
277
|
+
output(";") unless node.style == :compressed
|
276
278
|
end
|
277
279
|
|
278
280
|
# @comment
|
@@ -384,9 +386,41 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
|
|
384
386
|
|
385
387
|
private
|
386
388
|
|
389
|
+
# Reformats the value of `node` so that it's nicely indented, preserving its
|
390
|
+
# existing relative indentation.
|
391
|
+
#
|
392
|
+
# @param node [Sass::Script::Tree::PropNode] A custom property node.
|
393
|
+
# @return [String]
|
394
|
+
def format_custom_property_value(node)
|
395
|
+
if node.style == :compact || node.style == :compressed || !node.resolved_value.include?("\n")
|
396
|
+
# Folding not involving newlines was done in the parser. We can safely
|
397
|
+
# fold newlines here because tokens like strings can't contain literal
|
398
|
+
# newlines, so we know any adjacent whitespace is tokenized as whitespace.
|
399
|
+
return node.resolved_value.gsub(/[ \t\r\f]*\n[ \t\r\f\n]*/, ' ')
|
400
|
+
end
|
401
|
+
|
402
|
+
# Find the smallest amount of indentation in the custom property and use
|
403
|
+
# that as the base indentation level.
|
404
|
+
lines = node.resolved_value.split("\n")
|
405
|
+
indented_lines = lines[1..-1]
|
406
|
+
min_indentation = indented_lines.
|
407
|
+
map {|line| line[/^[ \t]*/]}.
|
408
|
+
reject {|line| line.empty?}.
|
409
|
+
min_by {|line| line.length}
|
410
|
+
|
411
|
+
# Limit the base indentation to the same indentation level as the node name
|
412
|
+
# so that if *every* line is indented relative to the property name that's
|
413
|
+
# preserved.
|
414
|
+
if node.name_source_range
|
415
|
+
base_indentation = min_indentation[0...node.name_source_range.start_pos.offset - 1]
|
416
|
+
end
|
417
|
+
|
418
|
+
lines.first + "\n" + indented_lines.join("\n").gsub(/^#{base_indentation}/, ' ' * @tabs)
|
419
|
+
end
|
420
|
+
|
387
421
|
def debug_info_rule(debug_info, options)
|
388
422
|
node = Sass::Tree::DirectiveNode.resolved("@media -sass-debug-info")
|
389
|
-
|
423
|
+
debug_info.map {|k, v| [k.to_s, v.to_s]}.to_a.each do |k, v|
|
390
424
|
rule = Sass::Tree::RuleNode.new([""])
|
391
425
|
rule.resolved_rules = Sass::Selector::CommaSequence.new(
|
392
426
|
[Sass::Selector::Sequence.new(
|
@@ -395,7 +429,7 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
|
|
395
429
|
false)
|
396
430
|
])
|
397
431
|
])
|
398
|
-
prop = Sass::Tree::PropNode.new([""],
|
432
|
+
prop = Sass::Tree::PropNode.new([""], [""], :new)
|
399
433
|
prop.resolved_name = "font-family"
|
400
434
|
prop.resolved_value = Sass::SCSS::RX.escape_ident(v.to_s)
|
401
435
|
rule << prop
|
data/lib/sass/util.rb
CHANGED
@@ -35,17 +35,6 @@ module Sass
|
|
35
35
|
File.join(Sass::ROOT_DIR, file)
|
36
36
|
end
|
37
37
|
|
38
|
-
# Converts an array of `[key, value]` pairs to a hash.
|
39
|
-
#
|
40
|
-
# @example
|
41
|
-
# to_hash([[:foo, "bar"], [:baz, "bang"]])
|
42
|
-
# #=> {:foo => "bar", :baz => "bang"}
|
43
|
-
# @param arr [Array<(Object, Object)>] An array of pairs
|
44
|
-
# @return [Hash] A hash
|
45
|
-
def to_hash(arr)
|
46
|
-
ordered_hash(*arr.compact)
|
47
|
-
end
|
48
|
-
|
49
38
|
# Maps the keys in a hash according to a block.
|
50
39
|
#
|
51
40
|
# @example
|
@@ -301,56 +290,6 @@ module Sass
|
|
301
290
|
lcs_backtrace(lcs_table(x, y, &block), x, y, x.size - 1, y.size - 1, &block)
|
302
291
|
end
|
303
292
|
|
304
|
-
# Converts a Hash to an Array. This is usually identical to `Hash#to_a`,
|
305
|
-
# with the following exceptions:
|
306
|
-
#
|
307
|
-
# * In Ruby 1.8, `Hash#to_a` is not deterministically ordered, but this is.
|
308
|
-
# * In Ruby 1.9 when running tests, this is ordered in the same way it would
|
309
|
-
# be under Ruby 1.8 (sorted key order rather than insertion order).
|
310
|
-
#
|
311
|
-
# @param hash [Hash]
|
312
|
-
# @return [Array]
|
313
|
-
def hash_to_a(hash)
|
314
|
-
return hash.to_a unless ruby1_8? || defined?(Test::Unit)
|
315
|
-
hash.sort_by {|k, _v| k}
|
316
|
-
end
|
317
|
-
|
318
|
-
# Performs the equivalent of `enum.group_by.to_a`, but with a guaranteed
|
319
|
-
# order. Unlike {Util#hash_to_a}, the resulting order isn't sorted key order;
|
320
|
-
# instead, it's the same order as `#group_by` has under Ruby 1.9 (key
|
321
|
-
# appearance order).
|
322
|
-
#
|
323
|
-
# @param enum [Enumerable]
|
324
|
-
# @return [Array<[Object, Array]>] An array of pairs.
|
325
|
-
def group_by_to_a(enum)
|
326
|
-
return enum.group_by {|e| yield(e)}.to_a unless ruby1_8?
|
327
|
-
order = {}
|
328
|
-
arr = []
|
329
|
-
groups = enum.group_by do |e|
|
330
|
-
res = yield(e)
|
331
|
-
unless order.include?(res)
|
332
|
-
order[res] = order.size
|
333
|
-
end
|
334
|
-
res
|
335
|
-
end
|
336
|
-
groups.each do |key, vals|
|
337
|
-
arr[order[key]] = [key, vals]
|
338
|
-
end
|
339
|
-
arr
|
340
|
-
end
|
341
|
-
|
342
|
-
# Like `String.upcase`, but only ever upcases ASCII letters.
|
343
|
-
def upcase(string)
|
344
|
-
return string.upcase unless ruby2_4?
|
345
|
-
string.upcase(:ascii)
|
346
|
-
end
|
347
|
-
|
348
|
-
# Like `String.downcase`, but only ever downcases ASCII letters.
|
349
|
-
def downcase(string)
|
350
|
-
return string.downcase unless ruby2_4?
|
351
|
-
string.downcase(:ascii)
|
352
|
-
end
|
353
|
-
|
354
293
|
# Returns a sub-array of `minuend` containing only elements that are also in
|
355
294
|
# `subtrahend`. Ensures that the return value has the same order as
|
356
295
|
# `minuend`, even on Rubinius where that's not guaranteed by `Array#-`.
|
@@ -430,7 +369,7 @@ module Sass
|
|
430
369
|
# Returns information about the caller of the previous method.
|
431
370
|
#
|
432
371
|
# @param entry [String] An entry in the `#caller` list, or a similarly formatted string
|
433
|
-
# @return [[String,
|
372
|
+
# @return [[String, Fixnum, (String, nil)]]
|
434
373
|
# An array containing the filename, line, and method name of the caller.
|
435
374
|
# The method name may be nil
|
436
375
|
def caller_info(entry = nil)
|
@@ -524,8 +463,7 @@ module Sass
|
|
524
463
|
#
|
525
464
|
# @param msg [String]
|
526
465
|
def sass_warn(msg)
|
527
|
-
msg
|
528
|
-
Sass.logger.warn(msg)
|
466
|
+
Sass.logger.warn("#{msg}\n")
|
529
467
|
end
|
530
468
|
|
531
469
|
## Cross Rails Version Compatibility
|
@@ -578,24 +516,6 @@ module Sass
|
|
578
516
|
version_geq(ActionPack::VERSION::STRING, version)
|
579
517
|
end
|
580
518
|
|
581
|
-
# Returns whether this environment is using Listen
|
582
|
-
# version 2.0.0 or greater.
|
583
|
-
#
|
584
|
-
# @return [Boolean]
|
585
|
-
def listen_geq_2?
|
586
|
-
return @listen_geq_2 if defined?(@listen_geq_2)
|
587
|
-
@listen_geq_2 =
|
588
|
-
begin
|
589
|
-
# Make sure we're loading listen/version from the same place that
|
590
|
-
# we're loading listen itself.
|
591
|
-
load_listen!
|
592
|
-
require 'listen/version'
|
593
|
-
version_geq(::Listen::VERSION, '2.0.0')
|
594
|
-
rescue LoadError
|
595
|
-
false
|
596
|
-
end
|
597
|
-
end
|
598
|
-
|
599
519
|
# Returns an ActionView::Template* class.
|
600
520
|
# In pre-3.0 versions of Rails, most of these classes
|
601
521
|
# were of the form `ActionView::TemplateFoo`,
|
@@ -648,7 +568,7 @@ module Sass
|
|
648
568
|
|
649
569
|
# Returns an array of ints representing the JRuby version number.
|
650
570
|
#
|
651
|
-
# @return [Array<
|
571
|
+
# @return [Array<Fixnum>]
|
652
572
|
def jruby_version
|
653
573
|
@jruby_version ||= ::JRUBY_VERSION.split(".").map {|s| s.to_i}
|
654
574
|
end
|
@@ -739,7 +659,7 @@ module Sass
|
|
739
659
|
def file_uri_from_path(path)
|
740
660
|
path = path.to_s if path.is_a?(Pathname)
|
741
661
|
path = path.tr('\\', '/') if windows?
|
742
|
-
path =
|
662
|
+
path = URI::DEFAULT_PARSER.escape(path)
|
743
663
|
return path.start_with?('/') ? "file://" + path : path unless windows?
|
744
664
|
return "file:///" + path.tr("\\", "/") if path =~ %r{^[a-zA-Z]:[/\\]}
|
745
665
|
return "file:" + path.tr("\\", "/") if path =~ %r{\\\\[^\\]+\\[^\\/]+}
|
@@ -774,102 +694,11 @@ module Sass
|
|
774
694
|
val || []
|
775
695
|
end
|
776
696
|
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
def ruby1?
|
783
|
-
return @ruby1 if defined?(@ruby1)
|
784
|
-
@ruby1 = RUBY_VERSION_COMPONENTS[0] <= 1
|
785
|
-
end
|
786
|
-
|
787
|
-
# Whether or not this is running under Ruby 1.8 or lower.
|
788
|
-
#
|
789
|
-
# Note that IronRuby counts as Ruby 1.8,
|
790
|
-
# because it doesn't support the Ruby 1.9 encoding API.
|
791
|
-
#
|
792
|
-
# @return [Boolean]
|
793
|
-
def ruby1_8?
|
794
|
-
# IronRuby says its version is 1.9, but doesn't support any of the encoding APIs.
|
795
|
-
# We have to fall back to 1.8 behavior.
|
796
|
-
return @ruby1_8 if defined?(@ruby1_8)
|
797
|
-
@ruby1_8 = ironruby? ||
|
798
|
-
(RUBY_VERSION_COMPONENTS[0] == 1 && RUBY_VERSION_COMPONENTS[1] < 9)
|
799
|
-
end
|
800
|
-
|
801
|
-
# Whether or not this is running under Ruby 1.9.2 exactly.
|
802
|
-
#
|
803
|
-
# @return [Boolean]
|
804
|
-
def ruby1_9_2?
|
805
|
-
return @ruby1_9_2 if defined?(@ruby1_9_2)
|
806
|
-
@ruby1_9_2 = RUBY_VERSION_COMPONENTS == [1, 9, 2]
|
807
|
-
end
|
808
|
-
|
809
|
-
# Whether or not this is running under Ruby 2.4 or higher.
|
810
|
-
#
|
811
|
-
# @return [Boolean]
|
812
|
-
def ruby2_4?
|
813
|
-
return @ruby2_4 if defined?(@ruby2_4)
|
814
|
-
@ruby2_4 =
|
815
|
-
if RUBY_VERSION_COMPONENTS[0] == 2
|
816
|
-
RUBY_VERSION_COMPONENTS[1] >= 4
|
817
|
-
else
|
818
|
-
RUBY_VERSION_COMPONENTS[0] > 2
|
819
|
-
end
|
820
|
-
end
|
821
|
-
|
822
|
-
# Wehter or not this is running under JRuby 1.6 or lower.
|
823
|
-
def jruby1_6?
|
824
|
-
return @jruby1_6 if defined?(@jruby1_6)
|
825
|
-
@jruby1_6 = jruby? && jruby_version[0] == 1 && jruby_version[1] < 7
|
826
|
-
end
|
827
|
-
|
828
|
-
# Whether or not this is running under MacRuby.
|
829
|
-
#
|
830
|
-
# @return [Boolean]
|
831
|
-
def macruby?
|
832
|
-
return @macruby if defined?(@macruby)
|
833
|
-
@macruby = RUBY_ENGINE == 'macruby'
|
834
|
-
end
|
835
|
-
|
836
|
-
require 'sass/util/ordered_hash' if ruby1_8?
|
837
|
-
|
838
|
-
# Converts a hash or a list of pairs into an order-preserving hash.
|
839
|
-
#
|
840
|
-
# On Ruby 1.8.7, this uses the orderedhash gem to simulate an
|
841
|
-
# order-preserving hash. On Ruby 1.9 and up, it just uses the native Hash
|
842
|
-
# class, since that preserves the order itself.
|
843
|
-
#
|
844
|
-
# @overload ordered_hash(hash)
|
845
|
-
# @param hash [Hash] a normal hash to convert to an ordered hash
|
846
|
-
# @return [Hash]
|
847
|
-
# @overload ordered_hash(*pairs)
|
848
|
-
# @example
|
849
|
-
# ordered_hash([:foo, "bar"], [:baz, "bang"])
|
850
|
-
# #=> {:foo => "bar", :baz => "bang"}
|
851
|
-
# ordered_hash #=> {}
|
852
|
-
# @param pairs [Array<(Object, Object)>] the list of key/value pairs for
|
853
|
-
# the hash.
|
854
|
-
# @return [Hash]
|
855
|
-
def ordered_hash(*pairs_or_hash)
|
856
|
-
if pairs_or_hash.length == 1 && pairs_or_hash.first.is_a?(Hash)
|
857
|
-
hash = pairs_or_hash.first
|
858
|
-
return hash unless ruby1_8?
|
859
|
-
return OrderedHash.new.merge hash
|
860
|
-
end
|
861
|
-
|
862
|
-
return Hash[pairs_or_hash] unless ruby1_8?
|
863
|
-
(pairs_or_hash.is_a?(NormalizedMap) ? NormalizedMap : OrderedHash)[*pairs_or_hash.flatten(1)]
|
864
|
-
end
|
865
|
-
|
866
|
-
unless ruby1_8?
|
867
|
-
CHARSET_REGEXP = /\A@charset "([^"]+)"/
|
868
|
-
bom = "\uFEFF"
|
869
|
-
UTF_8_BOM = bom.encode("UTF-8").force_encoding('BINARY')
|
870
|
-
UTF_16BE_BOM = bom.encode("UTF-16BE").force_encoding('BINARY')
|
871
|
-
UTF_16LE_BOM = bom.encode("UTF-16LE").force_encoding('BINARY')
|
872
|
-
end
|
697
|
+
CHARSET_REGEXP = /\A@charset "([^"]+)"/
|
698
|
+
bom = "\uFEFF"
|
699
|
+
UTF_8_BOM = bom.encode("UTF-8").force_encoding('BINARY')
|
700
|
+
UTF_16BE_BOM = bom.encode("UTF-16BE").force_encoding('BINARY')
|
701
|
+
UTF_16LE_BOM = bom.encode("UTF-16LE").force_encoding('BINARY')
|
873
702
|
|
874
703
|
# Like {\#check\_encoding}, but also checks for a `@charset` declaration
|
875
704
|
# at the beginning of the file and uses that encoding if it exists.
|
@@ -878,7 +707,7 @@ module Sass
|
|
878
707
|
#
|
879
708
|
# @param str [String] The string of which to check the encoding
|
880
709
|
# @return [(String, Encoding)] The original string encoded as UTF-8,
|
881
|
-
# and the source encoding of the string
|
710
|
+
# and the source encoding of the string
|
882
711
|
# @raise [Encoding::UndefinedConversionError] if the source encoding
|
883
712
|
# cannot be converted to UTF-8
|
884
713
|
# @raise [ArgumentError] if the document uses an unknown encoding with `@charset`
|
@@ -886,15 +715,6 @@ module Sass
|
|
886
715
|
# doesn't match its contents, or it doesn't declare an encoding and its
|
887
716
|
# contents are invalid in the native encoding.
|
888
717
|
def check_sass_encoding(str)
|
889
|
-
# On Ruby 1.8 we can't do anything complicated with encodings.
|
890
|
-
# Instead, we just strip out a UTF-8 BOM if it exists and
|
891
|
-
# sanitize according to Section 3.3 of CSS Syntax Level 3. We
|
892
|
-
# don't sanitize null characters since they might be components
|
893
|
-
# of other characters.
|
894
|
-
if ruby1_8?
|
895
|
-
return str.gsub(/\A\xEF\xBB\xBF/, '').gsub(/\r\n?|\f/, "\n"), nil
|
896
|
-
end
|
897
|
-
|
898
718
|
# Determine the fallback encoding following section 3.2 of CSS Syntax Level 3 and Encodings:
|
899
719
|
# http://www.w3.org/TR/2013/WD-css-syntax-3-20130919/#determine-the-fallback-encoding
|
900
720
|
# http://encoding.spec.whatwg.org/#decode
|
@@ -910,14 +730,9 @@ module Sass
|
|
910
730
|
str = binary.force_encoding('UTF-16LE')
|
911
731
|
elsif binary =~ CHARSET_REGEXP
|
912
732
|
charset = $1.force_encoding('US-ASCII')
|
913
|
-
|
914
|
-
if
|
733
|
+
encoding = Encoding.find(charset)
|
734
|
+
if encoding.name == 'UTF-16' || encoding.name == 'UTF-16BE'
|
915
735
|
encoding = Encoding.find('UTF-8')
|
916
|
-
else
|
917
|
-
encoding = Encoding.find(charset)
|
918
|
-
if encoding.name == 'UTF-16' || encoding.name == 'UTF-16BE'
|
919
|
-
encoding = Encoding.find('UTF-8')
|
920
|
-
end
|
921
736
|
end
|
922
737
|
str = binary.force_encoding(encoding)
|
923
738
|
elsif str.encoding.name == "ASCII-8BIT"
|
@@ -937,50 +752,6 @@ module Sass
|
|
937
752
|
end
|
938
753
|
end
|
939
754
|
|
940
|
-
# Checks to see if a class has a given method.
|
941
|
-
# For example:
|
942
|
-
#
|
943
|
-
# Sass::Util.has?(:public_instance_method, String, :gsub) #=> true
|
944
|
-
#
|
945
|
-
# Method collections like `Class#instance_methods`
|
946
|
-
# return strings in Ruby 1.8 and symbols in Ruby 1.9 and on,
|
947
|
-
# so this handles checking for them in a compatible way.
|
948
|
-
#
|
949
|
-
# @param attr [#to_s] The (singular) name of the method-collection method
|
950
|
-
# (e.g. `:instance_methods`, `:private_methods`)
|
951
|
-
# @param klass [Module] The class to check the methods of which to check
|
952
|
-
# @param method [String, Symbol] The name of the method do check for
|
953
|
-
# @return [Boolean] Whether or not the given collection has the given method
|
954
|
-
def has?(attr, klass, method)
|
955
|
-
klass.send("#{attr}s").include?(ruby1_8? ? method.to_s : method.to_sym)
|
956
|
-
end
|
957
|
-
|
958
|
-
# A version of `Enumerable#enum_with_index` that works in Ruby 1.8 and 1.9.
|
959
|
-
#
|
960
|
-
# @param enum [Enumerable] The enumerable to get the enumerator for
|
961
|
-
# @return [Enumerator] The with-index enumerator
|
962
|
-
def enum_with_index(enum)
|
963
|
-
ruby1_8? ? enum.enum_with_index : enum.each_with_index
|
964
|
-
end
|
965
|
-
|
966
|
-
# A version of `Enumerable#enum_cons` that works in Ruby 1.8 and 1.9.
|
967
|
-
#
|
968
|
-
# @param enum [Enumerable] The enumerable to get the enumerator for
|
969
|
-
# @param n [Integer] The size of each cons
|
970
|
-
# @return [Enumerator] The consed enumerator
|
971
|
-
def enum_cons(enum, n)
|
972
|
-
ruby1_8? ? enum.enum_cons(n) : enum.each_cons(n)
|
973
|
-
end
|
974
|
-
|
975
|
-
# A version of `Enumerable#enum_slice` that works in Ruby 1.8 and 1.9.
|
976
|
-
#
|
977
|
-
# @param enum [Enumerable] The enumerable to get the enumerator for
|
978
|
-
# @param n [Integer] The size of each slice
|
979
|
-
# @return [Enumerator] The consed enumerator
|
980
|
-
def enum_slice(enum, n)
|
981
|
-
ruby1_8? ? enum.enum_slice(n) : enum.each_slice(n)
|
982
|
-
end
|
983
|
-
|
984
755
|
# Destructively removes all elements from an array that match a block, and
|
985
756
|
# returns the removed elements.
|
986
757
|
#
|
@@ -999,14 +770,6 @@ module Sass
|
|
999
770
|
out
|
1000
771
|
end
|
1001
772
|
|
1002
|
-
# Returns the ASCII code of the given character.
|
1003
|
-
#
|
1004
|
-
# @param c [String] All characters but the first are ignored.
|
1005
|
-
# @return [Integer] The ASCII code of `c`.
|
1006
|
-
def ord(c)
|
1007
|
-
ruby1_8? ? c[0] : c.ord
|
1008
|
-
end
|
1009
|
-
|
1010
773
|
# Flattens the first level of nested arrays in `arrs`. Unlike
|
1011
774
|
# `Array#flatten`, this orders the result by taking the first
|
1012
775
|
# values from each array in order, then the second, and so on.
|
@@ -1127,11 +890,11 @@ module Sass
|
|
1127
890
|
|
1128
891
|
# Converts the argument into a valid JSON value.
|
1129
892
|
#
|
1130
|
-
# @param v [
|
893
|
+
# @param v [Fixnum, String, Array, Boolean, nil]
|
1131
894
|
# @return [String]
|
1132
895
|
def json_value_of(v)
|
1133
896
|
case v
|
1134
|
-
when
|
897
|
+
when Fixnum
|
1135
898
|
v.to_s
|
1136
899
|
when String
|
1137
900
|
"\"" + json_escape_string(v) + "\""
|
@@ -1156,7 +919,7 @@ module Sass
|
|
1156
919
|
BASE64_DIGITS = ('A'..'Z').to_a + ('a'..'z').to_a + ('0'..'9').to_a + ['+', '/']
|
1157
920
|
BASE64_DIGIT_MAP = begin
|
1158
921
|
map = {}
|
1159
|
-
|
922
|
+
BASE64_DIGITS.each_with_index.map do |digit, i|
|
1160
923
|
map[digit] = i
|
1161
924
|
end
|
1162
925
|
map
|
@@ -1164,7 +927,7 @@ module Sass
|
|
1164
927
|
|
1165
928
|
# Encodes `value` as VLQ (http://en.wikipedia.org/wiki/VLQ).
|
1166
929
|
#
|
1167
|
-
# @param value [
|
930
|
+
# @param value [Fixnum]
|
1168
931
|
# @return [String] The encoded value
|
1169
932
|
def encode_vlq(value)
|
1170
933
|
if value < 0
|
@@ -1185,35 +948,6 @@ module Sass
|
|
1185
948
|
result
|
1186
949
|
end
|
1187
950
|
|
1188
|
-
# This is a hack around the fact that you can't instantiate a URI parser on
|
1189
|
-
# 1.8, so we have to have this hacky stuff to work around it. When 1.8
|
1190
|
-
# support is dropped, we can remove this method.
|
1191
|
-
#
|
1192
|
-
# @private
|
1193
|
-
URI_ESCAPE = URI.const_defined?("DEFAULT_PARSER") ? URI::DEFAULT_PARSER : URI
|
1194
|
-
|
1195
|
-
# URI-escape `string`.
|
1196
|
-
#
|
1197
|
-
# @param string [String]
|
1198
|
-
# @return [String]
|
1199
|
-
def escape_uri(string)
|
1200
|
-
URI_ESCAPE.escape string
|
1201
|
-
end
|
1202
|
-
|
1203
|
-
# A cross-platform implementation of `File.absolute_path`.
|
1204
|
-
#
|
1205
|
-
# @param path [String]
|
1206
|
-
# @param dir_string [String] The directory to consider [path] relative to.
|
1207
|
-
# @return [String] The absolute version of `path`.
|
1208
|
-
def absolute_path(path, dir_string = nil)
|
1209
|
-
# Ruby 1.8 doesn't support File.absolute_path.
|
1210
|
-
return File.absolute_path(path, dir_string) unless ruby1_8?
|
1211
|
-
|
1212
|
-
# File.expand_path expands "~", which we don't want.
|
1213
|
-
return File.expand_path(path, dir_string) unless path[0] == ?~
|
1214
|
-
File.expand_path(File.join(".", path), dir_string)
|
1215
|
-
end
|
1216
|
-
|
1217
951
|
## Static Method Stuff
|
1218
952
|
|
1219
953
|
# The context in which the ERB for \{#def\_static\_method} will be run.
|
@@ -1271,44 +1005,6 @@ module Sass
|
|
1271
1005
|
tmpfile.unlink if tmpfile
|
1272
1006
|
end
|
1273
1007
|
|
1274
|
-
def load_listen!
|
1275
|
-
if defined?(gem)
|
1276
|
-
begin
|
1277
|
-
gem 'listen', '>= 1.1.0', '< 3.0.0'
|
1278
|
-
require 'listen'
|
1279
|
-
rescue Gem::LoadError
|
1280
|
-
dir = scope("vendor/listen/lib")
|
1281
|
-
$LOAD_PATH.unshift dir
|
1282
|
-
begin
|
1283
|
-
require 'listen'
|
1284
|
-
rescue LoadError => e
|
1285
|
-
if version_geq(RUBY_VERSION, "1.9.3")
|
1286
|
-
version_constraint = "~> 3.0"
|
1287
|
-
else
|
1288
|
-
version_constraint = "~> 1.1"
|
1289
|
-
end
|
1290
|
-
e.message << "\n" <<
|
1291
|
-
"Run \"gem install listen --version '#{version_constraint}'\" to get it."
|
1292
|
-
raise e
|
1293
|
-
end
|
1294
|
-
end
|
1295
|
-
else
|
1296
|
-
begin
|
1297
|
-
require 'listen'
|
1298
|
-
rescue LoadError => e
|
1299
|
-
dir = scope("vendor/listen/lib")
|
1300
|
-
if $LOAD_PATH.include?(dir)
|
1301
|
-
raise e unless File.exist?(scope(".git"))
|
1302
|
-
e.message << "\n" <<
|
1303
|
-
'Run "git submodule update --init" to get the bundled version.'
|
1304
|
-
else
|
1305
|
-
$LOAD_PATH.unshift dir
|
1306
|
-
retry
|
1307
|
-
end
|
1308
|
-
end
|
1309
|
-
end
|
1310
|
-
end
|
1311
|
-
|
1312
1008
|
private
|
1313
1009
|
|
1314
1010
|
def find_encoding_error(str)
|
@@ -1372,4 +1068,3 @@ end
|
|
1372
1068
|
|
1373
1069
|
require 'sass/util/multibyte_string_scanner'
|
1374
1070
|
require 'sass/util/normalized_map'
|
1375
|
-
require 'sass/util/cross_platform_random'
|