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 CHANGED
@@ -1 +1 @@
1
- d561c91ec63d2793e1ea0b9f571d18e2db83a65b
1
+ 37a46f42d51efbb1bb31d4b35c92442d2bed1b98
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.3.0.alpha.121
1
+ 3.3.0.alpha.127
@@ -1 +1 @@
1
- 23 March 2013 00:34:47 GMT
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.
@@ -110,11 +110,10 @@ module Sass
110
110
  open_file(filename) || $stdin
111
111
  end
112
112
  @options[:output_filename] = args.shift
113
- output ||= open_file(@options[:output_filename], 'w') || $stdout
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].path if @options[:output].is_a?(File)
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
- output.write(rendered)
346
- sourcemap.puts(mapping.to_json(
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
- output.write(engine.render)
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
- output.write(out)
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
@@ -54,12 +54,18 @@ module Sass
54
54
 
55
55
  # @see Node#to_sass
56
56
  def to_sass(opts = {})
57
- args = @args.map {|a| a.to_sass(opts)}.join(', ')
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.to_sass(opts)}"}.join(', ')
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.inspect}..."
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 the given value within the given
1585
- # list. If not found, returns false.
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
@@ -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
  #
@@ -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
- arr = [e]
272
+ list = node(List.new([e], :comma), start_pos)
273
273
  while tok = try_tok(:comma)
274
- if interp = try_op_before_interp(tok, e)
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
- arr << assert_expr(:interpolation)
278
+ list.value << assert_expr(:interpolation)
279
279
  end
280
- arr.size == 1 ? arr.first : node(List.new(arr, :comma), start_pos)
280
+ list.value.size == 1 ? list.value.first : list
281
281
  end
282
282
 
283
283
  production :equals, :interpolation, :single_eq
@@ -31,7 +31,7 @@ module Sass::Script
31
31
  # @see Node#to_s
32
32
  def to_s(opts = {})
33
33
  if @type == :identifier
34
- return @value.gsub(/\s+/, " ")
34
+ return @value.gsub(/\n\s*/, " ")
35
35
  end
36
36
 
37
37
  return "\"#{value.gsub('"', "\\\"")}\"" if opts[:quote] == %q{"}
@@ -1151,7 +1151,7 @@ MESSAGE
1151
1151
  end
1152
1152
 
1153
1153
  def rethrow(err)
1154
- if @throw_err
1154
+ if @throw_error
1155
1155
  throw :_sass_parser_error, err
1156
1156
  else
1157
1157
  @scanner = Sass::Util::MultibyteStringScanner.new(@scanner.string)
@@ -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 {|a| a.to_sass(@options)}.join(", ")
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.to_sass(@options)}"}.join(', ')
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.to_sass(@options)}..."
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)
@@ -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)"))
@@ -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}')
@@ -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: 592303103
4
+ hash: 592303091
5
5
  prerelease: 6
6
6
  segments:
7
7
  - 3
8
8
  - 3
9
9
  - 0
10
10
  - alpha
11
- - 121
12
- version: 3.3.0.alpha.121
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-03-22 00:00:00 -04:00
22
+ date: 2013-04-17 00:00:00 -04:00
23
23
  default_executable:
24
24
  dependencies:
25
25
  - !ruby/object:Gem::Dependency