sass 3.3.0.alpha.121 → 3.3.0.alpha.127

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/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