sass 3.3.0.rc.2 → 3.3.0.rc.3
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 +15 -0
- data/CONTRIBUTING +1 -1
- data/README.md +7 -7
- data/Rakefile +4 -2
- data/VERSION +1 -1
- data/VERSION_DATE +1 -1
- data/bin/sass +5 -1
- data/bin/sass-convert +5 -1
- data/bin/scss +5 -1
- data/ext/mkrf_conf.rb +23 -0
- data/lib/sass/css.rb +1 -1
- data/lib/sass/engine.rb +19 -9
- data/lib/sass/environment.rb +8 -0
- data/lib/sass/exec.rb +4 -4
- data/lib/sass/features.rb +0 -1
- data/lib/sass/importers/base.rb +13 -6
- data/lib/sass/importers/deprecated_path.rb +8 -2
- data/lib/sass/importers/filesystem.rb +33 -7
- data/lib/sass/logger.rb +1 -4
- data/lib/sass/logger/base.rb +0 -2
- data/lib/sass/logger/log_level.rb +0 -2
- data/lib/sass/plugin.rb +2 -2
- data/lib/sass/plugin/compiler.rb +23 -11
- data/lib/sass/plugin/configuration.rb +0 -1
- data/lib/sass/railtie.rb +1 -0
- data/lib/sass/script/css_lexer.rb +0 -1
- data/lib/sass/script/css_parser.rb +0 -1
- data/lib/sass/script/functions.rb +158 -96
- data/lib/sass/script/lexer.rb +29 -35
- data/lib/sass/script/parser.rb +10 -3
- data/lib/sass/script/tree.rb +0 -1
- data/lib/sass/script/tree/funcall.rb +21 -5
- data/lib/sass/script/tree/list_literal.rb +0 -1
- data/lib/sass/script/value/arg_list.rb +7 -3
- data/lib/sass/script/value/bool.rb +0 -1
- data/lib/sass/script/value/null.rb +0 -1
- data/lib/sass/script/value/number.rb +2 -6
- data/lib/sass/scss/css_parser.rb +0 -1
- data/lib/sass/scss/parser.rb +5 -5
- data/lib/sass/scss/script_lexer.rb +0 -1
- data/lib/sass/scss/script_parser.rb +0 -1
- data/lib/sass/selector.rb +11 -1
- data/lib/sass/selector/comma_sequence.rb +3 -4
- data/lib/sass/selector/sequence.rb +11 -7
- data/lib/sass/selector/simple_sequence.rb +42 -11
- data/lib/sass/source/map.rb +6 -19
- data/lib/sass/tree/at_root_node.rb +1 -1
- data/lib/sass/tree/mixin_node.rb +2 -2
- data/lib/sass/tree/prop_node.rb +0 -1
- data/lib/sass/tree/variable_node.rb +0 -5
- data/lib/sass/tree/visitors/check_nesting.rb +0 -1
- data/lib/sass/tree/visitors/convert.rb +2 -2
- data/lib/sass/tree/visitors/cssize.rb +184 -84
- data/lib/sass/tree/visitors/deep_copy.rb +0 -1
- data/lib/sass/tree/visitors/perform.rb +14 -44
- data/lib/sass/util.rb +59 -12
- data/lib/sass/util/cross_platform_random.rb +19 -0
- data/lib/sass/util/normalized_map.rb +17 -1
- data/test/sass/compiler_test.rb +10 -0
- data/test/sass/conversion_test.rb +36 -0
- data/test/sass/css2sass_test.rb +19 -0
- data/test/sass/engine_test.rb +54 -105
- data/test/sass/functions_test.rb +233 -26
- data/test/sass/importer_test.rb +72 -10
- data/test/sass/plugin_test.rb +14 -0
- data/test/sass/script_conversion_test.rb +4 -4
- data/test/sass/script_test.rb +58 -21
- data/test/sass/scss/css_test.rb +8 -1
- data/test/sass/scss/scss_test.rb +376 -179
- data/test/sass/source_map_test.rb +8 -0
- data/test/sass/templates/subdir/import_up1.scss +1 -0
- data/test/sass/templates/subdir/import_up2.scss +1 -0
- data/test/sass/util_test.rb +16 -0
- data/test/test_helper.rb +12 -4
- metadata +269 -287
- data/lib/sass/script/tree/selector.rb +0 -30
data/lib/sass/logger.rb
CHANGED
data/lib/sass/logger/base.rb
CHANGED
data/lib/sass/plugin.rb
CHANGED
@@ -120,11 +120,11 @@ module Sass
|
|
120
120
|
def options
|
121
121
|
compiler.options
|
122
122
|
end
|
123
|
-
|
124
123
|
end
|
125
124
|
end
|
126
125
|
|
127
|
-
|
126
|
+
# On Rails 3+ the rails plugin is loaded at the right time in railtie.rb
|
127
|
+
if defined?(ActionController) && !Sass::Util.ap_geq_3?
|
128
128
|
require 'sass/plugin/rails'
|
129
129
|
elsif defined?(Merb::Plugins)
|
130
130
|
require 'sass/plugin/merb'
|
data/lib/sass/plugin/compiler.rb
CHANGED
@@ -8,7 +8,6 @@ require 'sass/plugin/configuration'
|
|
8
8
|
require 'sass/plugin/staleness_checker'
|
9
9
|
|
10
10
|
module Sass::Plugin
|
11
|
-
|
12
11
|
# The Compiler class handles compilation of multiple files and/or directories,
|
13
12
|
# including checking which CSS files are out-of-date and need to be updated
|
14
13
|
# and calling Sass to perform the compilation on those files.
|
@@ -281,13 +280,7 @@ module Sass::Plugin
|
|
281
280
|
# https://github.com/nex3/sass/commit/a3031856b22bc834a5417dedecb038b7be9b9e3e
|
282
281
|
listener.force_polling(true) if @options[:poll] || Sass::Util.windows?
|
283
282
|
|
284
|
-
|
285
|
-
begin
|
286
|
-
listener.start!
|
287
|
-
rescue Exception => e
|
288
|
-
raise e unless e.is_a?(Interrupt)
|
289
|
-
end
|
290
|
-
# rubocop:enable RescueException
|
283
|
+
listen_to(listener)
|
291
284
|
end
|
292
285
|
|
293
286
|
# Non-destructively modifies \{#options} so that default values are properly set,
|
@@ -309,8 +302,25 @@ module Sass::Plugin
|
|
309
302
|
private
|
310
303
|
|
311
304
|
def create_listener(*args, &block)
|
312
|
-
|
313
|
-
|
305
|
+
if Sass::Util.listen_geq_2?
|
306
|
+
Listen.to(*args, &block)
|
307
|
+
else
|
308
|
+
Listen::Listener.new(*args, &block)
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
def listen_to(listener)
|
313
|
+
if Sass::Util.listen_geq_2?
|
314
|
+
listener.start
|
315
|
+
listener.thread.join
|
316
|
+
listener.stop # Partially work around guard/listen#146
|
317
|
+
else
|
318
|
+
begin
|
319
|
+
listener.start!
|
320
|
+
rescue Interrupt
|
321
|
+
# Squelch Interrupt for clean exit from Listen::Listener
|
322
|
+
end
|
323
|
+
end
|
314
324
|
end
|
315
325
|
|
316
326
|
def remove_redundant_directories(directories)
|
@@ -338,7 +348,9 @@ module Sass::Plugin
|
|
338
348
|
|
339
349
|
begin
|
340
350
|
File.read(filename) unless File.readable?(filename) # triggers an error for handling
|
341
|
-
engine_opts = engine_options(:css_filename => css,
|
351
|
+
engine_opts = engine_options(:css_filename => css,
|
352
|
+
:filename => filename,
|
353
|
+
:sourcemap_filename => sourcemap)
|
342
354
|
mapping = nil
|
343
355
|
engine = Sass::Engine.for_file(filename, engine_opts)
|
344
356
|
if sourcemap
|
data/lib/sass/railtie.rb
CHANGED
@@ -31,7 +31,7 @@ module Sass::Script
|
|
31
31
|
# \{#blue blue($color)}
|
32
32
|
# : Gets the blue component of a color.
|
33
33
|
#
|
34
|
-
# \{#mix mix($
|
34
|
+
# \{#mix mix($color1, $color2, \[$weight\])}
|
35
35
|
# : Mixes two colors together.
|
36
36
|
#
|
37
37
|
# ## HSL Functions
|
@@ -136,19 +136,19 @@ module Sass::Script
|
|
136
136
|
#
|
137
137
|
# ## Number Functions
|
138
138
|
#
|
139
|
-
# \{#percentage percentage($
|
139
|
+
# \{#percentage percentage($number)}
|
140
140
|
# : Converts a unitless number to a percentage.
|
141
141
|
#
|
142
|
-
# \{#round round($
|
142
|
+
# \{#round round($number)}
|
143
143
|
# : Rounds a number to the nearest whole number.
|
144
144
|
#
|
145
|
-
# \{#ceil ceil($
|
145
|
+
# \{#ceil ceil($number)}
|
146
146
|
# : Rounds a number up to the next whole number.
|
147
147
|
#
|
148
|
-
# \{#floor floor($
|
148
|
+
# \{#floor floor($number)}
|
149
149
|
# : Rounds a number down to the previous whole number.
|
150
150
|
#
|
151
|
-
# \{#abs abs($
|
151
|
+
# \{#abs abs($number)}
|
152
152
|
# : Returns the absolute value of a number.
|
153
153
|
#
|
154
154
|
# \{#min min($numbers...)\}
|
@@ -157,6 +157,9 @@ module Sass::Script
|
|
157
157
|
# \{#max max($numbers...)\}
|
158
158
|
# : Finds the maximum of several numbers.
|
159
159
|
#
|
160
|
+
# \{#random random([$limit])\}
|
161
|
+
# : Returns a random number.
|
162
|
+
#
|
160
163
|
# ## List Functions {#list-functions}
|
161
164
|
#
|
162
165
|
# All list functions work for maps as well, treating them as lists of pairs.
|
@@ -190,6 +193,9 @@ module Sass::Script
|
|
190
193
|
# \{#map_merge map-merge($map1, $map2)}
|
191
194
|
# : Merges two maps together into a new map.
|
192
195
|
#
|
196
|
+
# \{#map_remove map-remove($map, $key)}
|
197
|
+
# : Returns a new map with a key removed.
|
198
|
+
#
|
193
199
|
# \{#map_keys map-keys($map)}
|
194
200
|
# : Returns a list of all keys in a map.
|
195
201
|
#
|
@@ -231,7 +237,7 @@ module Sass::Script
|
|
231
237
|
# \{#unitless unitless($number)}
|
232
238
|
# : Returns whether a number has units.
|
233
239
|
#
|
234
|
-
# \{#comparable comparable($
|
240
|
+
# \{#comparable comparable($number1, $number2)}
|
235
241
|
# : Returns whether two numbers can be added, subtracted, or compared.
|
236
242
|
#
|
237
243
|
# \{#call call($name, $args...)}
|
@@ -306,7 +312,7 @@ module Sass::Script
|
|
306
312
|
# delayed.
|
307
313
|
# @attr var_args [Boolean] Whether the function takes a variable number of arguments.
|
308
314
|
# @attr var_kwargs [Boolean] Whether the function takes an arbitrary set of keyword arguments.
|
309
|
-
Signature = Struct.new(:args, :delayed_args, :var_args, :var_kwargs)
|
315
|
+
Signature = Struct.new(:args, :delayed_args, :var_args, :var_kwargs, :deprecated)
|
310
316
|
|
311
317
|
# Declare a Sass signature for a Ruby-defined function.
|
312
318
|
# This includes the names of the arguments,
|
@@ -361,7 +367,8 @@ module Sass::Script
|
|
361
367
|
args,
|
362
368
|
delayed_args,
|
363
369
|
options[:var_args],
|
364
|
-
options[:var_kwargs]
|
370
|
+
options[:var_kwargs],
|
371
|
+
options[:deprecated] && options[:deprecated].map {|a| a.to_s})
|
365
372
|
end
|
366
373
|
|
367
374
|
# Determine the correct signature for the number of arguments
|
@@ -401,6 +408,24 @@ module Sass::Script
|
|
401
408
|
@signatures[method_name].first
|
402
409
|
end
|
403
410
|
|
411
|
+
# Sets the random seed used by Sass's internal random number generator.
|
412
|
+
#
|
413
|
+
# This can be used to ensure consistent random number sequences which
|
414
|
+
# allows for consistent results when testing, etc.
|
415
|
+
#
|
416
|
+
# @param seed [Integer]
|
417
|
+
# @return [Integer] The same seed.
|
418
|
+
def self.random_seed=(seed)
|
419
|
+
@random_number_generator = Sass::Util::CrossPlatformRandom.new(seed)
|
420
|
+
end
|
421
|
+
|
422
|
+
# Get Sass's internal random number generator.
|
423
|
+
#
|
424
|
+
# @return [Random]
|
425
|
+
def self.random_number_generator
|
426
|
+
@random_number_generator ||= Sass::Util::CrossPlatformRandom.new
|
427
|
+
end
|
428
|
+
|
404
429
|
# The context in which methods in {Script::Functions} are evaluated.
|
405
430
|
# That means that all instance methods of {EvaluationContext}
|
406
431
|
# are available to use in functions.
|
@@ -740,7 +765,6 @@ module Sass::Script
|
|
740
765
|
# @raise [ArgumentError] if `$color` isn't a color
|
741
766
|
def hue(color)
|
742
767
|
assert_type color, :Color, :color
|
743
|
-
assert_type color, :Color
|
744
768
|
number(color.hue, "deg")
|
745
769
|
end
|
746
770
|
declare :hue, [:color]
|
@@ -1187,18 +1211,18 @@ module Sass::Script
|
|
1187
1211
|
# mix(#f00, #00f) => #7f007f
|
1188
1212
|
# mix(#f00, #00f, 25%) => #3f00bf
|
1189
1213
|
# mix(rgba(255, 0, 0, 0.5), #00f) => rgba(63, 0, 191, 0.75)
|
1190
|
-
# @overload mix($
|
1191
|
-
# @param $
|
1192
|
-
# @param $
|
1214
|
+
# @overload mix($color1, $color2, $weight: 50%)
|
1215
|
+
# @param $color1 [Sass::Script::Value::Color]
|
1216
|
+
# @param $color2 [Sass::Script::Value::Color]
|
1193
1217
|
# @param $weight [Sass::Script::Value::Number] The relative weight of each
|
1194
1218
|
# color. Closer to `0%` gives more weight to `$color`, closer to `100%`
|
1195
1219
|
# gives more weight to `$color2`
|
1196
1220
|
# @return [Sass::Script::Value::Color]
|
1197
1221
|
# @raise [ArgumentError] if `$weight` is out of bounds or any parameter is
|
1198
1222
|
# the wrong type
|
1199
|
-
def mix(
|
1200
|
-
assert_type
|
1201
|
-
assert_type
|
1223
|
+
def mix(color1, color2, weight = number(50))
|
1224
|
+
assert_type color1, :Color, :color1
|
1225
|
+
assert_type color2, :Color, :color2
|
1202
1226
|
assert_type weight, :Number, :weight
|
1203
1227
|
|
1204
1228
|
Sass::Util.check_range("Weight", 0..100, weight, '%')
|
@@ -1208,11 +1232,11 @@ module Sass::Script
|
|
1208
1232
|
# to perform the weighted average of the two RGB values.
|
1209
1233
|
#
|
1210
1234
|
# It works by first normalizing both parameters to be within [-1, 1],
|
1211
|
-
# where 1 indicates "only use
|
1235
|
+
# where 1 indicates "only use color1", -1 indicates "only use color2", and
|
1212
1236
|
# all values in between indicated a proportionately weighted average.
|
1213
1237
|
#
|
1214
1238
|
# Once we have the normalized variables w and a, we apply the formula
|
1215
|
-
# (w + a)/(1 + w*a) to get the combined weight (in [-1, 1]) of
|
1239
|
+
# (w + a)/(1 + w*a) to get the combined weight (in [-1, 1]) of color1.
|
1216
1240
|
# This formula has two especially nice properties:
|
1217
1241
|
#
|
1218
1242
|
# * When either w or a are -1 or 1, the combined weight is also that number
|
@@ -1220,21 +1244,21 @@ module Sass::Script
|
|
1220
1244
|
#
|
1221
1245
|
# * When a is 0, the combined weight is w, and vice versa.
|
1222
1246
|
#
|
1223
|
-
# Finally, the weight of
|
1224
|
-
# and the weight of
|
1247
|
+
# Finally, the weight of color1 is renormalized to be within [0, 1]
|
1248
|
+
# and the weight of color2 is given by 1 minus the weight of color1.
|
1225
1249
|
p = (weight.value / 100.0).to_f
|
1226
1250
|
w = p * 2 - 1
|
1227
|
-
a =
|
1251
|
+
a = color1.alpha - color2.alpha
|
1228
1252
|
|
1229
1253
|
w1 = ((w * a == -1 ? w : (w + a) / (1 + w * a)) + 1) / 2.0
|
1230
1254
|
w2 = 1 - w1
|
1231
1255
|
|
1232
|
-
rgba =
|
1233
|
-
rgba <<
|
1256
|
+
rgba = color1.rgb.zip(color2.rgb).map {|v1, v2| v1 * w1 + v2 * w2}
|
1257
|
+
rgba << color1.alpha * p + color2.alpha * (1 - p)
|
1234
1258
|
rgb_color(*rgba)
|
1235
1259
|
end
|
1236
|
-
declare :mix, [:color_1, :color_2]
|
1237
|
-
declare :mix, [:color_1, :color_2, :weight]
|
1260
|
+
declare :mix, [:color1, :color2], :deprecated => [:color_1, :color_2]
|
1261
|
+
declare :mix, [:color1, :color2, :weight], :deprecated => [:color_1, :color_2, :weight]
|
1238
1262
|
|
1239
1263
|
# Converts a color to grayscale. This is identical to `desaturate(color,
|
1240
1264
|
# 100%)`.
|
@@ -1376,7 +1400,7 @@ module Sass::Script
|
|
1376
1400
|
declare :str_insert, [:string, :insert, :index]
|
1377
1401
|
|
1378
1402
|
# Returns the index of the first occurance of `$substring` in `$string`. If
|
1379
|
-
# there is no such occurance, returns
|
1403
|
+
# there is no such occurance, returns `null`.
|
1380
1404
|
#
|
1381
1405
|
# Note that unlike some languages, the first character in a Sass string is
|
1382
1406
|
# number 1, the second number 2, and so forth.
|
@@ -1384,19 +1408,19 @@ module Sass::Script
|
|
1384
1408
|
# @example
|
1385
1409
|
# str-index(abcd, a) => 1
|
1386
1410
|
# str-index(abcd, ab) => 1
|
1387
|
-
# str-index(abcd, X) =>
|
1411
|
+
# str-index(abcd, X) => null
|
1388
1412
|
# str-index(abcd, c) => 3
|
1389
1413
|
#
|
1390
1414
|
# @overload str_index($string, $substring)
|
1391
1415
|
# @param $string [Sass::Script::Value::String]
|
1392
1416
|
# @param $substring [Sass::Script::Value::String]
|
1393
|
-
# @return [Sass::Script::Value::Number]
|
1417
|
+
# @return [Sass::Script::Value::Number, Sass::Script::Value::Null]
|
1394
1418
|
# @raise [ArgumentError] if any parameter is the wrong type
|
1395
1419
|
def str_index(string, substring)
|
1396
1420
|
assert_type string, :String, :string
|
1397
1421
|
assert_type substring, :String, :substring
|
1398
|
-
index = string.value.index(substring.value)
|
1399
|
-
number(index + 1)
|
1422
|
+
index = string.value.index(substring.value)
|
1423
|
+
index ? number(index + 1) : null
|
1400
1424
|
end
|
1401
1425
|
declare :str_index, [:string, :substring]
|
1402
1426
|
|
@@ -1546,90 +1570,90 @@ module Sass::Script
|
|
1546
1570
|
# comparable(2px, 1px) => true
|
1547
1571
|
# comparable(100px, 3em) => false
|
1548
1572
|
# comparable(10cm, 3mm) => true
|
1549
|
-
# @overload comparable($
|
1550
|
-
# @param $
|
1551
|
-
# @param $
|
1573
|
+
# @overload comparable($number1, $number2)
|
1574
|
+
# @param $number1 [Sass::Script::Value::Number]
|
1575
|
+
# @param $number2 [Sass::Script::Value::Number]
|
1552
1576
|
# @return [Sass::Script::Value::Bool]
|
1553
1577
|
# @raise [ArgumentError] if either parameter is the wrong type
|
1554
|
-
def comparable(
|
1555
|
-
assert_type
|
1556
|
-
assert_type
|
1557
|
-
bool(
|
1578
|
+
def comparable(number1, number2)
|
1579
|
+
assert_type number1, :Number, :number1
|
1580
|
+
assert_type number2, :Number, :number2
|
1581
|
+
bool(number1.comparable_to?(number2))
|
1558
1582
|
end
|
1559
|
-
declare :comparable, [:number_1, :number_2]
|
1583
|
+
declare :comparable, [:number1, :number2], :deprecated => [:number_1, :number_2]
|
1560
1584
|
|
1561
1585
|
# Converts a unitless number to a percentage.
|
1562
1586
|
#
|
1563
1587
|
# @example
|
1564
1588
|
# percentage(0.2) => 20%
|
1565
1589
|
# percentage(100px / 50px) => 200%
|
1566
|
-
# @overload percentage($
|
1567
|
-
# @param $
|
1590
|
+
# @overload percentage($number)
|
1591
|
+
# @param $number [Sass::Script::Value::Number]
|
1568
1592
|
# @return [Sass::Script::Value::Number]
|
1569
|
-
# @raise [ArgumentError] if `$
|
1570
|
-
def percentage(
|
1571
|
-
unless
|
1572
|
-
raise ArgumentError.new("$
|
1593
|
+
# @raise [ArgumentError] if `$number` isn't a unitless number
|
1594
|
+
def percentage(number)
|
1595
|
+
unless number.is_a?(Sass::Script::Value::Number) && number.unitless?
|
1596
|
+
raise ArgumentError.new("$number: #{number.inspect} is not a unitless number")
|
1573
1597
|
end
|
1574
|
-
number(
|
1598
|
+
number(number.value * 100, '%')
|
1575
1599
|
end
|
1576
|
-
declare :percentage, [:value]
|
1600
|
+
declare :percentage, [:number], :deprecated => [:value]
|
1577
1601
|
|
1578
1602
|
# Rounds a number to the nearest whole number.
|
1579
1603
|
#
|
1580
1604
|
# @example
|
1581
1605
|
# round(10.4px) => 10px
|
1582
1606
|
# round(10.6px) => 11px
|
1583
|
-
# @overload round($
|
1584
|
-
# @param $
|
1607
|
+
# @overload round($number)
|
1608
|
+
# @param $number [Sass::Script::Value::Number]
|
1585
1609
|
# @return [Sass::Script::Value::Number]
|
1586
|
-
# @raise [ArgumentError] if `$
|
1587
|
-
def round(
|
1588
|
-
numeric_transformation(
|
1610
|
+
# @raise [ArgumentError] if `$number` isn't a number
|
1611
|
+
def round(number)
|
1612
|
+
numeric_transformation(number) {|n| n.round}
|
1589
1613
|
end
|
1590
|
-
declare :round, [:value]
|
1614
|
+
declare :round, [:number], :deprecated => [:value]
|
1591
1615
|
|
1592
1616
|
# Rounds a number up to the next whole number.
|
1593
1617
|
#
|
1594
1618
|
# @example
|
1595
1619
|
# ceil(10.4px) => 11px
|
1596
1620
|
# ceil(10.6px) => 11px
|
1597
|
-
# @overload ceil($
|
1598
|
-
# @param $
|
1621
|
+
# @overload ceil($number)
|
1622
|
+
# @param $number [Sass::Script::Value::Number]
|
1599
1623
|
# @return [Sass::Script::Value::Number]
|
1600
|
-
# @raise [ArgumentError] if `$
|
1601
|
-
def ceil(
|
1602
|
-
numeric_transformation(
|
1624
|
+
# @raise [ArgumentError] if `$number` isn't a number
|
1625
|
+
def ceil(number)
|
1626
|
+
numeric_transformation(number) {|n| n.ceil}
|
1603
1627
|
end
|
1604
|
-
declare :ceil, [:value]
|
1628
|
+
declare :ceil, [:number], :deprecated => [:value]
|
1605
1629
|
|
1606
1630
|
# Rounds a number down to the previous whole number.
|
1607
1631
|
#
|
1608
1632
|
# @example
|
1609
1633
|
# floor(10.4px) => 10px
|
1610
1634
|
# floor(10.6px) => 10px
|
1611
|
-
# @overload floor($
|
1612
|
-
# @param $
|
1635
|
+
# @overload floor($number)
|
1636
|
+
# @param $number [Sass::Script::Value::Number]
|
1613
1637
|
# @return [Sass::Script::Value::Number]
|
1614
|
-
# @raise [ArgumentError] if `$
|
1615
|
-
def floor(
|
1616
|
-
numeric_transformation(
|
1638
|
+
# @raise [ArgumentError] if `$number` isn't a number
|
1639
|
+
def floor(number)
|
1640
|
+
numeric_transformation(number) {|n| n.floor}
|
1617
1641
|
end
|
1618
|
-
declare :floor, [:value]
|
1642
|
+
declare :floor, [:number], :deprecated => [:value]
|
1619
1643
|
|
1620
1644
|
# Returns the absolute value of a number.
|
1621
1645
|
#
|
1622
1646
|
# @example
|
1623
1647
|
# abs(10px) => 10px
|
1624
1648
|
# abs(-10px) => 10px
|
1625
|
-
# @overload abs($
|
1626
|
-
# @param $
|
1649
|
+
# @overload abs($number)
|
1650
|
+
# @param $number [Sass::Script::Value::Number]
|
1627
1651
|
# @return [Sass::Script::Value::Number]
|
1628
|
-
# @raise [ArgumentError] if `$
|
1629
|
-
def abs(
|
1630
|
-
numeric_transformation(
|
1652
|
+
# @raise [ArgumentError] if `$number` isn't a number
|
1653
|
+
def abs(number)
|
1654
|
+
numeric_transformation(number) {|n| n.abs}
|
1631
1655
|
end
|
1632
|
-
declare :abs, [:value]
|
1656
|
+
declare :abs, [:number], :deprecated => [:value]
|
1633
1657
|
|
1634
1658
|
# Finds the minimum of several numbers. This function takes any number of
|
1635
1659
|
# arguments.
|
@@ -1839,7 +1863,7 @@ module Sass::Script
|
|
1839
1863
|
declare :zip, [], :var_args => true
|
1840
1864
|
|
1841
1865
|
# Returns the position of a value within a list. If the value isn't found,
|
1842
|
-
# returns
|
1866
|
+
# returns `null` instead.
|
1843
1867
|
#
|
1844
1868
|
# Note that unlike some languages, the first item in a Sass list is number
|
1845
1869
|
# 1, the second number 2, and so forth.
|
@@ -1848,20 +1872,16 @@ module Sass::Script
|
|
1848
1872
|
#
|
1849
1873
|
# @example
|
1850
1874
|
# index(1px solid red, solid) => 2
|
1851
|
-
# index(1px solid red, dashed) =>
|
1875
|
+
# index(1px solid red, dashed) => null
|
1852
1876
|
# index((width: 10px, height: 20px), (height, 20px)) => 2
|
1853
1877
|
# @overload index($list, $value)
|
1854
1878
|
# @param $list [Sass::Script::Value::Base]
|
1855
1879
|
# @param $value [Sass::Script::Value::Base]
|
1856
|
-
# @return [Sass::Script::Value::Number, Sass::Script::Value::
|
1857
|
-
# 1-based index of `$value` in `$list`, or `
|
1880
|
+
# @return [Sass::Script::Value::Number, Sass::Script::Value::Null] The
|
1881
|
+
# 1-based index of `$value` in `$list`, or `null`
|
1858
1882
|
def index(list, value)
|
1859
1883
|
index = list.to_a.index {|e| e.eq(value).to_bool}
|
1860
|
-
|
1861
|
-
number(index + 1)
|
1862
|
-
else
|
1863
|
-
bool(false)
|
1864
|
-
end
|
1884
|
+
index ? number(index + 1) : null
|
1865
1885
|
end
|
1866
1886
|
declare :index, [:list, :value]
|
1867
1887
|
|
@@ -1894,7 +1914,7 @@ module Sass::Script
|
|
1894
1914
|
# if the map doesn't contain the given key
|
1895
1915
|
# @raise [ArgumentError] if `$map` is not a map
|
1896
1916
|
def map_get(map, key)
|
1897
|
-
assert_type map, :Map
|
1917
|
+
assert_type map, :Map, :map
|
1898
1918
|
to_h(map)[key] || null
|
1899
1919
|
end
|
1900
1920
|
declare :map_get, [:map, :key]
|
@@ -1917,11 +1937,29 @@ module Sass::Script
|
|
1917
1937
|
# @return [Sass::Script::Value::Map]
|
1918
1938
|
# @raise [ArgumentError] if either parameter is not a map
|
1919
1939
|
def map_merge(map1, map2)
|
1920
|
-
assert_type map1, :Map
|
1921
|
-
assert_type map2, :Map
|
1940
|
+
assert_type map1, :Map, :map1
|
1941
|
+
assert_type map2, :Map, :map2
|
1922
1942
|
map(to_h(map1).merge(to_h(map2)))
|
1923
1943
|
end
|
1924
|
-
declare :
|
1944
|
+
declare :map_merge, [:map1, :map2]
|
1945
|
+
|
1946
|
+
# Returns a new map with a key removed.
|
1947
|
+
#
|
1948
|
+
# @example
|
1949
|
+
# map-remove(("foo": 1, "bar": 2), "bar") => ("foo": 1)
|
1950
|
+
# map-remove(("foo": 1, "bar": 2), "baz") => ("foo": 1, "bar": 2)
|
1951
|
+
# @overload map_remove($map, $key)
|
1952
|
+
# @param $map [Sass::Script::Value::Map]
|
1953
|
+
# @param $key [Sass::Script::Value::Base]
|
1954
|
+
# @return [Sass::Script::Value::Map]
|
1955
|
+
# @raise [ArgumentError] if `$map` is not a map
|
1956
|
+
def map_remove(map, key)
|
1957
|
+
assert_type map, :Map, :map
|
1958
|
+
hash = to_h(map).dup
|
1959
|
+
hash.delete key
|
1960
|
+
map(hash)
|
1961
|
+
end
|
1962
|
+
declare :map_remove, [:map, :key]
|
1925
1963
|
|
1926
1964
|
# Returns a list of all keys in a map.
|
1927
1965
|
#
|
@@ -1932,7 +1970,7 @@ module Sass::Script
|
|
1932
1970
|
# @return [List] the list of keys, comma-separated
|
1933
1971
|
# @raise [ArgumentError] if `$map` is not a map
|
1934
1972
|
def map_keys(map)
|
1935
|
-
assert_type map, :Map
|
1973
|
+
assert_type map, :Map, :map
|
1936
1974
|
list(to_h(map).keys, :comma)
|
1937
1975
|
end
|
1938
1976
|
declare :map_keys, [:map]
|
@@ -1948,7 +1986,7 @@ module Sass::Script
|
|
1948
1986
|
# @return [List] the list of values, comma-separated
|
1949
1987
|
# @raise [ArgumentError] if `$map` is not a map
|
1950
1988
|
def map_values(map)
|
1951
|
-
assert_type map, :Map
|
1989
|
+
assert_type map, :Map, :map
|
1952
1990
|
list(to_h(map).values, :comma)
|
1953
1991
|
end
|
1954
1992
|
declare :map_values, [:map]
|
@@ -1964,7 +2002,7 @@ module Sass::Script
|
|
1964
2002
|
# @return [Sass::Script::Value::Bool]
|
1965
2003
|
# @raise [ArgumentError] if `$map` is not a map
|
1966
2004
|
def map_has_key(map, key)
|
1967
|
-
assert_type map, :Map
|
2005
|
+
assert_type map, :Map, :map
|
1968
2006
|
bool(to_h(map).has_key?(key))
|
1969
2007
|
end
|
1970
2008
|
declare :map_has_key, [:map, :key]
|
@@ -1984,8 +2022,8 @@ module Sass::Script
|
|
1984
2022
|
# @return [Sass::Script::Value::Map]
|
1985
2023
|
# @raise [ArgumentError] if `$args` isn't a variable argument list
|
1986
2024
|
def keywords(args)
|
1987
|
-
assert_type args, :ArgList
|
1988
|
-
map(Sass::Util.map_keys(args.keywords) {|k| Sass::Script::String.new(k)})
|
2025
|
+
assert_type args, :ArgList, :args
|
2026
|
+
map(Sass::Util.map_keys(args.keywords.as_stored) {|k| Sass::Script::String.new(k)})
|
1989
2027
|
end
|
1990
2028
|
declare :keywords, [:args]
|
1991
2029
|
|
@@ -2018,9 +2056,10 @@ module Sass::Script
|
|
2018
2056
|
# @overload unique_id()
|
2019
2057
|
# @return [Sass::Script::Value::String]
|
2020
2058
|
def unique_id
|
2021
|
-
|
2059
|
+
generator = Sass::Script::Functions.random_number_generator
|
2060
|
+
Thread.current[:sass_last_unique_id] ||= generator.rand(36**8)
|
2022
2061
|
# avoid the temptation of trying to guess the next unique value.
|
2023
|
-
value = (Thread.current[:sass_last_unique_id] += (rand(10) + 1))
|
2062
|
+
value = (Thread.current[:sass_last_unique_id] += (generator.rand(10) + 1))
|
2024
2063
|
# the u makes this a legal identifier if it would otherwise start with a number.
|
2025
2064
|
identifier("u" + value.to_s(36).rjust(8, '0'))
|
2026
2065
|
end
|
@@ -2050,7 +2089,7 @@ module Sass::Script
|
|
2050
2089
|
nil,
|
2051
2090
|
nil)
|
2052
2091
|
funcall.options = options
|
2053
|
-
|
2092
|
+
perform(funcall)
|
2054
2093
|
end
|
2055
2094
|
declare :call, [:name], :var_args => true, :var_kwargs => true
|
2056
2095
|
|
@@ -2097,7 +2136,7 @@ module Sass::Script
|
|
2097
2136
|
# @return [Sass::Script::Bool] Whether the variable is defined in
|
2098
2137
|
# the current scope.
|
2099
2138
|
def variable_exists(name)
|
2100
|
-
assert_type name, :String
|
2139
|
+
assert_type name, :String, :name
|
2101
2140
|
bool(environment.caller.var(name.value))
|
2102
2141
|
end
|
2103
2142
|
declare :variable_exists, [:name]
|
@@ -2118,7 +2157,7 @@ module Sass::Script
|
|
2118
2157
|
# @return [Sass::Script::Bool] Whether the variable is defined in
|
2119
2158
|
# the global scope.
|
2120
2159
|
def global_variable_exists(name)
|
2121
|
-
assert_type name, :String
|
2160
|
+
assert_type name, :String, :name
|
2122
2161
|
bool(environment.global_env.var(name.value))
|
2123
2162
|
end
|
2124
2163
|
declare :global_variable_exists, [:name]
|
@@ -2134,7 +2173,7 @@ module Sass::Script
|
|
2134
2173
|
# check.
|
2135
2174
|
# @return [Sass::Script::Bool] Whether the function is defined.
|
2136
2175
|
def function_exists(name)
|
2137
|
-
assert_type name, :String
|
2176
|
+
assert_type name, :String, :name
|
2138
2177
|
exists = Sass::Script::Functions.callable?(name.value.tr("-", "_"))
|
2139
2178
|
exists ||= environment.function(name.value)
|
2140
2179
|
bool(exists)
|
@@ -2152,12 +2191,11 @@ module Sass::Script
|
|
2152
2191
|
# check.
|
2153
2192
|
# @return [Sass::Script::Bool] Whether the mixin is defined.
|
2154
2193
|
def mixin_exists(name)
|
2155
|
-
assert_type name, :String
|
2194
|
+
assert_type name, :String, :name
|
2156
2195
|
bool(environment.mixin(name.value))
|
2157
2196
|
end
|
2158
2197
|
declare :mixin_exists, [:name]
|
2159
2198
|
|
2160
|
-
|
2161
2199
|
# Return a string containing the value as its Sass representation.
|
2162
2200
|
#
|
2163
2201
|
# @param value [Sass::Script::Value::Base] The value to inspect.
|
@@ -2168,6 +2206,30 @@ module Sass::Script
|
|
2168
2206
|
end
|
2169
2207
|
declare :inspect, [:value]
|
2170
2208
|
|
2209
|
+
# @overload random()
|
2210
|
+
# Return a decimal between 0 and 1, inclusive of 0 but not 1.
|
2211
|
+
# @return [Sass::Script::Number] A decimal value.
|
2212
|
+
# @overload random($limit)
|
2213
|
+
# Return an integer between 1 and `$limit`, inclusive of 1 but not `$limit`.
|
2214
|
+
# @param $limit [Sass::Script::Value::Number] The maximum of the random integer to be
|
2215
|
+
# returned, a positive integer.
|
2216
|
+
# @return [Sass::Script::Number] An integer.
|
2217
|
+
# @raise [ArgumentError] if the `$limit` is not 1 or greater
|
2218
|
+
def random(limit = nil)
|
2219
|
+
generator = Sass::Script::Functions.random_number_generator
|
2220
|
+
if limit
|
2221
|
+
assert_integer limit, "limit"
|
2222
|
+
if limit.value < 1
|
2223
|
+
raise ArgumentError.new("$limit #{limit} must be greater than or equal to 1")
|
2224
|
+
end
|
2225
|
+
number(1 + generator.rand(limit.value))
|
2226
|
+
else
|
2227
|
+
number(generator.rand)
|
2228
|
+
end
|
2229
|
+
end
|
2230
|
+
declare :random, []
|
2231
|
+
declare :random, [:limit]
|
2232
|
+
|
2171
2233
|
private
|
2172
2234
|
|
2173
2235
|
# This method implements the pattern of transforming a numeric value into
|