sass 3.3.0.alpha.121 → 3.3.0.alpha.127
Sign up to get free protection for your applications and to get access to all the features.
- data/REVISION +1 -1
- data/VERSION +1 -1
- data/VERSION_DATE +1 -1
- data/lib/sass/cache_stores/base.rb +2 -0
- data/lib/sass/exec.rb +16 -9
- data/lib/sass/script/funcall.rb +9 -3
- data/lib/sass/script/functions.rb +29 -4
- data/lib/sass/script/literal.rb +0 -18
- data/lib/sass/script/parser.rb +4 -4
- data/lib/sass/script/string.rb +1 -1
- data/lib/sass/scss/parser.rb +1 -1
- data/lib/sass/tree/visitors/convert.rb +9 -3
- data/test/sass/conversion_test.rb +24 -0
- data/test/sass/functions_test.rb +10 -0
- data/test/sass/script_test.rb +1 -0
- data/test/sass/scss/css_test.rb +11 -0
- metadata +4 -4
data/REVISION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
37a46f42d51efbb1bb31d4b35c92442d2bed1b98
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.3.0.alpha.
|
1
|
+
3.3.0.alpha.127
|
data/VERSION_DATE
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
18 April 2013 00:24:47 GMT
|
@@ -51,6 +51,7 @@ module Sass
|
|
51
51
|
_store(key, Sass::VERSION, sha, Marshal.dump(root))
|
52
52
|
rescue TypeError, LoadError => e
|
53
53
|
Sass::Util.sass_warn "Warning. Error encountered while saving cache #{path_to(key)}: #{e}"
|
54
|
+
nil
|
54
55
|
end
|
55
56
|
|
56
57
|
# Retrieve a {Sass::Tree::RootNode}.
|
@@ -63,6 +64,7 @@ module Sass
|
|
63
64
|
Marshal.load(contents) if contents
|
64
65
|
rescue EOFError, TypeError, ArgumentError, LoadError => e
|
65
66
|
Sass::Util.sass_warn "Warning. Error encountered while reading cache #{path_to(key)}: #{e}"
|
67
|
+
nil
|
66
68
|
end
|
67
69
|
|
68
70
|
# Return the key for the sass file.
|
data/lib/sass/exec.rb
CHANGED
@@ -110,11 +110,10 @@ module Sass
|
|
110
110
|
open_file(filename) || $stdin
|
111
111
|
end
|
112
112
|
@options[:output_filename] = args.shift
|
113
|
-
output ||=
|
113
|
+
output ||= @options[:output_filename] || $stdout
|
114
114
|
|
115
115
|
if @options[:sourcemap] && @options[:output_filename]
|
116
116
|
@options[:sourcemap_filename] = Util::sourcemap_name(@options[:output_filename])
|
117
|
-
@options[:sourcemap] = open_file(@options[:sourcemap_filename], 'w')
|
118
117
|
end
|
119
118
|
|
120
119
|
@options[:input], @options[:output] = input, output
|
@@ -162,6 +161,14 @@ module Sass
|
|
162
161
|
return "\e[#{COLORS[color]}m#{str}\e[0m"
|
163
162
|
end
|
164
163
|
|
164
|
+
def write_output(text, destination)
|
165
|
+
if destination.is_a?(String)
|
166
|
+
File.open(destination, 'w') {|file| file.write(text)}
|
167
|
+
else
|
168
|
+
destination.write(text)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
165
172
|
private
|
166
173
|
|
167
174
|
def open_file(filename, flag = 'r')
|
@@ -317,7 +324,7 @@ END
|
|
317
324
|
return watch_or_update if @options[:watch] || @options[:update]
|
318
325
|
super
|
319
326
|
@options[:for_engine][:filename] = @options[:filename]
|
320
|
-
@options[:for_engine][:css_filename] = @options[:output]
|
327
|
+
@options[:for_engine][:css_filename] = @options[:output] if @options[:output].is_a?(String)
|
321
328
|
|
322
329
|
begin
|
323
330
|
input = @options[:input]
|
@@ -342,12 +349,13 @@ END
|
|
342
349
|
relative_sourcemap_path = Pathname.new(@options[:sourcemap_filename]).
|
343
350
|
relative_path_from(Pathname.new(@options[:output_filename]).dirname)
|
344
351
|
rendered, mapping = engine.render_with_sourcemap(relative_sourcemap_path.to_s)
|
345
|
-
|
346
|
-
|
352
|
+
write_output(rendered, output)
|
353
|
+
write_output(mapping.to_json(
|
347
354
|
:css_path => @options[:output_filename],
|
348
|
-
:sourcemap_path => @options[:sourcemap_filename])
|
355
|
+
:sourcemap_path => @options[:sourcemap_filename]) + "\n",
|
356
|
+
@options[:sourcemap_filename])
|
349
357
|
else
|
350
|
-
|
358
|
+
write_output(engine.render, output)
|
351
359
|
end
|
352
360
|
rescue ::Sass::SyntaxError => e
|
353
361
|
raise e if @options[:trace]
|
@@ -664,7 +672,6 @@ END
|
|
664
672
|
end
|
665
673
|
|
666
674
|
input = open_file(f)
|
667
|
-
output = @options[:in_place] ? input : open_file(output, "w")
|
668
675
|
process_file(input, output)
|
669
676
|
end
|
670
677
|
end
|
@@ -709,7 +716,7 @@ END
|
|
709
716
|
end
|
710
717
|
|
711
718
|
output = File.open(input.path, 'w') if @options[:in_place]
|
712
|
-
|
719
|
+
write_output(out, output)
|
713
720
|
rescue ::Sass::SyntaxError => e
|
714
721
|
raise e if @options[:trace]
|
715
722
|
file = " of #{e.sass_filename}" if e.sass_filename
|
data/lib/sass/script/funcall.rb
CHANGED
@@ -54,12 +54,18 @@ module Sass
|
|
54
54
|
|
55
55
|
# @see Node#to_sass
|
56
56
|
def to_sass(opts = {})
|
57
|
-
|
57
|
+
arg_to_sass = lambda do |arg|
|
58
|
+
sass = arg.to_sass(opts)
|
59
|
+
sass = "(#{sass})" if arg.is_a?(Sass::Script::List) && arg.separator == :comma
|
60
|
+
sass
|
61
|
+
end
|
62
|
+
|
63
|
+
args = @args.map(&arg_to_sass).join(', ')
|
58
64
|
keywords = Sass::Util.hash_to_a(@keywords).
|
59
|
-
map {|k, v| "$#{dasherize(k, opts)}: #{v
|
65
|
+
map {|k, v| "$#{dasherize(k, opts)}: #{arg_to_sass[v]}"}.join(', ')
|
60
66
|
if self.splat
|
61
67
|
splat = (args.empty? && keywords.empty?) ? "" : ", "
|
62
|
-
splat = "#{splat}#{self.splat
|
68
|
+
splat = "#{splat}#{arg_to_sass[self.splat]}..."
|
63
69
|
end
|
64
70
|
"#{dasherize(name, opts)}(#{args}#{', ' unless args.empty? || keywords.empty?}#{keywords}#{splat})"
|
65
71
|
end
|
@@ -165,6 +165,15 @@ module Sass::Script
|
|
165
165
|
# \{#append append($list1, $val, \[$separator\])}
|
166
166
|
# : Appends a single value onto the end of a list.
|
167
167
|
#
|
168
|
+
# \{#zip zip($list1, $list2, ...)}
|
169
|
+
# : Combines several lists into a single multidimensional list.
|
170
|
+
#
|
171
|
+
# \{#index index($list, $value)}
|
172
|
+
# : Returns the position of a value within a list, or false.
|
173
|
+
#
|
174
|
+
# \{#list-separator list-separator(#list)}
|
175
|
+
# : Returns the separator of a list.
|
176
|
+
#
|
168
177
|
# ## Introspection Functions
|
169
178
|
#
|
170
179
|
# \{#type_of type-of($value)}
|
@@ -1555,8 +1564,8 @@ module Sass::Script
|
|
1555
1564
|
declare :append, [:list, :val]
|
1556
1565
|
declare :append, [:list, :val, :separator]
|
1557
1566
|
|
1558
|
-
# Combines several lists into a single comma separated list
|
1559
|
-
# space separated lists.
|
1567
|
+
# Combines several lists into a single comma separated list, where the nth
|
1568
|
+
# value is a space separated list of the source lists' nth values.
|
1560
1569
|
#
|
1561
1570
|
# The length of the resulting list is the length of the
|
1562
1571
|
# shortest list.
|
@@ -1581,8 +1590,8 @@ module Sass::Script
|
|
1581
1590
|
declare :zip, [], :var_args => true
|
1582
1591
|
|
1583
1592
|
|
1584
|
-
# Returns the position of
|
1585
|
-
#
|
1593
|
+
# Returns the position of a value within a list. If not found, returns
|
1594
|
+
# false.
|
1586
1595
|
#
|
1587
1596
|
# @example
|
1588
1597
|
# index(1px solid red, solid) => 2
|
@@ -1597,6 +1606,22 @@ module Sass::Script
|
|
1597
1606
|
end
|
1598
1607
|
declare :index, [:list, :value]
|
1599
1608
|
|
1609
|
+
# Returns the separator of the given list.
|
1610
|
+
# If not a list, returns false.
|
1611
|
+
#
|
1612
|
+
# @example
|
1613
|
+
# list-separator(1px 2px 3px) => 'space'
|
1614
|
+
# list-separator(1px, 2px, 3px) => 'comma'
|
1615
|
+
# list-separator('foo') => 'space'
|
1616
|
+
def list_separator(list)
|
1617
|
+
if list.class == Sass::Script::List
|
1618
|
+
String.new(list.separator.to_s)
|
1619
|
+
else
|
1620
|
+
String.new('space')
|
1621
|
+
end
|
1622
|
+
end
|
1623
|
+
declare :separator, [:list]
|
1624
|
+
|
1600
1625
|
# Returns one of two values based on the truth value of the first argument.
|
1601
1626
|
#
|
1602
1627
|
# @example
|
data/lib/sass/script/literal.rb
CHANGED
@@ -90,24 +90,6 @@ MSG
|
|
90
90
|
Sass::Script::Bool.new(!to_bool)
|
91
91
|
end
|
92
92
|
|
93
|
-
# The SassScript default operation (e.g. `$a $b`, `"foo" "bar"`).
|
94
|
-
#
|
95
|
-
# @param other [Literal] The right-hand side of the operator
|
96
|
-
# @return [Script::String] A string containing both literals
|
97
|
-
# separated by a space
|
98
|
-
def space(other)
|
99
|
-
Sass::Script::String.new("#{self.to_s} #{other.to_s}")
|
100
|
-
end
|
101
|
-
|
102
|
-
# The SassScript `,` operation (e.g. `$a, $b`, `"foo", "bar"`).
|
103
|
-
#
|
104
|
-
# @param other [Literal] The right-hand side of the operator
|
105
|
-
# @return [Script::String] A string containing both literals
|
106
|
-
# separated by `", "`
|
107
|
-
def comma(other)
|
108
|
-
Sass::Script::String.new("#{self.to_s},#{' ' unless options[:style] == :compressed}#{other.to_s}")
|
109
|
-
end
|
110
|
-
|
111
93
|
# The SassScript `=` operation
|
112
94
|
# (used for proprietary MS syntax like `alpha(opacity=20)`).
|
113
95
|
#
|
data/lib/sass/script/parser.rb
CHANGED
@@ -269,15 +269,15 @@ RUBY
|
|
269
269
|
interp = try_ops_after_interp([:comma], :expr) and return interp
|
270
270
|
start_pos = source_position
|
271
271
|
return unless e = interpolation
|
272
|
-
|
272
|
+
list = node(List.new([e], :comma), start_pos)
|
273
273
|
while tok = try_tok(:comma)
|
274
|
-
if interp = try_op_before_interp(tok,
|
274
|
+
if interp = try_op_before_interp(tok, list)
|
275
275
|
return interp unless other_interp = try_ops_after_interp([:comma], :expr, interp)
|
276
276
|
return other_interp
|
277
277
|
end
|
278
|
-
|
278
|
+
list.value << assert_expr(:interpolation)
|
279
279
|
end
|
280
|
-
|
280
|
+
list.value.size == 1 ? list.value.first : list
|
281
281
|
end
|
282
282
|
|
283
283
|
production :equals, :interpolation, :single_eq
|
data/lib/sass/script/string.rb
CHANGED
data/lib/sass/scss/parser.rb
CHANGED
@@ -195,13 +195,19 @@ class Sass::Tree::Visitors::Convert < Sass::Tree::Visitors::Base
|
|
195
195
|
end
|
196
196
|
|
197
197
|
def visit_mixin(node)
|
198
|
+
arg_to_sass = lambda do |arg|
|
199
|
+
sass = arg.to_sass(@options)
|
200
|
+
sass = "(#{sass})" if arg.is_a?(Sass::Script::List) && arg.separator == :comma
|
201
|
+
sass
|
202
|
+
end
|
203
|
+
|
198
204
|
unless node.args.empty? && node.keywords.empty? && node.splat.nil?
|
199
|
-
args = node.args.map
|
205
|
+
args = node.args.map(&arg_to_sass).join(", ")
|
200
206
|
keywords = Sass::Util.hash_to_a(node.keywords).
|
201
|
-
map {|k, v| "$#{dasherize(k)}: #{v
|
207
|
+
map {|k, v| "$#{dasherize(k)}: #{arg_to_sass[v]}"}.join(', ')
|
202
208
|
if node.splat
|
203
209
|
splat = (args.empty? && keywords.empty?) ? "" : ", "
|
204
|
-
splat = "#{splat}#{node.splat
|
210
|
+
splat = "#{splat}#{arg_to_sass[node.splat]}..."
|
205
211
|
end
|
206
212
|
arglist = "(#{args}#{', ' unless args.empty? || keywords.empty?}#{keywords}#{splat})"
|
207
213
|
end
|
@@ -1618,6 +1618,30 @@ SCSS
|
|
1618
1618
|
|
1619
1619
|
## Regression Tests
|
1620
1620
|
|
1621
|
+
def test_list_in_args
|
1622
|
+
assert_renders(<<SASS, <<SCSS)
|
1623
|
+
$foo: foo((a, b, c))
|
1624
|
+
$foo: foo($arg: (a, b, c))
|
1625
|
+
$foo: foo(a, b, (c, d, e)...)
|
1626
|
+
|
1627
|
+
+mixin((a, b, c))
|
1628
|
+
|
1629
|
+
+mixin($arg: (a, b, c))
|
1630
|
+
|
1631
|
+
+mixin(a, b, (c, d, e)...)
|
1632
|
+
SASS
|
1633
|
+
$foo: foo((a, b, c));
|
1634
|
+
$foo: foo($arg: (a, b, c));
|
1635
|
+
$foo: foo(a, b, (c, d, e)...);
|
1636
|
+
|
1637
|
+
@include mixin((a, b, c));
|
1638
|
+
|
1639
|
+
@include mixin($arg: (a, b, c));
|
1640
|
+
|
1641
|
+
@include mixin(a, b, (c, d, e)...);
|
1642
|
+
SCSS
|
1643
|
+
end
|
1644
|
+
|
1621
1645
|
def test_media_query_with_expr
|
1622
1646
|
assert_scss_to_sass <<SASS, <<SCSS
|
1623
1647
|
@media foo and (bar: baz)
|
data/test/sass/functions_test.rb
CHANGED
@@ -1116,6 +1116,16 @@ MSG
|
|
1116
1116
|
assert_equal("false", evaluate("index(1px, #00f)"))
|
1117
1117
|
end
|
1118
1118
|
|
1119
|
+
def test_list_separator
|
1120
|
+
assert_equal("space", evaluate("list-separator(1 2 3 4 5)"))
|
1121
|
+
assert_equal("comma", evaluate("list-separator((foo, bar, baz, bip))"))
|
1122
|
+
assert_equal("comma", evaluate("list-separator((foo, bar, baz bip))"))
|
1123
|
+
assert_equal("comma", evaluate("list-separator((foo, bar, (baz, bip)))"))
|
1124
|
+
assert_equal("space", evaluate("list-separator(#f00)"))
|
1125
|
+
assert_equal("space", evaluate("list-separator(())"))
|
1126
|
+
assert_equal("space", evaluate("list-separator(1 2 () 3)"))
|
1127
|
+
end
|
1128
|
+
|
1119
1129
|
def test_if
|
1120
1130
|
assert_equal("1px", evaluate("if(true, 1px, 2px)"))
|
1121
1131
|
assert_equal("2px", evaluate("if(false, 1px, 2px)"))
|
data/test/sass/script_test.rb
CHANGED
@@ -134,6 +134,7 @@ class SassScriptTest < Test::Unit::TestCase
|
|
134
134
|
assert_equal '3,7', resolve('#{1 + 2},#{3 + 4}')
|
135
135
|
assert_equal '3, 7, 11', resolve('#{1 + 2}, #{3 + 4}, #{5 + 6}')
|
136
136
|
assert_equal '3, 7, 11', resolve('3, #{3 + 4}, 11')
|
137
|
+
assert_equal '3, 7, 11', resolve('3, 7, #{5 + 6}')
|
137
138
|
|
138
139
|
assert_equal '3 / 7', resolve('3 / #{3 + 4}')
|
139
140
|
assert_equal '3 /7', resolve('3 /#{3 + 4}')
|
data/test/sass/scss/css_test.rb
CHANGED
@@ -1011,6 +1011,17 @@ SCSS
|
|
1011
1011
|
|
1012
1012
|
## Regressions
|
1013
1013
|
|
1014
|
+
def test_double_space_string
|
1015
|
+
assert_equal(<<CSS, render(<<SCSS))
|
1016
|
+
.a {
|
1017
|
+
content: " a"; }
|
1018
|
+
CSS
|
1019
|
+
.a {
|
1020
|
+
content: " a";
|
1021
|
+
}
|
1022
|
+
SCSS
|
1023
|
+
end
|
1024
|
+
|
1014
1025
|
def test_very_long_number_with_important_doesnt_take_forever
|
1015
1026
|
assert_equal(<<CSS, render(<<SCSS))
|
1016
1027
|
.foo {
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sass
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 592303091
|
5
5
|
prerelease: 6
|
6
6
|
segments:
|
7
7
|
- 3
|
8
8
|
- 3
|
9
9
|
- 0
|
10
10
|
- alpha
|
11
|
-
-
|
12
|
-
version: 3.3.0.alpha.
|
11
|
+
- 127
|
12
|
+
version: 3.3.0.alpha.127
|
13
13
|
platform: ruby
|
14
14
|
authors:
|
15
15
|
- Nathan Weizenbaum
|
@@ -19,7 +19,7 @@ autorequire:
|
|
19
19
|
bindir: bin
|
20
20
|
cert_chain: []
|
21
21
|
|
22
|
-
date: 2013-
|
22
|
+
date: 2013-04-17 00:00:00 -04:00
|
23
23
|
default_executable:
|
24
24
|
dependencies:
|
25
25
|
- !ruby/object:Gem::Dependency
|