sass 3.3.0.rc.1 → 3.3.0.rc.2

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 (78) hide show
  1. data/Rakefile +1 -1
  2. data/VERSION +1 -1
  3. data/VERSION_DATE +1 -1
  4. data/lib/sass.rb +5 -0
  5. data/lib/sass/engine.rb +3 -5
  6. data/lib/sass/plugin.rb +0 -1
  7. data/lib/sass/plugin/compiler.rb +1 -2
  8. data/lib/sass/script/functions.rb +16 -2
  9. data/lib/sass/script/lexer.rb +22 -12
  10. data/lib/sass/script/parser.rb +27 -14
  11. data/lib/sass/script/tree/variable.rb +1 -1
  12. data/lib/sass/script/value/base.rb +1 -1
  13. data/lib/sass/script/value/color.rb +29 -17
  14. data/lib/sass/script/value/list.rb +1 -1
  15. data/lib/sass/script/value/number.rb +8 -1
  16. data/lib/sass/scss/parser.rb +2 -2
  17. data/lib/sass/selector/sequence.rb +18 -19
  18. data/lib/sass/selector/simple_sequence.rb +5 -5
  19. data/lib/sass/source/map.rb +1 -1
  20. data/lib/sass/tree/node.rb +25 -0
  21. data/lib/sass/tree/variable_node.rb +5 -0
  22. data/lib/sass/tree/visitors/base.rb +4 -7
  23. data/lib/sass/tree/visitors/check_nesting.rb +2 -2
  24. data/lib/sass/tree/visitors/perform.rb +12 -7
  25. data/lib/sass/util.rb +95 -50
  26. data/lib/sass/util/normalized_map.rb +63 -14
  27. data/lib/sass/util/ordered_hash.rb +9 -5
  28. data/lib/sass/version.rb +10 -12
  29. data/test/sass/engine_test.rb +37 -0
  30. data/test/sass/functions_test.rb +9 -2
  31. data/test/sass/importer_test.rb +3 -3
  32. data/test/sass/script_test.rb +12 -10
  33. data/test/sass/source_map_test.rb +8 -8
  34. data/test/sass/util/normalized_map_test.rb +22 -1
  35. data/test/sass/util_test.rb +18 -0
  36. data/test/test_helper.rb +16 -0
  37. data/vendor/listen/CHANGELOG.md +228 -0
  38. data/vendor/listen/CONTRIBUTING.md +38 -0
  39. data/vendor/listen/Gemfile +30 -0
  40. data/vendor/listen/Guardfile +8 -0
  41. data/vendor/listen/LICENSE +20 -0
  42. data/vendor/listen/README.md +315 -0
  43. data/vendor/listen/Rakefile +47 -0
  44. data/vendor/listen/Vagrantfile +96 -0
  45. data/vendor/listen/lib/listen.rb +40 -0
  46. data/vendor/listen/lib/listen/adapter.rb +214 -0
  47. data/vendor/listen/lib/listen/adapters/bsd.rb +112 -0
  48. data/vendor/listen/lib/listen/adapters/darwin.rb +85 -0
  49. data/vendor/listen/lib/listen/adapters/linux.rb +113 -0
  50. data/vendor/listen/lib/listen/adapters/polling.rb +67 -0
  51. data/vendor/listen/lib/listen/adapters/windows.rb +87 -0
  52. data/vendor/listen/lib/listen/dependency_manager.rb +126 -0
  53. data/vendor/listen/lib/listen/directory_record.rb +371 -0
  54. data/vendor/listen/lib/listen/listener.rb +225 -0
  55. data/vendor/listen/lib/listen/multi_listener.rb +143 -0
  56. data/vendor/listen/lib/listen/turnstile.rb +28 -0
  57. data/vendor/listen/lib/listen/version.rb +3 -0
  58. data/vendor/listen/listen.gemspec +22 -0
  59. data/vendor/listen/spec/listen/adapter_spec.rb +183 -0
  60. data/vendor/listen/spec/listen/adapters/bsd_spec.rb +36 -0
  61. data/vendor/listen/spec/listen/adapters/darwin_spec.rb +37 -0
  62. data/vendor/listen/spec/listen/adapters/linux_spec.rb +47 -0
  63. data/vendor/listen/spec/listen/adapters/polling_spec.rb +68 -0
  64. data/vendor/listen/spec/listen/adapters/windows_spec.rb +30 -0
  65. data/vendor/listen/spec/listen/dependency_manager_spec.rb +107 -0
  66. data/vendor/listen/spec/listen/directory_record_spec.rb +1225 -0
  67. data/vendor/listen/spec/listen/listener_spec.rb +169 -0
  68. data/vendor/listen/spec/listen/multi_listener_spec.rb +174 -0
  69. data/vendor/listen/spec/listen/turnstile_spec.rb +56 -0
  70. data/vendor/listen/spec/listen_spec.rb +73 -0
  71. data/vendor/listen/spec/spec_helper.rb +21 -0
  72. data/vendor/listen/spec/support/adapter_helper.rb +629 -0
  73. data/vendor/listen/spec/support/directory_record_helper.rb +55 -0
  74. data/vendor/listen/spec/support/fixtures_helper.rb +29 -0
  75. data/vendor/listen/spec/support/listeners_helper.rb +156 -0
  76. data/vendor/listen/spec/support/platform_helper.rb +15 -0
  77. metadata +318 -300
  78. data/test/Gemfile.lock +0 -10
data/Rakefile CHANGED
@@ -21,7 +21,7 @@ end
21
21
 
22
22
  # ----- Code Style Enforcement -----
23
23
 
24
- if RUBY_VERSION !~ /^(1\.8|2\.1)/ && (ENV.has_key?("RUBOCOP") && ENV["RUBOCOP"] == "true" || !ENV.has_key?("RUBOCOP"))
24
+ if RUBY_VERSION !~ /^(1\.8|2\.1)/ && (ENV.has_key?("RUBOCOP") && ENV["RUBOCOP"] == "true" || !(ENV.has_key?("RUBOCOP") || ENV.has_key?("TEST")))
25
25
  require 'rubocop/rake_task'
26
26
  Rubocop::RakeTask.new do |t|
27
27
  t.patterns = FileList["lib/**/*"]
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.3.0.rc.1
1
+ 3.3.0.rc.2
@@ -1 +1 @@
1
- 12 October 2013 15:48:52 GMT
1
+ 23 November 2013 02:13:52 UTC
@@ -17,6 +17,11 @@ require 'sass/version'
17
17
  #
18
18
  # Also see the {file:SASS_REFERENCE.md full Sass reference}.
19
19
  module Sass
20
+ class << self
21
+ # @private
22
+ attr_accessor :tests_running
23
+ end
24
+
20
25
  # The global load paths for Sass files. This is meant for plugins and
21
26
  # libraries to register the paths to their Sass stylesheets to that they may
22
27
  # be `@imported`. This load path is used by every instance of {Sass::Engine}.
@@ -88,8 +88,6 @@ module Sass
88
88
  # output = sass_engine.render
89
89
  # puts output
90
90
  class Engine
91
- include Sass::Util
92
-
93
91
  # A line of Sass code.
94
92
  #
95
93
  # `text`: `String`
@@ -375,7 +373,7 @@ ERR
375
373
  end
376
374
 
377
375
  def encode_and_set_charset(rendered)
378
- return rendered if ruby1_8?
376
+ return rendered if Sass::Util.ruby1_8?
379
377
  begin
380
378
  # Try to convert the result to the original encoding,
381
379
  # but if that doesn't work fall back on UTF-8
@@ -431,7 +429,7 @@ ERR
431
429
  def check_encoding!
432
430
  return if @checked_encoding
433
431
  @checked_encoding = true
434
- @template, @original_encoding = check_sass_encoding(@template) do |msg, line|
432
+ @template, @original_encoding = Sass::Util.check_sass_encoding(@template) do |msg, line|
435
433
  raise Sass::SyntaxError.new(msg, :line => line)
436
434
  end
437
435
  end
@@ -766,7 +764,7 @@ WARNING
766
764
  value = self.class.parse_interp(
767
765
  line.text, line.index, to_parser_offset(line.offset), :filename => @filename)
768
766
  end
769
- value = with_extracted_values(value) do |str|
767
+ value = Sass::Util.with_extracted_values(value) do |str|
770
768
  str = str.gsub(/^#{line.comment_tab_str}/m, '')[2..-1] # get rid of // or /*
771
769
  format_comment_text(str, silent)
772
770
  end
@@ -33,7 +33,6 @@ module Sass
33
33
  # #=> Compiling app/sass/ie.scss to public/stylesheets/ie.css
34
34
  # @see Sass::Plugin::Compiler
35
35
  module Plugin
36
- include Sass::Util
37
36
  extend self
38
37
 
39
38
  @checked_for_updates = false
@@ -27,7 +27,6 @@ module Sass::Plugin
27
27
  # * `:never_update`
28
28
  # * `:always_check`
29
29
  class Compiler
30
- include Sass::Util
31
30
  include Configuration
32
31
  extend Sass::Callbacks
33
32
 
@@ -61,7 +60,7 @@ module Sass::Plugin
61
60
  # when an exception CSS file is being written.
62
61
  # To run an action for those files, use \{#on\_compilation\_error}.
63
62
  #
64
- # @yield [template, css]
63
+ # @yield [template, css, sourcemap]
65
64
  # @yieldparam template [String]
66
65
  # The location of the Sass/SCSS file being updated.
67
66
  # @yieldparam css [String]
@@ -219,6 +219,9 @@ module Sass::Script
219
219
  # \{#mixin_exists mixin-exists($name)}
220
220
  # : Returns whether a mixin with the given name exists.
221
221
  #
222
+ # \{#inspect inspect($value)}
223
+ # : Returns the string representation of a value as it would be represented in Sass.
224
+ #
222
225
  # \{#type_of type-of($value)}
223
226
  # : Returns the type of a value.
224
227
  #
@@ -1155,12 +1158,12 @@ module Sass::Script
1155
1158
  # same time
1156
1159
  def change_color(color, kwargs)
1157
1160
  assert_type color, :Color, :color
1158
- with = Sass::Util.map_hash(%w[red green blue hue saturation lightness alpha]) do |name, max|
1161
+ with = Sass::Util.to_hash(%w[red green blue hue saturation lightness alpha].map do |name|
1159
1162
  val = kwargs.delete(name)
1160
1163
  next unless val
1161
1164
  assert_type val, :Number, name
1162
1165
  [name.to_sym, val.value]
1163
- end
1166
+ end)
1164
1167
 
1165
1168
  unless kwargs.empty?
1166
1169
  name, val = kwargs.to_a.first
@@ -2154,6 +2157,17 @@ module Sass::Script
2154
2157
  end
2155
2158
  declare :mixin_exists, [:name]
2156
2159
 
2160
+
2161
+ # Return a string containing the value as its Sass representation.
2162
+ #
2163
+ # @param value [Sass::Script::Value::Base] The value to inspect.
2164
+ # @return [Sass::Script::Value::String] A respresentation of the value as
2165
+ # it would be written in Sass.
2166
+ def inspect(value)
2167
+ unquoted_string(value.to_sass)
2168
+ end
2169
+ declare :inspect, [:value]
2170
+
2157
2171
  private
2158
2172
 
2159
2173
  # This method implements the pattern of transforming a numeric value into
@@ -117,18 +117,28 @@ module Sass
117
117
  # while the boolean represents whether or not the string
118
118
  # is following an interpolated segment.
119
119
  STRING_REGULAR_EXPRESSIONS = {
120
- [:double, false] => string_re('"', '"'),
121
- [:single, false] => string_re("'", "'"),
122
- [:double, true] => string_re('', '"'),
123
- [:single, true] => string_re('', "'"),
124
- [:uri, false] => /url\(#{W}(#{URLCHAR}*?)(#{W}\)|#\{)/,
125
- [:uri, true] => /(#{URLCHAR}*?)(#{W}\)|#\{)/,
120
+ :double => {
121
+ false => string_re('"', '"'),
122
+ true => string_re('', '"')
123
+ },
124
+ :single => {
125
+ false => string_re("'", "'"),
126
+ true => string_re('', "'")
127
+ },
128
+ :uri => {
129
+ false => /url\(#{W}(#{URLCHAR}*?)(#{W}\)|#\{)/,
130
+ true => /(#{URLCHAR}*?)(#{W}\)|#\{)/
131
+ },
126
132
  # Defined in https://developer.mozilla.org/en/CSS/@-moz-document as a
127
133
  # non-standard version of http://www.w3.org/TR/css3-conditional/
128
- [:url_prefix, false] => /url-prefix\(#{W}(#{URLCHAR}*?)(#{W}\)|#\{)/,
129
- [:url_prefix, true] => /(#{URLCHAR}*?)(#{W}\)|#\{)/,
130
- [:domain, false] => /domain\(#{W}(#{URLCHAR}*?)(#{W}\)|#\{)/,
131
- [:domain, true] => /(#{URLCHAR}*?)(#{W}\)|#\{)/,
134
+ :url_prefix => {
135
+ false => /url-prefix\(#{W}(#{URLCHAR}*?)(#{W}\)|#\{)/,
136
+ true => /(#{URLCHAR}*?)(#{W}\)|#\{)/
137
+ },
138
+ :domain => {
139
+ false => /domain\(#{W}(#{URLCHAR}*?)(#{W}\)|#\{)/,
140
+ true => /(#{URLCHAR}*?)(#{W}\)|#\{)/
141
+ }
132
142
  }
133
143
 
134
144
  # @param str [String, StringScanner] The source text to lex
@@ -265,7 +275,7 @@ module Sass
265
275
  end
266
276
 
267
277
  def string(re, open)
268
- return unless scan(STRING_REGULAR_EXPRESSIONS[[re, open]])
278
+ return unless scan(STRING_REGULAR_EXPRESSIONS[re][open])
269
279
  if @scanner[2] == '#{' # '
270
280
  @scanner.pos -= 2 # Don't actually consume the #{
271
281
  @offset -= 2
@@ -364,7 +374,7 @@ MESSAGE
364
374
  return unless str
365
375
  c = str.count("\n")
366
376
  @line += c
367
- @offset = (c == 0 ? @offset + str.size : str[/\n([^\n]*)/, 1].size + 1)
377
+ @offset = (c == 0 ? @offset + str.size : str.size - str.rindex("\n") + 1)
368
378
  str
369
379
  end
370
380
 
@@ -219,7 +219,7 @@ module Sass
219
219
  interp = try_ops_after_interp(#{ops.inspect}, #{name.inspect})
220
220
  return interp if interp
221
221
  return unless e = #{sub}
222
- while tok = try_tok(#{ops.map {|o| o.inspect}.join(', ')})
222
+ while tok = try_toks(#{ops.map {|o| o.inspect}.join(', ')})
223
223
  if interp = try_op_before_interp(tok, e)
224
224
  other_interp = try_ops_after_interp(#{ops.inspect}, #{name.inspect}, interp)
225
225
  return interp unless other_interp
@@ -266,12 +266,12 @@ RUBY
266
266
  return unless e
267
267
  return list e, start_pos unless @lexer.peek && @lexer.peek.type == :colon
268
268
 
269
- key, value = map_pair(e)
270
- map = node(Sass::Script::Tree::MapLiteral.new([[key, value]]), start_pos)
269
+ pair = map_pair(e)
270
+ map = node(Sass::Script::Tree::MapLiteral.new([pair]), start_pos)
271
271
  while try_tok(:comma)
272
- return map unless (pair = map_pair)
273
- key, value = pair
274
- map.pairs << [key, value]
272
+ pair = map_pair
273
+ return map unless pair
274
+ map.pairs << pair
275
275
  end
276
276
  map
277
277
  end
@@ -321,7 +321,7 @@ RUBY
321
321
 
322
322
  def try_ops_after_interp(ops, name, prev = nil)
323
323
  return unless @lexer.after_interpolation?
324
- op = try_tok(*ops)
324
+ op = try_toks(*ops)
325
325
  return unless op
326
326
  interp = try_op_before_interp(op, prev)
327
327
  return interp if interp
@@ -413,12 +413,12 @@ RUBY
413
413
  if try_tok(:colon)
414
414
  val = assert_expr(:space)
415
415
  must_have_default = true
416
- elsif must_have_default
417
- raise SyntaxError.new(
418
- "Required argument #{var.inspect} must come before any optional arguments.")
419
416
  elsif try_tok(:splat)
420
417
  splat = var
421
418
  break
419
+ elsif must_have_default
420
+ raise SyntaxError.new(
421
+ "Required argument #{var.inspect} must come before any optional arguments.")
422
422
  end
423
423
  res << [var, val]
424
424
  break unless try_tok(:comma)
@@ -543,7 +543,7 @@ RUBY
543
543
  end
544
544
 
545
545
  def literal
546
- t = try_tok(:color, :bool, :null)
546
+ t = try_toks(:color, :bool, :null)
547
547
  return literal_node(t.value, t.source_range) if t
548
548
  end
549
549
 
@@ -564,13 +564,26 @@ RUBY
564
564
  @lexer.expected!(expected || EXPR_NAMES[name] || EXPR_NAMES[:default])
565
565
  end
566
566
 
567
- def assert_tok(*names)
568
- t = try_tok(*names)
567
+ def assert_tok(name)
568
+ # Avoids an array allocation caused by argument globbing in assert_toks.
569
+ t = try_tok(name)
570
+ return t if t
571
+ @lexer.expected!(Lexer::TOKEN_NAMES[name] || name.to_s)
572
+ end
573
+
574
+ def assert_toks(*names)
575
+ t = try_toks(*names)
569
576
  return t if t
570
577
  @lexer.expected!(names.map {|tok| Lexer::TOKEN_NAMES[tok] || tok}.join(" or "))
571
578
  end
572
579
 
573
- def try_tok(*names)
580
+ def try_tok(name)
581
+ # Avoids an array allocation caused by argument globbing in the try_toks method.
582
+ peeked = @lexer.peek
583
+ peeked && name == peeked.type && @lexer.next
584
+ end
585
+
586
+ def try_toks(*names)
574
587
  peeked = @lexer.peek
575
588
  peeked && names.include?(peeked.type) && @lexer.next
576
589
  end
@@ -47,7 +47,7 @@ module Sass::Script::Tree
47
47
  def _perform(environment)
48
48
  val = environment.var(name)
49
49
  raise Sass::SyntaxError.new("Undefined variable: \"$#{name}\".") unless val
50
- if val.is_a?(Sass::Script::Value::Number)
50
+ if val.is_a?(Sass::Script::Value::Number) && val.original
51
51
  val = val.dup
52
52
  val.original = nil
53
53
  end
@@ -30,7 +30,7 @@ module Sass::Script::Value
30
30
  #
31
31
  # @param value [Object] The object for \{#value}
32
32
  def initialize(value = nil)
33
- @value = value
33
+ @value = value.freeze
34
34
  end
35
35
 
36
36
  # Sets the options hash for this node,
@@ -14,13 +14,33 @@ module Sass::Script::Value
14
14
  # If only the alpha channel is modified using \{#with},
15
15
  # the cached RGB and HSL values are retained.
16
16
  class Color < Base
17
- class << self; include Sass::Util; end
17
+ # @private
18
+ #
19
+ # Convert a ruby integer to a rgba components
20
+ # @param color [Fixnum]
21
+ # @return [Array<Fixnum>] Array of 4 numbers representing r,g,b and alpha
22
+ def self.int_to_rgba(color)
23
+ rgba = (0..3).map {|n| color >> (n << 3) & 0xff}.reverse
24
+ rgba[-1] = rgba[-1] / 255.0
25
+ rgba
26
+ end
27
+
28
+ ALTERNATE_COLOR_NAMES = Sass::Util.map_vals({
29
+ 'aqua' => 0x00FFFFFF,
30
+ 'darkgrey' => 0xA9A9A9FF,
31
+ 'darkslategrey' => 0x2F4F4FFF,
32
+ 'dimgrey' => 0x696969FF,
33
+ 'fuchsia' => 0xFF00FFFF,
34
+ 'grey' => 0x808080FF,
35
+ 'lightgrey' => 0xD3D3D3FF,
36
+ 'lightslategrey' => 0x778899FF,
37
+ 'slategrey' => 0x708090FF,
38
+ }, &method(:int_to_rgba))
18
39
 
19
40
  # A hash from color names to `[red, green, blue]` value arrays.
20
- COLOR_NAMES = map_vals(
41
+ COLOR_NAMES = Sass::Util.map_vals({
21
42
  'aliceblue' => 0xF0F8FFFF,
22
43
  'antiquewhite' => 0xFAEBD7FF,
23
- 'aqua' => 0x00FFFFFF,
24
44
  'aquamarine' => 0x7FFFD4FF,
25
45
  'azure' => 0xF0FFFFFF,
26
46
  'beige' => 0xF5F5DCFF,
@@ -43,7 +63,6 @@ module Sass::Script::Value
43
63
  'darkcyan' => 0x008B8BFF,
44
64
  'darkgoldenrod' => 0xB8860BFF,
45
65
  'darkgray' => 0xA9A9A9FF,
46
- 'darkgrey' => 0xA9A9A9FF,
47
66
  'darkgreen' => 0x006400FF,
48
67
  'darkkhaki' => 0xBDB76BFF,
49
68
  'darkmagenta' => 0x8B008BFF,
@@ -55,24 +74,20 @@ module Sass::Script::Value
55
74
  'darkseagreen' => 0x8FBC8FFF,
56
75
  'darkslateblue' => 0x483D8BFF,
57
76
  'darkslategray' => 0x2F4F4FFF,
58
- 'darkslategrey' => 0x2F4F4FFF,
59
77
  'darkturquoise' => 0x00CED1FF,
60
78
  'darkviolet' => 0x9400D3FF,
61
79
  'deeppink' => 0xFF1493FF,
62
80
  'deepskyblue' => 0x00BFFFFF,
63
81
  'dimgray' => 0x696969FF,
64
- 'dimgrey' => 0x696969FF,
65
82
  'dodgerblue' => 0x1E90FFFF,
66
83
  'firebrick' => 0xB22222FF,
67
84
  'floralwhite' => 0xFFFAF0FF,
68
85
  'forestgreen' => 0x228B22FF,
69
- 'fuchsia' => 0xFF00FFFF,
70
86
  'gainsboro' => 0xDCDCDCFF,
71
87
  'ghostwhite' => 0xF8F8FFFF,
72
88
  'gold' => 0xFFD700FF,
73
89
  'goldenrod' => 0xDAA520FF,
74
90
  'gray' => 0x808080FF,
75
- 'grey' => 0x808080FF,
76
91
  'green' => 0x008000FF,
77
92
  'greenyellow' => 0xADFF2FFF,
78
93
  'honeydew' => 0xF0FFF0FF,
@@ -91,13 +106,11 @@ module Sass::Script::Value
91
106
  'lightgoldenrodyellow' => 0xFAFAD2FF,
92
107
  'lightgreen' => 0x90EE90FF,
93
108
  'lightgray' => 0xD3D3D3FF,
94
- 'lightgrey' => 0xD3D3D3FF,
95
109
  'lightpink' => 0xFFB6C1FF,
96
110
  'lightsalmon' => 0xFFA07AFF,
97
111
  'lightseagreen' => 0x20B2AAFF,
98
112
  'lightskyblue' => 0x87CEFAFF,
99
113
  'lightslategray' => 0x778899FF,
100
- 'lightslategrey' => 0x778899FF,
101
114
  'lightsteelblue' => 0xB0C4DEFF,
102
115
  'lightyellow' => 0xFFFFE0FF,
103
116
  'lime' => 0x00FF00FF,
@@ -150,7 +163,6 @@ module Sass::Script::Value
150
163
  'skyblue' => 0x87CEEBFF,
151
164
  'slateblue' => 0x6A5ACDFF,
152
165
  'slategray' => 0x708090FF,
153
- 'slategrey' => 0x708090FF,
154
166
  'snow' => 0xFFFAFAFF,
155
167
  'springgreen' => 0x00FF7FFF,
156
168
  'steelblue' => 0x4682B4FF,
@@ -166,14 +178,14 @@ module Sass::Script::Value
166
178
  'whitesmoke' => 0xF5F5F5FF,
167
179
  'yellow' => 0xFFFF00FF,
168
180
  'yellowgreen' => 0x9ACD32FF
169
- ) do |color|
170
- rgba = (0..3).map {|n| color >> (n << 3) & 0xff}.reverse
171
- rgba[-1] = rgba[-1] / 255.0
172
- rgba
173
- end
181
+ }, &method(:int_to_rgba))
174
182
 
175
183
  # A hash from `[red, green, blue, alpha]` value arrays to color names.
176
- COLOR_NAMES_REVERSE = map_hash(hash_to_a(COLOR_NAMES)) {|k, v| [v, k]}
184
+ COLOR_NAMES_REVERSE = COLOR_NAMES.invert.freeze
185
+
186
+ # We add the alternate color names after inverting because
187
+ # different ruby implementations and versions vary on the ordering of the result of invert.
188
+ COLOR_NAMES.update(ALTERNATE_COLOR_NAMES).freeze
177
189
 
178
190
  # Constructs an RGB or HSL color object,
179
191
  # optionally with an alpha channel.
@@ -52,7 +52,7 @@ module Sass::Script::Value
52
52
  def to_sass(opts = {})
53
53
  return "()" if value.empty?
54
54
  precedence = Sass::Script::Parser.precedence_of(separator)
55
- members = value.reject {|e| e.is_a?(Null)}.map do |v|
55
+ members = value.map do |v|
56
56
  if v.is_a?(List) && Sass::Script::Parser.precedence_of(v.separator) <= precedence ||
57
57
  separator == :space && v.is_a?(Sass::Script::Tree::UnaryOperation) &&
58
58
  (v.operator == :minus || v.operator == :plus)
@@ -276,7 +276,14 @@ module Sass::Script::Value
276
276
  # @return [String] The representation
277
277
  def inspect(opts = {})
278
278
  value = self.class.round(self.value)
279
- unitless? ? value.to_s : "#{value}#{unit_str}"
279
+ str = value.to_s
280
+
281
+ # Ruby will occasionally print in scientific notation if the number is
282
+ # small enough. That's technically valid CSS, but it's not well-supported
283
+ # and confusing.
284
+ str = ("%0.#{self.class.precision}f" % value).gsub(/0*$/, '') if str.include?('e')
285
+
286
+ unitless? ? str : "#{str}#{unit_str}"
280
287
  end
281
288
  alias_method :to_sass, :inspect
282
289
 
@@ -1092,11 +1092,11 @@ MESSAGE
1092
1092
  end
1093
1093
 
1094
1094
  def _interp_string(type)
1095
- start = tok(Sass::Script::Lexer::STRING_REGULAR_EXPRESSIONS[[type, false]])
1095
+ start = tok(Sass::Script::Lexer::STRING_REGULAR_EXPRESSIONS[type][false])
1096
1096
  return unless start
1097
1097
  res = [start]
1098
1098
 
1099
- mid_re = Sass::Script::Lexer::STRING_REGULAR_EXPRESSIONS[[type, true]]
1099
+ mid_re = Sass::Script::Lexer::STRING_REGULAR_EXPRESSIONS[type][true]
1100
1100
  # @scanner[2].empty? means we've started an interpolated section
1101
1101
  while @scanner[2] == '#{'
1102
1102
  @scanner.pos -= 2 # Don't consume the #{