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
@@ -16,26 +16,29 @@ module Sass
16
16
  # `value`: \[`Object`\]
17
17
  # : The Ruby object corresponding to the value of the token.
18
18
  #
19
- # `line`: \[`Fixnum`\]
20
- # : The line of the source file on which the token appears.
21
- #
22
- # `offset`: \[`Fixnum`\]
23
- # : The number of bytes into the line the SassScript token appeared.
19
+ # `source_range`: \[`Sass::Source::Range`\]
20
+ # : The range in the source file in which the token appeared.
24
21
  #
25
22
  # `pos`: \[`Fixnum`\]
26
23
  # : The scanner position at which the SassScript token appeared.
27
- Token = Struct.new(:type, :value, :line, :offset, :pos)
24
+ Token = Struct.new(:type, :value, :source_range, :pos)
28
25
 
29
26
  # The line number of the lexer's current position.
30
27
  #
31
28
  # @return [Fixnum]
32
- attr_reader :line
29
+ def line
30
+ return @line unless @tok
31
+ @tok.source_range.start_pos.line
32
+ end
33
33
 
34
34
  # The number of bytes into the current line
35
- # of the lexer's current position.
35
+ # of the lexer's current position (1-based).
36
36
  #
37
37
  # @return [Fixnum]
38
- attr_reader :offset
38
+ def offset
39
+ return @offset unless @tok
40
+ @tok.source_range.start_pos.offset
41
+ end
39
42
 
40
43
  # A hash from operator strings to the corresponding token types.
41
44
  OPERATORS = {
@@ -67,11 +70,10 @@ module Sass
67
70
 
68
71
  OPERATORS_REVERSE = Sass::Util.map_hash(OPERATORS) {|k, v| [v, k]}
69
72
 
70
- TOKEN_NAMES = Sass::Util.map_hash(OPERATORS_REVERSE) {|k, v| [k, v.inspect]}.merge({
73
+ TOKEN_NAMES = Sass::Util.map_hash(OPERATORS_REVERSE) {|k, v| [k, v.inspect]}.merge(
71
74
  :const => "variable (e.g. $foo)",
72
75
  :ident => "identifier (e.g. middle)",
73
- :bool => "boolean (e.g. true, false)",
74
- })
76
+ :bool => "boolean (e.g. true, false)")
75
77
 
76
78
  # A list of operator strings ordered with longer names first
77
79
  # so that `>` and `<` don't clobber `>=` and `<=`.
@@ -92,12 +94,17 @@ module Sass
92
94
  :color => HEXCOLOR,
93
95
  :bool => /(true|false)\b/,
94
96
  :null => /null\b/,
95
- :ident_op => %r{(#{Regexp.union(*IDENT_OP_NAMES.map{|s| Regexp.new(Regexp.escape(s) + "(?!#{NMCHAR}|\Z)")})})},
96
- :op => %r{(#{Regexp.union(*OP_NAMES)})},
97
+ :selector => /&/,
98
+ :ident_op => /(#{Regexp.union(*IDENT_OP_NAMES.map do |s|
99
+ Regexp.new(Regexp.escape(s) + "(?!#{NMCHAR}|\Z)")
100
+ end)})/,
101
+ :op => /(#{Regexp.union(*OP_NAMES)})/,
97
102
  }
98
103
 
99
104
  class << self
105
+
100
106
  private
107
+
101
108
  def string_re(open, close)
102
109
  /#{open}((?:\\.|\#(?!\{)|[^#{close}\\#])*)(#{close}|#\{)/
103
110
  end
@@ -125,10 +132,10 @@ module Sass
125
132
  }
126
133
 
127
134
  # @param str [String, StringScanner] The source text to lex
128
- # @param line [Fixnum] The line on which the SassScript appears.
129
- # Used for error reporting
130
- # @param offset [Fixnum] The number of characters in on which the SassScript appears.
131
- # Used for error reporting
135
+ # @param line [Fixnum] The 1-based line on which the SassScript appears.
136
+ # Used for error reporting and sourcemap building
137
+ # @param offset [Fixnum] The 1-based character (not byte) offset in the line in the source.
138
+ # Used for error reporting and sourcemap building
132
139
  # @param options [{Symbol => Object}] An options hash;
133
140
  # see {file:SASS_REFERENCE.md#sass_options the Sass options documentation}
134
141
  def initialize(str, line, offset, options)
@@ -147,7 +154,7 @@ module Sass
147
154
  @tok ||= read_token
148
155
  @tok, tok = nil, @tok
149
156
  @prev = tok
150
- return tok
157
+ tok
151
158
  end
152
159
 
153
160
  # Returns whether or not there's whitespace before the next token.
@@ -172,7 +179,11 @@ module Sass
172
179
  # Rewinds the underlying StringScanner
173
180
  # to before the token returned by \{#peek}.
174
181
  def unpeek!
175
- @scanner.pos = @tok.pos if @tok
182
+ if @tok
183
+ @scanner.pos = @tok.pos
184
+ @line = @tok.source_range.start_pos.line
185
+ @offset = @tok.source_range.start_pos.offset
186
+ end
176
187
  end
177
188
 
178
189
  # @return [Boolean] Whether or not there's more source text to lex.
@@ -215,13 +226,11 @@ module Sass
215
226
 
216
227
  def read_token
217
228
  return if done?
218
- return unless value = token
219
- type, val, size = value
220
- size ||= @scanner.matched_size
221
-
222
- val.line = @line if val.is_a?(Script::Node)
223
- Token.new(type, val, @line,
224
- current_position - size, @scanner.pos - size)
229
+ start_pos = source_position
230
+ value = token
231
+ return unless value
232
+ type, val = value
233
+ Token.new(type, val, range(start_pos), @scanner.pos - @scanner.matched_size)
225
234
  end
226
235
 
227
236
  def whitespace
@@ -236,8 +245,8 @@ module Sass
236
245
  end
237
246
 
238
247
  variable || string(:double, false) || string(:single, false) || number ||
239
- color || bool || null || string(:uri, false) || raw(UNICODERANGE) ||
240
- special_fun || special_val || ident_op || ident || op
248
+ color || bool || null || selector || string(:uri, false) ||
249
+ raw(UNICODERANGE) || special_fun || special_val || ident_op || ident || op
241
250
  end
242
251
 
243
252
  def variable
@@ -257,15 +266,17 @@ module Sass
257
266
 
258
267
  def string(re, open)
259
268
  return unless scan(STRING_REGULAR_EXPRESSIONS[[re, open]])
260
- if @scanner[2] == '#{' #'
269
+ if @scanner[2] == '#{' # '
261
270
  @scanner.pos -= 2 # Don't actually consume the #{
271
+ @offset -= 2
262
272
  @interpolation_stack << re
263
273
  end
264
274
  str =
265
275
  if re == :uri
266
- Script::String.new("#{'url(' unless open}#{@scanner[1]}#{')' unless @scanner[2] == '#{'}")
276
+ url = "#{'url(' unless open}#{@scanner[1]}#{')' unless @scanner[2] == '#{'}"
277
+ Script::Value::String.new(url)
267
278
  else
268
- Script::String.new(@scanner[1].gsub(/\\(['"]|\#\{)/, '\1'), :string)
279
+ Script::Value::String.new(@scanner[1].gsub(/\\(['"]|\#\{)/, '\1'), :string)
269
280
  end
270
281
  [:string, str]
271
282
  end
@@ -274,74 +285,95 @@ module Sass
274
285
  return unless scan(REGULAR_EXPRESSIONS[:number])
275
286
  value = @scanner[2] ? @scanner[2].to_f : @scanner[3].to_i
276
287
  value = -value if @scanner[1]
277
- [:number, Script::Number.new(value, Array(@scanner[4]))]
288
+ script_number = Script::Value::Number.new(value, Array(@scanner[4]))
289
+ [:number, script_number]
278
290
  end
279
291
 
280
292
  def color
281
- return unless s = scan(REGULAR_EXPRESSIONS[:color])
293
+ s = scan(REGULAR_EXPRESSIONS[:color])
294
+ return unless s
282
295
  raise Sass::SyntaxError.new(<<MESSAGE.rstrip) unless s.size == 4 || s.size == 7
283
296
  Colors must have either three or six digits: '#{s}'
284
297
  MESSAGE
285
- value = s.scan(/^#(..?)(..?)(..?)$/).first.
286
- map {|num| num.ljust(2, num).to_i(16)}
287
- [:color, Script::Color.new(value)]
298
+ script_color = Script::Value::Color.from_hex(s)
299
+ [:color, script_color]
288
300
  end
289
301
 
290
302
  def bool
291
- return unless s = scan(REGULAR_EXPRESSIONS[:bool])
292
- [:bool, Script::Bool.new(s == 'true')]
303
+ s = scan(REGULAR_EXPRESSIONS[:bool])
304
+ return unless s
305
+ script_bool = Script::Value::Bool.new(s == 'true')
306
+ [:bool, script_bool]
293
307
  end
294
308
 
295
309
  def null
296
310
  return unless scan(REGULAR_EXPRESSIONS[:null])
297
- [:null, Script::Null.new]
311
+ script_null = Script::Value::Null.new
312
+ [:null, script_null]
313
+ end
314
+
315
+ def selector
316
+ start_pos = source_position
317
+ return unless scan(REGULAR_EXPRESSIONS[:selector])
318
+ script_selector = Script::Tree::Selector.new
319
+ script_selector.source_range = range(start_pos)
320
+ [:selector, script_selector]
298
321
  end
299
322
 
300
323
  def special_fun
301
- return unless str1 = scan(/((-[\w-]+-)?(calc|element)|expression|progid:[a-z\.]*)\(/i)
324
+ str1 = scan(/((-[\w-]+-)?(calc|element)|expression|progid:[a-z\.]*)\(/i)
325
+ return unless str1
302
326
  str2, _ = Sass::Shared.balance(@scanner, ?(, ?), 1)
303
327
  c = str2.count("\n")
304
328
  old_line = @line
305
329
  old_offset = @offset
306
330
  @line += c
307
- @offset = (c == 0 ? @offset + str2.size : str2[/\n(.*)/, 1].size)
331
+ @offset = c == 0 ? @offset + str2.size : str2[/\n([^\n]*)/, 1].size + 1
308
332
  [:special_fun,
309
- Sass::Util.merge_adjacent_strings(
333
+ Sass::Util.merge_adjacent_strings(
310
334
  [str1] + Sass::Engine.parse_interp(str2, old_line, old_offset, @options)),
311
- str1.size + str2.size]
335
+ str1.size + str2.size]
312
336
  end
313
337
 
314
338
  def special_val
315
339
  return unless scan(/!important/i)
316
- [:string, Script::String.new("!important")]
340
+ [:string, Script::Value::String.new("!important")]
317
341
  end
318
342
 
319
343
  def ident_op
320
- return unless op = scan(REGULAR_EXPRESSIONS[:ident_op])
344
+ op = scan(REGULAR_EXPRESSIONS[:ident_op])
345
+ return unless op
321
346
  [OPERATORS[op]]
322
347
  end
323
348
 
324
349
  def op
325
- return unless op = scan(REGULAR_EXPRESSIONS[:op])
350
+ op = scan(REGULAR_EXPRESSIONS[:op])
351
+ return unless op
326
352
  @interpolation_stack << nil if op == :begin_interpolation
327
353
  [OPERATORS[op]]
328
354
  end
329
355
 
330
356
  def raw(rx)
331
- return unless val = scan(rx)
357
+ val = scan(rx)
358
+ return unless val
332
359
  [:raw, val]
333
360
  end
334
361
 
335
362
  def scan(re)
336
- return unless str = @scanner.scan(re)
363
+ str = @scanner.scan(re)
364
+ return unless str
337
365
  c = str.count("\n")
338
366
  @line += c
339
- @offset = (c == 0 ? @offset + str.size : str[/\n(.*)/, 1].size)
367
+ @offset = (c == 0 ? @offset + str.size : str[/\n([^\n]*)/, 1].size + 1)
340
368
  str
341
369
  end
342
370
 
343
- def current_position
344
- @offset + 1
371
+ def range(start_pos, end_pos = source_position)
372
+ Sass::Source::Range.new(start_pos, end_pos, @options[:filename], @options[:importer])
373
+ end
374
+
375
+ def source_position
376
+ Sass::Source::Position.new(@line, @offset)
345
377
  end
346
378
  end
347
379
  end