sass 3.4.25 → 3.7.4

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 (237) hide show
  1. checksums.yaml +4 -4
  2. data/CODE_OF_CONDUCT.md +1 -1
  3. data/CONTRIBUTING.md +3 -3
  4. data/README.md +17 -9
  5. data/VERSION +1 -1
  6. data/VERSION_DATE +1 -1
  7. data/VERSION_NAME +1 -1
  8. data/extra/sass-spec-ref.sh +9 -1
  9. data/lib/sass.rb +0 -7
  10. data/lib/sass/cache_stores/filesystem.rb +1 -1
  11. data/lib/sass/css.rb +1 -2
  12. data/lib/sass/engine.rb +39 -29
  13. data/lib/sass/environment.rb +26 -5
  14. data/lib/sass/error.rb +2 -2
  15. data/lib/sass/exec/base.rb +2 -13
  16. data/lib/sass/exec/sass_scss.rb +1 -5
  17. data/lib/sass/features.rb +1 -0
  18. data/lib/sass/importers/filesystem.rb +6 -4
  19. data/lib/sass/logger/base.rb +11 -0
  20. data/lib/sass/plugin/compiler.rb +20 -50
  21. data/lib/sass/plugin/configuration.rb +2 -2
  22. data/lib/sass/railtie.rb +1 -1
  23. data/lib/sass/script/css_parser.rb +4 -1
  24. data/lib/sass/script/functions.rb +308 -81
  25. data/lib/sass/script/lexer.rb +63 -9
  26. data/lib/sass/script/parser.rb +287 -118
  27. data/lib/sass/script/tree/funcall.rb +35 -34
  28. data/lib/sass/script/tree/interpolation.rb +0 -3
  29. data/lib/sass/script/tree/list_literal.rb +23 -8
  30. data/lib/sass/script/tree/map_literal.rb +2 -2
  31. data/lib/sass/script/tree/node.rb +0 -8
  32. data/lib/sass/script/tree/operation.rb +1 -8
  33. data/lib/sass/script/value.rb +2 -0
  34. data/lib/sass/script/value/arg_list.rb +1 -1
  35. data/lib/sass/script/value/base.rb +17 -0
  36. data/lib/sass/script/value/callable.rb +25 -0
  37. data/lib/sass/script/value/color.rb +8 -2
  38. data/lib/sass/script/value/function.rb +19 -0
  39. data/lib/sass/script/value/helpers.rb +37 -11
  40. data/lib/sass/script/value/list.rb +35 -14
  41. data/lib/sass/script/value/map.rb +2 -2
  42. data/lib/sass/script/value/number.rb +3 -2
  43. data/lib/sass/scss/css_parser.rb +6 -1
  44. data/lib/sass/scss/parser.rb +145 -56
  45. data/lib/sass/scss/rx.rb +5 -11
  46. data/lib/sass/scss/static_parser.rb +20 -42
  47. data/lib/sass/selector.rb +4 -0
  48. data/lib/sass/selector/abstract_sequence.rb +7 -6
  49. data/lib/sass/selector/comma_sequence.rb +9 -5
  50. data/lib/sass/selector/pseudo.rb +20 -3
  51. data/lib/sass/selector/sequence.rb +35 -10
  52. data/lib/sass/selector/simple.rb +9 -2
  53. data/lib/sass/selector/simple_sequence.rb +8 -4
  54. data/lib/sass/source/map.rb +2 -6
  55. data/lib/sass/stack.rb +21 -1
  56. data/lib/sass/tree/charset_node.rb +1 -1
  57. data/lib/sass/tree/prop_node.rb +45 -53
  58. data/lib/sass/tree/rule_node.rb +6 -8
  59. data/lib/sass/tree/visitors/check_nesting.rb +1 -1
  60. data/lib/sass/tree/visitors/convert.rb +2 -3
  61. data/lib/sass/tree/visitors/cssize.rb +4 -15
  62. data/lib/sass/tree/visitors/deep_copy.rb +1 -1
  63. data/lib/sass/tree/visitors/extend.rb +2 -8
  64. data/lib/sass/tree/visitors/perform.rb +23 -15
  65. data/lib/sass/tree/visitors/set_options.rb +1 -1
  66. data/lib/sass/tree/visitors/to_css.rb +49 -22
  67. data/lib/sass/util.rb +72 -310
  68. data/lib/sass/util/multibyte_string_scanner.rb +127 -131
  69. data/lib/sass/util/normalized_map.rb +1 -8
  70. data/lib/sass/version.rb +0 -4
  71. metadata +55 -202
  72. data/Rakefile +0 -453
  73. data/lib/sass/script/css_variable_warning.rb +0 -52
  74. data/lib/sass/util/cross_platform_random.rb +0 -19
  75. data/lib/sass/util/ordered_hash.rb +0 -192
  76. data/test/sass-spec.yml +0 -3
  77. data/test/sass/cache_test.rb +0 -131
  78. data/test/sass/callbacks_test.rb +0 -61
  79. data/test/sass/compiler_test.rb +0 -236
  80. data/test/sass/conversion_test.rb +0 -2188
  81. data/test/sass/css2sass_test.rb +0 -526
  82. data/test/sass/css_variable_test.rb +0 -132
  83. data/test/sass/data/hsl-rgb.txt +0 -319
  84. data/test/sass/encoding_test.rb +0 -219
  85. data/test/sass/engine_test.rb +0 -3447
  86. data/test/sass/exec_test.rb +0 -96
  87. data/test/sass/extend_test.rb +0 -1733
  88. data/test/sass/fixtures/test_staleness_check_across_importers.css +0 -1
  89. data/test/sass/fixtures/test_staleness_check_across_importers.scss +0 -1
  90. data/test/sass/functions_test.rb +0 -1977
  91. data/test/sass/importer_test.rb +0 -421
  92. data/test/sass/logger_test.rb +0 -58
  93. data/test/sass/mock_importer.rb +0 -49
  94. data/test/sass/more_results/more1.css +0 -9
  95. data/test/sass/more_results/more1_with_line_comments.css +0 -26
  96. data/test/sass/more_results/more_import.css +0 -29
  97. data/test/sass/more_templates/_more_partial.sass +0 -2
  98. data/test/sass/more_templates/more1.sass +0 -23
  99. data/test/sass/more_templates/more_import.sass +0 -11
  100. data/test/sass/plugin_test.rb +0 -556
  101. data/test/sass/results/alt.css +0 -4
  102. data/test/sass/results/basic.css +0 -9
  103. data/test/sass/results/cached_import_option.css +0 -3
  104. data/test/sass/results/compact.css +0 -5
  105. data/test/sass/results/complex.css +0 -86
  106. data/test/sass/results/compressed.css +0 -1
  107. data/test/sass/results/expanded.css +0 -19
  108. data/test/sass/results/filename_fn.css +0 -3
  109. data/test/sass/results/if.css +0 -3
  110. data/test/sass/results/import.css +0 -31
  111. data/test/sass/results/import_charset.css +0 -5
  112. data/test/sass/results/import_charset_1_8.css +0 -5
  113. data/test/sass/results/import_charset_ibm866.css +0 -5
  114. data/test/sass/results/import_content.css +0 -1
  115. data/test/sass/results/line_numbers.css +0 -49
  116. data/test/sass/results/mixins.css +0 -95
  117. data/test/sass/results/multiline.css +0 -24
  118. data/test/sass/results/nested.css +0 -22
  119. data/test/sass/results/options.css +0 -1
  120. data/test/sass/results/parent_ref.css +0 -13
  121. data/test/sass/results/script.css +0 -16
  122. data/test/sass/results/scss_import.css +0 -31
  123. data/test/sass/results/scss_importee.css +0 -2
  124. data/test/sass/results/subdir/nested_subdir/nested_subdir.css +0 -1
  125. data/test/sass/results/subdir/subdir.css +0 -3
  126. data/test/sass/results/units.css +0 -11
  127. data/test/sass/results/warn.css +0 -0
  128. data/test/sass/results/warn_imported.css +0 -0
  129. data/test/sass/script_conversion_test.rb +0 -357
  130. data/test/sass/script_test.rb +0 -1431
  131. data/test/sass/scss/css_test.rb +0 -1281
  132. data/test/sass/scss/rx_test.rb +0 -160
  133. data/test/sass/scss/scss_test.rb +0 -4205
  134. data/test/sass/scss/test_helper.rb +0 -37
  135. data/test/sass/source_map_test.rb +0 -1055
  136. data/test/sass/superselector_test.rb +0 -210
  137. data/test/sass/templates/_cached_import_option_partial.scss +0 -1
  138. data/test/sass/templates/_double_import_loop2.sass +0 -1
  139. data/test/sass/templates/_filename_fn_import.scss +0 -11
  140. data/test/sass/templates/_imported_charset_ibm866.sass +0 -4
  141. data/test/sass/templates/_imported_charset_utf8.sass +0 -4
  142. data/test/sass/templates/_imported_content.sass +0 -3
  143. data/test/sass/templates/_partial.sass +0 -2
  144. data/test/sass/templates/_same_name_different_partiality.scss +0 -1
  145. data/test/sass/templates/alt.sass +0 -16
  146. data/test/sass/templates/basic.sass +0 -23
  147. data/test/sass/templates/bork1.sass +0 -2
  148. data/test/sass/templates/bork2.sass +0 -2
  149. data/test/sass/templates/bork3.sass +0 -2
  150. data/test/sass/templates/bork4.sass +0 -2
  151. data/test/sass/templates/bork5.sass +0 -3
  152. data/test/sass/templates/cached_import_option.scss +0 -3
  153. data/test/sass/templates/compact.sass +0 -17
  154. data/test/sass/templates/complex.sass +0 -305
  155. data/test/sass/templates/compressed.sass +0 -15
  156. data/test/sass/templates/double_import_loop1.sass +0 -1
  157. data/test/sass/templates/expanded.sass +0 -17
  158. data/test/sass/templates/filename_fn.scss +0 -18
  159. data/test/sass/templates/if.sass +0 -11
  160. data/test/sass/templates/import.sass +0 -12
  161. data/test/sass/templates/import_charset.sass +0 -9
  162. data/test/sass/templates/import_charset_1_8.sass +0 -6
  163. data/test/sass/templates/import_charset_ibm866.sass +0 -11
  164. data/test/sass/templates/import_content.sass +0 -4
  165. data/test/sass/templates/importee.less +0 -2
  166. data/test/sass/templates/importee.sass +0 -19
  167. data/test/sass/templates/line_numbers.sass +0 -13
  168. data/test/sass/templates/mixin_bork.sass +0 -5
  169. data/test/sass/templates/mixins.sass +0 -76
  170. data/test/sass/templates/multiline.sass +0 -20
  171. data/test/sass/templates/nested.sass +0 -25
  172. data/test/sass/templates/nested_bork1.sass +0 -2
  173. data/test/sass/templates/nested_bork2.sass +0 -2
  174. data/test/sass/templates/nested_bork3.sass +0 -2
  175. data/test/sass/templates/nested_bork4.sass +0 -2
  176. data/test/sass/templates/nested_import.sass +0 -2
  177. data/test/sass/templates/nested_mixin_bork.sass +0 -6
  178. data/test/sass/templates/options.sass +0 -2
  179. data/test/sass/templates/parent_ref.sass +0 -25
  180. data/test/sass/templates/same_name_different_ext.sass +0 -2
  181. data/test/sass/templates/same_name_different_ext.scss +0 -1
  182. data/test/sass/templates/same_name_different_partiality.scss +0 -1
  183. data/test/sass/templates/script.sass +0 -101
  184. data/test/sass/templates/scss_import.scss +0 -12
  185. data/test/sass/templates/scss_importee.scss +0 -1
  186. data/test/sass/templates/single_import_loop.sass +0 -1
  187. data/test/sass/templates/subdir/import_up1.scss +0 -1
  188. data/test/sass/templates/subdir/import_up2.scss +0 -1
  189. data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +0 -2
  190. data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +0 -3
  191. data/test/sass/templates/subdir/subdir.sass +0 -6
  192. data/test/sass/templates/units.sass +0 -11
  193. data/test/sass/templates/warn.sass +0 -3
  194. data/test/sass/templates/warn_imported.sass +0 -4
  195. data/test/sass/test_helper.rb +0 -8
  196. data/test/sass/util/multibyte_string_scanner_test.rb +0 -155
  197. data/test/sass/util/normalized_map_test.rb +0 -51
  198. data/test/sass/util/subset_map_test.rb +0 -91
  199. data/test/sass/util_test.rb +0 -438
  200. data/test/sass/value_helpers_test.rb +0 -179
  201. data/test/test_helper.rb +0 -110
  202. data/vendor/listen/CHANGELOG.md +0 -1
  203. data/vendor/listen/CONTRIBUTING.md +0 -38
  204. data/vendor/listen/Gemfile +0 -20
  205. data/vendor/listen/Guardfile +0 -8
  206. data/vendor/listen/LICENSE +0 -20
  207. data/vendor/listen/README.md +0 -349
  208. data/vendor/listen/Rakefile +0 -5
  209. data/vendor/listen/Vagrantfile +0 -96
  210. data/vendor/listen/lib/listen.rb +0 -54
  211. data/vendor/listen/lib/listen/adapter.rb +0 -327
  212. data/vendor/listen/lib/listen/adapters/bsd.rb +0 -75
  213. data/vendor/listen/lib/listen/adapters/darwin.rb +0 -48
  214. data/vendor/listen/lib/listen/adapters/linux.rb +0 -81
  215. data/vendor/listen/lib/listen/adapters/polling.rb +0 -58
  216. data/vendor/listen/lib/listen/adapters/windows.rb +0 -91
  217. data/vendor/listen/lib/listen/directory_record.rb +0 -406
  218. data/vendor/listen/lib/listen/listener.rb +0 -323
  219. data/vendor/listen/lib/listen/turnstile.rb +0 -32
  220. data/vendor/listen/lib/listen/version.rb +0 -3
  221. data/vendor/listen/listen.gemspec +0 -28
  222. data/vendor/listen/spec/listen/adapter_spec.rb +0 -149
  223. data/vendor/listen/spec/listen/adapters/bsd_spec.rb +0 -36
  224. data/vendor/listen/spec/listen/adapters/darwin_spec.rb +0 -37
  225. data/vendor/listen/spec/listen/adapters/linux_spec.rb +0 -47
  226. data/vendor/listen/spec/listen/adapters/polling_spec.rb +0 -68
  227. data/vendor/listen/spec/listen/adapters/windows_spec.rb +0 -30
  228. data/vendor/listen/spec/listen/directory_record_spec.rb +0 -1250
  229. data/vendor/listen/spec/listen/listener_spec.rb +0 -258
  230. data/vendor/listen/spec/listen/turnstile_spec.rb +0 -56
  231. data/vendor/listen/spec/listen_spec.rb +0 -67
  232. data/vendor/listen/spec/spec_helper.rb +0 -25
  233. data/vendor/listen/spec/support/adapter_helper.rb +0 -666
  234. data/vendor/listen/spec/support/directory_record_helper.rb +0 -57
  235. data/vendor/listen/spec/support/fixtures_helper.rb +0 -29
  236. data/vendor/listen/spec/support/listeners_helper.rb +0 -179
  237. data/vendor/listen/spec/support/platform_helper.rb +0 -15
@@ -13,6 +13,11 @@ module Sass::Script::Tree
13
13
  # @return [String]
14
14
  attr_reader :name
15
15
 
16
+ # The callable to be invoked
17
+ #
18
+ # @return [Sass::Callable] or nil if no callable is provided.
19
+ attr_reader :callable
20
+
16
21
  # The arguments to the function.
17
22
  #
18
23
  # @return [Array<Node>]
@@ -39,13 +44,19 @@ module Sass::Script::Tree
39
44
  # @return [Node?]
40
45
  attr_accessor :kwarg_splat
41
46
 
42
- # @param name [String] See \{#name}
47
+ # @param name_or_callable [String, Sass::Callable] See \{#name}
43
48
  # @param args [Array<Node>] See \{#args}
44
49
  # @param keywords [Sass::Util::NormalizedMap<Node>] See \{#keywords}
45
50
  # @param splat [Node] See \{#splat}
46
51
  # @param kwarg_splat [Node] See \{#kwarg_splat}
47
- def initialize(name, args, keywords, splat, kwarg_splat)
48
- @name = name
52
+ def initialize(name_or_callable, args, keywords, splat, kwarg_splat)
53
+ if name_or_callable.is_a?(Sass::Callable)
54
+ @callable = name_or_callable
55
+ @name = name_or_callable.name
56
+ else
57
+ @callable = nil
58
+ @name = name_or_callable
59
+ end
49
60
  @args = args
50
61
  @keywords = keywords
51
62
  @splat = splat
@@ -56,15 +67,12 @@ module Sass::Script::Tree
56
67
  # @return [String] A string representation of the function call
57
68
  def inspect
58
69
  args = @args.map {|a| a.inspect}.join(', ')
59
- keywords = Sass::Util.hash_to_a(@keywords.as_stored).
60
- map {|k, v| "$#{k}: #{v.inspect}"}.join(', ')
61
- # rubocop:disable RedundantSelf
70
+ keywords = @keywords.as_stored.to_a.map {|k, v| "$#{k}: #{v.inspect}"}.join(', ')
62
71
  if self.splat
63
72
  splat = args.empty? && keywords.empty? ? "" : ", "
64
73
  splat = "#{splat}#{self.splat.inspect}..."
65
74
  splat = "#{splat}, #{kwarg_splat.inspect}..." if kwarg_splat
66
75
  end
67
- # rubocop:enable RedundantSelf
68
76
  "#{name}(#{args}#{', ' unless args.empty? || keywords.empty?}#{keywords}#{splat})"
69
77
  end
70
78
 
@@ -77,15 +85,12 @@ module Sass::Script::Tree
77
85
  end
78
86
 
79
87
  args = @args.map(&arg_to_sass)
80
- keywords = Sass::Util.hash_to_a(@keywords.as_stored).
81
- map {|k, v| "$#{dasherize(k, opts)}: #{arg_to_sass[v]}"}
88
+ keywords = @keywords.as_stored.to_a.map {|k, v| "$#{dasherize(k, opts)}: #{arg_to_sass[v]}"}
82
89
 
83
- # rubocop:disable RedundantSelf
84
90
  if self.splat
85
91
  splat = "#{arg_to_sass[self.splat]}..."
86
92
  kwarg_splat = "#{arg_to_sass[self.kwarg_splat]}..." if self.kwarg_splat
87
93
  end
88
- # rubocop:enable RedundantSelf
89
94
 
90
95
  arglist = [args, splat, keywords, kwarg_splat].flatten.compact.join(', ')
91
96
  "#{dasherize(name, opts)}(#{arglist})"
@@ -120,27 +125,31 @@ module Sass::Script::Tree
120
125
  # @return [Sass::Script::Value] The SassScript object that is the value of the function call
121
126
  # @raise [Sass::SyntaxError] if the function call raises an ArgumentError
122
127
  def _perform(environment)
123
- args = Sass::Util.enum_with_index(@args).
128
+ args = @args.each_with_index.
124
129
  map {|a, i| perform_arg(a, environment, signature && signature.args[i])}
125
130
  keywords = Sass::Util.map_hash(@keywords) do |k, v|
126
131
  [k, perform_arg(v, environment, k.tr('-', '_'))]
127
132
  end
128
133
  splat = Sass::Tree::Visitors::Perform.perform_splat(
129
134
  @splat, keywords, @kwarg_splat, environment)
130
- if (fn = environment.function(@name))
131
- css_variable_warning.warn! if css_variable_warning
132
- return without_original(perform_sass_fn(fn, args, splat, environment))
135
+
136
+ fn = @callable || environment.function(@name)
137
+
138
+ if fn && fn.origin == :stylesheet
139
+ environment.stack.with_function(filename, line, name) do
140
+ return without_original(perform_sass_fn(fn, args, splat, environment))
141
+ end
133
142
  end
134
143
 
135
144
  args = construct_ruby_args(ruby_name, args, splat, environment)
136
145
 
137
- if Sass::Script::Functions.callable?(ruby_name)
138
- css_variable_warning.warn! if css_variable_warning
139
-
146
+ if Sass::Script::Functions.callable?(ruby_name) && (!fn || fn.origin == :builtin)
140
147
  local_environment = Sass::Environment.new(environment.global_env, environment.options)
141
148
  local_environment.caller = Sass::ReadOnlyEnvironment.new(environment, environment.options)
142
- result = opts(Sass::Script::Functions::EvaluationContext.new(
143
- local_environment).send(ruby_name, *args))
149
+ result = local_environment.stack.with_function(filename, line, name) do
150
+ opts(Sass::Script::Functions::EvaluationContext.new(
151
+ local_environment).send(ruby_name, *args))
152
+ end
144
153
  without_original(result)
145
154
  else
146
155
  opts(to_literal(args))
@@ -206,6 +215,7 @@ module Sass::Script::Tree
206
215
  raise Sass::SyntaxError.new(
207
216
  "#{args[signature.args.size].inspect} is not a keyword argument for `#{name}'")
208
217
  elsif keywords.empty?
218
+ args << {} if signature.var_kwargs
209
219
  return args
210
220
  end
211
221
 
@@ -271,30 +281,21 @@ module Sass::Script::Tree
271
281
  message = "wrong number of arguments (#{given} for #{expected})"
272
282
  end
273
283
  elsif Sass::Util.jruby?
274
- if Sass::Util.jruby1_6?
275
- should_maybe_raise = e.message =~ /^wrong number of arguments \((\d+) for (\d+)\)/ &&
276
- # The one case where JRuby does include the Ruby name of the function
277
- # is manually-thrown ArgumentErrors, which are indistinguishable from
278
- # legitimate ArgumentErrors. We treat both of these as
279
- # Sass::SyntaxErrors even though it can hide Ruby errors.
280
- e.backtrace[0] !~ /:in `(block in )?#{ruby_name}'$/
281
- else
282
- should_maybe_raise =
283
- e.message =~ /^wrong number of arguments calling `[^`]+` \((\d+) for (\d+)\)/
284
- given, expected = $1, $2
285
- end
284
+ should_maybe_raise =
285
+ e.message =~ /^wrong number of arguments calling `[^`]+` \((\d+) for (\d+)\)/
286
+ given, expected = $1, $2
286
287
 
287
288
  if should_maybe_raise
288
289
  # JRuby 1.7 includes __send__ before send and _perform.
289
290
  trace = e.backtrace.dup
290
- raise e if !Sass::Util.jruby1_6? && trace.shift !~ /:in `__send__'$/
291
+ raise e if trace.shift !~ /:in `__send__'$/
291
292
 
292
293
  # JRuby (as of 1.7.2) doesn't put the actual method
293
294
  # for which the argument error was thrown in the backtrace, so we
294
295
  # detect whether our send threw an argument error.
295
296
  if !(trace[0] =~ /:in `send'$/ && trace[1] =~ /:in `_perform'$/)
296
297
  raise e
297
- elsif !Sass::Util.jruby1_6?
298
+ else
298
299
  # JRuby 1.7 doesn't use standard formatting for its ArgumentErrors.
299
300
  message = "wrong number of arguments (#{given} for #{expected})"
300
301
  end
@@ -47,10 +47,7 @@ module Sass::Script::Tree
47
47
  # @param wa [Boolean] See {Interpolation#whitespace_after}
48
48
  # @param originally_text [Boolean] See {Interpolation#originally_text}
49
49
  # @param warn_for_color [Boolean] See {Interpolation#warn_for_color}
50
- # @comment
51
- # rubocop:disable ParameterLists
52
50
  def initialize(before, mid, after, wb, wa, opts = {})
53
- # rubocop:enable ParameterLists
54
51
  @before = before
55
52
  @mid = mid
56
53
  @after = after
@@ -13,13 +13,20 @@ module Sass::Script::Tree
13
13
  # @return [Symbol]
14
14
  attr_reader :separator
15
15
 
16
+ # Whether the list is surrounded by square brackets.
17
+ #
18
+ # @return [Boolean]
19
+ attr_reader :bracketed
20
+
16
21
  # Creates a new list literal.
17
22
  #
18
23
  # @param elements [Array<Node>] See \{#elements}
19
24
  # @param separator [Symbol] See \{#separator}
20
- def initialize(elements, separator)
25
+ # @param bracketed [Boolean] See \{#bracketed}
26
+ def initialize(elements, separator: nil, bracketed: false)
21
27
  @elements = elements
22
28
  @separator = separator
29
+ @bracketed = bracketed
23
30
  end
24
31
 
25
32
  # @see Node#children
@@ -27,7 +34,7 @@ module Sass::Script::Tree
27
34
 
28
35
  # @see Value#to_sass
29
36
  def to_sass(opts = {})
30
- return "()" if elements.empty?
37
+ return bracketed ? "[]" : "()" if elements.empty?
31
38
  members = elements.map do |v|
32
39
  if element_needs_parens?(v)
33
40
  "(#{v.to_sass(opts)})"
@@ -36,9 +43,12 @@ module Sass::Script::Tree
36
43
  end
37
44
  end
38
45
 
39
- return "(#{members.first},)" if separator == :comma && members.length == 1
46
+ if separator == :comma && members.length == 1
47
+ return "#{bracketed ? '[' : '('}#{members.first},#{bracketed ? ']' : ')'}"
48
+ end
40
49
 
41
- members.join(sep_str(nil))
50
+ contents = members.join(sep_str(nil))
51
+ bracketed ? "[#{contents}]" : contents
42
52
  end
43
53
 
44
54
  # @see Node#deep_copy
@@ -49,7 +59,9 @@ module Sass::Script::Tree
49
59
  end
50
60
 
51
61
  def inspect
52
- "(#{elements.map {|e| e.inspect}.join(separator == :space ? ' ' : ', ')})"
62
+ (bracketed ? '[' : '(') +
63
+ elements.map {|e| e.inspect}.join(separator == :space ? ' ' : ', ') +
64
+ (bracketed ? ']' : ')')
53
65
  end
54
66
 
55
67
  def force_division!
@@ -61,7 +73,8 @@ module Sass::Script::Tree
61
73
  def _perform(environment)
62
74
  list = Sass::Script::Value::List.new(
63
75
  elements.map {|e| e.perform(environment)},
64
- separator)
76
+ separator: separator,
77
+ bracketed: bracketed)
65
78
  list.source_range = source_range
66
79
  list.options = options
67
80
  list
@@ -73,8 +86,10 @@ module Sass::Script::Tree
73
86
  # when serialized to Sass.
74
87
  def element_needs_parens?(element)
75
88
  if element.is_a?(ListLiteral)
76
- return Sass::Script::Parser.precedence_of(element.separator) <=
77
- Sass::Script::Parser.precedence_of(separator)
89
+ return false if element.elements.length < 2
90
+ return false if element.bracketed
91
+ return Sass::Script::Parser.precedence_of(element.separator || :space) <=
92
+ Sass::Script::Parser.precedence_of(separator || :space)
78
93
  end
79
94
 
80
95
  return false unless separator == :space
@@ -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(Sass::Util.to_hash(pairs.map do |(k, v)|
52
+ map = Sass::Script::Value::Map.new(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
@@ -23,14 +23,6 @@ module Sass::Script::Tree
23
23
  # @return [String]
24
24
  attr_accessor :filename
25
25
 
26
- # The warning that this node should emit if it executes in a way that's not
27
- # safe for a CSS variable value.
28
- #
29
- # This is `nil` if this is not in a CSS variable value.
30
- #
31
- # @return [Sass::Script::CssVariableWarning]
32
- attr_accessor :css_variable_warning
33
-
34
26
  # Sets the options hash for this node,
35
27
  # as well as for all child nodes.
36
28
  # See {file:SASS_REFERENCE.md#Options the Sass options documentation}.
@@ -81,13 +81,6 @@ module Sass::Script::Tree
81
81
  "Invalid null operation: \"#{value1.inspect} #{@operator} #{value2.inspect}\".")
82
82
  end
83
83
 
84
- if css_variable_warning && @operator == :div &&
85
- !(value1.is_a?(Sass::Script::Value::Number) && value1.original &&
86
- value2.is_a?(Sass::Script::Value::Number) && value2.original) &&
87
- !(value1.is_a?(Sass::Script::Value::String) && value2.is_a?(Sass::Script::Value::String))
88
- css_variable_warning.warn!
89
- end
90
-
91
84
  begin
92
85
  result = opts(value1.send(@operator, value2))
93
86
  rescue NoMethodError => e
@@ -118,7 +111,7 @@ module Sass::Script::Tree
118
111
  @@color_arithmetic_deprecation.warn(filename, line, <<WARNING)
119
112
  The operation `#{value1} #{@operator} #{value2}` is deprecated and will be an error in future versions.
120
113
  Consider using Sass's color functions instead.
121
- http://sass-lang.com/documentation/Sass/Script/Functions.html#other_color_functions
114
+ https://sass-lang.com/documentation/Sass/Script/Functions.html#other_color_functions
122
115
  WARNING
123
116
  end
124
117
 
@@ -9,3 +9,5 @@ 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)
20
+ super(value, separator: separator)
21
21
  if keywords.is_a?(Sass::Util::NormalizedMap)
22
22
  @keywords = keywords
23
23
  else
@@ -192,6 +192,12 @@ MSG
192
192
  # @return [Symbol]
193
193
  def separator; nil; end
194
194
 
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
+
195
201
  # Returns the value of this value as a list.
196
202
  # Single values are considered the same as single-element lists.
197
203
  #
@@ -228,6 +234,17 @@ MSG
228
234
  false
229
235
  end
230
236
 
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
+
231
248
  protected
232
249
 
233
250
  # Evaluates the value.
@@ -0,0 +1,25 @@
1
+ module Sass::Script::Value
2
+ # A SassScript object representing a null value.
3
+ class Callable < Base
4
+ # Constructs a Callable value for use in SassScript.
5
+ #
6
+ # @param callable [Sass::Callable] The callable to be used when the
7
+ # callable is called.
8
+ def initialize(callable)
9
+ super(callable)
10
+ end
11
+
12
+ def to_s(opts = {})
13
+ raise Sass::SyntaxError.new("#{to_sass} isn't a valid CSS value.")
14
+ end
15
+
16
+ def inspect
17
+ to_sass
18
+ end
19
+
20
+ # @abstract
21
+ def to_sass
22
+ Sass::Util.abstract(self)
23
+ end
24
+ end
25
+ end
@@ -277,13 +277,14 @@ module Sass::Script::Value
277
277
  #
278
278
  # @return [Color]
279
279
  def self.from_hex(hex_string, alpha = nil)
280
- unless hex_string =~ /^#?([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])$/i
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
282
282
  raise ArgumentError.new("#{hex_string.inspect} is not a valid hex color.")
283
283
  end
284
284
  red = $1.ljust(2, $1).to_i(16)
285
285
  green = $2.ljust(2, $2).to_i(16)
286
286
  blue = $3.ljust(2, $3).to_i(16)
287
+ alpha = $4.ljust(2, $4).to_i(16).to_f / 0xff if $4
287
288
 
288
289
  hex_string = "##{hex_string}" unless hex_string[0] == ?#
289
290
  attrs = {:red => red, :green => green, :blue => blue, :representation => hex_string}
@@ -563,6 +564,11 @@ module Sass::Script::Value
563
564
  def to_s(opts = {})
564
565
  return smallest if options[:style] == :compressed
565
566
  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)
566
572
  return name if name
567
573
  alpha? ? rgba_str : hex_str
568
574
  end
@@ -0,0 +1,19 @@
1
+ module Sass::Script::Value
2
+ # A SassScript object representing a function.
3
+ class Function < Callable
4
+ # Constructs a Function value for use in SassScript.
5
+ #
6
+ # @param function [Sass::Callable] The callable to be used when the
7
+ # function is invoked.
8
+ def initialize(function)
9
+ unless function.type == "function"
10
+ raise ArgumentError.new("A callable of type function was expected.")
11
+ end
12
+ super
13
+ end
14
+
15
+ def to_sass
16
+ %{get-function("#{value.name}")}
17
+ end
18
+ end
19
+ end
@@ -1,8 +1,6 @@
1
1
  module Sass::Script::Value
2
2
  # Provides helper functions for creating sass values from within ruby methods.
3
3
  # @since `3.3.0`
4
- # @comment
5
- # rubocop:disable ModuleLength
6
4
  module Helpers
7
5
  # Construct a Sass Boolean.
8
6
  #
@@ -68,26 +66,35 @@ module Sass::Script::Value
68
66
  Number.new(number, *parse_unit_string(unit_string))
69
67
  end
70
68
 
71
- # @overload list(*elements, separator)
69
+ # @overload list(*elements, separator:, bracketed: false)
72
70
  # Create a space-separated list from the arguments given.
73
71
  # @param elements [Array<Sass::Script::Value::Base>] Each argument will be a list element.
74
72
  # @param separator [Symbol] Either :space or :comma.
73
+ # @param bracketed [Boolean] Whether the list uses square brackets.
75
74
  # @return [Sass::Script::Value::List] The space separated list.
76
75
  #
77
- # @overload list(array, separator)
76
+ # @overload list(array, separator:, bracketed: false)
78
77
  # Create a space-separated list from the array given.
79
78
  # @param array [Array<Sass::Script::Value::Base>] A ruby array of Sass values
80
79
  # to make into a list.
80
+ # @param separator [Symbol] Either :space or :comma.
81
+ # @param bracketed [Boolean] Whether the list uses square brackets.
81
82
  # @return [Sass::Script::Value::List] The space separated list.
82
- def list(*elements)
83
- unless elements.last.is_a?(Symbol)
84
- raise ArgumentError.new("A list type of :space or :comma must be specified.")
83
+ def list(*elements, separator: nil, bracketed: false)
84
+ # Support passing separator as the last value in elements for
85
+ # backwards-compatibility.
86
+ if separator.nil?
87
+ if elements.last.is_a?(Symbol)
88
+ separator = elements.pop
89
+ else
90
+ raise ArgumentError.new("A separator of :space or :comma must be specified.")
91
+ end
85
92
  end
86
- separator = elements.pop
93
+
87
94
  if elements.size == 1 && elements.first.is_a?(Array)
88
95
  elements = elements.first
89
96
  end
90
- Sass::Script::Value::List.new(elements, separator)
97
+ Sass::Script::Value::List.new(elements, separator: separator, bracketed: bracketed)
91
98
  end
92
99
 
93
100
  # Construct a Sass map.
@@ -196,14 +203,33 @@ module Sass::Script::Value
196
203
  raise ArgumentError.new(err)
197
204
  end
198
205
 
199
- # Returns true when the literal is a string containing a calc()
206
+ # Returns true when the literal is a string containing a calc().
207
+ #
208
+ # Use \{#special_number?} in preference to this.
200
209
  #
201
210
  # @param literal [Sass::Script::Value::Base] The value to check
202
- # @return boolean
211
+ # @return Boolean
203
212
  def calc?(literal)
204
213
  literal.is_a?(Sass::Script::Value::String) && literal.value =~ /calc\(/
205
214
  end
206
215
 
216
+ # Returns true when the literal is a string containing a var().
217
+ #
218
+ # @param literal [Sass::Script::Value::Base] The value to check
219
+ # @return Boolean
220
+ def var?(literal)
221
+ literal.is_a?(Sass::Script::Value::String) && literal.value =~ /var\(/
222
+ end
223
+
224
+ # Returns whether the literal is a special CSS value that may evaluate to a
225
+ # number, such as `calc()` or `var()`.
226
+ #
227
+ # @param literal [Sass::Script::Value::Base] The value to check
228
+ # @return Boolean
229
+ def special_number?(literal)
230
+ literal.is_a?(Sass::Script::Value::String) && literal.value =~ /(calc|var)\(/
231
+ end
232
+
207
233
  private
208
234
 
209
235
  # Converts a user-provided selector into string form or throws an