sass 3.7.4 → 4.0.0.alpha.1

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -26,8 +26,8 @@ module Sass
26
26
  clear_callbacks!
27
27
  end
28
28
 
29
- # An options hash. See {file:SASS_REFERENCE.md#Options the Sass options
30
- # documentation}.
29
+ # An options hash.
30
+ # See {file:SASS_REFERENCE.md#options the Sass options documentation}.
31
31
  #
32
32
  # @return [{Symbol => Object}]
33
33
  def options
@@ -127,7 +127,7 @@ module Sass
127
127
 
128
128
  def normalize_template_location!
129
129
  options[:template_location] = convert_template_location(
130
- options[:template_location], options[:css_location])
130
+ options[:template_location], options[:css_location])
131
131
  end
132
132
  end
133
133
  end
@@ -15,7 +15,7 @@ unless defined?(Sass::MERB_LOADED)
15
15
  end
16
16
 
17
17
  {
18
- :always_update => false,
18
+ :always_update => false,
19
19
  :template_location => root + '/public/stylesheets/sass',
20
20
  :css_location => root + '/public/stylesheets',
21
21
  :cache_location => root + '/tmp/sass-cache',
@@ -9,19 +9,19 @@ module Sass
9
9
  #
10
10
  # ## Customize
11
11
  #
12
- # Sass::Plugin.options.merge!(
12
+ # Sass::Plugin.options.merge(
13
13
  # :cache_location => './tmp/sass-cache',
14
14
  # :never_update => environment != :production,
15
15
  # :full_exception => environment != :production)
16
16
  #
17
- # {file:SASS_REFERENCE.md#Options See the Reference for more options}.
17
+ # {file:SASS_REFERENCE.md#options See the Reference for more options}.
18
18
  #
19
19
  # ## Use
20
20
  #
21
21
  # Put your Sass files in `public/stylesheets/sass`.
22
22
  # Your CSS will be generated in `public/stylesheets`,
23
23
  # and regenerated every request if necessary.
24
- # The locations and frequency {file:SASS_REFERENCE.md#Options can be customized}.
24
+ # The locations and frequency {file:SASS_REFERENCE.md#options can be customized}.
25
25
  # That's all there is to it!
26
26
  class Rack
27
27
  # The delay, in seconds, between update checks.
@@ -39,7 +39,7 @@ module Sass
39
39
  # for checking the staleness of several stylesheets at once.
40
40
  #
41
41
  # @param options [{Symbol => Object}]
42
- # See {file:SASS_REFERENCE.md#Options the Sass options documentation}.
42
+ # See {file:SASS_REFERENCE.md#options the Sass options documentation}.
43
43
  def initialize(options)
44
44
  # URIs that are being actively checked for staleness. Protects against
45
45
  # import loops.
@@ -72,7 +72,7 @@ module Sass
72
72
  # Returns whether a Sass or SCSS stylesheet has been modified since a given time.
73
73
  #
74
74
  # @param template_file [String] The location of the Sass or SCSS template.
75
- # @param mtime [Time] The modification time to check against.
75
+ # @param mtime [Fixnum] The modification time to check against.
76
76
  # @param importer [Sass::Importers::Base] The importer used to locate the stylesheet.
77
77
  # Defaults to the filesystem importer.
78
78
  # @return [Boolean] Whether the stylesheet has been modified.
@@ -103,7 +103,7 @@ module Sass
103
103
  # so it's better to use when checking multiple stylesheets at once.
104
104
  #
105
105
  # @param template_file [String] The location of the Sass or SCSS template.
106
- # @param mtime [Time] The modification time to check against.
106
+ # @param mtime [Fixnum] The modification time to check against.
107
107
  # @param importer [Sass::Importers::Base] The importer used to locate the stylesheet.
108
108
  # Defaults to the filesystem importer.
109
109
  # @return [Boolean] Whether the stylesheet has been modified.
@@ -1,5 +1,5 @@
1
1
  # Rails 3.0.0.beta.2+, < 3.1
2
- if defined?(ActiveSupport) && ActiveSupport.public_methods.include?(:on_load) &&
2
+ if defined?(ActiveSupport) && Sass::Util.has?(:public_method, ActiveSupport, :on_load) &&
3
3
  !Sass::Util.ap_geq?('3.1.0.beta')
4
4
  require 'sass/plugin/configuration'
5
5
  ActiveSupport.on_load(:before_configuration) do
@@ -16,12 +16,12 @@ module Sass
16
16
  # Parses a string of SassScript
17
17
  #
18
18
  # @param value [String] The SassScript
19
- # @param line [Integer] The number of the line on which the SassScript appeared.
19
+ # @param line [Fixnum] The number of the line on which the SassScript appeared.
20
20
  # Used for error reporting
21
- # @param offset [Integer] The number of characters in on `line` that the SassScript started.
21
+ # @param offset [Fixnum] The number of characters in on `line` that the SassScript started.
22
22
  # Used for error reporting
23
23
  # @param options [{Symbol => Object}] An options hash;
24
- # see {file:SASS_REFERENCE.md#Options the Sass options documentation}
24
+ # see {file:SASS_REFERENCE.md#options the Sass options documentation}
25
25
  # @return [Script::Tree::Node] The root node of the parse tree
26
26
  def self.parse(value, line, offset, options = {})
27
27
  Parser.parse(value, line, offset, options)
@@ -19,15 +19,25 @@ module Sass
19
19
  def string
20
20
  tok = try_tok(:string)
21
21
  return number unless tok
22
- return if @lexer.peek && @lexer.peek.type == :begin_interpolation
23
- literal_node(tok.value, tok.source_range)
22
+ unless @lexer.peek && @lexer.peek.type == :begin_interpolation
23
+ return literal_node(tok.value, tok.source_range)
24
+ end
24
25
  end
25
26
 
26
- # Short-circuit all the SassScript-only productions
27
- def interpolation(first: nil, inner: :space)
28
- first || send(inner)
27
+ def ident
28
+ return funcall unless @lexer.peek && @lexer.peek.type == :ident
29
+ return if @stop_at && @stop_at.include?(@lexer.peek.value)
30
+
31
+ name = @lexer.next
32
+ if (color = Sass::Script::Value::Color::COLOR_NAMES[name.value.downcase])
33
+ literal_node(Sass::Script::Value::Color.new(color, name.value), name.source_range)
34
+ else
35
+ literal_node(Sass::Script::Value::String.new(name.value, :identifier), name.source_range)
36
+ end
29
37
  end
30
38
 
39
+ # Short-circuit all the SassScript-only productions
40
+ alias_method :interpolation, :space
31
41
  alias_method :or_expr, :div
32
42
  alias_method :unary_div, :ident
33
43
  alias_method :paren, :string
@@ -1,7 +1,9 @@
1
1
  require 'sass/script/value/helpers'
2
2
 
3
3
  module Sass::Script
4
+ # @comment
4
5
  # YARD can't handle some multiline tags, and we need really long tags for function declarations.
6
+ # rubocop:disable LineLength
5
7
  # Methods in this module are accessible from the SassScript context.
6
8
  # For example, you can write
7
9
  #
@@ -174,7 +176,7 @@ module Sass::Script
174
176
  # \{#set-nth set-nth($list, $n, $value)}
175
177
  # : Replaces the nth item in a list.
176
178
  #
177
- # \{#join join($list1, $list2, \[$separator, $bracketed\])}
179
+ # \{#join join($list1, $list2, \[$separator\])}
178
180
  # : Joins together two lists into one.
179
181
  #
180
182
  # \{#append append($list1, $val, \[$separator\])}
@@ -189,9 +191,6 @@ module Sass::Script
189
191
  # \{#list_separator list-separator($list)}
190
192
  # : Returns the separator of a list.
191
193
  #
192
- # \{#is_bracketed is-bracketed($list)}
193
- # : Returns whether a list has square brackets.
194
- #
195
194
  # ## Map Functions {#map-functions}
196
195
  #
197
196
  # Maps in Sass are immutable; all map functions return a new map rather than
@@ -277,9 +276,6 @@ module Sass::Script
277
276
  # \{#mixin_exists mixin-exists($name)}
278
277
  # : Returns whether a mixin with the given name exists.
279
278
  #
280
- # \{#content_exists content-exists()}
281
- # : Returns whether the current mixin was passed a content block.
282
- #
283
279
  # \{#inspect inspect($value)}
284
280
  # : Returns the string representation of a value as it would be represented in Sass.
285
281
  #
@@ -295,12 +291,8 @@ module Sass::Script
295
291
  # \{#comparable comparable($number1, $number2)}
296
292
  # : Returns whether two numbers can be added, subtracted, or compared.
297
293
  #
298
- # \{#call call($function, $args...)}
299
- # : Dynamically calls a Sass function reference returned by `get-function`.
300
- #
301
- # \{#get_function get-function($name, $css: false)}
302
- # : Looks up a function with the given name in the current lexical scope
303
- # and returns a reference to it.
294
+ # \{#call call($name, $args...)}
295
+ # : Dynamically calls a Sass function.
304
296
  #
305
297
  # ## Miscellaneous Functions
306
298
  #
@@ -362,6 +354,8 @@ module Sass::Script
362
354
  # representation) on those objects without first setting {Tree::Node#options=
363
355
  # the #options attribute}.
364
356
  #
357
+ # @comment
358
+ # rubocop:enable LineLength
365
359
  module Functions
366
360
  @signatures = {}
367
361
 
@@ -436,8 +430,8 @@ module Sass::Script
436
430
  # If no signatures match, the first signature is returned for error messaging.
437
431
  #
438
432
  # @param method_name [Symbol] The name of the Ruby function to be called.
439
- # @param arg_arity [Integer] The number of unnamed arguments the function was passed.
440
- # @param kwarg_arity [Integer] The number of keyword arguments the function was passed.
433
+ # @param arg_arity [Fixnum] The number of unnamed arguments the function was passed.
434
+ # @param kwarg_arity [Fixnum] The number of keyword arguments the function was passed.
441
435
  #
442
436
  # @return [{Symbol => Object}, nil]
443
437
  # The signature options for the matching signature,
@@ -460,8 +454,8 @@ module Sass::Script
460
454
  t_arg_arity = sig_arity
461
455
  end
462
456
 
463
- if (t_arg_arity == sig_arity || t_arg_arity > sig_arity && signature.var_args) &&
464
- (t_kwarg_arity == 0 || t_kwarg_arity > 0 && signature.var_kwargs)
457
+ if (t_arg_arity == sig_arity || t_arg_arity > sig_arity && signature.var_args) &&
458
+ (t_kwarg_arity == 0 || t_kwarg_arity > 0 && signature.var_kwargs)
465
459
  return signature
466
460
  end
467
461
  end
@@ -476,14 +470,14 @@ module Sass::Script
476
470
  # @param seed [Integer]
477
471
  # @return [Integer] The same seed.
478
472
  def self.random_seed=(seed)
479
- @random_number_generator = Random.new(seed)
473
+ @random_number_generator = Sass::Util::CrossPlatformRandom.new(seed)
480
474
  end
481
475
 
482
476
  # Get Sass's internal random number generator.
483
477
  #
484
478
  # @return [Random]
485
479
  def self.random_number_generator
486
- @random_number_generator ||= Random.new
480
+ @random_number_generator ||= Sass::Util::CrossPlatformRandom.new
487
481
  end
488
482
 
489
483
  # The context in which methods in {Script::Functions} are evaluated.
@@ -527,28 +521,15 @@ module Sass::Script
527
521
  # assert_type value, :String
528
522
  # assert_type value, :Number
529
523
  # @param value [Sass::Script::Value::Base] A SassScript value
530
- # @param type [Symbol, Array<Symbol>] The name(s) of the type the value is expected to be
524
+ # @param type [Symbol] The name of the type the value is expected to be
531
525
  # @param name [String, Symbol, nil] The name of the argument.
532
526
  # @raise [ArgumentError] if value is not of the correct type.
533
527
  def assert_type(value, type, name = nil)
534
- valid_types = Array(type)
535
- found_type = valid_types.find do |t|
536
- value.is_a?(Sass::Script::Value.const_get(t)) ||
537
- t == :Map && value.is_a?(Sass::Script::Value::List) && value.value.empty?
538
- end
539
-
540
- if found_type
541
- value.check_deprecated_interp if found_type == :String
542
- return
543
- end
544
-
545
- err = if valid_types.size == 1
546
- "#{value.inspect} is not a #{TYPE_NAMES[type] || type.to_s.downcase}"
547
- else
548
- type_names = valid_types.map {|t| TYPE_NAMES[t] || t.to_s.downcase}
549
- "#{value.inspect} is not any of #{type_names.join(', ')}"
550
- end
551
- err = "$#{name.to_s.tr('_', '-')}: " + err if name
528
+ klass = Sass::Script::Value.const_get(type)
529
+ return if value.is_a?(klass)
530
+ return if value.is_a?(Sass::Script::Value::List) && type == :Map && value.value.empty?
531
+ err = "#{value.inspect} is not a #{TYPE_NAMES[type] || type.to_s.downcase}"
532
+ err = "$#{name.to_s.gsub('_', '-')}: " + err if name
552
533
  raise ArgumentError.new(err)
553
534
  end
554
535
 
@@ -648,27 +629,23 @@ module Sass::Script
648
629
  # inclusive
649
630
  # @return [Sass::Script::Value::Color]
650
631
  # @raise [ArgumentError] if any parameter is the wrong type or out of bounds
651
- def rgb(red, green = nil, blue = nil)
652
- if green.nil?
653
- return unquoted_string("rgb(#{red})") if var?(red)
654
- raise ArgumentError.new("wrong number of arguments (1 for 3)")
655
- elsif blue.nil?
656
- return unquoted_string("rgb(#{red}, #{green})") if var?(red) || var?(green)
657
- raise ArgumentError.new("wrong number of arguments (2 for 3)")
658
- end
659
-
660
- if special_number?(red) || special_number?(green) || special_number?(blue)
632
+ def rgb(red, green, blue)
633
+ if calc?(red) || calc?(green) || calc?(blue)
661
634
  return unquoted_string("rgb(#{red}, #{green}, #{blue})")
662
635
  end
663
636
  assert_type red, :Number, :red
664
637
  assert_type green, :Number, :green
665
638
  assert_type blue, :Number, :blue
666
639
 
667
- color_attrs = [
668
- percentage_or_unitless(red, 255, "red"),
669
- percentage_or_unitless(green, 255, "green"),
670
- percentage_or_unitless(blue, 255, "blue")
671
- ]
640
+ color_attrs = [[red, :red], [green, :green], [blue, :blue]].map do |(c, name)|
641
+ if c.is_unit?("%")
642
+ c.value * 255 / 100.0
643
+ elsif c.unitless?
644
+ c.value
645
+ else
646
+ raise ArgumentError.new("Expected #{c} to be unitless or have a unit of % but got #{c}")
647
+ end
648
+ end
672
649
 
673
650
  # Don't store the string representation for function-created colors, both
674
651
  # because it's not very useful and because some functions aren't supported
@@ -676,8 +653,6 @@ module Sass::Script
676
653
  Sass::Script::Value::Color.new(color_attrs)
677
654
  end
678
655
  declare :rgb, [:red, :green, :blue]
679
- declare :rgb, [:red, :green]
680
- declare :rgb, [:red]
681
656
 
682
657
  # Creates a {Sass::Script::Value::Color Color} from red, green, blue, and
683
658
  # alpha values.
@@ -712,39 +687,20 @@ module Sass::Script
712
687
  # is the wrong type
713
688
  def rgba(*args)
714
689
  case args.size
715
- when 1
716
- return unquoted_string("rgba(#{args.first})") if var?(args.first)
717
- raise ArgumentError.new("wrong number of arguments (1 for 4)")
718
690
  when 2
719
691
  color, alpha = args
720
692
 
721
- if var?(color)
722
- return unquoted_string("rgba(#{color}, #{alpha})")
723
- elsif var?(alpha)
724
- if color.is_a?(Sass::Script::Value::Color)
725
- return unquoted_string("rgba(#{color.red}, #{color.green}, #{color.blue}, #{alpha})")
726
- else
727
- return unquoted_string("rgba(#{color}, #{alpha})")
728
- end
729
- end
730
-
731
693
  assert_type color, :Color, :color
732
- if special_number?(alpha)
694
+ if calc?(alpha)
733
695
  unquoted_string("rgba(#{color.red}, #{color.green}, #{color.blue}, #{alpha})")
734
696
  else
735
697
  assert_type alpha, :Number, :alpha
736
- color.with(:alpha => percentage_or_unitless(alpha, 1, "alpha"))
737
- end
738
- when 3
739
- if var?(args[0]) || var?(args[1]) || var?(args[2])
740
- unquoted_string("rgba(#{args.join(', ')})")
741
- else
742
- raise ArgumentError.new("wrong number of arguments (3 for 4)")
698
+ check_alpha_unit alpha, 'rgba'
699
+ color.with(:alpha => alpha.value)
743
700
  end
744
701
  when 4
745
702
  red, green, blue, alpha = args
746
- if special_number?(red) || special_number?(green) ||
747
- special_number?(blue) || special_number?(alpha)
703
+ if calc?(red) || calc?(green) || calc?(blue) || calc?(alpha)
748
704
  unquoted_string("rgba(#{red}, #{green}, #{blue}, #{alpha})")
749
705
  else
750
706
  rgba(rgb(red, green, blue), alpha)
@@ -754,9 +710,7 @@ module Sass::Script
754
710
  end
755
711
  end
756
712
  declare :rgba, [:red, :green, :blue, :alpha]
757
- declare :rgba, [:red, :green, :blue]
758
713
  declare :rgba, [:color, :alpha]
759
- declare :rgba, [:red]
760
714
 
761
715
  # Creates a {Sass::Script::Value::Color Color} from hue, saturation, and
762
716
  # lightness values. Uses the algorithm from the [CSS3 spec][].
@@ -774,24 +728,14 @@ module Sass::Script
774
728
  # @return [Sass::Script::Value::Color]
775
729
  # @raise [ArgumentError] if `$saturation` or `$lightness` are out of bounds
776
730
  # or any parameter is the wrong type
777
- def hsl(hue, saturation = nil, lightness = nil)
778
- if saturation.nil?
779
- return unquoted_string("hsl(#{hue})") if var?(hue)
780
- raise ArgumentError.new("wrong number of arguments (1 for 3)")
781
- elsif lightness.nil?
782
- return unquoted_string("hsl(#{hue}, #{saturation})") if var?(hue) || var?(saturation)
783
- raise ArgumentError.new("wrong number of arguments (2 for 3)")
784
- end
785
-
786
- if special_number?(hue) || special_number?(saturation) || special_number?(lightness)
731
+ def hsl(hue, saturation, lightness)
732
+ if calc?(hue) || calc?(saturation) || calc?(lightness)
787
733
  unquoted_string("hsl(#{hue}, #{saturation}, #{lightness})")
788
734
  else
789
735
  hsla(hue, saturation, lightness, number(1))
790
736
  end
791
737
  end
792
738
  declare :hsl, [:hue, :saturation, :lightness]
793
- declare :hsl, [:hue, :saturation]
794
- declare :hsl, [:hue]
795
739
 
796
740
  # Creates a {Sass::Script::Value::Color Color} from hue,
797
741
  # saturation, lightness, and alpha values. Uses the algorithm from
@@ -812,29 +756,15 @@ module Sass::Script
812
756
  # @return [Sass::Script::Value::Color]
813
757
  # @raise [ArgumentError] if `$saturation`, `$lightness`, or `$alpha` are out
814
758
  # of bounds or any parameter is the wrong type
815
- def hsla(hue, saturation = nil, lightness = nil, alpha = nil)
816
- if saturation.nil?
817
- return unquoted_string("hsla(#{hue})") if var?(hue)
818
- raise ArgumentError.new("wrong number of arguments (1 for 4)")
819
- elsif lightness.nil?
820
- return unquoted_string("hsla(#{hue}, #{saturation})") if var?(hue) || var?(saturation)
821
- raise ArgumentError.new("wrong number of arguments (2 for 4)")
822
- elsif alpha.nil?
823
- if var?(hue) || var?(saturation) || var?(lightness)
824
- return unquoted_string("hsla(#{hue}, #{saturation}, #{lightness})")
825
- else
826
- raise ArgumentError.new("wrong number of arguments (2 for 4)")
827
- end
828
- end
829
-
830
- if special_number?(hue) || special_number?(saturation) ||
831
- special_number?(lightness) || special_number?(alpha)
759
+ def hsla(hue, saturation, lightness, alpha)
760
+ if calc?(hue) || calc?(saturation) || calc?(lightness) || calc?(alpha)
832
761
  return unquoted_string("hsla(#{hue}, #{saturation}, #{lightness}, #{alpha})")
833
762
  end
834
763
  assert_type hue, :Number, :hue
835
764
  assert_type saturation, :Number, :saturation
836
765
  assert_type lightness, :Number, :lightness
837
766
  assert_type alpha, :Number, :alpha
767
+ check_alpha_unit alpha, 'hsla'
838
768
 
839
769
  h = hue.value
840
770
  s = saturation.value
@@ -844,13 +774,9 @@ module Sass::Script
844
774
  # because it's not very useful and because some functions aren't supported
845
775
  # on older browsers.
846
776
  Sass::Script::Value::Color.new(
847
- :hue => h, :saturation => s, :lightness => l,
848
- :alpha => percentage_or_unitless(alpha, 1, "alpha"))
777
+ :hue => h, :saturation => s, :lightness => l, :alpha => alpha.value)
849
778
  end
850
779
  declare :hsla, [:hue, :saturation, :lightness, :alpha]
851
- declare :hsla, [:hue, :saturation, :lightness]
852
- declare :hsla, [:hue, :saturation]
853
- declare :hsla, [:hue]
854
780
 
855
781
  # Gets the red component of a color. Calculated from HSL where necessary via
856
782
  # [this algorithm][hsl-to-rgb].
@@ -970,7 +896,7 @@ module Sass::Script
970
896
  a.value =~ /^[a-zA-Z]+\s*=/
971
897
  end
972
898
  # Support the proprietary MS alpha() function
973
- return identifier("alpha(#{args.map {|a| a.to_s}.join(', ')})")
899
+ return identifier("alpha(#{args.map {|a| a.to_s}.join(", ")})")
974
900
  end
975
901
 
976
902
  raise ArgumentError.new("wrong number of arguments (#{args.size} for 1)") if args.size != 1
@@ -1172,7 +1098,11 @@ module Sass::Script
1172
1098
  # adjust-color(#102030, $blue: 5) => #102035
1173
1099
  # adjust-color(#102030, $red: -5, $blue: 5) => #0b2035
1174
1100
  # adjust-color(hsl(25, 100%, 80%), $lightness: -30%, $alpha: -0.4) => hsla(25, 100%, 50%, 0.6)
1101
+ # @comment
1102
+ # rubocop:disable LineLength
1175
1103
  # @overload adjust_color($color, [$red], [$green], [$blue], [$hue], [$saturation], [$lightness], [$alpha])
1104
+ # @comment
1105
+ # rubocop:disable LineLength
1176
1106
  # @param $color [Sass::Script::Value::Color]
1177
1107
  # @param $red [Sass::Script::Value::Number] The adjustment to make on the
1178
1108
  # red component, between -255 and 255 inclusive
@@ -1195,14 +1125,15 @@ module Sass::Script
1195
1125
  def adjust_color(color, kwargs)
1196
1126
  assert_type color, :Color, :color
1197
1127
  with = Sass::Util.map_hash(
1198
- "red" => [-255..255, ""],
1199
- "green" => [-255..255, ""],
1200
- "blue" => [-255..255, ""],
1201
- "hue" => nil,
1202
- "saturation" => [-100..100, "%"],
1203
- "lightness" => [-100..100, "%"],
1204
- "alpha" => [-1..1, ""]
1205
- ) do |name, (range, units)|
1128
+ "red" => [-255..255, ""],
1129
+ "green" => [-255..255, ""],
1130
+ "blue" => [-255..255, ""],
1131
+ "hue" => nil,
1132
+ "saturation" => [-100..100, "%"],
1133
+ "lightness" => [-100..100, "%"],
1134
+ "alpha" => [-1..1, ""]
1135
+ ) do |name, (range, units)|
1136
+
1206
1137
  val = kwargs.delete(name)
1207
1138
  next unless val
1208
1139
  assert_type val, :Number, name
@@ -1248,7 +1179,11 @@ module Sass::Script
1248
1179
  # scale-color(hsl(120, 70%, 80%), $lightness: 50%) => hsl(120, 70%, 90%)
1249
1180
  # scale-color(rgb(200, 150%, 170%), $green: -40%, $blue: 70%) => rgb(200, 90, 229)
1250
1181
  # scale-color(hsl(200, 70%, 80%), $saturation: -90%, $alpha: -30%) => hsla(200, 7%, 80%, 0.7)
1182
+ # @comment
1183
+ # rubocop:disable LineLength
1251
1184
  # @overload scale_color($color, [$red], [$green], [$blue], [$saturation], [$lightness], [$alpha])
1185
+ # @comment
1186
+ # rubocop:disable LineLength
1252
1187
  # @param $color [Sass::Script::Value::Color]
1253
1188
  # @param $red [Sass::Script::Value::Number]
1254
1189
  # @param $green [Sass::Script::Value::Number]
@@ -1263,13 +1198,14 @@ module Sass::Script
1263
1198
  def scale_color(color, kwargs)
1264
1199
  assert_type color, :Color, :color
1265
1200
  with = Sass::Util.map_hash(
1266
- "red" => 255,
1267
- "green" => 255,
1268
- "blue" => 255,
1269
- "saturation" => 100,
1270
- "lightness" => 100,
1271
- "alpha" => 1
1272
- ) do |name, max|
1201
+ "red" => 255,
1202
+ "green" => 255,
1203
+ "blue" => 255,
1204
+ "saturation" => 100,
1205
+ "lightness" => 100,
1206
+ "alpha" => 1
1207
+ ) do |name, max|
1208
+
1273
1209
  val = kwargs.delete(name)
1274
1210
  next unless val
1275
1211
  assert_type val, :Number, name
@@ -1304,7 +1240,11 @@ module Sass::Script
1304
1240
  # change-color(#102030, $blue: 5) => #102005
1305
1241
  # change-color(#102030, $red: 120, $blue: 5) => #782005
1306
1242
  # change-color(hsl(25, 100%, 80%), $lightness: 40%, $alpha: 0.8) => hsla(25, 100%, 40%, 0.8)
1243
+ # @comment
1244
+ # rubocop:disable LineLength
1307
1245
  # @overload change_color($color, [$red], [$green], [$blue], [$hue], [$saturation], [$lightness], [$alpha])
1246
+ # @comment
1247
+ # rubocop:disable LineLength
1308
1248
  # @param $color [Sass::Script::Value::Color]
1309
1249
  # @param $red [Sass::Script::Value::Number] The new red component for the
1310
1250
  # color, within 0 and 255 inclusive
@@ -1374,7 +1314,7 @@ module Sass::Script
1374
1314
  # @param $color1 [Sass::Script::Value::Color]
1375
1315
  # @param $color2 [Sass::Script::Value::Color]
1376
1316
  # @param $weight [Sass::Script::Value::Number] The relative weight of each
1377
- # color. Closer to `100%` gives more weight to `$color1`, closer to `0%`
1317
+ # color. Closer to `0%` gives more weight to `$color1`, closer to `100%`
1378
1318
  # gives more weight to `$color2`
1379
1319
  # @return [Sass::Script::Value::Color]
1380
1320
  # @raise [ArgumentError] if `$weight` is out of bounds or any parameter is
@@ -1490,11 +1430,13 @@ module Sass::Script
1490
1430
  def unquote(string)
1491
1431
  unless string.is_a?(Sass::Script::Value::String)
1492
1432
  # Don't warn multiple times for the same source line.
1433
+ # rubocop:disable GlobalVars
1493
1434
  $_sass_warned_for_unquote ||= Set.new
1494
1435
  frame = environment.stack.frames.last
1495
1436
  key = [frame.filename, frame.line] if frame
1496
1437
  return string if frame && $_sass_warned_for_unquote.include?(key)
1497
1438
  $_sass_warned_for_unquote << key if frame
1439
+ # rubocop:enable GlobalVars
1498
1440
 
1499
1441
  Sass::Util.sass_warn(<<MESSAGE.strip)
1500
1442
  DEPRECATION WARNING: Passing #{string.to_sass}, a non-string value, to unquote()
@@ -1504,7 +1446,6 @@ MESSAGE
1504
1446
  return string
1505
1447
  end
1506
1448
 
1507
- string.check_deprecated_interp
1508
1449
  return string if string.type == :identifier
1509
1450
  identifier(string.value)
1510
1451
  end
@@ -1621,7 +1562,7 @@ MESSAGE
1621
1562
  # @param $start-at [Sass::Script::Value::Number] The index of the first
1622
1563
  # character of the substring. If this is negative, it counts from the end
1623
1564
  # of `$string`
1624
- # @param $end-at [Sass::Script::Value::Number] The index of the last
1565
+ # @param $end-before [Sass::Script::Value::Number] The index of the last
1625
1566
  # character of the substring. If this is negative, it counts from the end
1626
1567
  # of `$string`. Defaults to -1
1627
1568
  # @return [Sass::Script::Value::String] The substring. This will be quoted
@@ -1640,7 +1581,7 @@ MESSAGE
1640
1581
  s = string.value.length + s if s < 0
1641
1582
  s = 0 if s < 0
1642
1583
  e = string.value.length + e if e < 0
1643
- return Sass::Script::Value::String.new("", string.type) if e < 0
1584
+ e = 0 if s < 0
1644
1585
  extracted = string.value.slice(s..e)
1645
1586
  Sass::Script::Value::String.new(extracted || "", string.type)
1646
1587
  end
@@ -1658,7 +1599,7 @@ MESSAGE
1658
1599
  # @raise [ArgumentError] if `$string` isn't a string
1659
1600
  def to_upper_case(string)
1660
1601
  assert_type string, :String, :string
1661
- Sass::Script::Value::String.new(Sass::Util.upcase(string.value), string.type)
1602
+ Sass::Script::Value::String.new(string.value.upcase, string.type)
1662
1603
  end
1663
1604
  declare :to_upper_case, [:string]
1664
1605
 
@@ -1673,7 +1614,7 @@ MESSAGE
1673
1614
  # @raise [ArgumentError] if `$string` isn't a string
1674
1615
  def to_lower_case(string)
1675
1616
  assert_type string, :String, :string
1676
- Sass::Script::Value::String.new(Sass::Util.downcase(string.value), string.type)
1617
+ Sass::Script::Value::String.new(string.value.downcase, string.type)
1677
1618
  end
1678
1619
  declare :to_lower_case, [:string]
1679
1620
 
@@ -1686,17 +1627,11 @@ MESSAGE
1686
1627
  # type-of(true) => bool
1687
1628
  # type-of(#fff) => color
1688
1629
  # type-of(blue) => color
1689
- # type-of(null) => null
1690
- # type-of(a b c) => list
1691
- # type-of((a: 1, b: 2)) => map
1692
- # type-of(get-function("foo")) => function
1693
- #
1694
1630
  # @overload type_of($value)
1695
1631
  # @param $value [Sass::Script::Value::Base] The value to inspect
1696
1632
  # @return [Sass::Script::Value::String] The unquoted string name of the
1697
1633
  # value's type
1698
1634
  def type_of(value)
1699
- value.check_deprecated_interp if value.is_a?(Sass::Script::Value::String)
1700
1635
  identifier(value.class.name.gsub(/Sass::Script::Value::/, '').downcase)
1701
1636
  end
1702
1637
  declare :type_of, [:value]
@@ -1718,12 +1653,6 @@ MESSAGE
1718
1653
  #
1719
1654
  # * `at-error` indicates that the Sass `@error` directive is supported.
1720
1655
  #
1721
- # * `custom-property` indicates that the [Custom Properties Level 1][] spec
1722
- # is supported. This means that custom properties are parsed statically,
1723
- # with only interpolation treated as SassScript.
1724
- #
1725
- # [Custom Properties Level 1]: https://www.w3.org/TR/css-variables-1/
1726
- #
1727
1656
  # @example
1728
1657
  # feature-exists(some-feature-that-exists) => true
1729
1658
  # feature-exists(what-is-this-i-dont-know) => false
@@ -1738,55 +1667,6 @@ MESSAGE
1738
1667
  end
1739
1668
  declare :feature_exists, [:feature]
1740
1669
 
1741
- # Returns a reference to a function for later invocation with the `call()` function.
1742
- #
1743
- # If `$css` is `false`, the function reference may refer to a function
1744
- # defined in your stylesheet or built-in to the host environment. If it's
1745
- # `true` it will refer to a plain-CSS function.
1746
- #
1747
- # @example
1748
- # get-function("rgb")
1749
- #
1750
- # @function myfunc { @return "something"; }
1751
- # get-function("myfunc")
1752
- #
1753
- # @overload get_function($name, $css: false)
1754
- # @param name [Sass::Script::Value::String] The name of the function being referenced.
1755
- # @param css [Sass::Script::Value::Bool] Whether to get a plain CSS function.
1756
- #
1757
- # @return [Sass::Script::Value::Function] A function reference.
1758
- def get_function(name, kwargs = {})
1759
- assert_type name, :String, :name
1760
-
1761
- css = if kwargs.has_key?("css")
1762
- v = kwargs.delete("css")
1763
- assert_type v, :Bool, :css
1764
- v.value
1765
- else
1766
- false
1767
- end
1768
-
1769
- if kwargs.any?
1770
- raise ArgumentError.new("Illegal keyword argument '#{kwargs.keys.first}'")
1771
- end
1772
-
1773
- if css
1774
- return Sass::Script::Value::Function.new(
1775
- Sass::Callable.new(name.value, nil, nil, nil, nil, nil, "function", :css))
1776
- end
1777
-
1778
- callable = environment.caller.function(name.value) ||
1779
- (Sass::Script::Functions.callable?(name.value.tr("-", "_")) &&
1780
- Sass::Callable.new(name.value, nil, nil, nil, nil, nil, "function", :builtin))
1781
-
1782
- if callable
1783
- Sass::Script::Value::Function.new(callable)
1784
- else
1785
- raise Sass::SyntaxError.new("Function not found: #{name}")
1786
- end
1787
- end
1788
- declare :get_function, [:name], :var_kwargs => true
1789
-
1790
1670
  # Returns the unit(s) associated with a number. Complex units are sorted in
1791
1671
  # alphabetical order by numerator and denominator.
1792
1672
  #
@@ -1989,7 +1869,7 @@ MESSAGE
1989
1869
  index = n.to_i > 0 ? n.to_i - 1 : n.to_i
1990
1870
  new_list = list.to_a.dup
1991
1871
  new_list[index] = value
1992
- list.with_contents(new_list)
1872
+ Sass::Script::Value::List.new(new_list, list.separator)
1993
1873
  end
1994
1874
  declare :set_nth, [:list, :n, :value]
1995
1875
 
@@ -2030,9 +1910,6 @@ MESSAGE
2030
1910
  # list. If both lists have fewer than two items, spaces are used for the
2031
1911
  # resulting list.
2032
1912
  #
2033
- # Unless `$bracketed` is passed, the resulting list is bracketed if the
2034
- # first parameter is.
2035
- #
2036
1913
  # Like all list functions, `join()` returns a new list rather than modifying
2037
1914
  # its arguments in place.
2038
1915
  #
@@ -2042,70 +1919,27 @@ MESSAGE
2042
1919
  # join(10px, 20px) => 10px 20px
2043
1920
  # join(10px, 20px, comma) => 10px, 20px
2044
1921
  # join((blue, red), (#abc, #def), space) => blue red #abc #def
2045
- # join([10px], 20px) => [10px 20px]
2046
- # @overload join($list1, $list2, $separator: auto, $bracketed: auto)
1922
+ # @overload join($list1, $list2, $separator: auto)
2047
1923
  # @param $list1 [Sass::Script::Value::Base]
2048
1924
  # @param $list2 [Sass::Script::Value::Base]
2049
1925
  # @param $separator [Sass::Script::Value::String] The list separator to use.
2050
1926
  # If this is `comma` or `space`, that separator will be used. If this is
2051
1927
  # `auto` (the default), the separator is determined as explained above.
2052
- # @param $bracketed [Sass::Script::Value::Base] Whether the resulting list
2053
- # will be bracketed. If this is `auto` (the default), the separator is
2054
- # determined as explained above.
2055
1928
  # @return [Sass::Script::Value::List]
2056
- def join(list1, list2,
2057
- separator = identifier("auto"), bracketed = identifier("auto"),
2058
- kwargs = nil, *rest)
2059
- if separator.is_a?(Hash)
2060
- kwargs = separator
2061
- separator = identifier("auto")
2062
- elsif bracketed.is_a?(Hash)
2063
- kwargs = bracketed
2064
- bracketed = identifier("auto")
2065
- elsif rest.last.is_a?(Hash)
2066
- rest.unshift kwargs
2067
- kwargs = rest.pop
2068
- end
2069
-
2070
- unless rest.empty?
2071
- # Add 4 to rest.length because we don't want to count the kwargs hash,
2072
- # which is always passed.
2073
- raise ArgumentError.new("wrong number of arguments (#{rest.length + 4} for 2..4)")
2074
- end
2075
-
2076
- if kwargs
2077
- separator = kwargs.delete("separator") || separator
2078
- bracketed = kwargs.delete("bracketed") || bracketed
2079
-
2080
- unless kwargs.empty?
2081
- name, val = kwargs.to_a.first
2082
- raise ArgumentError.new("Unknown argument $#{name} (#{val})")
2083
- end
2084
- end
2085
-
1929
+ def join(list1, list2, separator = identifier("auto"))
2086
1930
  assert_type separator, :String, :separator
2087
- unless %w(auto space comma).include?(separator.value)
1931
+ unless %w[auto space comma].include?(separator.value)
2088
1932
  raise ArgumentError.new("Separator name must be space, comma, or auto")
2089
1933
  end
2090
-
2091
- list(list1.to_a + list2.to_a,
2092
- separator:
2093
- if separator.value == 'auto'
2094
- list1.separator || list2.separator || :space
2095
- else
2096
- separator.value.to_sym
2097
- end,
2098
- bracketed:
2099
- if bracketed.is_a?(Sass::Script::Value::String) && bracketed.value == 'auto'
2100
- list1.bracketed
2101
- else
2102
- bracketed.to_bool
2103
- end)
1934
+ sep = if separator.value == 'auto'
1935
+ list1.separator || list2.separator || :space
1936
+ else
1937
+ separator.value.to_sym
1938
+ end
1939
+ list(list1.to_a + list2.to_a, sep)
2104
1940
  end
2105
- # We don't actually take variable arguments or keyword arguments, but this
2106
- # is the best way to take either `$separator` or `$bracketed` as keywords
2107
- # without complaining about the other missing.
2108
- declare :join, [:list1, :list2], :var_args => true, :var_kwargs => true
1941
+ declare :join, [:list1, :list2]
1942
+ declare :join, [:list1, :list2, :separator]
2109
1943
 
2110
1944
  # Appends a single value onto the end of a list.
2111
1945
  #
@@ -2130,16 +1964,15 @@ MESSAGE
2130
1964
  # @return [Sass::Script::Value::List]
2131
1965
  def append(list, val, separator = identifier("auto"))
2132
1966
  assert_type separator, :String, :separator
2133
- unless %w(auto space comma).include?(separator.value)
1967
+ unless %w[auto space comma].include?(separator.value)
2134
1968
  raise ArgumentError.new("Separator name must be space, comma, or auto")
2135
1969
  end
2136
- list.with_contents(list.to_a + [val],
2137
- separator:
2138
- if separator.value == 'auto'
2139
- list.separator || :space
2140
- else
2141
- separator.value.to_sym
2142
- end)
1970
+ sep = if separator.value == 'auto'
1971
+ list.separator || :space
1972
+ else
1973
+ separator.value.to_sym
1974
+ end
1975
+ list(list.to_a + [val], sep)
2143
1976
  end
2144
1977
  declare :append, [:list, :val]
2145
1978
  declare :append, [:list, :val, :separator]
@@ -2209,20 +2042,7 @@ MESSAGE
2209
2042
  def list_separator(list)
2210
2043
  identifier((list.separator || :space).to_s)
2211
2044
  end
2212
- declare :list_separator, [:list]
2213
-
2214
- # Returns whether a list uses square brackets.
2215
- #
2216
- # @example
2217
- # is-bracketed(1px 2px 3px) => false
2218
- # is-bracketed([1px, 2px, 3px]) => true
2219
- # @overload is_bracketed($list)
2220
- # @param $list [Sass::Script::Value::Base]
2221
- # @return [Sass::Script::Value::Bool]
2222
- def is_bracketed(list)
2223
- bool(list.bracketed)
2224
- end
2225
- declare :is_bracketed, [:list]
2045
+ declare :separator, [:list]
2226
2046
 
2227
2047
  # Returns the value in a map associated with the given key. If the map
2228
2048
  # doesn't have such a key, returns `null`.
@@ -2408,24 +2228,10 @@ MESSAGE
2408
2228
  # $fn: nth;
2409
2229
  # call($fn, (a b c), 2) => b
2410
2230
  #
2411
- # @overload call($function, $args...)
2412
- # @param $function [Sass::Script::Value::Function] The function to call.
2231
+ # @overload call($name, $args...)
2232
+ # @param $name [String] The name of the function to call.
2413
2233
  def call(name, *args)
2414
- unless name.is_a?(Sass::Script::Value::String) ||
2415
- name.is_a?(Sass::Script::Value::Function)
2416
- assert_type name, :Function, :function
2417
- end
2418
- if name.is_a?(Sass::Script::Value::String)
2419
- name = if function_exists(name).to_bool
2420
- get_function(name)
2421
- else
2422
- get_function(name, "css" => bool(true))
2423
- end
2424
- Sass::Util.sass_warn(<<WARNING)
2425
- DEPRECATION WARNING: Passing a string to call() is deprecated and will be illegal
2426
- in Sass 4.0. Use call(#{name.to_sass}) instead.
2427
- WARNING
2428
- end
2234
+ assert_type name, :String, :name
2429
2235
  kwargs = args.last.is_a?(Hash) ? args.pop : {}
2430
2236
  funcall = Sass::Script::Tree::Funcall.new(
2431
2237
  name.value,
@@ -2433,8 +2239,6 @@ WARNING
2433
2239
  Sass::Util.map_vals(kwargs) {|v| Sass::Script::Tree::Literal.new(v)},
2434
2240
  nil,
2435
2241
  nil)
2436
- funcall.line = environment.stack.frames.last.line
2437
- funcall.filename = environment.stack.frames.last.filename
2438
2242
  funcall.options = options
2439
2243
  perform(funcall)
2440
2244
  end
@@ -2474,7 +2278,6 @@ WARNING
2474
2278
  # @example
2475
2279
  # $a-false-value: false;
2476
2280
  # variable-exists(a-false-value) => true
2477
- # variable-exists(a-null-value) => true
2478
2281
  #
2479
2282
  # variable-exists(nonexistent) => false
2480
2283
  #
@@ -2495,7 +2298,6 @@ WARNING
2495
2298
  # @example
2496
2299
  # $a-false-value: false;
2497
2300
  # global-variable-exists(a-false-value) => true
2498
- # global-variable-exists(a-null-value) => true
2499
2301
  #
2500
2302
  # .foo {
2501
2303
  # $some-var: false;
@@ -2523,12 +2325,12 @@ WARNING
2523
2325
  #
2524
2326
  # @overload function_exists($name)
2525
2327
  # @param name [Sass::Script::Value::String] The name of the function to
2526
- # check or a function reference.
2328
+ # check.
2527
2329
  # @return [Sass::Script::Value::Bool] Whether the function is defined.
2528
2330
  def function_exists(name)
2529
2331
  assert_type name, :String, :name
2530
2332
  exists = Sass::Script::Functions.callable?(name.value.tr("-", "_"))
2531
- exists ||= environment.caller.function(name.value)
2333
+ exists ||= environment.function(name.value)
2532
2334
  bool(exists)
2533
2335
  end
2534
2336
  declare :function_exists, [:name]
@@ -2551,31 +2353,6 @@ WARNING
2551
2353
  end
2552
2354
  declare :mixin_exists, [:name]
2553
2355
 
2554
- # Check whether a mixin was passed a content block.
2555
- #
2556
- # Unless `content-exists()` is called directly from a mixin, an error will be raised.
2557
- #
2558
- # @example
2559
- # @mixin needs-content {
2560
- # @if not content-exists() {
2561
- # @error "You must pass a content block!"
2562
- # }
2563
- # @content;
2564
- # }
2565
- #
2566
- # @overload content_exists()
2567
- # @return [Sass::Script::Value::Bool] Whether a content block was passed to the mixin.
2568
- def content_exists
2569
- # frames.last is the stack frame for this function,
2570
- # so we use frames[-2] to get the frame before that.
2571
- mixin_frame = environment.stack.frames[-2]
2572
- unless mixin_frame && mixin_frame.type == :mixin
2573
- raise Sass::SyntaxError.new("Cannot call content-exists() except within a mixin.")
2574
- end
2575
- bool(!environment.caller.content.nil?)
2576
- end
2577
- declare :content_exists, []
2578
-
2579
2356
  # Return a string containing the value as its Sass representation.
2580
2357
  #
2581
2358
  # @overload inspect($value)
@@ -2583,7 +2360,6 @@ WARNING
2583
2360
  # @return [Sass::Script::Value::String] A representation of the value as
2584
2361
  # it would be written in Sass.
2585
2362
  def inspect(value)
2586
- value.check_deprecated_interp if value.is_a?(Sass::Script::Value::String)
2587
2363
  unquoted_string(value.to_sass)
2588
2364
  end
2589
2365
  declare :inspect, [:value]
@@ -2657,7 +2433,7 @@ WARNING
2657
2433
  end
2658
2434
 
2659
2435
  parsed = [parse_selector(selectors.first, :selectors)]
2660
- parsed += selectors[1..-1].map {|sel| parse_selector(sel, :selectors, true)}
2436
+ parsed += selectors[1..-1].map {|sel| parse_selector(sel, :selectors, !!:parse_parent_ref)}
2661
2437
  parsed.inject {|result, child| child.resolve_parent_refs(result)}.to_sass_script
2662
2438
  end
2663
2439
  declare :selector_nest, [], :var_args => true
@@ -2745,7 +2521,7 @@ WARNING
2745
2521
 
2746
2522
  extends = Sass::Util::SubsetMap.new
2747
2523
  begin
2748
- extender.populate_extends(extends, extendee, nil, [], true)
2524
+ extender.populate_extends(extends, extendee)
2749
2525
  selector.do_extend(extends).to_sass_script
2750
2526
  rescue Sass::SyntaxError => e
2751
2527
  raise ArgumentError.new(e.to_s)
@@ -2788,8 +2564,8 @@ WARNING
2788
2564
 
2789
2565
  extends = Sass::Util::SubsetMap.new
2790
2566
  begin
2791
- replacement.populate_extends(extends, original, nil, [], true)
2792
- selector.do_extend(extends, [], true).to_sass_script
2567
+ replacement.populate_extends(extends, original)
2568
+ selector.do_extend(extends, [], !!:replace).to_sass_script
2793
2569
  rescue Sass::SyntaxError => e
2794
2570
  raise ArgumentError.new(e.to_s)
2795
2571
  end
@@ -2898,7 +2674,10 @@ WARNING
2898
2674
  yield(value.value), value.numerator_units, value.denominator_units)
2899
2675
  end
2900
2676
 
2677
+ # @comment
2678
+ # rubocop:disable ParameterLists
2901
2679
  def _adjust(color, amount, attr, range, op, units = "")
2680
+ # rubocop:enable ParameterLists
2902
2681
  assert_type color, :Color, :color
2903
2682
  assert_type amount, :Number, :amount
2904
2683
  Sass::Util.check_range('Amount', range, amount, units)
@@ -2906,14 +2685,19 @@ WARNING
2906
2685
  color.with(attr => color.send(attr).send(op, amount.value))
2907
2686
  end
2908
2687
 
2909
- def percentage_or_unitless(number, max, name)
2910
- if number.unitless?
2911
- number.value
2912
- elsif number.is_unit?("%")
2913
- max * number.value / 100.0;
2688
+ def check_alpha_unit(alpha, function)
2689
+ return if alpha.unitless?
2690
+
2691
+ if alpha.is_unit?("%")
2692
+ Sass::Util.sass_warn(<<WARNING)
2693
+ DEPRECATION WARNING: Passing a percentage as the alpha value to #{function}() will be
2694
+ interpreted differently in future versions of Sass. For now, use #{alpha.value} instead.
2695
+ WARNING
2914
2696
  else
2915
- raise ArgumentError.new(
2916
- "$#{name}: Expected #{number} to have no units or \"%\"");
2697
+ Sass::Util.sass_warn(<<WARNING)
2698
+ DEPRECATION WARNING: Passing a number with units as the alpha value to #{function}() is
2699
+ deprecated and will be an error in future versions of Sass. Use #{alpha.value} instead.
2700
+ WARNING
2917
2701
  end
2918
2702
  end
2919
2703
  end