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
@@ -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