sass 3.2.1 → 3.2.2
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.
- data/README.md +5 -4
- data/VERSION +1 -1
- data/VERSION_DATE +1 -1
- data/lib/sass/callbacks.rb +1 -1
- data/lib/sass/engine.rb +1 -1
- data/lib/sass/exec.rb +6 -0
- data/lib/sass/importers/filesystem.rb +41 -8
- data/lib/sass/logger/log_level.rb +3 -3
- data/lib/sass/plugin/compiler.rb +1 -1
- data/lib/sass/plugin/staleness_checker.rb +1 -1
- data/lib/sass/script/functions.rb +5 -5
- data/lib/sass/script/parser.rb +2 -2
- data/lib/sass/scss/parser.rb +12 -8
- data/lib/sass/tree/import_node.rb +9 -2
- data/lib/sass/tree/visitors/perform.rb +11 -9
- data/lib/sass/tree/visitors/set_options.rb +8 -0
- data/lib/sass/util.rb +13 -0
- data/test/sass/engine_test.rb +48 -3
- data/test/sass/plugin_test.rb +42 -6
- data/test/sass/results/cached_import_option.css +3 -0
- data/test/sass/scss/css_test.rb +12 -0
- data/test/sass/scss/scss_test.rb +8 -3
- data/test/sass/templates/_cached_import_option_partial.scss +1 -0
- data/test/sass/templates/_same_name_different_partiality.scss +1 -0
- data/test/sass/templates/cached_import_option.scss +3 -0
- data/test/sass/templates/same_name_different_ext.sass +2 -0
- data/test/sass/templates/same_name_different_ext.scss +1 -0
- data/test/sass/templates/same_name_different_partiality.scss +1 -0
- metadata +9 -2
data/README.md
CHANGED
@@ -173,10 +173,11 @@ See `sass-convert --help` for further information and options.
|
|
173
173
|
|
174
174
|
## Authors
|
175
175
|
|
176
|
-
Sass was envisioned by [Hampton Catlin](http://hamptoncatlin.com)
|
177
|
-
However, Hampton doesn't even know his way around the code anymore
|
178
|
-
occasionally consults on the language issues. Hampton lives in
|
179
|
-
|
176
|
+
Sass was envisioned by [Hampton Catlin](http://www.hamptoncatlin.com)
|
177
|
+
(@hcatlin). However, Hampton doesn't even know his way around the code anymore
|
178
|
+
and now occasionally consults on the language issues. Hampton lives in San
|
179
|
+
Francisco, California and works as VP of Technology
|
180
|
+
at [Moovweb](http://www.moovweb.com/).
|
180
181
|
|
181
182
|
[Nathan Weizenbaum](http://nex-3.com) is the primary developer and architect of
|
182
183
|
Sass. His hard work has kept the project alive by endlessly answering forum
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.2.
|
1
|
+
3.2.2
|
data/VERSION_DATE
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
03 November 2012 01:05:14 UTC
|
data/lib/sass/callbacks.rb
CHANGED
@@ -48,7 +48,7 @@ module Sass
|
|
48
48
|
# @param name [Symbol] The name of the callback
|
49
49
|
# @return [void]
|
50
50
|
def define_callback(name)
|
51
|
-
class_eval <<RUBY
|
51
|
+
class_eval <<RUBY, __FILE__, __LINE__ + 1
|
52
52
|
def on_#{name}(&block)
|
53
53
|
@_sass_callbacks ||= {}
|
54
54
|
(@_sass_callbacks[#{name.inspect}] ||= []) << block
|
data/lib/sass/engine.rb
CHANGED
@@ -820,7 +820,7 @@ WARNING
|
|
820
820
|
media_parser = Sass::SCSS::Parser.new(scanner, @options[:filename], @line)
|
821
821
|
media = media_parser.parse_media_query_list
|
822
822
|
Tree::CssImportNode.new(str || uri, media.to_a)
|
823
|
-
elsif val =~ /^
|
823
|
+
elsif val =~ /^(https?:)?\/\//
|
824
824
|
Tree::CssImportNode.new("url(#{val})")
|
825
825
|
else
|
826
826
|
Tree::ImportNode.new(val)
|
data/lib/sass/exec.rb
CHANGED
@@ -125,6 +125,7 @@ module Sass
|
|
125
125
|
def puts_action(name, color, arg)
|
126
126
|
return if @options[:for_engine][:quiet]
|
127
127
|
printf color(color, "%11s %s\n"), name, arg
|
128
|
+
STDOUT.flush
|
128
129
|
end
|
129
130
|
|
130
131
|
# Same as \{Kernel.puts}, but doesn't print anything if the `--quiet` option is set.
|
@@ -229,6 +230,10 @@ END
|
|
229
230
|
'Only meaningful for --watch and --update.') do
|
230
231
|
@options[:stop_on_error] = true
|
231
232
|
end
|
233
|
+
opts.on('--poll', 'Check for file changes manually, rather than relying on the OS.',
|
234
|
+
'Only meaningful for --watch.') do
|
235
|
+
@options[:poll] = true
|
236
|
+
end
|
232
237
|
opts.on('-f', '--force', 'Recompile all Sass files, even if the CSS file is newer.',
|
233
238
|
'Only meaningful for --update.') do
|
234
239
|
@options[:force] = true
|
@@ -357,6 +362,7 @@ END
|
|
357
362
|
require 'sass/plugin'
|
358
363
|
::Sass::Plugin.options.merge! @options[:for_engine]
|
359
364
|
::Sass::Plugin.options[:unix_newlines] = @options[:unix_newlines]
|
365
|
+
::Sass::Plugin.options[:poll] = @options[:poll]
|
360
366
|
|
361
367
|
if @options[:force]
|
362
368
|
raise "The --force flag may only be used with --update." unless @options[:update]
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'pathname'
|
2
|
+
require 'set'
|
2
3
|
|
3
4
|
module Sass
|
4
5
|
module Importers
|
@@ -14,6 +15,7 @@ module Sass
|
|
14
15
|
# This importer will import files relative to this path.
|
15
16
|
def initialize(root)
|
16
17
|
@root = File.expand_path(root)
|
18
|
+
@same_name_warnings = Set.new
|
17
19
|
end
|
18
20
|
|
19
21
|
# @see Base#find_relative
|
@@ -28,7 +30,7 @@ module Sass
|
|
28
30
|
|
29
31
|
# @see Base#mtime
|
30
32
|
def mtime(name, options)
|
31
|
-
file, s = find_real_file(@root, name)
|
33
|
+
file, s = Sass::Util.destructure(find_real_file(@root, name, options))
|
32
34
|
File.mtime(file) if file
|
33
35
|
rescue Errno::ENOENT
|
34
36
|
nil
|
@@ -106,15 +108,46 @@ module Sass
|
|
106
108
|
# @param dir [String] The directory relative to which to search.
|
107
109
|
# @param name [String] The filename to search for.
|
108
110
|
# @return [(String, Symbol)] A filename-syntax pair.
|
109
|
-
def find_real_file(dir, name)
|
110
|
-
|
111
|
+
def find_real_file(dir, name, options)
|
112
|
+
found = possible_files(remove_root(name)).map do |f, s|
|
111
113
|
path = (dir == "." || Pathname.new(f).absolute?) ? f : "#{dir}/#{f}"
|
112
|
-
|
113
|
-
full_path.gsub!(REDUNDANT_DIRECTORY,File::SEPARATOR)
|
114
|
-
|
114
|
+
Dir[path].map do |full_path|
|
115
|
+
full_path.gsub!(REDUNDANT_DIRECTORY, File::SEPARATOR)
|
116
|
+
[full_path, s]
|
115
117
|
end
|
116
118
|
end
|
117
|
-
|
119
|
+
found = Sass::Util.flatten(found, 1)
|
120
|
+
return if found.empty?
|
121
|
+
|
122
|
+
if found.size > 1 && !@same_name_warnings.include?(found.first.first)
|
123
|
+
found.each {|(f, _)| @same_name_warnings << f}
|
124
|
+
relative_to = Pathname.new(dir)
|
125
|
+
if options[:_line]
|
126
|
+
# If _line exists, we're here due to an actual import in an
|
127
|
+
# import_node and we want to print a warning for a user writing an
|
128
|
+
# ambiguous import.
|
129
|
+
candidates = found.map {|(f, _)| " " + Pathname.new(f).relative_path_from(relative_to).to_s}.join("\n")
|
130
|
+
Sass::Util.sass_warn <<WARNING
|
131
|
+
WARNING: On line #{options[:_line]}#{" of #{options[:filename]}" if options[:filename]}:
|
132
|
+
It's not clear which file to import for '@import "#{name}"'.
|
133
|
+
Candidates:
|
134
|
+
#{candidates}
|
135
|
+
For now I'll choose #{File.basename found.first.first}.
|
136
|
+
This will be an error in future versions of Sass.
|
137
|
+
WARNING
|
138
|
+
else
|
139
|
+
# Otherwise, we're here via StalenessChecker, and we want to print a
|
140
|
+
# warning for a user running `sass --watch` with two ambiguous files.
|
141
|
+
candidates = found.map {|(f, _)| " " + File.basename(f)}.join("\n")
|
142
|
+
Sass::Util.sass_warn <<WARNING
|
143
|
+
WARNING: In #{File.dirname(name)}:
|
144
|
+
There are multiple files that match the name "#{File.basename(name)}":
|
145
|
+
#{candidates}
|
146
|
+
This will be an error in future versions of Sass.
|
147
|
+
WARNING
|
148
|
+
end
|
149
|
+
end
|
150
|
+
found.first
|
118
151
|
end
|
119
152
|
|
120
153
|
# Splits a filename into three parts, a directory part, a basename, and an extension
|
@@ -132,7 +165,7 @@ module Sass
|
|
132
165
|
private
|
133
166
|
|
134
167
|
def _find(dir, name, options)
|
135
|
-
full_filename, syntax = find_real_file(dir, name)
|
168
|
+
full_filename, syntax = Sass::Util.destructure(find_real_file(dir, name, options))
|
136
169
|
return unless full_filename && File.readable?(full_filename)
|
137
170
|
|
138
171
|
options[:syntax] = syntax
|
@@ -36,14 +36,14 @@ module Sass
|
|
36
36
|
end
|
37
37
|
|
38
38
|
def define_logger(name, options = {})
|
39
|
-
class_eval
|
39
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
40
40
|
def #{name}(message)
|
41
41
|
#{options.fetch(:to, :log)}(#{name.inspect}, message)
|
42
42
|
end
|
43
|
-
|
43
|
+
RUBY
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
47
|
end
|
48
48
|
end
|
49
|
-
end
|
49
|
+
end
|
data/lib/sass/plugin/compiler.rb
CHANGED
@@ -300,7 +300,7 @@ module Sass::Plugin
|
|
300
300
|
|
301
301
|
# The native windows listener is much slower than the polling
|
302
302
|
# option, according to https://github.com/nex3/sass/commit/a3031856b22bc834a5417dedecb038b7be9b9e3e#commitcomment-1295118
|
303
|
-
listener.force_polling(true) if Sass::Util.windows?
|
303
|
+
listener.force_polling(true) if @options[:poll] || Sass::Util.windows?
|
304
304
|
|
305
305
|
begin
|
306
306
|
listener.start
|
@@ -140,7 +140,7 @@ module Sass
|
|
140
140
|
end
|
141
141
|
|
142
142
|
def dependencies(uri, importer)
|
143
|
-
stored_mtime, dependencies = @dependencies[[uri, importer]]
|
143
|
+
stored_mtime, dependencies = Sass::Util.destructure(@dependencies[[uri, importer]])
|
144
144
|
|
145
145
|
if !stored_mtime || stored_mtime < mtime(uri, importer)
|
146
146
|
dependencies = compute_dependencies(uri, importer)
|
@@ -90,13 +90,13 @@ module Sass::Script
|
|
90
90
|
#
|
91
91
|
# ## Other Color Functions
|
92
92
|
#
|
93
|
-
# \{#adjust_color adjust-color($color, \[$red\], \[$green\], \[$blue\], \[$hue\], \[$saturation\], \[$lightness\], \[$alpha\]}
|
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\], \[$saturation\], \[$lightness\], \[$alpha\])}
|
97
97
|
# : Fluidly scale one or more components of a color.
|
98
98
|
#
|
99
|
-
# \{#change_color change-color($color, \[$red\], \[$green\], \[$blue\], \[$hue\], \[$saturation\], \[$lightness\], \[$alpha\]}
|
99
|
+
# \{#change_color change-color($color, \[$red\], \[$green\], \[$blue\], \[$hue\], \[$saturation\], \[$lightness\], \[$alpha\])}
|
100
100
|
# : Changes one or more properties of a color.
|
101
101
|
#
|
102
102
|
# \{#ie_hex_str ie-hex-str($color)}
|
@@ -1235,8 +1235,8 @@ module Sass::Script
|
|
1235
1235
|
# arguments.
|
1236
1236
|
#
|
1237
1237
|
# @example
|
1238
|
-
# max(1px, 4px) =>
|
1239
|
-
# max(5em, 3em, 4em) =>
|
1238
|
+
# max(1px, 4px) => 4px
|
1239
|
+
# max(5em, 3em, 4em) => 5em
|
1240
1240
|
# @return [Number] The maximum value
|
1241
1241
|
# @raise [ArgumentError] if any argument isn't a number, or if not all of
|
1242
1242
|
# the arguments have comparable units
|
data/lib/sass/script/parser.rb
CHANGED
@@ -203,7 +203,7 @@ module Sass
|
|
203
203
|
# sub is the name of the production beneath it,
|
204
204
|
# and ops is a list of operators for this precedence level
|
205
205
|
def production(name, sub, *ops)
|
206
|
-
class_eval <<RUBY
|
206
|
+
class_eval <<RUBY, __FILE__, __LINE__ + 1
|
207
207
|
def #{name}
|
208
208
|
interp = try_ops_after_interp(#{ops.inspect}, #{name.inspect}) and return interp
|
209
209
|
return unless e = #{sub}
|
@@ -223,7 +223,7 @@ RUBY
|
|
223
223
|
end
|
224
224
|
|
225
225
|
def unary(op, sub)
|
226
|
-
class_eval <<RUBY
|
226
|
+
class_eval <<RUBY, __FILE__, __LINE__ + 1
|
227
227
|
def unary_#{op}
|
228
228
|
return #{sub} unless tok = try_tok(:#{op})
|
229
229
|
interp = try_op_before_interp(tok) and return interp
|
data/lib/sass/scss/parser.rb
CHANGED
@@ -307,6 +307,7 @@ module Sass
|
|
307
307
|
end
|
308
308
|
|
309
309
|
def import_arg
|
310
|
+
line = @line
|
310
311
|
return unless (str = tok(STRING)) || (uri = tok?(/url\(/i))
|
311
312
|
if uri
|
312
313
|
str = sass_script(:parse_string)
|
@@ -319,17 +320,19 @@ module Sass
|
|
319
320
|
ss
|
320
321
|
|
321
322
|
media = media_query_list
|
322
|
-
if path =~ /^
|
323
|
-
|
323
|
+
if path =~ /^(https?:)?\/\// || media || use_css_import?
|
324
|
+
node = Sass::Tree::CssImportNode.new(str, media.to_a)
|
325
|
+
else
|
326
|
+
node = Sass::Tree::ImportNode.new(path.strip)
|
324
327
|
end
|
325
|
-
|
326
|
-
node
|
328
|
+
node.line = line
|
329
|
+
node
|
327
330
|
end
|
328
331
|
|
329
332
|
def use_css_import?; false; end
|
330
333
|
|
331
334
|
def media_directive
|
332
|
-
block(node(Sass::Tree::MediaNode.new(media_query_list.to_a)), :directive)
|
335
|
+
block(node(Sass::Tree::MediaNode.new(expr!(:media_query_list).to_a)), :directive)
|
333
336
|
end
|
334
337
|
|
335
338
|
# http://www.w3.org/TR/css3-mediaqueries/#syntax
|
@@ -674,7 +677,7 @@ module Sass
|
|
674
677
|
expected('"{"') if res.length == 1 && res[0].is_a?(Selector::Universal)
|
675
678
|
throw_error {expected('"{"')}
|
676
679
|
rescue Sass::SyntaxError => e
|
677
|
-
e.message << "\n\n\"#{sel}\" may only be used at the beginning of a selector."
|
680
|
+
e.message << "\n\n\"#{sel}\" may only be used at the beginning of a compound selector."
|
678
681
|
raise e
|
679
682
|
end
|
680
683
|
end
|
@@ -706,7 +709,7 @@ module Sass
|
|
706
709
|
end
|
707
710
|
|
708
711
|
def element_name
|
709
|
-
ns, name = qualified_name(:allow_star_name)
|
712
|
+
ns, name = Sass::Util.destructure(qualified_name(:allow_star_name))
|
710
713
|
return unless ns || name
|
711
714
|
|
712
715
|
if name == '*'
|
@@ -797,7 +800,7 @@ module Sass
|
|
797
800
|
# could start a pseudo expression like "n+1", or it could start a
|
798
801
|
# selector like "n|m". In order to handle this, we must regrettably
|
799
802
|
# backtrack.
|
800
|
-
expr, sel = nil
|
803
|
+
expr, sel = nil, nil
|
801
804
|
pseudo_err = catch_error do
|
802
805
|
expr = pseudo_expr
|
803
806
|
next if tok?(/[,)]/)
|
@@ -1021,6 +1024,7 @@ MESSAGE
|
|
1021
1024
|
|
1022
1025
|
EXPR_NAMES = {
|
1023
1026
|
:media_query => "media query (e.g. print, screen, print and screen)",
|
1027
|
+
:media_query_list => "media query (e.g. print, screen, print and screen)",
|
1024
1028
|
:media_expr => "media expression (e.g. (min-device-width: 800px))",
|
1025
1029
|
:pseudo_arg => "expression (e.g. fr, 2n+1)",
|
1026
1030
|
:interp_ident => "identifier",
|
@@ -9,6 +9,9 @@ module Sass
|
|
9
9
|
# @return [String]
|
10
10
|
attr_reader :imported_filename
|
11
11
|
|
12
|
+
# Sets the imported file.
|
13
|
+
attr_writer :imported_file
|
14
|
+
|
12
15
|
# @param imported_filename [String] The name of the imported file
|
13
16
|
def initialize(imported_filename)
|
14
17
|
@imported_filename = imported_filename
|
@@ -43,12 +46,12 @@ module Sass
|
|
43
46
|
|
44
47
|
if @options[:importer]
|
45
48
|
f = @options[:importer].find_relative(
|
46
|
-
@imported_filename, @options[:filename],
|
49
|
+
@imported_filename, @options[:filename], options_for_importer)
|
47
50
|
return f if f
|
48
51
|
end
|
49
52
|
|
50
53
|
paths.each do |p|
|
51
|
-
if f = p.find(@imported_filename,
|
54
|
+
if f = p.find(@imported_filename, options_for_importer)
|
52
55
|
return f
|
53
56
|
end
|
54
57
|
end
|
@@ -63,6 +66,10 @@ module Sass
|
|
63
66
|
rescue SyntaxError => e
|
64
67
|
raise SyntaxError.new(e.message, :line => self.line, :filename => @filename)
|
65
68
|
end
|
69
|
+
|
70
|
+
def options_for_importer
|
71
|
+
@options.merge(:_line => line)
|
72
|
+
end
|
66
73
|
end
|
67
74
|
end
|
68
75
|
end
|
@@ -218,15 +218,17 @@ class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
|
|
218
218
|
file = node.imported_file
|
219
219
|
handle_import_loop!(node) if @stack.any? {|e| e[:filename] == file.options[:filename]}
|
220
220
|
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
221
|
+
begin
|
222
|
+
@stack.push(:filename => node.filename, :line => node.line)
|
223
|
+
root = file.to_tree
|
224
|
+
Sass::Tree::Visitors::CheckNesting.visit(root)
|
225
|
+
node.children = root.children.map {|c| visit(c)}.flatten
|
226
|
+
node
|
227
|
+
rescue Sass::SyntaxError => e
|
228
|
+
e.modify_backtrace(:filename => node.imported_file.options[:filename])
|
229
|
+
e.add_backtrace(:filename => node.filename, :line => node.line)
|
230
|
+
raise e
|
231
|
+
end
|
230
232
|
ensure
|
231
233
|
@stack.pop unless path
|
232
234
|
end
|
@@ -50,6 +50,14 @@ class Sass::Tree::Visitors::SetOptions < Sass::Tree::Visitors::Base
|
|
50
50
|
yield
|
51
51
|
end
|
52
52
|
|
53
|
+
def visit_import(node)
|
54
|
+
# We have no good way of propagating the new options through an Engine
|
55
|
+
# instance, so we just null it out. This also lets us avoid caching an
|
56
|
+
# imported Engine along with the importing source tree.
|
57
|
+
node.imported_file = nil
|
58
|
+
yield
|
59
|
+
end
|
60
|
+
|
53
61
|
def visit_mixindef(node)
|
54
62
|
node.args.each do |k, v|
|
55
63
|
k.options = @options
|
data/lib/sass/util.rb
CHANGED
@@ -467,6 +467,19 @@ module Sass
|
|
467
467
|
Dir.glob(path, &block)
|
468
468
|
end
|
469
469
|
|
470
|
+
# Prepare a value for a destructuring assignment (e.g. `a, b =
|
471
|
+
# val`). This works around a performance bug when using
|
472
|
+
# ActiveSupport, and only needs to be called when `val` is likely
|
473
|
+
# to be `nil` reasonably often.
|
474
|
+
#
|
475
|
+
# See [this bug report](http://redmine.ruby-lang.org/issues/4917).
|
476
|
+
#
|
477
|
+
# @param val [Object]
|
478
|
+
# @return [Object]
|
479
|
+
def destructure(val)
|
480
|
+
val || []
|
481
|
+
end
|
482
|
+
|
470
483
|
## Cross-Ruby-Version Compatibility
|
471
484
|
|
472
485
|
# Whether or not this is running under Ruby 1.8 or lower.
|
data/test/sass/engine_test.rb
CHANGED
@@ -145,8 +145,8 @@ MSG
|
|
145
145
|
"$var: true\n@while $var\n @extend .bar\n $var: false" => ["Extend directives may only be used within rules.", 3],
|
146
146
|
"@for $i from 0 to 1\n @extend .bar" => ["Extend directives may only be used within rules.", 2],
|
147
147
|
"@mixin foo\n @extend .bar\n@include foo" => ["Extend directives may only be used within rules.", 2],
|
148
|
-
"foo\n &a\n b: c" => ["Invalid CSS after \"&\": expected \"{\", was \"a\"\n\n\"a\" may only be used at the beginning of a selector.", 2],
|
149
|
-
"foo\n &1\n b: c" => ["Invalid CSS after \"&\": expected \"{\", was \"1\"\n\n\"1\" may only be used at the beginning of a selector.", 2],
|
148
|
+
"foo\n &a\n b: c" => ["Invalid CSS after \"&\": expected \"{\", was \"a\"\n\n\"a\" may only be used at the beginning of a compound selector.", 2],
|
149
|
+
"foo\n &1\n b: c" => ["Invalid CSS after \"&\": expected \"{\", was \"1\"\n\n\"1\" may only be used at the beginning of a compound selector.", 2],
|
150
150
|
"foo %\n a: b" => ['Invalid CSS after "foo %": expected placeholder name, was ""', 1],
|
151
151
|
"=foo\n @content error" => "Invalid content directive. Trailing characters found: \"error\".",
|
152
152
|
"=foo\n @content\n b: c" => "Illegal nesting: Nothing may be nested beneath @content directives.",
|
@@ -217,7 +217,47 @@ MSG
|
|
217
217
|
assert_equal("p {\n a: b; }\n p q {\n c: d; }\n",
|
218
218
|
render("p\n\ta: b\n\tq\n\t\tc: d\n"))
|
219
219
|
end
|
220
|
-
|
220
|
+
|
221
|
+
def test_import_same_name_different_ext
|
222
|
+
assert_warning <<WARNING do
|
223
|
+
WARNING: On line 1 of test_import_same_name_different_ext_inline.sass:
|
224
|
+
It's not clear which file to import for '@import "same_name_different_ext"'.
|
225
|
+
Candidates:
|
226
|
+
same_name_different_ext.sass
|
227
|
+
same_name_different_ext.scss
|
228
|
+
For now I'll choose same_name_different_ext.sass.
|
229
|
+
This will be an error in future versions of Sass.
|
230
|
+
WARNING
|
231
|
+
options = {:load_paths => [File.dirname(__FILE__) + '/templates/']}
|
232
|
+
munge_filename options
|
233
|
+
result = Sass::Engine.new("@import 'same_name_different_ext'", options).render
|
234
|
+
assert_equal(<<CSS, result)
|
235
|
+
.foo {
|
236
|
+
ext: sass; }
|
237
|
+
CSS
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
def test_import_same_name_different_partiality
|
242
|
+
assert_warning <<WARNING do
|
243
|
+
WARNING: On line 1 of test_import_same_name_different_partiality_inline.sass:
|
244
|
+
It's not clear which file to import for '@import "same_name_different_partiality"'.
|
245
|
+
Candidates:
|
246
|
+
_same_name_different_partiality.scss
|
247
|
+
same_name_different_partiality.scss
|
248
|
+
For now I'll choose _same_name_different_partiality.scss.
|
249
|
+
This will be an error in future versions of Sass.
|
250
|
+
WARNING
|
251
|
+
options = {:load_paths => [File.dirname(__FILE__) + '/templates/']}
|
252
|
+
munge_filename options
|
253
|
+
result = Sass::Engine.new("@import 'same_name_different_partiality'", options).render
|
254
|
+
assert_equal(<<CSS, result)
|
255
|
+
.foo {
|
256
|
+
partial: yes; }
|
257
|
+
CSS
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
221
261
|
EXCEPTION_MAP.each do |key, value|
|
222
262
|
define_method("test_exception (#{key.inspect})") do
|
223
263
|
line = 10
|
@@ -625,6 +665,11 @@ CSS
|
|
625
665
|
render("@import \"http://fonts.googleapis.com/css?family=Droid+Sans\""))
|
626
666
|
end
|
627
667
|
|
668
|
+
def test_protocol_relative_import
|
669
|
+
assert_equal("@import url(//fonts.googleapis.com/css?family=Droid+Sans);\n",
|
670
|
+
render("@import \"//fonts.googleapis.com/css?family=Droid+Sans\""))
|
671
|
+
end
|
672
|
+
|
628
673
|
def test_import_with_interpolation
|
629
674
|
assert_equal(<<CSS, render(<<SASS))
|
630
675
|
@import url("http://fonts.googleapis.com/css?family=Droid+Sans");
|
data/test/sass/plugin_test.rb
CHANGED
@@ -9,6 +9,12 @@ module Sass::Script::Functions
|
|
9
9
|
filename = options[:filename].gsub(%r{.*((/[^/]+){4})}, '\1')
|
10
10
|
Sass::Script::String.new(filename)
|
11
11
|
end
|
12
|
+
|
13
|
+
def whatever
|
14
|
+
custom = options[:custom]
|
15
|
+
whatever = custom && custom[:whatever]
|
16
|
+
Sass::Script::String.new(whatever || "incorrect")
|
17
|
+
end
|
12
18
|
end
|
13
19
|
|
14
20
|
class SassPluginTest < Test::Unit::TestCase
|
@@ -123,7 +129,7 @@ CSS
|
|
123
129
|
File.open(tempfile_loc('single_import_loop')) do |file|
|
124
130
|
assert_equal(<<CSS.strip, file.read.split("\n")[0...2].join("\n"))
|
125
131
|
/*
|
126
|
-
|
132
|
+
Syntax error: An @import loop has been found: #{template_loc('single_import_loop')} imports itself
|
127
133
|
CSS
|
128
134
|
end
|
129
135
|
end
|
@@ -134,9 +140,9 @@ CSS
|
|
134
140
|
File.open(tempfile_loc('double_import_loop1')) do |file|
|
135
141
|
assert_equal(<<CSS.strip, file.read.split("\n")[0...4].join("\n"))
|
136
142
|
/*
|
137
|
-
|
138
|
-
|
139
|
-
|
143
|
+
Syntax error: An @import loop has been found:
|
144
|
+
#{template_loc('double_import_loop1')} imports #{template_loc('_double_import_loop2')}
|
145
|
+
#{template_loc('_double_import_loop2')} imports #{template_loc('double_import_loop1')}
|
140
146
|
CSS
|
141
147
|
end
|
142
148
|
end
|
@@ -210,6 +216,19 @@ CSS
|
|
210
216
|
assert_needs_update "basic"
|
211
217
|
end
|
212
218
|
|
219
|
+
def test_import_same_name
|
220
|
+
assert_warning <<WARNING do
|
221
|
+
WARNING: In #{template_loc}:
|
222
|
+
There are multiple files that match the name "same_name_different_partiality.scss":
|
223
|
+
_same_name_different_partiality.scss
|
224
|
+
same_name_different_partiality.scss
|
225
|
+
This will be an error in future versions of Sass.
|
226
|
+
WARNING
|
227
|
+
touch "_same_name_different_partiality"
|
228
|
+
assert_needs_update "same_name_different_partiality"
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
213
232
|
# Callbacks
|
214
233
|
|
215
234
|
def test_updating_stylesheets_callback
|
@@ -333,7 +352,24 @@ CSS
|
|
333
352
|
check_for_updates!
|
334
353
|
assert_renders_correctly 'if'
|
335
354
|
ensure
|
336
|
-
set_plugin_opts
|
355
|
+
set_plugin_opts
|
356
|
+
end
|
357
|
+
|
358
|
+
def test_cached_import_option
|
359
|
+
set_plugin_opts :custom => {:whatever => "correct"}
|
360
|
+
check_for_updates!
|
361
|
+
assert_renders_correctly "cached_import_option"
|
362
|
+
|
363
|
+
@@cache_store.reset!
|
364
|
+
set_plugin_opts :custom => nil, :always_update => false
|
365
|
+
check_for_updates!
|
366
|
+
assert_renders_correctly "cached_import_option"
|
367
|
+
|
368
|
+
set_plugin_opts :custom => {:whatever => "correct"}, :always_update => true
|
369
|
+
check_for_updates!
|
370
|
+
assert_renders_correctly "cached_import_option"
|
371
|
+
ensure
|
372
|
+
set_plugin_opts :custom => nil
|
337
373
|
end
|
338
374
|
|
339
375
|
private
|
@@ -388,7 +424,7 @@ CSS
|
|
388
424
|
end
|
389
425
|
|
390
426
|
if block_given?
|
391
|
-
yield
|
427
|
+
Sass::Util.silence_sass_warnings {yield}
|
392
428
|
else
|
393
429
|
check_for_updates!
|
394
430
|
end
|
data/test/sass/scss/css_test.rb
CHANGED
@@ -1042,6 +1042,18 @@ body {
|
|
1042
1042
|
SCSS
|
1043
1043
|
end
|
1044
1044
|
|
1045
|
+
def test_malformed_media
|
1046
|
+
render <<SCSS
|
1047
|
+
@media {
|
1048
|
+
margin: 0;
|
1049
|
+
}
|
1050
|
+
SCSS
|
1051
|
+
assert(false, "Expected syntax error")
|
1052
|
+
rescue Sass::SyntaxError => e
|
1053
|
+
assert_equal 'Invalid CSS after "@media ": expected media query (e.g. print, screen, print and screen), was "{"', e.message
|
1054
|
+
assert_equal 1, e.sass_line
|
1055
|
+
end
|
1056
|
+
|
1045
1057
|
private
|
1046
1058
|
|
1047
1059
|
def assert_selector_parses(selector)
|
data/test/sass/scss/scss_test.rb
CHANGED
@@ -290,6 +290,11 @@ SCSS
|
|
290
290
|
render("@import \"http://fonts.googleapis.com/css?family=Droid+Sans\";"))
|
291
291
|
end
|
292
292
|
|
293
|
+
def test_protocol_relative_import
|
294
|
+
assert_equal("@import \"//fonts.googleapis.com/css?family=Droid+Sans\";\n",
|
295
|
+
render("@import \"//fonts.googleapis.com/css?family=Droid+Sans\";"))
|
296
|
+
end
|
297
|
+
|
293
298
|
def test_import_with_interpolation
|
294
299
|
assert_equal <<CSS, render(<<SCSS)
|
295
300
|
@import url("http://fonts.googleapis.com/css?family=Droid+Sans");
|
@@ -1664,7 +1669,7 @@ SCSS
|
|
1664
1669
|
assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render <<SCSS}
|
1665
1670
|
Invalid CSS after " .foo": expected "{", was "&.bar {a: b}"
|
1666
1671
|
|
1667
|
-
"&.bar" may only be used at the beginning of a selector.
|
1672
|
+
"&.bar" may only be used at the beginning of a compound selector.
|
1668
1673
|
MESSAGE
|
1669
1674
|
flim {
|
1670
1675
|
.foo&.bar {a: b}
|
@@ -1676,7 +1681,7 @@ SCSS
|
|
1676
1681
|
assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render <<SCSS}
|
1677
1682
|
Invalid CSS after " .foo.bar": expected "{", was "& {a: b}"
|
1678
1683
|
|
1679
|
-
"&" may only be used at the beginning of a selector.
|
1684
|
+
"&" may only be used at the beginning of a compound selector.
|
1680
1685
|
MESSAGE
|
1681
1686
|
flim {
|
1682
1687
|
.foo.bar& {a: b}
|
@@ -1688,7 +1693,7 @@ SCSS
|
|
1688
1693
|
assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render <<SCSS}
|
1689
1694
|
Invalid CSS after " &": expected "{", was "& {a: b}"
|
1690
1695
|
|
1691
|
-
"&" may only be used at the beginning of a selector.
|
1696
|
+
"&" may only be used at the beginning of a compound selector.
|
1692
1697
|
MESSAGE
|
1693
1698
|
flim {
|
1694
1699
|
&& {a: b}
|
@@ -0,0 +1 @@
|
|
1
|
+
partial {value: whatever()}
|
@@ -0,0 +1 @@
|
|
1
|
+
.foo {partial: yes}
|
@@ -0,0 +1 @@
|
|
1
|
+
.foo {ext: scss}
|
@@ -0,0 +1 @@
|
|
1
|
+
.foo {partial: no}
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sass
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.2.
|
4
|
+
version: 3.2.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2012-
|
14
|
+
date: 2012-11-03 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: yard
|
@@ -224,11 +224,13 @@ files:
|
|
224
224
|
- test/sass/templates/filename_fn.scss
|
225
225
|
- test/sass/templates/alt.sass
|
226
226
|
- test/sass/templates/nested_bork1.sass
|
227
|
+
- test/sass/templates/same_name_different_partiality.scss
|
227
228
|
- test/sass/templates/complex.sass
|
228
229
|
- test/sass/templates/units.sass
|
229
230
|
- test/sass/templates/nested_import.sass
|
230
231
|
- test/sass/templates/importee.sass
|
231
232
|
- test/sass/templates/importee.less
|
233
|
+
- test/sass/templates/_cached_import_option_partial.scss
|
232
234
|
- test/sass/templates/scss_importee.scss
|
233
235
|
- test/sass/templates/line_numbers.sass
|
234
236
|
- test/sass/templates/expanded.sass
|
@@ -242,6 +244,7 @@ files:
|
|
242
244
|
- test/sass/templates/nested.sass
|
243
245
|
- test/sass/templates/compact.sass
|
244
246
|
- test/sass/templates/single_import_loop.sass
|
247
|
+
- test/sass/templates/_same_name_different_partiality.scss
|
245
248
|
- test/sass/templates/multiline.sass
|
246
249
|
- test/sass/templates/_imported_charset_ibm866.sass
|
247
250
|
- test/sass/templates/double_import_loop1.sass
|
@@ -251,15 +254,18 @@ files:
|
|
251
254
|
- test/sass/templates/import.sass
|
252
255
|
- test/sass/templates/nested_bork3.sass
|
253
256
|
- test/sass/templates/script.sass
|
257
|
+
- test/sass/templates/same_name_different_ext.scss
|
254
258
|
- test/sass/templates/bork4.sass
|
255
259
|
- test/sass/templates/if.sass
|
256
260
|
- test/sass/templates/_partial.sass
|
257
261
|
- test/sass/templates/nested_mixin_bork.sass
|
258
262
|
- test/sass/templates/import_charset_1_8.sass
|
263
|
+
- test/sass/templates/same_name_different_ext.sass
|
259
264
|
- test/sass/templates/nested_bork2.sass
|
260
265
|
- test/sass/templates/mixin_bork.sass
|
261
266
|
- test/sass/templates/compressed.sass
|
262
267
|
- test/sass/templates/nested_bork4.sass
|
268
|
+
- test/sass/templates/cached_import_option.scss
|
263
269
|
- test/sass/templates/_imported_charset_utf8.sass
|
264
270
|
- test/sass/conversion_test.rb
|
265
271
|
- test/sass/script_test.rb
|
@@ -288,6 +294,7 @@ files:
|
|
288
294
|
- test/sass/results/parent_ref.css
|
289
295
|
- test/sass/results/script.css
|
290
296
|
- test/sass/results/complex.css
|
297
|
+
- test/sass/results/cached_import_option.css
|
291
298
|
- test/sass/results/import_charset.css
|
292
299
|
- test/sass/results/alt.css
|
293
300
|
- test/sass/results/if.css
|