haml 3.0.22 → 3.0.23

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 CHANGED
@@ -1 +1 @@
1
- 3.0.22
1
+ 3.0.23
@@ -155,7 +155,7 @@ module Haml
155
155
  end
156
156
 
157
157
  def handle_load_error(err)
158
- dep = err.message.scan(/^no such file to load -- (.*)/)[0]
158
+ dep = err.message[/^no such file to load -- (.*)/, 1]
159
159
  raise err if @options[:trace] || dep.nil? || dep.empty?
160
160
  $stderr.puts <<MESSAGE
161
161
  Required dependency #{dep} not found!
@@ -118,8 +118,8 @@ END
118
118
 
119
119
  names.map do |name|
120
120
  # Can't use || because someone might explicitly pass in false with a symbol
121
- sym_local = "_haml_locals[#{inspect(name.to_sym)}]"
122
- str_local = "_haml_locals[#{inspect(name.to_s)}]"
121
+ sym_local = "_haml_locals[#{inspect_obj(name.to_sym)}]"
122
+ str_local = "_haml_locals[#{inspect_obj(name.to_s)}]"
123
123
  "#{name} = #{sym_local}.nil? ? #{str_local} : #{sym_local}"
124
124
  end.join(';') + ';'
125
125
  end
@@ -320,7 +320,7 @@ END
320
320
  @to_merge.each do |type, val, tabs|
321
321
  case type
322
322
  when :text
323
- str << inspect(val)[1...-1]
323
+ str << inspect_obj(val)[1...-1]
324
324
  mtabs += tabs
325
325
  when :script
326
326
  if mtabs != 0 && !@options[:ugly]
@@ -579,17 +579,17 @@ END
579
579
  raise SyntaxError.new("Invalid tag: \"#{line}\".") unless match = line.scan(/%([-:\w]+)([-:\w\.\#]*)(.*)/)[0]
580
580
  tag_name, attributes, rest = match
581
581
  new_attributes_hash = old_attributes_hash = last_line = object_ref = nil
582
- attributes_hashes = []
582
+ attributes_hashes = {}
583
583
  while rest
584
584
  case rest[0]
585
585
  when ?{
586
586
  break if old_attributes_hash
587
587
  old_attributes_hash, rest, last_line = parse_old_attributes(rest)
588
- attributes_hashes << [:old, old_attributes_hash]
588
+ attributes_hashes[:old] = old_attributes_hash
589
589
  when ?(
590
590
  break if new_attributes_hash
591
591
  new_attributes_hash, rest, last_line = parse_new_attributes(rest)
592
- attributes_hashes << [:new, new_attributes_hash]
592
+ attributes_hashes[:new] = new_attributes_hash
593
593
  when ?[
594
594
  break if object_ref
595
595
  object_ref, rest = balance(rest, ?[, ?])
@@ -662,7 +662,7 @@ END
662
662
  if type == :static
663
663
  static_attributes[name] = val
664
664
  else
665
- dynamic_attributes << inspect(name) << " => " << val << ","
665
+ dynamic_attributes << inspect_obj(name) << " => " << val << ","
666
666
  end
667
667
  end
668
668
  dynamic_attributes << "}"
@@ -697,7 +697,7 @@ END
697
697
 
698
698
  return name, [:static, content.first[1]] if content.size == 1
699
699
  return name, [:dynamic,
700
- '"' + content.map {|(t, v)| t == :str ? inspect(v)[1...-1] : "\#{#{v}}"}.join + '"']
700
+ '"' + content.map {|(t, v)| t == :str ? inspect_obj(v)[1...-1] : "\#{#{v}}"}.join + '"']
701
701
  end
702
702
 
703
703
  # Parses a line that will render as an XHTML tag, and adds the code that will
@@ -757,16 +757,21 @@ END
757
757
  object_ref = "nil" if object_ref.nil? || @options[:suppress_eval]
758
758
 
759
759
  attributes = Precompiler.parse_class_and_id(attributes)
760
- attributes_hashes.map! do |syntax, attributes_hash|
761
- if syntax == :old
762
- static_attributes = parse_static_hash(attributes_hash)
763
- attributes_hash = nil if static_attributes || @options[:suppress_eval]
764
- else
765
- static_attributes, attributes_hash = attributes_hash
766
- end
760
+ attributes_list = []
761
+
762
+ if attributes_hashes[:new]
763
+ static_attributes, attributes_hash = attributes_hashes[:new]
764
+ Buffer.merge_attrs(attributes, static_attributes) if static_attributes
765
+ attributes_list << attributes_hash
766
+ end
767
+
768
+ if attributes_hashes[:old]
769
+ static_attributes = parse_static_hash(attributes_hashes[:old])
767
770
  Buffer.merge_attrs(attributes, static_attributes) if static_attributes
768
- attributes_hash
769
- end.compact!
771
+ attributes_list << attributes_hashes[:old] unless static_attributes || @options[:suppress_eval]
772
+ end
773
+
774
+ attributes_list.compact!
770
775
 
771
776
  raise SyntaxError.new("Illegal nesting: nesting within a self-closing tag is illegal.", @next_line.index) if block_opened? && self_closing
772
777
  raise SyntaxError.new("There's no Ruby code for #{action} to evaluate.", last_line - 1) if parse && value.empty?
@@ -784,7 +789,7 @@ END
784
789
  (nuke_inner_whitespace && block_opened?)
785
790
 
786
791
  # Check if we can render the tag directly to text and not process it in the buffer
787
- if object_ref == "nil" && attributes_hashes.empty? && !preserve_script
792
+ if object_ref == "nil" && attributes_list.empty? && !preserve_script
788
793
  tag_closed = !block_opened? && !self_closing && !parse
789
794
 
790
795
  open_tag = prerender_tag(tag_name, self_closing, attributes)
@@ -802,19 +807,19 @@ END
802
807
  return if tag_closed
803
808
  else
804
809
  flush_merged_text
805
- content = parse ? 'nil' : inspect(value)
806
- if attributes_hashes.empty?
807
- attributes_hashes = ''
808
- elsif attributes_hashes.size == 1
809
- attributes_hashes = ", #{attributes_hashes.first}"
810
+ content = parse ? 'nil' : inspect_obj(value)
811
+ if attributes_list.empty?
812
+ attributes_list = ''
813
+ elsif attributes_list.size == 1
814
+ attributes_list = ", #{attributes_list.first}"
810
815
  else
811
- attributes_hashes = ", (#{attributes_hashes.join(").merge(")})"
816
+ attributes_list = ", (#{attributes_list.join(").merge(")})"
812
817
  end
813
818
 
814
819
  args = [tag_name, self_closing, !block_opened?, preserve_tag, escape_html,
815
820
  attributes, nuke_outer_whitespace, nuke_inner_whitespace
816
- ].map {|v| inspect(v)}.join(', ')
817
- push_silent "_hamlout.open_tag(#{args}, #{object_ref}, #{content}#{attributes_hashes})"
821
+ ].map {|v| inspect_obj(v)}.join(', ')
822
+ push_silent "_hamlout.open_tag(#{args}, #{object_ref}, #{content}#{attributes_list})"
818
823
  @dont_tab_up_next_text = @dont_indent_next_line = dont_indent_next_line
819
824
  end
820
825
 
@@ -1019,7 +1024,7 @@ END
1019
1024
 
1020
1025
  def unescape_interpolation(str, opts = {})
1021
1026
  res = ''
1022
- rest = Haml::Shared.handle_interpolation inspect(str) do |scan|
1027
+ rest = Haml::Shared.handle_interpolation inspect_obj(str) do |scan|
1023
1028
  escapes = (scan[2].size - 1) / 2
1024
1029
  res << scan.matched[0...-3 - escapes]
1025
1030
  if escapes % 2 == 1
@@ -662,9 +662,9 @@ MSG
662
662
  #
663
663
  # @param obj {Object}
664
664
  # @return {String}
665
- def inspect(obj)
665
+ def inspect_obj(obj)
666
666
  return obj.inspect unless version_geq(::RUBY_VERSION, "1.9.2")
667
- return ':' + inspect(obj.to_s) if obj.is_a?(Symbol)
667
+ return ':' + inspect_obj(obj.to_s) if obj.is_a?(Symbol)
668
668
  return obj.inspect unless obj.is_a?(String)
669
669
  '"' + obj.gsub(/[\x00-\x7F]+/) {|s| s.inspect[1...-1]} + '"'
670
670
  end
@@ -16,6 +16,7 @@ require 'sass/tree/for_node'
16
16
  require 'sass/tree/debug_node'
17
17
  require 'sass/tree/warn_node'
18
18
  require 'sass/tree/import_node'
19
+ require 'sass/tree/charset_node'
19
20
  require 'sass/selector'
20
21
  require 'sass/environment'
21
22
  require 'sass/script'
@@ -195,7 +196,14 @@ module Sass
195
196
  def _render
196
197
  rendered = _to_tree.render
197
198
  return rendered if ruby1_8?
198
- return rendered.encode(source_encoding)
199
+ begin
200
+ # Try to convert the result to the original encoding,
201
+ # but if that doesn't work fall back on UTF-8
202
+ rendered = rendered.encode(source_encoding)
203
+ rescue EncodingError
204
+ end
205
+ rendered.gsub(Regexp.new('\A@charset "(.*?)"'.encode(source_encoding)),
206
+ "@charset \"#{source_encoding.name}\"".encode(source_encoding))
199
207
  end
200
208
 
201
209
  def _to_tree
@@ -542,6 +550,12 @@ WARNING
542
550
  :line => @line + 1) unless line.children.empty?
543
551
  offset = line.offset + line.text.index(value).to_i
544
552
  Tree::WarnNode.new(parse_script(value, :offset => offset))
553
+ elsif directive == "charset"
554
+ name = value && value[/\A(["'])(.*)\1\Z/, 2] #"
555
+ raise SyntaxError.new("Invalid charset directive '@charset': expected string.") unless name
556
+ raise SyntaxError.new("Illegal nesting: Nothing may be nested beneath charset directives.",
557
+ :line => @line + 1) unless line.children.empty?
558
+ Tree::CharsetNode.new(name)
545
559
  else
546
560
  Tree::DirectiveNode.new(line.text)
547
561
  end
@@ -228,7 +228,10 @@ module Sass
228
228
  # Finally, write the file
229
229
  flag = 'w'
230
230
  flag = 'wb' if Haml::Util.windows? && options[:unix_newlines]
231
- File.open(css, flag) {|file| file.print(result)}
231
+ File.open(css, flag) do |file|
232
+ file.set_encoding(result.encoding) unless Haml::Util.ruby1_8?
233
+ file.print(result)
234
+ end
232
235
  end
233
236
 
234
237
  def try_delete_css(css)
@@ -24,11 +24,6 @@ module Sass
24
24
  def interp_ident(ident = IDENT); tok(ident); end
25
25
  def use_css_import?; true; end
26
26
 
27
- def special_directive(name)
28
- return unless name == 'media' || name == 'import'
29
- super
30
- end
31
-
32
27
  def block_child(context)
33
28
  case context
34
29
  when :ruleset
@@ -98,7 +98,8 @@ module Sass
98
98
  node << comment
99
99
  end
100
100
 
101
- DIRECTIVES = Set[:mixin, :include, :debug, :warn, :for, :while, :if, :extend, :import, :media]
101
+ DIRECTIVES = Set[:mixin, :include, :debug, :warn, :for, :while, :if, :extend, :import,
102
+ :media, :charset]
102
103
 
103
104
  def directive
104
105
  return unless tok(/@/)
@@ -289,6 +290,13 @@ module Sass
289
290
  true
290
291
  end
291
292
 
293
+ def charset_directive
294
+ tok! STRING
295
+ name = @scanner[1] || @scanner[2]
296
+ ss
297
+ node(Sass::Tree::CharsetNode.new(name))
298
+ end
299
+
292
300
  def variable
293
301
  return unless tok(/\$/)
294
302
  name = tok!(IDENT)
@@ -32,7 +32,7 @@ module Sass
32
32
  def use_css_import?; true; end
33
33
 
34
34
  def special_directive(name)
35
- return unless name == 'media' || name == 'import'
35
+ return unless %w[media import charset].include?(name)
36
36
  super
37
37
  end
38
38
  end
@@ -0,0 +1,37 @@
1
+ module Sass::Tree
2
+ # A static node representing an unproccessed Sass `@charset` directive.
3
+ #
4
+ # @see Sass::Tree
5
+ class CharsetNode < Node
6
+ # The name of the charset.
7
+ #
8
+ # @return [String]
9
+ attr_accessor :name
10
+
11
+ # @param name [String] see \{#name}
12
+ def initialize(name)
13
+ @name = name
14
+ super()
15
+ end
16
+
17
+ # @see Node#invisible?
18
+ def invisible?
19
+ !Haml::Util.ruby1_8?
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
+ end
37
+ end
@@ -4,8 +4,8 @@ module Sass::Tree
4
4
  # are handled by their own nodes;
5
5
  # only CSS directives like `@media` and `@font-face` become {DirectiveNode}s.
6
6
  #
7
- # `@import` is a bit of a weird case;
8
- # it becomes an {ImportNode}.
7
+ # `@import` and `@charset` are special cases;
8
+ # they become {ImportNode}s and {CharsetNode}s, respectively.
9
9
  #
10
10
  # @see Sass::Tree
11
11
  class DirectiveNode < Node
@@ -47,7 +47,7 @@ module Sass
47
47
  # @return [(Tree::Node, Haml::Util::SubsetMap)] The resulting tree of static nodes
48
48
  # *and* the extensions defined for this tree
49
49
  def cssize(extends = Haml::Util::SubsetMap.new, parent = nil)
50
- return super(extends), extends
50
+ return super(extends, parent), extends
51
51
  rescue Sass::SyntaxError => e
52
52
  e.sass_template = @template
53
53
  raise e
@@ -106,7 +106,39 @@ module Sass
106
106
  end
107
107
  result.rstrip!
108
108
  return "" if result.empty?
109
- return result + "\n"
109
+ result << "\n"
110
+ unless Haml::Util.ruby1_8? || result.ascii_only?
111
+ if children.first.is_a?(CharsetNode)
112
+ begin
113
+ encoding = children.first.name
114
+ # Default to big-endian encoding, because we have to decide somehow
115
+ encoding << 'BE' if encoding =~ /\Autf-(16|32)\Z/i
116
+ result = result.encode(Encoding.find(encoding))
117
+ rescue EncodingError
118
+ end
119
+ end
120
+
121
+ result = "@charset \"#{result.encoding.name}\";#{
122
+ style == :compressed ? '' : "\n"
123
+ }".encode(result.encoding) + result
124
+ end
125
+ result
126
+ end
127
+
128
+ # In Ruby 1.8, ensures that there's only one @charset directive
129
+ # and that it's at the top of the document.
130
+ #
131
+ # @see Node#cssize
132
+ def cssize!(extends, parent)
133
+ super
134
+
135
+ # In Ruby 1.9 we can make all @charset nodes invisible
136
+ # and infer the final @charset from the encoding of the final string.
137
+ if Haml::Util.ruby1_8? && parent.nil?
138
+ charset = self.children.find {|c| c.is_a?(CharsetNode)}
139
+ self.children.reject! {|c| c.is_a?(CharsetNode)}
140
+ self.children.unshift charset if charset
141
+ end
110
142
  end
111
143
 
112
144
  # Returns an error message if the given child node is invalid,
@@ -1389,7 +1389,7 @@ SASS
1389
1389
 
1390
1390
  def test_new_attribute_ids
1391
1391
  assert_equal("<div id='foo_bar'></div>\n", render("#foo(id='bar')"))
1392
- assert_equal("<div id='foo_bar_baz'></div>\n", render("#foo{:id => 'bar'}(id='baz')"))
1392
+ assert_equal("<div id='foo_baz_bar'></div>\n", render("#foo{:id => 'bar'}(id='baz')"))
1393
1393
  assert_equal("<div id='foo_baz_bar'></div>\n", render("#foo(id='baz'){:id => 'bar'}"))
1394
1394
  foo = User.new(42)
1395
1395
  assert_equal("<div class='struct_user' id='foo_baz_bar_struct_user_42'></div>\n",
@@ -1398,7 +1398,7 @@ SASS
1398
1398
  render("#foo(id='baz')[foo]{:id => 'bar'}", :locals => {:foo => foo}))
1399
1399
  assert_equal("<div class='struct_user' id='foo_baz_bar_struct_user_42'></div>\n",
1400
1400
  render("#foo[foo](id='baz'){:id => 'bar'}", :locals => {:foo => foo}))
1401
- assert_equal("<div class='struct_user' id='foo_bar_baz_struct_user_42'></div>\n",
1401
+ assert_equal("<div class='struct_user' id='foo_baz_bar_struct_user_42'></div>\n",
1402
1402
  render("#foo[foo]{:id => 'bar'}(id='baz')", :locals => {:foo => foo}))
1403
1403
  end
1404
1404
 
@@ -1470,11 +1470,17 @@ SASS
1470
1470
  assert_equal("<a a='b' c='d'>bar</a>\n", render("%a(c='d'){:a => 'b'} bar"))
1471
1471
  assert_equal("<a a='b' c='d'>bar</a>\n", render("%a{:a => 'b'}(c='d') bar"))
1472
1472
 
1473
- assert_equal("<a a='d'>bar</a>\n", render("%a{:a => 'b'}(a='d') bar"))
1473
+ # Old-style always takes precedence over new-style,
1474
+ # because theoretically old-style could have arbitrary end-of-method-call syntax.
1475
+ assert_equal("<a a='b'>bar</a>\n", render("%a{:a => 'b'}(a='d') bar"))
1474
1476
  assert_equal("<a a='b'>bar</a>\n", render("%a(a='d'){:a => 'b'} bar"))
1475
1477
 
1476
1478
  assert_equal("<a a='b' b='c' c='d' d='e'>bar</a>\n",
1477
1479
  render("%a{:a => 'b',\n:b => 'c'}(c='d'\nd='e') bar"))
1480
+
1481
+ locals = {:b => 'b', :d => 'd'}
1482
+ assert_equal("<p a='b' c='d'></p>\n", render("%p{:a => b}(c=d)", :locals => locals))
1483
+ assert_equal("<p a='b' c='d'></p>\n", render("%p(a=b){:c => d}", :locals => locals))
1478
1484
  end
1479
1485
 
1480
1486
  # Ruby Multiline
@@ -607,6 +607,14 @@ foo {
607
607
  SCSS
608
608
  end
609
609
 
610
+ def test_charset
611
+ assert_renders <<SASS, <<SCSS
612
+ @charset "utf-8"
613
+ SASS
614
+ @charset "utf-8";
615
+ SCSS
616
+ end
617
+
610
618
  def test_for
611
619
  assert_renders <<SASS, <<SCSS
612
620
  foo
@@ -2128,7 +2128,7 @@ SASS
2128
2128
 
2129
2129
  def test_same_charset_as_encoding
2130
2130
  assert_renders_encoded(<<CSS, <<SASS)
2131
- @charset "utf-8";
2131
+ @charset "UTF-8";
2132
2132
  fóó {
2133
2133
  a: b; }
2134
2134
  CSS
@@ -2140,7 +2140,7 @@ SASS
2140
2140
 
2141
2141
  def test_different_charset_than_encoding
2142
2142
  assert_renders_encoded(<<CSS.force_encoding("IBM866"), <<SASS)
2143
- @charset "ibm866";
2143
+ @charset "IBM866";
2144
2144
  fóó {
2145
2145
  a: b; }
2146
2146
  CSS
@@ -2152,6 +2152,7 @@ SASS
2152
2152
 
2153
2153
  def test_different_encoding_than_system
2154
2154
  assert_renders_encoded(<<CSS.encode("IBM866"), <<SASS.encode("IBM866"))
2155
+ @charset "IBM866";
2155
2156
  тАЬ {
2156
2157
  a: b; }
2157
2158
  CSS
@@ -2161,20 +2162,20 @@ SASS
2161
2162
  end
2162
2163
 
2163
2164
  def test_multibyte_charset
2164
- assert_renders_encoded(<<CSS.encode("UTF-16BE"), <<SASS.encode("UTF-16BE").force_encoding("UTF-8"))
2165
- @charset "utf-16be";
2165
+ assert_renders_encoded(<<CSS.encode("UTF-16LE"), <<SASS.encode("UTF-16LE").force_encoding("UTF-8"))
2166
+ @charset "UTF-16LE";
2166
2167
  fóó {
2167
2168
  a: b; }
2168
2169
  CSS
2169
- @charset "utf-16be"
2170
+ @charset "utf-16le"
2170
2171
  fóó
2171
2172
  a: b
2172
2173
  SASS
2173
2174
  end
2174
2175
 
2175
2176
  def test_multibyte_charset_without_endian_specifier
2176
- assert_renders_encoded(<<CSS.encode("UTF-32LE"), <<SASS.encode("UTF-32LE").force_encoding("UTF-8"))
2177
- @charset "utf-32";
2177
+ assert_renders_encoded(<<CSS.encode("UTF-32BE"), <<SASS.encode("UTF-32BE").force_encoding("UTF-8"))
2178
+ @charset "UTF-32BE";
2178
2179
  fóó {
2179
2180
  a: b; }
2180
2181
  CSS
@@ -2186,6 +2187,7 @@ SASS
2186
2187
 
2187
2188
  def test_utf8_bom
2188
2189
  assert_renders_encoded(<<CSS, <<SASS.force_encoding("BINARY"))
2190
+ @charset "UTF-8";
2189
2191
  fóó {
2190
2192
  a: b; }
2191
2193
  CSS
@@ -2196,6 +2198,7 @@ SASS
2196
2198
 
2197
2199
  def test_utf16le_bom
2198
2200
  assert_renders_encoded(<<CSS.encode("UTF-16LE"), <<SASS.encode("UTF-16LE").force_encoding("BINARY"))
2201
+ @charset "UTF-16LE";
2199
2202
  fóó {
2200
2203
  a: b; }
2201
2204
  CSS
@@ -2206,6 +2209,7 @@ SASS
2206
2209
 
2207
2210
  def test_utf32be_bom
2208
2211
  assert_renders_encoded(<<CSS.encode("UTF-32BE"), <<SASS.encode("UTF-32BE").force_encoding("BINARY"))
2212
+ @charset "UTF-32BE";
2209
2213
  fóó {
2210
2214
  a: b; }
2211
2215
  CSS
@@ -9,6 +9,8 @@ class SassPluginTest < Test::Unit::TestCase
9
9
  subdir/subdir subdir/nested_subdir/nested_subdir
10
10
  options
11
11
  }
12
+ @@templates += %w[import_charset import_charset_ibm866] unless Haml::Util.ruby1_8?
13
+ @@templates << 'import_charset_1_8' if Haml::Util.ruby1_8?
12
14
 
13
15
  def setup
14
16
  FileUtils.mkdir tempfile_loc
@@ -267,11 +269,18 @@ CSS
267
269
  prefix = options[:prefix]
268
270
  result_name = arguments.shift
269
271
  tempfile_name = arguments.shift || result_name
270
- expected_lines = File.read(result_loc(result_name, prefix)).split("\n")
271
- actual_lines = File.read(tempfile_loc(tempfile_name, prefix)).split("\n")
272
+
273
+ expected_str = File.read(result_loc(result_name, prefix))
274
+ actual_str = File.read(tempfile_loc(tempfile_name, prefix))
275
+ unless Haml::Util.ruby1_8?
276
+ expected_str = expected_str.force_encoding('IBM866') if result_name == 'import_charset_ibm866'
277
+ actual_str = actual_str.force_encoding('IBM866') if tempfile_name == 'import_charset_ibm866'
278
+ end
279
+ expected_lines = expected_str.split("\n")
280
+ actual_lines = actual_str.split("\n")
272
281
 
273
282
  if actual_lines.first == "/*" && expected_lines.first != "/*"
274
- assert(false, actual_lines[0..actual_lines.enum_with_index.find {|l, i| l == "*/"}.last].join("\n"))
283
+ assert(false, actual_lines[0..Haml::Util.enum_with_index(actual_lines).find {|l, i| l == "*/"}.last].join("\n"))
275
284
  end
276
285
 
277
286
  expected_lines.zip(actual_lines).each_with_index do |pair, line|
@@ -0,0 +1,4 @@
1
+ @charset "UTF-8";
2
+ .foo { a: b; }
3
+
4
+ .bar { a: щ; }
@@ -0,0 +1,4 @@
1
+ @charset "IBM866";
2
+ .foo { a: b; }
3
+
4
+ .bar { a: �; }
@@ -0,0 +1,4 @@
1
+ @charset "IBM866";
2
+ .foo { a: b; }
3
+
4
+ .bar { a: �; }
@@ -49,11 +49,34 @@ baz {bar: baz}
49
49
  SCSS
50
50
  end
51
51
 
52
- def test_unicode
53
- assert_parses <<SCSS
52
+ if Haml::Util.ruby1_8?
53
+ def test_unicode
54
+ assert_parses <<SCSS
55
+ @charset "UTF-8";
56
+ foo {
57
+ bar: föö bâr; }
58
+ SCSS
59
+ assert_parses <<SCSS
54
60
  foo {
55
61
  bar: föö bâr; }
56
62
  SCSS
63
+ end
64
+ else
65
+ def test_unicode
66
+ assert_parses <<SCSS
67
+ @charset "UTF-8";
68
+ foo {
69
+ bar: föö bâr; }
70
+ SCSS
71
+ assert_equal <<CSS, render(<<SCSS)
72
+ @charset "UTF-8";
73
+ foo {
74
+ bar: föö bâr; }
75
+ CSS
76
+ foo {
77
+ bar: föö bâr; }
78
+ SCSS
79
+ end
57
80
  end
58
81
 
59
82
  def test_invisible_comments
@@ -429,10 +452,6 @@ SCSS
429
452
 
430
453
  ## Directives
431
454
 
432
- def test_charset_directive
433
- assert_parses '@charset "utf-8";'
434
- end
435
-
436
455
  def test_namespace_directive
437
456
  assert_parses '@namespace "http://www.w3.org/Profiles/xhtml1-strict";'
438
457
  assert_parses '@namespace url(http://www.w3.org/Profiles/xhtml1-strict);'
@@ -508,11 +527,11 @@ SCSS
508
527
  end
509
528
 
510
529
  def test_blockless_directive_without_semicolon
511
- assert_equal "@charset \"utf-8\";\n", render('@charset "utf-8"')
530
+ assert_equal "@foo \"bar\";\n", render('@foo "bar"')
512
531
  end
513
532
 
514
533
  def test_directive_with_lots_of_whitespace
515
- assert_equal "@charset \"utf-16\";\n", render('@charset "utf-16" ;')
534
+ assert_equal "@foo \"bar\";\n", render('@foo "bar" ;')
516
535
  end
517
536
 
518
537
  def test_empty_blockless_directive
@@ -0,0 +1,4 @@
1
+ @charset "IBM866"
2
+
3
+ .bar
4
+ a: �
@@ -0,0 +1,4 @@
1
+ @charset "UTF-8"
2
+
3
+ .bar
4
+ a: щ
@@ -0,0 +1,7 @@
1
+ .foo
2
+ a: b
3
+
4
+ // Even though the imported file is in IBM866,
5
+ // since the root file is in UTF-8/ASCII
6
+ // the output will end up being UTF-8.
7
+ @import "imported_charset_ibm866"
@@ -0,0 +1,4 @@
1
+ .foo
2
+ a: b
3
+
4
+ @import "imported_charset_ibm866"
@@ -0,0 +1,9 @@
1
+ @charset "IBM866"
2
+
3
+ .foo
4
+ a: b
5
+
6
+ // Even though the imported file is in UTF-8,
7
+ // since the root file is in IBM866
8
+ // the output will end up being IBM866.
9
+ @import "imported_charset_utf8"
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: haml
3
3
  version: !ruby/object:Gem::Version
4
- hash: 43
4
+ hash: 41
5
5
  prerelease: false
6
6
  segments:
7
7
  - 3
8
8
  - 0
9
- - 22
10
- version: 3.0.22
9
+ - 23
10
+ version: 3.0.23
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: 2010-10-19 00:00:00 -07:00
20
+ date: 2010-10-31 00:00:00 -07:00
21
21
  default_executable:
22
22
  dependencies:
23
23
  - !ruby/object:Gem::Dependency
@@ -96,6 +96,7 @@ files:
96
96
  - lib/sass/tree/root_node.rb
97
97
  - lib/sass/tree/node.rb
98
98
  - lib/sass/tree/if_node.rb
99
+ - lib/sass/tree/charset_node.rb
99
100
  - lib/sass/tree/extend_node.rb
100
101
  - lib/sass/tree/rule_node.rb
101
102
  - lib/sass/tree/mixin_def_node.rb
@@ -192,7 +193,9 @@ files:
192
193
  - test/sass/templates/basic.sass
193
194
  - test/sass/templates/line_numbers.sass
194
195
  - test/sass/templates/nested_bork2.sass
196
+ - test/sass/templates/_imported_charset_utf8.sass
195
197
  - test/sass/templates/mixin_bork.sass
198
+ - test/sass/templates/import_charset.sass
196
199
  - test/sass/templates/importee.less
197
200
  - test/sass/templates/warn.sass
198
201
  - test/sass/templates/parent_ref.sass
@@ -209,9 +212,11 @@ files:
209
212
  - test/sass/templates/bork3.sass
210
213
  - test/sass/templates/nested_mixin_bork.sass
211
214
  - test/sass/templates/complex.sass
215
+ - test/sass/templates/import_charset_ibm866.sass
212
216
  - test/sass/templates/alt.sass
213
217
  - test/sass/templates/scss_import.scss
214
218
  - test/sass/templates/compact.sass
219
+ - test/sass/templates/_imported_charset_ibm866.sass
215
220
  - test/sass/templates/nested.sass
216
221
  - test/sass/templates/subdir/subdir.sass
217
222
  - test/sass/templates/subdir/nested_subdir/_nested_partial.sass
@@ -219,6 +224,7 @@ files:
219
224
  - test/sass/templates/warn_imported.sass
220
225
  - test/sass/templates/options.sass
221
226
  - test/sass/templates/bork4.sass
227
+ - test/sass/templates/import_charset_1_8.sass
222
228
  - test/sass/templates/nested_bork4.sass
223
229
  - test/sass/templates/multiline.sass
224
230
  - test/sass/templates/expanded.sass
@@ -248,14 +254,17 @@ files:
248
254
  - test/sass/results/alt.css
249
255
  - test/sass/results/scss_importee.css
250
256
  - test/sass/results/line_numbers.css
257
+ - test/sass/results/import_charset.css
251
258
  - test/sass/results/expanded.css
252
259
  - test/sass/results/warn.css
253
260
  - test/sass/results/script.css
254
261
  - test/sass/results/scss_import.css
255
262
  - test/sass/results/nested.css
256
263
  - test/sass/results/options.css
264
+ - test/sass/results/import_charset_1_8.css
257
265
  - test/sass/results/parent_ref.css
258
266
  - test/sass/results/multiline.css
267
+ - test/sass/results/import_charset_ibm866.css
259
268
  - test/sass/results/subdir/subdir.css
260
269
  - test/sass/results/subdir/nested_subdir/nested_subdir.css
261
270
  - test/sass/results/warn_imported.css