sass 3.3.0 → 3.4.25
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.
- checksums.yaml +4 -4
- data/.yardopts +3 -1
- data/CODE_OF_CONDUCT.md +10 -0
- data/CONTRIBUTING.md +148 -0
- data/MIT-LICENSE +1 -1
- data/README.md +76 -62
- data/Rakefile +104 -24
- data/VERSION +1 -1
- data/VERSION_DATE +1 -1
- data/VERSION_NAME +1 -1
- data/bin/sass +1 -1
- data/bin/scss +1 -1
- data/extra/sass-spec-ref.sh +32 -0
- data/extra/update_watch.rb +1 -1
- data/lib/sass/cache_stores/filesystem.rb +9 -5
- data/lib/sass/cache_stores/memory.rb +4 -5
- data/lib/sass/callbacks.rb +2 -2
- data/lib/sass/css.rb +12 -13
- data/lib/sass/deprecation.rb +55 -0
- data/lib/sass/engine.rb +106 -70
- data/lib/sass/environment.rb +39 -19
- data/lib/sass/error.rb +17 -20
- data/lib/sass/exec/base.rb +199 -0
- data/lib/sass/exec/sass_convert.rb +283 -0
- data/lib/sass/exec/sass_scss.rb +440 -0
- data/lib/sass/exec.rb +5 -771
- data/lib/sass/features.rb +9 -2
- data/lib/sass/importers/base.rb +8 -3
- data/lib/sass/importers/filesystem.rb +30 -38
- data/lib/sass/logger/base.rb +8 -2
- data/lib/sass/logger/delayed.rb +50 -0
- data/lib/sass/logger.rb +8 -3
- data/lib/sass/media.rb +1 -4
- data/lib/sass/plugin/compiler.rb +224 -90
- data/lib/sass/plugin/configuration.rb +38 -22
- data/lib/sass/plugin/merb.rb +2 -2
- data/lib/sass/plugin/rack.rb +3 -3
- data/lib/sass/plugin/rails.rb +1 -1
- data/lib/sass/plugin/staleness_checker.rb +4 -4
- data/lib/sass/plugin.rb +6 -5
- data/lib/sass/script/css_lexer.rb +1 -1
- data/lib/sass/script/css_parser.rb +2 -3
- data/lib/sass/script/css_variable_warning.rb +52 -0
- data/lib/sass/script/functions.rb +739 -318
- data/lib/sass/script/lexer.rb +134 -54
- data/lib/sass/script/parser.rb +252 -56
- data/lib/sass/script/tree/funcall.rb +13 -6
- data/lib/sass/script/tree/interpolation.rb +127 -4
- data/lib/sass/script/tree/list_literal.rb +31 -4
- data/lib/sass/script/tree/literal.rb +4 -0
- data/lib/sass/script/tree/node.rb +21 -3
- data/lib/sass/script/tree/operation.rb +54 -1
- data/lib/sass/script/tree/selector.rb +26 -0
- data/lib/sass/script/tree/string_interpolation.rb +59 -38
- data/lib/sass/script/tree/variable.rb +1 -1
- data/lib/sass/script/tree.rb +1 -0
- data/lib/sass/script/value/base.rb +17 -14
- data/lib/sass/script/value/bool.rb +0 -5
- data/lib/sass/script/value/color.rb +78 -42
- data/lib/sass/script/value/helpers.rb +119 -2
- data/lib/sass/script/value/list.rb +0 -15
- data/lib/sass/script/value/map.rb +1 -1
- data/lib/sass/script/value/null.rb +0 -5
- data/lib/sass/script/value/number.rb +112 -31
- data/lib/sass/script/value/string.rb +102 -13
- data/lib/sass/script/value.rb +0 -1
- data/lib/sass/script.rb +3 -3
- data/lib/sass/scss/css_parser.rb +24 -4
- data/lib/sass/scss/parser.rb +290 -383
- data/lib/sass/scss/rx.rb +17 -9
- data/lib/sass/scss/static_parser.rb +306 -4
- data/lib/sass/scss.rb +0 -2
- data/lib/sass/selector/abstract_sequence.rb +35 -18
- data/lib/sass/selector/comma_sequence.rb +114 -19
- data/lib/sass/selector/pseudo.rb +266 -0
- data/lib/sass/selector/sequence.rb +146 -40
- data/lib/sass/selector/simple.rb +22 -33
- data/lib/sass/selector/simple_sequence.rb +122 -39
- data/lib/sass/selector.rb +57 -197
- data/lib/sass/shared.rb +2 -2
- data/lib/sass/source/map.rb +31 -14
- data/lib/sass/source/position.rb +4 -4
- data/lib/sass/stack.rb +2 -8
- data/lib/sass/supports.rb +10 -13
- data/lib/sass/tree/at_root_node.rb +1 -0
- data/lib/sass/tree/charset_node.rb +1 -1
- data/lib/sass/tree/comment_node.rb +1 -1
- data/lib/sass/tree/css_import_node.rb +9 -1
- data/lib/sass/tree/directive_node.rb +8 -2
- data/lib/sass/tree/error_node.rb +18 -0
- data/lib/sass/tree/extend_node.rb +1 -1
- data/lib/sass/tree/function_node.rb +9 -0
- data/lib/sass/tree/import_node.rb +6 -5
- data/lib/sass/tree/keyframe_rule_node.rb +15 -0
- data/lib/sass/tree/node.rb +5 -3
- data/lib/sass/tree/prop_node.rb +6 -7
- data/lib/sass/tree/rule_node.rb +26 -11
- data/lib/sass/tree/visitors/check_nesting.rb +56 -32
- data/lib/sass/tree/visitors/convert.rb +59 -44
- data/lib/sass/tree/visitors/cssize.rb +34 -30
- data/lib/sass/tree/visitors/deep_copy.rb +6 -1
- data/lib/sass/tree/visitors/extend.rb +15 -13
- data/lib/sass/tree/visitors/perform.rb +87 -50
- data/lib/sass/tree/visitors/set_options.rb +15 -1
- data/lib/sass/tree/visitors/to_css.rb +72 -43
- data/lib/sass/util/multibyte_string_scanner.rb +0 -2
- data/lib/sass/util/normalized_map.rb +0 -1
- data/lib/sass/util/subset_map.rb +2 -3
- data/lib/sass/util.rb +334 -154
- data/lib/sass/version.rb +7 -7
- data/lib/sass.rb +10 -8
- data/test/sass/cache_test.rb +62 -20
- data/test/sass/callbacks_test.rb +1 -1
- data/test/sass/compiler_test.rb +24 -11
- data/test/sass/conversion_test.rb +241 -50
- data/test/sass/css2sass_test.rb +73 -5
- data/test/sass/css_variable_test.rb +132 -0
- data/test/sass/encoding_test.rb +219 -0
- data/test/sass/engine_test.rb +343 -260
- data/test/sass/exec_test.rb +12 -2
- data/test/sass/extend_test.rb +333 -44
- data/test/sass/functions_test.rb +353 -260
- data/test/sass/importer_test.rb +40 -21
- data/test/sass/logger_test.rb +1 -1
- data/test/sass/more_results/more_import.css +1 -1
- data/test/sass/more_templates/more1.sass +10 -10
- data/test/sass/more_templates/more_import.sass +2 -2
- data/test/sass/plugin_test.rb +24 -21
- data/test/sass/results/compact.css +1 -1
- data/test/sass/results/complex.css +4 -4
- data/test/sass/results/expanded.css +1 -1
- data/test/sass/results/import.css +1 -1
- data/test/sass/results/import_charset_ibm866.css +2 -2
- data/test/sass/results/mixins.css +17 -17
- data/test/sass/results/nested.css +1 -1
- data/test/sass/results/parent_ref.css +2 -2
- data/test/sass/results/script.css +5 -5
- data/test/sass/results/scss_import.css +1 -1
- data/test/sass/script_conversion_test.rb +71 -39
- data/test/sass/script_test.rb +714 -123
- data/test/sass/scss/css_test.rb +213 -30
- data/test/sass/scss/rx_test.rb +8 -4
- data/test/sass/scss/scss_test.rb +766 -22
- data/test/sass/source_map_test.rb +263 -95
- data/test/sass/superselector_test.rb +210 -0
- data/test/sass/templates/_partial.sass +1 -1
- data/test/sass/templates/basic.sass +10 -10
- data/test/sass/templates/bork1.sass +1 -1
- data/test/sass/templates/bork5.sass +1 -1
- data/test/sass/templates/compact.sass +10 -10
- data/test/sass/templates/complex.sass +187 -187
- data/test/sass/templates/compressed.sass +10 -10
- data/test/sass/templates/expanded.sass +10 -10
- data/test/sass/templates/import.sass +2 -2
- data/test/sass/templates/importee.sass +3 -3
- data/test/sass/templates/mixins.sass +22 -22
- data/test/sass/templates/multiline.sass +4 -4
- data/test/sass/templates/nested.sass +13 -13
- data/test/sass/templates/parent_ref.sass +12 -12
- data/test/sass/templates/script.sass +70 -70
- data/test/sass/templates/scss_import.scss +2 -1
- data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +1 -1
- data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +2 -2
- data/test/sass/templates/subdir/subdir.sass +3 -3
- data/test/sass/templates/units.sass +10 -10
- data/test/sass/test_helper.rb +1 -1
- data/test/sass/util/multibyte_string_scanner_test.rb +11 -3
- data/test/sass/util/normalized_map_test.rb +1 -1
- data/test/sass/util/subset_map_test.rb +2 -2
- data/test/sass/util_test.rb +46 -45
- data/test/sass/value_helpers_test.rb +5 -7
- data/test/sass-spec.yml +3 -0
- data/test/test_helper.rb +7 -6
- data/vendor/listen/CHANGELOG.md +1 -228
- data/vendor/listen/Gemfile +5 -15
- data/vendor/listen/README.md +111 -77
- data/vendor/listen/Rakefile +0 -42
- data/vendor/listen/lib/listen/adapter.rb +195 -82
- data/vendor/listen/lib/listen/adapters/bsd.rb +27 -64
- data/vendor/listen/lib/listen/adapters/darwin.rb +21 -58
- data/vendor/listen/lib/listen/adapters/linux.rb +23 -55
- data/vendor/listen/lib/listen/adapters/polling.rb +25 -34
- data/vendor/listen/lib/listen/adapters/windows.rb +50 -46
- data/vendor/listen/lib/listen/directory_record.rb +96 -61
- data/vendor/listen/lib/listen/listener.rb +135 -37
- data/vendor/listen/lib/listen/turnstile.rb +9 -5
- data/vendor/listen/lib/listen/version.rb +1 -1
- data/vendor/listen/lib/listen.rb +33 -19
- data/vendor/listen/listen.gemspec +6 -0
- data/vendor/listen/spec/listen/adapter_spec.rb +43 -77
- data/vendor/listen/spec/listen/adapters/polling_spec.rb +8 -8
- data/vendor/listen/spec/listen/directory_record_spec.rb +81 -56
- data/vendor/listen/spec/listen/listener_spec.rb +128 -39
- data/vendor/listen/spec/listen_spec.rb +15 -21
- data/vendor/listen/spec/spec_helper.rb +4 -0
- data/vendor/listen/spec/support/adapter_helper.rb +52 -15
- data/vendor/listen/spec/support/directory_record_helper.rb +7 -5
- data/vendor/listen/spec/support/listeners_helper.rb +30 -7
- metadata +310 -300
- data/CONTRIBUTING +0 -3
- data/ext/mkrf_conf.rb +0 -27
- data/lib/sass/script/value/deprecated_false.rb +0 -55
- data/lib/sass/scss/script_lexer.rb +0 -15
- data/lib/sass/scss/script_parser.rb +0 -25
- data/vendor/listen/lib/listen/dependency_manager.rb +0 -126
- data/vendor/listen/lib/listen/multi_listener.rb +0 -143
- data/vendor/listen/spec/listen/dependency_manager_spec.rb +0 -107
- data/vendor/listen/spec/listen/multi_listener_spec.rb +0 -174
@@ -1,6 +1,9 @@
|
|
1
1
|
require 'sass/script/value/helpers'
|
2
2
|
|
3
3
|
module Sass::Script
|
4
|
+
# @comment
|
5
|
+
# YARD can't handle some multiline tags, and we need really long tags for function declarations.
|
6
|
+
# rubocop:disable LineLength
|
4
7
|
# Methods in this module are accessible from the SassScript context.
|
5
8
|
# For example, you can write
|
6
9
|
#
|
@@ -93,16 +96,13 @@ module Sass::Script
|
|
93
96
|
#
|
94
97
|
# ## Other Color Functions
|
95
98
|
#
|
96
|
-
# \{#adjust_color adjust-color($color, \[$red\], \[$green\], \[$blue\],
|
97
|
-
# \[$hue\], \[$saturation\], \[$lightness\], \[$alpha\])}
|
99
|
+
# \{#adjust_color adjust-color($color, \[$red\], \[$green\], \[$blue\], \[$hue\], \[$saturation\], \[$lightness\], \[$alpha\])}
|
98
100
|
# : Increases or decreases one or more components of a color.
|
99
101
|
#
|
100
|
-
# \{#scale_color scale-color($color, \[$red\], \[$green\], \[$blue\],
|
101
|
-
# \[$saturation\], \[$lightness\], \[$alpha\])}
|
102
|
+
# \{#scale_color scale-color($color, \[$red\], \[$green\], \[$blue\], \[$saturation\], \[$lightness\], \[$alpha\])}
|
102
103
|
# : Fluidly scales one or more properties of a color.
|
103
104
|
#
|
104
|
-
# \{#change_color change-color($color, \[$red\], \[$green\], \[$blue\],
|
105
|
-
# \[$hue\], \[$saturation\], \[$lightness\], \[$alpha\])}
|
105
|
+
# \{#change_color change-color($color, \[$red\], \[$green\], \[$blue\], \[$hue\], \[$saturation\], \[$lightness\], \[$alpha\])}
|
106
106
|
# : Changes one or more properties of a color.
|
107
107
|
#
|
108
108
|
# \{#ie_hex_str ie-hex-str($color)}
|
@@ -123,7 +123,7 @@ module Sass::Script
|
|
123
123
|
# : Inserts `$insert` into `$string` at `$index`.
|
124
124
|
#
|
125
125
|
# \{#str_index str-index($string, $substring)}
|
126
|
-
# : Returns the index of the first
|
126
|
+
# : Returns the index of the first occurrence of `$substring` in `$string`.
|
127
127
|
#
|
128
128
|
# \{#str_slice str-slice($string, $start-at, [$end-at])}
|
129
129
|
# : Extracts a substring from `$string`.
|
@@ -162,6 +162,9 @@ module Sass::Script
|
|
162
162
|
#
|
163
163
|
# ## List Functions {#list-functions}
|
164
164
|
#
|
165
|
+
# Lists in Sass are immutable; all list functions return a new list rather
|
166
|
+
# than updating the existing list in-place.
|
167
|
+
#
|
165
168
|
# All list functions work for maps as well, treating them as lists of pairs.
|
166
169
|
#
|
167
170
|
# \{#length length($list)}
|
@@ -170,6 +173,9 @@ module Sass::Script
|
|
170
173
|
# \{#nth nth($list, $n)}
|
171
174
|
# : Returns a specific item in a list.
|
172
175
|
#
|
176
|
+
# \{#set-nth set-nth($list, $n, $value)}
|
177
|
+
# : Replaces the nth item in a list.
|
178
|
+
#
|
173
179
|
# \{#join join($list1, $list2, \[$separator\])}
|
174
180
|
# : Joins together two lists into one.
|
175
181
|
#
|
@@ -182,19 +188,22 @@ module Sass::Script
|
|
182
188
|
# \{#index index($list, $value)}
|
183
189
|
# : Returns the position of a value within a list.
|
184
190
|
#
|
185
|
-
# \{#list_separator list-separator(
|
191
|
+
# \{#list_separator list-separator($list)}
|
186
192
|
# : Returns the separator of a list.
|
187
193
|
#
|
188
194
|
# ## Map Functions {#map-functions}
|
189
195
|
#
|
196
|
+
# Maps in Sass are immutable; all map functions return a new map rather than
|
197
|
+
# updating the existing map in-place.
|
198
|
+
#
|
190
199
|
# \{#map_get map-get($map, $key)}
|
191
200
|
# : Returns the value in a map associated with a given key.
|
192
201
|
#
|
193
202
|
# \{#map_merge map-merge($map1, $map2)}
|
194
203
|
# : Merges two maps together into a new map.
|
195
204
|
#
|
196
|
-
# \{#map_remove map-remove($map, $
|
197
|
-
# : Returns a new map with
|
205
|
+
# \{#map_remove map-remove($map, $keys...)}
|
206
|
+
# : Returns a new map with keys removed.
|
198
207
|
#
|
199
208
|
# \{#map_keys map-keys($map)}
|
200
209
|
# : Returns a list of all keys in a map.
|
@@ -202,12 +211,54 @@ module Sass::Script
|
|
202
211
|
# \{#map_values map-values($map)}
|
203
212
|
# : Returns a list of all values in a map.
|
204
213
|
#
|
205
|
-
# \{#map_has_key map-has-key($key)}
|
214
|
+
# \{#map_has_key map-has-key($map, $key)}
|
206
215
|
# : Returns whether a map has a value associated with a given key.
|
207
216
|
#
|
208
217
|
# \{#keywords keywords($args)}
|
209
218
|
# : Returns the keywords passed to a function that takes variable arguments.
|
210
219
|
#
|
220
|
+
# ## Selector Functions
|
221
|
+
#
|
222
|
+
# Selector functions are very liberal in the formats they support
|
223
|
+
# for selector arguments. They can take a plain string, a list of
|
224
|
+
# lists as returned by `&` or anything in between:
|
225
|
+
#
|
226
|
+
# * A plain string, such as `".foo .bar, .baz .bang"`.
|
227
|
+
# * A space-separated list of strings such as `(".foo" ".bar")`.
|
228
|
+
# * A comma-separated list of strings such as `(".foo .bar", ".baz .bang")`.
|
229
|
+
# * A comma-separated list of space-separated lists of strings such
|
230
|
+
# as `((".foo" ".bar"), (".baz" ".bang"))`.
|
231
|
+
#
|
232
|
+
# In general, selector functions allow placeholder selectors
|
233
|
+
# (`%foo`) but disallow parent-reference selectors (`&`).
|
234
|
+
#
|
235
|
+
# \{#selector_nest selector-nest($selectors...)}
|
236
|
+
# : Nests selector beneath one another like they would be nested in the
|
237
|
+
# stylesheet.
|
238
|
+
#
|
239
|
+
# \{#selector_append selector-append($selectors...)}
|
240
|
+
# : Appends selectors to one another without spaces in between.
|
241
|
+
#
|
242
|
+
# \{#selector_extend selector-extend($selector, $extendee, $extender)}
|
243
|
+
# : Extends `$extendee` with `$extender` within `$selector`.
|
244
|
+
#
|
245
|
+
# \{#selector_replace selector-replace($selector, $original, $replacement)}
|
246
|
+
# : Replaces `$original` with `$replacement` within `$selector`.
|
247
|
+
#
|
248
|
+
# \{#selector_unify selector-unify($selector1, $selector2)}
|
249
|
+
# : Unifies two selectors to produce a selector that matches
|
250
|
+
# elements matched by both.
|
251
|
+
#
|
252
|
+
# \{#is_superselector is-superselector($super, $sub)}
|
253
|
+
# : Returns whether `$super` matches all the elements `$sub` does, and
|
254
|
+
# possibly more.
|
255
|
+
#
|
256
|
+
# \{#simple_selectors simple-selectors($selector)}
|
257
|
+
# : Returns the simple selectors that comprise a compound selector.
|
258
|
+
#
|
259
|
+
# \{#selector_parse selector-parse($selector)}
|
260
|
+
# : Parses a selector into the format returned by `&`.
|
261
|
+
#
|
211
262
|
# ## Introspection Functions
|
212
263
|
#
|
213
264
|
# \{#feature_exists feature-exists($feature)}
|
@@ -302,6 +353,10 @@ module Sass::Script
|
|
302
353
|
# safe to call {Value::Base#to_s #to_s} (or other methods that use the string
|
303
354
|
# representation) on those objects without first setting {Tree::Node#options=
|
304
355
|
# the #options attribute}.
|
356
|
+
#
|
357
|
+
# @comment
|
358
|
+
# rubocop:enable LineLength
|
359
|
+
# rubocop:disable ModuleLength
|
305
360
|
module Functions
|
306
361
|
@signatures = {}
|
307
362
|
|
@@ -376,8 +431,8 @@ module Sass::Script
|
|
376
431
|
# If no signatures match, the first signature is returned for error messaging.
|
377
432
|
#
|
378
433
|
# @param method_name [Symbol] The name of the Ruby function to be called.
|
379
|
-
# @param arg_arity [
|
380
|
-
# @param kwarg_arity [
|
434
|
+
# @param arg_arity [Integer] The number of unnamed arguments the function was passed.
|
435
|
+
# @param kwarg_arity [Integer] The number of keyword arguments the function was passed.
|
381
436
|
#
|
382
437
|
# @return [{Symbol => Object}, nil]
|
383
438
|
# The signature options for the matching signature,
|
@@ -400,8 +455,8 @@ module Sass::Script
|
|
400
455
|
t_arg_arity = sig_arity
|
401
456
|
end
|
402
457
|
|
403
|
-
if
|
404
|
-
(t_kwarg_arity == 0
|
458
|
+
if (t_arg_arity == sig_arity || t_arg_arity > sig_arity && signature.var_args) &&
|
459
|
+
(t_kwarg_arity == 0 || t_kwarg_arity > 0 && signature.var_kwargs)
|
405
460
|
return signature
|
406
461
|
end
|
407
462
|
end
|
@@ -434,8 +489,7 @@ module Sass::Script
|
|
434
489
|
include Value::Helpers
|
435
490
|
|
436
491
|
# The human-readable names for [Sass::Script::Value::Base]. The default is
|
437
|
-
# just the downcased name of the type.
|
438
|
-
# name.
|
492
|
+
# just the downcased name of the type.
|
439
493
|
TYPE_NAMES = {:ArgList => 'variable argument list'}
|
440
494
|
|
441
495
|
# The environment for this function. This environment's
|
@@ -473,10 +527,14 @@ module Sass::Script
|
|
473
527
|
# @raise [ArgumentError] if value is not of the correct type.
|
474
528
|
def assert_type(value, type, name = nil)
|
475
529
|
klass = Sass::Script::Value.const_get(type)
|
476
|
-
|
477
|
-
|
530
|
+
if value.is_a?(klass)
|
531
|
+
value.check_deprecated_interp if type == :String
|
532
|
+
return
|
533
|
+
end
|
534
|
+
|
535
|
+
return if value.is_a?(Sass::Script::Value::List) && type == :Map && value.value.empty?
|
478
536
|
err = "#{value.inspect} is not a #{TYPE_NAMES[type] || type.to_s.downcase}"
|
479
|
-
err = "$#{name.to_s.
|
537
|
+
err = "$#{name.to_s.tr('_', '-')}: " + err if name
|
480
538
|
raise ArgumentError.new(err)
|
481
539
|
end
|
482
540
|
|
@@ -565,32 +623,38 @@ module Sass::Script
|
|
565
623
|
#
|
566
624
|
# @see #rgba
|
567
625
|
# @overload rgb($red, $green, $blue)
|
568
|
-
#
|
569
|
-
#
|
570
|
-
#
|
571
|
-
#
|
572
|
-
#
|
573
|
-
#
|
574
|
-
#
|
575
|
-
#
|
576
|
-
#
|
626
|
+
# @param $red [Sass::Script::Value::Number] The amount of red in the color.
|
627
|
+
# Must be between 0 and 255 inclusive, or between `0%` and `100%`
|
628
|
+
# inclusive
|
629
|
+
# @param $green [Sass::Script::Value::Number] The amount of green in the
|
630
|
+
# color. Must be between 0 and 255 inclusive, or between `0%` and `100%`
|
631
|
+
# inclusive
|
632
|
+
# @param $blue [Sass::Script::Value::Number] The amount of blue in the
|
633
|
+
# color. Must be between 0 and 255 inclusive, or between `0%` and `100%`
|
634
|
+
# inclusive
|
577
635
|
# @return [Sass::Script::Value::Color]
|
578
636
|
# @raise [ArgumentError] if any parameter is the wrong type or out of bounds
|
579
637
|
def rgb(red, green, blue)
|
638
|
+
if calc?(red) || calc?(green) || calc?(blue)
|
639
|
+
return unquoted_string("rgb(#{red}, #{green}, #{blue})")
|
640
|
+
end
|
580
641
|
assert_type red, :Number, :red
|
581
642
|
assert_type green, :Number, :green
|
582
643
|
assert_type blue, :Number, :blue
|
583
644
|
|
584
|
-
color_attrs = [
|
645
|
+
color_attrs = [red, green, blue].map do |c|
|
585
646
|
if c.is_unit?("%")
|
586
|
-
|
587
|
-
v * 255 / 100.0
|
647
|
+
c.value * 255 / 100.0
|
588
648
|
elsif c.unitless?
|
589
|
-
|
649
|
+
c.value
|
590
650
|
else
|
591
651
|
raise ArgumentError.new("Expected #{c} to be unitless or have a unit of % but got #{c}")
|
592
652
|
end
|
593
653
|
end
|
654
|
+
|
655
|
+
# Don't store the string representation for function-created colors, both
|
656
|
+
# because it's not very useful and because some functions aren't supported
|
657
|
+
# on older browsers.
|
594
658
|
Sass::Script::Value::Color.new(color_attrs)
|
595
659
|
end
|
596
660
|
declare :rgb, [:red, :green, :blue]
|
@@ -601,11 +665,11 @@ module Sass::Script
|
|
601
665
|
#
|
602
666
|
# @overload rgba($red, $green, $blue, $alpha)
|
603
667
|
# @param $red [Sass::Script::Value::Number] The amount of red in the
|
604
|
-
# color. Must be between 0 and 255 inclusive
|
668
|
+
# color. Must be between 0 and 255 inclusive or 0% and 100% inclusive
|
605
669
|
# @param $green [Sass::Script::Value::Number] The amount of green in the
|
606
|
-
# color. Must be between 0 and 255 inclusive
|
670
|
+
# color. Must be between 0 and 255 inclusive or 0% and 100% inclusive
|
607
671
|
# @param $blue [Sass::Script::Value::Number] The amount of blue in the
|
608
|
-
# color. Must be between 0 and 255 inclusive
|
672
|
+
# color. Must be between 0 and 255 inclusive or 0% and 100% inclusive
|
609
673
|
# @param $alpha [Sass::Script::Value::Number] The opacity of the color.
|
610
674
|
# Must be between 0 and 1 inclusive
|
611
675
|
# @return [Sass::Script::Value::Color]
|
@@ -632,13 +696,20 @@ module Sass::Script
|
|
632
696
|
color, alpha = args
|
633
697
|
|
634
698
|
assert_type color, :Color, :color
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
699
|
+
if calc?(alpha)
|
700
|
+
unquoted_string("rgba(#{color.red}, #{color.green}, #{color.blue}, #{alpha})")
|
701
|
+
else
|
702
|
+
assert_type alpha, :Number, :alpha
|
703
|
+
check_alpha_unit alpha, 'rgba'
|
704
|
+
color.with(:alpha => alpha.value)
|
705
|
+
end
|
639
706
|
when 4
|
640
707
|
red, green, blue, alpha = args
|
641
|
-
|
708
|
+
if calc?(red) || calc?(green) || calc?(blue) || calc?(alpha)
|
709
|
+
unquoted_string("rgba(#{red}, #{green}, #{blue}, #{alpha})")
|
710
|
+
else
|
711
|
+
rgba(rgb(red, green, blue), alpha)
|
712
|
+
end
|
642
713
|
else
|
643
714
|
raise ArgumentError.new("wrong number of arguments (#{args.size} for 4)")
|
644
715
|
end
|
@@ -653,17 +724,21 @@ module Sass::Script
|
|
653
724
|
#
|
654
725
|
# @see #hsla
|
655
726
|
# @overload hsl($hue, $saturation, $lightness)
|
656
|
-
#
|
657
|
-
#
|
658
|
-
#
|
659
|
-
#
|
660
|
-
#
|
661
|
-
#
|
727
|
+
# @param $hue [Sass::Script::Value::Number] The hue of the color. Should be
|
728
|
+
# between 0 and 360 degrees, inclusive
|
729
|
+
# @param $saturation [Sass::Script::Value::Number] The saturation of the
|
730
|
+
# color. Must be between `0%` and `100%`, inclusive
|
731
|
+
# @param $lightness [Sass::Script::Value::Number] The lightness of the
|
732
|
+
# color. Must be between `0%` and `100%`, inclusive
|
662
733
|
# @return [Sass::Script::Value::Color]
|
663
734
|
# @raise [ArgumentError] if `$saturation` or `$lightness` are out of bounds
|
664
735
|
# or any parameter is the wrong type
|
665
736
|
def hsl(hue, saturation, lightness)
|
666
|
-
|
737
|
+
if calc?(hue) || calc?(saturation) || calc?(lightness)
|
738
|
+
unquoted_string("hsl(#{hue}, #{saturation}, #{lightness})")
|
739
|
+
else
|
740
|
+
hsla(hue, saturation, lightness, number(1))
|
741
|
+
end
|
667
742
|
end
|
668
743
|
declare :hsl, [:hue, :saturation, :lightness]
|
669
744
|
|
@@ -675,29 +750,34 @@ module Sass::Script
|
|
675
750
|
#
|
676
751
|
# @see #hsl
|
677
752
|
# @overload hsla($hue, $saturation, $lightness, $alpha)
|
678
|
-
#
|
679
|
-
#
|
680
|
-
#
|
681
|
-
#
|
682
|
-
#
|
683
|
-
#
|
684
|
-
#
|
685
|
-
#
|
753
|
+
# @param $hue [Sass::Script::Value::Number] The hue of the color. Should be
|
754
|
+
# between 0 and 360 degrees, inclusive
|
755
|
+
# @param $saturation [Sass::Script::Value::Number] The saturation of the
|
756
|
+
# color. Must be between `0%` and `100%`, inclusive
|
757
|
+
# @param $lightness [Sass::Script::Value::Number] The lightness of the
|
758
|
+
# color. Must be between `0%` and `100%`, inclusive
|
759
|
+
# @param $alpha [Sass::Script::Value::Number] The opacity of the color. Must
|
760
|
+
# be between 0 and 1, inclusive
|
686
761
|
# @return [Sass::Script::Value::Color]
|
687
762
|
# @raise [ArgumentError] if `$saturation`, `$lightness`, or `$alpha` are out
|
688
763
|
# of bounds or any parameter is the wrong type
|
689
764
|
def hsla(hue, saturation, lightness, alpha)
|
765
|
+
if calc?(hue) || calc?(saturation) || calc?(lightness) || calc?(alpha)
|
766
|
+
return unquoted_string("hsla(#{hue}, #{saturation}, #{lightness}, #{alpha})")
|
767
|
+
end
|
690
768
|
assert_type hue, :Number, :hue
|
691
769
|
assert_type saturation, :Number, :saturation
|
692
770
|
assert_type lightness, :Number, :lightness
|
693
771
|
assert_type alpha, :Number, :alpha
|
694
|
-
|
695
|
-
Sass::Util.check_range('Alpha channel', 0..1, alpha)
|
772
|
+
check_alpha_unit alpha, 'hsla'
|
696
773
|
|
697
774
|
h = hue.value
|
698
|
-
s =
|
699
|
-
l =
|
775
|
+
s = saturation.value
|
776
|
+
l = lightness.value
|
700
777
|
|
778
|
+
# Don't store the string representation for function-created colors, both
|
779
|
+
# because it's not very useful and because some functions aren't supported
|
780
|
+
# on older browsers.
|
701
781
|
Sass::Script::Value::Color.new(
|
702
782
|
:hue => h, :saturation => s, :lightness => l, :alpha => alpha.value)
|
703
783
|
end
|
@@ -709,7 +789,7 @@ module Sass::Script
|
|
709
789
|
# [hsl-to-rgb]: http://www.w3.org/TR/css3-color/#hsl-color
|
710
790
|
#
|
711
791
|
# @overload red($color)
|
712
|
-
#
|
792
|
+
# @param $color [Sass::Script::Value::Color]
|
713
793
|
# @return [Sass::Script::Value::Number] The red component, between 0 and 255
|
714
794
|
# inclusive
|
715
795
|
# @raise [ArgumentError] if `$color` isn't a color
|
@@ -725,7 +805,7 @@ module Sass::Script
|
|
725
805
|
# [hsl-to-rgb]: http://www.w3.org/TR/css3-color/#hsl-color
|
726
806
|
#
|
727
807
|
# @overload green($color)
|
728
|
-
#
|
808
|
+
# @param $color [Sass::Script::Value::Color]
|
729
809
|
# @return [Sass::Script::Value::Number] The green component, between 0 and
|
730
810
|
# 255 inclusive
|
731
811
|
# @raise [ArgumentError] if `$color` isn't a color
|
@@ -741,7 +821,7 @@ module Sass::Script
|
|
741
821
|
# [hsl-to-rgb]: http://www.w3.org/TR/css3-color/#hsl-color
|
742
822
|
#
|
743
823
|
# @overload blue($color)
|
744
|
-
#
|
824
|
+
# @param $color [Sass::Script::Value::Color]
|
745
825
|
# @return [Sass::Script::Value::Number] The blue component, between 0 and
|
746
826
|
# 255 inclusive
|
747
827
|
# @raise [ArgumentError] if `$color` isn't a color
|
@@ -759,7 +839,7 @@ module Sass::Script
|
|
759
839
|
# [rgb-to-hsl]: http://en.wikipedia.org/wiki/HSL_and_HSV#Conversion_from_RGB_to_HSL_or_HSV
|
760
840
|
#
|
761
841
|
# @overload hue($color)
|
762
|
-
#
|
842
|
+
# @param $color [Sass::Script::Value::Color]
|
763
843
|
# @return [Sass::Script::Value::Number] The hue component, between 0deg and
|
764
844
|
# 360deg
|
765
845
|
# @raise [ArgumentError] if `$color` isn't a color
|
@@ -777,7 +857,7 @@ module Sass::Script
|
|
777
857
|
# [rgb-to-hsl]: http://en.wikipedia.org/wiki/HSL_and_HSV#Conversion_from_RGB_to_HSL_or_HSV
|
778
858
|
#
|
779
859
|
# @overload saturation($color)
|
780
|
-
#
|
860
|
+
# @param $color [Sass::Script::Value::Color]
|
781
861
|
# @return [Sass::Script::Value::Number] The saturation component, between 0%
|
782
862
|
# and 100%
|
783
863
|
# @raise [ArgumentError] if `$color` isn't a color
|
@@ -795,7 +875,7 @@ module Sass::Script
|
|
795
875
|
# [rgb-to-hsl]: http://en.wikipedia.org/wiki/HSL_and_HSV#Conversion_from_RGB_to_HSL_or_HSV
|
796
876
|
#
|
797
877
|
# @overload lightness($color)
|
798
|
-
#
|
878
|
+
# @param $color [Sass::Script::Value::Color]
|
799
879
|
# @return [Sass::Script::Value::Number] The lightness component, between 0%
|
800
880
|
# and 100%
|
801
881
|
# @raise [ArgumentError] if `$color` isn't a color
|
@@ -812,7 +892,7 @@ module Sass::Script
|
|
812
892
|
# syntax as a special case.
|
813
893
|
#
|
814
894
|
# @overload alpha($color)
|
815
|
-
#
|
895
|
+
# @param $color [Sass::Script::Value::Color]
|
816
896
|
# @return [Sass::Script::Value::Number] The alpha component, between 0 and 1
|
817
897
|
# @raise [ArgumentError] if `$color` isn't a color
|
818
898
|
def alpha(*args)
|
@@ -821,7 +901,7 @@ module Sass::Script
|
|
821
901
|
a.value =~ /^[a-zA-Z]+\s*=/
|
822
902
|
end
|
823
903
|
# Support the proprietary MS alpha() function
|
824
|
-
return identifier("alpha(#{args.map {|a| a.to_s}.join(
|
904
|
+
return identifier("alpha(#{args.map {|a| a.to_s}.join(', ')})")
|
825
905
|
end
|
826
906
|
|
827
907
|
raise ArgumentError.new("wrong number of arguments (#{args.size} for 1)") if args.size != 1
|
@@ -835,7 +915,7 @@ module Sass::Script
|
|
835
915
|
# otherwise specified.
|
836
916
|
#
|
837
917
|
# @overload opacity($color)
|
838
|
-
#
|
918
|
+
# @param $color [Sass::Script::Value::Color]
|
839
919
|
# @return [Sass::Script::Value::Number] The alpha component, between 0 and 1
|
840
920
|
# @raise [ArgumentError] if `$color` isn't a color
|
841
921
|
def opacity(color)
|
@@ -855,9 +935,9 @@ module Sass::Script
|
|
855
935
|
# opacify(rgba(0, 0, 0, 0.5), 0.1) => rgba(0, 0, 0, 0.6)
|
856
936
|
# opacify(rgba(0, 0, 17, 0.8), 0.2) => #001
|
857
937
|
# @overload opacify($color, $amount)
|
858
|
-
#
|
859
|
-
#
|
860
|
-
#
|
938
|
+
# @param $color [Sass::Script::Value::Color]
|
939
|
+
# @param $amount [Sass::Script::Value::Number] The amount to increase the
|
940
|
+
# opacity by, between 0 and 1
|
861
941
|
# @return [Sass::Script::Value::Color]
|
862
942
|
# @raise [ArgumentError] if `$amount` is out of bounds, or either parameter
|
863
943
|
# is the wrong type
|
@@ -877,9 +957,9 @@ module Sass::Script
|
|
877
957
|
# transparentize(rgba(0, 0, 0, 0.5), 0.1) => rgba(0, 0, 0, 0.4)
|
878
958
|
# transparentize(rgba(0, 0, 0, 0.8), 0.2) => rgba(0, 0, 0, 0.6)
|
879
959
|
# @overload transparentize($color, $amount)
|
880
|
-
#
|
881
|
-
#
|
882
|
-
#
|
960
|
+
# @param $color [Sass::Script::Value::Color]
|
961
|
+
# @param $amount [Sass::Script::Value::Number] The amount to decrease the
|
962
|
+
# opacity by, between 0 and 1
|
883
963
|
# @return [Sass::Script::Value::Color]
|
884
964
|
# @raise [ArgumentError] if `$amount` is out of bounds, or either parameter
|
885
965
|
# is the wrong type
|
@@ -899,9 +979,9 @@ module Sass::Script
|
|
899
979
|
# lighten(hsl(0, 0%, 0%), 30%) => hsl(0, 0, 30)
|
900
980
|
# lighten(#800, 20%) => #e00
|
901
981
|
# @overload lighten($color, $amount)
|
902
|
-
#
|
903
|
-
#
|
904
|
-
#
|
982
|
+
# @param $color [Sass::Script::Value::Color]
|
983
|
+
# @param $amount [Sass::Script::Value::Number] The amount to increase the
|
984
|
+
# lightness by, between `0%` and `100%`
|
905
985
|
# @return [Sass::Script::Value::Color]
|
906
986
|
# @raise [ArgumentError] if `$amount` is out of bounds, or either parameter
|
907
987
|
# is the wrong type
|
@@ -918,9 +998,9 @@ module Sass::Script
|
|
918
998
|
# darken(hsl(25, 100%, 80%), 30%) => hsl(25, 100%, 50%)
|
919
999
|
# darken(#800, 20%) => #200
|
920
1000
|
# @overload darken($color, $amount)
|
921
|
-
#
|
922
|
-
#
|
923
|
-
#
|
1001
|
+
# @param $color [Sass::Script::Value::Color]
|
1002
|
+
# @param $amount [Sass::Script::Value::Number] The amount to decrease the
|
1003
|
+
# lightness by, between `0%` and `100%`
|
924
1004
|
# @return [Sass::Script::Value::Color]
|
925
1005
|
# @raise [ArgumentError] if `$amount` is out of bounds, or either parameter
|
926
1006
|
# is the wrong type
|
@@ -937,9 +1017,9 @@ module Sass::Script
|
|
937
1017
|
# saturate(hsl(120, 30%, 90%), 20%) => hsl(120, 50%, 90%)
|
938
1018
|
# saturate(#855, 20%) => #9e3f3f
|
939
1019
|
# @overload saturate($color, $amount)
|
940
|
-
#
|
941
|
-
#
|
942
|
-
#
|
1020
|
+
# @param $color [Sass::Script::Value::Color]
|
1021
|
+
# @param $amount [Sass::Script::Value::Number] The amount to increase the
|
1022
|
+
# saturation by, between `0%` and `100%`
|
943
1023
|
# @return [Sass::Script::Value::Color]
|
944
1024
|
# @raise [ArgumentError] if `$amount` is out of bounds, or either parameter
|
945
1025
|
# is the wrong type
|
@@ -960,9 +1040,9 @@ module Sass::Script
|
|
960
1040
|
# desaturate(hsl(120, 30%, 90%), 20%) => hsl(120, 10%, 90%)
|
961
1041
|
# desaturate(#855, 20%) => #726b6b
|
962
1042
|
# @overload desaturate($color, $amount)
|
963
|
-
#
|
964
|
-
#
|
965
|
-
#
|
1043
|
+
# @param $color [Sass::Script::Value::Color]
|
1044
|
+
# @param $amount [Sass::Script::Value::Number] The amount to decrease the
|
1045
|
+
# saturation by, between `0%` and `100%`
|
966
1046
|
# @return [Sass::Script::Value::Color]
|
967
1047
|
# @raise [ArgumentError] if `$amount` is out of bounds, or either parameter
|
968
1048
|
# is the wrong type
|
@@ -977,12 +1057,12 @@ module Sass::Script
|
|
977
1057
|
#
|
978
1058
|
# @example
|
979
1059
|
# adjust-hue(hsl(120, 30%, 90%), 60deg) => hsl(180, 30%, 90%)
|
980
|
-
# adjust-hue(hsl(120, 30%, 90%),
|
1060
|
+
# adjust-hue(hsl(120, 30%, 90%), -60deg) => hsl(60, 30%, 90%)
|
981
1061
|
# adjust-hue(#811, 45deg) => #886a11
|
982
1062
|
# @overload adjust_hue($color, $degrees)
|
983
|
-
#
|
984
|
-
#
|
985
|
-
#
|
1063
|
+
# @param $color [Sass::Script::Value::Color]
|
1064
|
+
# @param $degrees [Sass::Script::Value::Number] The number of degrees to
|
1065
|
+
# rotate the hue
|
986
1066
|
# @return [Sass::Script::Value::Color]
|
987
1067
|
# @raise [ArgumentError] if either parameter is the wrong type
|
988
1068
|
def adjust_hue(color, degrees)
|
@@ -999,13 +1079,13 @@ module Sass::Script
|
|
999
1079
|
# ie-hex-str(#3322BB) => #FF3322BB
|
1000
1080
|
# ie-hex-str(rgba(0, 255, 0, 0.5)) => #8000FF00
|
1001
1081
|
# @overload ie_hex_str($color)
|
1002
|
-
#
|
1082
|
+
# @param $color [Sass::Script::Value::Color]
|
1003
1083
|
# @return [Sass::Script::Value::String] The IE-formatted string
|
1004
1084
|
# representation of the color
|
1005
1085
|
# @raise [ArgumentError] if `$color` isn't a color
|
1006
1086
|
def ie_hex_str(color)
|
1007
1087
|
assert_type color, :Color, :color
|
1008
|
-
alpha = (color.alpha * 255).
|
1088
|
+
alpha = Sass::Util.round(color.alpha * 255).to_s(16).rjust(2, '0')
|
1009
1089
|
identifier("##{alpha}#{color.send(:hex_str)[1..-1]}".upcase)
|
1010
1090
|
end
|
1011
1091
|
declare :ie_hex_str, [:color]
|
@@ -1023,23 +1103,22 @@ module Sass::Script
|
|
1023
1103
|
# adjust-color(#102030, $blue: 5) => #102035
|
1024
1104
|
# adjust-color(#102030, $red: -5, $blue: 5) => #0b2035
|
1025
1105
|
# adjust-color(hsl(25, 100%, 80%), $lightness: -30%, $alpha: -0.4) => hsla(25, 100%, 50%, 0.6)
|
1026
|
-
# @overload adjust_color($color, [$red], [$green], [$blue],
|
1027
|
-
#
|
1028
|
-
#
|
1029
|
-
#
|
1030
|
-
#
|
1031
|
-
#
|
1032
|
-
#
|
1033
|
-
#
|
1034
|
-
#
|
1035
|
-
#
|
1036
|
-
#
|
1037
|
-
#
|
1038
|
-
#
|
1039
|
-
#
|
1040
|
-
#
|
1041
|
-
#
|
1042
|
-
# alpha component, between -1 and 1 inclusive
|
1106
|
+
# @overload adjust_color($color, [$red], [$green], [$blue], [$hue], [$saturation], [$lightness], [$alpha])
|
1107
|
+
# @param $color [Sass::Script::Value::Color]
|
1108
|
+
# @param $red [Sass::Script::Value::Number] The adjustment to make on the
|
1109
|
+
# red component, between -255 and 255 inclusive
|
1110
|
+
# @param $green [Sass::Script::Value::Number] The adjustment to make on the
|
1111
|
+
# green component, between -255 and 255 inclusive
|
1112
|
+
# @param $blue [Sass::Script::Value::Number] The adjustment to make on the
|
1113
|
+
# blue component, between -255 and 255 inclusive
|
1114
|
+
# @param $hue [Sass::Script::Value::Number] The adjustment to make on the
|
1115
|
+
# hue component, in degrees
|
1116
|
+
# @param $saturation [Sass::Script::Value::Number] The adjustment to make on
|
1117
|
+
# the saturation component, between `-100%` and `100%` inclusive
|
1118
|
+
# @param $lightness [Sass::Script::Value::Number] The adjustment to make on
|
1119
|
+
# the lightness component, between `-100%` and `100%` inclusive
|
1120
|
+
# @param $alpha [Sass::Script::Value::Number] The adjustment to make on the
|
1121
|
+
# alpha component, between -1 and 1 inclusive
|
1043
1122
|
# @return [Sass::Script::Value::Color]
|
1044
1123
|
# @raise [ArgumentError] if any parameter is the wrong type or out-of
|
1045
1124
|
# bounds, or if RGB properties and HSL properties are adjusted at the
|
@@ -1047,15 +1126,14 @@ module Sass::Script
|
|
1047
1126
|
def adjust_color(color, kwargs)
|
1048
1127
|
assert_type color, :Color, :color
|
1049
1128
|
with = Sass::Util.map_hash(
|
1050
|
-
|
1051
|
-
|
1052
|
-
|
1053
|
-
|
1054
|
-
|
1055
|
-
|
1056
|
-
|
1057
|
-
|
1058
|
-
|
1129
|
+
"red" => [-255..255, ""],
|
1130
|
+
"green" => [-255..255, ""],
|
1131
|
+
"blue" => [-255..255, ""],
|
1132
|
+
"hue" => nil,
|
1133
|
+
"saturation" => [-100..100, "%"],
|
1134
|
+
"lightness" => [-100..100, "%"],
|
1135
|
+
"alpha" => [-1..1, ""]
|
1136
|
+
) do |name, (range, units)|
|
1059
1137
|
val = kwargs.delete(name)
|
1060
1138
|
next unless val
|
1061
1139
|
assert_type val, :Number, name
|
@@ -1101,15 +1179,14 @@ module Sass::Script
|
|
1101
1179
|
# scale-color(hsl(120, 70%, 80%), $lightness: 50%) => hsl(120, 70%, 90%)
|
1102
1180
|
# scale-color(rgb(200, 150%, 170%), $green: -40%, $blue: 70%) => rgb(200, 90, 229)
|
1103
1181
|
# scale-color(hsl(200, 70%, 80%), $saturation: -90%, $alpha: -30%) => hsla(200, 7%, 80%, 0.7)
|
1104
|
-
# @overload scale_color($color, [$red], [$green], [$blue],
|
1105
|
-
#
|
1106
|
-
#
|
1107
|
-
#
|
1108
|
-
#
|
1109
|
-
#
|
1110
|
-
#
|
1111
|
-
#
|
1112
|
-
# @param $alpha [Sass::Script::Value::Number]
|
1182
|
+
# @overload scale_color($color, [$red], [$green], [$blue], [$saturation], [$lightness], [$alpha])
|
1183
|
+
# @param $color [Sass::Script::Value::Color]
|
1184
|
+
# @param $red [Sass::Script::Value::Number]
|
1185
|
+
# @param $green [Sass::Script::Value::Number]
|
1186
|
+
# @param $blue [Sass::Script::Value::Number]
|
1187
|
+
# @param $saturation [Sass::Script::Value::Number]
|
1188
|
+
# @param $lightness [Sass::Script::Value::Number]
|
1189
|
+
# @param $alpha [Sass::Script::Value::Number]
|
1113
1190
|
# @return [Sass::Script::Value::Color]
|
1114
1191
|
# @raise [ArgumentError] if any parameter is the wrong type or out-of
|
1115
1192
|
# bounds, or if RGB properties and HSL properties are adjusted at the
|
@@ -1117,14 +1194,13 @@ module Sass::Script
|
|
1117
1194
|
def scale_color(color, kwargs)
|
1118
1195
|
assert_type color, :Color, :color
|
1119
1196
|
with = Sass::Util.map_hash(
|
1120
|
-
|
1121
|
-
|
1122
|
-
|
1123
|
-
|
1124
|
-
|
1125
|
-
|
1126
|
-
|
1127
|
-
|
1197
|
+
"red" => 255,
|
1198
|
+
"green" => 255,
|
1199
|
+
"blue" => 255,
|
1200
|
+
"saturation" => 100,
|
1201
|
+
"lightness" => 100,
|
1202
|
+
"alpha" => 1
|
1203
|
+
) do |name, max|
|
1128
1204
|
val = kwargs.delete(name)
|
1129
1205
|
next unless val
|
1130
1206
|
assert_type val, :Number, name
|
@@ -1159,35 +1235,49 @@ module Sass::Script
|
|
1159
1235
|
# change-color(#102030, $blue: 5) => #102005
|
1160
1236
|
# change-color(#102030, $red: 120, $blue: 5) => #782005
|
1161
1237
|
# change-color(hsl(25, 100%, 80%), $lightness: 40%, $alpha: 0.8) => hsla(25, 100%, 40%, 0.8)
|
1162
|
-
# @overload change_color($color, [$red], [$green], [$blue], [$hue],
|
1163
|
-
#
|
1164
|
-
#
|
1165
|
-
#
|
1166
|
-
#
|
1167
|
-
#
|
1168
|
-
#
|
1169
|
-
#
|
1170
|
-
#
|
1171
|
-
#
|
1172
|
-
#
|
1173
|
-
#
|
1174
|
-
#
|
1175
|
-
#
|
1176
|
-
#
|
1177
|
-
#
|
1178
|
-
# the color, within 0 and 1 inclusive
|
1238
|
+
# @overload change_color($color, [$red], [$green], [$blue], [$hue], [$saturation], [$lightness], [$alpha])
|
1239
|
+
# @param $color [Sass::Script::Value::Color]
|
1240
|
+
# @param $red [Sass::Script::Value::Number] The new red component for the
|
1241
|
+
# color, within 0 and 255 inclusive
|
1242
|
+
# @param $green [Sass::Script::Value::Number] The new green component for
|
1243
|
+
# the color, within 0 and 255 inclusive
|
1244
|
+
# @param $blue [Sass::Script::Value::Number] The new blue component for the
|
1245
|
+
# color, within 0 and 255 inclusive
|
1246
|
+
# @param $hue [Sass::Script::Value::Number] The new hue component for the
|
1247
|
+
# color, in degrees
|
1248
|
+
# @param $saturation [Sass::Script::Value::Number] The new saturation
|
1249
|
+
# component for the color, between `0%` and `100%` inclusive
|
1250
|
+
# @param $lightness [Sass::Script::Value::Number] The new lightness
|
1251
|
+
# component for the color, within `0%` and `100%` inclusive
|
1252
|
+
# @param $alpha [Sass::Script::Value::Number] The new alpha component for
|
1253
|
+
# the color, within 0 and 1 inclusive
|
1179
1254
|
# @return [Sass::Script::Value::Color]
|
1180
1255
|
# @raise [ArgumentError] if any parameter is the wrong type or out-of
|
1181
1256
|
# bounds, or if RGB properties and HSL properties are adjusted at the
|
1182
1257
|
# same time
|
1183
1258
|
def change_color(color, kwargs)
|
1184
1259
|
assert_type color, :Color, :color
|
1185
|
-
with = Sass::Util.
|
1260
|
+
with = Sass::Util.map_hash(
|
1261
|
+
'red' => ['Red value', 0..255],
|
1262
|
+
'green' => ['Green value', 0..255],
|
1263
|
+
'blue' => ['Blue value', 0..255],
|
1264
|
+
'hue' => [],
|
1265
|
+
'saturation' => ['Saturation', 0..100, '%'],
|
1266
|
+
'lightness' => ['Lightness', 0..100, '%'],
|
1267
|
+
'alpha' => ['Alpha channel', 0..1]
|
1268
|
+
) do |name, (desc, range, unit)|
|
1186
1269
|
val = kwargs.delete(name)
|
1187
1270
|
next unless val
|
1188
1271
|
assert_type val, :Number, name
|
1189
|
-
|
1190
|
-
|
1272
|
+
|
1273
|
+
if range
|
1274
|
+
val = Sass::Util.check_range(desc, range, val, unit)
|
1275
|
+
else
|
1276
|
+
val = val.value
|
1277
|
+
end
|
1278
|
+
|
1279
|
+
[name.to_sym, val]
|
1280
|
+
end
|
1191
1281
|
|
1192
1282
|
unless kwargs.empty?
|
1193
1283
|
name, val = kwargs.to_a.first
|
@@ -1212,11 +1302,11 @@ module Sass::Script
|
|
1212
1302
|
# mix(#f00, #00f, 25%) => #3f00bf
|
1213
1303
|
# mix(rgba(255, 0, 0, 0.5), #00f) => rgba(63, 0, 191, 0.75)
|
1214
1304
|
# @overload mix($color1, $color2, $weight: 50%)
|
1215
|
-
#
|
1216
|
-
#
|
1217
|
-
#
|
1218
|
-
#
|
1219
|
-
#
|
1305
|
+
# @param $color1 [Sass::Script::Value::Color]
|
1306
|
+
# @param $color2 [Sass::Script::Value::Color]
|
1307
|
+
# @param $weight [Sass::Script::Value::Number] The relative weight of each
|
1308
|
+
# color. Closer to `100%` gives more weight to `$color1`, closer to `0%`
|
1309
|
+
# gives more weight to `$color2`
|
1220
1310
|
# @return [Sass::Script::Value::Color]
|
1221
1311
|
# @raise [ArgumentError] if `$weight` is out of bounds or any parameter is
|
1222
1312
|
# the wrong type
|
@@ -1257,15 +1347,15 @@ module Sass::Script
|
|
1257
1347
|
rgba << color1.alpha * p + color2.alpha * (1 - p)
|
1258
1348
|
rgb_color(*rgba)
|
1259
1349
|
end
|
1260
|
-
declare :mix, [:color1, :color2]
|
1261
|
-
declare :mix, [:color1, :color2, :weight]
|
1350
|
+
declare :mix, [:color1, :color2]
|
1351
|
+
declare :mix, [:color1, :color2, :weight]
|
1262
1352
|
|
1263
1353
|
# Converts a color to grayscale. This is identical to `desaturate(color,
|
1264
1354
|
# 100%)`.
|
1265
1355
|
#
|
1266
1356
|
# @see #desaturate
|
1267
1357
|
# @overload grayscale($color)
|
1268
|
-
#
|
1358
|
+
# @param $color [Sass::Script::Value::Color]
|
1269
1359
|
# @return [Sass::Script::Value::Color]
|
1270
1360
|
# @raise [ArgumentError] if `$color` isn't a color
|
1271
1361
|
def grayscale(color)
|
@@ -1281,7 +1371,7 @@ module Sass::Script
|
|
1281
1371
|
#
|
1282
1372
|
# @see #adjust_hue #adjust-hue
|
1283
1373
|
# @overload complement($color)
|
1284
|
-
#
|
1374
|
+
# @param $color [Sass::Script::Value::Color]
|
1285
1375
|
# @return [Sass::Script::Value::Color]
|
1286
1376
|
# @raise [ArgumentError] if `$color` isn't a color
|
1287
1377
|
def complement(color)
|
@@ -1293,7 +1383,7 @@ module Sass::Script
|
|
1293
1383
|
# are inverted, while the opacity is left alone.
|
1294
1384
|
#
|
1295
1385
|
# @overload invert($color)
|
1296
|
-
#
|
1386
|
+
# @param $color [Sass::Script::Value::Color]
|
1297
1387
|
# @return [Sass::Script::Value::Color]
|
1298
1388
|
# @raise [ArgumentError] if `$color` isn't a color
|
1299
1389
|
def invert(color)
|
@@ -1317,15 +1407,31 @@ module Sass::Script
|
|
1317
1407
|
# unquote("foo") => foo
|
1318
1408
|
# unquote(foo) => foo
|
1319
1409
|
# @overload unquote($string)
|
1320
|
-
#
|
1410
|
+
# @param $string [Sass::Script::Value::String]
|
1321
1411
|
# @return [Sass::Script::Value::String]
|
1322
1412
|
# @raise [ArgumentError] if `$string` isn't a string
|
1323
1413
|
def unquote(string)
|
1324
|
-
|
1325
|
-
|
1326
|
-
|
1327
|
-
|
1414
|
+
unless string.is_a?(Sass::Script::Value::String)
|
1415
|
+
# Don't warn multiple times for the same source line.
|
1416
|
+
# rubocop:disable GlobalVars
|
1417
|
+
$_sass_warned_for_unquote ||= Set.new
|
1418
|
+
frame = environment.stack.frames.last
|
1419
|
+
key = [frame.filename, frame.line] if frame
|
1420
|
+
return string if frame && $_sass_warned_for_unquote.include?(key)
|
1421
|
+
$_sass_warned_for_unquote << key if frame
|
1422
|
+
# rubocop:enable GlobalVars
|
1423
|
+
|
1424
|
+
Sass::Util.sass_warn(<<MESSAGE.strip)
|
1425
|
+
DEPRECATION WARNING: Passing #{string.to_sass}, a non-string value, to unquote()
|
1426
|
+
will be an error in future versions of Sass.
|
1427
|
+
#{environment.stack.to_s.gsub(/^/, ' ' * 8)}
|
1428
|
+
MESSAGE
|
1429
|
+
return string
|
1328
1430
|
end
|
1431
|
+
|
1432
|
+
string.check_deprecated_interp
|
1433
|
+
return string if string.type == :identifier
|
1434
|
+
identifier(string.value)
|
1329
1435
|
end
|
1330
1436
|
declare :unquote, [:string]
|
1331
1437
|
|
@@ -1337,7 +1443,7 @@ module Sass::Script
|
|
1337
1443
|
# quote("foo") => "foo"
|
1338
1444
|
# quote(foo) => "foo"
|
1339
1445
|
# @overload quote($string)
|
1340
|
-
#
|
1446
|
+
# @param $string [Sass::Script::Value::String]
|
1341
1447
|
# @return [Sass::Script::Value::String]
|
1342
1448
|
# @raise [ArgumentError] if `$string` isn't a string
|
1343
1449
|
def quote(string)
|
@@ -1355,7 +1461,7 @@ module Sass::Script
|
|
1355
1461
|
# @example
|
1356
1462
|
# str-length("foo") => 3
|
1357
1463
|
# @overload str_length($string)
|
1358
|
-
#
|
1464
|
+
# @param $string [Sass::Script::Value::String]
|
1359
1465
|
# @return [Sass::Script::Value::Number]
|
1360
1466
|
# @raise [ArgumentError] if `$string` isn't a string
|
1361
1467
|
def str_length(string)
|
@@ -1375,12 +1481,12 @@ module Sass::Script
|
|
1375
1481
|
# str-insert("abcd", "X", 5) => "abcdX"
|
1376
1482
|
#
|
1377
1483
|
# @overload str_insert($string, $insert, $index)
|
1378
|
-
#
|
1379
|
-
#
|
1380
|
-
#
|
1381
|
-
#
|
1382
|
-
#
|
1383
|
-
#
|
1484
|
+
# @param $string [Sass::Script::Value::String]
|
1485
|
+
# @param $insert [Sass::Script::Value::String]
|
1486
|
+
# @param $index [Sass::Script::Value::Number] The position at which
|
1487
|
+
# `$insert` will be inserted. Negative indices count from the end of
|
1488
|
+
# `$string`. An index that's outside the bounds of the string will insert
|
1489
|
+
# `$insert` at the front or back of the string
|
1384
1490
|
# @return [Sass::Script::Value::String] The result string. This will be
|
1385
1491
|
# quoted if and only if `$string` was quoted
|
1386
1492
|
# @raise [ArgumentError] if any parameter is the wrong type
|
@@ -1389,18 +1495,18 @@ module Sass::Script
|
|
1389
1495
|
assert_type insert, :String, :insert
|
1390
1496
|
assert_integer index, :index
|
1391
1497
|
assert_unit index, nil, :index
|
1392
|
-
insertion_point = if index.
|
1393
|
-
[index.
|
1498
|
+
insertion_point = if index.to_i > 0
|
1499
|
+
[index.to_i - 1, original.value.size].min
|
1394
1500
|
else
|
1395
|
-
[index.
|
1501
|
+
[index.to_i, -original.value.size - 1].max
|
1396
1502
|
end
|
1397
1503
|
result = original.value.dup.insert(insertion_point, insert.value)
|
1398
1504
|
Sass::Script::Value::String.new(result, original.type)
|
1399
1505
|
end
|
1400
1506
|
declare :str_insert, [:string, :insert, :index]
|
1401
1507
|
|
1402
|
-
# Returns the index of the first
|
1403
|
-
# there is no such
|
1508
|
+
# Returns the index of the first occurrence of `$substring` in `$string`. If
|
1509
|
+
# there is no such occurrence, returns `null`.
|
1404
1510
|
#
|
1405
1511
|
# Note that unlike some languages, the first character in a Sass string is
|
1406
1512
|
# number 1, the second number 2, and so forth.
|
@@ -1412,8 +1518,8 @@ module Sass::Script
|
|
1412
1518
|
# str-index(abcd, c) => 3
|
1413
1519
|
#
|
1414
1520
|
# @overload str_index($string, $substring)
|
1415
|
-
#
|
1416
|
-
#
|
1521
|
+
# @param $string [Sass::Script::Value::String]
|
1522
|
+
# @param $substring [Sass::Script::Value::String]
|
1417
1523
|
# @return [Sass::Script::Value::Number, Sass::Script::Value::Null]
|
1418
1524
|
# @raise [ArgumentError] if any parameter is the wrong type
|
1419
1525
|
def str_index(string, substring)
|
@@ -1437,14 +1543,14 @@ module Sass::Script
|
|
1437
1543
|
# str-slice("abcd", 2, -2) => "bc"
|
1438
1544
|
#
|
1439
1545
|
# @overload str_slice($string, $start-at, $end-at: -1)
|
1440
|
-
#
|
1441
|
-
#
|
1442
|
-
#
|
1443
|
-
#
|
1444
|
-
#
|
1445
|
-
#
|
1446
|
-
#
|
1447
|
-
#
|
1546
|
+
# @param $start-at [Sass::Script::Value::Number] The index of the first
|
1547
|
+
# character of the substring. If this is negative, it counts from the end
|
1548
|
+
# of `$string`
|
1549
|
+
# @param $end-at [Sass::Script::Value::Number] The index of the last
|
1550
|
+
# character of the substring. If this is negative, it counts from the end
|
1551
|
+
# of `$string`. Defaults to -1
|
1552
|
+
# @return [Sass::Script::Value::String] The substring. This will be quoted
|
1553
|
+
# if and only if `$string` was quoted
|
1448
1554
|
# @raise [ArgumentError] if any parameter is the wrong type
|
1449
1555
|
def str_slice(string, start_at, end_at = nil)
|
1450
1556
|
assert_type string, :String, :string
|
@@ -1453,12 +1559,13 @@ module Sass::Script
|
|
1453
1559
|
end_at = number(-1) if end_at.nil?
|
1454
1560
|
assert_unit end_at, nil, "end-at"
|
1455
1561
|
|
1562
|
+
return Sass::Script::Value::String.new("", string.type) if end_at.value == 0
|
1456
1563
|
s = start_at.value > 0 ? start_at.value - 1 : start_at.value
|
1457
1564
|
e = end_at.value > 0 ? end_at.value - 1 : end_at.value
|
1458
1565
|
s = string.value.length + s if s < 0
|
1459
1566
|
s = 0 if s < 0
|
1460
1567
|
e = string.value.length + e if e < 0
|
1461
|
-
|
1568
|
+
return Sass::Script::Value::String.new("", string.type) if e < 0
|
1462
1569
|
extracted = string.value.slice(s..e)
|
1463
1570
|
Sass::Script::Value::String.new(extracted || "", string.type)
|
1464
1571
|
end
|
@@ -1471,12 +1578,12 @@ module Sass::Script
|
|
1471
1578
|
# to-upper-case(abcd) => ABCD
|
1472
1579
|
#
|
1473
1580
|
# @overload to_upper_case($string)
|
1474
|
-
#
|
1581
|
+
# @param $string [Sass::Script::Value::String]
|
1475
1582
|
# @return [Sass::Script::Value::String]
|
1476
1583
|
# @raise [ArgumentError] if `$string` isn't a string
|
1477
1584
|
def to_upper_case(string)
|
1478
1585
|
assert_type string, :String, :string
|
1479
|
-
Sass::Script::Value::String.new(string.value
|
1586
|
+
Sass::Script::Value::String.new(Sass::Util.upcase(string.value), string.type)
|
1480
1587
|
end
|
1481
1588
|
declare :to_upper_case, [:string]
|
1482
1589
|
|
@@ -1486,12 +1593,12 @@ module Sass::Script
|
|
1486
1593
|
# to-lower-case(ABCD) => abcd
|
1487
1594
|
#
|
1488
1595
|
# @overload to_lower_case($string)
|
1489
|
-
#
|
1596
|
+
# @param $string [Sass::Script::Value::String]
|
1490
1597
|
# @return [Sass::Script::Value::String]
|
1491
1598
|
# @raise [ArgumentError] if `$string` isn't a string
|
1492
1599
|
def to_lower_case(string)
|
1493
1600
|
assert_type string, :String, :string
|
1494
|
-
Sass::Script::Value::String.new(string.value
|
1601
|
+
Sass::Script::Value::String.new(Sass::Util.downcase(string.value), string.type)
|
1495
1602
|
end
|
1496
1603
|
declare :to_lower_case, [:string]
|
1497
1604
|
|
@@ -1504,23 +1611,40 @@ module Sass::Script
|
|
1504
1611
|
# type-of(true) => bool
|
1505
1612
|
# type-of(#fff) => color
|
1506
1613
|
# type-of(blue) => color
|
1614
|
+
# type-of(null) => null
|
1507
1615
|
# @overload type_of($value)
|
1508
|
-
#
|
1616
|
+
# @param $value [Sass::Script::Value::Base] The value to inspect
|
1509
1617
|
# @return [Sass::Script::Value::String] The unquoted string name of the
|
1510
1618
|
# value's type
|
1511
1619
|
def type_of(value)
|
1620
|
+
value.check_deprecated_interp if value.is_a?(Sass::Script::Value::String)
|
1512
1621
|
identifier(value.class.name.gsub(/Sass::Script::Value::/, '').downcase)
|
1513
1622
|
end
|
1514
1623
|
declare :type_of, [:value]
|
1515
1624
|
|
1516
1625
|
# Returns whether a feature exists in the current Sass runtime.
|
1517
1626
|
#
|
1627
|
+
# The following features are supported:
|
1628
|
+
#
|
1629
|
+
# * `global-variable-shadowing` indicates that a local variable will shadow
|
1630
|
+
# a global variable unless `!global` is used.
|
1631
|
+
#
|
1632
|
+
# * `extend-selector-pseudoclass` indicates that `@extend` will reach into
|
1633
|
+
# selector pseudoclasses like `:not`.
|
1634
|
+
#
|
1635
|
+
# * `units-level-3` indicates full support for unit arithmetic using units
|
1636
|
+
# defined in the [Values and Units Level 3][] spec.
|
1637
|
+
#
|
1638
|
+
# [Values and Units Level 3]: http://www.w3.org/TR/css3-values/
|
1639
|
+
#
|
1640
|
+
# * `at-error` indicates that the Sass `@error` directive is supported.
|
1641
|
+
#
|
1518
1642
|
# @example
|
1519
1643
|
# feature-exists(some-feature-that-exists) => true
|
1520
1644
|
# feature-exists(what-is-this-i-dont-know) => false
|
1521
1645
|
#
|
1522
1646
|
# @overload feature_exists($feature)
|
1523
|
-
#
|
1647
|
+
# @param $feature [Sass::Script::Value::String] The name of the feature
|
1524
1648
|
# @return [Sass::Script::Value::Bool] Whether the feature is supported in this version of Sass
|
1525
1649
|
# @raise [ArgumentError] if `$feature` isn't a string
|
1526
1650
|
def feature_exists(feature)
|
@@ -1539,7 +1663,7 @@ module Sass::Script
|
|
1539
1663
|
# unit(10px * 5em) => "em*px"
|
1540
1664
|
# unit(10px * 5em / 30cm / 1rem) => "em*px/cm*rem"
|
1541
1665
|
# @overload unit($number)
|
1542
|
-
#
|
1666
|
+
# @param $number [Sass::Script::Value::Number]
|
1543
1667
|
# @return [Sass::Script::Value::String] The unit(s) of the number, as a
|
1544
1668
|
# quoted string
|
1545
1669
|
# @raise [ArgumentError] if `$number` isn't a number
|
@@ -1555,7 +1679,7 @@ module Sass::Script
|
|
1555
1679
|
# unitless(100) => true
|
1556
1680
|
# unitless(100px) => false
|
1557
1681
|
# @overload unitless($number)
|
1558
|
-
#
|
1682
|
+
# @param $number [Sass::Script::Value::Number]
|
1559
1683
|
# @return [Sass::Script::Value::Bool]
|
1560
1684
|
# @raise [ArgumentError] if `$number` isn't a number
|
1561
1685
|
def unitless(number)
|
@@ -1571,8 +1695,8 @@ module Sass::Script
|
|
1571
1695
|
# comparable(100px, 3em) => false
|
1572
1696
|
# comparable(10cm, 3mm) => true
|
1573
1697
|
# @overload comparable($number1, $number2)
|
1574
|
-
#
|
1575
|
-
#
|
1698
|
+
# @param $number1 [Sass::Script::Value::Number]
|
1699
|
+
# @param $number2 [Sass::Script::Value::Number]
|
1576
1700
|
# @return [Sass::Script::Value::Bool]
|
1577
1701
|
# @raise [ArgumentError] if either parameter is the wrong type
|
1578
1702
|
def comparable(number1, number2)
|
@@ -1580,7 +1704,7 @@ module Sass::Script
|
|
1580
1704
|
assert_type number2, :Number, :number2
|
1581
1705
|
bool(number1.comparable_to?(number2))
|
1582
1706
|
end
|
1583
|
-
declare :comparable, [:number1, :number2]
|
1707
|
+
declare :comparable, [:number1, :number2]
|
1584
1708
|
|
1585
1709
|
# Converts a unitless number to a percentage.
|
1586
1710
|
#
|
@@ -1588,7 +1712,7 @@ module Sass::Script
|
|
1588
1712
|
# percentage(0.2) => 20%
|
1589
1713
|
# percentage(100px / 50px) => 200%
|
1590
1714
|
# @overload percentage($number)
|
1591
|
-
#
|
1715
|
+
# @param $number [Sass::Script::Value::Number]
|
1592
1716
|
# @return [Sass::Script::Value::Number]
|
1593
1717
|
# @raise [ArgumentError] if `$number` isn't a unitless number
|
1594
1718
|
def percentage(number)
|
@@ -1597,7 +1721,7 @@ module Sass::Script
|
|
1597
1721
|
end
|
1598
1722
|
number(number.value * 100, '%')
|
1599
1723
|
end
|
1600
|
-
declare :percentage, [:number]
|
1724
|
+
declare :percentage, [:number]
|
1601
1725
|
|
1602
1726
|
# Rounds a number to the nearest whole number.
|
1603
1727
|
#
|
@@ -1605,13 +1729,13 @@ module Sass::Script
|
|
1605
1729
|
# round(10.4px) => 10px
|
1606
1730
|
# round(10.6px) => 11px
|
1607
1731
|
# @overload round($number)
|
1608
|
-
#
|
1732
|
+
# @param $number [Sass::Script::Value::Number]
|
1609
1733
|
# @return [Sass::Script::Value::Number]
|
1610
1734
|
# @raise [ArgumentError] if `$number` isn't a number
|
1611
1735
|
def round(number)
|
1612
|
-
numeric_transformation(number) {|n|
|
1736
|
+
numeric_transformation(number) {|n| Sass::Util.round(n)}
|
1613
1737
|
end
|
1614
|
-
declare :round, [:number]
|
1738
|
+
declare :round, [:number]
|
1615
1739
|
|
1616
1740
|
# Rounds a number up to the next whole number.
|
1617
1741
|
#
|
@@ -1619,13 +1743,13 @@ module Sass::Script
|
|
1619
1743
|
# ceil(10.4px) => 11px
|
1620
1744
|
# ceil(10.6px) => 11px
|
1621
1745
|
# @overload ceil($number)
|
1622
|
-
#
|
1746
|
+
# @param $number [Sass::Script::Value::Number]
|
1623
1747
|
# @return [Sass::Script::Value::Number]
|
1624
1748
|
# @raise [ArgumentError] if `$number` isn't a number
|
1625
1749
|
def ceil(number)
|
1626
1750
|
numeric_transformation(number) {|n| n.ceil}
|
1627
1751
|
end
|
1628
|
-
declare :ceil, [:number]
|
1752
|
+
declare :ceil, [:number]
|
1629
1753
|
|
1630
1754
|
# Rounds a number down to the previous whole number.
|
1631
1755
|
#
|
@@ -1633,13 +1757,13 @@ module Sass::Script
|
|
1633
1757
|
# floor(10.4px) => 10px
|
1634
1758
|
# floor(10.6px) => 10px
|
1635
1759
|
# @overload floor($number)
|
1636
|
-
#
|
1760
|
+
# @param $number [Sass::Script::Value::Number]
|
1637
1761
|
# @return [Sass::Script::Value::Number]
|
1638
1762
|
# @raise [ArgumentError] if `$number` isn't a number
|
1639
1763
|
def floor(number)
|
1640
1764
|
numeric_transformation(number) {|n| n.floor}
|
1641
1765
|
end
|
1642
|
-
declare :floor, [:number]
|
1766
|
+
declare :floor, [:number]
|
1643
1767
|
|
1644
1768
|
# Returns the absolute value of a number.
|
1645
1769
|
#
|
@@ -1647,13 +1771,13 @@ module Sass::Script
|
|
1647
1771
|
# abs(10px) => 10px
|
1648
1772
|
# abs(-10px) => 10px
|
1649
1773
|
# @overload abs($number)
|
1650
|
-
#
|
1774
|
+
# @param $number [Sass::Script::Value::Number]
|
1651
1775
|
# @return [Sass::Script::Value::Number]
|
1652
1776
|
# @raise [ArgumentError] if `$number` isn't a number
|
1653
1777
|
def abs(number)
|
1654
1778
|
numeric_transformation(number) {|n| n.abs}
|
1655
1779
|
end
|
1656
|
-
declare :abs, [:number]
|
1780
|
+
declare :abs, [:number]
|
1657
1781
|
|
1658
1782
|
# Finds the minimum of several numbers. This function takes any number of
|
1659
1783
|
# arguments.
|
@@ -1662,7 +1786,7 @@ module Sass::Script
|
|
1662
1786
|
# min(1px, 4px) => 1px
|
1663
1787
|
# min(5em, 3em, 4em) => 3em
|
1664
1788
|
# @overload min($numbers...)
|
1665
|
-
#
|
1789
|
+
# @param $numbers [[Sass::Script::Value::Number]]
|
1666
1790
|
# @return [Sass::Script::Value::Number]
|
1667
1791
|
# @raise [ArgumentError] if any argument isn't a number, or if not all of
|
1668
1792
|
# the arguments have comparable units
|
@@ -1679,7 +1803,7 @@ module Sass::Script
|
|
1679
1803
|
# max(1px, 4px) => 4px
|
1680
1804
|
# max(5em, 3em, 4em) => 5em
|
1681
1805
|
# @overload max($numbers...)
|
1682
|
-
#
|
1806
|
+
# @param $numbers [[Sass::Script::Value::Number]]
|
1683
1807
|
# @return [Sass::Script::Value::Number]
|
1684
1808
|
# @raise [ArgumentError] if any argument isn't a number, or if not all of
|
1685
1809
|
# the arguments have comparable units
|
@@ -1698,7 +1822,7 @@ module Sass::Script
|
|
1698
1822
|
# length(10px 20px 30px) => 3
|
1699
1823
|
# length((width: 10px, height: 20px)) => 2
|
1700
1824
|
# @overload length($list)
|
1701
|
-
#
|
1825
|
+
# @param $list [Sass::Script::Value::Base]
|
1702
1826
|
# @return [Sass::Script::Value::Number]
|
1703
1827
|
def length(list)
|
1704
1828
|
number(list.to_a.size)
|
@@ -1717,11 +1841,11 @@ module Sass::Script
|
|
1717
1841
|
# @example
|
1718
1842
|
# set-nth($list: 10px 20px 30px, $n: 2, $value: -20px) => 10px -20px 30px
|
1719
1843
|
# @overload set-nth($list, $n, $value)
|
1720
|
-
#
|
1721
|
-
#
|
1722
|
-
#
|
1723
|
-
#
|
1724
|
-
#
|
1844
|
+
# @param $list [Sass::Script::Value::Base] The list that will be copied, having the element
|
1845
|
+
# at index `$n` changed.
|
1846
|
+
# @param $n [Sass::Script::Value::Number] The index of the item to set.
|
1847
|
+
# Negative indices count from the end of the list.
|
1848
|
+
# @param $value [Sass::Script::Value::Base] The new value at index `$n`.
|
1725
1849
|
# @return [Sass::Script::Value::List]
|
1726
1850
|
# @raise [ArgumentError] if `$n` isn't an integer between 1 and the length
|
1727
1851
|
# of `$list`
|
@@ -1750,9 +1874,9 @@ module Sass::Script
|
|
1750
1874
|
# nth((Helvetica, Arial, sans-serif), 3) => sans-serif
|
1751
1875
|
# nth((width: 10px, length: 20px), 2) => length, 20px
|
1752
1876
|
# @overload nth($list, $n)
|
1753
|
-
#
|
1754
|
-
#
|
1755
|
-
#
|
1877
|
+
# @param $list [Sass::Script::Value::Base]
|
1878
|
+
# @param $n [Sass::Script::Value::Number] The index of the item to get.
|
1879
|
+
# Negative indices count from the end of the list.
|
1756
1880
|
# @return [Sass::Script::Value::Base]
|
1757
1881
|
# @raise [ArgumentError] if `$n` isn't an integer between 1 and the length
|
1758
1882
|
# of `$list`
|
@@ -1772,6 +1896,9 @@ module Sass::Script
|
|
1772
1896
|
# list. If both lists have fewer than two items, spaces are used for the
|
1773
1897
|
# resulting list.
|
1774
1898
|
#
|
1899
|
+
# Like all list functions, `join()` returns a new list rather than modifying
|
1900
|
+
# its arguments in place.
|
1901
|
+
#
|
1775
1902
|
# @example
|
1776
1903
|
# join(10px 20px, 30px 40px) => 10px 20px 30px 40px
|
1777
1904
|
# join((blue, red), (#abc, #def)) => blue, red, #abc, #def
|
@@ -1779,15 +1906,15 @@ module Sass::Script
|
|
1779
1906
|
# join(10px, 20px, comma) => 10px, 20px
|
1780
1907
|
# join((blue, red), (#abc, #def), space) => blue red #abc #def
|
1781
1908
|
# @overload join($list1, $list2, $separator: auto)
|
1782
|
-
#
|
1783
|
-
#
|
1784
|
-
#
|
1785
|
-
#
|
1786
|
-
#
|
1909
|
+
# @param $list1 [Sass::Script::Value::Base]
|
1910
|
+
# @param $list2 [Sass::Script::Value::Base]
|
1911
|
+
# @param $separator [Sass::Script::Value::String] The list separator to use.
|
1912
|
+
# If this is `comma` or `space`, that separator will be used. If this is
|
1913
|
+
# `auto` (the default), the separator is determined as explained above.
|
1787
1914
|
# @return [Sass::Script::Value::List]
|
1788
1915
|
def join(list1, list2, separator = identifier("auto"))
|
1789
1916
|
assert_type separator, :String, :separator
|
1790
|
-
unless %w
|
1917
|
+
unless %w(auto space comma).include?(separator.value)
|
1791
1918
|
raise ArgumentError.new("Separator name must be space, comma, or auto")
|
1792
1919
|
end
|
1793
1920
|
sep = if separator.value == 'auto'
|
@@ -1805,6 +1932,9 @@ module Sass::Script
|
|
1805
1932
|
# Unless the `$separator` argument is passed, if the list had only one item,
|
1806
1933
|
# the resulting list will be space-separated.
|
1807
1934
|
#
|
1935
|
+
# Like all list functions, `append()` returns a new list rather than
|
1936
|
+
# modifying its argument in place.
|
1937
|
+
#
|
1808
1938
|
# @example
|
1809
1939
|
# append(10px 20px, 30px) => 10px 20px 30px
|
1810
1940
|
# append((blue, red), green) => blue, red, green
|
@@ -1812,15 +1942,15 @@ module Sass::Script
|
|
1812
1942
|
# append(10px, 20px, comma) => 10px, 20px
|
1813
1943
|
# append((blue, red), green, space) => blue red green
|
1814
1944
|
# @overload append($list, $val, $separator: auto)
|
1815
|
-
#
|
1816
|
-
#
|
1817
|
-
#
|
1818
|
-
#
|
1819
|
-
#
|
1945
|
+
# @param $list [Sass::Script::Value::Base]
|
1946
|
+
# @param $val [Sass::Script::Value::Base]
|
1947
|
+
# @param $separator [Sass::Script::Value::String] The list separator to use.
|
1948
|
+
# If this is `comma` or `space`, that separator will be used. If this is
|
1949
|
+
# `auto` (the default), the separator is determined as explained above.
|
1820
1950
|
# @return [Sass::Script::Value::List]
|
1821
1951
|
def append(list, val, separator = identifier("auto"))
|
1822
1952
|
assert_type separator, :String, :separator
|
1823
|
-
unless %w
|
1953
|
+
unless %w(auto space comma).include?(separator.value)
|
1824
1954
|
raise ArgumentError.new("Separator name must be space, comma, or auto")
|
1825
1955
|
end
|
1826
1956
|
sep = if separator.value == 'auto'
|
@@ -1844,7 +1974,7 @@ module Sass::Script
|
|
1844
1974
|
# zip(1px 1px 3px, solid dashed solid, red green blue)
|
1845
1975
|
# => 1px solid red, 1px dashed green, 3px solid blue
|
1846
1976
|
# @overload zip($lists...)
|
1847
|
-
#
|
1977
|
+
# @param $lists [[Sass::Script::Value::Base]]
|
1848
1978
|
# @return [Sass::Script::Value::List]
|
1849
1979
|
def zip(*lists)
|
1850
1980
|
length = nil
|
@@ -1873,16 +2003,15 @@ module Sass::Script
|
|
1873
2003
|
# @example
|
1874
2004
|
# index(1px solid red, solid) => 2
|
1875
2005
|
# index(1px solid red, dashed) => null
|
1876
|
-
# index((width: 10px, height: 20px), (height
|
2006
|
+
# index((width: 10px, height: 20px), (height 20px)) => 2
|
1877
2007
|
# @overload index($list, $value)
|
1878
|
-
#
|
1879
|
-
#
|
2008
|
+
# @param $list [Sass::Script::Value::Base]
|
2009
|
+
# @param $value [Sass::Script::Value::Base]
|
1880
2010
|
# @return [Sass::Script::Value::Number, Sass::Script::Value::Null] The
|
1881
2011
|
# 1-based index of `$value` in `$list`, or `null`
|
1882
2012
|
def index(list, value)
|
1883
2013
|
index = list.to_a.index {|e| e.eq(value).to_bool}
|
1884
|
-
|
1885
|
-
Sass::Script::Value::DeprecatedFalse.new(environment)
|
2014
|
+
index ? number(index + 1) : null
|
1886
2015
|
end
|
1887
2016
|
declare :index, [:list, :value]
|
1888
2017
|
|
@@ -1894,7 +2023,7 @@ module Sass::Script
|
|
1894
2023
|
# list-separator(1px, 2px, 3px) => comma
|
1895
2024
|
# list-separator('foo') => space
|
1896
2025
|
# @overload list_separator($list)
|
1897
|
-
#
|
2026
|
+
# @param $list [Sass::Script::Value::Base]
|
1898
2027
|
# @return [Sass::Script::Value::String] `comma` or `space`
|
1899
2028
|
def list_separator(list)
|
1900
2029
|
identifier((list.separator || :space).to_s)
|
@@ -1909,14 +2038,14 @@ module Sass::Script
|
|
1909
2038
|
# map-get(("foo": 1, "bar": 2), "bar") => 2
|
1910
2039
|
# map-get(("foo": 1, "bar": 2), "baz") => null
|
1911
2040
|
# @overload map_get($map, $key)
|
1912
|
-
#
|
1913
|
-
#
|
2041
|
+
# @param $map [Sass::Script::Value::Map]
|
2042
|
+
# @param $key [Sass::Script::Value::Base]
|
1914
2043
|
# @return [Sass::Script::Value::Base] The value indexed by `$key`, or `null`
|
1915
2044
|
# if the map doesn't contain the given key
|
1916
2045
|
# @raise [ArgumentError] if `$map` is not a map
|
1917
2046
|
def map_get(map, key)
|
1918
2047
|
assert_type map, :Map, :map
|
1919
|
-
to_h
|
2048
|
+
map.to_h[key] || null
|
1920
2049
|
end
|
1921
2050
|
declare :map_get, [:map, :key]
|
1922
2051
|
|
@@ -1929,50 +2058,57 @@ module Sass::Script
|
|
1929
2058
|
# same order as in `$map1`. New keys from `$map2` will be placed at the end
|
1930
2059
|
# of the map.
|
1931
2060
|
#
|
2061
|
+
# Like all map functions, `map-merge()` returns a new map rather than
|
2062
|
+
# modifying its arguments in place.
|
2063
|
+
#
|
1932
2064
|
# @example
|
1933
2065
|
# map-merge(("foo": 1), ("bar": 2)) => ("foo": 1, "bar": 2)
|
1934
2066
|
# map-merge(("foo": 1, "bar": 2), ("bar": 3)) => ("foo": 1, "bar": 3)
|
1935
2067
|
# @overload map_merge($map1, $map2)
|
1936
|
-
#
|
1937
|
-
#
|
2068
|
+
# @param $map1 [Sass::Script::Value::Map]
|
2069
|
+
# @param $map2 [Sass::Script::Value::Map]
|
1938
2070
|
# @return [Sass::Script::Value::Map]
|
1939
2071
|
# @raise [ArgumentError] if either parameter is not a map
|
1940
2072
|
def map_merge(map1, map2)
|
1941
2073
|
assert_type map1, :Map, :map1
|
1942
2074
|
assert_type map2, :Map, :map2
|
1943
|
-
map(
|
2075
|
+
map(map1.to_h.merge(map2.to_h))
|
1944
2076
|
end
|
1945
2077
|
declare :map_merge, [:map1, :map2]
|
1946
2078
|
|
1947
|
-
# Returns a new map with
|
2079
|
+
# Returns a new map with keys removed.
|
2080
|
+
#
|
2081
|
+
# Like all map functions, `map-merge()` returns a new map rather than
|
2082
|
+
# modifying its arguments in place.
|
1948
2083
|
#
|
1949
2084
|
# @example
|
1950
2085
|
# map-remove(("foo": 1, "bar": 2), "bar") => ("foo": 1)
|
2086
|
+
# map-remove(("foo": 1, "bar": 2, "baz": 3), "bar", "baz") => ("foo": 1)
|
1951
2087
|
# map-remove(("foo": 1, "bar": 2), "baz") => ("foo": 1, "bar": 2)
|
1952
|
-
# @overload map_remove($map, $
|
1953
|
-
#
|
1954
|
-
#
|
2088
|
+
# @overload map_remove($map, $keys...)
|
2089
|
+
# @param $map [Sass::Script::Value::Map]
|
2090
|
+
# @param $keys [[Sass::Script::Value::Base]]
|
1955
2091
|
# @return [Sass::Script::Value::Map]
|
1956
2092
|
# @raise [ArgumentError] if `$map` is not a map
|
1957
|
-
def map_remove(map,
|
2093
|
+
def map_remove(map, *keys)
|
1958
2094
|
assert_type map, :Map, :map
|
1959
|
-
hash =
|
1960
|
-
hash.
|
2095
|
+
hash = map.to_h.dup
|
2096
|
+
hash.delete_if {|key, _| keys.include?(key)}
|
1961
2097
|
map(hash)
|
1962
2098
|
end
|
1963
|
-
declare :map_remove, [:map, :key]
|
2099
|
+
declare :map_remove, [:map, :key], :var_args => true
|
1964
2100
|
|
1965
2101
|
# Returns a list of all keys in a map.
|
1966
2102
|
#
|
1967
2103
|
# @example
|
1968
2104
|
# map-keys(("foo": 1, "bar": 2)) => "foo", "bar"
|
1969
2105
|
# @overload map_keys($map)
|
1970
|
-
#
|
2106
|
+
# @param $map [Map]
|
1971
2107
|
# @return [List] the list of keys, comma-separated
|
1972
2108
|
# @raise [ArgumentError] if `$map` is not a map
|
1973
2109
|
def map_keys(map)
|
1974
2110
|
assert_type map, :Map, :map
|
1975
|
-
list(
|
2111
|
+
list(map.to_h.keys, :comma)
|
1976
2112
|
end
|
1977
2113
|
declare :map_keys, [:map]
|
1978
2114
|
|
@@ -1983,12 +2119,12 @@ module Sass::Script
|
|
1983
2119
|
# map-values(("foo": 1, "bar": 2)) => 1, 2
|
1984
2120
|
# map-values(("foo": 1, "bar": 2, "baz": 1)) => 1, 2, 1
|
1985
2121
|
# @overload map_values($map)
|
1986
|
-
#
|
2122
|
+
# @param $map [Map]
|
1987
2123
|
# @return [List] the list of values, comma-separated
|
1988
2124
|
# @raise [ArgumentError] if `$map` is not a map
|
1989
2125
|
def map_values(map)
|
1990
2126
|
assert_type map, :Map, :map
|
1991
|
-
list(
|
2127
|
+
list(map.to_h.values, :comma)
|
1992
2128
|
end
|
1993
2129
|
declare :map_values, [:map]
|
1994
2130
|
|
@@ -1998,13 +2134,13 @@ module Sass::Script
|
|
1998
2134
|
# map-has-key(("foo": 1, "bar": 2), "foo") => true
|
1999
2135
|
# map-has-key(("foo": 1, "bar": 2), "baz") => false
|
2000
2136
|
# @overload map_has_key($map, $key)
|
2001
|
-
#
|
2002
|
-
#
|
2137
|
+
# @param $map [Sass::Script::Value::Map]
|
2138
|
+
# @param $key [Sass::Script::Value::Base]
|
2003
2139
|
# @return [Sass::Script::Value::Bool]
|
2004
2140
|
# @raise [ArgumentError] if `$map` is not a map
|
2005
2141
|
def map_has_key(map, key)
|
2006
2142
|
assert_type map, :Map, :map
|
2007
|
-
bool(
|
2143
|
+
bool(map.to_h.has_key?(key))
|
2008
2144
|
end
|
2009
2145
|
declare :map_has_key, [:map, :key]
|
2010
2146
|
|
@@ -2019,12 +2155,12 @@ module Sass::Script
|
|
2019
2155
|
#
|
2020
2156
|
# @include foo($arg1: val, $arg2: val);
|
2021
2157
|
# @overload keywords($args)
|
2022
|
-
#
|
2158
|
+
# @param $args [Sass::Script::Value::ArgList]
|
2023
2159
|
# @return [Sass::Script::Value::Map]
|
2024
2160
|
# @raise [ArgumentError] if `$args` isn't a variable argument list
|
2025
2161
|
def keywords(args)
|
2026
2162
|
assert_type args, :ArgList, :args
|
2027
|
-
map(Sass::Util.map_keys(args.keywords.as_stored) {|k| Sass::Script::String.new(k)})
|
2163
|
+
map(Sass::Util.map_keys(args.keywords.as_stored) {|k| Sass::Script::Value::String.new(k)})
|
2028
2164
|
end
|
2029
2165
|
declare :keywords, [:args]
|
2030
2166
|
|
@@ -2036,10 +2172,10 @@ module Sass::Script
|
|
2036
2172
|
# if(true, 1px, 2px) => 1px
|
2037
2173
|
# if(false, 1px, 2px) => 2px
|
2038
2174
|
# @overload if($condition, $if-true, $if-false)
|
2039
|
-
#
|
2040
|
-
#
|
2041
|
-
#
|
2042
|
-
#
|
2175
|
+
# @param $condition [Sass::Script::Value::Base] Whether the `$if-true` or
|
2176
|
+
# `$if-false` will be returned
|
2177
|
+
# @param $if-true [Sass::Script::Tree::Node]
|
2178
|
+
# @param $if-false [Sass::Script::Tree::Node]
|
2043
2179
|
# @return [Sass::Script::Value::Base] `$if-true` or `$if-false`
|
2044
2180
|
def if(condition, if_true, if_false)
|
2045
2181
|
if condition.to_bool
|
@@ -2076,10 +2212,10 @@ module Sass::Script
|
|
2076
2212
|
# call(scale-color, #0a64ff, $lightness: -10%) => #0058ef
|
2077
2213
|
#
|
2078
2214
|
# $fn: nth;
|
2079
|
-
# call($fn,
|
2215
|
+
# call($fn, (a b c), 2) => b
|
2080
2216
|
#
|
2081
2217
|
# @overload call($name, $args...)
|
2082
|
-
#
|
2218
|
+
# @param $name [String] The name of the function to call.
|
2083
2219
|
def call(name, *args)
|
2084
2220
|
assert_type name, :String, :name
|
2085
2221
|
kwargs = args.last.is_a?(Hash) ? args.pop : {}
|
@@ -2094,31 +2230,29 @@ module Sass::Script
|
|
2094
2230
|
end
|
2095
2231
|
declare :call, [:name], :var_args => true, :var_kwargs => true
|
2096
2232
|
|
2097
|
-
# This function only exists as a workaround for IE7's [`content:
|
2098
|
-
# bug]
|
2233
|
+
# This function only exists as a workaround for IE7's [`content:
|
2234
|
+
# counter` bug](http://jes.st/2013/ie7s-css-breaking-content-counter-bug/).
|
2235
|
+
# It works identically to any other plain-CSS function, except it
|
2099
2236
|
# avoids adding spaces between the argument commas.
|
2100
2237
|
#
|
2101
|
-
# [bug]: http://jes.st/2013/ie7s-css-breaking-content-counter-bug/
|
2102
|
-
#
|
2103
2238
|
# @example
|
2104
2239
|
# counter(item, ".") => counter(item,".")
|
2105
2240
|
# @overload counter($args...)
|
2106
|
-
# @return [String]
|
2241
|
+
# @return [Sass::Script::Value::String]
|
2107
2242
|
def counter(*args)
|
2108
2243
|
identifier("counter(#{args.map {|a| a.to_s(options)}.join(',')})")
|
2109
2244
|
end
|
2110
2245
|
declare :counter, [], :var_args => true
|
2111
2246
|
|
2112
|
-
# This function only exists as a workaround for IE7's [`content:
|
2113
|
-
# bug]
|
2247
|
+
# This function only exists as a workaround for IE7's [`content:
|
2248
|
+
# counter` bug](http://jes.st/2013/ie7s-css-breaking-content-counter-bug/).
|
2249
|
+
# It works identically to any other plain-CSS function, except it
|
2114
2250
|
# avoids adding spaces between the argument commas.
|
2115
2251
|
#
|
2116
|
-
# [bug]: http://jes.st/2013/ie7s-css-breaking-content-counter-bug/
|
2117
|
-
#
|
2118
2252
|
# @example
|
2119
2253
|
# counters(item, ".") => counters(item,".")
|
2120
2254
|
# @overload counters($args...)
|
2121
|
-
# @return [String]
|
2255
|
+
# @return [Sass::Script::Value::String]
|
2122
2256
|
def counters(*args)
|
2123
2257
|
identifier("counters(#{args.map {|a| a.to_s(options)}.join(',')})")
|
2124
2258
|
end
|
@@ -2130,11 +2264,14 @@ module Sass::Script
|
|
2130
2264
|
# @example
|
2131
2265
|
# $a-false-value: false;
|
2132
2266
|
# variable-exists(a-false-value) => true
|
2267
|
+
# variable-exists(a-null-value) => true
|
2133
2268
|
#
|
2134
2269
|
# variable-exists(nonexistent) => false
|
2135
|
-
#
|
2136
|
-
#
|
2137
|
-
#
|
2270
|
+
#
|
2271
|
+
# @overload variable_exists($name)
|
2272
|
+
# @param $name [Sass::Script::Value::String] The name of the variable to
|
2273
|
+
# check. The name should not include the `$`.
|
2274
|
+
# @return [Sass::Script::Value::Bool] Whether the variable is defined in
|
2138
2275
|
# the current scope.
|
2139
2276
|
def variable_exists(name)
|
2140
2277
|
assert_type name, :String, :name
|
@@ -2148,14 +2285,17 @@ module Sass::Script
|
|
2148
2285
|
# @example
|
2149
2286
|
# $a-false-value: false;
|
2150
2287
|
# global-variable-exists(a-false-value) => true
|
2288
|
+
# global-variable-exists(a-null-value) => true
|
2151
2289
|
#
|
2152
2290
|
# .foo {
|
2153
2291
|
# $some-var: false;
|
2154
2292
|
# @if global-variable-exists(some-var) { /* false, doesn't run */ }
|
2155
2293
|
# }
|
2156
|
-
#
|
2157
|
-
#
|
2158
|
-
#
|
2294
|
+
#
|
2295
|
+
# @overload global_variable_exists($name)
|
2296
|
+
# @param $name [Sass::Script::Value::String] The name of the variable to
|
2297
|
+
# check. The name should not include the `$`.
|
2298
|
+
# @return [Sass::Script::Value::Bool] Whether the variable is defined in
|
2159
2299
|
# the global scope.
|
2160
2300
|
def global_variable_exists(name)
|
2161
2301
|
assert_type name, :String, :name
|
@@ -2170,9 +2310,11 @@ module Sass::Script
|
|
2170
2310
|
#
|
2171
2311
|
# @function myfunc { @return "something"; }
|
2172
2312
|
# function-exists(myfunc) => true
|
2173
|
-
#
|
2174
|
-
#
|
2175
|
-
#
|
2313
|
+
#
|
2314
|
+
# @overload function_exists($name)
|
2315
|
+
# @param name [Sass::Script::Value::String] The name of the function to
|
2316
|
+
# check.
|
2317
|
+
# @return [Sass::Script::Value::Bool] Whether the function is defined.
|
2176
2318
|
def function_exists(name)
|
2177
2319
|
assert_type name, :String, :name
|
2178
2320
|
exists = Sass::Script::Functions.callable?(name.value.tr("-", "_"))
|
@@ -2188,9 +2330,11 @@ module Sass::Script
|
|
2188
2330
|
#
|
2189
2331
|
# @mixin red-text { color: red; }
|
2190
2332
|
# mixin-exists(red-text) => true
|
2191
|
-
#
|
2192
|
-
#
|
2193
|
-
#
|
2333
|
+
#
|
2334
|
+
# @overload mixin_exists($name)
|
2335
|
+
# @param name [Sass::Script::Value::String] The name of the mixin to
|
2336
|
+
# check.
|
2337
|
+
# @return [Sass::Script::Value::Bool] Whether the mixin is defined.
|
2194
2338
|
def mixin_exists(name)
|
2195
2339
|
assert_type name, :String, :name
|
2196
2340
|
bool(environment.mixin(name.value))
|
@@ -2199,31 +2343,33 @@ module Sass::Script
|
|
2199
2343
|
|
2200
2344
|
# Return a string containing the value as its Sass representation.
|
2201
2345
|
#
|
2202
|
-
# @
|
2203
|
-
#
|
2346
|
+
# @overload inspect($value)
|
2347
|
+
# @param $value [Sass::Script::Value::Base] The value to inspect.
|
2348
|
+
# @return [Sass::Script::Value::String] A representation of the value as
|
2204
2349
|
# it would be written in Sass.
|
2205
2350
|
def inspect(value)
|
2351
|
+
value.check_deprecated_interp if value.is_a?(Sass::Script::Value::String)
|
2206
2352
|
unquoted_string(value.to_sass)
|
2207
2353
|
end
|
2208
2354
|
declare :inspect, [:value]
|
2209
2355
|
|
2210
2356
|
# @overload random()
|
2211
2357
|
# Return a decimal between 0 and 1, inclusive of 0 but not 1.
|
2212
|
-
# @return [Sass::Script::Number] A decimal value.
|
2358
|
+
# @return [Sass::Script::Value::Number] A decimal value.
|
2213
2359
|
# @overload random($limit)
|
2214
|
-
# Return an integer between 1 and `$limit`, inclusive of 1
|
2360
|
+
# Return an integer between 1 and `$limit`, inclusive of both 1 and `$limit`.
|
2215
2361
|
# @param $limit [Sass::Script::Value::Number] The maximum of the random integer to be
|
2216
2362
|
# returned, a positive integer.
|
2217
|
-
# @return [Sass::Script::Number] An integer.
|
2363
|
+
# @return [Sass::Script::Value::Number] An integer.
|
2218
2364
|
# @raise [ArgumentError] if the `$limit` is not 1 or greater
|
2219
2365
|
def random(limit = nil)
|
2220
2366
|
generator = Sass::Script::Functions.random_number_generator
|
2221
2367
|
if limit
|
2222
2368
|
assert_integer limit, "limit"
|
2223
|
-
if limit.
|
2369
|
+
if limit.to_i < 1
|
2224
2370
|
raise ArgumentError.new("$limit #{limit} must be greater than or equal to 1")
|
2225
2371
|
end
|
2226
|
-
number(1 + generator.rand(limit.
|
2372
|
+
number(1 + generator.rand(limit.to_i))
|
2227
2373
|
else
|
2228
2374
|
number(generator.rand)
|
2229
2375
|
end
|
@@ -2231,6 +2377,281 @@ module Sass::Script
|
|
2231
2377
|
declare :random, []
|
2232
2378
|
declare :random, [:limit]
|
2233
2379
|
|
2380
|
+
# Parses a user-provided selector into a list of lists of strings
|
2381
|
+
# as returned by `&`.
|
2382
|
+
#
|
2383
|
+
# @example
|
2384
|
+
# selector-parse(".foo .bar, .baz .bang") => ('.foo' '.bar', '.baz' '.bang')
|
2385
|
+
#
|
2386
|
+
# @overload selector_parse($selector)
|
2387
|
+
# @param $selector [Sass::Script::Value::String, Sass::Script::Value::List]
|
2388
|
+
# The selector to parse. This can be either a string, a list of
|
2389
|
+
# strings, or a list of lists of strings as returned by `&`.
|
2390
|
+
# @return [Sass::Script::Value::List]
|
2391
|
+
# A list of lists of strings representing `$selector`. This is
|
2392
|
+
# in the same format as a selector returned by `&`.
|
2393
|
+
def selector_parse(selector)
|
2394
|
+
parse_selector(selector, :selector).to_sass_script
|
2395
|
+
end
|
2396
|
+
declare :selector_parse, [:selector]
|
2397
|
+
|
2398
|
+
# Return a new selector with all selectors in `$selectors` nested beneath
|
2399
|
+
# one another as though they had been nested in the stylesheet as
|
2400
|
+
# `$selector1 { $selector2 { ... } }`.
|
2401
|
+
#
|
2402
|
+
# Unlike most selector functions, `selector-nest` allows the
|
2403
|
+
# parent selector `&` to be used in any selector but the first.
|
2404
|
+
#
|
2405
|
+
# @example
|
2406
|
+
# selector-nest(".foo", ".bar", ".baz") => .foo .bar .baz
|
2407
|
+
# selector-nest(".a .foo", ".b .bar") => .a .foo .b .bar
|
2408
|
+
# selector-nest(".foo", "&.bar") => .foo.bar
|
2409
|
+
#
|
2410
|
+
# @overload selector_nest($selectors...)
|
2411
|
+
# @param $selectors [[Sass::Script::Value::String, Sass::Script::Value::List]]
|
2412
|
+
# The selectors to nest. At least one selector must be passed. Each of
|
2413
|
+
# these can be either a string, a list of strings, or a list of lists of
|
2414
|
+
# strings as returned by `&`.
|
2415
|
+
# @return [Sass::Script::Value::List]
|
2416
|
+
# A list of lists of strings representing the result of nesting
|
2417
|
+
# `$selectors`. This is in the same format as a selector returned by
|
2418
|
+
# `&`.
|
2419
|
+
def selector_nest(*selectors)
|
2420
|
+
if selectors.empty?
|
2421
|
+
raise ArgumentError.new("$selectors: At least one selector must be passed")
|
2422
|
+
end
|
2423
|
+
|
2424
|
+
parsed = [parse_selector(selectors.first, :selectors)]
|
2425
|
+
parsed += selectors[1..-1].map {|sel| parse_selector(sel, :selectors, true)}
|
2426
|
+
parsed.inject {|result, child| child.resolve_parent_refs(result)}.to_sass_script
|
2427
|
+
end
|
2428
|
+
declare :selector_nest, [], :var_args => true
|
2429
|
+
|
2430
|
+
# Return a new selector with all selectors in `$selectors` appended one
|
2431
|
+
# another as though they had been nested in the stylesheet as `$selector1 {
|
2432
|
+
# &$selector2 { ... } }`.
|
2433
|
+
#
|
2434
|
+
# @example
|
2435
|
+
# selector-append(".foo", ".bar", ".baz") => .foo.bar.baz
|
2436
|
+
# selector-append(".a .foo", ".b .bar") => "a .foo.b .bar"
|
2437
|
+
# selector-append(".foo", "-suffix") => ".foo-suffix"
|
2438
|
+
#
|
2439
|
+
# @overload selector_append($selectors...)
|
2440
|
+
# @param $selectors [[Sass::Script::Value::String, Sass::Script::Value::List]]
|
2441
|
+
# The selectors to append. At least one selector must be passed. Each of
|
2442
|
+
# these can be either a string, a list of strings, or a list of lists of
|
2443
|
+
# strings as returned by `&`.
|
2444
|
+
# @return [Sass::Script::Value::List]
|
2445
|
+
# A list of lists of strings representing the result of appending
|
2446
|
+
# `$selectors`. This is in the same format as a selector returned by
|
2447
|
+
# `&`.
|
2448
|
+
# @raise [ArgumentError] if a selector could not be appended.
|
2449
|
+
def selector_append(*selectors)
|
2450
|
+
if selectors.empty?
|
2451
|
+
raise ArgumentError.new("$selectors: At least one selector must be passed")
|
2452
|
+
end
|
2453
|
+
|
2454
|
+
selectors.map {|sel| parse_selector(sel, :selectors)}.inject do |parent, child|
|
2455
|
+
child.members.each do |seq|
|
2456
|
+
sseq = seq.members.first
|
2457
|
+
unless sseq.is_a?(Sass::Selector::SimpleSequence)
|
2458
|
+
raise ArgumentError.new("Can't append \"#{seq}\" to \"#{parent}\"")
|
2459
|
+
end
|
2460
|
+
|
2461
|
+
base = sseq.base
|
2462
|
+
case base
|
2463
|
+
when Sass::Selector::Universal
|
2464
|
+
raise ArgumentError.new("Can't append \"#{seq}\" to \"#{parent}\"")
|
2465
|
+
when Sass::Selector::Element
|
2466
|
+
unless base.namespace.nil?
|
2467
|
+
raise ArgumentError.new("Can't append \"#{seq}\" to \"#{parent}\"")
|
2468
|
+
end
|
2469
|
+
sseq.members[0] = Sass::Selector::Parent.new(base.name)
|
2470
|
+
else
|
2471
|
+
sseq.members.unshift Sass::Selector::Parent.new
|
2472
|
+
end
|
2473
|
+
end
|
2474
|
+
child.resolve_parent_refs(parent)
|
2475
|
+
end.to_sass_script
|
2476
|
+
end
|
2477
|
+
declare :selector_append, [], :var_args => true
|
2478
|
+
|
2479
|
+
# Returns a new version of `$selector` with `$extendee` extended
|
2480
|
+
# with `$extender`. This works just like the result of
|
2481
|
+
#
|
2482
|
+
# $selector { ... }
|
2483
|
+
# $extender { @extend $extendee }
|
2484
|
+
#
|
2485
|
+
# @example
|
2486
|
+
# selector-extend(".a .b", ".b", ".foo .bar") => .a .b, .a .foo .bar, .foo .a .bar
|
2487
|
+
#
|
2488
|
+
# @overload selector_extend($selector, $extendee, $extender)
|
2489
|
+
# @param $selector [Sass::Script::Value::String, Sass::Script::Value::List]
|
2490
|
+
# The selector within which `$extendee` is extended with
|
2491
|
+
# `$extender`. This can be either a string, a list of strings,
|
2492
|
+
# or a list of lists of strings as returned by `&`.
|
2493
|
+
# @param $extendee [Sass::Script::Value::String, Sass::Script::Value::List]
|
2494
|
+
# The selector being extended. This can be either a string, a
|
2495
|
+
# list of strings, or a list of lists of strings as returned
|
2496
|
+
# by `&`.
|
2497
|
+
# @param $extender [Sass::Script::Value::String, Sass::Script::Value::List]
|
2498
|
+
# The selector being injected into `$selector`. This can be
|
2499
|
+
# either a string, a list of strings, or a list of lists of
|
2500
|
+
# strings as returned by `&`.
|
2501
|
+
# @return [Sass::Script::Value::List]
|
2502
|
+
# A list of lists of strings representing the result of the
|
2503
|
+
# extension. This is in the same format as a selector returned
|
2504
|
+
# by `&`.
|
2505
|
+
# @raise [ArgumentError] if the extension fails
|
2506
|
+
def selector_extend(selector, extendee, extender)
|
2507
|
+
selector = parse_selector(selector, :selector)
|
2508
|
+
extendee = parse_selector(extendee, :extendee)
|
2509
|
+
extender = parse_selector(extender, :extender)
|
2510
|
+
|
2511
|
+
extends = Sass::Util::SubsetMap.new
|
2512
|
+
begin
|
2513
|
+
extender.populate_extends(extends, extendee, nil, [], true)
|
2514
|
+
selector.do_extend(extends).to_sass_script
|
2515
|
+
rescue Sass::SyntaxError => e
|
2516
|
+
raise ArgumentError.new(e.to_s)
|
2517
|
+
end
|
2518
|
+
end
|
2519
|
+
declare :selector_extend, [:selector, :extendee, :extender]
|
2520
|
+
|
2521
|
+
# Replaces all instances of `$original` with `$replacement` in `$selector`
|
2522
|
+
#
|
2523
|
+
# This works by using `@extend` and throwing away the original
|
2524
|
+
# selector. This means that it can be used to do very advanced
|
2525
|
+
# replacements; see the examples below.
|
2526
|
+
#
|
2527
|
+
# @example
|
2528
|
+
# selector-replace(".foo .bar", ".bar", ".baz") => ".foo .baz"
|
2529
|
+
# selector-replace(".foo.bar.baz", ".foo.baz", ".qux") => ".bar.qux"
|
2530
|
+
#
|
2531
|
+
# @overload selector_replace($selector, $original, $replacement)
|
2532
|
+
# @param $selector [Sass::Script::Value::String, Sass::Script::Value::List]
|
2533
|
+
# The selector within which `$original` is replaced with
|
2534
|
+
# `$replacement`. This can be either a string, a list of
|
2535
|
+
# strings, or a list of lists of strings as returned by `&`.
|
2536
|
+
# @param $original [Sass::Script::Value::String, Sass::Script::Value::List]
|
2537
|
+
# The selector being replaced. This can be either a string, a
|
2538
|
+
# list of strings, or a list of lists of strings as returned
|
2539
|
+
# by `&`.
|
2540
|
+
# @param $replacement [Sass::Script::Value::String, Sass::Script::Value::List]
|
2541
|
+
# The selector that `$original` is being replaced with. This
|
2542
|
+
# can be either a string, a list of strings, or a list of
|
2543
|
+
# lists of strings as returned by `&`.
|
2544
|
+
# @return [Sass::Script::Value::List]
|
2545
|
+
# A list of lists of strings representing the result of the
|
2546
|
+
# extension. This is in the same format as a selector returned
|
2547
|
+
# by `&`.
|
2548
|
+
# @raise [ArgumentError] if the replacement fails
|
2549
|
+
def selector_replace(selector, original, replacement)
|
2550
|
+
selector = parse_selector(selector, :selector)
|
2551
|
+
original = parse_selector(original, :original)
|
2552
|
+
replacement = parse_selector(replacement, :replacement)
|
2553
|
+
|
2554
|
+
extends = Sass::Util::SubsetMap.new
|
2555
|
+
begin
|
2556
|
+
replacement.populate_extends(extends, original, nil, [], true)
|
2557
|
+
selector.do_extend(extends, [], true).to_sass_script
|
2558
|
+
rescue Sass::SyntaxError => e
|
2559
|
+
raise ArgumentError.new(e.to_s)
|
2560
|
+
end
|
2561
|
+
end
|
2562
|
+
declare :selector_replace, [:selector, :original, :replacement]
|
2563
|
+
|
2564
|
+
# Unifies two selectors into a single selector that matches only
|
2565
|
+
# elements matched by both input selectors. Returns `null` if
|
2566
|
+
# there is no such selector.
|
2567
|
+
#
|
2568
|
+
# Like the selector unification done for `@extend`, this doesn't
|
2569
|
+
# guarantee that the output selector will match *all* elements
|
2570
|
+
# matched by both input selectors. For example, if `.a .b` is
|
2571
|
+
# unified with `.x .y`, `.a .x .b.y, .x .a .b.y` will be returned,
|
2572
|
+
# but `.a.x .b.y` will not. This avoids exponential output size
|
2573
|
+
# while matching all elements that are likely to exist in
|
2574
|
+
# practice.
|
2575
|
+
#
|
2576
|
+
# @example
|
2577
|
+
# selector-unify(".a", ".b") => .a.b
|
2578
|
+
# selector-unify(".a .b", ".x .y") => .a .x .b.y, .x .a .b.y
|
2579
|
+
# selector-unify(".a.b", ".b.c") => .a.b.c
|
2580
|
+
# selector-unify("#a", "#b") => null
|
2581
|
+
#
|
2582
|
+
# @overload selector_unify($selector1, $selector2)
|
2583
|
+
# @param $selector1 [Sass::Script::Value::String, Sass::Script::Value::List]
|
2584
|
+
# The first selector to be unified. This can be either a
|
2585
|
+
# string, a list of strings, or a list of lists of strings as
|
2586
|
+
# returned by `&`.
|
2587
|
+
# @param $selector2 [Sass::Script::Value::String, Sass::Script::Value::List]
|
2588
|
+
# The second selector to be unified. This can be either a
|
2589
|
+
# string, a list of strings, or a list of lists of strings as
|
2590
|
+
# returned by `&`.
|
2591
|
+
# @return [Sass::Script::Value::List, Sass::Script::Value::Null]
|
2592
|
+
# A list of lists of strings representing the result of the
|
2593
|
+
# unification, or null if no unification exists. This is in
|
2594
|
+
# the same format as a selector returned by `&`.
|
2595
|
+
def selector_unify(selector1, selector2)
|
2596
|
+
selector1 = parse_selector(selector1, :selector1)
|
2597
|
+
selector2 = parse_selector(selector2, :selector2)
|
2598
|
+
return null unless (unified = selector1.unify(selector2))
|
2599
|
+
unified.to_sass_script
|
2600
|
+
end
|
2601
|
+
declare :selector_unify, [:selector1, :selector2]
|
2602
|
+
|
2603
|
+
# Returns the [simple
|
2604
|
+
# selectors](http://dev.w3.org/csswg/selectors4/#simple) that
|
2605
|
+
# comprise the compound selector `$selector`.
|
2606
|
+
#
|
2607
|
+
# Note that `$selector` **must be** a [compound
|
2608
|
+
# selector](http://dev.w3.org/csswg/selectors4/#compound). That
|
2609
|
+
# means it cannot contain commas or spaces. It also means that
|
2610
|
+
# unlike other selector functions, this takes only strings, not
|
2611
|
+
# lists.
|
2612
|
+
#
|
2613
|
+
# @example
|
2614
|
+
# simple-selectors(".foo.bar") => ".foo", ".bar"
|
2615
|
+
# simple-selectors(".foo.bar.baz") => ".foo", ".bar", ".baz"
|
2616
|
+
#
|
2617
|
+
# @overload simple_selectors($selector)
|
2618
|
+
# @param $selector [Sass::Script::Value::String]
|
2619
|
+
# The compound selector whose simple selectors will be extracted.
|
2620
|
+
# @return [Sass::Script::Value::List]
|
2621
|
+
# A list of simple selectors in the compound selector.
|
2622
|
+
def simple_selectors(selector)
|
2623
|
+
selector = parse_compound_selector(selector, :selector)
|
2624
|
+
list(selector.members.map {|simple| unquoted_string(simple.to_s)}, :comma)
|
2625
|
+
end
|
2626
|
+
declare :simple_selectors, [:selector]
|
2627
|
+
|
2628
|
+
# Returns whether `$super` is a superselector of `$sub`. This means that
|
2629
|
+
# `$super` matches all the elements that `$sub` matches, as well as possibly
|
2630
|
+
# additional elements. In general, simpler selectors tend to be
|
2631
|
+
# superselectors of more complex oned.
|
2632
|
+
#
|
2633
|
+
# @example
|
2634
|
+
# is-superselector(".foo", ".foo.bar") => true
|
2635
|
+
# is-superselector(".foo.bar", ".foo") => false
|
2636
|
+
# is-superselector(".bar", ".foo .bar") => true
|
2637
|
+
# is-superselector(".foo .bar", ".bar") => false
|
2638
|
+
#
|
2639
|
+
# @overload is_superselector($super, $sub)
|
2640
|
+
# @param $super [Sass::Script::Value::String, Sass::Script::Value::List]
|
2641
|
+
# The potential superselector. This can be either a string, a list of
|
2642
|
+
# strings, or a list of lists of strings as returned by `&`.
|
2643
|
+
# @param $sub [Sass::Script::Value::String, Sass::Script::Value::List]
|
2644
|
+
# The potential subselector. This can be either a string, a list of
|
2645
|
+
# strings, or a list of lists of strings as returned by `&`.
|
2646
|
+
# @return [Sass::Script::Value::Bool]
|
2647
|
+
# Whether `$selector1` is a superselector of `$selector2`.
|
2648
|
+
def is_superselector(sup, sub)
|
2649
|
+
sup = parse_selector(sup, :super)
|
2650
|
+
sub = parse_selector(sub, :sub)
|
2651
|
+
bool(sup.superselector?(sub))
|
2652
|
+
end
|
2653
|
+
declare :is_superselector, [:super, :sub]
|
2654
|
+
|
2234
2655
|
private
|
2235
2656
|
|
2236
2657
|
# This method implements the pattern of transforming a numeric value into
|
@@ -2250,23 +2671,23 @@ module Sass::Script
|
|
2250
2671
|
assert_type amount, :Number, :amount
|
2251
2672
|
Sass::Util.check_range('Amount', range, amount, units)
|
2252
2673
|
|
2253
|
-
|
2254
|
-
# or should we do so in the Color constructor itself,
|
2255
|
-
# and allow clipping in rgb() et al?
|
2256
|
-
color.with(attr => Sass::Util.restrict(
|
2257
|
-
color.send(attr).send(op, amount.value), range))
|
2674
|
+
color.with(attr => color.send(attr).send(op, amount.value))
|
2258
2675
|
end
|
2259
2676
|
|
2260
|
-
def
|
2261
|
-
return
|
2677
|
+
def check_alpha_unit(alpha, function)
|
2678
|
+
return if alpha.unitless?
|
2262
2679
|
|
2263
|
-
|
2264
|
-
|
2265
|
-
DEPRECATION WARNING: Passing
|
2266
|
-
|
2267
|
-
http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#maps.
|
2680
|
+
if alpha.is_unit?("%")
|
2681
|
+
Sass::Util.sass_warn(<<WARNING)
|
2682
|
+
DEPRECATION WARNING: Passing a percentage as the alpha value to #{function}() will be
|
2683
|
+
interpreted differently in future versions of Sass. For now, use #{alpha.value} instead.
|
2268
2684
|
WARNING
|
2269
|
-
|
2685
|
+
else
|
2686
|
+
Sass::Util.sass_warn(<<WARNING)
|
2687
|
+
DEPRECATION WARNING: Passing a number with units as the alpha value to #{function}() is
|
2688
|
+
deprecated and will be an error in future versions of Sass. Use #{alpha.value} instead.
|
2689
|
+
WARNING
|
2690
|
+
end
|
2270
2691
|
end
|
2271
2692
|
end
|
2272
2693
|
end
|