sass 3.1.8 → 3.1.9
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/VERSION +1 -1
- data/lib/sass/engine.rb +26 -10
- data/lib/sass/less.rb +1 -1
- data/lib/sass/scss/parser.rb +28 -8
- data/lib/sass/shared.rb +1 -1
- data/lib/sass/tree/comment_node.rb +24 -11
- data/lib/sass/tree/visitors/convert.rb +10 -5
- data/lib/sass/tree/visitors/perform.rb +36 -8
- data/lib/sass/tree/visitors/to_css.rb +2 -12
- data/lib/sass/util.rb +51 -0
- data/test/sass/conversion_test.rb +2 -6
- data/test/sass/engine_test.rb +38 -5
- data/test/sass/scss/css_test.rb +6 -0
- data/test/sass/util_test.rb +12 -0
- metadata +4 -4
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.1.
|
1
|
+
3.1.9
|
data/lib/sass/engine.rb
CHANGED
@@ -90,7 +90,10 @@ module Sass
|
|
90
90
|
#
|
91
91
|
# `children`: `Array<Line>`
|
92
92
|
# : The lines nested below this one.
|
93
|
-
|
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)
|
94
97
|
def comment?
|
95
98
|
text[0] == COMMENT_CHAR && (text[1] == SASS_COMMENT_CHAR || text[1] == CSS_COMMENT_CHAR)
|
96
99
|
end
|
@@ -107,6 +110,10 @@ module Sass
|
|
107
110
|
# which is not output as a CSS comment.
|
108
111
|
SASS_COMMENT_CHAR = ?/
|
109
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
|
+
|
110
117
|
# The character that follows the general COMMENT_CHAR and designates a CSS comment,
|
111
118
|
# which is embedded in the CSS document.
|
112
119
|
CSS_COMMENT_CHAR = ?*
|
@@ -420,7 +427,8 @@ but this line was indented by #{Sass::Shared.human_indentation line[/^\s*/]}.
|
|
420
427
|
MSG
|
421
428
|
end
|
422
429
|
|
423
|
-
last.
|
430
|
+
last.comment_tab_str ||= comment_tab_str
|
431
|
+
last.text << "\n" << line
|
424
432
|
true
|
425
433
|
end
|
426
434
|
|
@@ -486,8 +494,8 @@ MSG
|
|
486
494
|
if child.is_a?(Tree::CommentNode) && child.silent
|
487
495
|
if continued_comment &&
|
488
496
|
child.line == continued_comment.line +
|
489
|
-
continued_comment.
|
490
|
-
continued_comment.value
|
497
|
+
continued_comment.lines + 1
|
498
|
+
continued_comment.value += ["\n"] + child.value
|
491
499
|
next
|
492
500
|
end
|
493
501
|
|
@@ -538,7 +546,7 @@ WARNING
|
|
538
546
|
when ?$
|
539
547
|
parse_variable(line)
|
540
548
|
when COMMENT_CHAR
|
541
|
-
parse_comment(line
|
549
|
+
parse_comment(line)
|
542
550
|
when DIRECTIVE_CHAR
|
543
551
|
parse_directive(parent, line, root)
|
544
552
|
when ESCAPE_CHAR
|
@@ -600,11 +608,19 @@ WARNING
|
|
600
608
|
end
|
601
609
|
|
602
610
|
def parse_comment(line)
|
603
|
-
if line[1] == CSS_COMMENT_CHAR || line[1] == SASS_COMMENT_CHAR
|
604
|
-
silent = line[1] == SASS_COMMENT_CHAR
|
605
|
-
|
606
|
-
|
607
|
-
|
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)
|
608
624
|
else
|
609
625
|
Tree::RuleNode.new(parse_interp(line))
|
610
626
|
end
|
data/lib/sass/less.rb
CHANGED
@@ -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
|
data/lib/sass/scss/parser.rb
CHANGED
@@ -89,14 +89,28 @@ module Sass
|
|
89
89
|
end
|
90
90
|
|
91
91
|
def process_comment(text, node)
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
92
|
+
silent = text =~ /^\/\//
|
93
|
+
line = @line - text.count("\n")
|
94
|
+
if loud = text =~ %r{^/[/*]!}
|
95
|
+
value = Sass::Engine.parse_interp(text, line, @scanner.pos - text.size, :filename => @filename)
|
96
|
+
value[0].slice!(2) # get rid of the "!"
|
97
|
+
else
|
98
|
+
value = [text]
|
99
|
+
end
|
100
|
+
|
101
|
+
if silent
|
102
|
+
value = Sass::Util.with_extracted_values(value) do |str|
|
103
|
+
str.sub(/^\s*\/\//, '/*').gsub(/^\s*\/\//, ' *') + ' */'
|
104
|
+
end
|
105
|
+
else
|
106
|
+
value.unshift(@scanner.
|
107
|
+
string[0...@scanner.pos].
|
108
|
+
reverse[/.*?\*\/(.*?)($|\Z)/, 1].
|
109
|
+
reverse.gsub(/[^\s]/, ' '))
|
110
|
+
end
|
111
|
+
|
112
|
+
comment = Sass::Tree::CommentNode.new(value, silent, loud)
|
113
|
+
comment.line = line
|
100
114
|
node << comment
|
101
115
|
end
|
102
116
|
|
@@ -777,8 +791,14 @@ MESSAGE
|
|
777
791
|
end
|
778
792
|
|
779
793
|
def str?
|
794
|
+
pos = @scanner.pos
|
795
|
+
line = @line
|
780
796
|
@strs.push ""
|
781
797
|
yield && @strs.last
|
798
|
+
rescue Sass::SyntaxError => e
|
799
|
+
@scanner.pos = pos
|
800
|
+
@line = line
|
801
|
+
nil
|
782
802
|
ensure
|
783
803
|
@strs.pop
|
784
804
|
end
|
data/lib/sass/shared.rb
CHANGED
@@ -17,7 +17,7 @@ module Sass
|
|
17
17
|
# @return [String] The text remaining in the scanner after all `#{`s have been processed
|
18
18
|
def handle_interpolation(str)
|
19
19
|
scan = StringScanner.new(str)
|
20
|
-
yield scan while scan.scan(/(.*?)(\\*)\#\{/)
|
20
|
+
yield scan while scan.scan(/(.*?)(\\*)\#\{/m)
|
21
21
|
scan.rest
|
22
22
|
end
|
23
23
|
|
@@ -6,10 +6,19 @@ module Sass::Tree
|
|
6
6
|
# @see Sass::Tree
|
7
7
|
class CommentNode < Node
|
8
8
|
# The text of the comment, not including `/*` and `*/`.
|
9
|
+
# Interspersed with {Sass::Script::Node}s representing `#{}`-interpolation
|
10
|
+
# if this is a loud comment.
|
9
11
|
#
|
10
|
-
# @return [String]
|
12
|
+
# @return [Array<String, Sass::Script::Node>]
|
11
13
|
attr_accessor :value
|
12
14
|
|
15
|
+
# The text of the comment
|
16
|
+
# after any interpolated SassScript has been resolved.
|
17
|
+
# Only set once \{Tree::Visitors::Perform} has been run.
|
18
|
+
#
|
19
|
+
# @return [String]
|
20
|
+
attr_accessor :resolved_value
|
21
|
+
|
13
22
|
# Whether the comment is loud.
|
14
23
|
#
|
15
24
|
# Loud comments start with ! and force the comment to be generated
|
@@ -23,14 +32,13 @@ module Sass::Tree
|
|
23
32
|
# @return [Boolean]
|
24
33
|
attr_accessor :silent
|
25
34
|
|
26
|
-
# @param value [String] See \{#value}
|
35
|
+
# @param value [Array<String, Sass::Script::Node>] See \{#value}
|
27
36
|
# @param silent [Boolean] See \{#silent}
|
28
|
-
|
29
|
-
|
37
|
+
# @param loud [Boolean] See \{#loud}
|
38
|
+
def initialize(value, silent, loud)
|
39
|
+
@value = Sass::Util.with_extracted_values(value) {|str| normalize_indentation str}
|
30
40
|
@silent = silent
|
31
|
-
@
|
32
|
-
@loud = @value =~ %r{^(/[\/\*])?!}
|
33
|
-
@value.sub!("#{$1}!", $1.to_s) if @loud
|
41
|
+
@loud = loud
|
34
42
|
super()
|
35
43
|
end
|
36
44
|
|
@@ -40,7 +48,7 @@ module Sass::Tree
|
|
40
48
|
# @return [Boolean] Whether or not this node and the other object
|
41
49
|
# are the same
|
42
50
|
def ==(other)
|
43
|
-
self.class == other.class && value == other.value && silent == other.silent
|
51
|
+
self.class == other.class && value == other.value && silent == other.silent && loud == other.loud
|
44
52
|
end
|
45
53
|
|
46
54
|
# Returns `true` if this is a silent comment
|
@@ -57,9 +65,14 @@ module Sass::Tree
|
|
57
65
|
end
|
58
66
|
end
|
59
67
|
|
60
|
-
# Returns
|
61
|
-
|
62
|
-
|
68
|
+
# Returns the number of lines in the comment.
|
69
|
+
#
|
70
|
+
# @return [Fixnum]
|
71
|
+
def lines
|
72
|
+
@value.inject(0) do |s, e|
|
73
|
+
next s + e.count("\n") if e.is_a?(String)
|
74
|
+
next s
|
75
|
+
end
|
63
76
|
end
|
64
77
|
|
65
78
|
private
|
@@ -32,7 +32,7 @@ class Sass::Tree::Visitors::Convert < Sass::Tree::Visitors::Base
|
|
32
32
|
visit(child) +
|
33
33
|
if nxt &&
|
34
34
|
(child.is_a?(Sass::Tree::CommentNode) &&
|
35
|
-
child.line + child.
|
35
|
+
child.line + child.lines + 1 == nxt.line) ||
|
36
36
|
(child.is_a?(Sass::Tree::ImportNode) && nxt.is_a?(Sass::Tree::ImportNode) &&
|
37
37
|
child.line + 1 == nxt.line) ||
|
38
38
|
(child.is_a?(Sass::Tree::VariableNode) && nxt.is_a?(Sass::Tree::VariableNode) &&
|
@@ -49,8 +49,13 @@ class Sass::Tree::Visitors::Convert < Sass::Tree::Visitors::Base
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def visit_comment(node)
|
52
|
+
value = node.value.map do |r|
|
53
|
+
next r if r.is_a?(String)
|
54
|
+
"\#{#{r.to_sass(@options)}}"
|
55
|
+
end.join
|
56
|
+
|
52
57
|
content = if @format == :sass
|
53
|
-
content =
|
58
|
+
content = value.gsub(/\*\/$/, '').rstrip
|
54
59
|
if content =~ /\A[ \t]/
|
55
60
|
# Re-indent SCSS comments like this:
|
56
61
|
# /* foo
|
@@ -78,11 +83,11 @@ class Sass::Tree::Visitors::Convert < Sass::Tree::Visitors::Base
|
|
78
83
|
content.gsub!(/^/, tab_str)
|
79
84
|
content.rstrip + "\n"
|
80
85
|
else
|
81
|
-
spaces = (' ' * [@tabs -
|
86
|
+
spaces = (' ' * [@tabs - value[/^ */].size, 0].max)
|
82
87
|
content = if node.silent
|
83
|
-
|
88
|
+
value.gsub(/^[\/ ]\*/, '//').gsub(/ *\*\/$/, '')
|
84
89
|
else
|
85
|
-
|
90
|
+
value
|
86
91
|
end.gsub(/^/, spaces) + "\n"
|
87
92
|
content
|
88
93
|
end
|
@@ -53,12 +53,10 @@ class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
|
|
53
53
|
# Removes this node from the tree if it's a silent comment.
|
54
54
|
def visit_comment(node)
|
55
55
|
return [] if node.invisible?
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
node.value = run_interp([Sass::Script::String.new(node.value)])
|
61
|
-
end
|
56
|
+
check_for_loud_silent_comment node
|
57
|
+
check_for_comment_interp node
|
58
|
+
node.resolved_value = run_interp_no_strip(node.value)
|
59
|
+
node.resolved_value.gsub!(/\\([\\#])/, '\1')
|
62
60
|
node
|
63
61
|
end
|
64
62
|
|
@@ -278,14 +276,18 @@ END
|
|
278
276
|
|
279
277
|
private
|
280
278
|
|
281
|
-
def
|
279
|
+
def run_interp_no_strip(text)
|
282
280
|
text.map do |r|
|
283
281
|
next r if r.is_a?(String)
|
284
282
|
val = r.perform(@environment)
|
285
283
|
# Interpolated strings should never render with quotes
|
286
284
|
next val.value if val.is_a?(Sass::Script::String)
|
287
285
|
val.to_s
|
288
|
-
end.join
|
286
|
+
end.join
|
287
|
+
end
|
288
|
+
|
289
|
+
def run_interp(text)
|
290
|
+
run_interp_no_strip(text).strip
|
289
291
|
end
|
290
292
|
|
291
293
|
def handle_include_loop!(node)
|
@@ -301,4 +303,30 @@ END
|
|
301
303
|
end.join("\n")
|
302
304
|
raise Sass::SyntaxError.new(msg)
|
303
305
|
end
|
306
|
+
|
307
|
+
def check_for_loud_silent_comment(node)
|
308
|
+
return unless node.loud && node.silent
|
309
|
+
Sass::Util.sass_warn <<MESSAGE
|
310
|
+
WARNING:
|
311
|
+
On line #{node.line}#{" of '#{node.filename}'" if node.filename}
|
312
|
+
`//` comments will no longer be allowed to use the `!` flag in Sass 3.2.
|
313
|
+
Please change to `/*` comments.
|
314
|
+
MESSAGE
|
315
|
+
end
|
316
|
+
|
317
|
+
def check_for_comment_interp(node)
|
318
|
+
return if node.loud
|
319
|
+
node.value.each do |e|
|
320
|
+
next unless e.is_a?(String)
|
321
|
+
e.scan(/(\\*)#\{/) do |esc|
|
322
|
+
Sass::Util.sass_warn <<MESSAGE if esc.first.size.even?
|
323
|
+
WARNING:
|
324
|
+
On line #{node.line}#{" of '#{node.filename}'" if node.filename}
|
325
|
+
Comments will evaluate the contents of interpolations (\#{ ... }) in Sass 3.2.
|
326
|
+
Please escape the interpolation by adding a backslash before the `#`.
|
327
|
+
MESSAGE
|
328
|
+
return
|
329
|
+
end
|
330
|
+
end
|
331
|
+
end
|
304
332
|
end
|
@@ -57,21 +57,11 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
|
|
57
57
|
|
58
58
|
def visit_comment(node)
|
59
59
|
return if node.invisible?
|
60
|
-
spaces = (' ' * [@tabs - node.
|
60
|
+
spaces = (' ' * [@tabs - node.resolved_value[/^ */].size, 0].max)
|
61
61
|
|
62
|
-
content = node.
|
62
|
+
content = node.resolved_value.gsub(/^/, spaces).gsub(%r{^(\s*)//(.*)$}) do |md|
|
63
63
|
"#{$1}/*#{$2} */"
|
64
64
|
end
|
65
|
-
if content =~ /[^\\]\#\{.*\}/
|
66
|
-
Sass::Util.sass_warn <<MESSAGE
|
67
|
-
WARNING:
|
68
|
-
On line #{node.line}#{" of '#{node.filename}'" if node.filename}
|
69
|
-
Comments will evaluate the contents of interpolations (\#{ ... }) in Sass 3.2.
|
70
|
-
Please escape the interpolation by adding a backslash before the hash sign.
|
71
|
-
MESSAGE
|
72
|
-
elsif content =~ /\\\#\{.*\}/
|
73
|
-
content.gsub!(/\\(\#\{.*\})/, '\1')
|
74
|
-
end
|
75
65
|
content.gsub!(/\n +(\* *(?!\/))?/, ' ') if (node.style == :compact || node.style == :compressed) && !node.loud
|
76
66
|
content
|
77
67
|
end
|
data/lib/sass/util.rb
CHANGED
@@ -612,6 +612,57 @@ MSG
|
|
612
612
|
'"' + obj.gsub(/[\x00-\x7F]+/) {|s| s.inspect[1...-1]} + '"'
|
613
613
|
end
|
614
614
|
|
615
|
+
# Extracts the non-string vlaues from an array containing both strings and non-strings.
|
616
|
+
# These values are replaced with escape sequences.
|
617
|
+
# This can be undone using \{#inject\_values}.
|
618
|
+
#
|
619
|
+
# This is useful e.g. when we want to do string manipulation
|
620
|
+
# on an interpolated string.
|
621
|
+
#
|
622
|
+
# The precise format of the resulting string is not guaranteed.
|
623
|
+
# However, it is guaranteed that newlines and whitespace won't be affected.
|
624
|
+
#
|
625
|
+
# @param arr [Array] The array from which values are extracted.
|
626
|
+
# @return [(String, Array)] The resulting string, and an array of extracted values.
|
627
|
+
def extract_values(arr)
|
628
|
+
values = []
|
629
|
+
return arr.map do |e|
|
630
|
+
next e.gsub('{', '{{') if e.is_a?(String)
|
631
|
+
values << e
|
632
|
+
next "{#{values.count - 1}}"
|
633
|
+
end.join, values
|
634
|
+
end
|
635
|
+
|
636
|
+
# Undoes \{#extract\_values} by transforming a string with escape sequences
|
637
|
+
# into an array of strings and non-string values.
|
638
|
+
#
|
639
|
+
# @param str [String] The string with escape sequences.
|
640
|
+
# @param values [Array] The array of values to inject.
|
641
|
+
# @return [Array] The array of strings and values.
|
642
|
+
def inject_values(str, values)
|
643
|
+
return [str.gsub('{{', '{')] if values.empty?
|
644
|
+
# Add an extra { so that we process the tail end of the string
|
645
|
+
result = (str + '{{').scan(/(.*?)(?:(\{\{)|\{(\d+)\})/m).map do |(pre, esc, n)|
|
646
|
+
[pre, esc ? '{' : '', n ? values[n.to_i] : '']
|
647
|
+
end.flatten(1)
|
648
|
+
result[-2] = '' # Get rid of the extra {
|
649
|
+
merge_adjacent_strings(result).reject {|s| s == ''}
|
650
|
+
end
|
651
|
+
|
652
|
+
# Allows modifications to be performed on the string form
|
653
|
+
# of an array containing both strings and non-strings.
|
654
|
+
#
|
655
|
+
# @param arr [Array] The array from which values are extracted.
|
656
|
+
# @yield [str] A block in which string manipulation can be done to the array.
|
657
|
+
# @yieldparam str [String] The string form of `arr`.
|
658
|
+
# @yieldreturn [String] The modified string.
|
659
|
+
# @return [Array] The modified, interpolated array.
|
660
|
+
def with_extracted_values(arr)
|
661
|
+
str, vals = extract_values(arr)
|
662
|
+
str = yield str
|
663
|
+
inject_values(str, vals)
|
664
|
+
end
|
665
|
+
|
615
666
|
## Static Method Stuff
|
616
667
|
|
617
668
|
# The context in which the ERB for \{#def\_static\_method} will be run.
|
@@ -1131,17 +1131,13 @@ div
|
|
1131
1131
|
SASS
|
1132
1132
|
end
|
1133
1133
|
|
1134
|
-
|
1134
|
+
def test_loud_comment_conversion
|
1135
1135
|
assert_renders(<<SASS, <<SCSS)
|
1136
1136
|
/*! \#{"interpolated"}
|
1137
|
-
/*!
|
1138
|
-
* \#{"also interpolated"}
|
1139
1137
|
SASS
|
1140
1138
|
/*! \#{"interpolated"} */
|
1141
|
-
/*!
|
1142
|
-
* \#{"also interpolated"} */
|
1143
1139
|
SCSS
|
1144
|
-
assert_renders(<<SASS, <<SCSS)
|
1140
|
+
silence_warnings {assert_renders(<<SASS, <<SCSS)}
|
1145
1141
|
//! \#{"interpolated"}
|
1146
1142
|
//!
|
1147
1143
|
//! \#{"also interpolated"}
|
data/test/sass/engine_test.rb
CHANGED
@@ -1570,11 +1570,11 @@ foo
|
|
1570
1570
|
*/
|
1571
1571
|
SASS
|
1572
1572
|
end
|
1573
|
+
|
1573
1574
|
def test_loud_comment_in_silent_comment
|
1574
|
-
assert_equal <<CSS, render(<<SASS, :style => :compressed)
|
1575
|
+
silence_warnings {assert_equal <<CSS, render(<<SASS, :style => :compressed)}
|
1575
1576
|
foo{color:blue;/* foo */
|
1576
1577
|
/* bar */
|
1577
|
-
/* */
|
1578
1578
|
/* bip */
|
1579
1579
|
/* baz */}
|
1580
1580
|
CSS
|
@@ -1590,8 +1590,7 @@ SASS
|
|
1590
1590
|
|
1591
1591
|
def test_loud_comment_is_evaluated
|
1592
1592
|
assert_equal <<CSS, render(<<SASS)
|
1593
|
-
/*
|
1594
|
-
* Hue: 327.216deg */
|
1593
|
+
/* Hue: 327.216deg */
|
1595
1594
|
CSS
|
1596
1595
|
/*!
|
1597
1596
|
Hue: \#{hue(#f836a0)}
|
@@ -2030,6 +2029,31 @@ CSS
|
|
2030
2029
|
|
2031
2030
|
# Regression tests
|
2032
2031
|
|
2032
|
+
def test_interpolated_comment_in_mixin
|
2033
|
+
assert_equal <<CSS, render(<<SASS)
|
2034
|
+
/* color: red */
|
2035
|
+
.foo {
|
2036
|
+
color: red; }
|
2037
|
+
|
2038
|
+
/* color: blue */
|
2039
|
+
.foo {
|
2040
|
+
color: blue; }
|
2041
|
+
|
2042
|
+
/* color: green */
|
2043
|
+
.foo {
|
2044
|
+
color: green; }
|
2045
|
+
CSS
|
2046
|
+
=foo($var)
|
2047
|
+
/*! color: \#{$var}
|
2048
|
+
.foo
|
2049
|
+
color: $var
|
2050
|
+
|
2051
|
+
+foo(red)
|
2052
|
+
+foo(blue)
|
2053
|
+
+foo(green)
|
2054
|
+
SASS
|
2055
|
+
end
|
2056
|
+
|
2033
2057
|
def test_parens_in_mixins
|
2034
2058
|
assert_equal(<<CSS, render(<<SASS))
|
2035
2059
|
.foo {
|
@@ -2308,7 +2332,16 @@ SASS
|
|
2308
2332
|
WARNING:
|
2309
2333
|
On line 1 of 'test_comment_interpolation_warning_inline.sass'
|
2310
2334
|
Comments will evaluate the contents of interpolations (\#{ ... }) in Sass 3.2.
|
2311
|
-
Please escape the interpolation by adding a backslash before the
|
2335
|
+
Please escape the interpolation by adding a backslash before the `#`.
|
2336
|
+
END
|
2337
|
+
end
|
2338
|
+
|
2339
|
+
def test_loud_silent_comment_warning
|
2340
|
+
assert_warning(<<END) {render("//! \#{foo}")}
|
2341
|
+
WARNING:
|
2342
|
+
On line 1 of 'test_loud_silent_comment_warning_inline.sass'
|
2343
|
+
`//` comments will no longer be allowed to use the `!` flag in Sass 3.2.
|
2344
|
+
Please change to `/*` comments.
|
2312
2345
|
END
|
2313
2346
|
end
|
2314
2347
|
|
data/test/sass/scss/css_test.rb
CHANGED
@@ -800,6 +800,12 @@ SCSS
|
|
800
800
|
assert_selector_parses('E*:hover')
|
801
801
|
end
|
802
802
|
|
803
|
+
def test_spaceless_combo_selectors
|
804
|
+
assert_equal "E > F {\n a: b; }\n", render("E>F { a: b;} ")
|
805
|
+
assert_equal "E ~ F {\n a: b; }\n", render("E~F { a: b;} ")
|
806
|
+
assert_equal "E + F {\n a: b; }\n", render("E+F { a: b;} ")
|
807
|
+
end
|
808
|
+
|
803
809
|
## Errors
|
804
810
|
|
805
811
|
def test_invalid_directives
|
data/test/sass/util_test.rb
CHANGED
@@ -208,6 +208,18 @@ class UtilTest < Test::Unit::TestCase
|
|
208
208
|
assert(set_eql?(s1, s2))
|
209
209
|
end
|
210
210
|
|
211
|
+
def test_extract_and_inject_values
|
212
|
+
test = lambda {|arr| assert_equal(arr, with_extracted_values(arr) {|str| str})}
|
213
|
+
|
214
|
+
test[['foo bar']]
|
215
|
+
test[['foo {12} bar']]
|
216
|
+
test[['foo {{12} bar']]
|
217
|
+
test[['foo {{1', 12, '2} bar']]
|
218
|
+
test[['foo 1', 2, '{3', 4, 5, 6, '{7}', 8]]
|
219
|
+
test[['foo 1', [2, 3, 4], ' bar']]
|
220
|
+
test[['foo ', 1, "\n bar\n", [2, 3, 4], "\n baz"]]
|
221
|
+
end
|
222
|
+
|
211
223
|
def test_caller_info
|
212
224
|
assert_equal(["/tmp/foo.rb", 12, "fizzle"], caller_info("/tmp/foo.rb:12: in `fizzle'"))
|
213
225
|
assert_equal(["/tmp/foo.rb", 12, nil], caller_info("/tmp/foo.rb:12"))
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sass
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 17
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 3
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 3.1.
|
9
|
+
- 9
|
10
|
+
version: 3.1.9
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Nathan Weizenbaum
|
@@ -17,7 +17,7 @@ autorequire:
|
|
17
17
|
bindir: bin
|
18
18
|
cert_chain: []
|
19
19
|
|
20
|
-
date: 2011-
|
20
|
+
date: 2011-10-06 00:00:00 -07:00
|
21
21
|
default_executable:
|
22
22
|
dependencies:
|
23
23
|
- !ruby/object:Gem::Dependency
|