haml 3.1.3 → 3.1.4
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of haml might be problematic. Click here for more details.
- data/Rakefile +42 -17
- data/VERSION +1 -1
- data/lib/haml/compiler.rb +3 -3
- data/lib/haml/helpers/action_view_mods.rb +4 -3
- data/lib/haml/template.rb +3 -1
- data/test/gemfiles/Gemfile.rails-2.0.x +8 -0
- data/test/gemfiles/Gemfile.rails-2.0.x.lock +38 -0
- data/test/gemfiles/Gemfile.rails-2.1.x +8 -0
- data/test/gemfiles/Gemfile.rails-2.1.x.lock +38 -0
- data/test/gemfiles/Gemfile.rails-2.2.x +8 -0
- data/test/gemfiles/Gemfile.rails-2.2.x.lock +38 -0
- data/test/gemfiles/Gemfile.rails-2.3.x +8 -0
- data/test/gemfiles/Gemfile.rails-2.3.x.lock +40 -0
- data/test/gemfiles/Gemfile.rails-3.0.x +8 -0
- data/test/gemfiles/Gemfile.rails-3.0.x.lock +85 -0
- data/test/gemfiles/Gemfile.rails-3.1.x +8 -0
- data/test/gemfiles/Gemfile.rails-3.1.x.lock +98 -0
- data/test/gemfiles/Gemfile.rails-xss-2.3.x +9 -0
- data/test/gemfiles/Gemfile.rails-xss-2.3.x.lock +42 -0
- data/test/haml/engine_test.rb +19 -0
- data/test/haml/html2haml_test.rb +1 -1
- data/test/haml/template_test.rb +20 -2
- data/test/haml/templates/partial_layout.haml +4 -1
- data/test/linked_rails.rb +4 -4
- data/vendor/sass/VERSION +1 -1
- data/vendor/sass/doc-src/SASS_CHANGELOG.md +115 -2
- data/vendor/sass/doc-src/SASS_REFERENCE.md +12 -4
- data/vendor/sass/lib/sass.rb +1 -0
- data/vendor/sass/lib/sass/cache_stores/base.rb +3 -1
- data/vendor/sass/lib/sass/cache_stores/filesystem.rb +2 -0
- data/vendor/sass/lib/sass/css.rb +2 -1
- data/vendor/sass/lib/sass/engine.rb +39 -23
- data/vendor/sass/lib/sass/environment.rb +11 -0
- data/vendor/sass/lib/sass/exec.rb +14 -1
- data/vendor/sass/lib/sass/importers/base.rb +2 -1
- data/vendor/sass/lib/sass/importers/filesystem.rb +18 -13
- data/vendor/sass/lib/sass/less.rb +2 -2
- data/vendor/sass/lib/sass/logger.rb +15 -0
- data/vendor/sass/lib/sass/logger/base.rb +32 -0
- data/vendor/sass/lib/sass/logger/log_level.rb +49 -0
- data/vendor/sass/lib/sass/plugin.rb +4 -8
- data/vendor/sass/lib/sass/plugin/compiler.rb +42 -17
- data/vendor/sass/lib/sass/plugin/configuration.rb +0 -2
- data/vendor/sass/lib/sass/railtie.rb +1 -1
- data/vendor/sass/lib/sass/script/funcall.rb +14 -1
- data/vendor/sass/lib/sass/script/functions.rb +44 -1
- data/vendor/sass/lib/sass/script/interpolation.rb +9 -0
- data/vendor/sass/lib/sass/script/lexer.rb +6 -1
- data/vendor/sass/lib/sass/script/list.rb +7 -0
- data/vendor/sass/lib/sass/script/literal.rb +5 -0
- data/vendor/sass/lib/sass/script/node.rb +8 -0
- data/vendor/sass/lib/sass/script/number.rb +28 -5
- data/vendor/sass/lib/sass/script/operation.rb +8 -0
- data/vendor/sass/lib/sass/script/parser.rb +12 -5
- data/vendor/sass/lib/sass/script/string_interpolation.rb +9 -0
- data/vendor/sass/lib/sass/script/unary_operation.rb +7 -0
- data/vendor/sass/lib/sass/script/variable.rb +5 -0
- data/vendor/sass/lib/sass/scss/parser.rb +78 -38
- data/vendor/sass/lib/sass/scss/rx.rb +2 -1
- data/vendor/sass/lib/sass/scss/static_parser.rb +2 -2
- data/vendor/sass/lib/sass/shared.rb +1 -1
- data/vendor/sass/lib/sass/tree/comment_node.rb +24 -11
- data/vendor/sass/lib/sass/tree/debug_node.rb +1 -1
- data/vendor/sass/lib/sass/tree/each_node.rb +1 -1
- data/vendor/sass/lib/sass/tree/extend_node.rb +1 -1
- data/vendor/sass/lib/sass/tree/for_node.rb +2 -2
- data/vendor/sass/lib/sass/tree/function_node.rb +1 -1
- data/vendor/sass/lib/sass/tree/if_node.rb +1 -14
- data/vendor/sass/lib/sass/tree/mixin_def_node.rb +1 -1
- data/vendor/sass/lib/sass/tree/mixin_node.rb +2 -2
- data/vendor/sass/lib/sass/tree/node.rb +2 -5
- data/vendor/sass/lib/sass/tree/prop_node.rb +2 -9
- data/vendor/sass/lib/sass/tree/return_node.rb +1 -1
- data/vendor/sass/lib/sass/tree/rule_node.rb +9 -2
- data/vendor/sass/lib/sass/tree/variable_node.rb +1 -1
- data/vendor/sass/lib/sass/tree/visitors/check_nesting.rb +17 -18
- data/vendor/sass/lib/sass/tree/visitors/convert.rb +10 -5
- data/vendor/sass/lib/sass/tree/visitors/deep_copy.rb +87 -0
- data/vendor/sass/lib/sass/tree/visitors/perform.rb +50 -19
- data/vendor/sass/lib/sass/tree/visitors/set_options.rb +97 -0
- data/vendor/sass/lib/sass/tree/visitors/to_css.rb +9 -15
- data/vendor/sass/lib/sass/tree/warn_node.rb +1 -1
- data/vendor/sass/lib/sass/tree/while_node.rb +1 -1
- data/vendor/sass/lib/sass/util.rb +58 -6
- data/vendor/sass/sass.gemspec +2 -1
- data/vendor/sass/test/Gemfile +4 -0
- data/vendor/sass/test/Gemfile.lock +19 -0
- data/vendor/sass/test/sass/cache_test.rb +15 -0
- data/vendor/sass/test/sass/conversion_test.rb +2 -6
- data/vendor/sass/test/sass/css2sass_test.rb +9 -0
- data/vendor/sass/test/sass/engine_test.rb +124 -26
- data/vendor/sass/test/sass/fixtures/test_staleness_check_across_importers.css +1 -0
- data/vendor/sass/test/sass/fixtures/test_staleness_check_across_importers.scss +1 -0
- data/vendor/sass/test/sass/functions_test.rb +13 -0
- data/vendor/sass/test/sass/importer_test.rb +110 -0
- data/vendor/sass/test/sass/logger_test.rb +58 -0
- data/vendor/sass/test/sass/plugin_test.rb +16 -13
- data/vendor/sass/test/sass/script_conversion_test.rb +2 -0
- data/vendor/sass/test/sass/script_test.rb +18 -0
- data/vendor/sass/test/sass/scss/css_test.rb +7 -1
- data/vendor/sass/test/sass/scss/scss_test.rb +37 -13
- data/vendor/sass/test/sass/templates/bork5.sass +3 -0
- data/vendor/sass/test/sass/templates/nested_bork5.sass +2 -0
- data/vendor/sass/test/sass/test_helper.rb +1 -1
- data/vendor/sass/test/sass/util_test.rb +12 -0
- data/vendor/sass/vendor/fssm/Gemfile +3 -0
- data/vendor/sass/vendor/fssm/LICENSE +1 -1
- data/vendor/sass/vendor/fssm/README.markdown +55 -27
- data/vendor/sass/vendor/fssm/Rakefile +6 -54
- data/vendor/sass/vendor/fssm/example.rb +6 -3
- data/vendor/sass/vendor/fssm/fssm.gemspec +17 -70
- data/vendor/sass/vendor/fssm/lib/fssm.rb +7 -3
- data/vendor/sass/vendor/fssm/lib/fssm/backends/fsevents.rb +1 -1
- data/vendor/sass/vendor/fssm/lib/fssm/backends/inotify.rb +2 -2
- data/vendor/sass/vendor/fssm/lib/fssm/backends/polling.rb +2 -2
- data/vendor/sass/vendor/fssm/lib/fssm/backends/rbfsevent.rb +42 -0
- data/vendor/sass/vendor/fssm/lib/fssm/backends/rubycocoa/fsevents.rb +10 -10
- data/vendor/sass/vendor/fssm/lib/fssm/monitor.rb +19 -9
- data/vendor/sass/vendor/fssm/lib/fssm/path.rb +24 -21
- data/vendor/sass/vendor/fssm/lib/fssm/pathname.rb +13 -479
- data/vendor/sass/vendor/fssm/lib/fssm/state/directory.rb +29 -11
- data/vendor/sass/vendor/fssm/lib/fssm/state/file.rb +1 -1
- data/vendor/sass/vendor/fssm/lib/fssm/support.rb +41 -12
- data/vendor/sass/vendor/fssm/lib/fssm/tree.rb +6 -6
- data/vendor/sass/vendor/fssm/lib/fssm/version.rb +3 -0
- data/vendor/sass/vendor/fssm/profile/prof-cache.rb +3 -3
- data/vendor/sass/vendor/fssm/profile/prof-pathname-rubinius.rb +35 -0
- data/vendor/sass/vendor/fssm/profile/prof-pathname.rb +7 -7
- data/vendor/sass/vendor/fssm/spec/count_down_latch.rb +151 -0
- data/vendor/sass/vendor/fssm/spec/monitor_spec.rb +202 -0
- data/vendor/sass/vendor/fssm/spec/path_spec.rb +36 -15
- data/vendor/sass/vendor/fssm/spec/spec_helper.rb +6 -6
- metadata +36 -5
- data/vendor/sass/vendor/fssm/VERSION.yml +0 -5
@@ -49,6 +49,8 @@ module Sass
|
|
49
49
|
# @param obj [Object] The object to cache.
|
50
50
|
def store(key, sha, root)
|
51
51
|
_store(key, Sass::VERSION, sha, Marshal.dump(root))
|
52
|
+
rescue TypeError, LoadError => e
|
53
|
+
Sass::Util.sass_warn "Warning. Error encountered while saving cache #{path_to(key)}: #{e}"
|
52
54
|
end
|
53
55
|
|
54
56
|
# Retrieve a {Sass::Tree::RootNode}.
|
@@ -59,7 +61,7 @@ module Sass
|
|
59
61
|
def retrieve(key, sha)
|
60
62
|
contents = _retrieve(key, Sass::VERSION, sha)
|
61
63
|
Marshal.load(contents) if contents
|
62
|
-
rescue EOFError, TypeError, ArgumentError => e
|
64
|
+
rescue EOFError, TypeError, ArgumentError, LoadError => e
|
63
65
|
Sass::Util.sass_warn "Warning. Error encountered while reading cache #{path_to(key)}: #{e}"
|
64
66
|
end
|
65
67
|
|
data/vendor/sass/lib/sass/css.rb
CHANGED
@@ -75,7 +75,7 @@ module Sass
|
|
75
75
|
#
|
76
76
|
# @return [Tree::Node] The root node of the parsed tree
|
77
77
|
def build_tree
|
78
|
-
root = Sass::SCSS::CssParser.new(@template).parse
|
78
|
+
root = Sass::SCSS::CssParser.new(@template, @options[:filename]).parse
|
79
79
|
expand_commas root
|
80
80
|
parent_ref_rules root
|
81
81
|
remove_parent_refs root
|
@@ -106,6 +106,7 @@ module Sass
|
|
106
106
|
next child
|
107
107
|
end
|
108
108
|
child.rule.first.split(',').map do |rule|
|
109
|
+
next if rule.strip.empty?
|
109
110
|
node = Tree::RuleNode.new([rule.strip])
|
110
111
|
node.children = child.children
|
111
112
|
node
|
@@ -28,6 +28,8 @@ require 'sass/tree/visitors/perform'
|
|
28
28
|
require 'sass/tree/visitors/cssize'
|
29
29
|
require 'sass/tree/visitors/convert'
|
30
30
|
require 'sass/tree/visitors/to_css'
|
31
|
+
require 'sass/tree/visitors/deep_copy'
|
32
|
+
require 'sass/tree/visitors/set_options'
|
31
33
|
require 'sass/tree/visitors/check_nesting'
|
32
34
|
require 'sass/selector'
|
33
35
|
require 'sass/environment'
|
@@ -88,7 +90,10 @@ module Sass
|
|
88
90
|
#
|
89
91
|
# `children`: `Array<Line>`
|
90
92
|
# : The lines nested below this one.
|
91
|
-
|
93
|
+
#
|
94
|
+
# `comment_tab_str`: `String?`
|
95
|
+
# : The prefix indentation for this comment, if it is a comment.
|
96
|
+
class Line < Struct.new(:text, :tabs, :index, :offset, :filename, :children, :comment_tab_str)
|
92
97
|
def comment?
|
93
98
|
text[0] == COMMENT_CHAR && (text[1] == SASS_COMMENT_CHAR || text[1] == CSS_COMMENT_CHAR)
|
94
99
|
end
|
@@ -105,6 +110,10 @@ module Sass
|
|
105
110
|
# which is not output as a CSS comment.
|
106
111
|
SASS_COMMENT_CHAR = ?/
|
107
112
|
|
113
|
+
# The character that indicates that a comment allows interpolation
|
114
|
+
# and should be preserved even in `:compressed` mode.
|
115
|
+
SASS_LOUD_COMMENT_CHAR = ?!
|
116
|
+
|
108
117
|
# The character that follows the general COMMENT_CHAR and designates a CSS comment,
|
109
118
|
# which is embedded in the CSS document.
|
110
119
|
CSS_COMMENT_CHAR = ?*
|
@@ -307,7 +316,6 @@ module Sass
|
|
307
316
|
sha = Digest::SHA1.hexdigest(@template)
|
308
317
|
|
309
318
|
if root = @options[:cache_store].retrieve(key, sha)
|
310
|
-
@options = root.options.merge(@options)
|
311
319
|
root.options = @options
|
312
320
|
return root
|
313
321
|
end
|
@@ -316,7 +324,7 @@ module Sass
|
|
316
324
|
check_encoding!
|
317
325
|
|
318
326
|
if @options[:syntax] == :scss
|
319
|
-
root = Sass::SCSS::Parser.new(@template).parse
|
327
|
+
root = Sass::SCSS::Parser.new(@template, @options[:filename]).parse
|
320
328
|
else
|
321
329
|
root = Tree::RootNode.new(@template)
|
322
330
|
append_children(root, tree(tabulate(@template)).first, true)
|
@@ -326,7 +334,7 @@ module Sass
|
|
326
334
|
if @options[:cache] && key && sha
|
327
335
|
begin
|
328
336
|
old_options = root.options
|
329
|
-
root.options = {
|
337
|
+
root.options = {}
|
330
338
|
@options[:cache_store].store(key, sha, root)
|
331
339
|
ensure
|
332
340
|
root.options = old_options
|
@@ -419,7 +427,8 @@ but this line was indented by #{Sass::Shared.human_indentation line[/^\s*/]}.
|
|
419
427
|
MSG
|
420
428
|
end
|
421
429
|
|
422
|
-
last.
|
430
|
+
last.comment_tab_str ||= comment_tab_str
|
431
|
+
last.text << "\n" << line
|
423
432
|
true
|
424
433
|
end
|
425
434
|
|
@@ -485,8 +494,8 @@ MSG
|
|
485
494
|
if child.is_a?(Tree::CommentNode) && child.silent
|
486
495
|
if continued_comment &&
|
487
496
|
child.line == continued_comment.line +
|
488
|
-
continued_comment.
|
489
|
-
continued_comment.value
|
497
|
+
continued_comment.lines + 1
|
498
|
+
continued_comment.value += ["\n"] + child.value
|
490
499
|
next
|
491
500
|
end
|
492
501
|
|
@@ -537,7 +546,7 @@ WARNING
|
|
537
546
|
when ?$
|
538
547
|
parse_variable(line)
|
539
548
|
when COMMENT_CHAR
|
540
|
-
parse_comment(line
|
549
|
+
parse_comment(line)
|
541
550
|
when DIRECTIVE_CHAR
|
542
551
|
parse_directive(parent, line, root)
|
543
552
|
when ESCAPE_CHAR
|
@@ -558,7 +567,7 @@ WARNING
|
|
558
567
|
def parse_property_or_rule(line)
|
559
568
|
scanner = StringScanner.new(line.text)
|
560
569
|
hack_char = scanner.scan(/[:\*\.]|\#(?!\{)/)
|
561
|
-
parser = Sass::SCSS::SassParser.new(scanner, @line)
|
570
|
+
parser = Sass::SCSS::SassParser.new(scanner, @options[:filename], @line)
|
562
571
|
|
563
572
|
unless res = parser.parse_interp_ident
|
564
573
|
return Tree::RuleNode.new(parse_interp(line.text))
|
@@ -581,15 +590,9 @@ WARNING
|
|
581
590
|
if value.strip.empty?
|
582
591
|
expr = Sass::Script::String.new("")
|
583
592
|
else
|
584
|
-
important = false
|
585
|
-
if value =~ Sass::SCSS::RX::IMPORTANT
|
586
|
-
important = true
|
587
|
-
value = value.gsub(Sass::SCSS::RX::IMPORTANT,"")
|
588
|
-
end
|
589
593
|
expr = parse_script(value, :offset => line.offset + line.text.index(value))
|
590
|
-
|
591
594
|
end
|
592
|
-
Tree::PropNode.new(parse_interp(name), expr,
|
595
|
+
Tree::PropNode.new(parse_interp(name), expr, prop)
|
593
596
|
end
|
594
597
|
|
595
598
|
def parse_variable(line)
|
@@ -605,11 +608,19 @@ WARNING
|
|
605
608
|
end
|
606
609
|
|
607
610
|
def parse_comment(line)
|
608
|
-
if line[1] == CSS_COMMENT_CHAR || line[1] == SASS_COMMENT_CHAR
|
609
|
-
silent = line[1] == SASS_COMMENT_CHAR
|
610
|
-
|
611
|
-
|
612
|
-
|
611
|
+
if line.text[1] == CSS_COMMENT_CHAR || line.text[1] == SASS_COMMENT_CHAR
|
612
|
+
silent = line.text[1] == SASS_COMMENT_CHAR
|
613
|
+
if loud = line.text[2] == SASS_LOUD_COMMENT_CHAR
|
614
|
+
value = self.class.parse_interp(line.text, line.index, line.offset, :filename => @filename)
|
615
|
+
value[0].slice!(2) # get rid of the "!"
|
616
|
+
else
|
617
|
+
value = [line.text]
|
618
|
+
end
|
619
|
+
value = with_extracted_values(value) do |str|
|
620
|
+
str = str.gsub(/^#{line.comment_tab_str}/m, '')[2..-1] # get rid of // or /*
|
621
|
+
format_comment_text(str, silent)
|
622
|
+
end
|
623
|
+
Tree::CommentNode.new(value, silent, loud)
|
613
624
|
else
|
614
625
|
Tree::RuleNode.new(parse_interp(line))
|
615
626
|
end
|
@@ -750,6 +761,11 @@ WARNING
|
|
750
761
|
break unless scanner.scan(/,\s*/)
|
751
762
|
end
|
752
763
|
|
764
|
+
if scanner.scan(/;/)
|
765
|
+
raise SyntaxError.new("Invalid @import: expected end of line, was \";\".",
|
766
|
+
:line => @line)
|
767
|
+
end
|
768
|
+
|
753
769
|
return values
|
754
770
|
end
|
755
771
|
|
@@ -757,12 +773,12 @@ WARNING
|
|
757
773
|
return if scanner.eos?
|
758
774
|
unless (str = scanner.scan(Sass::SCSS::RX::STRING)) ||
|
759
775
|
(uri = scanner.scan(Sass::SCSS::RX::URI))
|
760
|
-
return Tree::ImportNode.new(scanner.scan(/[
|
776
|
+
return Tree::ImportNode.new(scanner.scan(/[^,;]+/))
|
761
777
|
end
|
762
778
|
|
763
779
|
val = scanner[1] || scanner[2]
|
764
780
|
scanner.scan(/\s*/)
|
765
|
-
if media = scanner.scan(/[
|
781
|
+
if media = scanner.scan(/[^,;].*/)
|
766
782
|
Tree::DirectiveNode.new("@import #{str || uri} #{media}")
|
767
783
|
elsif uri
|
768
784
|
Tree::DirectiveNode.new("@import #{uri}")
|
@@ -93,6 +93,17 @@ module Sass
|
|
93
93
|
@mixins_in_use ||= @parent.mixins_in_use
|
94
94
|
end
|
95
95
|
|
96
|
+
def stack_trace
|
97
|
+
trace = []
|
98
|
+
stack.reverse.each_with_index do |entry, i|
|
99
|
+
msg = "#{i == 0 ? "on" : "from"} line #{entry[:line]}"
|
100
|
+
msg << " of #{entry[:filename] || "an unknown file"}"
|
101
|
+
msg << ", in `#{entry[:mixin]}'" if entry[:mixin]
|
102
|
+
trace << msg
|
103
|
+
end
|
104
|
+
trace
|
105
|
+
end
|
106
|
+
|
96
107
|
private
|
97
108
|
|
98
109
|
def parent_options
|
@@ -229,6 +229,10 @@ END
|
|
229
229
|
'Only meaningful for --watch and --update.') do
|
230
230
|
@options[:stop_on_error] = true
|
231
231
|
end
|
232
|
+
opts.on('-f', '--force', 'Recompile all Sass files, even if the CSS file is newer.',
|
233
|
+
'Only meaningful for --update.') do
|
234
|
+
@options[:force] = true
|
235
|
+
end
|
232
236
|
opts.on('-c', '--check', "Just check syntax, don't evaluate.") do
|
233
237
|
require 'stringio'
|
234
238
|
@options[:check_syntax] = true
|
@@ -238,6 +242,10 @@ END
|
|
238
242
|
'Output style. Can be nested (default), compact, compressed, or expanded.') do |name|
|
239
243
|
@options[:for_engine][:style] = name.to_sym
|
240
244
|
end
|
245
|
+
opts.on('--precision NUMBER_OF_DIGITS', Integer,
|
246
|
+
'How many digits of precision to use when outputting decimal numbers. Defaults to 3.') do |precision|
|
247
|
+
::Sass::Script::Number.precision = precision
|
248
|
+
end
|
241
249
|
opts.on('-q', '--quiet', 'Silence warnings and status messages during compilation.') do
|
242
250
|
@options[:for_engine][:quiet] = true
|
243
251
|
end
|
@@ -350,6 +358,11 @@ END
|
|
350
358
|
::Sass::Plugin.options.merge! @options[:for_engine]
|
351
359
|
::Sass::Plugin.options[:unix_newlines] = @options[:unix_newlines]
|
352
360
|
|
361
|
+
if @options[:force]
|
362
|
+
raise "The --force flag may only be used with --update." unless @options[:update]
|
363
|
+
::Sass::Plugin.options[:always_update] = true
|
364
|
+
end
|
365
|
+
|
353
366
|
raise <<MSG if @args.empty?
|
354
367
|
What files should I watch? Did you mean something like:
|
355
368
|
#{@default_syntax} --watch input.#{@default_syntax}:output.css
|
@@ -372,7 +385,7 @@ MSG
|
|
372
385
|
|
373
386
|
dirs, files = @args.map {|name| split_colon_path(name)}.
|
374
387
|
partition {|i, _| File.directory? i}
|
375
|
-
files.map! {|from, to| [from, to || from.gsub(
|
388
|
+
files.map! {|from, to| [from, to || from.gsub(/\.[^.]*?$/, '.css')]}
|
376
389
|
dirs.map! {|from, to| [from, to || from]}
|
377
390
|
::Sass::Plugin.options[:template_location] = dirs
|
378
391
|
|
@@ -72,7 +72,8 @@ module Sass
|
|
72
72
|
# If no such files exist, it should return nil.
|
73
73
|
#
|
74
74
|
# The {Sass::Engine} to be returned should be passed `options`,
|
75
|
-
# with a few modifications. `:
|
75
|
+
# with a few modifications. `:syntax` should be set appropriately,
|
76
|
+
# `:filename` should be set to `uri`,
|
76
77
|
# and `:importer` should be set to this importer.
|
77
78
|
#
|
78
79
|
# @param uri [String] The URI to import.
|
@@ -13,7 +13,7 @@ module Sass
|
|
13
13
|
# @param root [String] The root path.
|
14
14
|
# This importer will import files relative to this path.
|
15
15
|
def initialize(root)
|
16
|
-
@root = root
|
16
|
+
@root = File.expand_path(root)
|
17
17
|
end
|
18
18
|
|
19
19
|
# @see Base#find_relative
|
@@ -45,14 +45,21 @@ module Sass
|
|
45
45
|
@root
|
46
46
|
end
|
47
47
|
|
48
|
+
def hash
|
49
|
+
@root.hash
|
50
|
+
end
|
51
|
+
|
52
|
+
def eql?(other)
|
53
|
+
root.eql?(other.root)
|
54
|
+
end
|
55
|
+
|
48
56
|
protected
|
49
57
|
|
50
58
|
# If a full uri is passed, this removes the root from it
|
51
59
|
# otherwise returns the name unchanged
|
52
60
|
def remove_root(name)
|
53
|
-
|
54
|
-
|
55
|
-
name[root.length..-1]
|
61
|
+
if name.index(@root + "/") == 0
|
62
|
+
name[(@root.length + 1)..-1]
|
56
63
|
else
|
57
64
|
name
|
58
65
|
end
|
@@ -77,6 +84,7 @@ module Sass
|
|
77
84
|
# The first element of each pair is a filename to look for;
|
78
85
|
# the second element is the syntax that file would be in (`:sass` or `:scss`).
|
79
86
|
def possible_files(name)
|
87
|
+
name = escape_glob_characters(name)
|
80
88
|
dirname, basename, extname = split(name)
|
81
89
|
sorted_exts = extensions.sort
|
82
90
|
syntax = extensions[extname]
|
@@ -85,6 +93,11 @@ module Sass
|
|
85
93
|
sorted_exts.map {|ext, syn| ["#{dirname}/{_,}#{basename}.#{ext}", syn]}
|
86
94
|
end
|
87
95
|
|
96
|
+
def escape_glob_characters(name)
|
97
|
+
name.gsub(/[\*\[\]\{\}\?]/) do |char|
|
98
|
+
"\\#{char}"
|
99
|
+
end
|
100
|
+
end
|
88
101
|
|
89
102
|
REDUNDANT_DIRECTORY = %r{#{Regexp.escape(File::SEPARATOR)}\.#{Regexp.escape(File::SEPARATOR)}}
|
90
103
|
# Given a base directory and an `@import`ed name,
|
@@ -95,7 +108,7 @@ module Sass
|
|
95
108
|
# @return [(String, Symbol)] A filename-syntax pair.
|
96
109
|
def find_real_file(dir, name)
|
97
110
|
for (f,s) in possible_files(remove_root(name))
|
98
|
-
path = (dir == ".") ? f : "#{dir}/#{f}"
|
111
|
+
path = (dir == "." || Pathname.new(f).absolute?) ? f : "#{dir}/#{f}"
|
99
112
|
if full_path = Dir[path].first
|
100
113
|
full_path.gsub!(REDUNDANT_DIRECTORY,File::SEPARATOR)
|
101
114
|
return full_path, s
|
@@ -116,14 +129,6 @@ module Sass
|
|
116
129
|
[dirname, basename, extension]
|
117
130
|
end
|
118
131
|
|
119
|
-
def hash
|
120
|
-
@root.hash
|
121
|
-
end
|
122
|
-
|
123
|
-
def eql?(other)
|
124
|
-
root.eql?(other.root)
|
125
|
-
end
|
126
|
-
|
127
132
|
private
|
128
133
|
|
129
134
|
def _find(dir, name, options)
|
@@ -31,7 +31,7 @@ module Less
|
|
31
31
|
WARNING: Sass doesn't support mixing in selector sequences.
|
32
32
|
Replacing "#{sel}" with "@extend #{base}"
|
33
33
|
WARNING
|
34
|
-
env << Node::SassNode.new(Sass::Tree::CommentNode.new("// #{sel};", true))
|
34
|
+
env << Node::SassNode.new(Sass::Tree::CommentNode.new(["// #{sel};"], true, false))
|
35
35
|
env << Node::SassNode.new(Sass::Tree::ExtendNode.new([base]))
|
36
36
|
end
|
37
37
|
end
|
@@ -225,7 +225,7 @@ WARNING
|
|
225
225
|
class Property
|
226
226
|
def to_sass_tree
|
227
227
|
return if hide_in_sass
|
228
|
-
Sass::Tree::PropNode.new([self], @value.to_sass_tree,
|
228
|
+
Sass::Tree::PropNode.new([self], @value.to_sass_tree, :new)
|
229
229
|
end
|
230
230
|
end
|
231
231
|
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'sass/logger/log_level'
|
2
|
+
|
3
|
+
class Sass::Logger::Base
|
4
|
+
|
5
|
+
include Sass::Logger::LogLevel
|
6
|
+
|
7
|
+
attr_accessor :log_level
|
8
|
+
attr_accessor :disabled
|
9
|
+
|
10
|
+
log_level :trace
|
11
|
+
log_level :debug
|
12
|
+
log_level :info
|
13
|
+
log_level :warn
|
14
|
+
log_level :error
|
15
|
+
|
16
|
+
def initialize(log_level = :debug)
|
17
|
+
self.log_level = log_level
|
18
|
+
end
|
19
|
+
|
20
|
+
def logging_level?(level)
|
21
|
+
!disabled && self.class.log_level?(level, log_level)
|
22
|
+
end
|
23
|
+
|
24
|
+
def log(level, message)
|
25
|
+
self._log(level, message) if logging_level?(level)
|
26
|
+
end
|
27
|
+
|
28
|
+
def _log(level, message)
|
29
|
+
Kernel::warn(message)
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Sass
|
2
|
+
module Logger
|
3
|
+
module LogLevel
|
4
|
+
|
5
|
+
def self.included(base)
|
6
|
+
base.extend(ClassMethods)
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
def inherited(subclass)
|
11
|
+
subclass.log_levels = subclass.superclass.log_levels.dup
|
12
|
+
end
|
13
|
+
|
14
|
+
def log_levels
|
15
|
+
@log_levels ||= {}
|
16
|
+
end
|
17
|
+
|
18
|
+
def log_levels=(levels)
|
19
|
+
@log_levels = levels
|
20
|
+
end
|
21
|
+
|
22
|
+
def log_level?(level, min_level)
|
23
|
+
log_levels[level] >= log_levels[min_level]
|
24
|
+
end
|
25
|
+
|
26
|
+
def log_level(name, options = {})
|
27
|
+
if options[:prepend]
|
28
|
+
level = log_levels.values.min
|
29
|
+
level = level.nil? ? 0 : level - 1
|
30
|
+
else
|
31
|
+
level = log_levels.values.max
|
32
|
+
level = level.nil? ? 0 : level + 1
|
33
|
+
end
|
34
|
+
log_levels.update(name => level)
|
35
|
+
define_logger(name)
|
36
|
+
end
|
37
|
+
|
38
|
+
def define_logger(name, options = {})
|
39
|
+
class_eval %Q{
|
40
|
+
def #{name}(message)
|
41
|
+
#{options.fetch(:to, :log)}(#{name.inspect}, message)
|
42
|
+
end
|
43
|
+
}
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|