sass 3.7.4 → 4.0.0.alpha.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 (257) hide show
  1. checksums.yaml +13 -5
  2. data/.yardopts +1 -1
  3. data/CODE_OF_CONDUCT.md +1 -1
  4. data/CONTRIBUTING.md +1 -146
  5. data/MIT-LICENSE +1 -1
  6. data/README.md +25 -39
  7. data/Rakefile +274 -0
  8. data/VERSION +1 -1
  9. data/VERSION_DATE +1 -1
  10. data/lib/sass.rb +3 -3
  11. data/lib/sass/cache_stores/filesystem.rb +2 -2
  12. data/lib/sass/cache_stores/memory.rb +5 -4
  13. data/lib/sass/callbacks.rb +2 -2
  14. data/lib/sass/css.rb +12 -12
  15. data/lib/sass/engine.rb +44 -62
  16. data/lib/sass/environment.rb +7 -35
  17. data/lib/sass/error.rb +14 -14
  18. data/lib/sass/exec/base.rb +14 -3
  19. data/lib/sass/exec/sass_convert.rb +6 -20
  20. data/lib/sass/exec/sass_scss.rb +29 -5
  21. data/lib/sass/features.rb +2 -3
  22. data/lib/sass/importers/filesystem.rb +6 -11
  23. data/lib/sass/logger.rb +3 -8
  24. data/lib/sass/logger/base.rb +2 -19
  25. data/lib/sass/plugin.rb +2 -3
  26. data/lib/sass/plugin/compiler.rb +67 -48
  27. data/lib/sass/plugin/configuration.rb +3 -3
  28. data/lib/sass/plugin/merb.rb +1 -1
  29. data/lib/sass/plugin/rack.rb +3 -3
  30. data/lib/sass/plugin/staleness_checker.rb +3 -3
  31. data/lib/sass/railtie.rb +1 -1
  32. data/lib/sass/script.rb +3 -3
  33. data/lib/sass/script/css_parser.rb +15 -5
  34. data/lib/sass/script/functions.rb +121 -337
  35. data/lib/sass/script/lexer.rb +36 -102
  36. data/lib/sass/script/parser.rb +153 -529
  37. data/lib/sass/script/tree/funcall.rb +34 -42
  38. data/lib/sass/script/tree/interpolation.rb +26 -171
  39. data/lib/sass/script/tree/list_literal.rb +8 -23
  40. data/lib/sass/script/tree/map_literal.rb +2 -2
  41. data/lib/sass/script/tree/node.rb +3 -3
  42. data/lib/sass/script/tree/operation.rb +16 -43
  43. data/lib/sass/script/tree/string_interpolation.rb +43 -64
  44. data/lib/sass/script/tree/variable.rb +1 -1
  45. data/lib/sass/script/value.rb +0 -2
  46. data/lib/sass/script/value/arg_list.rb +1 -1
  47. data/lib/sass/script/value/base.rb +9 -27
  48. data/lib/sass/script/value/color.rb +18 -26
  49. data/lib/sass/script/value/helpers.rb +18 -44
  50. data/lib/sass/script/value/list.rb +14 -35
  51. data/lib/sass/script/value/map.rb +2 -2
  52. data/lib/sass/script/value/number.rb +16 -26
  53. data/lib/sass/script/value/string.rb +1 -30
  54. data/lib/sass/scss.rb +2 -0
  55. data/lib/sass/scss/css_parser.rb +3 -7
  56. data/lib/sass/scss/parser.rb +78 -196
  57. data/lib/sass/scss/rx.rb +14 -7
  58. data/lib/sass/scss/script_lexer.rb +15 -0
  59. data/lib/sass/scss/script_parser.rb +25 -0
  60. data/lib/sass/scss/static_parser.rb +55 -38
  61. data/lib/sass/selector.rb +10 -7
  62. data/lib/sass/selector/abstract_sequence.rb +12 -15
  63. data/lib/sass/selector/comma_sequence.rb +6 -24
  64. data/lib/sass/selector/pseudo.rb +6 -19
  65. data/lib/sass/selector/sequence.rb +16 -14
  66. data/lib/sass/selector/simple.rb +7 -9
  67. data/lib/sass/selector/simple_sequence.rb +12 -16
  68. data/lib/sass/shared.rb +1 -1
  69. data/lib/sass/source/map.rb +9 -7
  70. data/lib/sass/source/position.rb +4 -4
  71. data/lib/sass/stack.rb +3 -23
  72. data/lib/sass/tree/charset_node.rb +1 -1
  73. data/lib/sass/tree/comment_node.rb +1 -1
  74. data/lib/sass/tree/function_node.rb +3 -2
  75. data/lib/sass/tree/node.rb +3 -5
  76. data/lib/sass/tree/prop_node.rb +58 -49
  77. data/lib/sass/tree/rule_node.rb +8 -15
  78. data/lib/sass/tree/visitors/check_nesting.rb +23 -19
  79. data/lib/sass/tree/visitors/convert.rb +13 -15
  80. data/lib/sass/tree/visitors/cssize.rb +15 -4
  81. data/lib/sass/tree/visitors/deep_copy.rb +2 -2
  82. data/lib/sass/tree/visitors/extend.rb +14 -10
  83. data/lib/sass/tree/visitors/perform.rb +18 -29
  84. data/lib/sass/tree/visitors/set_options.rb +2 -2
  85. data/lib/sass/tree/visitors/to_css.rb +47 -77
  86. data/lib/sass/util.rb +311 -98
  87. data/lib/sass/util/cross_platform_random.rb +19 -0
  88. data/lib/sass/util/multibyte_string_scanner.rb +133 -127
  89. data/lib/sass/util/normalized_map.rb +8 -1
  90. data/lib/sass/util/ordered_hash.rb +192 -0
  91. data/lib/sass/version.rb +6 -2
  92. data/test/sass/cache_test.rb +131 -0
  93. data/test/sass/callbacks_test.rb +61 -0
  94. data/test/sass/compiler_test.rb +236 -0
  95. data/test/sass/conversion_test.rb +2171 -0
  96. data/test/sass/css2sass_test.rb +526 -0
  97. data/test/sass/data/hsl-rgb.txt +319 -0
  98. data/test/sass/encoding_test.rb +219 -0
  99. data/test/sass/engine_test.rb +3400 -0
  100. data/test/sass/exec_test.rb +86 -0
  101. data/test/sass/extend_test.rb +1719 -0
  102. data/test/sass/fixtures/test_staleness_check_across_importers.css +1 -0
  103. data/test/sass/fixtures/test_staleness_check_across_importers.scss +1 -0
  104. data/test/sass/functions_test.rb +1984 -0
  105. data/test/sass/importer_test.rb +421 -0
  106. data/test/sass/logger_test.rb +58 -0
  107. data/test/sass/mock_importer.rb +49 -0
  108. data/test/sass/more_results/more1.css +9 -0
  109. data/test/sass/more_results/more1_with_line_comments.css +26 -0
  110. data/test/sass/more_results/more_import.css +29 -0
  111. data/test/sass/more_templates/_more_partial.sass +2 -0
  112. data/test/sass/more_templates/more1.sass +23 -0
  113. data/test/sass/more_templates/more_import.sass +11 -0
  114. data/test/sass/plugin_test.rb +556 -0
  115. data/test/sass/results/alt.css +4 -0
  116. data/test/sass/results/basic.css +9 -0
  117. data/test/sass/results/cached_import_option.css +3 -0
  118. data/test/sass/results/compact.css +5 -0
  119. data/test/sass/results/complex.css +86 -0
  120. data/test/sass/results/compressed.css +1 -0
  121. data/test/sass/results/expanded.css +19 -0
  122. data/test/sass/results/filename_fn.css +3 -0
  123. data/test/sass/results/if.css +3 -0
  124. data/test/sass/results/import.css +31 -0
  125. data/test/sass/results/import_charset.css +5 -0
  126. data/test/sass/results/import_charset_1_8.css +5 -0
  127. data/test/sass/results/import_charset_ibm866.css +5 -0
  128. data/test/sass/results/import_content.css +1 -0
  129. data/test/sass/results/line_numbers.css +49 -0
  130. data/test/sass/results/mixins.css +95 -0
  131. data/test/sass/results/multiline.css +24 -0
  132. data/test/sass/results/nested.css +22 -0
  133. data/test/sass/results/options.css +1 -0
  134. data/test/sass/results/parent_ref.css +13 -0
  135. data/test/sass/results/script.css +16 -0
  136. data/test/sass/results/scss_import.css +31 -0
  137. data/test/sass/results/scss_importee.css +2 -0
  138. data/test/sass/results/subdir/nested_subdir/nested_subdir.css +1 -0
  139. data/test/sass/results/subdir/subdir.css +3 -0
  140. data/test/sass/results/units.css +11 -0
  141. data/test/sass/results/warn.css +0 -0
  142. data/test/sass/results/warn_imported.css +0 -0
  143. data/test/sass/script_conversion_test.rb +306 -0
  144. data/test/sass/script_test.rb +1206 -0
  145. data/test/sass/scss/css_test.rb +1281 -0
  146. data/test/sass/scss/rx_test.rb +160 -0
  147. data/test/sass/scss/scss_test.rb +4147 -0
  148. data/test/sass/scss/test_helper.rb +37 -0
  149. data/test/sass/source_map_test.rb +1055 -0
  150. data/test/sass/superselector_test.rb +210 -0
  151. data/test/sass/templates/_cached_import_option_partial.scss +1 -0
  152. data/test/sass/templates/_double_import_loop2.sass +1 -0
  153. data/test/sass/templates/_filename_fn_import.scss +11 -0
  154. data/test/sass/templates/_imported_charset_ibm866.sass +4 -0
  155. data/test/sass/templates/_imported_charset_utf8.sass +4 -0
  156. data/test/sass/templates/_imported_content.sass +3 -0
  157. data/test/sass/templates/_partial.sass +2 -0
  158. data/test/sass/templates/_same_name_different_partiality.scss +1 -0
  159. data/test/sass/templates/alt.sass +16 -0
  160. data/test/sass/templates/basic.sass +23 -0
  161. data/test/sass/templates/bork1.sass +2 -0
  162. data/test/sass/templates/bork2.sass +2 -0
  163. data/test/sass/templates/bork3.sass +2 -0
  164. data/test/sass/templates/bork4.sass +2 -0
  165. data/test/sass/templates/bork5.sass +3 -0
  166. data/test/sass/templates/cached_import_option.scss +3 -0
  167. data/test/sass/templates/compact.sass +17 -0
  168. data/test/sass/templates/complex.sass +305 -0
  169. data/test/sass/templates/compressed.sass +15 -0
  170. data/test/sass/templates/double_import_loop1.sass +1 -0
  171. data/test/sass/templates/expanded.sass +17 -0
  172. data/test/sass/templates/filename_fn.scss +18 -0
  173. data/test/sass/templates/if.sass +11 -0
  174. data/test/sass/templates/import.sass +12 -0
  175. data/test/sass/templates/import_charset.sass +9 -0
  176. data/test/sass/templates/import_charset_1_8.sass +6 -0
  177. data/test/sass/templates/import_charset_ibm866.sass +11 -0
  178. data/test/sass/templates/import_content.sass +4 -0
  179. data/test/sass/templates/importee.less +2 -0
  180. data/test/sass/templates/importee.sass +19 -0
  181. data/test/sass/templates/line_numbers.sass +13 -0
  182. data/test/sass/templates/mixin_bork.sass +5 -0
  183. data/test/sass/templates/mixins.sass +76 -0
  184. data/test/sass/templates/multiline.sass +20 -0
  185. data/test/sass/templates/nested.sass +25 -0
  186. data/test/sass/templates/nested_bork1.sass +2 -0
  187. data/test/sass/templates/nested_bork2.sass +2 -0
  188. data/test/sass/templates/nested_bork3.sass +2 -0
  189. data/test/sass/templates/nested_bork4.sass +2 -0
  190. data/test/sass/templates/nested_import.sass +2 -0
  191. data/test/sass/templates/nested_mixin_bork.sass +6 -0
  192. data/test/sass/templates/options.sass +2 -0
  193. data/test/sass/templates/parent_ref.sass +25 -0
  194. data/test/sass/templates/same_name_different_ext.sass +2 -0
  195. data/test/sass/templates/same_name_different_ext.scss +1 -0
  196. data/test/sass/templates/same_name_different_partiality.scss +1 -0
  197. data/test/sass/templates/script.sass +101 -0
  198. data/test/sass/templates/scss_import.scss +12 -0
  199. data/test/sass/templates/scss_importee.scss +1 -0
  200. data/test/sass/templates/single_import_loop.sass +1 -0
  201. data/test/sass/templates/subdir/import_up1.scss +1 -0
  202. data/test/sass/templates/subdir/import_up2.scss +1 -0
  203. data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +2 -0
  204. data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +3 -0
  205. data/test/sass/templates/subdir/subdir.sass +6 -0
  206. data/test/sass/templates/units.sass +11 -0
  207. data/test/sass/templates/warn.sass +3 -0
  208. data/test/sass/templates/warn_imported.sass +4 -0
  209. data/test/sass/test_helper.rb +8 -0
  210. data/test/sass/util/multibyte_string_scanner_test.rb +147 -0
  211. data/test/sass/util/normalized_map_test.rb +51 -0
  212. data/test/sass/util/subset_map_test.rb +91 -0
  213. data/test/sass/util_test.rb +438 -0
  214. data/test/sass/value_helpers_test.rb +179 -0
  215. data/test/test_helper.rb +110 -0
  216. data/vendor/listen/CHANGELOG.md +1 -0
  217. data/vendor/listen/CONTRIBUTING.md +38 -0
  218. data/vendor/listen/Gemfile +20 -0
  219. data/vendor/listen/Guardfile +8 -0
  220. data/vendor/listen/LICENSE +20 -0
  221. data/vendor/listen/README.md +349 -0
  222. data/vendor/listen/Rakefile +5 -0
  223. data/vendor/listen/Vagrantfile +96 -0
  224. data/vendor/listen/lib/listen.rb +54 -0
  225. data/vendor/listen/lib/listen/adapter.rb +327 -0
  226. data/vendor/listen/lib/listen/adapters/bsd.rb +75 -0
  227. data/vendor/listen/lib/listen/adapters/darwin.rb +48 -0
  228. data/vendor/listen/lib/listen/adapters/linux.rb +81 -0
  229. data/vendor/listen/lib/listen/adapters/polling.rb +58 -0
  230. data/vendor/listen/lib/listen/adapters/windows.rb +91 -0
  231. data/vendor/listen/lib/listen/directory_record.rb +406 -0
  232. data/vendor/listen/lib/listen/listener.rb +323 -0
  233. data/vendor/listen/lib/listen/turnstile.rb +32 -0
  234. data/vendor/listen/lib/listen/version.rb +3 -0
  235. data/vendor/listen/listen.gemspec +28 -0
  236. data/vendor/listen/spec/listen/adapter_spec.rb +149 -0
  237. data/vendor/listen/spec/listen/adapters/bsd_spec.rb +36 -0
  238. data/vendor/listen/spec/listen/adapters/darwin_spec.rb +37 -0
  239. data/vendor/listen/spec/listen/adapters/linux_spec.rb +47 -0
  240. data/vendor/listen/spec/listen/adapters/polling_spec.rb +68 -0
  241. data/vendor/listen/spec/listen/adapters/windows_spec.rb +30 -0
  242. data/vendor/listen/spec/listen/directory_record_spec.rb +1250 -0
  243. data/vendor/listen/spec/listen/listener_spec.rb +258 -0
  244. data/vendor/listen/spec/listen/turnstile_spec.rb +56 -0
  245. data/vendor/listen/spec/listen_spec.rb +67 -0
  246. data/vendor/listen/spec/spec_helper.rb +25 -0
  247. data/vendor/listen/spec/support/adapter_helper.rb +666 -0
  248. data/vendor/listen/spec/support/directory_record_helper.rb +57 -0
  249. data/vendor/listen/spec/support/fixtures_helper.rb +29 -0
  250. data/vendor/listen/spec/support/listeners_helper.rb +179 -0
  251. data/vendor/listen/spec/support/platform_helper.rb +15 -0
  252. metadata +217 -76
  253. data/extra/sass-spec-ref.sh +0 -40
  254. data/lib/sass/deprecation.rb +0 -55
  255. data/lib/sass/logger/delayed.rb +0 -50
  256. data/lib/sass/script/value/callable.rb +0 -25
  257. data/lib/sass/script/value/function.rb +0 -19
@@ -49,14 +49,14 @@ module Sass::Script::Tree
49
49
  # @see Node#_perform
50
50
  def _perform(environment)
51
51
  keys = Set.new
52
- map = Sass::Script::Value::Map.new(Hash[pairs.map do |(k, v)|
52
+ map = Sass::Script::Value::Map.new(Sass::Util.to_hash(pairs.map do |(k, v)|
53
53
  k, v = k.perform(environment), v.perform(environment)
54
54
  if keys.include?(k)
55
55
  raise Sass::SyntaxError.new("Duplicate key #{k.inspect} in map #{to_sass}.")
56
56
  end
57
57
  keys << k
58
58
  [k, v]
59
- end])
59
+ end))
60
60
  map.options = options
61
61
  map
62
62
  end
@@ -10,7 +10,7 @@ module Sass::Script::Tree
10
10
 
11
11
  # The line of the document on which this node appeared.
12
12
  #
13
- # @return [Integer]
13
+ # @return [Fixnum]
14
14
  attr_accessor :line
15
15
 
16
16
  # The source range in the document on which this node appeared.
@@ -25,7 +25,7 @@ module Sass::Script::Tree
25
25
 
26
26
  # Sets the options hash for this node,
27
27
  # as well as for all child nodes.
28
- # See {file:SASS_REFERENCE.md#Options the Sass options documentation}.
28
+ # See {file:SASS_REFERENCE.md#options the Sass options documentation}.
29
29
  #
30
30
  # @param options [{Symbol => Object}] The options
31
31
  def options=(options)
@@ -90,7 +90,7 @@ module Sass::Script::Tree
90
90
  # Converts underscores to dashes if the :dasherize option is set.
91
91
  def dasherize(s, opts)
92
92
  if opts[:dasherize]
93
- s.tr('_', '-')
93
+ s.gsub(/_/, '-')
94
94
  else
95
95
  s
96
96
  end
@@ -2,9 +2,6 @@ module Sass::Script::Tree
2
2
  # A SassScript parse node representing a binary operation,
3
3
  # such as `$a + $b` or `"foo" + 1`.
4
4
  class Operation < Node
5
- @@color_arithmetic_deprecation = Sass::Deprecation.new
6
- @@unitless_equals_deprecation = Sass::Deprecation.new
7
-
8
5
  attr_reader :operand1
9
6
  attr_reader :operand2
10
7
  attr_reader :operator
@@ -88,52 +85,28 @@ module Sass::Script::Tree
88
85
  raise Sass::SyntaxError.new("Undefined operation: \"#{value1} #{@operator} #{value2}\".")
89
86
  end
90
87
 
91
- warn_for_color_arithmetic(value1, value2)
92
- warn_for_unitless_equals(value1, value2, result)
88
+ if (@operator == :eq || @operator == :neq) && value1.is_a?(Sass::Script::Value::Number) &&
89
+ value2.is_a?(Sass::Script::Value::Number) && value1.unitless? != value2.unitless? &&
90
+ result == (if @operator == :eq
91
+ Sass::Script::Value::Bool::TRUE
92
+ else
93
+ Sass::Script::Value::Bool::FALSE
94
+ end)
95
+
96
+ operation = "#{value1} #{@operator == :eq ? '==' : '!='} #{value2}"
97
+ future_value = @operator == :neq
98
+ Sass::Util.sass_warn <<WARNING
99
+ DEPRECATION WARNING on line #{line}#{" of #{filename}" if filename}:
100
+ The result of `#{operation}` will be `#{future_value}` in future releases of Sass.
101
+ Unitless numbers will no longer be equal to the same numbers with units.
102
+ WARNING
103
+ end
93
104
 
94
105
  result
95
106
  end
96
107
 
97
108
  private
98
109
 
99
- def warn_for_color_arithmetic(value1, value2)
100
- return unless @operator == :plus || @operator == :times || @operator == :minus ||
101
- @operator == :div || @operator == :mod
102
-
103
- if value1.is_a?(Sass::Script::Value::Number)
104
- return unless value2.is_a?(Sass::Script::Value::Color)
105
- elsif value1.is_a?(Sass::Script::Value::Color)
106
- return unless value2.is_a?(Sass::Script::Value::Color) || value2.is_a?(Sass::Script::Value::Number)
107
- else
108
- return
109
- end
110
-
111
- @@color_arithmetic_deprecation.warn(filename, line, <<WARNING)
112
- The operation `#{value1} #{@operator} #{value2}` is deprecated and will be an error in future versions.
113
- Consider using Sass's color functions instead.
114
- https://sass-lang.com/documentation/Sass/Script/Functions.html#other_color_functions
115
- WARNING
116
- end
117
-
118
- def warn_for_unitless_equals(value1, value2, result)
119
- return unless @operator == :eq || @operator == :neq
120
- return unless value1.is_a?(Sass::Script::Value::Number)
121
- return unless value2.is_a?(Sass::Script::Value::Number)
122
- return unless value1.unitless? != value2.unitless?
123
- return unless result == (if @operator == :eq
124
- Sass::Script::Value::Bool::TRUE
125
- else
126
- Sass::Script::Value::Bool::FALSE
127
- end)
128
-
129
- operation = "#{value1.to_sass} #{@operator == :eq ? '==' : '!='} #{value2.to_sass}"
130
- future_value = @operator == :neq
131
- @@unitless_equals_deprecation.warn(filename, line, <<WARNING)
132
- The result of `#{operation}` will be `#{future_value}` in future releases of Sass.
133
- Unitless numbers will no longer be equal to the same numbers with units.
134
- WARNING
135
- end
136
-
137
110
  def operand_to_sass(op, side, opts)
138
111
  return "(#{op.to_sass(opts)})" if op.is_a?(Sass::Script::Tree::ListLiteral)
139
112
  return op.to_sass(opts) unless op.is_a?(Operation)
@@ -3,15 +3,9 @@ module Sass::Script::Tree
3
3
  #
4
4
  # @see Interpolation
5
5
  class StringInterpolation < Node
6
- # @return [Literal] The string literal before this interpolation.
7
- attr_reader :before
8
-
9
- # @return [Node] The SassScript within the interpolation
10
- attr_reader :mid
11
-
12
- # @return [StringInterpolation, Literal]
13
- # The string literal or string interpolation before this interpolation.
14
- attr_reader :after
6
+ # @return [[Node, String]] The contents of the interpolation. Strings are
7
+ # literal text, nodes are interpolated segments.
8
+ attr_reader :contents
15
9
 
16
10
  # Whether this is a CSS string or a CSS identifier. The difference is that
17
11
  # strings are written with double-quotes, while identifiers aren't.
@@ -20,62 +14,56 @@ module Sass::Script::Tree
20
14
  # functions such as `url()`.
21
15
  #
22
16
  # @return [Symbol] `:string` or `:identifier`
23
- def type
24
- @before.value.type
25
- end
17
+ attr_reader :type
26
18
 
27
- # Returns the quote character that should be used to wrap a Sass
28
- # representation of this interpolation.
29
- def quote
30
- quote_for(self) || '"'
31
- end
32
-
33
- # Interpolation in a string is of the form `"before #{mid} after"`,
34
- # where `before` and `after` may include more interpolation.
19
+ # Interpolation in a string.
35
20
  #
36
- # @param before [StringInterpolation, Literal] See {StringInterpolation#before}
37
- # @param mid [Node] See {StringInterpolation#mid}
38
- # @param after [Literal] See {StringInterpolation#after}
39
- def initialize(before, mid, after)
40
- @before = before
41
- @mid = mid
42
- @after = after
21
+ # @param contents [[Node, String]] See {StringInterpolation#contents}
22
+ # @param type [Symbol] See {StringInterpolation#type}
23
+ def initialize(contents, type = :string)
24
+ @contents = Sass::Util.merge_adjacent_strings(contents)
25
+ @type = type
43
26
  end
44
27
 
45
28
  # @return [String] A human-readable s-expression representation of the interpolation
46
29
  def inspect
47
- "(string_interpolation #{@before.inspect} #{@mid.inspect} #{@after.inspect})"
30
+ "(string_interpolation #{@type.inspect} #{contents.map {|c| c.inspect}.join(', ')})"
48
31
  end
49
32
 
50
33
  # @see Node#to_sass
51
34
  def to_sass(opts = {})
52
- quote = type == :string ? opts[:quote] || quote_for(self) || '"' : :none
35
+ quote = type == :string ? opts[:quote] || detected_quote : :none
53
36
  opts = opts.merge(:quote => quote)
54
37
 
55
38
  res = ""
56
39
  res << quote if quote != :none
57
- res << _to_sass(before, opts)
58
- res << '#{' << @mid.to_sass(opts.merge(:quote => nil)) << '}'
59
- res << _to_sass(after, opts)
40
+ contents.each do |c|
41
+ if c.is_a?(String)
42
+ c = Sass::Script::Value::String.quote(c, opts).slice(1...-1) if quote != :none
43
+ res << c
44
+ else
45
+ res << '#{' << c.to_sass(opts.merge(:quote => nil)) << '}'
46
+ end
47
+ end
60
48
  res << quote if quote != :none
61
49
  res
62
50
  end
63
51
 
64
- # Returns the three components of the interpolation, `before`, `mid`, and `after`.
52
+ # Returns the node contents of this interpolation.
65
53
  #
66
54
  # @return [Array<Node>]
67
55
  # @see #initialize
68
56
  # @see Node#children
69
57
  def children
70
- [@before, @mid, @after].compact
58
+ contents.select {|c| c.is_a?(Sass::Script::Tree::Node)}
71
59
  end
72
60
 
73
61
  # @see Node#deep_copy
74
62
  def deep_copy
75
63
  node = dup
76
- node.instance_variable_set('@before', @before.deep_copy) if @before
77
- node.instance_variable_set('@mid', @mid.deep_copy)
78
- node.instance_variable_set('@after', @after.deep_copy) if @after
64
+ node.instance_variable_set('@contents', contents.map do |c|
65
+ c.is_a?(String) ? c : c.deep_copy
66
+ end)
79
67
  node
80
68
  end
81
69
 
@@ -87,39 +75,30 @@ module Sass::Script::Tree
87
75
  # @return [Sass::Script::Value::String]
88
76
  # The SassScript string that is the value of the interpolation
89
77
  def _perform(environment)
90
- res = ""
91
- before = @before.perform(environment)
92
- res << before.value
93
- mid = @mid.perform(environment)
94
- res << (mid.is_a?(Sass::Script::Value::String) ? mid.value : mid.to_s(:quote => :none))
95
- res << @after.perform(environment).value
96
- opts(Sass::Script::Value::String.new(res, before.type))
78
+ opts(Sass::Script::Value::String.new(contents.map do |c|
79
+ next c if c.is_a?(String)
80
+ value = c.perform(environment)
81
+ value.is_a?(Sass::Script::Value::String) ? value.value : value.to_s(:quote => :none)
82
+ end.join, type))
97
83
  end
98
84
 
99
85
  private
100
86
 
101
- def _to_sass(string_or_interp, opts)
102
- result = string_or_interp.to_sass(opts)
103
- opts[:quote] == :none ? result : result.slice(1...-1)
104
- end
105
-
106
- def quote_for(string_or_interp)
107
- if string_or_interp.is_a?(Sass::Script::Tree::Literal)
108
- return nil if string_or_interp.value.value.empty?
109
- return '"' if string_or_interp.value.value.include?("'")
110
- return "'" if string_or_interp.value.value.include?('"')
111
- return nil
87
+ # Returns the best quote to use for this interpolation.
88
+ #
89
+ # @return [String]
90
+ def detected_quote
91
+ has_double_quote = false
92
+ contents.each do |c|
93
+ next if c.is_a?(Sass::Script::Tree::Node)
94
+
95
+ # Double-quotes take precedence over single quotes, so if any string contains
96
+ # a single quote we'll definitely end up using double quotes.
97
+ return '"' if c.include?("'")
98
+ has_double_quote ||= c.include?('"')
112
99
  end
113
100
 
114
- # Double-quotes take precedence over single quotes.
115
- before_quote = quote_for(string_or_interp.before)
116
- return '"' if before_quote == '"'
117
- after_quote = quote_for(string_or_interp.after)
118
- return '"' if after_quote == '"'
119
-
120
- # Returns "'" if either or both insist on single quotes, and nil
121
- # otherwise.
122
- before_quote || after_quote
101
+ has_double_quote ? "'" : '"'
123
102
  end
124
103
  end
125
104
  end
@@ -14,7 +14,7 @@ module Sass::Script::Tree
14
14
  # @param name [String] See \{#name}
15
15
  def initialize(name)
16
16
  @name = name
17
- @underscored_name = name.tr("-", "_")
17
+ @underscored_name = name.gsub(/-/, "_")
18
18
  super()
19
19
  end
20
20
 
@@ -9,5 +9,3 @@ require 'sass/script/value/null'
9
9
  require 'sass/script/value/list'
10
10
  require 'sass/script/value/arg_list'
11
11
  require 'sass/script/value/map'
12
- require 'sass/script/value/callable'
13
- require 'sass/script/value/function'
@@ -17,7 +17,7 @@ module Sass::Script::Value
17
17
  # @param keywords [Hash<String, Value>, NormalizedMap<Value>] See \{#keywords}
18
18
  # @param separator [String] See \{List#separator}.
19
19
  def initialize(value, keywords, separator)
20
- super(value, separator: separator)
20
+ super(value, separator)
21
21
  if keywords.is_a?(Sass::Util::NormalizedMap)
22
22
  @keywords = keywords
23
23
  else
@@ -22,12 +22,11 @@ module Sass::Script::Value
22
22
  def initialize(value = nil)
23
23
  value.freeze unless value.nil? || value == true || value == false
24
24
  @value = value
25
- @options = nil
26
25
  end
27
26
 
28
27
  # Sets the options hash for this node,
29
28
  # as well as for all child nodes.
30
- # See {file:SASS_REFERENCE.md#Options the Sass options documentation}.
29
+ # See {file:SASS_REFERENCE.md#options the Sass options documentation}.
31
30
  #
32
31
  # @param options [{Symbol => Object}] The options
33
32
  attr_writer :options
@@ -88,7 +87,7 @@ MSG
88
87
  # @return [Script::Value::String] A string containing both values
89
88
  # separated by `"="`
90
89
  def single_eq(other)
91
- Sass::Script::Value::String.new("#{self}=#{other}")
90
+ Sass::Script::Value::String.new("#{to_s}=#{other.to_s}")
92
91
  end
93
92
 
94
93
  # The SassScript `+` operation.
@@ -107,7 +106,7 @@ MSG
107
106
  # @return [Script::Value::String] A string containing both values
108
107
  # separated by `"-"`
109
108
  def minus(other)
110
- Sass::Script::Value::String.new("#{self}-#{other}")
109
+ Sass::Script::Value::String.new("#{to_s}-#{other.to_s}")
111
110
  end
112
111
 
113
112
  # The SassScript `/` operation.
@@ -116,7 +115,7 @@ MSG
116
115
  # @return [Script::Value::String] A string containing both values
117
116
  # separated by `"/"`
118
117
  def div(other)
119
- Sass::Script::Value::String.new("#{self}/#{other}")
118
+ Sass::Script::Value::String.new("#{to_s}/#{other.to_s}")
120
119
  end
121
120
 
122
121
  # The SassScript unary `+` operation (e.g. `+$a`).
@@ -125,7 +124,7 @@ MSG
125
124
  # @return [Script::Value::String] A string containing the value
126
125
  # preceded by `"+"`
127
126
  def unary_plus
128
- Sass::Script::Value::String.new("+#{self}")
127
+ Sass::Script::Value::String.new("+#{to_s}")
129
128
  end
130
129
 
131
130
  # The SassScript unary `-` operation (e.g. `-$a`).
@@ -134,7 +133,7 @@ MSG
134
133
  # @return [Script::Value::String] A string containing the value
135
134
  # preceded by `"-"`
136
135
  def unary_minus
137
- Sass::Script::Value::String.new("-#{self}")
136
+ Sass::Script::Value::String.new("-#{to_s}")
138
137
  end
139
138
 
140
139
  # The SassScript unary `/` operation (e.g. `/$a`).
@@ -143,13 +142,13 @@ MSG
143
142
  # @return [Script::Value::String] A string containing the value
144
143
  # preceded by `"/"`
145
144
  def unary_div
146
- Sass::Script::Value::String.new("/#{self}")
145
+ Sass::Script::Value::String.new("/#{to_s}")
147
146
  end
148
147
 
149
148
  # Returns the hash code of this value. Two objects' hash codes should be
150
149
  # equal if the objects are equal.
151
150
  #
152
- # @return [Integer for Ruby 2.4.0+, Fixnum for earlier Ruby versions] The hash code.
151
+ # @return [Fixnum] The hash code.
153
152
  def hash
154
153
  value.hash
155
154
  end
@@ -176,7 +175,7 @@ MSG
176
175
  eq(other).to_bool
177
176
  end
178
177
 
179
- # @return [Integer] The integer value of this value
178
+ # @return [Fixnum] The integer value of this value
180
179
  # @raise [Sass::SyntaxError] if this value isn't an integer
181
180
  def to_i
182
181
  raise Sass::SyntaxError.new("#{inspect} is not an integer.")
@@ -192,12 +191,6 @@ MSG
192
191
  # @return [Symbol]
193
192
  def separator; nil; end
194
193
 
195
- # Whether the value is surrounded by square brackets. For non-list values,
196
- # this will be `false`.
197
- #
198
- # @return [Boolean]
199
- def bracketed; false; end
200
-
201
194
  # Returns the value of this value as a list.
202
195
  # Single values are considered the same as single-element lists.
203
196
  #
@@ -234,17 +227,6 @@ MSG
234
227
  false
235
228
  end
236
229
 
237
- # Creates a new list containing `contents` but with the same brackets and
238
- # separators as this object, when interpreted as a list.
239
- #
240
- # @param contents [Array<Value>] The contents of the new list.
241
- # @param separator [Symbol] The separator of the new list. Defaults to \{#separator}.
242
- # @param bracketed [Boolean] Whether the new list is bracketed. Defaults to \{#bracketed}.
243
- # @return [Sass::Script::Value::List]
244
- def with_contents(contents, separator: self.separator, bracketed: self.bracketed)
245
- Sass::Script::Value::List.new(contents, separator: separator, bracketed: bracketed)
246
- end
247
-
248
230
  protected
249
231
 
250
232
  # Evaluates the value.
@@ -17,16 +17,15 @@ module Sass::Script::Value
17
17
  # @private
18
18
  #
19
19
  # Convert a ruby integer to a rgba components
20
- # @param color [Integer]
21
- # @return [Array<Integer>] Array of 4 numbers representing r,g,b and alpha
20
+ # @param color [Fixnum]
21
+ # @return [Array<Fixnum>] Array of 4 numbers representing r,g,b and alpha
22
22
  def self.int_to_rgba(color)
23
23
  rgba = (0..3).map {|n| color >> (n << 3) & 0xff}.reverse
24
24
  rgba[-1] = rgba[-1] / 255.0
25
25
  rgba
26
26
  end
27
27
 
28
- ALTERNATE_COLOR_NAMES = Sass::Util.map_vals(
29
- {
28
+ ALTERNATE_COLOR_NAMES = Sass::Util.map_vals({
30
29
  'aqua' => 0x00FFFFFF,
31
30
  'darkgrey' => 0xA9A9A9FF,
32
31
  'darkslategrey' => 0x2F4F4FFF,
@@ -36,11 +35,10 @@ module Sass::Script::Value
36
35
  'lightgrey' => 0xD3D3D3FF,
37
36
  'lightslategrey' => 0x778899FF,
38
37
  'slategrey' => 0x708090FF,
39
- }, &method(:int_to_rgba))
38
+ }, &method(:int_to_rgba))
40
39
 
41
40
  # A hash from color names to `[red, green, blue]` value arrays.
42
- COLOR_NAMES = Sass::Util.map_vals(
43
- {
41
+ COLOR_NAMES = Sass::Util.map_vals({
44
42
  'aliceblue' => 0xF0F8FFFF,
45
43
  'antiquewhite' => 0xFAEBD7FF,
46
44
  'aquamarine' => 0x7FFFD4FF,
@@ -181,7 +179,7 @@ module Sass::Script::Value
181
179
  'whitesmoke' => 0xF5F5F5FF,
182
180
  'yellow' => 0xFFFF00FF,
183
181
  'yellowgreen' => 0x9ACD32FF
184
- }, &method(:int_to_rgba))
182
+ }, &method(:int_to_rgba))
185
183
 
186
184
  # A hash from `[red, green, blue, alpha]` value arrays to color names.
187
185
  COLOR_NAMES_REVERSE = COLOR_NAMES.invert.freeze
@@ -239,7 +237,7 @@ module Sass::Script::Value
239
237
  @attrs[:alpha] = attrs[3] ? attrs[3].to_f : 1
240
238
  @representation = representation
241
239
  else
242
- attrs = attrs.reject {|_k, v| v.nil?}
240
+ attrs = attrs.reject {|k, v| v.nil?}
243
241
  hsl = [:hue, :saturation, :lightness] & attrs.keys
244
242
  rgb = [:red, :green, :blue] & attrs.keys
245
243
  if !allow_both_rgb_and_hsl && !hsl.empty? && !rgb.empty?
@@ -277,14 +275,13 @@ module Sass::Script::Value
277
275
  #
278
276
  # @return [Color]
279
277
  def self.from_hex(hex_string, alpha = nil)
280
- unless hex_string =~ /^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})?$/i ||
281
- hex_string =~ /^#?([0-9a-f])([0-9a-f])([0-9a-f])([0-9a-f])?$/i
278
+ unless hex_string =~ /^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i ||
279
+ hex_string =~ /^#?([0-9a-f])([0-9a-f])([0-9a-f])$/i
282
280
  raise ArgumentError.new("#{hex_string.inspect} is not a valid hex color.")
283
281
  end
284
282
  red = $1.ljust(2, $1).to_i(16)
285
283
  green = $2.ljust(2, $2).to_i(16)
286
284
  blue = $3.ljust(2, $3).to_i(16)
287
- alpha = $4.ljust(2, $4).to_i(16).to_f / 0xff if $4
288
285
 
289
286
  hex_string = "##{hex_string}" unless hex_string[0] == ?#
290
287
  attrs = {:red => red, :green => green, :blue => blue, :representation => hex_string}
@@ -294,7 +291,7 @@ module Sass::Script::Value
294
291
 
295
292
  # The red component of the color.
296
293
  #
297
- # @return [Integer]
294
+ # @return [Fixnum]
298
295
  def red
299
296
  hsl_to_rgb!
300
297
  @attrs[:red]
@@ -302,7 +299,7 @@ module Sass::Script::Value
302
299
 
303
300
  # The green component of the color.
304
301
  #
305
- # @return [Integer]
302
+ # @return [Fixnum]
306
303
  def green
307
304
  hsl_to_rgb!
308
305
  @attrs[:green]
@@ -310,7 +307,7 @@ module Sass::Script::Value
310
307
 
311
308
  # The blue component of the color.
312
309
  #
313
- # @return [Integer]
310
+ # @return [Fixnum]
314
311
  def blue
315
312
  hsl_to_rgb!
316
313
  @attrs[:blue]
@@ -343,7 +340,7 @@ module Sass::Script::Value
343
340
  # The alpha channel (opacity) of the color.
344
341
  # This is 1 unless otherwise defined.
345
342
  #
346
- # @return [Integer]
343
+ # @return [Fixnum]
347
344
  def alpha
348
345
  @attrs[:alpha].to_f
349
346
  end
@@ -358,7 +355,7 @@ module Sass::Script::Value
358
355
 
359
356
  # Returns the red, green, and blue components of the color.
360
357
  #
361
- # @return [Array<Integer>] A frozen three-element array of the red, green, and blue
358
+ # @return [Array<Fixnum>] A frozen three-element array of the red, green, and blue
362
359
  # values (respectively) of the color
363
360
  def rgb
364
361
  [red, green, blue].freeze
@@ -366,7 +363,7 @@ module Sass::Script::Value
366
363
 
367
364
  # Returns the red, green, blue, and alpha components of the color.
368
365
  #
369
- # @return [Array<Integer>] A frozen four-element array of the red, green,
366
+ # @return [Array<Fixnum>] A frozen four-element array of the red, green,
370
367
  # blue, and alpha values (respectively) of the color
371
368
  def rgba
372
369
  [red, green, blue, alpha].freeze
@@ -374,7 +371,7 @@ module Sass::Script::Value
374
371
 
375
372
  # Returns the hue, saturation, and lightness components of the color.
376
373
  #
377
- # @return [Array<Integer>] A frozen three-element array of the
374
+ # @return [Array<Fixnum>] A frozen three-element array of the
378
375
  # hue, saturation, and lightness values (respectively) of the color
379
376
  def hsl
380
377
  [hue, saturation, lightness].freeze
@@ -382,7 +379,7 @@ module Sass::Script::Value
382
379
 
383
380
  # Returns the hue, saturation, lightness, and alpha components of the color.
384
381
  #
385
- # @return [Array<Integer>] A frozen four-element array of the hue,
382
+ # @return [Array<Fixnum>] A frozen four-element array of the hue,
386
383
  # saturation, lightness, and alpha values (respectively) of the color
387
384
  def hsla
388
385
  [hue, saturation, lightness, alpha].freeze
@@ -424,7 +421,7 @@ module Sass::Script::Value
424
421
  # @return [Color] The new Color object
425
422
  # @raise [ArgumentError] if both RGB and HSL keys are specified
426
423
  def with(attrs)
427
- attrs = attrs.reject {|_k, v| v.nil?}
424
+ attrs = attrs.reject {|k, v| v.nil?}
428
425
  hsl = !([:hue, :saturation, :lightness] & attrs.keys).empty?
429
426
  rgb = !([:red, :green, :blue] & attrs.keys).empty?
430
427
  if hsl && rgb
@@ -564,11 +561,6 @@ module Sass::Script::Value
564
561
  def to_s(opts = {})
565
562
  return smallest if options[:style] == :compressed
566
563
  return representation if representation
567
-
568
- # IE10 doesn't properly support the color name "transparent", so we emit
569
- # generated transparent colors as rgba(0, 0, 0, 0) in favor of that. See
570
- # #1782.
571
- return rgba_str if Number.basically_equal?(alpha, 0)
572
564
  return name if name
573
565
  alpha? ? rgba_str : hex_str
574
566
  end