sass 3.3.0 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +1 -1
  3. data/README.md +58 -50
  4. data/Rakefile +1 -4
  5. data/VERSION +1 -1
  6. data/VERSION_DATE +1 -1
  7. data/VERSION_NAME +1 -1
  8. data/bin/sass +1 -1
  9. data/bin/scss +1 -1
  10. data/lib/sass/cache_stores/filesystem.rb +6 -2
  11. data/lib/sass/css.rb +1 -3
  12. data/lib/sass/engine.rb +37 -46
  13. data/lib/sass/environment.rb +13 -17
  14. data/lib/sass/error.rb +6 -9
  15. data/lib/sass/exec/base.rb +187 -0
  16. data/lib/sass/exec/sass_convert.rb +264 -0
  17. data/lib/sass/exec/sass_scss.rb +424 -0
  18. data/lib/sass/exec.rb +5 -771
  19. data/lib/sass/features.rb +7 -0
  20. data/lib/sass/importers/base.rb +7 -2
  21. data/lib/sass/importers/filesystem.rb +9 -25
  22. data/lib/sass/importers.rb +0 -1
  23. data/lib/sass/media.rb +1 -4
  24. data/lib/sass/plugin/compiler.rb +200 -83
  25. data/lib/sass/plugin/staleness_checker.rb +1 -1
  26. data/lib/sass/plugin.rb +3 -3
  27. data/lib/sass/script/css_lexer.rb +1 -1
  28. data/lib/sass/script/functions.rb +622 -268
  29. data/lib/sass/script/lexer.rb +99 -34
  30. data/lib/sass/script/parser.rb +24 -23
  31. data/lib/sass/script/tree/funcall.rb +1 -1
  32. data/lib/sass/script/tree/interpolation.rb +20 -2
  33. data/lib/sass/script/tree/selector.rb +26 -0
  34. data/lib/sass/script/tree/string_interpolation.rb +1 -1
  35. data/lib/sass/script/tree.rb +1 -0
  36. data/lib/sass/script/value/base.rb +7 -5
  37. data/lib/sass/script/value/bool.rb +0 -5
  38. data/lib/sass/script/value/color.rb +39 -21
  39. data/lib/sass/script/value/helpers.rb +107 -0
  40. data/lib/sass/script/value/list.rb +0 -15
  41. data/lib/sass/script/value/null.rb +0 -5
  42. data/lib/sass/script/value/number.rb +62 -14
  43. data/lib/sass/script/value/string.rb +59 -11
  44. data/lib/sass/script/value.rb +0 -1
  45. data/lib/sass/scss/css_parser.rb +8 -2
  46. data/lib/sass/scss/parser.rb +190 -328
  47. data/lib/sass/scss/rx.rb +15 -6
  48. data/lib/sass/scss/static_parser.rb +298 -1
  49. data/lib/sass/selector/abstract_sequence.rb +28 -13
  50. data/lib/sass/selector/comma_sequence.rb +92 -13
  51. data/lib/sass/selector/pseudo.rb +256 -0
  52. data/lib/sass/selector/sequence.rb +94 -24
  53. data/lib/sass/selector/simple.rb +14 -25
  54. data/lib/sass/selector/simple_sequence.rb +97 -33
  55. data/lib/sass/selector.rb +57 -194
  56. data/lib/sass/shared.rb +1 -1
  57. data/lib/sass/source/map.rb +26 -12
  58. data/lib/sass/stack.rb +0 -6
  59. data/lib/sass/supports.rb +2 -3
  60. data/lib/sass/tree/at_root_node.rb +1 -0
  61. data/lib/sass/tree/charset_node.rb +1 -1
  62. data/lib/sass/tree/directive_node.rb +8 -2
  63. data/lib/sass/tree/error_node.rb +18 -0
  64. data/lib/sass/tree/extend_node.rb +1 -1
  65. data/lib/sass/tree/function_node.rb +4 -0
  66. data/lib/sass/tree/keyframe_rule_node.rb +15 -0
  67. data/lib/sass/tree/prop_node.rb +1 -1
  68. data/lib/sass/tree/rule_node.rb +12 -7
  69. data/lib/sass/tree/visitors/check_nesting.rb +38 -10
  70. data/lib/sass/tree/visitors/convert.rb +16 -18
  71. data/lib/sass/tree/visitors/cssize.rb +29 -29
  72. data/lib/sass/tree/visitors/deep_copy.rb +5 -0
  73. data/lib/sass/tree/visitors/perform.rb +45 -33
  74. data/lib/sass/tree/visitors/set_options.rb +14 -0
  75. data/lib/sass/tree/visitors/to_css.rb +15 -14
  76. data/lib/sass/util/subset_map.rb +1 -1
  77. data/lib/sass/util.rb +222 -99
  78. data/lib/sass/version.rb +5 -5
  79. data/lib/sass.rb +0 -5
  80. data/test/sass/cache_test.rb +62 -20
  81. data/test/sass/callbacks_test.rb +1 -1
  82. data/test/sass/compiler_test.rb +19 -10
  83. data/test/sass/conversion_test.rb +58 -1
  84. data/test/sass/css2sass_test.rb +23 -4
  85. data/test/sass/encoding_test.rb +219 -0
  86. data/test/sass/engine_test.rb +136 -199
  87. data/test/sass/exec_test.rb +2 -2
  88. data/test/sass/extend_test.rb +236 -19
  89. data/test/sass/functions_test.rb +295 -253
  90. data/test/sass/importer_test.rb +31 -21
  91. data/test/sass/logger_test.rb +1 -1
  92. data/test/sass/more_results/more_import.css +1 -1
  93. data/test/sass/plugin_test.rb +14 -13
  94. data/test/sass/results/compact.css +1 -1
  95. data/test/sass/results/complex.css +4 -4
  96. data/test/sass/results/expanded.css +1 -1
  97. data/test/sass/results/import.css +1 -1
  98. data/test/sass/results/import_charset_ibm866.css +2 -2
  99. data/test/sass/results/mixins.css +17 -17
  100. data/test/sass/results/nested.css +1 -1
  101. data/test/sass/results/parent_ref.css +2 -2
  102. data/test/sass/results/script.css +3 -3
  103. data/test/sass/results/scss_import.css +1 -1
  104. data/test/sass/script_conversion_test.rb +10 -7
  105. data/test/sass/script_test.rb +288 -74
  106. data/test/sass/scss/css_test.rb +141 -24
  107. data/test/sass/scss/rx_test.rb +4 -4
  108. data/test/sass/scss/scss_test.rb +457 -18
  109. data/test/sass/source_map_test.rb +115 -25
  110. data/test/sass/superselector_test.rb +191 -0
  111. data/test/sass/templates/scss_import.scss +2 -1
  112. data/test/sass/test_helper.rb +1 -1
  113. data/test/sass/util/multibyte_string_scanner_test.rb +1 -1
  114. data/test/sass/util/normalized_map_test.rb +1 -1
  115. data/test/sass/util/subset_map_test.rb +2 -2
  116. data/test/sass/util_test.rb +31 -1
  117. data/test/sass/value_helpers_test.rb +5 -7
  118. data/test/test_helper.rb +2 -2
  119. data/vendor/listen/CHANGELOG.md +1 -228
  120. data/vendor/listen/Gemfile +5 -15
  121. data/vendor/listen/README.md +111 -77
  122. data/vendor/listen/Rakefile +0 -42
  123. data/vendor/listen/lib/listen/adapter.rb +195 -82
  124. data/vendor/listen/lib/listen/adapters/bsd.rb +27 -64
  125. data/vendor/listen/lib/listen/adapters/darwin.rb +21 -58
  126. data/vendor/listen/lib/listen/adapters/linux.rb +23 -55
  127. data/vendor/listen/lib/listen/adapters/polling.rb +25 -34
  128. data/vendor/listen/lib/listen/adapters/windows.rb +50 -46
  129. data/vendor/listen/lib/listen/directory_record.rb +96 -61
  130. data/vendor/listen/lib/listen/listener.rb +135 -37
  131. data/vendor/listen/lib/listen/turnstile.rb +9 -5
  132. data/vendor/listen/lib/listen/version.rb +1 -1
  133. data/vendor/listen/lib/listen.rb +33 -19
  134. data/vendor/listen/listen.gemspec +6 -0
  135. data/vendor/listen/spec/listen/adapter_spec.rb +43 -77
  136. data/vendor/listen/spec/listen/adapters/polling_spec.rb +8 -8
  137. data/vendor/listen/spec/listen/directory_record_spec.rb +81 -56
  138. data/vendor/listen/spec/listen/listener_spec.rb +128 -39
  139. data/vendor/listen/spec/listen_spec.rb +15 -21
  140. data/vendor/listen/spec/spec_helper.rb +4 -0
  141. data/vendor/listen/spec/support/adapter_helper.rb +52 -15
  142. data/vendor/listen/spec/support/directory_record_helper.rb +7 -5
  143. data/vendor/listen/spec/support/listeners_helper.rb +30 -7
  144. metadata +25 -22
  145. data/ext/mkrf_conf.rb +0 -27
  146. data/lib/sass/importers/deprecated_path.rb +0 -51
  147. data/lib/sass/script/value/deprecated_false.rb +0 -55
  148. data/vendor/listen/lib/listen/dependency_manager.rb +0 -126
  149. data/vendor/listen/lib/listen/multi_listener.rb +0 -143
  150. data/vendor/listen/spec/listen/dependency_manager_spec.rb +0 -107
  151. 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)}
@@ -193,8 +193,8 @@ module Sass::Script
193
193
  # \{#map_merge map-merge($map1, $map2)}
194
194
  # : Merges two maps together into a new map.
195
195
  #
196
- # \{#map_remove map-remove($map, $key)}
197
- # : Returns a new map with a key removed.
196
+ # \{#map_remove map-remove($map, $keys...)}
197
+ # : Returns a new map with keys removed.
198
198
  #
199
199
  # \{#map_keys map-keys($map)}
200
200
  # : Returns a list of all keys in a map.
@@ -202,12 +202,54 @@ module Sass::Script
202
202
  # \{#map_values map-values($map)}
203
203
  # : Returns a list of all values in a map.
204
204
  #
205
- # \{#map_has_key map-has-key($key)}
205
+ # \{#map_has_key map-has-key($map, $key)}
206
206
  # : Returns whether a map has a value associated with a given key.
207
207
  #
208
208
  # \{#keywords keywords($args)}
209
209
  # : Returns the keywords passed to a function that takes variable arguments.
210
210
  #
211
+ # ## Selector Functions
212
+ #
213
+ # Selector functions are very liberal in the formats they support
214
+ # for selector arguments. They can take a plain string, a list of
215
+ # lists as returned by `&` or anything in between:
216
+ #
217
+ # * A plain sring, such as `".foo .bar, .baz .bang"`.
218
+ # * A space-separated list of strings such as `(".foo" ".bar")`.
219
+ # * A comma-separated list of strings such as `(".foo .bar", ".baz .bang")`.
220
+ # * A comma-separated list of space-separated lists of strings such
221
+ # as `((".foo" ".bar"), (".baz" ".bang"))`.
222
+ #
223
+ # In general, selector functions allow placeholder selectors
224
+ # (`%foo`) but disallow parent-reference selectors (`&`).
225
+ #
226
+ # \{#selector_nest selector-nest($selectors...)}
227
+ # : Nests selector beneath one another like they would be nested in the
228
+ # stylesheet.
229
+ #
230
+ # \{#selector_append selector-append($selectors...)}
231
+ # : Appends selectors to one another without spaces in between.
232
+ #
233
+ # \{#selector_extend selector-extend($selector, $extendee, $extender)}
234
+ # : Extends `$extendee` with `$extender` within `$selector`.
235
+ #
236
+ # \{#selector_replace selector-replace($selector, $original, $replacement)}
237
+ # : Replaces `$original` with `$replacement` within `$selector`.
238
+ #
239
+ # \{#selector_unify selector-unify($selector1, $selector2)}
240
+ # : Unifies two selectors to produce a selector that matches
241
+ # elements matched by both.
242
+ #
243
+ # \{#is_superselector is-superselector($super, $sub)}
244
+ # : Returns whether `$super` matches all the elements `$sub` does, and
245
+ # possibly more.
246
+ #
247
+ # \{#simple_selectors simple-selectors($selector)}
248
+ # : Returns the simple selectors that comprise a compound selector.
249
+ #
250
+ # \{#selector_parse selector-parse($selector)}
251
+ # : Parses a selector into the format returned by `&`.
252
+ #
211
253
  # ## Introspection Functions
212
254
  #
213
255
  # \{#feature_exists feature-exists($feature)}
@@ -302,6 +344,9 @@ module Sass::Script
302
344
  # safe to call {Value::Base#to_s #to_s} (or other methods that use the string
303
345
  # representation) on those objects without first setting {Tree::Node#options=
304
346
  # the #options attribute}.
347
+ #
348
+ # @comment
349
+ # rubocop:enable LineLength
305
350
  module Functions
306
351
  @signatures = {}
307
352
 
@@ -474,7 +519,7 @@ module Sass::Script
474
519
  def assert_type(value, type, name = nil)
475
520
  klass = Sass::Script::Value.const_get(type)
476
521
  return if value.is_a?(klass)
477
- return if value.is_a?(Sass::Script::Value::List) && type == :Map && value.is_pseudo_map?
522
+ return if value.is_a?(Sass::Script::Value::List) && type == :Map && value.value.empty?
478
523
  err = "#{value.inspect} is not a #{TYPE_NAMES[type] || type.to_s.downcase}"
479
524
  err = "$#{name.to_s.gsub('_', '-')}: " + err if name
480
525
  raise ArgumentError.new(err)
@@ -565,15 +610,15 @@ module Sass::Script
565
610
  #
566
611
  # @see #rgba
567
612
  # @overload rgb($red, $green, $blue)
568
- # @param $red [Sass::Script::Value::Number] The amount of red in the color.
569
- # Must be between 0 and 255 inclusive, or between `0%` and `100%`
570
- # inclusive
571
- # @param $green [Sass::Script::Value::Number] The amount of green in the
572
- # color. Must be between 0 and 255 inclusive, or between `0%` and `100%`
573
- # inclusive
574
- # @param $blue [Sass::Script::Value::Number] The amount of blue in the
575
- # color. Must be between 0 and 255 inclusive, or between `0%` and `100%`
576
- # inclusive
613
+ # @param $red [Sass::Script::Value::Number] The amount of red in the color.
614
+ # Must be between 0 and 255 inclusive, or between `0%` and `100%`
615
+ # inclusive
616
+ # @param $green [Sass::Script::Value::Number] The amount of green in the
617
+ # color. Must be between 0 and 255 inclusive, or between `0%` and `100%`
618
+ # inclusive
619
+ # @param $blue [Sass::Script::Value::Number] The amount of blue in the
620
+ # color. Must be between 0 and 255 inclusive, or between `0%` and `100%`
621
+ # inclusive
577
622
  # @return [Sass::Script::Value::Color]
578
623
  # @raise [ArgumentError] if any parameter is the wrong type or out of bounds
579
624
  def rgb(red, green, blue)
@@ -583,14 +628,17 @@ module Sass::Script
583
628
 
584
629
  color_attrs = [[red, :red], [green, :green], [blue, :blue]].map do |(c, name)|
585
630
  if c.is_unit?("%")
586
- v = Sass::Util.check_range("$#{name}: Color value", 0..100, c, '%')
587
- v * 255 / 100.0
631
+ c.value * 255 / 100.0
588
632
  elsif c.unitless?
589
- Sass::Util.check_range("$#{name}: Color value", 0..255, c)
633
+ c.value
590
634
  else
591
635
  raise ArgumentError.new("Expected #{c} to be unitless or have a unit of % but got #{c}")
592
636
  end
593
637
  end
638
+
639
+ # Don't store the string representation for function-created colors, both
640
+ # because it's not very useful and because some functions aren't supported
641
+ # on older browsers.
594
642
  Sass::Script::Value::Color.new(color_attrs)
595
643
  end
596
644
  declare :rgb, [:red, :green, :blue]
@@ -634,7 +682,6 @@ module Sass::Script
634
682
  assert_type color, :Color, :color
635
683
  assert_type alpha, :Number, :alpha
636
684
 
637
- Sass::Util.check_range('Alpha channel', 0..1, alpha)
638
685
  color.with(:alpha => alpha.value)
639
686
  when 4
640
687
  red, green, blue, alpha = args
@@ -653,12 +700,12 @@ module Sass::Script
653
700
  #
654
701
  # @see #hsla
655
702
  # @overload hsl($hue, $saturation, $lightness)
656
- # @param $hue [Sass::Script::Value::Number] The hue of the color. Should be
657
- # between 0 and 360 degrees, inclusive
658
- # @param $saturation [Sass::Script::Value::Number] The saturation of the
659
- # color. Must be between `0%` and `100%`, inclusive
660
- # @param $lightness [Sass::Script::Value::Number] The lightness of the
661
- # color. Must be between `0%` and `100%`, inclusive
703
+ # @param $hue [Sass::Script::Value::Number] The hue of the color. Should be
704
+ # between 0 and 360 degrees, inclusive
705
+ # @param $saturation [Sass::Script::Value::Number] The saturation of the
706
+ # color. Must be between `0%` and `100%`, inclusive
707
+ # @param $lightness [Sass::Script::Value::Number] The lightness of the
708
+ # color. Must be between `0%` and `100%`, inclusive
662
709
  # @return [Sass::Script::Value::Color]
663
710
  # @raise [ArgumentError] if `$saturation` or `$lightness` are out of bounds
664
711
  # or any parameter is the wrong type
@@ -675,14 +722,14 @@ module Sass::Script
675
722
  #
676
723
  # @see #hsl
677
724
  # @overload hsla($hue, $saturation, $lightness, $alpha)
678
- # @param $hue [Sass::Script::Value::Number] The hue of the color. Should be
679
- # between 0 and 360 degrees, inclusive
680
- # @param $saturation [Sass::Script::Value::Number] The saturation of the
681
- # color. Must be between `0%` and `100%`, inclusive
682
- # @param $lightness [Sass::Script::Value::Number] The lightness of the
683
- # color. Must be between `0%` and `100%`, inclusive
684
- # @param $alpha [Sass::Script::Value::Number] The opacity of the color. Must
685
- # be between 0 and 1, inclusive
725
+ # @param $hue [Sass::Script::Value::Number] The hue of the color. Should be
726
+ # between 0 and 360 degrees, inclusive
727
+ # @param $saturation [Sass::Script::Value::Number] The saturation of the
728
+ # color. Must be between `0%` and `100%`, inclusive
729
+ # @param $lightness [Sass::Script::Value::Number] The lightness of the
730
+ # color. Must be between `0%` and `100%`, inclusive
731
+ # @param $alpha [Sass::Script::Value::Number] The opacity of the color. Must
732
+ # be between 0 and 1, inclusive
686
733
  # @return [Sass::Script::Value::Color]
687
734
  # @raise [ArgumentError] if `$saturation`, `$lightness`, or `$alpha` are out
688
735
  # of bounds or any parameter is the wrong type
@@ -692,12 +739,13 @@ module Sass::Script
692
739
  assert_type lightness, :Number, :lightness
693
740
  assert_type alpha, :Number, :alpha
694
741
 
695
- Sass::Util.check_range('Alpha channel', 0..1, alpha)
696
-
697
742
  h = hue.value
698
- s = Sass::Util.check_range('Saturation', 0..100, saturation, '%')
699
- l = Sass::Util.check_range('Lightness', 0..100, lightness, '%')
743
+ s = saturation.value
744
+ l = lightness.value
700
745
 
746
+ # Don't store the string representation for function-created colors, both
747
+ # because it's not very useful and because some functions aren't supported
748
+ # on older browsers.
701
749
  Sass::Script::Value::Color.new(
702
750
  :hue => h, :saturation => s, :lightness => l, :alpha => alpha.value)
703
751
  end
@@ -709,7 +757,7 @@ module Sass::Script
709
757
  # [hsl-to-rgb]: http://www.w3.org/TR/css3-color/#hsl-color
710
758
  #
711
759
  # @overload red($color)
712
- # @param $color [Sass::Script::Value::Color]
760
+ # @param $color [Sass::Script::Value::Color]
713
761
  # @return [Sass::Script::Value::Number] The red component, between 0 and 255
714
762
  # inclusive
715
763
  # @raise [ArgumentError] if `$color` isn't a color
@@ -725,7 +773,7 @@ module Sass::Script
725
773
  # [hsl-to-rgb]: http://www.w3.org/TR/css3-color/#hsl-color
726
774
  #
727
775
  # @overload green($color)
728
- # @param $color [Sass::Script::Value::Color]
776
+ # @param $color [Sass::Script::Value::Color]
729
777
  # @return [Sass::Script::Value::Number] The green component, between 0 and
730
778
  # 255 inclusive
731
779
  # @raise [ArgumentError] if `$color` isn't a color
@@ -741,7 +789,7 @@ module Sass::Script
741
789
  # [hsl-to-rgb]: http://www.w3.org/TR/css3-color/#hsl-color
742
790
  #
743
791
  # @overload blue($color)
744
- # @param $color [Sass::Script::Value::Color]
792
+ # @param $color [Sass::Script::Value::Color]
745
793
  # @return [Sass::Script::Value::Number] The blue component, between 0 and
746
794
  # 255 inclusive
747
795
  # @raise [ArgumentError] if `$color` isn't a color
@@ -759,7 +807,7 @@ module Sass::Script
759
807
  # [rgb-to-hsl]: http://en.wikipedia.org/wiki/HSL_and_HSV#Conversion_from_RGB_to_HSL_or_HSV
760
808
  #
761
809
  # @overload hue($color)
762
- # @param $color [Sass::Script::Value::Color]
810
+ # @param $color [Sass::Script::Value::Color]
763
811
  # @return [Sass::Script::Value::Number] The hue component, between 0deg and
764
812
  # 360deg
765
813
  # @raise [ArgumentError] if `$color` isn't a color
@@ -777,7 +825,7 @@ module Sass::Script
777
825
  # [rgb-to-hsl]: http://en.wikipedia.org/wiki/HSL_and_HSV#Conversion_from_RGB_to_HSL_or_HSV
778
826
  #
779
827
  # @overload saturation($color)
780
- # @param $color [Sass::Script::Value::Color]
828
+ # @param $color [Sass::Script::Value::Color]
781
829
  # @return [Sass::Script::Value::Number] The saturation component, between 0%
782
830
  # and 100%
783
831
  # @raise [ArgumentError] if `$color` isn't a color
@@ -795,7 +843,7 @@ module Sass::Script
795
843
  # [rgb-to-hsl]: http://en.wikipedia.org/wiki/HSL_and_HSV#Conversion_from_RGB_to_HSL_or_HSV
796
844
  #
797
845
  # @overload lightness($color)
798
- # @param $color [Sass::Script::Value::Color]
846
+ # @param $color [Sass::Script::Value::Color]
799
847
  # @return [Sass::Script::Value::Number] The lightness component, between 0%
800
848
  # and 100%
801
849
  # @raise [ArgumentError] if `$color` isn't a color
@@ -812,7 +860,7 @@ module Sass::Script
812
860
  # syntax as a special case.
813
861
  #
814
862
  # @overload alpha($color)
815
- # @param $color [Sass::Script::Value::Color]
863
+ # @param $color [Sass::Script::Value::Color]
816
864
  # @return [Sass::Script::Value::Number] The alpha component, between 0 and 1
817
865
  # @raise [ArgumentError] if `$color` isn't a color
818
866
  def alpha(*args)
@@ -835,7 +883,7 @@ module Sass::Script
835
883
  # otherwise specified.
836
884
  #
837
885
  # @overload opacity($color)
838
- # @param $color [Sass::Script::Value::Color]
886
+ # @param $color [Sass::Script::Value::Color]
839
887
  # @return [Sass::Script::Value::Number] The alpha component, between 0 and 1
840
888
  # @raise [ArgumentError] if `$color` isn't a color
841
889
  def opacity(color)
@@ -855,9 +903,9 @@ module Sass::Script
855
903
  # opacify(rgba(0, 0, 0, 0.5), 0.1) => rgba(0, 0, 0, 0.6)
856
904
  # opacify(rgba(0, 0, 17, 0.8), 0.2) => #001
857
905
  # @overload opacify($color, $amount)
858
- # @param $color [Sass::Script::Value::Color]
859
- # @param $amount [Sass::Script::Value::Number] The amount to increase the
860
- # opacity by, between 0 and 1
906
+ # @param $color [Sass::Script::Value::Color]
907
+ # @param $amount [Sass::Script::Value::Number] The amount to increase the
908
+ # opacity by, between 0 and 1
861
909
  # @return [Sass::Script::Value::Color]
862
910
  # @raise [ArgumentError] if `$amount` is out of bounds, or either parameter
863
911
  # is the wrong type
@@ -877,9 +925,9 @@ module Sass::Script
877
925
  # transparentize(rgba(0, 0, 0, 0.5), 0.1) => rgba(0, 0, 0, 0.4)
878
926
  # transparentize(rgba(0, 0, 0, 0.8), 0.2) => rgba(0, 0, 0, 0.6)
879
927
  # @overload transparentize($color, $amount)
880
- # @param $color [Sass::Script::Value::Color]
881
- # @param $amount [Sass::Script::Value::Number] The amount to decrease the
882
- # opacity by, between 0 and 1
928
+ # @param $color [Sass::Script::Value::Color]
929
+ # @param $amount [Sass::Script::Value::Number] The amount to decrease the
930
+ # opacity by, between 0 and 1
883
931
  # @return [Sass::Script::Value::Color]
884
932
  # @raise [ArgumentError] if `$amount` is out of bounds, or either parameter
885
933
  # is the wrong type
@@ -899,9 +947,9 @@ module Sass::Script
899
947
  # lighten(hsl(0, 0%, 0%), 30%) => hsl(0, 0, 30)
900
948
  # lighten(#800, 20%) => #e00
901
949
  # @overload lighten($color, $amount)
902
- # @param $color [Sass::Script::Value::Color]
903
- # @param $amount [Sass::Script::Value::Number] The amount to increase the
904
- # lightness by, between `0%` and `100%`
950
+ # @param $color [Sass::Script::Value::Color]
951
+ # @param $amount [Sass::Script::Value::Number] The amount to increase the
952
+ # lightness by, between `0%` and `100%`
905
953
  # @return [Sass::Script::Value::Color]
906
954
  # @raise [ArgumentError] if `$amount` is out of bounds, or either parameter
907
955
  # is the wrong type
@@ -918,9 +966,9 @@ module Sass::Script
918
966
  # darken(hsl(25, 100%, 80%), 30%) => hsl(25, 100%, 50%)
919
967
  # darken(#800, 20%) => #200
920
968
  # @overload darken($color, $amount)
921
- # @param $color [Sass::Script::Value::Color]
922
- # @param $amount [Sass::Script::Value::Number] The amount to dencrease the
923
- # lightness by, between `0%` and `100%`
969
+ # @param $color [Sass::Script::Value::Color]
970
+ # @param $amount [Sass::Script::Value::Number] The amount to decrease the
971
+ # lightness by, between `0%` and `100%`
924
972
  # @return [Sass::Script::Value::Color]
925
973
  # @raise [ArgumentError] if `$amount` is out of bounds, or either parameter
926
974
  # is the wrong type
@@ -937,9 +985,9 @@ module Sass::Script
937
985
  # saturate(hsl(120, 30%, 90%), 20%) => hsl(120, 50%, 90%)
938
986
  # saturate(#855, 20%) => #9e3f3f
939
987
  # @overload saturate($color, $amount)
940
- # @param $color [Sass::Script::Value::Color]
941
- # @param $amount [Sass::Script::Value::Number] The amount to increase the
942
- # saturation by, between `0%` and `100%`
988
+ # @param $color [Sass::Script::Value::Color]
989
+ # @param $amount [Sass::Script::Value::Number] The amount to increase the
990
+ # saturation by, between `0%` and `100%`
943
991
  # @return [Sass::Script::Value::Color]
944
992
  # @raise [ArgumentError] if `$amount` is out of bounds, or either parameter
945
993
  # is the wrong type
@@ -960,9 +1008,9 @@ module Sass::Script
960
1008
  # desaturate(hsl(120, 30%, 90%), 20%) => hsl(120, 10%, 90%)
961
1009
  # desaturate(#855, 20%) => #726b6b
962
1010
  # @overload desaturate($color, $amount)
963
- # @param $color [Sass::Script::Value::Color]
964
- # @param $amount [Sass::Script::Value::Number] The amount to decrease the
965
- # saturation by, between `0%` and `100%`
1011
+ # @param $color [Sass::Script::Value::Color]
1012
+ # @param $amount [Sass::Script::Value::Number] The amount to decrease the
1013
+ # saturation by, between `0%` and `100%`
966
1014
  # @return [Sass::Script::Value::Color]
967
1015
  # @raise [ArgumentError] if `$amount` is out of bounds, or either parameter
968
1016
  # is the wrong type
@@ -977,12 +1025,12 @@ module Sass::Script
977
1025
  #
978
1026
  # @example
979
1027
  # adjust-hue(hsl(120, 30%, 90%), 60deg) => hsl(180, 30%, 90%)
980
- # adjust-hue(hsl(120, 30%, 90%), 060deg) => hsl(60, 30%, 90%)
1028
+ # adjust-hue(hsl(120, 30%, 90%), -60deg) => hsl(60, 30%, 90%)
981
1029
  # adjust-hue(#811, 45deg) => #886a11
982
1030
  # @overload adjust_hue($color, $degrees)
983
- # @param $color [Sass::Script::Value::Color]
984
- # @param $degrees [Sass::Script::Value::Number] The number of degrees to
985
- # rotate the hue
1031
+ # @param $color [Sass::Script::Value::Color]
1032
+ # @param $degrees [Sass::Script::Value::Number] The number of degrees to
1033
+ # rotate the hue
986
1034
  # @return [Sass::Script::Value::Color]
987
1035
  # @raise [ArgumentError] if either parameter is the wrong type
988
1036
  def adjust_hue(color, degrees)
@@ -999,7 +1047,7 @@ module Sass::Script
999
1047
  # ie-hex-str(#3322BB) => #FF3322BB
1000
1048
  # ie-hex-str(rgba(0, 255, 0, 0.5)) => #8000FF00
1001
1049
  # @overload ie_hex_str($color)
1002
- # @param $color [Sass::Script::Value::Color]
1050
+ # @param $color [Sass::Script::Value::Color]
1003
1051
  # @return [Sass::Script::Value::String] The IE-formatted string
1004
1052
  # representation of the color
1005
1053
  # @raise [ArgumentError] if `$color` isn't a color
@@ -1023,23 +1071,26 @@ module Sass::Script
1023
1071
  # adjust-color(#102030, $blue: 5) => #102035
1024
1072
  # adjust-color(#102030, $red: -5, $blue: 5) => #0b2035
1025
1073
  # 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
- # [$hue], [$saturation], [$lightness], [$alpha])
1028
- # @param $color [Sass::Script::Value::Color]
1029
- # @param $red [Sass::Script::Value::Number] The adjustment to make on the
1030
- # red component, between -255 and 255 inclusive
1031
- # @param $green [Sass::Script::Value::Number] The adjustment to make on the
1032
- # green component, between -255 and 255 inclusive
1033
- # @param $blue [Sass::Script::Value::Number] The adjustment to make on the
1034
- # blue component, between -255 and 255 inclusive
1035
- # @param $hue [Sass::Script::Value::Number] The adjustment to make on the
1036
- # hue component, in degrees
1037
- # @param $saturation [Sass::Script::Value::Number] The adjustment to make on
1038
- # the saturation component, between `-100%` and `100%` inclusive
1039
- # @param $lightness [Sass::Script::Value::Number] The adjustment to make on
1040
- # the lightness component, between `-100%` and `100%` inclusive
1041
- # @param $alpha [Sass::Script::Value::Number] The adjustment to make on the
1042
- # alpha component, between -1 and 1 inclusive
1074
+ # @comment
1075
+ # rubocop:disable LineLength
1076
+ # @overload adjust_color($color, [$red], [$green], [$blue], [$hue], [$saturation], [$lightness], [$alpha])
1077
+ # @comment
1078
+ # rubocop:disable LineLength
1079
+ # @param $color [Sass::Script::Value::Color]
1080
+ # @param $red [Sass::Script::Value::Number] The adjustment to make on the
1081
+ # red component, between -255 and 255 inclusive
1082
+ # @param $green [Sass::Script::Value::Number] The adjustment to make on the
1083
+ # green component, between -255 and 255 inclusive
1084
+ # @param $blue [Sass::Script::Value::Number] The adjustment to make on the
1085
+ # blue component, between -255 and 255 inclusive
1086
+ # @param $hue [Sass::Script::Value::Number] The adjustment to make on the
1087
+ # hue component, in degrees
1088
+ # @param $saturation [Sass::Script::Value::Number] The adjustment to make on
1089
+ # the saturation component, between `-100%` and `100%` inclusive
1090
+ # @param $lightness [Sass::Script::Value::Number] The adjustment to make on
1091
+ # the lightness component, between `-100%` and `100%` inclusive
1092
+ # @param $alpha [Sass::Script::Value::Number] The adjustment to make on the
1093
+ # alpha component, between -1 and 1 inclusive
1043
1094
  # @return [Sass::Script::Value::Color]
1044
1095
  # @raise [ArgumentError] if any parameter is the wrong type or out-of
1045
1096
  # bounds, or if RGB properties and HSL properties are adjusted at the
@@ -1101,15 +1152,18 @@ module Sass::Script
1101
1152
  # scale-color(hsl(120, 70%, 80%), $lightness: 50%) => hsl(120, 70%, 90%)
1102
1153
  # scale-color(rgb(200, 150%, 170%), $green: -40%, $blue: 70%) => rgb(200, 90, 229)
1103
1154
  # 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
- # [$saturation], [$lightness], [$alpha])
1106
- # @param $color [Sass::Script::Value::Color]
1107
- # @param $red [Sass::Script::Value::Number]
1108
- # @param $green [Sass::Script::Value::Number]
1109
- # @param $blue [Sass::Script::Value::Number]
1110
- # @param $saturation [Sass::Script::Value::Number]
1111
- # @param $lightness [Sass::Script::Value::Number]
1112
- # @param $alpha [Sass::Script::Value::Number]
1155
+ # @comment
1156
+ # rubocop:disable LineLength
1157
+ # @overload scale_color($color, [$red], [$green], [$blue], [$saturation], [$lightness], [$alpha])
1158
+ # @comment
1159
+ # rubocop:disable LineLength
1160
+ # @param $color [Sass::Script::Value::Color]
1161
+ # @param $red [Sass::Script::Value::Number]
1162
+ # @param $green [Sass::Script::Value::Number]
1163
+ # @param $blue [Sass::Script::Value::Number]
1164
+ # @param $saturation [Sass::Script::Value::Number]
1165
+ # @param $lightness [Sass::Script::Value::Number]
1166
+ # @param $alpha [Sass::Script::Value::Number]
1113
1167
  # @return [Sass::Script::Value::Color]
1114
1168
  # @raise [ArgumentError] if any parameter is the wrong type or out-of
1115
1169
  # bounds, or if RGB properties and HSL properties are adjusted at the
@@ -1159,35 +1213,53 @@ module Sass::Script
1159
1213
  # change-color(#102030, $blue: 5) => #102005
1160
1214
  # change-color(#102030, $red: 120, $blue: 5) => #782005
1161
1215
  # 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
- # [$saturation], [$lightness], [$alpha])
1164
- # @param $color [Sass::Script::Value::Color]
1165
- # @param $red [Sass::Script::Value::Number] The new red component for the
1166
- # color, within 0 and 255 inclusive
1167
- # @param $green [Sass::Script::Value::Number] The new green component for
1168
- # the color, within 0 and 255 inclusive
1169
- # @param $blue [Sass::Script::Value::Number] The new blue component for the
1170
- # color, within 0 and 255 inclusive
1171
- # @param $hue [Sass::Script::Value::Number] The new hue component for the
1172
- # color, in degrees
1173
- # @param $saturation [Sass::Script::Value::Number] The new saturation
1174
- # component for the color, between `0%` and `100%` inclusive
1175
- # @param $lightness [Sass::Script::Value::Number] The new lightness
1176
- # component for the color, within `0%` and `100%` inclusive
1177
- # @param $alpha [Sass::Script::Value::Number] The new alpha component for
1178
- # the color, within 0 and 1 inclusive
1216
+ # @comment
1217
+ # rubocop:disable LineLength
1218
+ # @overload change_color($color, [$red], [$green], [$blue], [$hue], [$saturation], [$lightness], [$alpha])
1219
+ # @comment
1220
+ # rubocop:disable LineLength
1221
+ # @param $color [Sass::Script::Value::Color]
1222
+ # @param $red [Sass::Script::Value::Number] The new red component for the
1223
+ # color, within 0 and 255 inclusive
1224
+ # @param $green [Sass::Script::Value::Number] The new green component for
1225
+ # the color, within 0 and 255 inclusive
1226
+ # @param $blue [Sass::Script::Value::Number] The new blue component for the
1227
+ # color, within 0 and 255 inclusive
1228
+ # @param $hue [Sass::Script::Value::Number] The new hue component for the
1229
+ # color, in degrees
1230
+ # @param $saturation [Sass::Script::Value::Number] The new saturation
1231
+ # component for the color, between `0%` and `100%` inclusive
1232
+ # @param $lightness [Sass::Script::Value::Number] The new lightness
1233
+ # component for the color, within `0%` and `100%` inclusive
1234
+ # @param $alpha [Sass::Script::Value::Number] The new alpha component for
1235
+ # the color, within 0 and 1 inclusive
1179
1236
  # @return [Sass::Script::Value::Color]
1180
1237
  # @raise [ArgumentError] if any parameter is the wrong type or out-of
1181
1238
  # bounds, or if RGB properties and HSL properties are adjusted at the
1182
1239
  # same time
1183
1240
  def change_color(color, kwargs)
1184
1241
  assert_type color, :Color, :color
1185
- with = Sass::Util.to_hash(%w[red green blue hue saturation lightness alpha].map do |name|
1242
+ with = Sass::Util.map_hash(
1243
+ 'red' => ['Red value', 0..255],
1244
+ 'green' => ['Green value', 0..255],
1245
+ 'blue' => ['Blue value', 0..255],
1246
+ 'hue' => [],
1247
+ 'saturation' => ['Saturation', 0..100, '%'],
1248
+ 'lightness' => ['Lightness', 0..100, '%'],
1249
+ 'alpha' => ['Alpha channel', 0..1]
1250
+ ) do |name, (desc, range, unit)|
1186
1251
  val = kwargs.delete(name)
1187
1252
  next unless val
1188
1253
  assert_type val, :Number, name
1189
- [name.to_sym, val.value]
1190
- end)
1254
+
1255
+ if range
1256
+ val = Sass::Util.check_range(desc, range, val, unit)
1257
+ else
1258
+ val = val.value
1259
+ end
1260
+
1261
+ [name.to_sym, val]
1262
+ end
1191
1263
 
1192
1264
  unless kwargs.empty?
1193
1265
  name, val = kwargs.to_a.first
@@ -1212,11 +1284,11 @@ module Sass::Script
1212
1284
  # mix(#f00, #00f, 25%) => #3f00bf
1213
1285
  # mix(rgba(255, 0, 0, 0.5), #00f) => rgba(63, 0, 191, 0.75)
1214
1286
  # @overload mix($color1, $color2, $weight: 50%)
1215
- # @param $color1 [Sass::Script::Value::Color]
1216
- # @param $color2 [Sass::Script::Value::Color]
1217
- # @param $weight [Sass::Script::Value::Number] The relative weight of each
1218
- # color. Closer to `0%` gives more weight to `$color`, closer to `100%`
1219
- # gives more weight to `$color2`
1287
+ # @param $color1 [Sass::Script::Value::Color]
1288
+ # @param $color2 [Sass::Script::Value::Color]
1289
+ # @param $weight [Sass::Script::Value::Number] The relative weight of each
1290
+ # color. Closer to `0%` gives more weight to `$color`, closer to `100%`
1291
+ # gives more weight to `$color2`
1220
1292
  # @return [Sass::Script::Value::Color]
1221
1293
  # @raise [ArgumentError] if `$weight` is out of bounds or any parameter is
1222
1294
  # the wrong type
@@ -1257,15 +1329,15 @@ module Sass::Script
1257
1329
  rgba << color1.alpha * p + color2.alpha * (1 - p)
1258
1330
  rgb_color(*rgba)
1259
1331
  end
1260
- declare :mix, [:color1, :color2], :deprecated => [:color_1, :color_2]
1261
- declare :mix, [:color1, :color2, :weight], :deprecated => [:color_1, :color_2, :weight]
1332
+ declare :mix, [:color1, :color2]
1333
+ declare :mix, [:color1, :color2, :weight]
1262
1334
 
1263
1335
  # Converts a color to grayscale. This is identical to `desaturate(color,
1264
1336
  # 100%)`.
1265
1337
  #
1266
1338
  # @see #desaturate
1267
1339
  # @overload grayscale($color)
1268
- # @param $color [Sass::Script::Value::Color]
1340
+ # @param $color [Sass::Script::Value::Color]
1269
1341
  # @return [Sass::Script::Value::Color]
1270
1342
  # @raise [ArgumentError] if `$color` isn't a color
1271
1343
  def grayscale(color)
@@ -1281,7 +1353,7 @@ module Sass::Script
1281
1353
  #
1282
1354
  # @see #adjust_hue #adjust-hue
1283
1355
  # @overload complement($color)
1284
- # @param $color [Sass::Script::Value::Color]
1356
+ # @param $color [Sass::Script::Value::Color]
1285
1357
  # @return [Sass::Script::Value::Color]
1286
1358
  # @raise [ArgumentError] if `$color` isn't a color
1287
1359
  def complement(color)
@@ -1293,7 +1365,7 @@ module Sass::Script
1293
1365
  # are inverted, while the opacity is left alone.
1294
1366
  #
1295
1367
  # @overload invert($color)
1296
- # @param $color [Sass::Script::Value::Color]
1368
+ # @param $color [Sass::Script::Value::Color]
1297
1369
  # @return [Sass::Script::Value::Color]
1298
1370
  # @raise [ArgumentError] if `$color` isn't a color
1299
1371
  def invert(color)
@@ -1317,7 +1389,7 @@ module Sass::Script
1317
1389
  # unquote("foo") => foo
1318
1390
  # unquote(foo) => foo
1319
1391
  # @overload unquote($string)
1320
- # @param $string [Sass::Script::Value::String]
1392
+ # @param $string [Sass::Script::Value::String]
1321
1393
  # @return [Sass::Script::Value::String]
1322
1394
  # @raise [ArgumentError] if `$string` isn't a string
1323
1395
  def unquote(string)
@@ -1337,7 +1409,7 @@ module Sass::Script
1337
1409
  # quote("foo") => "foo"
1338
1410
  # quote(foo) => "foo"
1339
1411
  # @overload quote($string)
1340
- # @param $string [Sass::Script::Value::String]
1412
+ # @param $string [Sass::Script::Value::String]
1341
1413
  # @return [Sass::Script::Value::String]
1342
1414
  # @raise [ArgumentError] if `$string` isn't a string
1343
1415
  def quote(string)
@@ -1355,7 +1427,7 @@ module Sass::Script
1355
1427
  # @example
1356
1428
  # str-length("foo") => 3
1357
1429
  # @overload str_length($string)
1358
- # @param $string [Sass::Script::Value::String]
1430
+ # @param $string [Sass::Script::Value::String]
1359
1431
  # @return [Sass::Script::Value::Number]
1360
1432
  # @raise [ArgumentError] if `$string` isn't a string
1361
1433
  def str_length(string)
@@ -1375,12 +1447,12 @@ module Sass::Script
1375
1447
  # str-insert("abcd", "X", 5) => "abcdX"
1376
1448
  #
1377
1449
  # @overload str_insert($string, $insert, $index)
1378
- # @param $string [Sass::Script::Value::String]
1379
- # @param $insert [Sass::Script::Value::String]
1380
- # @param $index [Sass::Script::Value::Number] The position at which
1381
- # `$insert` will be inserted. Negative indices count from the end of
1382
- # `$string`. An index that's outside the bounds of the string will insert
1383
- # `$insert` at the front or back of the string
1450
+ # @param $string [Sass::Script::Value::String]
1451
+ # @param $insert [Sass::Script::Value::String]
1452
+ # @param $index [Sass::Script::Value::Number] The position at which
1453
+ # `$insert` will be inserted. Negative indices count from the end of
1454
+ # `$string`. An index that's outside the bounds of the string will insert
1455
+ # `$insert` at the front or back of the string
1384
1456
  # @return [Sass::Script::Value::String] The result string. This will be
1385
1457
  # quoted if and only if `$string` was quoted
1386
1458
  # @raise [ArgumentError] if any parameter is the wrong type
@@ -1399,8 +1471,8 @@ module Sass::Script
1399
1471
  end
1400
1472
  declare :str_insert, [:string, :insert, :index]
1401
1473
 
1402
- # Returns the index of the first occurance of `$substring` in `$string`. If
1403
- # there is no such occurance, returns `null`.
1474
+ # Returns the index of the first occurrence of `$substring` in `$string`. If
1475
+ # there is no such occurrence, returns `null`.
1404
1476
  #
1405
1477
  # Note that unlike some languages, the first character in a Sass string is
1406
1478
  # number 1, the second number 2, and so forth.
@@ -1412,8 +1484,8 @@ module Sass::Script
1412
1484
  # str-index(abcd, c) => 3
1413
1485
  #
1414
1486
  # @overload str_index($string, $substring)
1415
- # @param $string [Sass::Script::Value::String]
1416
- # @param $substring [Sass::Script::Value::String]
1487
+ # @param $string [Sass::Script::Value::String]
1488
+ # @param $substring [Sass::Script::Value::String]
1417
1489
  # @return [Sass::Script::Value::Number, Sass::Script::Value::Null]
1418
1490
  # @raise [ArgumentError] if any parameter is the wrong type
1419
1491
  def str_index(string, substring)
@@ -1437,14 +1509,14 @@ module Sass::Script
1437
1509
  # str-slice("abcd", 2, -2) => "bc"
1438
1510
  #
1439
1511
  # @overload str_slice($string, $start-at, $end-at: -1)
1440
- # @param $start-at [Sass::Script::Value::Number] The index of the first
1441
- # character of the substring. If this is negative, it counts from the end
1442
- # of `$string`
1443
- # @param $end-before [Sass::Script::Value::Number] The index of the last
1444
- # character of the substring. If this is negative, it counts from the end
1445
- # of `$string`. Defaults to -1
1446
- # @return [Sass::Script::Value::String] The substring. This will be quoted
1447
- # if and only if `$string` was quoted
1512
+ # @param $start-at [Sass::Script::Value::Number] The index of the first
1513
+ # character of the substring. If this is negative, it counts from the end
1514
+ # of `$string`
1515
+ # @param $end-before [Sass::Script::Value::Number] The index of the last
1516
+ # character of the substring. If this is negative, it counts from the end
1517
+ # of `$string`. Defaults to -1
1518
+ # @return [Sass::Script::Value::String] The substring. This will be quoted
1519
+ # if and only if `$string` was quoted
1448
1520
  # @raise [ArgumentError] if any parameter is the wrong type
1449
1521
  def str_slice(string, start_at, end_at = nil)
1450
1522
  assert_type string, :String, :string
@@ -1453,6 +1525,7 @@ module Sass::Script
1453
1525
  end_at = number(-1) if end_at.nil?
1454
1526
  assert_unit end_at, nil, "end-at"
1455
1527
 
1528
+ return Sass::Script::Value::String.new("", string.type) if end_at.value == 0
1456
1529
  s = start_at.value > 0 ? start_at.value - 1 : start_at.value
1457
1530
  e = end_at.value > 0 ? end_at.value - 1 : end_at.value
1458
1531
  s = string.value.length + s if s < 0
@@ -1471,7 +1544,7 @@ module Sass::Script
1471
1544
  # to-upper-case(abcd) => ABCD
1472
1545
  #
1473
1546
  # @overload to_upper_case($string)
1474
- # @param $string [Sass::Script::Value::String]
1547
+ # @param $string [Sass::Script::Value::String]
1475
1548
  # @return [Sass::Script::Value::String]
1476
1549
  # @raise [ArgumentError] if `$string` isn't a string
1477
1550
  def to_upper_case(string)
@@ -1486,7 +1559,7 @@ module Sass::Script
1486
1559
  # to-lower-case(ABCD) => abcd
1487
1560
  #
1488
1561
  # @overload to_lower_case($string)
1489
- # @param $string [Sass::Script::Value::String]
1562
+ # @param $string [Sass::Script::Value::String]
1490
1563
  # @return [Sass::Script::Value::String]
1491
1564
  # @raise [ArgumentError] if `$string` isn't a string
1492
1565
  def to_lower_case(string)
@@ -1505,7 +1578,7 @@ module Sass::Script
1505
1578
  # type-of(#fff) => color
1506
1579
  # type-of(blue) => color
1507
1580
  # @overload type_of($value)
1508
- # @param $value [Sass::Script::Value::Base] The value to inspect
1581
+ # @param $value [Sass::Script::Value::Base] The value to inspect
1509
1582
  # @return [Sass::Script::Value::String] The unquoted string name of the
1510
1583
  # value's type
1511
1584
  def type_of(value)
@@ -1515,12 +1588,27 @@ module Sass::Script
1515
1588
 
1516
1589
  # Returns whether a feature exists in the current Sass runtime.
1517
1590
  #
1591
+ # The following features are supported:
1592
+ #
1593
+ # * `global-variable-shadowing` indicates that a local variable will shadow
1594
+ # a global variable unless `!global` is used.
1595
+ #
1596
+ # * `extend-selector-pseudoclass` indicates that `@extend` will reach into
1597
+ # selector pseudoclasses like `:not`.
1598
+ #
1599
+ # * `units-level-3` indicates full support for unit arithmetic using units
1600
+ # defined in the [Values and Units Level 3][] spec.
1601
+ #
1602
+ # [Values and Units Level 3]: http://www.w3.org/TR/css3-values/
1603
+ #
1604
+ # * `at-error` indicates that the Sass `@error` directive is supported.
1605
+ #
1518
1606
  # @example
1519
1607
  # feature-exists(some-feature-that-exists) => true
1520
1608
  # feature-exists(what-is-this-i-dont-know) => false
1521
1609
  #
1522
1610
  # @overload feature_exists($feature)
1523
- # @param $feature [Sass::Script::Value::String] The name of the feature
1611
+ # @param $feature [Sass::Script::Value::String] The name of the feature
1524
1612
  # @return [Sass::Script::Value::Bool] Whether the feature is supported in this version of Sass
1525
1613
  # @raise [ArgumentError] if `$feature` isn't a string
1526
1614
  def feature_exists(feature)
@@ -1539,7 +1627,7 @@ module Sass::Script
1539
1627
  # unit(10px * 5em) => "em*px"
1540
1628
  # unit(10px * 5em / 30cm / 1rem) => "em*px/cm*rem"
1541
1629
  # @overload unit($number)
1542
- # @param $number [Sass::Script::Value::Number]
1630
+ # @param $number [Sass::Script::Value::Number]
1543
1631
  # @return [Sass::Script::Value::String] The unit(s) of the number, as a
1544
1632
  # quoted string
1545
1633
  # @raise [ArgumentError] if `$number` isn't a number
@@ -1555,7 +1643,7 @@ module Sass::Script
1555
1643
  # unitless(100) => true
1556
1644
  # unitless(100px) => false
1557
1645
  # @overload unitless($number)
1558
- # @param $number [Sass::Script::Value::Number]
1646
+ # @param $number [Sass::Script::Value::Number]
1559
1647
  # @return [Sass::Script::Value::Bool]
1560
1648
  # @raise [ArgumentError] if `$number` isn't a number
1561
1649
  def unitless(number)
@@ -1571,8 +1659,8 @@ module Sass::Script
1571
1659
  # comparable(100px, 3em) => false
1572
1660
  # comparable(10cm, 3mm) => true
1573
1661
  # @overload comparable($number1, $number2)
1574
- # @param $number1 [Sass::Script::Value::Number]
1575
- # @param $number2 [Sass::Script::Value::Number]
1662
+ # @param $number1 [Sass::Script::Value::Number]
1663
+ # @param $number2 [Sass::Script::Value::Number]
1576
1664
  # @return [Sass::Script::Value::Bool]
1577
1665
  # @raise [ArgumentError] if either parameter is the wrong type
1578
1666
  def comparable(number1, number2)
@@ -1580,7 +1668,7 @@ module Sass::Script
1580
1668
  assert_type number2, :Number, :number2
1581
1669
  bool(number1.comparable_to?(number2))
1582
1670
  end
1583
- declare :comparable, [:number1, :number2], :deprecated => [:number_1, :number_2]
1671
+ declare :comparable, [:number1, :number2]
1584
1672
 
1585
1673
  # Converts a unitless number to a percentage.
1586
1674
  #
@@ -1588,7 +1676,7 @@ module Sass::Script
1588
1676
  # percentage(0.2) => 20%
1589
1677
  # percentage(100px / 50px) => 200%
1590
1678
  # @overload percentage($number)
1591
- # @param $number [Sass::Script::Value::Number]
1679
+ # @param $number [Sass::Script::Value::Number]
1592
1680
  # @return [Sass::Script::Value::Number]
1593
1681
  # @raise [ArgumentError] if `$number` isn't a unitless number
1594
1682
  def percentage(number)
@@ -1597,7 +1685,7 @@ module Sass::Script
1597
1685
  end
1598
1686
  number(number.value * 100, '%')
1599
1687
  end
1600
- declare :percentage, [:number], :deprecated => [:value]
1688
+ declare :percentage, [:number]
1601
1689
 
1602
1690
  # Rounds a number to the nearest whole number.
1603
1691
  #
@@ -1605,13 +1693,13 @@ module Sass::Script
1605
1693
  # round(10.4px) => 10px
1606
1694
  # round(10.6px) => 11px
1607
1695
  # @overload round($number)
1608
- # @param $number [Sass::Script::Value::Number]
1696
+ # @param $number [Sass::Script::Value::Number]
1609
1697
  # @return [Sass::Script::Value::Number]
1610
1698
  # @raise [ArgumentError] if `$number` isn't a number
1611
1699
  def round(number)
1612
1700
  numeric_transformation(number) {|n| n.round}
1613
1701
  end
1614
- declare :round, [:number], :deprecated => [:value]
1702
+ declare :round, [:number]
1615
1703
 
1616
1704
  # Rounds a number up to the next whole number.
1617
1705
  #
@@ -1619,13 +1707,13 @@ module Sass::Script
1619
1707
  # ceil(10.4px) => 11px
1620
1708
  # ceil(10.6px) => 11px
1621
1709
  # @overload ceil($number)
1622
- # @param $number [Sass::Script::Value::Number]
1710
+ # @param $number [Sass::Script::Value::Number]
1623
1711
  # @return [Sass::Script::Value::Number]
1624
1712
  # @raise [ArgumentError] if `$number` isn't a number
1625
1713
  def ceil(number)
1626
1714
  numeric_transformation(number) {|n| n.ceil}
1627
1715
  end
1628
- declare :ceil, [:number], :deprecated => [:value]
1716
+ declare :ceil, [:number]
1629
1717
 
1630
1718
  # Rounds a number down to the previous whole number.
1631
1719
  #
@@ -1633,13 +1721,13 @@ module Sass::Script
1633
1721
  # floor(10.4px) => 10px
1634
1722
  # floor(10.6px) => 10px
1635
1723
  # @overload floor($number)
1636
- # @param $number [Sass::Script::Value::Number]
1724
+ # @param $number [Sass::Script::Value::Number]
1637
1725
  # @return [Sass::Script::Value::Number]
1638
1726
  # @raise [ArgumentError] if `$number` isn't a number
1639
1727
  def floor(number)
1640
1728
  numeric_transformation(number) {|n| n.floor}
1641
1729
  end
1642
- declare :floor, [:number], :deprecated => [:value]
1730
+ declare :floor, [:number]
1643
1731
 
1644
1732
  # Returns the absolute value of a number.
1645
1733
  #
@@ -1647,13 +1735,13 @@ module Sass::Script
1647
1735
  # abs(10px) => 10px
1648
1736
  # abs(-10px) => 10px
1649
1737
  # @overload abs($number)
1650
- # @param $number [Sass::Script::Value::Number]
1738
+ # @param $number [Sass::Script::Value::Number]
1651
1739
  # @return [Sass::Script::Value::Number]
1652
1740
  # @raise [ArgumentError] if `$number` isn't a number
1653
1741
  def abs(number)
1654
1742
  numeric_transformation(number) {|n| n.abs}
1655
1743
  end
1656
- declare :abs, [:number], :deprecated => [:value]
1744
+ declare :abs, [:number]
1657
1745
 
1658
1746
  # Finds the minimum of several numbers. This function takes any number of
1659
1747
  # arguments.
@@ -1662,7 +1750,7 @@ module Sass::Script
1662
1750
  # min(1px, 4px) => 1px
1663
1751
  # min(5em, 3em, 4em) => 3em
1664
1752
  # @overload min($numbers...)
1665
- # @param $numbers [[Sass::Script::Value::Number]]
1753
+ # @param $numbers [[Sass::Script::Value::Number]]
1666
1754
  # @return [Sass::Script::Value::Number]
1667
1755
  # @raise [ArgumentError] if any argument isn't a number, or if not all of
1668
1756
  # the arguments have comparable units
@@ -1679,7 +1767,7 @@ module Sass::Script
1679
1767
  # max(1px, 4px) => 4px
1680
1768
  # max(5em, 3em, 4em) => 5em
1681
1769
  # @overload max($numbers...)
1682
- # @param $numbers [[Sass::Script::Value::Number]]
1770
+ # @param $numbers [[Sass::Script::Value::Number]]
1683
1771
  # @return [Sass::Script::Value::Number]
1684
1772
  # @raise [ArgumentError] if any argument isn't a number, or if not all of
1685
1773
  # the arguments have comparable units
@@ -1698,7 +1786,7 @@ module Sass::Script
1698
1786
  # length(10px 20px 30px) => 3
1699
1787
  # length((width: 10px, height: 20px)) => 2
1700
1788
  # @overload length($list)
1701
- # @param $list [Sass::Script::Value::Base]
1789
+ # @param $list [Sass::Script::Value::Base]
1702
1790
  # @return [Sass::Script::Value::Number]
1703
1791
  def length(list)
1704
1792
  number(list.to_a.size)
@@ -1717,11 +1805,11 @@ module Sass::Script
1717
1805
  # @example
1718
1806
  # set-nth($list: 10px 20px 30px, $n: 2, $value: -20px) => 10px -20px 30px
1719
1807
  # @overload set-nth($list, $n, $value)
1720
- # @param $list [Sass::Script::Value::Base] The list that will be copied, having the element
1721
- # at index `$n` changed.
1722
- # @param $n [Sass::Script::Value::Number] The index of the item to set.
1723
- # Negative indices count from the end of the list.
1724
- # @param $value [Sass::Script::Value::Base] The new value at index `$n`.
1808
+ # @param $list [Sass::Script::Value::Base] The list that will be copied, having the element
1809
+ # at index `$n` changed.
1810
+ # @param $n [Sass::Script::Value::Number] The index of the item to set.
1811
+ # Negative indices count from the end of the list.
1812
+ # @param $value [Sass::Script::Value::Base] The new value at index `$n`.
1725
1813
  # @return [Sass::Script::Value::List]
1726
1814
  # @raise [ArgumentError] if `$n` isn't an integer between 1 and the length
1727
1815
  # of `$list`
@@ -1750,9 +1838,9 @@ module Sass::Script
1750
1838
  # nth((Helvetica, Arial, sans-serif), 3) => sans-serif
1751
1839
  # nth((width: 10px, length: 20px), 2) => length, 20px
1752
1840
  # @overload nth($list, $n)
1753
- # @param $list [Sass::Script::Value::Base]
1754
- # @param $n [Sass::Script::Value::Number] The index of the item to get.
1755
- # Negative indices count from the end of the list.
1841
+ # @param $list [Sass::Script::Value::Base]
1842
+ # @param $n [Sass::Script::Value::Number] The index of the item to get.
1843
+ # Negative indices count from the end of the list.
1756
1844
  # @return [Sass::Script::Value::Base]
1757
1845
  # @raise [ArgumentError] if `$n` isn't an integer between 1 and the length
1758
1846
  # of `$list`
@@ -1779,11 +1867,11 @@ module Sass::Script
1779
1867
  # join(10px, 20px, comma) => 10px, 20px
1780
1868
  # join((blue, red), (#abc, #def), space) => blue red #abc #def
1781
1869
  # @overload join($list1, $list2, $separator: auto)
1782
- # @param $list1 [Sass::Script::Value::Base]
1783
- # @param $list2 [Sass::Script::Value::Base]
1784
- # @param $separator [Sass::Script::Value::String] The list separator to use.
1785
- # If this is `comma` or `space`, that separator will be used. If this is
1786
- # `auto` (the default), the separator is determined as explained above.
1870
+ # @param $list1 [Sass::Script::Value::Base]
1871
+ # @param $list2 [Sass::Script::Value::Base]
1872
+ # @param $separator [Sass::Script::Value::String] The list separator to use.
1873
+ # If this is `comma` or `space`, that separator will be used. If this is
1874
+ # `auto` (the default), the separator is determined as explained above.
1787
1875
  # @return [Sass::Script::Value::List]
1788
1876
  def join(list1, list2, separator = identifier("auto"))
1789
1877
  assert_type separator, :String, :separator
@@ -1812,11 +1900,11 @@ module Sass::Script
1812
1900
  # append(10px, 20px, comma) => 10px, 20px
1813
1901
  # append((blue, red), green, space) => blue red green
1814
1902
  # @overload append($list, $val, $separator: auto)
1815
- # @param $list [Sass::Script::Value::Base]
1816
- # @param $val [Sass::Script::Value::Base]
1817
- # @param $separator [Sass::Script::Value::String] The list separator to use.
1818
- # If this is `comma` or `space`, that separator will be used. If this is
1819
- # `auto` (the default), the separator is determined as explained above.
1903
+ # @param $list [Sass::Script::Value::Base]
1904
+ # @param $val [Sass::Script::Value::Base]
1905
+ # @param $separator [Sass::Script::Value::String] The list separator to use.
1906
+ # If this is `comma` or `space`, that separator will be used. If this is
1907
+ # `auto` (the default), the separator is determined as explained above.
1820
1908
  # @return [Sass::Script::Value::List]
1821
1909
  def append(list, val, separator = identifier("auto"))
1822
1910
  assert_type separator, :String, :separator
@@ -1844,7 +1932,7 @@ module Sass::Script
1844
1932
  # zip(1px 1px 3px, solid dashed solid, red green blue)
1845
1933
  # => 1px solid red, 1px dashed green, 3px solid blue
1846
1934
  # @overload zip($lists...)
1847
- # @param $lists [[Sass::Script::Value::Base]]
1935
+ # @param $lists [[Sass::Script::Value::Base]]
1848
1936
  # @return [Sass::Script::Value::List]
1849
1937
  def zip(*lists)
1850
1938
  length = nil
@@ -1873,16 +1961,15 @@ module Sass::Script
1873
1961
  # @example
1874
1962
  # index(1px solid red, solid) => 2
1875
1963
  # index(1px solid red, dashed) => null
1876
- # index((width: 10px, height: 20px), (height, 20px)) => 2
1964
+ # index((width: 10px, height: 20px), (height 20px)) => 2
1877
1965
  # @overload index($list, $value)
1878
- # @param $list [Sass::Script::Value::Base]
1879
- # @param $value [Sass::Script::Value::Base]
1966
+ # @param $list [Sass::Script::Value::Base]
1967
+ # @param $value [Sass::Script::Value::Base]
1880
1968
  # @return [Sass::Script::Value::Number, Sass::Script::Value::Null] The
1881
1969
  # 1-based index of `$value` in `$list`, or `null`
1882
1970
  def index(list, value)
1883
1971
  index = list.to_a.index {|e| e.eq(value).to_bool}
1884
- return number(index + 1) if index
1885
- Sass::Script::Value::DeprecatedFalse.new(environment)
1972
+ index ? number(index + 1) : null
1886
1973
  end
1887
1974
  declare :index, [:list, :value]
1888
1975
 
@@ -1894,7 +1981,7 @@ module Sass::Script
1894
1981
  # list-separator(1px, 2px, 3px) => comma
1895
1982
  # list-separator('foo') => space
1896
1983
  # @overload list_separator($list)
1897
- # @param $list [Sass::Script::Value::Base]
1984
+ # @param $list [Sass::Script::Value::Base]
1898
1985
  # @return [Sass::Script::Value::String] `comma` or `space`
1899
1986
  def list_separator(list)
1900
1987
  identifier((list.separator || :space).to_s)
@@ -1909,14 +1996,14 @@ module Sass::Script
1909
1996
  # map-get(("foo": 1, "bar": 2), "bar") => 2
1910
1997
  # map-get(("foo": 1, "bar": 2), "baz") => null
1911
1998
  # @overload map_get($map, $key)
1912
- # @param $map [Sass::Script::Value::Map]
1913
- # @param $key [Sass::Script::Value::Base]
1999
+ # @param $map [Sass::Script::Value::Map]
2000
+ # @param $key [Sass::Script::Value::Base]
1914
2001
  # @return [Sass::Script::Value::Base] The value indexed by `$key`, or `null`
1915
2002
  # if the map doesn't contain the given key
1916
2003
  # @raise [ArgumentError] if `$map` is not a map
1917
2004
  def map_get(map, key)
1918
2005
  assert_type map, :Map, :map
1919
- to_h(map)[key] || null
2006
+ map.to_h[key] || null
1920
2007
  end
1921
2008
  declare :map_get, [:map, :key]
1922
2009
 
@@ -1933,46 +2020,47 @@ module Sass::Script
1933
2020
  # map-merge(("foo": 1), ("bar": 2)) => ("foo": 1, "bar": 2)
1934
2021
  # map-merge(("foo": 1, "bar": 2), ("bar": 3)) => ("foo": 1, "bar": 3)
1935
2022
  # @overload map_merge($map1, $map2)
1936
- # @param $map1 [Sass::Script::Value::Map]
1937
- # @param $map2 [Sass::Script::Value::Map]
2023
+ # @param $map1 [Sass::Script::Value::Map]
2024
+ # @param $map2 [Sass::Script::Value::Map]
1938
2025
  # @return [Sass::Script::Value::Map]
1939
2026
  # @raise [ArgumentError] if either parameter is not a map
1940
2027
  def map_merge(map1, map2)
1941
2028
  assert_type map1, :Map, :map1
1942
2029
  assert_type map2, :Map, :map2
1943
- map(to_h(map1).merge(to_h(map2)))
2030
+ map(map1.to_h.merge(map2.to_h))
1944
2031
  end
1945
2032
  declare :map_merge, [:map1, :map2]
1946
2033
 
1947
- # Returns a new map with a key removed.
2034
+ # Returns a new map with keys removed.
1948
2035
  #
1949
2036
  # @example
1950
2037
  # map-remove(("foo": 1, "bar": 2), "bar") => ("foo": 1)
2038
+ # map-remove(("foo": 1, "bar": 2, "baz": 3), "bar", "baz") => ("foo": 1)
1951
2039
  # map-remove(("foo": 1, "bar": 2), "baz") => ("foo": 1, "bar": 2)
1952
- # @overload map_remove($map, $key)
1953
- # @param $map [Sass::Script::Value::Map]
1954
- # @param $key [Sass::Script::Value::Base]
2040
+ # @overload map_remove($map, $keys...)
2041
+ # @param $map [Sass::Script::Value::Map]
2042
+ # @param $keys [[Sass::Script::Value::Base]]
1955
2043
  # @return [Sass::Script::Value::Map]
1956
2044
  # @raise [ArgumentError] if `$map` is not a map
1957
- def map_remove(map, key)
2045
+ def map_remove(map, *keys)
1958
2046
  assert_type map, :Map, :map
1959
- hash = to_h(map).dup
1960
- hash.delete key
2047
+ hash = map.to_h.dup
2048
+ hash.delete_if {|key, _| keys.include?(key)}
1961
2049
  map(hash)
1962
2050
  end
1963
- declare :map_remove, [:map, :key]
2051
+ declare :map_remove, [:map, :key], :var_args => true
1964
2052
 
1965
2053
  # Returns a list of all keys in a map.
1966
2054
  #
1967
2055
  # @example
1968
2056
  # map-keys(("foo": 1, "bar": 2)) => "foo", "bar"
1969
2057
  # @overload map_keys($map)
1970
- # @param $map [Map]
2058
+ # @param $map [Map]
1971
2059
  # @return [List] the list of keys, comma-separated
1972
2060
  # @raise [ArgumentError] if `$map` is not a map
1973
2061
  def map_keys(map)
1974
2062
  assert_type map, :Map, :map
1975
- list(to_h(map).keys, :comma)
2063
+ list(map.to_h.keys, :comma)
1976
2064
  end
1977
2065
  declare :map_keys, [:map]
1978
2066
 
@@ -1983,12 +2071,12 @@ module Sass::Script
1983
2071
  # map-values(("foo": 1, "bar": 2)) => 1, 2
1984
2072
  # map-values(("foo": 1, "bar": 2, "baz": 1)) => 1, 2, 1
1985
2073
  # @overload map_values($map)
1986
- # @param $map [Map]
2074
+ # @param $map [Map]
1987
2075
  # @return [List] the list of values, comma-separated
1988
2076
  # @raise [ArgumentError] if `$map` is not a map
1989
2077
  def map_values(map)
1990
2078
  assert_type map, :Map, :map
1991
- list(to_h(map).values, :comma)
2079
+ list(map.to_h.values, :comma)
1992
2080
  end
1993
2081
  declare :map_values, [:map]
1994
2082
 
@@ -1998,13 +2086,13 @@ module Sass::Script
1998
2086
  # map-has-key(("foo": 1, "bar": 2), "foo") => true
1999
2087
  # map-has-key(("foo": 1, "bar": 2), "baz") => false
2000
2088
  # @overload map_has_key($map, $key)
2001
- # @param $map [Sass::Script::Value::Map]
2002
- # @param $key [Sass::Script::Value::Base]
2089
+ # @param $map [Sass::Script::Value::Map]
2090
+ # @param $key [Sass::Script::Value::Base]
2003
2091
  # @return [Sass::Script::Value::Bool]
2004
2092
  # @raise [ArgumentError] if `$map` is not a map
2005
2093
  def map_has_key(map, key)
2006
2094
  assert_type map, :Map, :map
2007
- bool(to_h(map).has_key?(key))
2095
+ bool(map.to_h.has_key?(key))
2008
2096
  end
2009
2097
  declare :map_has_key, [:map, :key]
2010
2098
 
@@ -2019,12 +2107,12 @@ module Sass::Script
2019
2107
  #
2020
2108
  # @include foo($arg1: val, $arg2: val);
2021
2109
  # @overload keywords($args)
2022
- # @param $args [Sass::Script::Value::ArgList]
2110
+ # @param $args [Sass::Script::Value::ArgList]
2023
2111
  # @return [Sass::Script::Value::Map]
2024
2112
  # @raise [ArgumentError] if `$args` isn't a variable argument list
2025
2113
  def keywords(args)
2026
2114
  assert_type args, :ArgList, :args
2027
- map(Sass::Util.map_keys(args.keywords.as_stored) {|k| Sass::Script::String.new(k)})
2115
+ map(Sass::Util.map_keys(args.keywords.as_stored) {|k| Sass::Script::Value::String.new(k)})
2028
2116
  end
2029
2117
  declare :keywords, [:args]
2030
2118
 
@@ -2036,10 +2124,10 @@ module Sass::Script
2036
2124
  # if(true, 1px, 2px) => 1px
2037
2125
  # if(false, 1px, 2px) => 2px
2038
2126
  # @overload if($condition, $if-true, $if-false)
2039
- # @param $condition [Sass::Script::Value::Base] Whether the `$if-true` or
2040
- # `$if-false` will be returned
2041
- # @param $if-true [Sass::Script::Tree::Node]
2042
- # @param $if-false [Sass::Script::Tree::Node]
2127
+ # @param $condition [Sass::Script::Value::Base] Whether the `$if-true` or
2128
+ # `$if-false` will be returned
2129
+ # @param $if-true [Sass::Script::Tree::Node]
2130
+ # @param $if-false [Sass::Script::Tree::Node]
2043
2131
  # @return [Sass::Script::Value::Base] `$if-true` or `$if-false`
2044
2132
  def if(condition, if_true, if_false)
2045
2133
  if condition.to_bool
@@ -2076,10 +2164,10 @@ module Sass::Script
2076
2164
  # call(scale-color, #0a64ff, $lightness: -10%) => #0058ef
2077
2165
  #
2078
2166
  # $fn: nth;
2079
- # call($fn, 2, (a b c)) => b
2167
+ # call($fn, (a b c), 2) => b
2080
2168
  #
2081
2169
  # @overload call($name, $args...)
2082
- # @param $name [String] The name of the function to call.
2170
+ # @param $name [String] The name of the function to call.
2083
2171
  def call(name, *args)
2084
2172
  assert_type name, :String, :name
2085
2173
  kwargs = args.last.is_a?(Hash) ? args.pop : {}
@@ -2094,31 +2182,29 @@ module Sass::Script
2094
2182
  end
2095
2183
  declare :call, [:name], :var_args => true, :var_kwargs => true
2096
2184
 
2097
- # This function only exists as a workaround for IE7's [`content: counter`
2098
- # bug][bug]. It works identically to any other plain-CSS function, except it
2185
+ # This function only exists as a workaround for IE7's [`content:
2186
+ # counter` bug](http://jes.st/2013/ie7s-css-breaking-content-counter-bug/).
2187
+ # It works identically to any other plain-CSS function, except it
2099
2188
  # avoids adding spaces between the argument commas.
2100
2189
  #
2101
- # [bug]: http://jes.st/2013/ie7s-css-breaking-content-counter-bug/
2102
- #
2103
2190
  # @example
2104
2191
  # counter(item, ".") => counter(item,".")
2105
2192
  # @overload counter($args...)
2106
- # @return [String]
2193
+ # @return [Sass::Script::Value::String]
2107
2194
  def counter(*args)
2108
2195
  identifier("counter(#{args.map {|a| a.to_s(options)}.join(',')})")
2109
2196
  end
2110
2197
  declare :counter, [], :var_args => true
2111
2198
 
2112
- # This function only exists as a workaround for IE7's [`content: counters`
2113
- # bug][bug]. It works identically to any other plain-CSS function, except it
2199
+ # This function only exists as a workaround for IE7's [`content:
2200
+ # counter` bug](http://jes.st/2013/ie7s-css-breaking-content-counter-bug/).
2201
+ # It works identically to any other plain-CSS function, except it
2114
2202
  # avoids adding spaces between the argument commas.
2115
2203
  #
2116
- # [bug]: http://jes.st/2013/ie7s-css-breaking-content-counter-bug/
2117
- #
2118
2204
  # @example
2119
2205
  # counters(item, ".") => counters(item,".")
2120
2206
  # @overload counters($args...)
2121
- # @return [String]
2207
+ # @return [Sass::Script::Value::String]
2122
2208
  def counters(*args)
2123
2209
  identifier("counters(#{args.map {|a| a.to_s(options)}.join(',')})")
2124
2210
  end
@@ -2132,9 +2218,11 @@ module Sass::Script
2132
2218
  # variable-exists(a-false-value) => true
2133
2219
  #
2134
2220
  # variable-exists(nonexistent) => false
2135
- # @param name [Sass::Script::String] The name of the variable to
2136
- # check. The name should not include the `$`.
2137
- # @return [Sass::Script::Bool] Whether the variable is defined in
2221
+ #
2222
+ # @overload variable_exists($name)
2223
+ # @param $name [Sass::Script::Value::String] The name of the variable to
2224
+ # check. The name should not include the `$`.
2225
+ # @return [Sass::Script::Value::Bool] Whether the variable is defined in
2138
2226
  # the current scope.
2139
2227
  def variable_exists(name)
2140
2228
  assert_type name, :String, :name
@@ -2153,9 +2241,11 @@ module Sass::Script
2153
2241
  # $some-var: false;
2154
2242
  # @if global-variable-exists(some-var) { /* false, doesn't run */ }
2155
2243
  # }
2156
- # @param name [Sass::Script::String] The name of the variable to
2157
- # check. The name should not include the `$`.
2158
- # @return [Sass::Script::Bool] Whether the variable is defined in
2244
+ #
2245
+ # @overload global_variable_exists($name)
2246
+ # @param $name [Sass::Script::Value::String] The name of the variable to
2247
+ # check. The name should not include the `$`.
2248
+ # @return [Sass::Script::Value::Bool] Whether the variable is defined in
2159
2249
  # the global scope.
2160
2250
  def global_variable_exists(name)
2161
2251
  assert_type name, :String, :name
@@ -2170,9 +2260,11 @@ module Sass::Script
2170
2260
  #
2171
2261
  # @function myfunc { @return "something"; }
2172
2262
  # function-exists(myfunc) => true
2173
- # @param name [Sass::Script::String] The name of the function to
2174
- # check.
2175
- # @return [Sass::Script::Bool] Whether the function is defined.
2263
+ #
2264
+ # @overload function_exists($name)
2265
+ # @param name [Sass::Script::Value::String] The name of the function to
2266
+ # check.
2267
+ # @return [Sass::Script::Value::Bool] Whether the function is defined.
2176
2268
  def function_exists(name)
2177
2269
  assert_type name, :String, :name
2178
2270
  exists = Sass::Script::Functions.callable?(name.value.tr("-", "_"))
@@ -2188,9 +2280,11 @@ module Sass::Script
2188
2280
  #
2189
2281
  # @mixin red-text { color: red; }
2190
2282
  # mixin-exists(red-text) => true
2191
- # @param name [Sass::Script::String] The name of the mixin to
2192
- # check.
2193
- # @return [Sass::Script::Bool] Whether the mixin is defined.
2283
+ #
2284
+ # @overload mixin_exists($name)
2285
+ # @param name [Sass::Script::Value::String] The name of the mixin to
2286
+ # check.
2287
+ # @return [Sass::Script::Value::Bool] Whether the mixin is defined.
2194
2288
  def mixin_exists(name)
2195
2289
  assert_type name, :String, :name
2196
2290
  bool(environment.mixin(name.value))
@@ -2199,8 +2293,9 @@ module Sass::Script
2199
2293
 
2200
2294
  # Return a string containing the value as its Sass representation.
2201
2295
  #
2202
- # @param value [Sass::Script::Value::Base] The value to inspect.
2203
- # @return [Sass::Script::Value::String] A respresentation of the value as
2296
+ # @overload inspect($value)
2297
+ # @param $value [Sass::Script::Value::Base] The value to inspect.
2298
+ # @return [Sass::Script::Value::String] A representation of the value as
2204
2299
  # it would be written in Sass.
2205
2300
  def inspect(value)
2206
2301
  unquoted_string(value.to_sass)
@@ -2209,12 +2304,12 @@ module Sass::Script
2209
2304
 
2210
2305
  # @overload random()
2211
2306
  # Return a decimal between 0 and 1, inclusive of 0 but not 1.
2212
- # @return [Sass::Script::Number] A decimal value.
2307
+ # @return [Sass::Script::Value::Number] A decimal value.
2213
2308
  # @overload random($limit)
2214
2309
  # Return an integer between 1 and `$limit`, inclusive of 1 but not `$limit`.
2215
2310
  # @param $limit [Sass::Script::Value::Number] The maximum of the random integer to be
2216
2311
  # returned, a positive integer.
2217
- # @return [Sass::Script::Number] An integer.
2312
+ # @return [Sass::Script::Value::Number] An integer.
2218
2313
  # @raise [ArgumentError] if the `$limit` is not 1 or greater
2219
2314
  def random(limit = nil)
2220
2315
  generator = Sass::Script::Functions.random_number_generator
@@ -2231,6 +2326,281 @@ module Sass::Script
2231
2326
  declare :random, []
2232
2327
  declare :random, [:limit]
2233
2328
 
2329
+ # Parses a user-provided selector into a list of lists of strings
2330
+ # as returned by `&`.
2331
+ #
2332
+ # @example
2333
+ # selector-parse(".foo .bar, .baz .bang") => ('.foo' '.bar', '.baz' '.bang')
2334
+ #
2335
+ # @overload selector_parse($selector)
2336
+ # @param $selector [Sass::Script::Value::String, Sass::Script::Value::List]
2337
+ # The selector to parse. This can be either a string, a list of
2338
+ # strings, or a list of lists of strings as returned by `&`.
2339
+ # @return [Sass::Script::Value::List]
2340
+ # A list of lists of strings representing `$selector`. This is
2341
+ # in the same format as a selector returned by `&`.
2342
+ def selector_parse(selector)
2343
+ parse_selector(selector, :selector).to_sass_script
2344
+ end
2345
+ declare :selector_parse, [:selector]
2346
+
2347
+ # Return a new selector with all selectors in `$selectors` nested beneath
2348
+ # one another as though they had been nested in the stylesheet as
2349
+ # `$selector1 { $selector2 { ... } }`.
2350
+ #
2351
+ # Unlike most selector functions, `selector-nest` allows the
2352
+ # parent selector `&` to be used in any selector but the first.
2353
+ #
2354
+ # @example
2355
+ # selector-nest(".foo", ".bar", ".baz") => .foo .bar .baz
2356
+ # selector-nest(".a .foo", ".b .bar") => .a .foo .b .bar
2357
+ # selector-nest(".foo", "&.bar") => .foo.bar
2358
+ #
2359
+ # @overload selector_nest($selectors...)
2360
+ # @param $selectors [[Sass::Script::Value::String, Sass::Script::Value::List]]
2361
+ # The selectors to nest. At least one selector must be passed. Each of
2362
+ # these can be either a string, a list of strings, or a list of lists of
2363
+ # strings as returned by `&`.
2364
+ # @return [Sass::Script::Value::List]
2365
+ # A list of lists of strings representing the result of nesting
2366
+ # `$selectors`. This is in the same format as a selector returned by
2367
+ # `&`.
2368
+ def selector_nest(*selectors)
2369
+ if selectors.empty?
2370
+ raise ArgumentError.new("$selectors: At least one selector must be passed")
2371
+ end
2372
+
2373
+ parsed = [parse_selector(selectors.first, :selectors)]
2374
+ parsed += selectors[1..-1].map {|sel| parse_selector(sel, :selectors, !!:parse_parent_ref)}
2375
+ parsed.inject {|result, child| child.resolve_parent_refs(result)}.to_sass_script
2376
+ end
2377
+ declare :selector_nest, [], :var_args => true
2378
+
2379
+ # Return a new selector with all selectors in `$selectors` appended one
2380
+ # another as though they had been nested in the stylesheet as `$selector1 {
2381
+ # &$selector2 { ... } }`.
2382
+ #
2383
+ # @example
2384
+ # selector-append(".foo", ".bar", ".baz") => .foo.bar.baz
2385
+ # selector-append(".a .foo", ".b .bar") => "a .foo.b .bar"
2386
+ # selector-append(".foo", "-suffix") => ".foo-suffix"
2387
+ #
2388
+ # @overload selector_append($selectors...)
2389
+ # @param $selectors [[Sass::Script::Value::String, Sass::Script::Value::List]]
2390
+ # The selectors to append. At least one selector must be passed. Each of
2391
+ # these can be either a string, a list of strings, or a list of lists of
2392
+ # strings as returned by `&`.
2393
+ # @return [Sass::Script::Value::List]
2394
+ # A list of lists of strings representing the result of appending
2395
+ # `$selectors`. This is in the same format as a selector returned by
2396
+ # `&`.
2397
+ # @raise [ArgumentError] if a selector could not be appended.
2398
+ def selector_append(*selectors)
2399
+ if selectors.empty?
2400
+ raise ArgumentError.new("$selectors: At least one selector must be passed")
2401
+ end
2402
+
2403
+ selectors.map {|sel| parse_selector(sel, :selectors)}.inject do |parent, child|
2404
+ child.members.each do |seq|
2405
+ sseq = seq.members.first
2406
+ unless sseq.is_a?(Sass::Selector::SimpleSequence)
2407
+ raise ArgumentError.new("Can't append \"#{seq}\" to \"#{parent}\"")
2408
+ end
2409
+
2410
+ base = sseq.base
2411
+ case base
2412
+ when Sass::Selector::Universal
2413
+ raise ArgumentError.new("Can't append \"#{seq}\" to \"#{parent}\"")
2414
+ when Sass::Selector::Element
2415
+ unless base.namespace.nil?
2416
+ raise ArgumentError.new("Can't append \"#{seq}\" to \"#{parent}\"")
2417
+ end
2418
+ sseq.members[0] = Sass::Selector::Parent.new(base.name)
2419
+ else
2420
+ sseq.members.unshift Sass::Selector::Parent.new
2421
+ end
2422
+ end
2423
+ child.resolve_parent_refs(parent)
2424
+ end.to_sass_script
2425
+ end
2426
+ declare :selector_append, [], :var_args => true
2427
+
2428
+ # Returns a new version of `$selector` with `$extendee` extended
2429
+ # with `$extender`. This works just like the result of
2430
+ #
2431
+ # $selector { ... }
2432
+ # $extender { @extend $extendee }
2433
+ #
2434
+ # @example
2435
+ # selector-extend(".a .b", ".b", ".foo .bar") => .a .b, .a .foo .bar, .foo .a .bar
2436
+ #
2437
+ # @overload selector_extend($selector, $extendee, $extender)
2438
+ # @param $selector [Sass::Script::Value::String, Sass::Script::Value::List]
2439
+ # The selector within which `$extendee` is extended with
2440
+ # `$extender`. This can be either a string, a list of strings,
2441
+ # or a list of lists of strings as returned by `&`.
2442
+ # @param $extendee [Sass::Script::Value::String, Sass::Script::Value::List]
2443
+ # The selector being extended. This can be either a string, a
2444
+ # list of strings, or a list of lists of strings as returned
2445
+ # by `&`.
2446
+ # @param $extender [Sass::Script::Value::String, Sass::Script::Value::List]
2447
+ # The selector being injected into `$selector`. This can be
2448
+ # either a string, a list of strings, or a list of lists of
2449
+ # strings as returned by `&`.
2450
+ # @return [Sass::Script::Value::List]
2451
+ # A list of lists of strings representing the result of the
2452
+ # extension. This is in the same format as a selector returned
2453
+ # by `&`.
2454
+ # @raise [ArgumentError] if the extension fails
2455
+ def selector_extend(selector, extendee, extender)
2456
+ selector = parse_selector(selector, :selector)
2457
+ extendee = parse_selector(extendee, :extendee)
2458
+ extender = parse_selector(extender, :extender)
2459
+
2460
+ extends = Sass::Util::SubsetMap.new
2461
+ begin
2462
+ extender.populate_extends(extends, extendee)
2463
+ selector.do_extend(extends).to_sass_script
2464
+ rescue Sass::SyntaxError => e
2465
+ raise ArgumentError.new(e.to_s)
2466
+ end
2467
+ end
2468
+ declare :selector_extend, [:selector, :extendee, :extender]
2469
+
2470
+ # Replaces all instances of `$original` with `$replacement` in `$selector`
2471
+ #
2472
+ # This works by using `@extend` and throwing away the original
2473
+ # selector. This means that it can be used to do very advanced
2474
+ # replacements; see the examples below.
2475
+ #
2476
+ # @example
2477
+ # selector-replace(".foo .bar", ".bar", ".baz") => ".foo .baz"
2478
+ # selector-replace(".foo.bar.baz", ".foo.baz", ".qux") => ".bar.qux"
2479
+ #
2480
+ # @overload selector_replace($selector, $original, $replacement)
2481
+ # @param $selector [Sass::Script::Value::String, Sass::Script::Value::List]
2482
+ # The selector within which `$original` is replaced with
2483
+ # `$replacement`. This can be either a string, a list of
2484
+ # strings, or a list of lists of strings as returned by `&`.
2485
+ # @param $original [Sass::Script::Value::String, Sass::Script::Value::List]
2486
+ # The selector being replaced. This can be either a string, a
2487
+ # list of strings, or a list of lists of strings as returned
2488
+ # by `&`.
2489
+ # @param $replacement [Sass::Script::Value::String, Sass::Script::Value::List]
2490
+ # The selector that `$original` is being replaced with. This
2491
+ # can be either a string, a list of strings, or a list of
2492
+ # lists of strings as returned by `&`.
2493
+ # @return [Sass::Script::Value::List]
2494
+ # A list of lists of strings representing the result of the
2495
+ # extension. This is in the same format as a selector returned
2496
+ # by `&`.
2497
+ # @raise [ArgumentError] if the replacement fails
2498
+ def selector_replace(selector, original, replacement)
2499
+ selector = parse_selector(selector, :selector)
2500
+ original = parse_selector(original, :original)
2501
+ replacement = parse_selector(replacement, :replacement)
2502
+
2503
+ extends = Sass::Util::SubsetMap.new
2504
+ begin
2505
+ replacement.populate_extends(extends, original)
2506
+ selector.do_extend(extends, [], !!:replace).to_sass_script
2507
+ rescue Sass::SyntaxError => e
2508
+ raise ArgumentError.new(e.to_s)
2509
+ end
2510
+ end
2511
+ declare :selector_replace, [:selector, :original, :replacement]
2512
+
2513
+ # Unifies two selectors into a single selector that matches only
2514
+ # elements matched by both input selectors. Returns `null` if
2515
+ # there is no such selector.
2516
+ #
2517
+ # Like the selector unification done for `@extend`, this doesn't
2518
+ # guarantee that the output selector will match *all* elements
2519
+ # matched by both input selectors. For example, if `.a .b` is
2520
+ # unified with `.x .y`, `.a .x .b.y, .x .a .b.y` will be returned,
2521
+ # but `.a.x .b.y` will not. This avoids exponential output size
2522
+ # while matching all elements that are likely to exist in
2523
+ # practice.
2524
+ #
2525
+ # @example
2526
+ # selector-unify(".a", ".b") => .a.b
2527
+ # selector-unify(".a .b", ".x .y") => .a .x .b.y, .x .a .b.y
2528
+ # selector-unify(".a.b", ".b.c") => .a.b.c
2529
+ # selector-unify("#a", "#b") => null
2530
+ #
2531
+ # @overload selector_unify($selector1, $selector2)
2532
+ # @param $selector1 [Sass::Script::Value::String, Sass::Script::Value::List]
2533
+ # The first selector to be unified. This can be either a
2534
+ # string, a list of strings, or a list of lists of strings as
2535
+ # returned by `&`.
2536
+ # @param $selector2 [Sass::Script::Value::String, Sass::Script::Value::List]
2537
+ # The second selector to be unified. This can be either a
2538
+ # string, a list of strings, or a list of lists of strings as
2539
+ # returned by `&`.
2540
+ # @return [Sass::Script::Value::List, Sass::Script::Value::Null]
2541
+ # A list of lists of strings representing the result of the
2542
+ # unification, or null if no unification exists. This is in
2543
+ # the same format as a selector returned by `&`.
2544
+ def selector_unify(selector1, selector2)
2545
+ selector1 = parse_selector(selector1, :selector1)
2546
+ selector2 = parse_selector(selector2, :selector2)
2547
+ return null unless (unified = selector1.unify(selector2))
2548
+ unified.to_sass_script
2549
+ end
2550
+ declare :selector_unify, [:selector1, :selector2]
2551
+
2552
+ # Returns the [simple
2553
+ # selectors](http://dev.w3.org/csswg/selectors4/#simple) that
2554
+ # comprise the compound selector `$selector`.
2555
+ #
2556
+ # Note that `$selector` **must be** a [compound
2557
+ # selector](http://dev.w3.org/csswg/selectors4/#compound). That
2558
+ # means it cannot contain commas or spaces. It also means that
2559
+ # unlike other selector functions, this takes only strings, not
2560
+ # lists.
2561
+ #
2562
+ # @example
2563
+ # simple-selectors(".foo.bar") => ".foo", ".bar"
2564
+ # simple-selectors(".foo.bar.baz") => ".foo", ".bar", ".baz"
2565
+ #
2566
+ # @overload simple_selectors($selector)
2567
+ # @param $selector [Sass::Script::Value::String]
2568
+ # The compound selector whose simple selectors will be extracted.
2569
+ # @return [Sass::Script::Value::List]
2570
+ # A list of simple selectors in the compound selector.
2571
+ def simple_selectors(selector)
2572
+ selector = parse_compound_selector(selector, :selector)
2573
+ list(selector.members.map {|simple| unquoted_string(simple.to_s)}, :comma)
2574
+ end
2575
+ declare :simple_selectors, [:selector]
2576
+
2577
+ # Returns whether `$super` is a superselector of `$sub`. This means that
2578
+ # `$super` matches all the elements that `$sub` matches, as well as possibly
2579
+ # additional elements. In general, simpler selectors tend to be
2580
+ # superselectors of more complex oned.
2581
+ #
2582
+ # @example
2583
+ # is-superselector(".foo", ".foo.bar") => true
2584
+ # is-superselector(".foo.bar", ".foo") => false
2585
+ # is-superselector(".bar", ".foo .bar") => true
2586
+ # is-superselector(".foo .bar", ".bar") => false
2587
+ #
2588
+ # @overload is_superselector($super, $sub)
2589
+ # @param $super [Sass::Script::Value::String, Sass::Script::Value::List]
2590
+ # The potential superselector. This can be either a string, a list of
2591
+ # strings, or a list of lists of strings as returned by `&`.
2592
+ # @param $sub [Sass::Script::Value::String, Sass::Script::Value::List]
2593
+ # The potential subselector. This can be either a string, a list of
2594
+ # strings, or a list of lists of strings as returned by `&`.
2595
+ # @return [Sass::Script::Value::Bool]
2596
+ # Whether `$selector1` is a superselector of `$selector2`.
2597
+ def is_superselector(sup, sub)
2598
+ sup = parse_selector(sup, :super)
2599
+ sub = parse_selector(sub, :sub)
2600
+ bool(sup.superselector?(sub))
2601
+ end
2602
+ declare :is_superselector, [:super, :sub]
2603
+
2234
2604
  private
2235
2605
 
2236
2606
  # This method implements the pattern of transforming a numeric value into
@@ -2250,23 +2620,7 @@ module Sass::Script
2250
2620
  assert_type amount, :Number, :amount
2251
2621
  Sass::Util.check_range('Amount', range, amount, units)
2252
2622
 
2253
- # TODO: is it worth restricting here,
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))
2258
- end
2259
-
2260
- def to_h(obj)
2261
- return obj.to_h unless obj.is_a?(Sass::Script::Value::List) && obj.needs_map_warning?
2262
-
2263
- fn_name = Sass::Util.caller_info.last.gsub('_', '-')
2264
- Sass::Util.sass_warn <<WARNING + environment.stack.to_s.gsub(/^/, ' ')
2265
- DEPRECATION WARNING: Passing lists of pairs to #{fn_name} is deprecated and will
2266
- be removed in future versions of Sass. Use Sass maps instead. For details, see
2267
- http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#maps.
2268
- WARNING
2269
- obj.to_h
2623
+ color.with(attr => color.send(attr).send(op, amount.value))
2270
2624
  end
2271
2625
  end
2272
2626
  end