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.
Files changed (156) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -1
  3. data/README.md +1 -1
  4. data/Rakefile +13 -157
  5. data/VERSION +1 -1
  6. data/VERSION_DATE +1 -1
  7. data/VERSION_NAME +1 -1
  8. data/lib/sass.rb +3 -10
  9. data/lib/sass/cache_stores/filesystem.rb +1 -1
  10. data/lib/sass/css.rb +2 -3
  11. data/lib/sass/engine.rb +46 -32
  12. data/lib/sass/environment.rb +27 -6
  13. data/lib/sass/error.rb +5 -5
  14. data/lib/sass/exec/base.rb +3 -12
  15. data/lib/sass/features.rb +1 -0
  16. data/lib/sass/importers/filesystem.rb +2 -2
  17. data/lib/sass/plugin.rb +1 -1
  18. data/lib/sass/plugin/compiler.rb +21 -51
  19. data/lib/sass/plugin/configuration.rb +1 -1
  20. data/lib/sass/plugin/rack.rb +3 -3
  21. data/lib/sass/plugin/staleness_checker.rb +3 -3
  22. data/lib/sass/railtie.rb +1 -1
  23. data/lib/sass/script.rb +3 -3
  24. data/lib/sass/script/functions.rb +238 -47
  25. data/lib/sass/script/lexer.rb +8 -6
  26. data/lib/sass/script/parser.rb +76 -75
  27. data/lib/sass/script/tree/funcall.rb +35 -30
  28. data/lib/sass/script/tree/list_literal.rb +23 -8
  29. data/lib/sass/script/tree/map_literal.rb +2 -2
  30. data/lib/sass/script/tree/node.rb +2 -10
  31. data/lib/sass/script/tree/operation.rb +16 -50
  32. data/lib/sass/script/value.rb +2 -0
  33. data/lib/sass/script/value/arg_list.rb +1 -1
  34. data/lib/sass/script/value/base.rb +20 -3
  35. data/lib/sass/script/value/callable.rb +25 -0
  36. data/lib/sass/script/value/color.rb +10 -10
  37. data/lib/sass/script/value/function.rb +19 -0
  38. data/lib/sass/script/value/helpers.rb +16 -7
  39. data/lib/sass/script/value/list.rb +33 -12
  40. data/lib/sass/script/value/map.rb +2 -2
  41. data/lib/sass/script/value/number.rb +3 -3
  42. data/lib/sass/script/value/string.rb +12 -5
  43. data/lib/sass/scss/parser.rb +101 -45
  44. data/lib/sass/scss/rx.rb +5 -11
  45. data/lib/sass/scss/static_parser.rb +0 -7
  46. data/lib/sass/selector.rb +4 -0
  47. data/lib/sass/selector/abstract_sequence.rb +5 -5
  48. data/lib/sass/selector/comma_sequence.rb +3 -15
  49. data/lib/sass/selector/pseudo.rb +4 -0
  50. data/lib/sass/selector/sequence.rb +30 -3
  51. data/lib/sass/selector/simple.rb +13 -7
  52. data/lib/sass/selector/simple_sequence.rb +1 -1
  53. data/lib/sass/shared.rb +3 -5
  54. data/lib/sass/source/map.rb +4 -4
  55. data/lib/sass/source/position.rb +4 -4
  56. data/lib/sass/stack.rb +21 -1
  57. data/lib/sass/tree/charset_node.rb +1 -1
  58. data/lib/sass/tree/comment_node.rb +1 -1
  59. data/lib/sass/tree/node.rb +3 -3
  60. data/lib/sass/tree/prop_node.rb +46 -54
  61. data/lib/sass/tree/rule_node.rb +7 -15
  62. data/lib/sass/tree/visitors/check_nesting.rb +1 -1
  63. data/lib/sass/tree/visitors/convert.rb +2 -3
  64. data/lib/sass/tree/visitors/cssize.rb +1 -10
  65. data/lib/sass/tree/visitors/deep_copy.rb +2 -2
  66. data/lib/sass/tree/visitors/perform.rb +23 -12
  67. data/lib/sass/tree/visitors/set_options.rb +1 -1
  68. data/lib/sass/tree/visitors/to_css.rb +46 -12
  69. data/lib/sass/util.rb +16 -321
  70. data/lib/sass/util/multibyte_string_scanner.rb +127 -131
  71. data/lib/sass/util/normalized_map.rb +1 -8
  72. data/lib/sass/version.rb +2 -2
  73. data/test/sass-spec.yml +1 -1
  74. data/test/sass/compiler_test.rb +4 -14
  75. data/test/sass/conversion_test.rb +113 -162
  76. data/test/sass/css2sass_test.rb +17 -19
  77. data/test/sass/css_variable_test.rb +176 -70
  78. data/test/sass/encoding_test.rb +2 -32
  79. data/test/sass/engine_test.rb +114 -65
  80. data/test/sass/extend_test.rb +37 -51
  81. data/test/sass/functions_test.rb +57 -15
  82. data/test/sass/importer_test.rb +2 -2
  83. data/test/sass/more_templates/more1.sass +10 -10
  84. data/test/sass/more_templates/more_import.sass +2 -2
  85. data/test/sass/plugin_test.rb +9 -12
  86. data/test/sass/script_conversion_test.rb +9 -0
  87. data/test/sass/script_test.rb +38 -48
  88. data/test/sass/scss/css_test.rb +5 -19
  89. data/test/sass/scss/scss_test.rb +58 -39
  90. data/test/sass/source_map_test.rb +26 -28
  91. data/test/sass/templates/_partial.sass +1 -1
  92. data/test/sass/templates/basic.sass +10 -10
  93. data/test/sass/templates/bork1.sass +1 -1
  94. data/test/sass/templates/bork5.sass +1 -1
  95. data/test/sass/templates/compact.sass +10 -10
  96. data/test/sass/templates/complex.sass +187 -187
  97. data/test/sass/templates/compressed.sass +10 -10
  98. data/test/sass/templates/expanded.sass +10 -10
  99. data/test/sass/templates/import.sass +2 -2
  100. data/test/sass/templates/importee.sass +3 -3
  101. data/test/sass/templates/mixins.sass +22 -22
  102. data/test/sass/templates/multiline.sass +4 -4
  103. data/test/sass/templates/nested.sass +13 -13
  104. data/test/sass/templates/parent_ref.sass +12 -12
  105. data/test/sass/templates/script.sass +70 -70
  106. data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +1 -1
  107. data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +2 -2
  108. data/test/sass/templates/subdir/subdir.sass +3 -3
  109. data/test/sass/templates/units.sass +10 -10
  110. data/test/sass/util/multibyte_string_scanner_test.rb +139 -149
  111. data/test/sass/util_test.rb +0 -36
  112. data/test/test_helper.rb +39 -0
  113. metadata +30 -57
  114. data/extra/sass-spec-ref.sh +0 -32
  115. data/lib/sass/deprecation.rb +0 -55
  116. data/lib/sass/script/css_variable_warning.rb +0 -52
  117. data/lib/sass/util/cross_platform_random.rb +0 -19
  118. data/lib/sass/util/ordered_hash.rb +0 -192
  119. data/test/sass/results/import_charset_1_8.css +0 -5
  120. data/test/sass/templates/import_charset_1_8.sass +0 -6
  121. data/vendor/listen/CHANGELOG.md +0 -1
  122. data/vendor/listen/CONTRIBUTING.md +0 -38
  123. data/vendor/listen/Gemfile +0 -20
  124. data/vendor/listen/Guardfile +0 -8
  125. data/vendor/listen/LICENSE +0 -20
  126. data/vendor/listen/README.md +0 -349
  127. data/vendor/listen/Rakefile +0 -5
  128. data/vendor/listen/Vagrantfile +0 -96
  129. data/vendor/listen/lib/listen.rb +0 -54
  130. data/vendor/listen/lib/listen/adapter.rb +0 -327
  131. data/vendor/listen/lib/listen/adapters/bsd.rb +0 -75
  132. data/vendor/listen/lib/listen/adapters/darwin.rb +0 -48
  133. data/vendor/listen/lib/listen/adapters/linux.rb +0 -81
  134. data/vendor/listen/lib/listen/adapters/polling.rb +0 -58
  135. data/vendor/listen/lib/listen/adapters/windows.rb +0 -91
  136. data/vendor/listen/lib/listen/directory_record.rb +0 -406
  137. data/vendor/listen/lib/listen/listener.rb +0 -323
  138. data/vendor/listen/lib/listen/turnstile.rb +0 -32
  139. data/vendor/listen/lib/listen/version.rb +0 -3
  140. data/vendor/listen/listen.gemspec +0 -28
  141. data/vendor/listen/spec/listen/adapter_spec.rb +0 -149
  142. data/vendor/listen/spec/listen/adapters/bsd_spec.rb +0 -36
  143. data/vendor/listen/spec/listen/adapters/darwin_spec.rb +0 -37
  144. data/vendor/listen/spec/listen/adapters/linux_spec.rb +0 -47
  145. data/vendor/listen/spec/listen/adapters/polling_spec.rb +0 -68
  146. data/vendor/listen/spec/listen/adapters/windows_spec.rb +0 -30
  147. data/vendor/listen/spec/listen/directory_record_spec.rb +0 -1250
  148. data/vendor/listen/spec/listen/listener_spec.rb +0 -258
  149. data/vendor/listen/spec/listen/turnstile_spec.rb +0 -56
  150. data/vendor/listen/spec/listen_spec.rb +0 -67
  151. data/vendor/listen/spec/spec_helper.rb +0 -25
  152. data/vendor/listen/spec/support/adapter_helper.rb +0 -666
  153. data/vendor/listen/spec/support/directory_record_helper.rb +0 -57
  154. data/vendor/listen/spec/support/fixtures_helper.rb +0 -29
  155. data/vendor/listen/spec/support/listeners_helper.rb +0 -179
  156. data/vendor/listen/spec/support/platform_helper.rb +0 -15
@@ -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 [Integer]
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 && ("file://" + Sass::Util.escape_uri(File.expand_path(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
- warnings = Sass::Util.silence_warnings do
142
- parser = Sass::SCSS::StaticParser.new(@rule.join.strip, nil, nil, 1)
143
- # rubocop:disable RescueModifier
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 = Sass::Util.enum_with_index(@parents.reverse).
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 = Sass::Util.hash_to_a(node.keywords.as_stored).
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
- Sass::Util.enum_cons(nodes + [nil], 2).map do |child, nxt|
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
- # In Ruby 1.8, ensures that there's only one `@charset` directive
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 = Sass::Util::NormalizedMap.new(Hash[node.keywords.map {|k, v| [k, v.deep_copy]}])
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
- @@function_name_deprecation.warn(node.filename, node.line, <<WARNING)
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
- val = node.value.perform(@environment)
399
- node.resolved_value = val.to_s
400
- node.value_source_range = val.source_range if val.source_range
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
- msg = "WARNING: #{res}\n "
487
- msg << @environment.stack.to_s.gsub("\n", "\n ") << "\n"
488
- Sass::Util.sass_warn msg
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" << Sass::Util.enum_cons(files, 2).map do |m1, m2|
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 = String.new("")
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 Sass::Util.ruby1_8? || @result.ascii_only?
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
- if node.style == :compressed
269
- output(":")
270
- for_node(node, :value) {output(node.resolved_value)}
271
- else
272
- output(": ")
273
- for_node(node, :value) {output(node.resolved_value)}
274
- output(";")
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
- Sass::Util.hash_to_a(debug_info.map {|k, v| [k.to_s, v.to_s]}).each do |k, v|
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([""], Sass::Script::Value::String.new(''), :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
@@ -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, Integer, (String, nil)]]
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 += "\n" unless ruby1?
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<Integer>]
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 = Sass::Util.escape_uri(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
- ## Cross-Ruby-Version Compatibility
778
-
779
- # Whether or not this is running under a Ruby version under 2.0.
780
- #
781
- # @return [Boolean]
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 (or `nil` under Ruby 1.8)
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
- # Ruby 1.9.2 doesn't recognize a UTF-16 encoding without an endian marker.
914
- if ruby1_9_2? && charset.downcase == 'utf-16'
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 [Integer, String, Array, Boolean, nil]
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 Integer
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
- Sass::Util.enum_with_index(BASE64_DIGITS).map do |digit, i|
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 [Integer]
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'