haml 3.1.0 → 3.1.1
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/VERSION +1 -1
- data/vendor/sass/Rakefile +22 -46
- data/vendor/sass/VERSION +1 -1
- data/vendor/sass/VERSION_NAME +1 -1
- data/vendor/sass/bin/scss +8 -0
- data/vendor/sass/doc-src/SASS_CHANGELOG.md +125 -9
- data/vendor/sass/doc-src/SASS_REFERENCE.md +84 -8
- data/vendor/sass/lib/sass.rb +0 -3
- data/vendor/sass/lib/sass/cache_stores.rb +1 -0
- data/vendor/sass/lib/sass/cache_stores/base.rb +2 -2
- data/vendor/sass/lib/sass/cache_stores/chain.rb +33 -0
- data/vendor/sass/lib/sass/cache_stores/filesystem.rb +6 -4
- data/vendor/sass/lib/sass/cache_stores/memory.rb +8 -12
- data/vendor/sass/lib/sass/engine.rb +65 -56
- data/vendor/sass/lib/sass/environment.rb +5 -2
- data/vendor/sass/lib/sass/exec.rb +52 -21
- data/vendor/sass/lib/sass/importers/filesystem.rb +32 -9
- data/vendor/sass/lib/sass/less.rb +1 -1
- data/vendor/sass/lib/sass/plugin.rb +11 -1
- data/vendor/sass/lib/sass/plugin/compiler.rb +21 -12
- data/vendor/sass/lib/sass/plugin/rails.rb +8 -82
- data/vendor/sass/lib/sass/plugin/staleness_checker.rb +10 -10
- data/vendor/sass/lib/sass/railtie.rb +3 -2
- data/vendor/sass/lib/sass/script.rb +2 -25
- data/vendor/sass/lib/sass/script/color.rb +4 -15
- data/vendor/sass/lib/sass/script/funcall.rb +63 -19
- data/vendor/sass/lib/sass/script/functions.rb +257 -19
- data/vendor/sass/lib/sass/script/lexer.rb +1 -4
- data/vendor/sass/lib/sass/script/list.rb +2 -2
- data/vendor/sass/lib/sass/script/node.rb +0 -27
- data/vendor/sass/lib/sass/script/number.rb +1 -1
- data/vendor/sass/lib/sass/script/operation.rb +0 -5
- data/vendor/sass/lib/sass/script/parser.rb +30 -12
- data/vendor/sass/lib/sass/script/string.rb +2 -17
- data/vendor/sass/lib/sass/script/string_interpolation.rb +1 -0
- data/vendor/sass/lib/sass/scss/parser.rb +58 -18
- data/vendor/sass/lib/sass/scss/rx.rb +2 -1
- data/vendor/sass/lib/sass/scss/script_lexer.rb +1 -1
- data/vendor/sass/lib/sass/selector/comma_sequence.rb +2 -3
- data/vendor/sass/lib/sass/selector/sequence.rb +3 -6
- data/vendor/sass/lib/sass/selector/simple_sequence.rb +2 -3
- data/vendor/sass/lib/sass/tree/charset_node.rb +0 -15
- data/vendor/sass/lib/sass/tree/comment_node.rb +20 -71
- data/vendor/sass/lib/sass/tree/debug_node.rb +4 -22
- data/vendor/sass/lib/sass/tree/directive_node.rb +0 -52
- data/vendor/sass/lib/sass/tree/each_node.rb +8 -38
- data/vendor/sass/lib/sass/tree/extend_node.rb +12 -48
- data/vendor/sass/lib/sass/tree/for_node.rb +20 -51
- data/vendor/sass/lib/sass/tree/function_node.rb +27 -0
- data/vendor/sass/lib/sass/tree/if_node.rb +22 -57
- data/vendor/sass/lib/sass/tree/import_node.rb +0 -56
- data/vendor/sass/lib/sass/tree/media_node.rb +0 -43
- data/vendor/sass/lib/sass/tree/mixin_def_node.rb +12 -45
- data/vendor/sass/lib/sass/tree/mixin_node.rb +13 -124
- data/vendor/sass/lib/sass/tree/node.rb +18 -304
- data/vendor/sass/lib/sass/tree/prop_node.rb +24 -92
- data/vendor/sass/lib/sass/tree/return_node.rb +18 -0
- data/vendor/sass/lib/sass/tree/root_node.rb +4 -133
- data/vendor/sass/lib/sass/tree/rule_node.rb +21 -164
- data/vendor/sass/lib/sass/tree/variable_node.rb +14 -23
- data/vendor/sass/lib/sass/tree/visitors/base.rb +75 -0
- data/vendor/sass/lib/sass/tree/visitors/check_nesting.rb +134 -0
- data/vendor/sass/lib/sass/tree/visitors/convert.rb +255 -0
- data/vendor/sass/lib/sass/tree/visitors/cssize.rb +175 -0
- data/vendor/sass/lib/sass/tree/visitors/perform.rb +301 -0
- data/vendor/sass/lib/sass/tree/visitors/to_css.rb +216 -0
- data/vendor/sass/lib/sass/tree/warn_node.rb +4 -28
- data/vendor/sass/lib/sass/tree/while_node.rb +5 -35
- data/vendor/sass/lib/sass/util.rb +0 -50
- data/vendor/sass/sass.gemspec +1 -1
- data/vendor/sass/test/sass/conversion_test.rb +53 -102
- data/vendor/sass/test/sass/engine_test.rb +416 -540
- data/vendor/sass/test/sass/functions_test.rb +306 -4
- data/vendor/sass/test/sass/importer_test.rb +0 -22
- data/vendor/sass/test/sass/plugin_test.rb +51 -21
- data/vendor/sass/test/sass/results/if.css +3 -0
- data/vendor/sass/test/sass/script_conversion_test.rb +0 -38
- data/vendor/sass/test/sass/script_test.rb +19 -4
- data/vendor/sass/test/sass/scss/scss_test.rb +32 -11
- data/vendor/sass/test/sass/templates/if.sass +11 -0
- data/vendor/sass/test/sass/templates/nested_import.sass +2 -0
- data/vendor/sass/test/sass/util_test.rb +0 -21
- data/vendor/sass/test/test_helper.rb +0 -3
- metadata +268 -258
- data/vendor/sass/bin/css2sass +0 -13
- data/vendor/sass/lib/sass/cache_stores/active_support.rb +0 -28
- data/vendor/sass/lib/sass/importers/rails.rb +0 -75
@@ -149,7 +149,7 @@ module Sass::Script
|
|
149
149
|
def div(other)
|
150
150
|
if other.is_a? Number
|
151
151
|
res = operate(other, :/)
|
152
|
-
if self.original && other.original
|
152
|
+
if self.original && other.original
|
153
153
|
res.original = "#{self.original}/#{other.original}"
|
154
154
|
end
|
155
155
|
res
|
@@ -66,11 +66,6 @@ module Sass::Script
|
|
66
66
|
literal1 = @operand1.perform(environment)
|
67
67
|
literal2 = @operand2.perform(environment)
|
68
68
|
|
69
|
-
if @operator == :space && context == :equals
|
70
|
-
literal1 = Sass::Script::String.new(literal1.value) if literal1.is_a?(Sass::Script::String)
|
71
|
-
literal2 = Sass::Script::String.new(literal2.value) if literal2.is_a?(Sass::Script::String)
|
72
|
-
end
|
73
|
-
|
74
69
|
begin
|
75
70
|
opts(literal1.send(@operator, literal2))
|
76
71
|
rescue NoMethodError => e
|
@@ -112,6 +112,24 @@ module Sass
|
|
112
112
|
raise e
|
113
113
|
end
|
114
114
|
|
115
|
+
# Parses the argument list for a function definition.
|
116
|
+
#
|
117
|
+
# @return [Array<Script::Node>] The root nodes of the arguments.
|
118
|
+
# @raise [Sass::SyntaxError] if the argument list isn't valid SassScript
|
119
|
+
def parse_function_definition_arglist
|
120
|
+
args = defn_arglist!(true)
|
121
|
+
assert_done
|
122
|
+
|
123
|
+
args.each do |k, v|
|
124
|
+
k.options = @options
|
125
|
+
v.options = @options if v
|
126
|
+
end
|
127
|
+
args
|
128
|
+
rescue Sass::SyntaxError => e
|
129
|
+
e.modify_backtrace :line => @lexer.line, :filename => @options[:filename]
|
130
|
+
raise e
|
131
|
+
end
|
132
|
+
|
115
133
|
# Parses a SassScript expression.
|
116
134
|
#
|
117
135
|
# @overload parse(str, line, offset, filename = nil)
|
@@ -283,24 +301,23 @@ RUBY
|
|
283
301
|
node(Script::Funcall.new(tok.value, args, keywords))
|
284
302
|
end
|
285
303
|
|
286
|
-
def defn_arglist!(
|
287
|
-
|
304
|
+
def defn_arglist!(must_have_parens)
|
305
|
+
if must_have_parens
|
306
|
+
assert_tok(:lparen)
|
307
|
+
else
|
308
|
+
return [] unless try_tok(:lparen)
|
309
|
+
end
|
288
310
|
return [] if try_tok(:rparen)
|
311
|
+
|
289
312
|
res = []
|
313
|
+
must_have_default = false
|
290
314
|
loop do
|
291
315
|
line = @lexer.line
|
292
316
|
offset = @lexer.offset + 1
|
293
317
|
c = assert_tok(:const)
|
294
318
|
var = Script::Variable.new(c.value)
|
295
|
-
if tok =
|
319
|
+
if tok = try_tok(:colon)
|
296
320
|
val = assert_expr(:space)
|
297
|
-
|
298
|
-
if tok.type == :single_eq
|
299
|
-
val.context = :equals
|
300
|
-
val.options = @options
|
301
|
-
Script.equals_warning("mixin argument defaults", "$#{c.value}",
|
302
|
-
val.to_sass, false, line, offset, @options[:filename])
|
303
|
-
end
|
304
321
|
must_have_default = true
|
305
322
|
elsif must_have_default
|
306
323
|
raise SyntaxError.new("Required argument #{var.inspect} must come before any optional arguments.")
|
@@ -376,9 +393,10 @@ RUBY
|
|
376
393
|
return variable unless try_tok(:lparen)
|
377
394
|
was_in_parens = @in_parens
|
378
395
|
@in_parens = true
|
379
|
-
|
396
|
+
line = @lexer.line
|
397
|
+
e = expr
|
380
398
|
assert_tok(:rparen)
|
381
|
-
return e
|
399
|
+
return e || node(List.new([], :space), line)
|
382
400
|
ensure
|
383
401
|
@in_parens = was_in_parens
|
384
402
|
end
|
@@ -15,15 +15,6 @@ module Sass::Script
|
|
15
15
|
# @return [Symbol] `:string` or `:identifier`
|
16
16
|
attr_reader :type
|
17
17
|
|
18
|
-
# In addition to setting the \{#context} of the string,
|
19
|
-
# this sets the string to be an identifier if the context is `:equals`.
|
20
|
-
#
|
21
|
-
# @see Node#context=
|
22
|
-
def context=(context)
|
23
|
-
super
|
24
|
-
@type = :identifier if context == :equals
|
25
|
-
end
|
26
|
-
|
27
18
|
# Creates a new string.
|
28
19
|
#
|
29
20
|
# @param value [String] See \{#value}
|
@@ -42,7 +33,7 @@ module Sass::Script
|
|
42
33
|
# @see Node#to_s
|
43
34
|
def to_s(opts = {})
|
44
35
|
if @type == :identifier
|
45
|
-
return @
|
36
|
+
return @value.tr("\n", " ")
|
46
37
|
end
|
47
38
|
|
48
39
|
return "\"#{value.gsub('"', "\\\"")}\"" if opts[:quote] == %q{"}
|
@@ -54,13 +45,7 @@ module Sass::Script
|
|
54
45
|
|
55
46
|
# @see Node#to_sass
|
56
47
|
def to_sass(opts = {})
|
57
|
-
|
58
|
-
self.value !~ Sass::SCSS::RX::URI &&
|
59
|
-
Sass::SCSS::RX.escape_ident(self.value).include?(?\\)
|
60
|
-
return "unquote(#{Sass::Script::String.new(self.value, :string).to_sass})"
|
61
|
-
else
|
62
|
-
return to_s
|
63
|
-
end
|
48
|
+
to_s
|
64
49
|
end
|
65
50
|
end
|
66
51
|
end
|
@@ -23,6 +23,7 @@ module Sass::Script
|
|
23
23
|
# @see Node#to_sass
|
24
24
|
def to_sass(opts = {})
|
25
25
|
# We can get rid of all of this when we remove the deprecated :equals context
|
26
|
+
# XXX CE: It's gone now but I'm not sure what can be removed now.
|
26
27
|
before_unquote, before_quote_char, before_str = parse_str(@before.to_sass(opts))
|
27
28
|
after_unquote, after_quote_char, after_str = parse_str(@after.to_sass(opts))
|
28
29
|
unquote = before_unquote || after_unquote ||
|
@@ -98,8 +98,8 @@ module Sass
|
|
98
98
|
node << comment
|
99
99
|
end
|
100
100
|
|
101
|
-
DIRECTIVES = Set[:mixin, :include, :
|
102
|
-
:else, :extend, :import, :media, :charset]
|
101
|
+
DIRECTIVES = Set[:mixin, :include, :function, :return, :debug, :warn, :for,
|
102
|
+
:each, :while, :if, :else, :extend, :import, :media, :charset]
|
103
103
|
|
104
104
|
def directive
|
105
105
|
return unless tok(/@/)
|
@@ -144,6 +144,17 @@ module Sass
|
|
144
144
|
node(Sass::Tree::MixinNode.new(name, args, keywords))
|
145
145
|
end
|
146
146
|
|
147
|
+
def function_directive
|
148
|
+
name = tok! IDENT
|
149
|
+
args = sass_script(:parse_function_definition_arglist)
|
150
|
+
ss
|
151
|
+
block(node(Sass::Tree::FunctionNode.new(name, args)), :function)
|
152
|
+
end
|
153
|
+
|
154
|
+
def return_directive
|
155
|
+
node(Sass::Tree::ReturnNode.new(sass_script(:parse)))
|
156
|
+
end
|
157
|
+
|
147
158
|
def debug_directive
|
148
159
|
node(Sass::Tree::DebugNode.new(sass_script(:parse)))
|
149
160
|
end
|
@@ -225,8 +236,7 @@ module Sass
|
|
225
236
|
end
|
226
237
|
|
227
238
|
def else_directive
|
228
|
-
|
229
|
-
"Invalid CSS: @else must come after @if", :line => @line)
|
239
|
+
err("Invalid CSS: @else must come after @if")
|
230
240
|
end
|
231
241
|
|
232
242
|
def extend_directive
|
@@ -365,6 +375,7 @@ module Sass
|
|
365
375
|
end
|
366
376
|
|
367
377
|
def block_child(context)
|
378
|
+
return variable || directive if context == :function
|
368
379
|
return variable || directive || ruleset if context == :stylesheet
|
369
380
|
variable || directive || declaration_or_ruleset
|
370
381
|
end
|
@@ -391,11 +402,9 @@ module Sass
|
|
391
402
|
# no colon after the identifier, whitespace after the colon),
|
392
403
|
# but I'm not sure the gains would be worth the added complexity.
|
393
404
|
def declaration_or_ruleset
|
394
|
-
pos = @scanner.pos
|
395
|
-
line = @line
|
396
405
|
old_use_property_exception, @use_property_exception =
|
397
406
|
@use_property_exception, false
|
398
|
-
|
407
|
+
decl_err = catch_error do
|
399
408
|
decl = declaration
|
400
409
|
unless decl && decl.has_children
|
401
410
|
# We want an exception if it's not there,
|
@@ -403,17 +412,10 @@ module Sass
|
|
403
412
|
tok!(/[;}]/) unless tok?(/[;}]/)
|
404
413
|
end
|
405
414
|
return decl
|
406
|
-
rescue Sass::SyntaxError => decl_err
|
407
415
|
end
|
408
416
|
|
409
|
-
|
410
|
-
@
|
411
|
-
|
412
|
-
begin
|
413
|
-
return ruleset
|
414
|
-
rescue Sass::SyntaxError => ruleset_err
|
415
|
-
raise @use_property_exception ? decl_err : ruleset_err
|
416
|
-
end
|
417
|
+
ruleset_err = catch_error {return ruleset}
|
418
|
+
rethrow(@use_property_exception ? decl_err : ruleset_err)
|
417
419
|
ensure
|
418
420
|
@use_property_exception = old_use_property_exception
|
419
421
|
end
|
@@ -636,9 +638,11 @@ MESSAGE
|
|
636
638
|
tok!(/:/)
|
637
639
|
space, value = value!
|
638
640
|
ss
|
641
|
+
important = tok(IMPORTANT)
|
642
|
+
ss
|
639
643
|
require_block = tok?(/\{/)
|
640
644
|
|
641
|
-
node = node(Sass::Tree::PropNode.new(name.flatten.compact, value, :new))
|
645
|
+
node = node(Sass::Tree::PropNode.new(name.flatten.compact, value, !!important, :new))
|
642
646
|
|
643
647
|
return node unless require_block
|
644
648
|
nested_properties! node, space
|
@@ -672,7 +676,7 @@ MESSAGE
|
|
672
676
|
end
|
673
677
|
|
674
678
|
def nested_properties!(node, space)
|
675
|
-
|
679
|
+
err(<<MESSAGE) unless space
|
676
680
|
Invalid CSS: a space is required between a property and its definition
|
677
681
|
when it has other properties nested beneath it.
|
678
682
|
MESSAGE
|
@@ -786,6 +790,9 @@ MESSAGE
|
|
786
790
|
result = parser.send(*args)
|
787
791
|
@line = parser.line
|
788
792
|
result
|
793
|
+
rescue Sass::SyntaxError => e
|
794
|
+
throw(:_sass_parser_error, true) if @throw_error
|
795
|
+
raise e
|
789
796
|
end
|
790
797
|
|
791
798
|
def merge(arr)
|
@@ -832,9 +839,42 @@ MESSAGE
|
|
832
839
|
end
|
833
840
|
|
834
841
|
def expected(name)
|
842
|
+
throw(:_sass_parser_error, true) if @throw_error
|
835
843
|
self.class.expected(@scanner, @expected || name, @line)
|
836
844
|
end
|
837
845
|
|
846
|
+
def err(msg)
|
847
|
+
throw(:_sass_parser_error, true) if @throw_error
|
848
|
+
raise Sass::SyntaxError.new(msg, :line => @line)
|
849
|
+
end
|
850
|
+
|
851
|
+
def catch_error(&block)
|
852
|
+
old_throw_error, @throw_error = @throw_error, true
|
853
|
+
pos = @scanner.pos
|
854
|
+
line = @line
|
855
|
+
expected = @expected
|
856
|
+
if catch(:_sass_parser_error, &block)
|
857
|
+
@scanner.pos = pos
|
858
|
+
@line = line
|
859
|
+
@expected = expected
|
860
|
+
{:pos => pos, :line => line, :expected => @expected, :block => block}
|
861
|
+
end
|
862
|
+
ensure
|
863
|
+
@throw_error = old_throw_error
|
864
|
+
end
|
865
|
+
|
866
|
+
def rethrow(err)
|
867
|
+
if @throw_err
|
868
|
+
throw :_sass_parser_error, err
|
869
|
+
else
|
870
|
+
@scanner = StringScanner.new(@scanner.string)
|
871
|
+
@scanner.pos = err[:pos]
|
872
|
+
@line = err[:line]
|
873
|
+
@expected = err[:expected]
|
874
|
+
err[:block].call
|
875
|
+
end
|
876
|
+
end
|
877
|
+
|
838
878
|
# @private
|
839
879
|
def self.expected(scanner, expected, line)
|
840
880
|
pos = scanner.pos
|
@@ -68,6 +68,7 @@ module Sass
|
|
68
68
|
URLCHAR = /[#%&*-~]|#{NONASCII}|#{ESCAPE}/
|
69
69
|
URL = /(#{URLCHAR}*)/
|
70
70
|
W = /[ \t\r\n\f]*/
|
71
|
+
VARIABLE = /(\$)(#{Sass::SCSS::RX::IDENT})/
|
71
72
|
|
72
73
|
# This is more liberal than the spec's definition,
|
73
74
|
# but that definition didn't work well with the greediness rules
|
@@ -118,7 +119,7 @@ module Sass
|
|
118
119
|
# We could use it for 1.9 only, but I don't want to introduce a cross-version
|
119
120
|
# behavior difference.
|
120
121
|
# In any case, almost all CSS idents will be matched by this.
|
121
|
-
STATIC_VALUE = /(-?#{NMSTART}|#{STRING_NOINTERP}|\s(?!%)|#[a-f0-9]|[,%]|#{NUM}
|
122
|
+
STATIC_VALUE = /(-?#{NMSTART}|#{STRING_NOINTERP}|\s(?!%)|#[a-f0-9]|[,%]|#{NUM})+(?=[;}])/i
|
122
123
|
|
123
124
|
STATIC_SELECTOR = /(#{NMCHAR}|\s|[,>+*]|[:#.]#{NMSTART})+(?=[{])/i
|
124
125
|
end
|
@@ -38,9 +38,8 @@ module Sass
|
|
38
38
|
end.flatten)
|
39
39
|
end
|
40
40
|
|
41
|
-
# Non-destrucively extends this selector
|
42
|
-
#
|
43
|
-
# (which should be populated via {Sass::Tree::Node#cssize}).
|
41
|
+
# Non-destrucively extends this selector with the extensions specified in a hash
|
42
|
+
# (which should come from {Sass::Tree::Visitors::Cssize}).
|
44
43
|
#
|
45
44
|
# @todo Link this to the reference documentation on `@extend`
|
46
45
|
# when such a thing exists.
|
@@ -65,9 +65,8 @@ module Sass
|
|
65
65
|
end.flatten)
|
66
66
|
end
|
67
67
|
|
68
|
-
# Non-destructively extends this selector
|
69
|
-
#
|
70
|
-
# (which should be populated via {Sass::Tree::Node#cssize}).
|
68
|
+
# Non-destructively extends this selector with the extensions specified in a hash
|
69
|
+
# (which should come from {Sass::Tree::Visitors::Cssize}).
|
71
70
|
#
|
72
71
|
# @overload def do_extend(extends)
|
73
72
|
# @param extends [Sass::Util::SubsetMap{Selector::Simple => Selector::Sequence}]
|
@@ -104,9 +103,7 @@ module Sass
|
|
104
103
|
# @see Simple#to_a
|
105
104
|
def to_a
|
106
105
|
ary = @members.map {|seq_or_op| seq_or_op.is_a?(SimpleSequence) ? seq_or_op.to_a : seq_or_op}
|
107
|
-
|
108
|
-
ary = Sass::Util.substitute(ary, [" ", "\n", " "], ["\n"])
|
109
|
-
ary.flatten.compact
|
106
|
+
Sass::Util.intersperse(ary, " ").flatten.compact
|
110
107
|
end
|
111
108
|
|
112
109
|
# Returns a string representation of the sequence.
|
@@ -51,9 +51,8 @@ module Sass
|
|
51
51
|
[SimpleSequence.new(super_seq.members.last.members + @members[1..-1])]
|
52
52
|
end
|
53
53
|
|
54
|
-
# Non-destrucively extends this selector
|
55
|
-
#
|
56
|
-
# (which should be populated via {Sass::Tree::Node#cssize}).
|
54
|
+
# Non-destrucively extends this selector with the extensions specified in a hash
|
55
|
+
# (which should come from {Sass::Tree::Visitors::Cssize}).
|
57
56
|
#
|
58
57
|
# @overload def do_extend(extends)
|
59
58
|
# @param extends [{Selector::Simple => Selector::Sequence}]
|
@@ -18,20 +18,5 @@ module Sass::Tree
|
|
18
18
|
def invisible?
|
19
19
|
!Sass::Util.ruby1_8?
|
20
20
|
end
|
21
|
-
|
22
|
-
protected
|
23
|
-
|
24
|
-
# @see Node#to_src
|
25
|
-
def to_src(tabs, opts, fmt)
|
26
|
-
"#{' ' * tabs}@charset \"#{name}\"#{semi fmt}\n"
|
27
|
-
end
|
28
|
-
|
29
|
-
# Computes the CSS for the directive.
|
30
|
-
#
|
31
|
-
# @param tabs [Fixnum] The level of indentation for the CSS
|
32
|
-
# @return [String] The resulting CSS
|
33
|
-
def _to_s(tabs)
|
34
|
-
"@charset \"#{name}\";"
|
35
|
-
end
|
36
21
|
end
|
37
22
|
end
|
@@ -10,6 +10,14 @@ module Sass::Tree
|
|
10
10
|
# @return [String]
|
11
11
|
attr_accessor :value
|
12
12
|
|
13
|
+
# Whether the comment is loud.
|
14
|
+
#
|
15
|
+
# Loud comments start with ! and force the comment to be generated
|
16
|
+
# irrespective of compilation settings or the comment syntax used.
|
17
|
+
#
|
18
|
+
# @return [Boolean]
|
19
|
+
attr_accessor :loud
|
20
|
+
|
13
21
|
# Whether or not the comment is silent (that is, doesn't output to CSS).
|
14
22
|
#
|
15
23
|
# @return [Boolean]
|
@@ -19,8 +27,10 @@ module Sass::Tree
|
|
19
27
|
# @param silent [Boolean] See \{#silent}
|
20
28
|
def initialize(value, silent)
|
21
29
|
@lines = []
|
22
|
-
@value = normalize_indentation value
|
23
30
|
@silent = silent
|
31
|
+
@value = normalize_indentation value
|
32
|
+
@loud = @value =~ %r{^(/[\/\*])?!}
|
33
|
+
@value.sub!("#{$1}!", $1.to_s) if @loud
|
24
34
|
super()
|
25
35
|
end
|
26
36
|
|
@@ -36,81 +46,20 @@ module Sass::Tree
|
|
36
46
|
# Returns `true` if this is a silent comment
|
37
47
|
# or the current style doesn't render comments.
|
38
48
|
#
|
49
|
+
# Comments starting with ! are never invisible (and the ! is removed from the output.)
|
50
|
+
#
|
39
51
|
# @return [Boolean]
|
40
52
|
def invisible?
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
# @see Node#to_sass
|
45
|
-
def to_sass(tabs, opts = {})
|
46
|
-
content = value.gsub(/\*\/$/, '').rstrip
|
47
|
-
if content =~ /\A[ \t]/
|
48
|
-
# Re-indent SCSS comments like this:
|
49
|
-
# /* foo
|
50
|
-
# bar
|
51
|
-
# baz */
|
52
|
-
content.gsub!(/^/, ' ')
|
53
|
-
content.sub!(/\A([ \t]*)\/\*/, '/*\1')
|
54
|
-
end
|
55
|
-
|
56
|
-
content =
|
57
|
-
unless content.include?("\n")
|
58
|
-
content
|
59
|
-
else
|
60
|
-
content.gsub!(/\n( \*|\/\/)/, "\n ")
|
61
|
-
spaces = content.scan(/\n( *)/).map {|s| s.first.size}.min
|
62
|
-
sep = silent ? "\n//" : "\n *"
|
63
|
-
if spaces >= 2
|
64
|
-
content.gsub(/\n /, sep)
|
65
|
-
else
|
66
|
-
content.gsub(/\n#{' ' * spaces}/, sep)
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
content.gsub!(/\A\/\*/, '//') if silent
|
71
|
-
content.gsub!(/^/, ' ' * tabs)
|
72
|
-
content.rstrip + "\n"
|
73
|
-
end
|
74
|
-
|
75
|
-
# @see Node#to_scss
|
76
|
-
def to_scss(tabs, opts = {})
|
77
|
-
spaces = (' ' * [tabs - value[/^ */].size, 0].max)
|
78
|
-
if silent
|
79
|
-
value.gsub(/^[\/ ]\*/, '//').gsub(/ *\*\/$/, '')
|
53
|
+
if @loud
|
54
|
+
return false
|
80
55
|
else
|
81
|
-
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
protected
|
86
|
-
|
87
|
-
# Computes the CSS for the comment.
|
88
|
-
#
|
89
|
-
# Returns `nil` if this is a silent comment
|
90
|
-
# or the current style doesn't render comments.
|
91
|
-
#
|
92
|
-
# @overload to_s(tabs = 0)
|
93
|
-
# @param tabs [Fixnum] The level of indentation for the CSS
|
94
|
-
# @return [String, nil] The resulting CSS
|
95
|
-
# @see #invisible?
|
96
|
-
def _to_s(tabs = 0, _ = nil)
|
97
|
-
return if invisible?
|
98
|
-
spaces = (' ' * [tabs - 1 - value[/^ */].size, 0].max)
|
99
|
-
|
100
|
-
content = value.gsub(/^/, spaces)
|
101
|
-
content.gsub!(/\n +(\* *(?!\/))?/, ' ') if style == :compact
|
102
|
-
content
|
56
|
+
@silent || (style == :compressed)
|
57
|
+
end
|
103
58
|
end
|
104
59
|
|
105
|
-
#
|
106
|
-
|
107
|
-
|
108
|
-
# variable and mixin values
|
109
|
-
# @return [Tree::Node, Array<Tree::Node>] The resulting static nodes
|
110
|
-
# @see Sass::Tree
|
111
|
-
def _perform(environment)
|
112
|
-
return [] if @silent
|
113
|
-
self
|
60
|
+
# Returns whether this comment should be interpolated for dynamic comment generation.
|
61
|
+
def evaluated?
|
62
|
+
@loud
|
114
63
|
end
|
115
64
|
|
116
65
|
private
|