sass 3.1.21 → 3.2.0.alpha.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.
Files changed (180) hide show
  1. data/README.md +5 -4
  2. data/REVISION +1 -1
  3. data/Rakefile +6 -15
  4. data/VERSION +1 -1
  5. data/VERSION_NAME +1 -1
  6. data/lib/sass.rb +0 -1
  7. data/lib/sass/cache_stores/base.rb +1 -3
  8. data/lib/sass/cache_stores/filesystem.rb +0 -3
  9. data/lib/sass/css.rb +49 -145
  10. data/lib/sass/engine.rb +23 -47
  11. data/lib/sass/environment.rb +5 -30
  12. data/lib/sass/exec.rb +7 -30
  13. data/lib/sass/importers/base.rb +1 -2
  14. data/lib/sass/importers/filesystem.rb +13 -18
  15. data/lib/sass/less.rb +1 -1
  16. data/lib/sass/plugin.rb +8 -4
  17. data/lib/sass/plugin/compiler.rb +67 -93
  18. data/lib/sass/plugin/configuration.rb +2 -0
  19. data/lib/sass/plugin/staleness_checker.rb +4 -14
  20. data/lib/sass/repl.rb +3 -2
  21. data/lib/sass/script.rb +1 -0
  22. data/lib/sass/script/color.rb +9 -4
  23. data/lib/sass/script/funcall.rb +3 -16
  24. data/lib/sass/script/functions.rb +55 -98
  25. data/lib/sass/script/interpolation.rb +0 -9
  26. data/lib/sass/script/lexer.rb +4 -2
  27. data/lib/sass/script/list.rb +0 -8
  28. data/lib/sass/script/literal.rb +20 -5
  29. data/lib/sass/script/node.rb +0 -8
  30. data/lib/sass/script/number.rb +11 -35
  31. data/lib/sass/script/operation.rb +0 -16
  32. data/lib/sass/script/parser.rb +5 -12
  33. data/lib/sass/script/string_interpolation.rb +0 -9
  34. data/lib/sass/script/unary_operation.rb +0 -7
  35. data/lib/sass/script/variable.rb +1 -5
  36. data/lib/sass/scss/parser.rb +54 -191
  37. data/lib/sass/scss/rx.rb +3 -15
  38. data/lib/sass/scss/static_parser.rb +3 -3
  39. data/lib/sass/selector.rb +3 -15
  40. data/lib/sass/selector/abstract_sequence.rb +2 -11
  41. data/lib/sass/selector/comma_sequence.rb +3 -8
  42. data/lib/sass/selector/sequence.rb +11 -74
  43. data/lib/sass/selector/simple.rb +1 -7
  44. data/lib/sass/selector/simple_sequence.rb +8 -28
  45. data/lib/sass/shared.rb +5 -3
  46. data/lib/sass/tree/comment_node.rb +12 -25
  47. data/lib/sass/tree/debug_node.rb +1 -1
  48. data/lib/sass/tree/directive_node.rb +0 -5
  49. data/lib/sass/tree/each_node.rb +1 -1
  50. data/lib/sass/tree/extend_node.rb +1 -1
  51. data/lib/sass/tree/for_node.rb +2 -2
  52. data/lib/sass/tree/function_node.rb +1 -1
  53. data/lib/sass/tree/if_node.rb +14 -1
  54. data/lib/sass/tree/media_node.rb +4 -4
  55. data/lib/sass/tree/mixin_def_node.rb +1 -1
  56. data/lib/sass/tree/mixin_node.rb +2 -2
  57. data/lib/sass/tree/node.rb +26 -10
  58. data/lib/sass/tree/return_node.rb +1 -1
  59. data/lib/sass/tree/root_node.rb +1 -1
  60. data/lib/sass/tree/rule_node.rb +11 -9
  61. data/lib/sass/tree/variable_node.rb +1 -1
  62. data/lib/sass/tree/visitors/base.rb +1 -1
  63. data/lib/sass/tree/visitors/check_nesting.rb +36 -29
  64. data/lib/sass/tree/visitors/convert.rb +9 -16
  65. data/lib/sass/tree/visitors/cssize.rb +9 -40
  66. data/lib/sass/tree/visitors/perform.rb +23 -79
  67. data/lib/sass/tree/visitors/to_css.rb +21 -23
  68. data/lib/sass/tree/warn_node.rb +1 -1
  69. data/lib/sass/tree/while_node.rb +1 -1
  70. data/lib/sass/util.rb +9 -147
  71. data/lib/sass/version.rb +0 -14
  72. data/test/sass/cache_test.rb +0 -15
  73. data/test/sass/conversion_test.rb +8 -50
  74. data/test/sass/css2sass_test.rb +0 -33
  75. data/test/sass/engine_test.rb +32 -283
  76. data/test/sass/extend_test.rb +0 -315
  77. data/test/sass/functions_test.rb +23 -60
  78. data/test/sass/importer_test.rb +0 -110
  79. data/test/sass/more_results/more_import.css +2 -2
  80. data/test/sass/plugin_test.rb +13 -40
  81. data/test/sass/results/import.css +2 -2
  82. data/test/sass/results/import_charset.css +0 -1
  83. data/test/sass/results/import_charset_1_8.css +0 -1
  84. data/test/sass/results/import_charset_ibm866.css +0 -1
  85. data/test/sass/results/scss_import.css +2 -2
  86. data/test/sass/results/units.css +1 -1
  87. data/test/sass/script_conversion_test.rb +0 -2
  88. data/test/sass/script_test.rb +4 -28
  89. data/test/sass/scss/css_test.rb +1 -79
  90. data/test/sass/scss/scss_test.rb +16 -96
  91. data/test/sass/templates/import_charset.sass +0 -2
  92. data/test/sass/templates/import_charset_1_8.sass +0 -2
  93. data/test/sass/templates/import_charset_ibm866.sass +0 -2
  94. data/test/sass/test_helper.rb +1 -1
  95. data/test/sass/util_test.rb +0 -28
  96. data/test/test_helper.rb +0 -2
  97. data/vendor/{listen → fssm}/LICENSE +1 -1
  98. data/vendor/fssm/README.markdown +55 -0
  99. data/vendor/fssm/Rakefile +59 -0
  100. data/vendor/fssm/VERSION.yml +5 -0
  101. data/vendor/fssm/example.rb +9 -0
  102. data/vendor/fssm/fssm.gemspec +77 -0
  103. data/vendor/fssm/lib/fssm.rb +33 -0
  104. data/vendor/fssm/lib/fssm/backends/fsevents.rb +36 -0
  105. data/vendor/fssm/lib/fssm/backends/inotify.rb +26 -0
  106. data/vendor/fssm/lib/fssm/backends/polling.rb +25 -0
  107. data/vendor/fssm/lib/fssm/backends/rubycocoa/fsevents.rb +131 -0
  108. data/vendor/fssm/lib/fssm/monitor.rb +26 -0
  109. data/vendor/fssm/lib/fssm/path.rb +91 -0
  110. data/vendor/fssm/lib/fssm/pathname.rb +502 -0
  111. data/vendor/fssm/lib/fssm/state/directory.rb +57 -0
  112. data/vendor/fssm/lib/fssm/state/file.rb +24 -0
  113. data/vendor/fssm/lib/fssm/support.rb +63 -0
  114. data/vendor/fssm/lib/fssm/tree.rb +176 -0
  115. data/vendor/fssm/profile/prof-cache.rb +40 -0
  116. data/vendor/fssm/profile/prof-fssm-pathname.html +1231 -0
  117. data/vendor/fssm/profile/prof-pathname.rb +68 -0
  118. data/vendor/fssm/profile/prof-plain-pathname.html +988 -0
  119. data/vendor/fssm/profile/prof.html +2379 -0
  120. data/vendor/fssm/spec/path_spec.rb +75 -0
  121. data/vendor/fssm/spec/root/duck/quack.txt +0 -0
  122. data/vendor/fssm/spec/root/file.css +0 -0
  123. data/vendor/fssm/spec/root/file.rb +0 -0
  124. data/vendor/fssm/spec/root/file.yml +0 -0
  125. data/vendor/fssm/spec/root/moo/cow.txt +0 -0
  126. data/vendor/fssm/spec/spec_helper.rb +14 -0
  127. metadata +246 -281
  128. data/VERSION_DATE +0 -1
  129. data/lib/sass/logger.rb +0 -15
  130. data/lib/sass/logger/base.rb +0 -32
  131. data/lib/sass/logger/log_level.rb +0 -49
  132. data/lib/sass/tree/visitors/deep_copy.rb +0 -87
  133. data/lib/sass/tree/visitors/extend.rb +0 -42
  134. data/lib/sass/tree/visitors/set_options.rb +0 -97
  135. data/lib/sass/util/multibyte_string_scanner.rb +0 -134
  136. data/test/Gemfile +0 -4
  137. data/test/Gemfile.lock +0 -19
  138. data/test/sass/fixtures/test_staleness_check_across_importers.css +0 -1
  139. data/test/sass/fixtures/test_staleness_check_across_importers.scss +0 -1
  140. data/test/sass/logger_test.rb +0 -58
  141. data/test/sass/templates/_double_import_loop2.sass +0 -1
  142. data/test/sass/templates/bork5.sass +0 -3
  143. data/test/sass/templates/double_import_loop1.sass +0 -1
  144. data/test/sass/templates/nested_bork5.sass +0 -2
  145. data/test/sass/templates/single_import_loop.sass +0 -1
  146. data/test/sass/util/multibyte_string_scanner_test.rb +0 -147
  147. data/vendor/listen/CHANGELOG.md +0 -147
  148. data/vendor/listen/Gemfile +0 -23
  149. data/vendor/listen/Guardfile +0 -8
  150. data/vendor/listen/README.md +0 -312
  151. data/vendor/listen/Rakefile +0 -47
  152. data/vendor/listen/Vagrantfile +0 -96
  153. data/vendor/listen/lib/listen.rb +0 -38
  154. data/vendor/listen/lib/listen/adapter.rb +0 -167
  155. data/vendor/listen/lib/listen/adapters/darwin.rb +0 -84
  156. data/vendor/listen/lib/listen/adapters/linux.rb +0 -110
  157. data/vendor/listen/lib/listen/adapters/polling.rb +0 -66
  158. data/vendor/listen/lib/listen/adapters/windows.rb +0 -81
  159. data/vendor/listen/lib/listen/directory_record.rb +0 -318
  160. data/vendor/listen/lib/listen/listener.rb +0 -203
  161. data/vendor/listen/lib/listen/multi_listener.rb +0 -121
  162. data/vendor/listen/lib/listen/turnstile.rb +0 -28
  163. data/vendor/listen/lib/listen/version.rb +0 -3
  164. data/vendor/listen/listen.gemspec +0 -26
  165. data/vendor/listen/spec/listen/adapter_spec.rb +0 -142
  166. data/vendor/listen/spec/listen/adapters/darwin_spec.rb +0 -31
  167. data/vendor/listen/spec/listen/adapters/linux_spec.rb +0 -41
  168. data/vendor/listen/spec/listen/adapters/polling_spec.rb +0 -68
  169. data/vendor/listen/spec/listen/adapters/windows_spec.rb +0 -24
  170. data/vendor/listen/spec/listen/directory_record_spec.rb +0 -1138
  171. data/vendor/listen/spec/listen/listener_spec.rb +0 -155
  172. data/vendor/listen/spec/listen/multi_listener_spec.rb +0 -156
  173. data/vendor/listen/spec/listen/turnstile_spec.rb +0 -56
  174. data/vendor/listen/spec/listen_spec.rb +0 -73
  175. data/vendor/listen/spec/spec_helper.rb +0 -18
  176. data/vendor/listen/spec/support/adapter_helper.rb +0 -716
  177. data/vendor/listen/spec/support/directory_record_helper.rb +0 -55
  178. data/vendor/listen/spec/support/fixtures_helper.rb +0 -29
  179. data/vendor/listen/spec/support/listeners_helper.rb +0 -144
  180. data/vendor/listen/spec/support/platform_helper.rb +0 -11
@@ -31,6 +31,8 @@ module Sass
31
31
  # @return [{Symbol => Object}]
32
32
  def options
33
33
  @options ||= default_options.dup
34
+ @options[:cache_store] ||= Sass::CacheStores::Filesystem.new(@options[:cache_location])
35
+ @options
34
36
  end
35
37
 
36
38
  # Sets the options hash.
@@ -39,10 +39,6 @@ module Sass
39
39
  def initialize(options)
40
40
  @dependencies = self.class.dependencies_cache
41
41
 
42
- # URIs that are being actively checked for staleness. Protects against
43
- # import loops.
44
- @actively_checking = Set.new
45
-
46
42
  # Entries in the following instance-level caches are never explicitly expired.
47
43
  # Instead they are supposed to automaticaly go out of scope when a series of staleness checks
48
44
  # (this instance of StalenessChecker was created for) is finished.
@@ -152,16 +148,10 @@ module Sass
152
148
 
153
149
  def dependency_updated?(css_mtime)
154
150
  Proc.new do |uri, importer|
155
- next true if @actively_checking.include?(uri)
156
- begin
157
- @actively_checking << uri
158
- sass_mtime = mtime(uri, importer)
159
- !sass_mtime ||
160
- sass_mtime > css_mtime ||
161
- dependencies_stale?(uri, importer, css_mtime)
162
- ensure
163
- @actively_checking.delete uri
164
- end
151
+ sass_mtime = mtime(uri, importer)
152
+ !sass_mtime ||
153
+ sass_mtime > css_mtime ||
154
+ dependencies_stale?(uri, importer, css_mtime)
165
155
  end
166
156
  end
167
157
 
@@ -15,6 +15,7 @@ module Sass
15
15
  # Starts the read-eval-print loop.
16
16
  def run
17
17
  environment = Environment.new
18
+ environment.set_var('important', Script::String.new('!important'))
18
19
  @line = 0
19
20
  loop do
20
21
  @line += 1
@@ -34,8 +35,8 @@ module Sass
34
35
  case text
35
36
  when Script::MATCH
36
37
  name = $1
37
- guarded = !!$3
38
- val = Script::Parser.parse($2, @line, text.size - ($3 || '').size - $2.size)
38
+ guarded = $3 == '||=' || $4
39
+ val = Script::Parser.parse($3, @line, text.size - $3.size)
39
40
 
40
41
  unless guarded && environment.var(name)
41
42
  environment.set_var(name, val.perform(environment))
@@ -1,3 +1,4 @@
1
+ require 'strscan'
1
2
  require 'sass/script/node'
2
3
  require 'sass/script/variable'
3
4
  require 'sass/script/funcall'
@@ -101,16 +101,21 @@ module Sass::Script
101
101
  [:red, :green, :blue].each do |k|
102
102
  next if @attrs[k].nil?
103
103
  @attrs[k] = @attrs[k].to_i
104
- Sass::Util.check_range("#{k.to_s.capitalize} value", 0..255, @attrs[k])
104
+ next if (0..255).include?(@attrs[k])
105
+ raise ArgumentError.new("#{k.to_s.capitalize} value must be between 0 and 255")
105
106
  end
106
107
 
107
108
  [:saturation, :lightness].each do |k|
108
109
  next if @attrs[k].nil?
109
- value = Number.new(@attrs[k], ['%']) # Get correct unit for error messages
110
- @attrs[k] = Sass::Util.check_range("#{k.to_s.capitalize}", 0..100, value, '%')
110
+ @attrs[k] = 0 if @attrs[k] < 0.00001 && @attrs[k] > -0.00001
111
+ @attrs[k] = 100 if @attrs[k] - 100 < 0.00001 && @attrs[k] - 100 > -0.00001
112
+ next if (0..100).include?(@attrs[k])
113
+ raise ArgumentError.new("#{k.to_s.capitalize} must be between 0 and 100")
111
114
  end
112
115
 
113
- @attrs[:alpha] = Sass::Util.check_range("Alpha channel", 0..1, @attrs[:alpha])
116
+ unless (0..1).include?(@attrs[:alpha])
117
+ raise ArgumentError.new("Alpha channel must be between 0 and 1")
118
+ end
114
119
  end
115
120
 
116
121
  # The red component of the color.
@@ -36,7 +36,7 @@ module Sass
36
36
  # @return [String] A string representation of the function call
37
37
  def inspect
38
38
  args = @args.map {|a| a.inspect}.join(', ')
39
- keywords = Sass::Util.hash_to_a(@keywords).
39
+ keywords = @keywords.sort_by {|k, v| k}.
40
40
  map {|k, v| "$#{k}: #{v.inspect}"}.join(', ')
41
41
  "#{name}(#{args}#{', ' unless args.empty? || keywords.empty?}#{keywords})"
42
42
  end
@@ -44,7 +44,7 @@ module Sass
44
44
  # @see Node#to_sass
45
45
  def to_sass(opts = {})
46
46
  args = @args.map {|a| a.to_sass(opts)}.join(', ')
47
- keywords = Sass::Util.hash_to_a(@keywords).
47
+ keywords = @keywords.sort_by {|k, v| k}.
48
48
  map {|k, v| "$#{dasherize(k, opts)}: #{v.to_sass(opts)}"}.join(', ')
49
49
  "#{dasherize(name, opts)}(#{args}#{', ' unless args.empty? || keywords.empty?}#{keywords})"
50
50
  end
@@ -57,14 +57,6 @@ module Sass
57
57
  @args + @keywords.values
58
58
  end
59
59
 
60
- # @see Node#deep_copy
61
- def deep_copy
62
- node = dup
63
- node.instance_variable_set('@args', args.map {|a| a.deep_copy})
64
- node.instance_variable_set('@keywords', Hash[keywords.map {|k, v| [k, v.deep_copy]}])
65
- node
66
- end
67
-
68
60
  protected
69
61
 
70
62
  # Evaluates the function call.
@@ -88,12 +80,7 @@ module Sass
88
80
  opts(Functions::EvaluationContext.new(environment.options).send(ruby_name, *args))
89
81
  end
90
82
  rescue ArgumentError => e
91
- # If this is a legitimate Ruby-raised argument error, re-raise it.
92
- # Otherwise, it's an error in the user's stylesheet, so wrap it.
93
- if e.message =~ /^wrong number of arguments \(\d+ for \d+\)/ &&
94
- e.backtrace[0] !~ /:in `(block in )?#{ruby_name}'$/
95
- raise e
96
- end
83
+ raise e unless e.backtrace.any? {|t| t =~ /:in `(block in )?(#{name}|perform)'$/}
97
84
  raise Sass::SyntaxError.new("#{e.message} for `#{name}'")
98
85
  end
99
86
 
@@ -93,7 +93,7 @@ module Sass::Script
93
93
  # \{#adjust_color adjust-color($color, \[$red\], \[$green\], \[$blue\], \[$hue\], \[$saturation\], \[$lightness\], \[$alpha\]}
94
94
  # : Increase or decrease any of the components of a color.
95
95
  #
96
- # \{#scale_color scale-color($color, \[$red\], \[$green\], \[$blue\], \[$saturation\], \[$lightness\], \[$alpha\]}
96
+ # \{#scale_color scale-color($color, \[$red\], \[$green\], \[$blue\], \[$hue\], \[$saturation\], \[$lightness\], \[$alpha\]}
97
97
  # : Fluidly scale one or more components of a color.
98
98
  #
99
99
  # \{#change_color change-color($color, \[$red\], \[$green\], \[$blue\], \[$hue\], \[$saturation\], \[$lightness\], \[$alpha\]}
@@ -135,9 +135,6 @@ module Sass::Script
135
135
  # \{#join join($list1, $list2, \[$separator\])}
136
136
  # : Joins together two lists into one.
137
137
  #
138
- # \{#append append($list1, $val, \[$separator\])}
139
- # : Appends a single value onto the end of a list.
140
- #
141
138
  # ## Introspection Functions
142
139
  #
143
140
  # \{#type_of type-of($value)}
@@ -369,10 +366,11 @@ module Sass::Script
369
366
  Color.new([red, green, blue].map do |c|
370
367
  v = c.value
371
368
  if c.numerator_units == ["%"] && c.denominator_units.empty?
372
- v = Sass::Util.check_range("Color value", 0..100, c, '%')
373
- v * 255 / 100.0
369
+ next v * 255 / 100.0 if (0..100).include?(v)
370
+ raise ArgumentError.new("Color value #{c} must be between 0% and 100% inclusive")
374
371
  else
375
- Sass::Util.check_range("Color value", 0..255, c)
372
+ next v if (0..255).include?(v)
373
+ raise ArgumentError.new("Color value #{v} must be between 0 and 255 inclusive")
376
374
  end
377
375
  end)
378
376
  end
@@ -412,7 +410,10 @@ module Sass::Script
412
410
  assert_type color, :Color
413
411
  assert_type alpha, :Number
414
412
 
415
- Sass::Util.check_range('Alpha channel', 0..1, alpha)
413
+ unless (0..1).include?(alpha.value)
414
+ raise ArgumentError.new("Alpha channel #{alpha.value} must be between 0 and 1 inclusive")
415
+ end
416
+
416
417
  color.with(:alpha => alpha.value)
417
418
  when 4
418
419
  red, green, blue, alpha = args
@@ -462,11 +463,16 @@ module Sass::Script
462
463
  assert_type lightness, :Number
463
464
  assert_type alpha, :Number
464
465
 
465
- Sass::Util.check_range('Alpha channel', 0..1, alpha)
466
+ unless (0..1).include?(alpha.value)
467
+ raise ArgumentError.new("Alpha channel #{alpha.value} must be between 0 and 1")
468
+ end
466
469
 
467
- h = hue.value
468
- s = Sass::Util.check_range('Saturation', 0..100, saturation, '%')
469
- l = Sass::Util.check_range('Lightness', 0..100, lightness, '%')
470
+ original_s = saturation
471
+ original_l = lightness
472
+ # This algorithm is from http://www.w3.org/TR/css3-color#hsl-color
473
+ h, s, l = [hue, saturation, lightness].map { |a| a.value }
474
+ raise ArgumentError.new("Saturation #{s} must be between 0% and 100%") unless (0..100).include?(s)
475
+ raise ArgumentError.new("Lightness #{l} must be between 0% and 100%") unless (0..100).include?(l)
470
476
 
471
477
  Color.new(:hue => h, :saturation => s, :lightness => l, :alpha => alpha.value)
472
478
  end
@@ -576,10 +582,7 @@ module Sass::Script
576
582
  return Sass::Script::String.new("alpha(#{args.map {|a| a.to_s}.join(", ")})")
577
583
  end
578
584
 
579
- raise ArgumentError.new("wrong number of arguments (#{args.size} for 1)") if args.size != 1
580
-
581
- assert_type args.first, :Color
582
- Sass::Script::Number.new(args.first.alpha)
585
+ opacity(*args)
583
586
  end
584
587
  declare :alpha, [:color]
585
588
 
@@ -592,7 +595,6 @@ module Sass::Script
592
595
  # @see #transparentize
593
596
  # @raise [ArgumentError] If `color` isn't a color
594
597
  def opacity(color)
595
- return Sass::Script::String.new("opacity(#{color})") if color.is_a?(Sass::Script::Number)
596
598
  assert_type color, :Color
597
599
  Sass::Script::Number.new(color.alpha)
598
600
  end
@@ -683,21 +685,16 @@ module Sass::Script
683
685
  # @example
684
686
  # saturate(hsl(120, 30%, 90%), 20%) => hsl(120, 50%, 90%)
685
687
  # saturate(#855, 20%) => #9e3f3f
686
- # @overload saturate(color, amount)
687
- # @param color [Color]
688
- # @param amount [Number]
689
- # @return [Color]
690
- # @see #desaturate
691
- # @raise [ArgumentError] If `color` isn't a color,
692
- # or `number` isn't a number between 0% and 100%
693
- def saturate(color, amount = nil)
694
- # Support the filter effects definition of saturate.
695
- # https://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html
696
- return Sass::Script::String.new("saturate(#{color})") if amount.nil?
688
+ # @param color [Color]
689
+ # @param amount [Number]
690
+ # @return [Color]
691
+ # @see #desaturate
692
+ # @raise [ArgumentError] If `color` isn't a color,
693
+ # or `number` isn't a number between 0% and 100%
694
+ def saturate(color, amount)
697
695
  _adjust(color, amount, :saturation, 0..100, :+, "%")
698
696
  end
699
697
  declare :saturate, [:color, :amount]
700
- declare :saturate, [:amount]
701
698
 
702
699
  # Makes a color less saturated.
703
700
  # Takes a color and an amount between 0% and 100%,
@@ -781,7 +778,9 @@ module Sass::Script
781
778
 
782
779
  next unless val = kwargs.delete(name)
783
780
  assert_type val, :Number, name
784
- Sass::Util.check_range("$#{name}: Amount", range, val, units) if range
781
+ if range && !range.include?(val.value)
782
+ raise ArgumentError.new("$#{name}: Amount #{val} must be between #{range.first}#{units} and #{range.last}#{units}")
783
+ end
785
784
  adjusted = color.send(name) + val.value
786
785
  adjusted = [0, Sass::Util.restrict(adjusted, range)].max if range
787
786
  [name.to_sym, adjusted]
@@ -850,8 +849,8 @@ module Sass::Script
850
849
  assert_type val, :Number, name
851
850
  if !(val.numerator_units == ['%'] && val.denominator_units.empty?)
852
851
  raise ArgumentError.new("$#{name}: Amount #{val} must be a % (e.g. #{val.value}%)")
853
- else
854
- Sass::Util.check_range("$#{name}: Amount", -100..100, val, '%')
852
+ elsif !(-100..100).include?(val.value)
853
+ raise ArgumentError.new("$#{name}: Amount #{val} must be between -100% and 100%")
855
854
  end
856
855
 
857
856
  current = color.send(name)
@@ -945,28 +944,31 @@ module Sass::Script
945
944
  assert_type color2, :Color
946
945
  assert_type weight, :Number
947
946
 
948
- Sass::Util.check_range("Weight", 0..100, weight, '%')
947
+ unless (0..100).include?(weight.value)
948
+ raise ArgumentError.new("Weight #{weight} must be between 0% and 100%")
949
+ end
949
950
 
950
- # This algorithm factors in both the user-provided weight (w) and the
951
- # difference between the alpha values of the two colors (a) to decide how
952
- # to perform the weighted average of the two RGB values.
951
+ # This algorithm factors in both the user-provided weight
952
+ # and the difference between the alpha values of the two colors
953
+ # to decide how to perform the weighted average of the two RGB values.
953
954
  #
954
955
  # It works by first normalizing both parameters to be within [-1, 1],
955
- # where 1 indicates "only use color1", -1 indicates "only use color2", and
956
- # all values in between indicated a proportionately weighted average.
956
+ # where 1 indicates "only use color1", -1 indicates "only use color 0",
957
+ # and all values in between indicated a proportionately weighted average.
957
958
  #
958
- # Once we have the normalized variables w and a, we apply the formula
959
- # (w + a)/(1 + w*a) to get the combined weight (in [-1, 1]) of color1.
959
+ # Once we have the normalized variables w and a,
960
+ # we apply the formula (w + a)/(1 + w*a)
961
+ # to get the combined weight (in [-1, 1]) of color1.
960
962
  # This formula has two especially nice properties:
961
963
  #
962
964
  # * When either w or a are -1 or 1, the combined weight is also that number
963
965
  # (cases where w * a == -1 are undefined, and handled as a special case).
964
966
  #
965
- # * When a is 0, the combined weight is w, and vice versa.
967
+ # * When a is 0, the combined weight is w, and vice versa
966
968
  #
967
969
  # Finally, the weight of color1 is renormalized to be within [0, 1]
968
970
  # and the weight of color2 is given by 1 minus the weight of color1.
969
- p = (weight.value/100.0).to_f
971
+ p = weight.value/100.0
970
972
  w = p*2 - 1
971
973
  a = color1.alpha - color2.alpha
972
974
 
@@ -988,7 +990,6 @@ module Sass::Script
988
990
  # @raise [ArgumentError] if `color` isn't a color
989
991
  # @see #desaturate
990
992
  def grayscale(color)
991
- return Sass::Script::String.new("grayscale(#{color})") if color.is_a?(Sass::Script::Number)
992
993
  desaturate color, Number.new(100)
993
994
  end
994
995
  declare :grayscale, [:color]
@@ -1012,15 +1013,12 @@ module Sass::Script
1012
1013
  # @return [Color]
1013
1014
  # @raise [ArgumentError] if `color` isn't a color
1014
1015
  def invert(color)
1015
- return Sass::Script::String.new("invert(#{color})") if color.is_a?(Sass::Script::Number)
1016
-
1017
1016
  assert_type color, :Color
1018
1017
  color.with(
1019
1018
  :red => (255 - color.red),
1020
1019
  :green => (255 - color.green),
1021
1020
  :blue => (255 - color.blue))
1022
1021
  end
1023
- declare :invert, [:color]
1024
1022
 
1025
1023
  # Removes quotes from a string if the string is quoted,
1026
1024
  # or returns the same string if it's not.
@@ -1153,8 +1151,8 @@ module Sass::Script
1153
1151
  # Rounds a number up to the nearest whole number.
1154
1152
  #
1155
1153
  # @example
1156
- # ceil(10.4px) => 11px
1157
- # ceil(10.6px) => 11px
1154
+ # ciel(10.4px) => 11px
1155
+ # ciel(10.6px) => 11px
1158
1156
  # @param value [Number] The number
1159
1157
  # @return [Number] The rounded number
1160
1158
  # @raise [ArgumentError] if `value` isn't a number
@@ -1276,14 +1274,14 @@ module Sass::Script
1276
1274
  # append(10px 20px, 30px) => 10px 20px 30px
1277
1275
  # append((blue, red), green) => blue, red, green
1278
1276
  # append(10px 20px, 30px 40px) => 10px 20px (30px 40px)
1279
- # append(10px, 20px, comma) => 10px, 20px
1280
- # append((blue, red), green, space) => blue red green
1281
- # @overload append(list, val, separator: auto)
1282
- # @param list [Literal] The list to add the value to
1283
- # @param val [Literal] The value to add to the end of the list
1277
+ # join(10px, 20px, comma) => 10px, 20px
1278
+ # join((blue, red), green, space) => blue red green
1279
+ # @overload join(list, val, separator: auto)
1280
+ # @param list1 [Literal] The first list to join
1281
+ # @param list2 [Literal] The second list to join
1284
1282
  # @param separator [String] How the list separator (comma or space) should be determined.
1285
1283
  # If this is `comma` or `space`, that is always the separator;
1286
- # if this is `auto` (the default), the separator is the same as that used by the list.
1284
+ # if this is `auto` (the default), the separator is determined as explained above.
1287
1285
  def append(list, val, separator = Sass::Script::String.new("auto"))
1288
1286
  assert_type separator, :String
1289
1287
  unless %w[auto space comma].include?(separator.value)
@@ -1301,49 +1299,6 @@ module Sass::Script
1301
1299
  declare :append, [:list, :val]
1302
1300
  declare :append, [:list, :val, :separator]
1303
1301
 
1304
- # Combines several lists into a single comma separated list
1305
- # space separated lists.
1306
- #
1307
- # The length of the resulting list is the length of the
1308
- # shortest list.
1309
- #
1310
- # @example
1311
- # zip(1px 1px 3px, solid dashed solid, red green blue)
1312
- # => 1px solid red, 1px dashed green, 3px solid blue
1313
- def zip(*lists)
1314
- length = nil
1315
- values = []
1316
- lists.each do |list|
1317
- assert_type list, :List
1318
- values << list.value.dup
1319
- length = length.nil? ? list.value.length : [length, list.value.length].min
1320
- end
1321
- values.each do |value|
1322
- value.slice!(length)
1323
- end
1324
- new_list_value = values.first.zip(*values[1..-1])
1325
- List.new(new_list_value.map{|list| List.new(list, :space)}, :comma)
1326
- end
1327
- declare :zip, [], :var_args => true
1328
-
1329
-
1330
- # Returns the position of the given value within the given
1331
- # list. If not found, returns false.
1332
- #
1333
- # @example
1334
- # index(1px solid red, solid) => 2
1335
- # index(1px solid red, dashed) => false
1336
- def index(list, value)
1337
- assert_type list, :List
1338
- index = list.value.index {|e| e.eq(value).to_bool }
1339
- if index
1340
- Number.new(index + 1)
1341
- else
1342
- Bool.new(false)
1343
- end
1344
- end
1345
- declare :index, [:list, :value]
1346
-
1347
1302
  # Returns one of two values based on the truth value of the first argument.
1348
1303
  #
1349
1304
  # @example
@@ -1374,7 +1329,9 @@ module Sass::Script
1374
1329
  def _adjust(color, amount, attr, range, op, units = "")
1375
1330
  assert_type color, :Color
1376
1331
  assert_type amount, :Number
1377
- Sass::Util.check_range('Amount', range, amount, units)
1332
+ unless range.include?(amount.value)
1333
+ raise ArgumentError.new("Amount #{amount} must be between #{range.first}#{units} and #{range.last}#{units}")
1334
+ end
1378
1335
 
1379
1336
  # TODO: is it worth restricting here,
1380
1337
  # or should we do so in the Color constructor itself,
@@ -50,15 +50,6 @@ module Sass::Script
50
50
  [@before, @mid, @after].compact
51
51
  end
52
52
 
53
- # @see Node#deep_copy
54
- def deep_copy
55
- node = dup
56
- node.instance_variable_set('@before', @before.deep_copy) if @before
57
- node.instance_variable_set('@mid', @mid.deep_copy)
58
- node.instance_variable_set('@after', @after.deep_copy) if @after
59
- node
60
- end
61
-
62
53
  protected
63
54
 
64
55
  # Evaluates the interpolation.
@@ -1,5 +1,7 @@
1
1
  require 'sass/scss/rx'
2
2
 
3
+ require 'strscan'
4
+
3
5
  module Sass
4
6
  module Script
5
7
  # The lexical analyzer for SassScript.
@@ -124,7 +126,7 @@ module Sass
124
126
  # @param options [{Symbol => Object}] An options hash;
125
127
  # see {file:SASS_REFERENCE.md#sass_options the Sass options documentation}
126
128
  def initialize(str, line, offset, options)
127
- @scanner = str.is_a?(StringScanner) ? str : Sass::Util::MultibyteStringScanner.new(str)
129
+ @scanner = str.is_a?(StringScanner) ? str : StringScanner.new(str)
128
130
  @line = line
129
131
  @offset = offset
130
132
  @options = options
@@ -287,7 +289,7 @@ MESSAGE
287
289
  end
288
290
 
289
291
  def special_fun
290
- return unless str1 = scan(/((-[\w-]+-)?(calc|element)|expression|progid:[a-z\.]*)\(/i)
292
+ return unless str1 = scan(/((-[\w-]+-)?calc|expression|progid:[a-z\.]*)\(/i)
291
293
  str2, _ = Sass::Shared.balance(@scanner, ?(, ?), 1)
292
294
  c = str2.count("\n")
293
295
  old_line = @line