sass 3.4.25 → 3.5.0.pre.rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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'