sass 3.2.7 → 3.3.0.rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (184) hide show
  1. data/MIT-LICENSE +2 -2
  2. data/README.md +14 -2
  3. data/Rakefile +25 -1
  4. data/VERSION +1 -1
  5. data/VERSION_DATE +1 -1
  6. data/VERSION_NAME +1 -1
  7. data/lib/sass/cache_stores/base.rb +4 -2
  8. data/lib/sass/cache_stores/chain.rb +2 -1
  9. data/lib/sass/cache_stores/filesystem.rb +2 -6
  10. data/lib/sass/cache_stores/memory.rb +1 -1
  11. data/lib/sass/cache_stores/null.rb +2 -2
  12. data/lib/sass/callbacks.rb +1 -0
  13. data/lib/sass/css.rb +10 -10
  14. data/lib/sass/engine.rb +403 -150
  15. data/lib/sass/environment.rb +136 -57
  16. data/lib/sass/error.rb +7 -7
  17. data/lib/sass/exec.rb +123 -39
  18. data/lib/sass/features.rb +41 -0
  19. data/lib/sass/importers/base.rb +33 -2
  20. data/lib/sass/importers/deprecated_path.rb +45 -0
  21. data/lib/sass/importers/filesystem.rb +25 -14
  22. data/lib/sass/importers.rb +1 -0
  23. data/lib/sass/logger/base.rb +3 -3
  24. data/lib/sass/logger/log_level.rb +4 -6
  25. data/lib/sass/media.rb +19 -19
  26. data/lib/sass/plugin/compiler.rb +141 -101
  27. data/lib/sass/plugin/configuration.rb +18 -22
  28. data/lib/sass/plugin/merb.rb +1 -1
  29. data/lib/sass/plugin/staleness_checker.rb +24 -8
  30. data/lib/sass/plugin.rb +4 -2
  31. data/lib/sass/repl.rb +3 -3
  32. data/lib/sass/script/css_lexer.rb +9 -4
  33. data/lib/sass/script/css_parser.rb +6 -2
  34. data/lib/sass/script/functions.rb +1343 -590
  35. data/lib/sass/script/lexer.rb +84 -52
  36. data/lib/sass/script/parser.rb +217 -97
  37. data/lib/sass/script/tree/funcall.rb +290 -0
  38. data/lib/sass/script/{interpolation.rb → tree/interpolation.rb} +34 -13
  39. data/lib/sass/script/tree/list_literal.rb +80 -0
  40. data/lib/sass/script/tree/literal.rb +47 -0
  41. data/lib/sass/script/tree/map_literal.rb +64 -0
  42. data/lib/sass/script/{node.rb → tree/node.rb} +22 -12
  43. data/lib/sass/script/{operation.rb → tree/operation.rb} +17 -25
  44. data/lib/sass/script/tree/selector.rb +30 -0
  45. data/lib/sass/script/{string_interpolation.rb → tree/string_interpolation.rb} +5 -4
  46. data/lib/sass/script/{unary_operation.rb → tree/unary_operation.rb} +14 -9
  47. data/lib/sass/script/tree/variable.rb +57 -0
  48. data/lib/sass/script/tree.rb +16 -0
  49. data/lib/sass/script/{arg_list.rb → value/arg_list.rb} +4 -24
  50. data/lib/sass/script/value/base.rb +248 -0
  51. data/lib/sass/script/value/bool.rb +36 -0
  52. data/lib/sass/script/{color.rb → value/color.rb} +239 -195
  53. data/lib/sass/script/value/helpers.rb +155 -0
  54. data/lib/sass/script/value/list.rb +119 -0
  55. data/lib/sass/script/value/map.rb +70 -0
  56. data/lib/sass/script/value/null.rb +45 -0
  57. data/lib/sass/script/{number.rb → value/number.rb} +91 -65
  58. data/lib/sass/script/{string.rb → value/string.rb} +9 -11
  59. data/lib/sass/script/value.rb +11 -0
  60. data/lib/sass/script.rb +35 -8
  61. data/lib/sass/scss/css_parser.rb +2 -1
  62. data/lib/sass/scss/parser.rb +338 -170
  63. data/lib/sass/scss/rx.rb +5 -6
  64. data/lib/sass/scss/script_lexer.rb +1 -0
  65. data/lib/sass/scss/script_parser.rb +1 -0
  66. data/lib/sass/scss/static_parser.rb +23 -6
  67. data/lib/sass/selector/abstract_sequence.rb +2 -2
  68. data/lib/sass/selector/comma_sequence.rb +21 -16
  69. data/lib/sass/selector/sequence.rb +60 -34
  70. data/lib/sass/selector/simple.rb +11 -12
  71. data/lib/sass/selector/simple_sequence.rb +55 -33
  72. data/lib/sass/selector.rb +52 -48
  73. data/lib/sass/source/map.rb +211 -0
  74. data/lib/sass/source/position.rb +39 -0
  75. data/lib/sass/source/range.rb +41 -0
  76. data/lib/sass/stack.rb +120 -0
  77. data/lib/sass/supports.rb +12 -13
  78. data/lib/sass/tree/at_root_node.rb +82 -0
  79. data/lib/sass/tree/comment_node.rb +3 -3
  80. data/lib/sass/tree/css_import_node.rb +11 -11
  81. data/lib/sass/tree/debug_node.rb +2 -2
  82. data/lib/sass/tree/directive_node.rb +13 -2
  83. data/lib/sass/tree/each_node.rb +8 -8
  84. data/lib/sass/tree/extend_node.rb +13 -6
  85. data/lib/sass/tree/for_node.rb +4 -4
  86. data/lib/sass/tree/function_node.rb +5 -4
  87. data/lib/sass/tree/if_node.rb +1 -1
  88. data/lib/sass/tree/import_node.rb +4 -5
  89. data/lib/sass/tree/media_node.rb +4 -14
  90. data/lib/sass/tree/mixin_def_node.rb +4 -4
  91. data/lib/sass/tree/mixin_node.rb +21 -8
  92. data/lib/sass/tree/node.rb +29 -12
  93. data/lib/sass/tree/prop_node.rb +38 -18
  94. data/lib/sass/tree/return_node.rb +3 -2
  95. data/lib/sass/tree/root_node.rb +19 -3
  96. data/lib/sass/tree/rule_node.rb +25 -17
  97. data/lib/sass/tree/supports_node.rb +0 -13
  98. data/lib/sass/tree/trace_node.rb +2 -1
  99. data/lib/sass/tree/variable_node.rb +9 -3
  100. data/lib/sass/tree/visitors/base.rb +6 -6
  101. data/lib/sass/tree/visitors/check_nesting.rb +12 -9
  102. data/lib/sass/tree/visitors/convert.rb +63 -38
  103. data/lib/sass/tree/visitors/cssize.rb +63 -23
  104. data/lib/sass/tree/visitors/deep_copy.rb +6 -5
  105. data/lib/sass/tree/visitors/extend.rb +7 -7
  106. data/lib/sass/tree/visitors/perform.rb +256 -151
  107. data/lib/sass/tree/visitors/set_options.rb +6 -6
  108. data/lib/sass/tree/visitors/to_css.rb +231 -81
  109. data/lib/sass/tree/warn_node.rb +2 -2
  110. data/lib/sass/tree/while_node.rb +2 -2
  111. data/lib/sass/util/multibyte_string_scanner.rb +2 -0
  112. data/lib/sass/util/normalized_map.rb +65 -0
  113. data/lib/sass/util/ordered_hash.rb +188 -0
  114. data/lib/sass/util/subset_map.rb +3 -2
  115. data/lib/sass/util/test.rb +9 -0
  116. data/lib/sass/util.rb +220 -34
  117. data/lib/sass/version.rb +9 -9
  118. data/lib/sass.rb +14 -7
  119. data/test/sass/compiler_test.rb +213 -0
  120. data/test/sass/conversion_test.rb +235 -9
  121. data/test/sass/engine_test.rb +230 -60
  122. data/test/sass/exec_test.rb +86 -0
  123. data/test/sass/extend_test.rb +215 -147
  124. data/test/sass/functions_test.rb +584 -99
  125. data/test/sass/importer_test.rb +165 -17
  126. data/test/sass/plugin_test.rb +19 -13
  127. data/test/sass/script_conversion_test.rb +40 -0
  128. data/test/sass/script_test.rb +231 -21
  129. data/test/sass/scss/css_test.rb +14 -5
  130. data/test/sass/scss/scss_test.rb +1266 -66
  131. data/test/sass/source_map_test.rb +879 -0
  132. data/test/sass/templates/bork5.sass +3 -0
  133. data/test/sass/util/normalized_map_test.rb +30 -0
  134. data/test/sass/util_test.rb +90 -0
  135. data/test/sass/value_helpers_test.rb +181 -0
  136. data/test/test_helper.rb +7 -2
  137. metadata +316 -291
  138. data/lib/sass/script/bool.rb +0 -18
  139. data/lib/sass/script/funcall.rb +0 -231
  140. data/lib/sass/script/list.rb +0 -84
  141. data/lib/sass/script/literal.rb +0 -239
  142. data/lib/sass/script/null.rb +0 -34
  143. data/lib/sass/script/variable.rb +0 -58
  144. data/test/Gemfile +0 -3
  145. data/vendor/listen/CHANGELOG.md +0 -221
  146. data/vendor/listen/CONTRIBUTING.md +0 -38
  147. data/vendor/listen/Gemfile +0 -30
  148. data/vendor/listen/Guardfile +0 -8
  149. data/vendor/listen/LICENSE +0 -20
  150. data/vendor/listen/README.md +0 -315
  151. data/vendor/listen/Rakefile +0 -47
  152. data/vendor/listen/Vagrantfile +0 -96
  153. data/vendor/listen/lib/listen/adapter.rb +0 -214
  154. data/vendor/listen/lib/listen/adapters/bsd.rb +0 -112
  155. data/vendor/listen/lib/listen/adapters/darwin.rb +0 -85
  156. data/vendor/listen/lib/listen/adapters/linux.rb +0 -113
  157. data/vendor/listen/lib/listen/adapters/polling.rb +0 -67
  158. data/vendor/listen/lib/listen/adapters/windows.rb +0 -87
  159. data/vendor/listen/lib/listen/dependency_manager.rb +0 -126
  160. data/vendor/listen/lib/listen/directory_record.rb +0 -371
  161. data/vendor/listen/lib/listen/listener.rb +0 -225
  162. data/vendor/listen/lib/listen/multi_listener.rb +0 -143
  163. data/vendor/listen/lib/listen/turnstile.rb +0 -28
  164. data/vendor/listen/lib/listen/version.rb +0 -3
  165. data/vendor/listen/lib/listen.rb +0 -40
  166. data/vendor/listen/listen.gemspec +0 -22
  167. data/vendor/listen/spec/listen/adapter_spec.rb +0 -183
  168. data/vendor/listen/spec/listen/adapters/bsd_spec.rb +0 -36
  169. data/vendor/listen/spec/listen/adapters/darwin_spec.rb +0 -37
  170. data/vendor/listen/spec/listen/adapters/linux_spec.rb +0 -47
  171. data/vendor/listen/spec/listen/adapters/polling_spec.rb +0 -68
  172. data/vendor/listen/spec/listen/adapters/windows_spec.rb +0 -30
  173. data/vendor/listen/spec/listen/dependency_manager_spec.rb +0 -107
  174. data/vendor/listen/spec/listen/directory_record_spec.rb +0 -1225
  175. data/vendor/listen/spec/listen/listener_spec.rb +0 -169
  176. data/vendor/listen/spec/listen/multi_listener_spec.rb +0 -174
  177. data/vendor/listen/spec/listen/turnstile_spec.rb +0 -56
  178. data/vendor/listen/spec/listen_spec.rb +0 -73
  179. data/vendor/listen/spec/spec_helper.rb +0 -21
  180. data/vendor/listen/spec/support/adapter_helper.rb +0 -629
  181. data/vendor/listen/spec/support/directory_record_helper.rb +0 -55
  182. data/vendor/listen/spec/support/fixtures_helper.rb +0 -29
  183. data/vendor/listen/spec/support/listeners_helper.rb +0 -156
  184. data/vendor/listen/spec/support/platform_helper.rb +0 -15
@@ -0,0 +1,188 @@
1
+ # Copyright (c) 2005-2013 David Heinemeier Hansson
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ # This class was copied from an old version of ActiveSupport.
23
+ class OrderedHash < ::Hash
24
+ # In MRI the Hash class is core and written in C. In particular, methods are
25
+ # programmed with explicit C function calls and polymorphism is not honored.
26
+ #
27
+ # For example, []= is crucial in this implementation to maintain the @keys
28
+ # array but hash.c invokes rb_hash_aset() originally. This prevents method
29
+ # reuse through inheritance and forces us to reimplement stuff.
30
+ #
31
+ # For instance, we cannot use the inherited #merge! because albeit the algorithm
32
+ # itself would work, our []= is not being called at all by the C code.
33
+
34
+ def initialize(*args, &block)
35
+ super
36
+ @keys = []
37
+ end
38
+
39
+ def self.[](*args)
40
+ ordered_hash = new
41
+
42
+ if args.length == 1 && args.first.is_a?(Array)
43
+ args.first.each do |key_value_pair|
44
+ next unless key_value_pair.is_a?(Array)
45
+ ordered_hash[key_value_pair[0]] = key_value_pair[1]
46
+ end
47
+
48
+ return ordered_hash
49
+ end
50
+
51
+ unless args.size.even?
52
+ raise ArgumentError.new("odd number of arguments for Hash")
53
+ end
54
+
55
+ args.each_with_index do |val, ind|
56
+ next if ind.odd?
57
+ ordered_hash[val] = args[ind + 1]
58
+ end
59
+
60
+ ordered_hash
61
+ end
62
+
63
+ def initialize_copy(other)
64
+ super
65
+ # make a deep copy of keys
66
+ @keys = other.keys
67
+ end
68
+
69
+ def []=(key, value)
70
+ @keys << key unless has_key?(key)
71
+ super
72
+ end
73
+
74
+ def delete(key)
75
+ if has_key? key
76
+ index = @keys.index(key)
77
+ @keys.delete_at index
78
+ end
79
+ super
80
+ end
81
+
82
+ def delete_if
83
+ super
84
+ sync_keys!
85
+ self
86
+ end
87
+
88
+ def reject!
89
+ super
90
+ sync_keys!
91
+ self
92
+ end
93
+
94
+ def reject(&block)
95
+ dup.reject!(&block)
96
+ end
97
+
98
+ def keys
99
+ @keys.dup
100
+ end
101
+
102
+ def values
103
+ @keys.map {|key| self[key]}
104
+ end
105
+
106
+ def to_hash
107
+ self
108
+ end
109
+
110
+ def to_a
111
+ @keys.map {|key| [key, self[key]]}
112
+ end
113
+
114
+ def each_key
115
+ return to_enum(:each_key) unless block_given?
116
+ @keys.each {|key| yield key}
117
+ self
118
+ end
119
+
120
+ def each_value
121
+ return to_enum(:each_value) unless block_given?
122
+ @keys.each {|key| yield self[key]}
123
+ self
124
+ end
125
+
126
+ def each
127
+ return to_enum(:each) unless block_given?
128
+ @keys.each {|key| yield [key, self[key]]}
129
+ self
130
+ end
131
+
132
+ def each_pair
133
+ return to_enum(:each_pair) unless block_given?
134
+ @keys.each {|key| yield key, self[key]}
135
+ self
136
+ end
137
+
138
+ alias_method :select, :find_all
139
+
140
+ def clear
141
+ super
142
+ @keys.clear
143
+ self
144
+ end
145
+
146
+ def shift
147
+ k = @keys.first
148
+ v = delete(k)
149
+ [k, v]
150
+ end
151
+
152
+ def merge!(other_hash)
153
+ if block_given?
154
+ other_hash.each {|k, v| self[k] = key?(k) ? yield(k, self[k], v) : v}
155
+ else
156
+ other_hash.each {|k, v| self[k] = v}
157
+ end
158
+ self
159
+ end
160
+
161
+ alias_method :update, :merge!
162
+
163
+ def merge(other_hash, &block)
164
+ dup.merge!(other_hash, &block)
165
+ end
166
+
167
+ # When replacing with another hash, the initial order of our keys must come from the other hash --
168
+ # ordered or not.
169
+ def replace(other)
170
+ super
171
+ @keys = other.keys
172
+ self
173
+ end
174
+
175
+ def invert
176
+ OrderedHash[to_a.map! {|key_value_pair| key_value_pair.reverse}]
177
+ end
178
+
179
+ def inspect
180
+ "#<OrderedHash #{super}>"
181
+ end
182
+
183
+ private
184
+
185
+ def sync_keys!
186
+ @keys.delete_if {|k| !has_key?(k)}
187
+ end
188
+ end
@@ -72,7 +72,8 @@ module Sass
72
72
  # @see #[]
73
73
  def get(set)
74
74
  res = set.map do |k|
75
- next unless subsets = @hash[k]
75
+ subsets = @hash[k]
76
+ next unless subsets
76
77
  subsets.map do |subenum, subset, index|
77
78
  next unless subset.subset?(set)
78
79
  [index, subenum]
@@ -83,7 +84,7 @@ module Sass
83
84
  res.uniq!
84
85
  res.sort!
85
86
  res.map! {|i, s| [@vals[i], s]}
86
- return res
87
+ res
87
88
  end
88
89
 
89
90
  # Same as \{#get}, but doesn't return the subsets of the argument
@@ -0,0 +1,9 @@
1
+ module Sass
2
+ module Util
3
+ module Test
4
+ def skip(msg = nil, bt = caller)
5
+ super if defined?(super)
6
+ end
7
+ end
8
+ end
9
+ end
data/lib/sass/util.rb CHANGED
@@ -3,6 +3,8 @@ require 'set'
3
3
  require 'enumerator'
4
4
  require 'stringio'
5
5
  require 'rbconfig'
6
+ require 'uri'
7
+ require 'thread'
6
8
 
7
9
  require 'sass/root'
8
10
  require 'sass/util/subset_map'
@@ -29,6 +31,36 @@ module Sass
29
31
  File.join(Sass::ROOT_DIR, file)
30
32
  end
31
33
 
34
+ # Converts a hash or a list of pairs into an order-preserving hash.
35
+ #
36
+ # On Ruby 1.8.7, this uses the orderedhash gem to simulate an
37
+ # order-preserving hash. On Ruby 1.9 and up, it just uses the native Hash
38
+ # class, since that preserves the order itself.
39
+ #
40
+ # @overload ordered_hash(hash)
41
+ # @param hash [Hash] a normal hash to convert to an ordered hash
42
+ # @return [Hash]
43
+ # @overload ordered_hash(*pairs)
44
+ # @example
45
+ # ordered_hash([:foo, "bar"], [:baz, "bang"])
46
+ # #=> {:foo => "bar", :baz => "bang"}
47
+ # ordered_hash #=> {}
48
+ # @param pairs [Array<(Object, Object)>] the list of key/value pairs for
49
+ # the hash.
50
+ # @return [Hash]
51
+ def ordered_hash(*pairs_or_hash)
52
+ require 'sass/util/ordered_hash' if ruby1_8?
53
+
54
+ if pairs_or_hash.length == 1 && pairs_or_hash.first.is_a?(Hash)
55
+ hash = pairs_or_hash.first
56
+ return hash unless ruby1_8?
57
+ return OrderedHash.new.merge hash
58
+ end
59
+
60
+ return Hash[pairs_or_hash] unless ruby1_8?
61
+ OrderedHash[*flatten(pairs_or_hash, 1)]
62
+ end
63
+
32
64
  # Converts an array of `[key, value]` pairs to a hash.
33
65
  #
34
66
  # @example
@@ -37,7 +69,7 @@ module Sass
37
69
  # @param arr [Array<(Object, Object)>] An array of pairs
38
70
  # @return [Hash] A hash
39
71
  def to_hash(arr)
40
- Hash[arr.compact]
72
+ ordered_hash(*arr.compact)
41
73
  end
42
74
 
43
75
  # Maps the keys in a hash according to a block.
@@ -164,8 +196,8 @@ module Sass
164
196
  res = ary.dup
165
197
  i = 0
166
198
  while i < res.size
167
- if res[i...i+from.size] == from
168
- res[i...i+from.size] = to
199
+ if res[i...i + from.size] == from
200
+ res[i...i + from.size] = to
169
201
  end
170
202
  i += 1
171
203
  end
@@ -216,7 +248,7 @@ module Sass
216
248
  x = [nil, *x]
217
249
  y = [nil, *y]
218
250
  block ||= proc {|a, b| a == b && a}
219
- lcs_backtrace(lcs_table(x, y, &block), x, y, x.size-1, y.size-1, &block)
251
+ lcs_backtrace(lcs_table(x, y, &block), x, y, x.size - 1, y.size - 1, &block)
220
252
  end
221
253
 
222
254
  # Converts a Hash to an Array. This is usually identical to `Hash#to_a`,
@@ -230,11 +262,11 @@ module Sass
230
262
  # @return [Array]
231
263
  def hash_to_a(hash)
232
264
  return hash.to_a unless ruby1_8? || defined?(Test::Unit)
233
- return hash.sort_by {|k, v| k}
265
+ hash.sort_by {|k, v| k}
234
266
  end
235
267
 
236
268
  # Performs the equivalent of `enum.group_by.to_a`, but with a guaranteed
237
- # order. Unlike [#hash_to_a], the resulting order isn't sorted key order;
269
+ # order. Unlike {Util#hash_to_a}, the resulting order isn't sorted key order;
238
270
  # instead, it's the same order as `#group_by` has under Ruby 1.9 (key
239
271
  # appearance order).
240
272
  #
@@ -244,13 +276,14 @@ module Sass
244
276
  return enum.group_by(&block).to_a unless ruby1_8?
245
277
  order = {}
246
278
  arr = []
247
- enum.group_by do |e|
279
+ groups = enum.group_by do |e|
248
280
  res = block[e]
249
281
  unless order.include?(res)
250
282
  order[res] = order.size
251
283
  end
252
284
  res
253
- end.each do |key, vals|
285
+ end
286
+ groups.each do |key, vals|
254
287
  arr[order[key]] = [key, vals]
255
288
  end
256
289
  arr
@@ -258,7 +291,7 @@ module Sass
258
291
 
259
292
  # Returns a sub-array of `minuend` containing only elements that are also in
260
293
  # `subtrahend`. Ensures that the return value has the same order as
261
- # `minuend`, even on Rubinius where that's not guaranteed by {Array#-}.
294
+ # `minuend`, even on Rubinius where that's not guaranteed by `Array#-`.
262
295
  #
263
296
  # @param minuend [Array]
264
297
  # @param subtrahend [Array]
@@ -272,7 +305,7 @@ module Sass
272
305
  # Returns a string description of the character that caused an
273
306
  # `Encoding::UndefinedConversionError`.
274
307
  #
275
- # @param [Encoding::UndefinedConversionError]
308
+ # @param e [Encoding::UndefinedConversionError]
276
309
  # @return [String]
277
310
  def undefined_conversion_error_char(e)
278
311
  # Rubinius (as of 2.0.0.rc1) pre-quotes the error character.
@@ -280,7 +313,7 @@ module Sass
280
313
  # JRuby (as of 1.7.2) doesn't have an error_char field on
281
314
  # Encoding::UndefinedConversionError.
282
315
  return e.error_char.dump unless jruby?
283
- e.message[/^"[^"]+"/] #"
316
+ e.message[/^"[^"]+"/] # "
284
317
  end
285
318
 
286
319
  # Asserts that `value` falls within `range` (inclusive), leaving
@@ -288,14 +321,14 @@ module Sass
288
321
  #
289
322
  # @param name [String] The name of the value. Used in the error message.
290
323
  # @param range [Range] The allowed range of values.
291
- # @param value [Numeric, Sass::Script::Number] The value to check.
324
+ # @param value [Numeric, Sass::Script::Value::Number] The value to check.
292
325
  # @param unit [String] The unit of the value. Used in error reporting.
293
326
  # @return [Numeric] `value` adjusted to fall within range, if it
294
327
  # was outside by a floating-point margin.
295
- def check_range(name, range, value, unit='')
328
+ def check_range(name, range, value, unit = '')
296
329
  grace = (-0.00001..0.00001)
297
330
  str = value.to_s
298
- value = value.value if value.is_a?(Sass::Script::Number)
331
+ value = value.value if value.is_a?(Sass::Script::Value::Number)
299
332
  return value if range.include?(value)
300
333
  return range.first if grace.include?(value - range.first)
301
334
  return range.last if grace.include?(value - range.last)
@@ -323,7 +356,8 @@ module Sass
323
356
  # Returns information about the caller of the previous method.
324
357
  #
325
358
  # @param entry [String] An entry in the `#caller` list, or a similarly formatted string
326
- # @return [[String, Fixnum, (String, nil)]] An array containing the filename, line, and method name of the caller.
359
+ # @return [[String, Fixnum, (String, nil)]]
360
+ # An array containing the filename, line, and method name of the caller.
327
361
  # The method name may be nil
328
362
  def caller_info(entry = nil)
329
363
  # JRuby evaluates `caller` incorrectly when it's in an actual default argument.
@@ -391,7 +425,6 @@ module Sass
391
425
  $stderr = the_real_stderr
392
426
  end
393
427
 
394
- @@silence_warnings = false
395
428
  # Silences all Sass warnings within a block.
396
429
  #
397
430
  # @yield A block in which no Sass warnings will be printed
@@ -423,7 +456,7 @@ module Sass
423
456
  raise "ERROR: Rails.root is nil!"
424
457
  end
425
458
  return RAILS_ROOT.to_s if defined?(RAILS_ROOT)
426
- return nil
459
+ nil
427
460
  end
428
461
 
429
462
  # Returns the environment of the Rails application,
@@ -434,7 +467,7 @@ module Sass
434
467
  def rails_env
435
468
  return ::Rails.env.to_s if defined?(::Rails.env)
436
469
  return RAILS_ENV.to_s if defined?(RAILS_ENV)
437
- return nil
470
+ nil
438
471
  end
439
472
 
440
473
  # Returns whether this environment is using ActionPack
@@ -470,7 +503,7 @@ module Sass
470
503
  # or `ActionView::Template::Error`.
471
504
  def av_template_class(name)
472
505
  return ActionView.const_get("Template#{name}") if ActionView.const_defined?("Template#{name}")
473
- return ActionView::Template.const_get(name.to_s)
506
+ ActionView::Template.const_get(name.to_s)
474
507
  end
475
508
 
476
509
  ## Cross-OS Compatibility
@@ -503,11 +536,16 @@ module Sass
503
536
  RUBY_PLATFORM =~ /java/
504
537
  end
505
538
 
539
+ # @see #jruby_version-class_method
540
+ def jruby_version
541
+ Sass::Util.jruby_version
542
+ end
543
+
506
544
  # Returns an array of ints representing the JRuby version number.
507
545
  #
508
546
  # @return [Array<Fixnum>]
509
- def jruby_version
510
- $jruby_version ||= ::JRUBY_VERSION.split(".").map {|s| s.to_i}
547
+ def self.jruby_version
548
+ @jruby_version ||= ::JRUBY_VERSION.split(".").map {|s| s.to_i}
511
549
  end
512
550
 
513
551
  # Like `Dir.glob`, but works with backslash-separated paths on Windows.
@@ -605,7 +643,7 @@ Invalid #{encoding.name} character #{undefined_conversion_error_char(e)}
605
643
  MSG
606
644
  end
607
645
  end
608
- return str
646
+ str
609
647
  end
610
648
 
611
649
  # Like {\#check\_encoding}, but also checks for a `@charset` declaration
@@ -638,7 +676,7 @@ MSG
638
676
  charset, bom = $1, $2
639
677
  if charset
640
678
  charset = charset.force_encoding(encoding).encode("UTF-8")
641
- if endianness = encoding[/[BL]E$/]
679
+ if (endianness = encoding[/[BL]E$/])
642
680
  begin
643
681
  Encoding.find(charset + endianness)
644
682
  charset << endianness
@@ -785,8 +823,9 @@ MSG
785
823
  set1.to_a.uniq.sort_by {|e| e.hash}.eql?(set2.to_a.uniq.sort_by {|e| e.hash})
786
824
  end
787
825
 
788
- # Like `Object#inspect`, but preserves non-ASCII characters rather than escaping them under Ruby 1.9.2.
789
- # This is necessary so that the precompiled Haml template can be `#encode`d into `@options[:encoding]`
826
+ # Like `Object#inspect`, but preserves non-ASCII characters rather than
827
+ # escaping them under Ruby 1.9.2. This is necessary so that the
828
+ # precompiled Haml template can be `#encode`d into `@options[:encoding]`
790
829
  # before being evaluated.
791
830
  #
792
831
  # @param obj {Object}
@@ -812,11 +851,12 @@ MSG
812
851
  # @return [(String, Array)] The resulting string, and an array of extracted values.
813
852
  def extract_values(arr)
814
853
  values = []
815
- return arr.map do |e|
854
+ mapped = arr.map do |e|
816
855
  next e.gsub('{', '{{') if e.is_a?(String)
817
856
  values << e
818
857
  next "{#{values.count - 1}}"
819
- end.join, values
858
+ end
859
+ return mapped.join, values
820
860
  end
821
861
 
822
862
  # Undoes \{#extract\_values} by transforming a string with escape sequences
@@ -849,6 +889,115 @@ MSG
849
889
  inject_values(str, vals)
850
890
  end
851
891
 
892
+ # Builds a sourcemap file name given the generated CSS file name.
893
+ #
894
+ # @param css [String] The generated CSS file name.
895
+ # @return [String] The source map file name.
896
+ def sourcemap_name(css)
897
+ css + ".map"
898
+ end
899
+
900
+ # Escapes certain characters so that the result can be used
901
+ # as the JSON string value. Returns the original string if
902
+ # no escaping is necessary.
903
+ #
904
+ # @param s [String] The string to be escaped
905
+ # @return [String] The escaped string
906
+ def json_escape_string(s)
907
+ return s if s !~ /["\\\b\f\n\r\t]/
908
+
909
+ result = ""
910
+ s.split("").each do |c|
911
+ case c
912
+ when '"', "\\"
913
+ result << "\\" << c
914
+ when "\n" then result << "\\n"
915
+ when "\t" then result << "\\t"
916
+ when "\r" then result << "\\r"
917
+ when "\f" then result << "\\f"
918
+ when "\b" then result << "\\b"
919
+ else
920
+ result << c
921
+ end
922
+ end
923
+ result
924
+ end
925
+
926
+ # Converts the argument into a valid JSON value.
927
+ #
928
+ # @param v [Fixnum, String, Array, Boolean, nil]
929
+ # @return [String]
930
+ def json_value_of(v)
931
+ case v
932
+ when Fixnum
933
+ v.to_s
934
+ when String
935
+ "\"" + json_escape_string(v) + "\""
936
+ when Array
937
+ "[" + v.map {|x| json_value_of(x)}.join(",") + "]"
938
+ when NilClass
939
+ "null"
940
+ when TrueClass
941
+ "true"
942
+ when FalseClass
943
+ "false"
944
+ else
945
+ raise ArgumentError.new("Unknown type: #{v.class.name}")
946
+ end
947
+ end
948
+
949
+ VLQ_BASE_SHIFT = 5
950
+ VLQ_BASE = 1 << VLQ_BASE_SHIFT
951
+ VLQ_BASE_MASK = VLQ_BASE - 1
952
+ VLQ_CONTINUATION_BIT = VLQ_BASE
953
+
954
+ BASE64_DIGITS = ('A'..'Z').to_a + ('a'..'z').to_a + ('0'..'9').to_a + ['+', '/']
955
+ BASE64_DIGIT_MAP = begin
956
+ map = {}
957
+ Sass::Util.enum_with_index(BASE64_DIGITS).map do |digit, i|
958
+ map[digit] = i
959
+ end
960
+ map
961
+ end
962
+
963
+ # Encodes `value` as VLQ (http://en.wikipedia.org/wiki/VLQ).
964
+ #
965
+ # @param value [Fixnum]
966
+ # @return [String] The encoded value
967
+ def encode_vlq(value)
968
+ if value < 0
969
+ value = ((-value) << 1) | 1
970
+ else
971
+ value <<= 1
972
+ end
973
+
974
+ result = ''
975
+ begin
976
+ digit = value & VLQ_BASE_MASK
977
+ value >>= VLQ_BASE_SHIFT
978
+ if value > 0
979
+ digit |= VLQ_CONTINUATION_BIT
980
+ end
981
+ result << BASE64_DIGITS[digit]
982
+ end while value > 0
983
+ result
984
+ end
985
+
986
+ # This is a hack around the fact that you can't instantiate a URI parser on
987
+ # 1.8, so we have to have this hacky stuff to work around it. When 1.8
988
+ # support is dropped, we can remove this method.
989
+ #
990
+ # @private
991
+ URI_ESCAPE = URI.const_defined?("DEFAULT_PARSER") ? URI::DEFAULT_PARSER : URI
992
+
993
+ # URI-escape `string`.
994
+ #
995
+ # @param string [String]
996
+ # @return [String]
997
+ def escape_uri(string)
998
+ URI_ESCAPE.escape string
999
+ end
1000
+
852
1001
  ## Static Method Stuff
853
1002
 
854
1003
  # The context in which the ERB for \{#def\_static\_method} will be run.
@@ -868,11 +1017,43 @@ MSG
868
1017
  end
869
1018
  end
870
1019
 
1020
+ # @private
1021
+ ATOMIC_WRITE_MUTEX = Mutex.new
1022
+
1023
+ # This creates a temp file and yields it for writing. When the
1024
+ # write is complete, the file is moved into the desired location.
1025
+ # The atomicity of this operation is provided by the filesystem's
1026
+ # rename operation.
1027
+ #
1028
+ # @param filename [String] The file to write to.
1029
+ # @yieldparam tmpfile [Tempfile] The temp file that can be written to.
1030
+ # @return The value returned by the block.
1031
+ def atomic_create_and_write_file(filename)
1032
+ require 'tempfile'
1033
+ tmpfile = Tempfile.new(File.basename(filename), File.dirname(filename))
1034
+ tmpfile.binmode if tmpfile.respond_to?(:binmode)
1035
+ result = yield tmpfile
1036
+ tmpfile.close
1037
+ ATOMIC_WRITE_MUTEX.synchronize do
1038
+ File.rename tmpfile.path, filename
1039
+ end
1040
+ result
1041
+ ensure
1042
+ # close and remove the tempfile if it still exists,
1043
+ # presumably due to an error during write
1044
+ tmpfile.close if tmpfile
1045
+ tmpfile.unlink if tmpfile
1046
+ end
1047
+
871
1048
  private
872
1049
 
1050
+ # rubocop:disable LineLength
1051
+
1052
+
873
1053
  # Calculates the memoization table for the Least Common Subsequence algorithm.
874
1054
  # Algorithm from [Wikipedia](http://en.wikipedia.org/wiki/Longest_common_subsequence_problem#Computing_the_length_of_the_LCS)
875
1055
  def lcs_table(x, y)
1056
+ # rubocop:enable LineLength
876
1057
  c = Array.new(x.size) {[]}
877
1058
  x.size.times {|i| c[i][0] = 0}
878
1059
  y.size.times {|j| c[0][j] = 0}
@@ -880,27 +1061,32 @@ MSG
880
1061
  (1...y.size).each do |j|
881
1062
  c[i][j] =
882
1063
  if yield x[i], y[j]
883
- c[i-1][j-1] + 1
1064
+ c[i - 1][j - 1] + 1
884
1065
  else
885
- [c[i][j-1], c[i-1][j]].max
1066
+ [c[i][j - 1], c[i - 1][j]].max
886
1067
  end
887
1068
  end
888
1069
  end
889
- return c
1070
+ c
890
1071
  end
891
1072
 
1073
+ # rubocop:disable ParameterLists, LineLength
1074
+
1075
+
892
1076
  # Computes a single longest common subsequence for arrays x and y.
893
1077
  # Algorithm from [Wikipedia](http://en.wikipedia.org/wiki/Longest_common_subsequence_problem#Reading_out_an_LCS)
894
1078
  def lcs_backtrace(c, x, y, i, j, &block)
1079
+ # rubocop:enable ParameterList, LineLengths
895
1080
  return [] if i == 0 || j == 0
896
- if v = yield(x[i], y[j])
897
- return lcs_backtrace(c, x, y, i-1, j-1, &block) << v
1081
+ if (v = yield(x[i], y[j]))
1082
+ return lcs_backtrace(c, x, y, i - 1, j - 1, &block) << v
898
1083
  end
899
1084
 
900
- return lcs_backtrace(c, x, y, i, j-1, &block) if c[i][j-1] > c[i-1][j]
901
- return lcs_backtrace(c, x, y, i-1, j, &block)
1085
+ return lcs_backtrace(c, x, y, i, j - 1, &block) if c[i][j - 1] > c[i - 1][j]
1086
+ lcs_backtrace(c, x, y, i - 1, j, &block)
902
1087
  end
903
1088
  end
904
1089
  end
905
1090
 
906
1091
  require 'sass/util/multibyte_string_scanner'
1092
+ require 'sass/util/normalized_map'