sass 3.2.1 → 3.2.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|