haml 3.0.15 → 3.0.16

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.15
1
+ 3.0.16
@@ -388,7 +388,7 @@ END
388
388
  ::Sass::Plugin.options.merge! @options[:for_engine]
389
389
  ::Sass::Plugin.options[:unix_newlines] = @options[:unix_newlines]
390
390
 
391
- if @args[1] && !colon_path?(@args[0])
391
+ if !colon_path?(@args[0]) && probably_dest_dir?(@args[1])
392
392
  flag = @options[:update] ? "--update" : "--watch"
393
393
  err =
394
394
  if !File.exist?(@args[1])
@@ -396,7 +396,7 @@ END
396
396
  elsif @args[1] =~ /\.css$/
397
397
  "is a CSS file"
398
398
  end
399
- raise <<MSG if err
399
+ msg = <<MSG if err
400
400
  File #{@args[1]} #{err}.
401
401
  Did you mean: sass #{flag} #{@args[0]}:#{@args[1]}
402
402
  MSG
@@ -452,6 +452,13 @@ MSG
452
452
  end
453
453
  return one, two
454
454
  end
455
+
456
+ # Whether path is likely to be meant as the destination
457
+ # in a source:dest pair.
458
+ def probably_dest_dir?(path)
459
+ return false if colon_path?(path)
460
+ return Dir.glob(File.join(path, "*.s[ca]ss")).empty?
461
+ end
455
462
  end
456
463
 
457
464
  # The `haml` executable.
@@ -140,7 +140,8 @@ module ActionView
140
140
  module FormTagHelper
141
141
  def form_tag_with_haml(url_for_options = {}, options = {}, *parameters_for_url, &proc)
142
142
  if is_haml?
143
- if block_given?
143
+ wrap_block = block_given? && block_is_haml?(proc)
144
+ if wrap_block
144
145
  oldproc = proc
145
146
  proc = haml_bind_proc do |*args|
146
147
  concat "\n"
@@ -148,7 +149,7 @@ module ActionView
148
149
  end
149
150
  end
150
151
  res = form_tag_without_haml(url_for_options, options, *parameters_for_url, &proc) + "\n"
151
- res << "\n" if block_given?
152
+ res << "\n" if wrap_block
152
153
  res
153
154
  else
154
155
  form_tag_without_haml(url_for_options, options, *parameters_for_url, &proc)
@@ -160,12 +161,13 @@ module ActionView
160
161
 
161
162
  module FormHelper
162
163
  def form_for_with_haml(object_name, *args, &proc)
163
- if block_given? && is_haml?
164
+ wrap_block = block_given? && is_haml? && block_is_haml?(proc)
165
+ if wrap_block
164
166
  oldproc = proc
165
167
  proc = proc {|*args| with_tabs(1) {oldproc.call(*args)}}
166
168
  end
167
169
  res = form_for_without_haml(object_name, *args, &proc)
168
- res << "\n" if block_given? && is_haml?
170
+ res << "\n" if wrap_block
169
171
  res
170
172
  end
171
173
  alias_method :form_for_without_haml, :form_for
@@ -191,7 +193,8 @@ module ActionView
191
193
  module FormTagHelper
192
194
  def form_tag_with_haml(url_for_options = {}, options = {}, *parameters_for_url, &proc)
193
195
  if is_haml?
194
- if block_given?
196
+ wrap_block = block_given? && block_is_haml?(proc)
197
+ if wrap_block
195
198
  oldproc = proc
196
199
  proc = haml_bind_proc do |*args|
197
200
  concat "\n"
@@ -218,7 +221,8 @@ module ActionView
218
221
 
219
222
  module FormHelper
220
223
  def form_for_with_haml(object_name, *args, &proc)
221
- if block_given? && is_haml?
224
+ wrap_block = block_given? && is_haml? && block_is_haml?(proc)
225
+ if wrap_block
222
226
  oldproc = proc
223
227
  proc = haml_bind_proc do |*args|
224
228
  tab_up
@@ -229,7 +233,7 @@ module ActionView
229
233
  concat haml_indent
230
234
  end
231
235
  form_for_without_haml(object_name, *args, &proc)
232
- concat "\n" if block_given? && is_haml?
236
+ concat "\n" if wrap_block
233
237
  Haml::Helpers::ErrorReturn.new("form_for") if is_haml?
234
238
  end
235
239
  alias_method :form_for_without_haml, :form_for
@@ -100,6 +100,23 @@ end
100
100
 
101
101
  require 'hpricot'
102
102
 
103
+ # @private
104
+ HAML_TAGS = %w[haml:block haml:loud haml:silent]
105
+
106
+ Hpricot::ElementContent.keys.each do |k|
107
+ HAML_TAGS.each do |el|
108
+ val = Hpricot::ElementContent[k]
109
+ val[el.hash] = true if val.is_a?(Hash)
110
+ end
111
+ end
112
+
113
+ HAML_TAGS.each do |t|
114
+ Hpricot::ElementContent[t] = {}
115
+ Hpricot::ElementContent.keys.each do |key|
116
+ Hpricot::ElementContent[t][key.hash] = true
117
+ end
118
+ end
119
+
103
120
  module Haml
104
121
  # Converts HTML documents into Haml templates.
105
122
  # Depends on [Hpricot](http://github.com/whymirror/hpricot) for HTML parsing.
@@ -248,12 +248,20 @@ END
248
248
  # It's important to preserve tabulation modification for keywords
249
249
  # that involve choosing between posible blocks of code.
250
250
  if %w[else elsif when].include?(keyword)
251
- @dont_indent_next_line, @dont_tab_up_next_text = @to_close_stack.last[1..2]
251
+ # Whether a script block has already been opened immediately above this line
252
+ was_opened = @to_close_stack.last && @to_close_stack.last.first == :script
253
+ if was_opened
254
+ @dont_indent_next_line, @dont_tab_up_next_text = @to_close_stack.last[1..2]
255
+ end
252
256
 
253
257
  # when is unusual in that either it will be indented twice,
254
- # or the case won't have created its own indentation
255
- if keyword == "when"
256
- push_and_tabulate([:script, @dont_indent_next_line, @dont_tab_up_next_text, false])
258
+ # or the case won't have created its own indentation.
259
+ # Also, if no block has been opened yet, we need to make sure we add an end
260
+ # once we de-indent.
261
+ if !was_opened || keyword == "when"
262
+ push_and_tabulate([
263
+ :script, @dont_indent_next_line, @dont_tab_up_next_text,
264
+ !was_opened])
257
265
  end
258
266
  elsif block || text =~ /^-\s*(case|if)\b/
259
267
  push_and_tabulate([:script, @dont_indent_next_line, @dont_tab_up_next_text])
@@ -667,13 +667,14 @@ WARNING
667
667
  end
668
668
 
669
669
  return silent ? "//" : "/* */" if content.empty?
670
+ content.last.gsub!(%r{ ?\*/ *$}, '')
670
671
  content.map! {|l| l.gsub!(/^\*( ?)/, '\1') || (l.empty? ? "" : " ") + l}
671
672
  content.first.gsub!(/^ /, '') unless removed_first
672
- content.last.gsub!(%r{ ?\*/ *$}, '')
673
673
  if silent
674
674
  "//" + content.join("\n//")
675
675
  else
676
- "/*" + content.join("\n *") + " */"
676
+ # The #gsub fixes the case of a trailing */
677
+ "/*" + content.join("\n *").gsub(/ \*\Z/, '') + " */"
677
678
  end
678
679
  end
679
680
 
@@ -63,7 +63,7 @@ module Sass
63
63
 
64
64
  IDENT = /-?#{NMSTART}#{NMCHAR}*/
65
65
  NAME = /#{NMCHAR}+/
66
- NUM = /[0-9]+|[0-9]*.[0-9]+/
66
+ NUM = /[0-9]+|[0-9]*\.[0-9]+/
67
67
  STRING = /#{STRING1}|#{STRING2}/
68
68
  URLCHAR = /[#%&*-~]|#{NONASCII}|#{ESCAPE}/
69
69
  URL = /(#{URLCHAR}*)/
@@ -98,7 +98,7 @@ module Sass::Tree
98
98
  spaces = (' ' * [tabs - 1 - value[/^ */].size, 0].max)
99
99
 
100
100
  content = value.gsub(/^/, spaces)
101
- content.gsub!(/\n +(\* *)?/, ' ') if style == :compact
101
+ content.gsub!(/\n +(\* *(?!\/))?/, ' ') if style == :compact
102
102
  content
103
103
  end
104
104
 
@@ -697,6 +697,72 @@ HTML
697
697
  HAML
698
698
  end
699
699
 
700
+ def test_case_assigned_to_var
701
+ assert_equal(<<HTML, render(<<HAML))
702
+ bar
703
+ HTML
704
+ - var = case 12
705
+ - when 1; "foo"
706
+ - when 12; "bar"
707
+ = var
708
+ HAML
709
+
710
+ assert_equal(<<HTML, render(<<HAML))
711
+ bar
712
+ HTML
713
+ - var = case 12
714
+ - when 1
715
+ - "foo"
716
+ - when 12
717
+ - "bar"
718
+ = var
719
+ HAML
720
+
721
+ assert_equal(<<HTML, render(<<HAML))
722
+ bar
723
+ HTML
724
+ - var = case 12
725
+ - when 1
726
+ - "foo"
727
+ - when 12
728
+ - "bar"
729
+ = var
730
+ HAML
731
+ end
732
+
733
+ def test_if_assigned_to_var
734
+ assert_equal(<<HTML, render(<<HAML))
735
+ foo
736
+ HTML
737
+ - var = if false
738
+ - else
739
+ - "foo"
740
+ = var
741
+ HAML
742
+
743
+ assert_equal(<<HTML, render(<<HAML))
744
+ foo
745
+ HTML
746
+ - var = if false
747
+ - elsif 12
748
+ - "foo"
749
+ - elsif 14; "bar"
750
+ - else
751
+ - "baz"
752
+ = var
753
+ HAML
754
+
755
+ assert_equal(<<HTML, render(<<HAML))
756
+ foo
757
+ HTML
758
+ - var = if false
759
+ - "bar"
760
+ - else
761
+ - "foo"
762
+ = var
763
+ HAML
764
+ end
765
+
700
766
  # HTML escaping tests
701
767
 
702
768
  def test_ampersand_equals_should_escape
@@ -5,6 +5,10 @@ class ActionView::Base
5
5
  def nested_tag
6
6
  content_tag(:span) {content_tag(:div) {"something"}}
7
7
  end
8
+
9
+ def wacky_form
10
+ form_tag("/foo") {"bar"}
11
+ end
8
12
  end
9
13
 
10
14
  module Haml::Helpers
@@ -176,6 +180,15 @@ HTML
176
180
  HAML
177
181
  end
178
182
 
183
+ def test_form_tag_in_helper_with_string_block
184
+ def @base.protect_against_forgery?; false; end
185
+ assert_equal(<<HTML, render(<<HAML, :action_view))
186
+ <form #{rails_form_attr}action="/foo" method="post">#{rails_form_opener}bar</form>
187
+ HTML
188
+ #{rails_block_helper_char} wacky_form
189
+ HAML
190
+ end
191
+
179
192
  def test_haml_tag_name_attribute_with_id
180
193
  assert_equal("<p id='some_id'></p>\n", render("- haml_tag 'p#some_id'"))
181
194
  end
@@ -397,7 +410,7 @@ MESSAGE
397
410
  render("- something_that_uses_haml_concat")
398
411
  assert false, "Expected Haml::Error"
399
412
  rescue Haml::Error => e
400
- assert_equal 12, e.backtrace[0].scan(/:(\d+)/).first.first.to_i
413
+ assert_equal 16, e.backtrace[0].scan(/:(\d+)/).first.first.to_i
401
414
  end
402
415
 
403
416
  class ActsLikeTag
@@ -405,6 +405,22 @@ HAML
405
405
  <% ensure %>
406
406
  <p>c</p>
407
407
  <% end %>
408
+ ERB
409
+ end
410
+
411
+ # Regression
412
+
413
+ def test_tag_inside_block
414
+ assert_equal(<<HAML.rstrip, render_erb(<<ERB))
415
+ %table
416
+ - foo.each do
417
+ %tr
418
+ HAML
419
+ <table>
420
+ <% foo.each do %>
421
+ <tr></tr>
422
+ <% end %>
423
+ </table>
408
424
  ERB
409
425
  end
410
426
  end
@@ -490,17 +490,6 @@ CSS
490
490
  assert_equal("@import url(./fonts.css);\n", render("@import \"./fonts.css\""))
491
491
  end
492
492
 
493
- def test_media_import
494
- assert_equal("@import \"./fonts.sass\" all;\n",
495
- render("@import \"./fonts.sass\" all"))
496
- assert_equal(<<CSS, render(<<SASS))
497
- @import "./fonts.sass" all;
498
- @import url(./fonts.scss);
499
- CSS
500
- @import "./fonts.sass" all, url(./fonts.scss)
501
- SASS
502
- end
503
-
504
493
  def test_http_import
505
494
  assert_equal("@import url(http://fonts.googleapis.com/css?family=Droid+Sans);\n",
506
495
  render("@import \"http://fonts.googleapis.com/css?family=Droid+Sans\""))
@@ -1484,6 +1473,32 @@ foo
1484
1473
  SASS
1485
1474
  end
1486
1475
 
1476
+ def test_loud_comment_with_close
1477
+ assert_equal <<CSS, render(<<SASS)
1478
+ foo {
1479
+ /* foo
1480
+ * bar */ }
1481
+ CSS
1482
+ foo
1483
+ /* foo
1484
+ bar */
1485
+ SASS
1486
+ end
1487
+
1488
+ def test_loud_comment_with_separate_line_close
1489
+ assert_equal <<CSS, render(<<SASS)
1490
+ foo {
1491
+ /* foo
1492
+ * bar
1493
+ */ }
1494
+ CSS
1495
+ foo
1496
+ /* foo
1497
+ * bar
1498
+ */
1499
+ SASS
1500
+ end
1501
+
1487
1502
  def test_attribute_selector_with_spaces
1488
1503
  assert_equal(<<CSS, render(<<SASS))
1489
1504
  a b[foo=bar] {
@@ -393,7 +393,7 @@ SCSS
393
393
  assert_equal <<CSS, render(<<SCSS)
394
394
  foo {
395
395
  a: -0.5em;
396
- b: +0.5em;
396
+ b: 0.5em;
397
397
  c: -foo(12px);
398
398
  d: +foo(12px); }
399
399
  CSS
@@ -866,6 +866,20 @@ SCSS
866
866
  assert_equal 1, e.sass_line
867
867
  end
868
868
 
869
+ ## Regressions
870
+
871
+ def test_closing_line_comment_end_with_compact_output
872
+ assert_equal(<<CSS, render(<<SCSS, :style => :compact))
873
+ /* foo */
874
+ bar { baz: bang; }
875
+ CSS
876
+ /*
877
+ * foo
878
+ */
879
+ bar {baz: bang}
880
+ SCSS
881
+ end
882
+
869
883
  private
870
884
 
871
885
  def assert_selector_parses(selector)
@@ -1039,6 +1039,16 @@ MESSAGE
1039
1039
  .bar {
1040
1040
  @include foo(bar, );
1041
1041
  }
1042
+ SCSS
1043
+ end
1044
+
1045
+ def test_interpolation
1046
+ assert_equal <<CSS, render(<<SCSS)
1047
+ ul li#foo a span.label {
1048
+ foo: bar; }
1049
+ CSS
1050
+ $bar : "#foo";
1051
+ ul li\#{$bar} a span.label { foo: bar; }
1042
1052
  SCSS
1043
1053
  end
1044
1054
  end
@@ -0,0 +1,23 @@
1
+
2
+
3
+ body
4
+ :font Arial
5
+ :background blue
6
+
7
+ #page
8
+ :width 700px
9
+ :height 100
10
+ #header
11
+ :height 300px
12
+ h1
13
+ :font-size 50px
14
+ :color blue
15
+
16
+ #content.user.show
17
+ #container.top
18
+ #column.left
19
+ :width 100px
20
+ #column.right
21
+ :width 600px
22
+ #container.bottom
23
+ :background brown
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: haml
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.15
4
+ version: 3.0.16
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan Weizenbaum
@@ -11,7 +11,7 @@ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
13
 
14
- date: 2010-07-28 00:00:00 -07:00
14
+ date: 2010-08-08 00:00:00 -07:00
15
15
  default_executable:
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
@@ -192,6 +192,7 @@ files:
192
192
  - test/sass/templates/subdir/subdir.sass
193
193
  - test/sass/templates/subdir/nested_subdir/_nested_partial.sass
194
194
  - test/sass/templates/subdir/nested_subdir/nested_subdir.sass
195
+ - test/sass/templates/basic.sass
195
196
  - test/sass/templates/_partial.sass
196
197
  - test/sass/templates/options.sass
197
198
  - test/sass/templates/units.sass