sass 3.4.0 → 3.4.25

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 (142) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +3 -1
  3. data/CODE_OF_CONDUCT.md +10 -0
  4. data/CONTRIBUTING.md +148 -0
  5. data/MIT-LICENSE +1 -1
  6. data/README.md +26 -20
  7. data/Rakefile +103 -20
  8. data/VERSION +1 -1
  9. data/VERSION_DATE +1 -1
  10. data/extra/sass-spec-ref.sh +32 -0
  11. data/extra/update_watch.rb +1 -1
  12. data/lib/sass/cache_stores/filesystem.rb +7 -7
  13. data/lib/sass/cache_stores/memory.rb +4 -5
  14. data/lib/sass/callbacks.rb +2 -2
  15. data/lib/sass/css.rb +11 -10
  16. data/lib/sass/deprecation.rb +55 -0
  17. data/lib/sass/engine.rb +83 -38
  18. data/lib/sass/environment.rb +26 -2
  19. data/lib/sass/error.rb +12 -12
  20. data/lib/sass/exec/base.rb +15 -3
  21. data/lib/sass/exec/sass_convert.rb +34 -15
  22. data/lib/sass/exec/sass_scss.rb +23 -7
  23. data/lib/sass/features.rb +2 -2
  24. data/lib/sass/importers/base.rb +1 -1
  25. data/lib/sass/importers/deprecated_path.rb +51 -0
  26. data/lib/sass/importers/filesystem.rb +24 -16
  27. data/lib/sass/importers.rb +1 -0
  28. data/lib/sass/logger/base.rb +8 -2
  29. data/lib/sass/logger/delayed.rb +50 -0
  30. data/lib/sass/logger.rb +8 -3
  31. data/lib/sass/plugin/compiler.rb +42 -25
  32. data/lib/sass/plugin/configuration.rb +38 -22
  33. data/lib/sass/plugin/merb.rb +2 -2
  34. data/lib/sass/plugin/rack.rb +3 -3
  35. data/lib/sass/plugin/rails.rb +1 -1
  36. data/lib/sass/plugin/staleness_checker.rb +3 -3
  37. data/lib/sass/plugin.rb +3 -2
  38. data/lib/sass/script/css_parser.rb +2 -3
  39. data/lib/sass/script/css_variable_warning.rb +52 -0
  40. data/lib/sass/script/functions.rb +140 -73
  41. data/lib/sass/script/lexer.rb +37 -22
  42. data/lib/sass/script/parser.rb +235 -40
  43. data/lib/sass/script/tree/funcall.rb +12 -5
  44. data/lib/sass/script/tree/interpolation.rb +109 -4
  45. data/lib/sass/script/tree/list_literal.rb +31 -4
  46. data/lib/sass/script/tree/literal.rb +4 -0
  47. data/lib/sass/script/tree/node.rb +21 -3
  48. data/lib/sass/script/tree/operation.rb +54 -1
  49. data/lib/sass/script/tree/string_interpolation.rb +58 -37
  50. data/lib/sass/script/tree/variable.rb +1 -1
  51. data/lib/sass/script/value/base.rb +10 -9
  52. data/lib/sass/script/value/color.rb +42 -24
  53. data/lib/sass/script/value/helpers.rb +16 -6
  54. data/lib/sass/script/value/map.rb +1 -1
  55. data/lib/sass/script/value/number.rb +52 -19
  56. data/lib/sass/script/value/string.rb +46 -5
  57. data/lib/sass/script.rb +3 -3
  58. data/lib/sass/scss/css_parser.rb +16 -2
  59. data/lib/sass/scss/parser.rb +120 -75
  60. data/lib/sass/scss/rx.rb +9 -10
  61. data/lib/sass/scss/static_parser.rb +19 -14
  62. data/lib/sass/scss.rb +0 -2
  63. data/lib/sass/selector/abstract_sequence.rb +8 -6
  64. data/lib/sass/selector/comma_sequence.rb +25 -9
  65. data/lib/sass/selector/pseudo.rb +45 -35
  66. data/lib/sass/selector/sequence.rb +54 -18
  67. data/lib/sass/selector/simple.rb +11 -11
  68. data/lib/sass/selector/simple_sequence.rb +34 -15
  69. data/lib/sass/selector.rb +7 -10
  70. data/lib/sass/shared.rb +1 -1
  71. data/lib/sass/source/map.rb +7 -4
  72. data/lib/sass/source/position.rb +4 -4
  73. data/lib/sass/stack.rb +2 -2
  74. data/lib/sass/supports.rb +8 -10
  75. data/lib/sass/tree/comment_node.rb +1 -1
  76. data/lib/sass/tree/css_import_node.rb +9 -1
  77. data/lib/sass/tree/function_node.rb +8 -3
  78. data/lib/sass/tree/import_node.rb +6 -5
  79. data/lib/sass/tree/node.rb +5 -3
  80. data/lib/sass/tree/prop_node.rb +5 -6
  81. data/lib/sass/tree/rule_node.rb +14 -4
  82. data/lib/sass/tree/visitors/check_nesting.rb +18 -22
  83. data/lib/sass/tree/visitors/convert.rb +43 -26
  84. data/lib/sass/tree/visitors/cssize.rb +5 -1
  85. data/lib/sass/tree/visitors/deep_copy.rb +1 -1
  86. data/lib/sass/tree/visitors/extend.rb +15 -13
  87. data/lib/sass/tree/visitors/perform.rb +42 -17
  88. data/lib/sass/tree/visitors/set_options.rb +1 -1
  89. data/lib/sass/tree/visitors/to_css.rb +58 -30
  90. data/lib/sass/util/multibyte_string_scanner.rb +0 -2
  91. data/lib/sass/util/normalized_map.rb +0 -1
  92. data/lib/sass/util/subset_map.rb +1 -2
  93. data/lib/sass/util.rb +125 -68
  94. data/lib/sass/version.rb +2 -2
  95. data/lib/sass.rb +10 -3
  96. data/test/sass/compiler_test.rb +6 -2
  97. data/test/sass/conversion_test.rb +187 -53
  98. data/test/sass/css2sass_test.rb +50 -1
  99. data/test/sass/css_variable_test.rb +132 -0
  100. data/test/sass/engine_test.rb +207 -61
  101. data/test/sass/exec_test.rb +10 -0
  102. data/test/sass/extend_test.rb +101 -29
  103. data/test/sass/functions_test.rb +60 -9
  104. data/test/sass/importer_test.rb +9 -0
  105. data/test/sass/more_templates/more1.sass +10 -10
  106. data/test/sass/more_templates/more_import.sass +2 -2
  107. data/test/sass/plugin_test.rb +10 -8
  108. data/test/sass/results/script.css +3 -3
  109. data/test/sass/script_conversion_test.rb +58 -29
  110. data/test/sass/script_test.rb +430 -53
  111. data/test/sass/scss/css_test.rb +73 -7
  112. data/test/sass/scss/rx_test.rb +4 -0
  113. data/test/sass/scss/scss_test.rb +309 -4
  114. data/test/sass/source_map_test.rb +152 -74
  115. data/test/sass/superselector_test.rb +19 -0
  116. data/test/sass/templates/_partial.sass +1 -1
  117. data/test/sass/templates/basic.sass +10 -10
  118. data/test/sass/templates/bork1.sass +1 -1
  119. data/test/sass/templates/bork5.sass +1 -1
  120. data/test/sass/templates/compact.sass +10 -10
  121. data/test/sass/templates/complex.sass +187 -187
  122. data/test/sass/templates/compressed.sass +10 -10
  123. data/test/sass/templates/expanded.sass +10 -10
  124. data/test/sass/templates/import.sass +2 -2
  125. data/test/sass/templates/importee.sass +3 -3
  126. data/test/sass/templates/mixins.sass +22 -22
  127. data/test/sass/templates/multiline.sass +4 -4
  128. data/test/sass/templates/nested.sass +13 -13
  129. data/test/sass/templates/parent_ref.sass +12 -12
  130. data/test/sass/templates/script.sass +70 -70
  131. data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +1 -1
  132. data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +2 -2
  133. data/test/sass/templates/subdir/subdir.sass +3 -3
  134. data/test/sass/templates/units.sass +10 -10
  135. data/test/sass/util/multibyte_string_scanner_test.rb +10 -2
  136. data/test/sass/util_test.rb +15 -44
  137. data/test/sass-spec.yml +3 -0
  138. data/test/test_helper.rb +5 -4
  139. metadata +302 -295
  140. data/CONTRIBUTING +0 -3
  141. data/lib/sass/scss/script_lexer.rb +0 -15
  142. data/lib/sass/scss/script_parser.rb +0 -25
@@ -0,0 +1,51 @@
1
+ module Sass
2
+ module Importers
3
+ # This importer emits a deprecation warning the first time it is used to
4
+ # import a file. It is used to deprecate the current working
5
+ # directory from the list of automatic sass load paths.
6
+ class DeprecatedPath < Filesystem
7
+ # @param root [String] The absolute, expanded path to the folder that is deprecated.
8
+ def initialize(root)
9
+ @specified_root = root
10
+ @warning_given = false
11
+ super
12
+ end
13
+
14
+ # @see Sass::Importers::Base#find
15
+ def find(*args)
16
+ found = super
17
+ if found && !@warning_given
18
+ @warning_given = true
19
+ Sass::Util.sass_warn deprecation_warning
20
+ end
21
+ found
22
+ end
23
+
24
+ # @see Base#directories_to_watch
25
+ def directories_to_watch
26
+ # The current working directory was not watched in Sass 3.2,
27
+ # so we continue not to watch it while it's deprecated.
28
+ []
29
+ end
30
+
31
+ # @see Sass::Importers::Base#to_s
32
+ def to_s
33
+ "#{@root} (DEPRECATED)"
34
+ end
35
+
36
+ protected
37
+
38
+ # @return [String] The deprecation warning that will be printed the first
39
+ # time an import occurs.
40
+ def deprecation_warning
41
+ path = @specified_root == "." ? "the current working directory" : @specified_root
42
+ <<WARNING
43
+ DEPRECATION WARNING: Importing from #{path} will not be
44
+ automatic in future versions of Sass. To avoid future errors, you can add it
45
+ to your environment explicitly by setting `SASS_PATH=#{@specified_root}`, by using the -I command
46
+ line option, or by changing your Sass configuration options.
47
+ WARNING
48
+ end
49
+ end
50
+ end
51
+ end
@@ -13,6 +13,7 @@ module Sass
13
13
  # This importer will import files relative to this path.
14
14
  def initialize(root)
15
15
  @root = File.expand_path(root)
16
+ @real_root = Sass::Util.realpath(@root).to_s
16
17
  @same_name_warnings = Set.new
17
18
  end
18
19
 
@@ -50,7 +51,7 @@ module Sass
50
51
  end
51
52
 
52
53
  def eql?(other)
53
- root.eql?(other.root)
54
+ !other.nil? && other.respond_to?(:root) && root.eql?(other.root)
54
55
  end
55
56
 
56
57
  # @see Base#directories_to_watch
@@ -60,21 +61,21 @@ module Sass
60
61
 
61
62
  # @see Base#watched_file?
62
63
  def watched_file?(filename)
63
- filename =~ /\.s[ac]ss$/ &&
64
- filename.start_with?(root + File::SEPARATOR)
64
+ # Check against the root with symlinks resolved, since Listen
65
+ # returns fully-resolved paths.
66
+ filename =~ /\.s[ac]ss$/ && filename.start_with?(@real_root + File::SEPARATOR)
65
67
  end
66
68
 
67
69
  def public_url(name, sourcemap_directory)
68
70
  file_pathname = Sass::Util.cleanpath(Sass::Util.absolute_path(name, @root))
69
- if sourcemap_directory.nil?
71
+ return Sass::Util.file_uri_from_path(file_pathname) if sourcemap_directory.nil?
72
+
73
+ sourcemap_pathname = Sass::Util.cleanpath(sourcemap_directory)
74
+ begin
75
+ Sass::Util.file_uri_from_path(
76
+ Sass::Util.relative_path_from(file_pathname, sourcemap_pathname))
77
+ rescue ArgumentError # when a relative path cannot be constructed
70
78
  Sass::Util.file_uri_from_path(file_pathname)
71
- else
72
- sourcemap_pathname = Sass::Util.cleanpath(sourcemap_directory)
73
- begin
74
- Sass::Util.file_uri_from_path(file_pathname.relative_path_from(sourcemap_pathname))
75
- rescue ArgumentError # when a relative path cannot be constructed
76
- Sass::Util.file_uri_from_path(file_pathname)
77
- end
78
79
  end
79
80
  end
80
81
 
@@ -121,7 +122,7 @@ module Sass
121
122
  end
122
123
 
123
124
  # JRuby chokes when trying to import files from JARs when the path starts with './'.
124
- ret.map {|f, s| [f.sub(/^\.\//, ''), s]}
125
+ ret.map {|f, s| [f.sub(%r{^\./}, ''), s]}
125
126
  end
126
127
 
127
128
  def escape_glob_characters(name)
@@ -143,14 +144,16 @@ module Sass
143
144
  name = name.gsub(File::ALT_SEPARATOR, File::SEPARATOR) unless File::ALT_SEPARATOR.nil?
144
145
 
145
146
  found = possible_files(remove_root(name)).map do |f, s|
146
- path = (dir == "." || Sass::Util.pathname(f).absolute?) ? f :
147
- "#{escape_glob_characters(dir)}/#{f}"
147
+ path = if dir == "." || Sass::Util.pathname(f).absolute?
148
+ f
149
+ else
150
+ "#{escape_glob_characters(dir)}/#{f}"
151
+ end
148
152
  Dir[path].map do |full_path|
149
153
  full_path.gsub!(REDUNDANT_DIRECTORY, File::SEPARATOR)
150
154
  [Sass::Util.cleanpath(full_path).to_s, s]
151
155
  end
152
- end
153
- found = Sass::Util.flatten(found, 1)
156
+ end.flatten(1)
154
157
  return if found.empty?
155
158
 
156
159
  if found.size > 1 && !@same_name_warnings.include?(found.first.first)
@@ -201,6 +204,11 @@ WARNING
201
204
  full_filename, syntax = Sass::Util.destructure(find_real_file(dir, name, options))
202
205
  return unless full_filename && File.readable?(full_filename)
203
206
 
207
+ # TODO: this preserves historical behavior, but it's possible
208
+ # :filename should be either normalized to the native format
209
+ # or consistently URI-format.
210
+ full_filename = full_filename.tr("\\", "/") if Sass::Util.windows?
211
+
204
212
  options[:syntax] = syntax
205
213
  options[:filename] = full_filename
206
214
  options[:importer] = self
@@ -20,3 +20,4 @@ end
20
20
 
21
21
  require 'sass/importers/base'
22
22
  require 'sass/importers/filesystem'
23
+ require 'sass/importers/deprecated_path'
@@ -5,6 +5,7 @@ class Sass::Logger::Base
5
5
 
6
6
  attr_accessor :log_level
7
7
  attr_accessor :disabled
8
+ attr_accessor :io
8
9
 
9
10
  log_level :trace
10
11
  log_level :debug
@@ -12,8 +13,9 @@ class Sass::Logger::Base
12
13
  log_level :warn
13
14
  log_level :error
14
15
 
15
- def initialize(log_level = :debug)
16
+ def initialize(log_level = :debug, io = nil)
16
17
  self.log_level = log_level
18
+ self.io = io
17
19
  end
18
20
 
19
21
  def logging_level?(level)
@@ -25,6 +27,10 @@ class Sass::Logger::Base
25
27
  end
26
28
 
27
29
  def _log(level, message)
28
- Kernel.warn(message)
30
+ if io
31
+ io.puts(message)
32
+ else
33
+ Kernel.warn(message)
34
+ end
29
35
  end
30
36
  end
@@ -0,0 +1,50 @@
1
+ require 'sass/logger/log_level'
2
+
3
+ # A logger that delays messages until they're explicitly flushed to an inner
4
+ # logger.
5
+ #
6
+ # This can be installed around the current logger by calling \{#install!}, and
7
+ # the original logger can be replaced by calling \{#uninstall!}. The log
8
+ # messages can be flushed by calling \{#flush}.
9
+ class Sass::Logger::Delayed < Sass::Logger::Base
10
+ # Installs a new delayed logger as the current Sass logger, wrapping the
11
+ # original logger.
12
+ #
13
+ # This can be undone by calling \{#uninstall!}.
14
+ #
15
+ # @return [Sass::Logger::Delayed] The newly-created logger.
16
+ def self.install!
17
+ logger = Sass::Logger::Delayed.new(Sass.logger)
18
+ Sass.logger = logger
19
+ logger
20
+ end
21
+
22
+ # Creates a delayed logger wrapping `inner`.
23
+ #
24
+ # @param inner [Sass::Logger::Base] The wrapped logger.
25
+ def initialize(inner)
26
+ self.log_level = inner.log_level
27
+ @inner = inner
28
+ @messages = []
29
+ end
30
+
31
+ # Flushes all queued logs to the wrapped logger.
32
+ def flush
33
+ @messages.each {|(l, m)| @inner.log(l, m)}
34
+ end
35
+
36
+ # Uninstalls this logger from \{Sass.logger\}. This should only be called if
37
+ # the logger was installed using \{#install!}
38
+ def uninstall!
39
+ if Sass.logger != self
40
+ throw Exception.new("Can't uninstall a logger that's not currently installed.")
41
+ end
42
+
43
+ @inner.log_level = log_level
44
+ Sass.logger = @inner
45
+ end
46
+
47
+ def _log(level, message)
48
+ @messages << [level, message]
49
+ end
50
+ end
data/lib/sass/logger.rb CHANGED
@@ -2,11 +2,16 @@ module Sass::Logger; end
2
2
 
3
3
  require "sass/logger/log_level"
4
4
  require "sass/logger/base"
5
+ require "sass/logger/delayed"
5
6
 
6
7
  module Sass
7
8
  class << self
8
- attr_accessor :logger
9
- end
9
+ def logger=(l)
10
+ Thread.current[:sass_logger] = l
11
+ end
10
12
 
11
- self.logger = Sass::Logger::Base.new
13
+ def logger
14
+ Thread.current[:sass_logger] ||= Sass::Logger::Base.new
15
+ end
16
+ end
12
17
  end
@@ -31,8 +31,9 @@ module Sass::Plugin
31
31
  # Creates a new compiler.
32
32
  #
33
33
  # @param opts [{Symbol => Object}]
34
- # See {file:SASS_REFERENCE.md#sass_options the Sass options documentation}.
34
+ # See {file:SASS_REFERENCE.md#Options the Sass options documentation}.
35
35
  def initialize(opts = {})
36
+ @watched_files = Set.new
36
37
  options.merge!(opts)
37
38
  end
38
39
 
@@ -238,18 +239,19 @@ module Sass::Plugin
238
239
  # of the directories being updated.
239
240
  def file_list(individual_files = [])
240
241
  files = individual_files.map do |tuple|
241
- if tuple.size < 3
242
+ if engine_options[:sourcemap] == :none
243
+ tuple[0..1]
244
+ elsif tuple.size < 3
242
245
  [tuple[0], tuple[1], Sass::Util.sourcemap_name(tuple[1])]
243
246
  else
244
- tuple
247
+ tuple.dup
245
248
  end
246
249
  end
247
250
 
248
251
  template_location_array.each do |template_location, css_location|
249
252
  Sass::Util.glob(File.join(template_location, "**", "[^_]*.s[ca]ss")).sort.each do |file|
250
253
  # Get the relative path to the file
251
- name = Sass::Util.pathname(file).relative_path_from(
252
- Sass::Util.pathname(template_location.to_s)).to_s
254
+ name = Sass::Util.relative_path_from(file, template_location).to_s
253
255
  css = css_filename(name, css_location)
254
256
  sourcemap = Sass::Util.sourcemap_name(css) unless engine_options[:sourcemap] == :none
255
257
  files << [file, css, sourcemap]
@@ -287,13 +289,18 @@ module Sass::Plugin
287
289
  # @option options [Boolean] :skip_initial_update
288
290
  # Don't do an initial update when starting the watcher when true
289
291
  def watch(individual_files = [], options = {})
292
+ @inferred_directories = []
290
293
  options, individual_files = individual_files, [] if individual_files.is_a?(Hash)
291
294
  update_stylesheets(individual_files) unless options[:skip_initial_update]
292
295
 
293
296
  directories = watched_paths
294
297
  individual_files.each do |(source, _, _)|
295
- directories << File.dirname(File.expand_path(source))
298
+ source = File.expand_path(source)
299
+ @watched_files << Sass::Util.realpath(source).to_s
300
+ @inferred_directories << File.dirname(source)
296
301
  end
302
+
303
+ directories += @inferred_directories
297
304
  directories = remove_redundant_directories(directories)
298
305
 
299
306
  # A Listen version prior to 2.0 will write a test file to a directory to
@@ -395,7 +402,8 @@ module Sass::Plugin
395
402
 
396
403
  def listen_to(listener)
397
404
  if Sass::Util.listen_geq_2?
398
- listener.map {|l| l.start}.each {|thread| thread.join}
405
+ listener.map {|l| l.start}
406
+ sleep
399
407
  else
400
408
  listener.start!
401
409
  end
@@ -435,6 +443,7 @@ module Sass::Plugin
435
443
  end
436
444
 
437
445
  removed.uniq.each do |f|
446
+ next unless watched_file?(f)
438
447
  run_template_deleted(relative_to_pwd(f))
439
448
  if (files = individual_files.find {|(source, _, _)| File.expand_path(source) == f})
440
449
  recompile_required = true
@@ -448,21 +457,20 @@ module Sass::Plugin
448
457
  # And try to remove the css file that corresponds to it
449
458
  template_location_array.each do |(sass_dir, css_dir)|
450
459
  sass_dir = File.expand_path(sass_dir)
451
- if child_of_directory?(sass_dir, f)
452
- remainder = f[(sass_dir.size + 1)..-1]
453
- try_delete_css(css_filename(remainder, css_dir))
454
- break
455
- end
460
+ next unless child_of_directory?(sass_dir, f)
461
+ remainder = f[(sass_dir.size + 1)..-1]
462
+ try_delete_css(css_filename(remainder, css_dir))
463
+ break
456
464
  end
457
465
  end
458
466
  end
459
467
 
460
- if recompile_required
461
- # In case a file we're watching is removed and then recreated we
462
- # prune out the non-existant files here.
463
- watched_files_remaining = individual_files.select {|(source, _, _)| File.exist?(source)}
464
- update_stylesheets(watched_files_remaining)
465
- end
468
+ return unless recompile_required
469
+
470
+ # In case a file we're watching is removed and then recreated we
471
+ # prune out the non-existant files here.
472
+ watched_files_remaining = individual_files.select {|(source, _, _)| File.exist?(source)}
473
+ update_stylesheets(watched_files_remaining)
466
474
  end
467
475
 
468
476
  def update_stylesheet(filename, css, sourcemap)
@@ -494,7 +502,9 @@ module Sass::Plugin
494
502
 
495
503
  write_file(css, rendered)
496
504
  if mapping
497
- write_file(sourcemap, mapping.to_json(
505
+ write_file(
506
+ sourcemap,
507
+ mapping.to_json(
498
508
  :css_path => css, :sourcemap_path => sourcemap, :type => options[:sourcemap]))
499
509
  end
500
510
  run_updated_stylesheet(filename, css, sourcemap) unless compilation_error_occured
@@ -515,14 +525,21 @@ module Sass::Plugin
515
525
  File.delete css
516
526
  end
517
527
  map = Sass::Util.sourcemap_name(css)
518
- if File.exist?(map)
519
- run_deleting_sourcemap map
520
- File.delete map
521
- end
528
+
529
+ return unless File.exist?(map)
530
+
531
+ run_deleting_sourcemap map
532
+ File.delete map
522
533
  end
523
534
 
524
535
  def watched_file?(file)
525
- normalized_load_paths.find {|lp| lp.watched_file?(file)}
536
+ @watched_files.include?(file) ||
537
+ normalized_load_paths.any? {|lp| lp.watched_file?(file)} ||
538
+ @inferred_directories.any? {|d| sass_file_in_directory?(d, file)}
539
+ end
540
+
541
+ def sass_file_in_directory?(directory, filename)
542
+ filename =~ /\.s[ac]ss$/ && filename.start_with?(directory + File::SEPARATOR)
526
543
  end
527
544
 
528
545
  def watched_paths
@@ -552,7 +569,7 @@ module Sass::Plugin
552
569
  end
553
570
 
554
571
  def relative_to_pwd(f)
555
- Sass::Util.pathname(f).relative_path_from(Sass::Util.pathname(Dir.pwd)).to_s
572
+ Sass::Util.relative_path_from(f, Dir.pwd).to_s
556
573
  rescue ArgumentError # when a relative path cannot be computed
557
574
  f
558
575
  end
@@ -1,8 +1,10 @@
1
1
  module Sass
2
2
  module Plugin
3
- # We keep configuration in its own self-contained file
4
- # so that we can load it independently in Rails 3,
5
- # where the full plugin stuff is lazy-loaded.
3
+ # We keep configuration in its own self-contained file so that we can load
4
+ # it independently in Rails 3, where the full plugin stuff is lazy-loaded.
5
+ #
6
+ # Note that this is not guaranteed to be thread-safe. For guaranteed thread
7
+ # safety, use a separate {Sass::Plugin} for each thread.
6
8
  module Configuration
7
9
  # Returns the default options for a {Sass::Plugin::Compiler}.
8
10
  #
@@ -25,7 +27,7 @@ module Sass
25
27
  end
26
28
 
27
29
  # An options hash.
28
- # See {file:SASS_REFERENCE.md#sass_options the Sass options documentation}.
30
+ # See {file:SASS_REFERENCE.md#Options the Sass options documentation}.
29
31
  #
30
32
  # @return [{Symbol => Object}]
31
33
  def options
@@ -85,33 +87,47 @@ module Sass
85
87
  # See the {file:SASS_REFERENCE.md#template_location-option `:template_location` option}
86
88
  # for details.
87
89
  #
90
+ # Modifications to the returned array may not be persistent. Use {#add_template_location}
91
+ # and {#remove_template_location} instead.
92
+ #
88
93
  # @return [Array<(String, String)>]
89
94
  # An array of `[template_location, css_location]` pairs.
90
95
  def template_location_array
91
- old_template_location = options[:template_location]
92
- normalize_template_location!
93
- options[:template_location]
94
- ensure
95
- options[:template_location] = old_template_location
96
+ convert_template_location(options[:template_location], options[:css_location])
96
97
  end
97
98
 
98
99
  private
99
100
 
100
- def normalize_template_location!
101
- return if options[:template_location].is_a?(Array)
102
- options[:template_location] =
103
- case options[:template_location]
104
- when nil
105
- if options[:css_location]
106
- [[File.join(options[:css_location], 'sass'), options[:css_location]]]
107
- else
108
- []
109
- end
110
- when String
111
- [[options[:template_location], options[:css_location]]]
101
+ # Returns the given template location, as an array. If it's already an array,
102
+ # it is returned unmodified. Otherwise, a new array is created and returned.
103
+ #
104
+ # @param template_location [String, Array<(String, String)>]
105
+ # A single template location, or a pre-normalized array of template
106
+ # locations and CSS locations.
107
+ # @param css_location [String?]
108
+ # The location for compiled CSS files.
109
+ # @return [Array<(String, String)>]
110
+ # An array of `[template_location, css_location]` pairs.
111
+ def convert_template_location(template_location, css_location)
112
+ return template_location if template_location.is_a?(Array)
113
+
114
+ case template_location
115
+ when nil
116
+ if css_location
117
+ [[File.join(css_location, 'sass'), css_location]]
112
118
  else
113
- options[:template_location].to_a
119
+ []
114
120
  end
121
+ when String
122
+ [[template_location, css_location]]
123
+ else
124
+ template_location.to_a
125
+ end
126
+ end
127
+
128
+ def normalize_template_location!
129
+ options[:template_location] = convert_template_location(
130
+ options[:template_location], options[:css_location])
115
131
  end
116
132
  end
117
133
  end
@@ -2,7 +2,7 @@ unless defined?(Sass::MERB_LOADED)
2
2
  Sass::MERB_LOADED = true
3
3
 
4
4
  module Sass::Plugin::Configuration
5
- # Different default options in a m envirionment.
5
+ # Different default options in a m environment.
6
6
  def default_options
7
7
  @default_options ||= begin
8
8
  version = Merb::VERSION.split('.').map {|n| n.to_i}
@@ -15,7 +15,7 @@ unless defined?(Sass::MERB_LOADED)
15
15
  end
16
16
 
17
17
  {
18
- :always_update => false,
18
+ :always_update => false,
19
19
  :template_location => root + '/public/stylesheets/sass',
20
20
  :css_location => root + '/public/stylesheets',
21
21
  :cache_location => root + '/tmp/sass-cache',
@@ -9,19 +9,19 @@ module Sass
9
9
  #
10
10
  # ## Customize
11
11
  #
12
- # Sass::Plugin.options.merge(
12
+ # Sass::Plugin.options.merge!(
13
13
  # :cache_location => './tmp/sass-cache',
14
14
  # :never_update => environment != :production,
15
15
  # :full_exception => environment != :production)
16
16
  #
17
- # {file:SASS_REFERENCE.md#options See the Reference for more options}.
17
+ # {file:SASS_REFERENCE.md#Options See the Reference for more options}.
18
18
  #
19
19
  # ## Use
20
20
  #
21
21
  # Put your Sass files in `public/stylesheets/sass`.
22
22
  # Your CSS will be generated in `public/stylesheets`,
23
23
  # and regenerated every request if necessary.
24
- # The locations and frequency {file:SASS_REFERENCE.md#options can be customized}.
24
+ # The locations and frequency {file:SASS_REFERENCE.md#Options can be customized}.
25
25
  # That's all there is to it!
26
26
  class Rack
27
27
  # The delay, in seconds, between update checks.
@@ -2,7 +2,7 @@ unless defined?(Sass::RAILS_LOADED)
2
2
  Sass::RAILS_LOADED = true
3
3
 
4
4
  module Sass::Plugin::Configuration
5
- # Different default options in a rails envirionment.
5
+ # Different default options in a rails environment.
6
6
  def default_options
7
7
  return @default_options if @default_options
8
8
  opts = {
@@ -39,7 +39,7 @@ module Sass
39
39
  # for checking the staleness of several stylesheets at once.
40
40
  #
41
41
  # @param options [{Symbol => Object}]
42
- # See {file:SASS_REFERENCE.md#sass_options the Sass options documentation}.
42
+ # See {file:SASS_REFERENCE.md#Options the Sass options documentation}.
43
43
  def initialize(options)
44
44
  # URIs that are being actively checked for staleness. Protects against
45
45
  # import loops.
@@ -72,7 +72,7 @@ module Sass
72
72
  # Returns whether a Sass or SCSS stylesheet has been modified since a given time.
73
73
  #
74
74
  # @param template_file [String] The location of the Sass or SCSS template.
75
- # @param mtime [Fixnum] The modification time to check against.
75
+ # @param mtime [Time] The modification time to check against.
76
76
  # @param importer [Sass::Importers::Base] The importer used to locate the stylesheet.
77
77
  # Defaults to the filesystem importer.
78
78
  # @return [Boolean] Whether the stylesheet has been modified.
@@ -103,7 +103,7 @@ module Sass
103
103
  # so it's better to use when checking multiple stylesheets at once.
104
104
  #
105
105
  # @param template_file [String] The location of the Sass or SCSS template.
106
- # @param mtime [Fixnum] The modification time to check against.
106
+ # @param mtime [Time] The modification time to check against.
107
107
  # @param importer [Sass::Importers::Base] The importer used to locate the stylesheet.
108
108
  # Defaults to the filesystem importer.
109
109
  # @return [Boolean] Whether the stylesheet has been modified.
data/lib/sass/plugin.rb CHANGED
@@ -12,7 +12,7 @@ module Sass
12
12
  # when it's used as a plugin for various frameworks.
13
13
  # All Rack-enabled frameworks are supported out of the box.
14
14
  # The plugin is
15
- # {file:SASS_REFERENCE.md#rails_merb_plugin automatically activated for Rails and Merb}.
15
+ # {file:SASS_REFERENCE.md#Rack_Rails_Merb_Plugin automatically activated for Rails and Merb}.
16
16
  # Other frameworks must enable it explicitly; see {Sass::Plugin::Rack}.
17
17
  #
18
18
  # This module has a large set of callbacks available
@@ -93,7 +93,8 @@ module Sass
93
93
  # the second is the location of the CSS file that it should be compiled to.
94
94
  # @see #update_stylesheets
95
95
  def force_update_stylesheets(individual_files = [])
96
- Compiler.new(options.dup.merge(
96
+ Compiler.new(
97
+ options.dup.merge(
97
98
  :never_update => false,
98
99
  :always_update => true,
99
100
  :cache => false)).update_stylesheets(individual_files)
@@ -19,9 +19,8 @@ module Sass
19
19
  def string
20
20
  tok = try_tok(:string)
21
21
  return number unless tok
22
- unless @lexer.peek && @lexer.peek.type == :begin_interpolation
23
- return literal_node(tok.value, tok.source_range)
24
- end
22
+ return if @lexer.peek && @lexer.peek.type == :begin_interpolation
23
+ literal_node(tok.value, tok.source_range)
25
24
  end
26
25
 
27
26
  # Short-circuit all the SassScript-only productions
@@ -0,0 +1,52 @@
1
+ module Sass
2
+ module Script
3
+ # An object tracking whether a warning has been emitted for a given script
4
+ # tree.
5
+ #
6
+ # This is shared among all objects in a script tree. Whenever any of those
7
+ # objects encounters a situation in which it wouldn't produce semantically
8
+ # identical CSS to its input, it calls \{#warn!\}. The first time \{#warn!}
9
+ # is called for a given warning object, it prints a deprecation warning.
10
+ class CssVariableWarning
11
+ def initialize
12
+ @warned = false
13
+ @value = nil
14
+ end
15
+
16
+ # Sets the root of the script tree that this warning refers to.
17
+ #
18
+ # @param value [Sass::Script::Tree::Node]
19
+ def value=(value)
20
+ warn_called = @warned && !@value
21
+ @value = value
22
+ print_warning if warn_called
23
+ end
24
+
25
+ # The first time this is called, it prints a deprecation warning.
26
+ #
27
+ # This may be called before \{#value=}. If it is, the warning is emitted
28
+ # once the script tree is set.
29
+ def warn!
30
+ return if @warned
31
+ @warned = true
32
+ return unless @value
33
+
34
+ print_warning
35
+ end
36
+
37
+ private
38
+
39
+ # Prints this node's warning.
40
+ def print_warning
41
+ of_filename = " of #{@value.filename}" if @value.filename
42
+ Sass::Util.sass_warn(
43
+ "DEPRECATION WARNING on line #{@value.line}#{of_filename}:\n" +
44
+ "Sass 3.6 will change the way CSS variables are parsed. Instead of being parsed as\n" +
45
+ "normal properties, they will not allow any Sass-specific behavior other than \#{}.\n" +
46
+ "For forwards-compatibility, use \#{}:\n" +
47
+ "\n" +
48
+ " --variable: \#{#{@value.to_sass}};")
49
+ end
50
+ end
51
+ end
52
+ end