From 6d8feeb378441237bada08420078a093f1c71598 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mislav=20Marohni=C4=87?= Date: Thu, 16 Oct 2008 10:37:57 +0200 Subject: [PATCH 1/3] html2haml: fix HTML entities being escaped in erb blocks --- lib/haml/html.rb | 3 +-- test/haml/html2haml_test.rb | 5 +++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/haml/html.rb b/lib/haml/html.rb index e7f063aa..da3c6ea8 100644 --- a/lib/haml/html.rb +++ b/lib/haml/html.rb @@ -131,8 +131,7 @@ module Haml def to_haml(tabs = 0) output = "#{tabulate(tabs)}" if HTML.options[:rhtml] && name[0...5] == 'haml:' - return output + HTML.send("haml_tag_#{name[5..-1]}", - CGI.unescapeHTML(self.innerHTML)) + return output + HTML.send("haml_tag_#{name[5..-1]}", CGI.unescapeHTML(self.inner_text)) end output += "%#{name}" unless name == 'div' && (attributes.include?('id') || attributes.include?('class')) diff --git a/test/haml/html2haml_test.rb b/test/haml/html2haml_test.rb index 0132e12f..9eb6a79b 100644 --- a/test/haml/html2haml_test.rb +++ b/test/haml/html2haml_test.rb @@ -40,6 +40,11 @@ class Html2HamlTest < Test::Unit::TestCase assert_equal '= h @item.title', render_rhtml('<%=h @item.title %>') assert_equal '= h @item.title', render_rhtml('<%=h @item.title -%>') end + + def test_rhtml_with_html_special_chars + assert_equal '= 3 < 5 ? "OK" : "Your computer is b0rken"', + render_rhtml(%Q{<%= 3 < 5 ? "OK" : "Your computer is b0rken" %>}) + end protected From 5a447751ccc4a294770f2e255af9ed33e1814404 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mislav=20Marohni=C4=87?= Date: Thu, 16 Oct 2008 11:37:58 +0200 Subject: [PATCH 2/3] html2haml: handle dynamic attributes (RHTML mode) --- lib/haml/html.rb | 50 ++++++++++++++++++++++++++++++++----- test/haml/html2haml_test.rb | 10 ++++++++ 2 files changed, 54 insertions(+), 6 deletions(-) diff --git a/lib/haml/html.rb b/lib/haml/html.rb index da3c6ea8..06192676 100644 --- a/lib/haml/html.rb +++ b/lib/haml/html.rb @@ -134,13 +134,17 @@ module Haml return output + HTML.send("haml_tag_#{name[5..-1]}", CGI.unescapeHTML(self.inner_text)) end - output += "%#{name}" unless name == 'div' && (attributes.include?('id') || attributes.include?('class')) + output += "%#{name}" unless name == 'div' && (static_id? || static_classname?) if attributes - output += "##{attributes['id']}" if attributes['id'] - attributes['class'].split(' ').each { |c| output += ".#{c}" } if attributes['class'] - remove_attribute('id') - remove_attribute('class') + if static_id? + output += "##{attributes['id']}" + remove_attribute('id') + end + if static_classname? + attributes['class'].split(' ').each { |c| output += ".#{c}" } + remove_attribute('class') + end output += haml_attributes if attributes.length > 0 end @@ -155,13 +159,47 @@ module Haml end private + + def dynamic_attributes + @dynamic_attributes ||= begin + attributes.inject({}) do |dynamic, pair| + name, value = pair + unless value.empty? + ruby_value = value.sub(%r{\s*(.+?)\s*}) do |str| + $'.empty? and $`.empty? ? $1: "\#{#{$1}}" + end + unless ruby_value == value + dynamic[name] = ruby_value + end + end + dynamic + end + end + end + + def static_attribute?(name) + attributes[name] and !dynamic_attribute?(name) + end + + def dynamic_attribute?(name) + HTML.options[:rhtml] and dynamic_attributes.key?(name) + end + + def static_id? + static_attribute? 'id' + end + + def static_classname? + static_attribute? 'class' + end # Returns a string representation of an attributes hash # that's prettier than that produced by Hash#inspect def haml_attributes attrs = attributes.map do |name, value| + value = dynamic_attribute?(name) ? dynamic_attributes[name] : value.inspect name = name.index(/\W/) ? name.inspect : ":#{name}" - "#{name} => #{value.inspect}" + "#{name} => #{value}" end "{ #{attrs.join(', ')} }" end diff --git a/test/haml/html2haml_test.rb b/test/haml/html2haml_test.rb index 9eb6a79b..6cac5243 100644 --- a/test/haml/html2haml_test.rb +++ b/test/haml/html2haml_test.rb @@ -45,6 +45,16 @@ class Html2HamlTest < Test::Unit::TestCase assert_equal '= 3 < 5 ? "OK" : "Your computer is b0rken"', render_rhtml(%Q{<%= 3 < 5 ? "OK" : "Your computer is b0rken" %>}) end + + def test_rhtml_in_class_attribute + assert_equal "%div{ :class => dyna_class }\n I have a dynamic attribute", + render_rhtml(%Q{
I have a dynamic attribute
}) + end + + def test_rhtml_in_id_attribute + assert_equal "%div{ :id => dyna_id }\n I have a dynamic attribute", + render_rhtml(%Q{
I have a dynamic attribute
}) + end protected From 9ce2a46adf778d4ea7078797570639a0a8fb784b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mislav=20Marohni=C4=87?= Date: Thu, 16 Oct 2008 11:42:23 +0200 Subject: [PATCH 3/3] html2haml: rhtml in attribute can result in Ruby string interpolation --- lib/haml/html.rb | 8 +++++--- test/haml/html2haml_test.rb | 5 +++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/haml/html.rb b/lib/haml/html.rb index 06192676..de30b35b 100644 --- a/lib/haml/html.rb +++ b/lib/haml/html.rb @@ -165,11 +165,13 @@ module Haml attributes.inject({}) do |dynamic, pair| name, value = pair unless value.empty? - ruby_value = value.sub(%r{\s*(.+?)\s*}) do |str| - $'.empty? and $`.empty? ? $1: "\#{#{$1}}" + full_match = nil + ruby_value = value.sub(%r{\s*(.+?)\s*}) do + full_match = $`.empty? and $'.empty? + full_match ? $1: "\#{#{$1}}" end unless ruby_value == value - dynamic[name] = ruby_value + dynamic[name] = full_match ? ruby_value : %("#{ruby_value}") end end dynamic diff --git a/test/haml/html2haml_test.rb b/test/haml/html2haml_test.rb index 6cac5243..0485fc3d 100644 --- a/test/haml/html2haml_test.rb +++ b/test/haml/html2haml_test.rb @@ -55,6 +55,11 @@ class Html2HamlTest < Test::Unit::TestCase assert_equal "%div{ :id => dyna_id }\n I have a dynamic attribute", render_rhtml(%Q{
I have a dynamic attribute
}) end + + def test_rhtml_in_attribute_results_in_string_interpolation + assert_equal %(%div{ :id => "item_\#{i}" }\n Ruby string interpolation FTW), + render_rhtml(%Q{
Ruby string interpolation FTW
}) + end protected