diff --git a/lib/haml/helpers.rb b/lib/haml/helpers.rb index b839dc47..dcc7e510 100644 --- a/lib/haml/helpers.rb +++ b/lib/haml/helpers.rb @@ -1,3 +1,5 @@ +require File.dirname(__FILE__) + '/helpers/action_view_mods' + module Haml # This module contains various helpful methods to make it easier to do # various tasks. Haml::Helpers is automatically included in the context @@ -5,6 +7,19 @@ module Haml # disposal from within the template. module Helpers self.extend self + + @@action_view = false + @@force_no_action_view = false + + # Returns whether or not ActionView is available. + def self.action_view? + @@action_view + end + + # Sets whether or not ActionView is available. + def self.action_view(value) # :nodoc: + @@action_view = value + end # Takes any string, finds all the endlines and converts them to # html entities for endlines so they'll render correctly in @@ -49,5 +64,7 @@ module Haml def buffer # :nodoc: @haml_stack[-1] end + + include ActionViewMods if self.const_defined? "ActionViewMods" end end diff --git a/lib/haml/helpers/action_view_mods.rb b/lib/haml/helpers/action_view_mods.rb new file mode 100644 index 00000000..0a727b0d --- /dev/null +++ b/lib/haml/helpers/action_view_mods.rb @@ -0,0 +1,32 @@ +begin + require 'rubygems' + require 'active_support' + require 'action_view' + action_view_included = true +rescue LoadError + action_view_included = false +end + +if action_view_included + class ActionView::Base + alias_method :old_concat, :concat unless instance_methods.include? "old_concat" + end + + module Haml + module Helpers + # This module overrides various helpers in ActionView to make them + # work more effectively with Haml. It's not available unless ActionView + # is installed. + module ActionViewMods + def self.included(othermod) + othermod.action_view(true) + end + + def concat(string, binding = nil) + buffer.buffer.concat(string) + end + end + end + end +end + diff --git a/test/helper_test.rb b/test/helper_test.rb index 3402d558..a754184f 100644 --- a/test/helper_test.rb +++ b/test/helper_test.rb @@ -35,17 +35,45 @@ class HelperTest < Test::Unit::TestCase assert_equal(render("foo\n- tab_up\nbar\n- tab_down\nbaz"), "foo\n bar\nbaz\n") end - def test_helper_leak + def test_helpers_dont_leak # Haml helpers shouldn't be accessible from ERB render("foo") proper_behavior = false - + begin ActionView::Base.new.render(:inline => "<%= flatten('Foo\\nBar') %>") rescue NoMethodError proper_behavior = true end - + assert(proper_behavior) + + begin + ActionView::Base.new.render(:inline => "<%= concat('foo') %>") + rescue ArgumentError + proper_behavior = true + end assert(proper_behavior) end + + def test_action_view_included + assert(Haml::Helpers.action_view?) + end + + def test_action_view_not_included + #This is for 100% rcov, rather than any real testing purposes. + Kernel.module_eval do + alias_method :old_require, :require + def require(string) + raise LoadError if string == "action_view" + old_require string + end + end + + load File.dirname(__FILE__) + '/../lib/haml/helpers/action_view_mods.rb' + + Kernel.module_eval do + alias_method :require, :old_require + end + end end + diff --git a/test/results/helpers.xhtml b/test/results/helpers.xhtml index 7249f160..0aada943 100644 --- a/test/results/helpers.xhtml +++ b/test/results/helpers.xhtml @@ -29,3 +29,5 @@

baz

boom

+foo + diff --git a/test/templates/helpers.haml b/test/templates/helpers.haml index b33627b9..a88d4375 100644 --- a/test/templates/helpers.haml +++ b/test/templates/helpers.haml @@ -15,3 +15,5 @@ %p baz - buffer.tabulation = 10 %p boom +- concat "foo\n" +