Skip to content

Commit

Permalink
Deprecate block_called_from_erb? pending a solution for getting it in…
Browse files Browse the repository at this point in the history
…to apps
  • Loading branch information
Carlhuda authored and wycats committed Mar 10, 2010
1 parent f30b7a0 commit 4464b8e
Show file tree
Hide file tree
Showing 9 changed files with 154 additions and 64 deletions.
1 change: 1 addition & 0 deletions actionpack/lib/action_view/helpers.rb
Expand Up @@ -10,6 +10,7 @@ module Helpers #:nodoc:
autoload :CsrfHelper, 'action_view/helpers/csrf_helper'
autoload :DateHelper, 'action_view/helpers/date_helper'
autoload :DebugHelper, 'action_view/helpers/debug_helper'
autoload :DeprecatedBlockHelpers, 'action_view/helpers/deprecated_block_helpers'
autoload :FormHelper, 'action_view/helpers/form_helper'
autoload :FormOptionsHelper, 'action_view/helpers/form_options_helper'
autoload :FormTagHelper, 'action_view/helpers/form_tag_helper'
Expand Down
14 changes: 5 additions & 9 deletions actionpack/lib/action_view/helpers/capture_helper.rb
Expand Up @@ -30,14 +30,10 @@ module CaptureHelper
# <b><%= @greeting %></b>
# </body></html>
#
def capture(*args, &block)
# Return captured buffer in erb.
if block_called_from_erb?(block)
with_output_buffer { block.call(*args) }
else
# Return block result otherwise, but protect buffer also.
with_output_buffer { return block.call(*args) }
end
def capture(*args)
value = nil
buffer = with_output_buffer { value = yield *args }
buffer.presence || value
end

# Calling content_for stores a block of markup in an identifier for later use.
Expand Down Expand Up @@ -143,7 +139,7 @@ def content_for?(name)
# Defaults to a new empty string.
def with_output_buffer(buf = nil) #:nodoc:
unless buf
buf = ActiveSupport::SafeBuffer.new
buf = ActionView::OutputBuffer.new
buf.force_encoding(output_buffer.encoding) if buf.respond_to?(:force_encoding)
end
self.output_buffer, old_buffer = buf, output_buffer
Expand Down
35 changes: 35 additions & 0 deletions actionpack/lib/action_view/helpers/deprecated_block_helpers.rb
@@ -0,0 +1,35 @@
module ActionView
module Helpers
module DeprecatedBlockHelpers
extend ActiveSupport::Concern

include ActionView::Helpers::TagHelper
include ActionView::Helpers::TextHelper
include ActionView::Helpers::JavaScriptHelper

def content_tag(*, &block)
block_called_from_erb?(block) ? safe_concat(super) : super
end

def javascript_tag(*, &block)
block_called_from_erb?(block) ? safe_concat(super) : super
end

BLOCK_CALLED_FROM_ERB = 'defined? __in_erb_template'

if RUBY_VERSION < '1.9.0'
# Check whether we're called from an erb template.
# We'd return a string in any other case, but erb <%= ... %>
# can't take an <% end %> later on, so we have to use <% ... %>
# and implicitly concat.
def block_called_from_erb?(block)
block && eval(BLOCK_CALLED_FROM_ERB, block)
end
else
def block_called_from_erb?(block)
block && eval(BLOCK_CALLED_FROM_ERB, block.binding)
end
end
end
end
end
8 changes: 1 addition & 7 deletions actionpack/lib/action_view/helpers/javascript_helper.rb
Expand Up @@ -83,13 +83,7 @@ def javascript_tag(content_or_options_with_block = nil, html_options = {}, &bloc
content_or_options_with_block
end

tag = content_tag(:script, javascript_cdata_section(content), html_options.merge(:type => Mime::JS))

if block_called_from_erb?(block)
safe_concat(tag)
else
tag
end
content_tag(:script, javascript_cdata_section(content), html_options.merge(:type => Mime::JS))
end

def javascript_cdata_section(content) #:nodoc:
Expand Down
26 changes: 4 additions & 22 deletions actionpack/lib/action_view/helpers/tag_helper.rb
Expand Up @@ -7,6 +7,9 @@ module Helpers #:nodoc:
module TagHelper
include ERB::Util

extend ActiveSupport::Concern
include CaptureHelper

BOOLEAN_ATTRIBUTES = %w(disabled readonly multiple checked autobuffer
autoplay controls loop selected hidden scoped async
defer reversed ismap seemless muted required
Expand Down Expand Up @@ -69,13 +72,7 @@ def tag(name, options = nil, open = false, escape = true)
def content_tag(name, content_or_options_with_block = nil, options = nil, escape = true, &block)
if block_given?
options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash)
content_tag = content_tag_string(name, capture(&block), options, escape)

if block_called_from_erb?(block)
safe_concat(content_tag)
else
content_tag
end
content_tag_string(name, capture(&block), options, escape)
else
content_tag_string(name, content_or_options_with_block, options, escape)
end
Expand Down Expand Up @@ -109,21 +106,6 @@ def escape_once(html)
end

private
BLOCK_CALLED_FROM_ERB = 'defined? __in_erb_template'

if RUBY_VERSION < '1.9.0'
# Check whether we're called from an erb template.
# We'd return a string in any other case, but erb <%= ... %>
# can't take an <% end %> later on, so we have to use <% ... %>
# and implicitly concat.
def block_called_from_erb?(block)
block && eval(BLOCK_CALLED_FROM_ERB, block)
end
else
def block_called_from_erb?(block)
block && eval(BLOCK_CALLED_FROM_ERB, block.binding)
end
end

def content_tag_string(name, content, options, escape = true)
tag_options = tag_options(options, escape) if options
Expand Down
46 changes: 41 additions & 5 deletions actionpack/lib/action_view/template/handlers/erb.rb
Expand Up @@ -3,10 +3,46 @@
require 'erubis'

module ActionView
class OutputBuffer
def initialize
@buffer = ActiveSupport::SafeBuffer.new
end

def safe_concat(value)
@buffer.safe_concat(value)
end

def <<(value)
@buffer << value.to_s
end

def length
@buffer.length
end

def [](*args)
@buffer[*args]
end

def to_s
@buffer.to_s
end

def empty?
@buffer.empty?
end

if "".respond_to?(:force_encoding)
def force_encoding(encoding)
@buffer.force_encoding(encoding)
end
end
end

module Template::Handlers
class Erubis < ::Erubis::Eruby
def add_preamble(src)
src << "@output_buffer = ActiveSupport::SafeBuffer.new;"
src << "@output_buffer = ActionView::OutputBuffer.new;"
end

def add_text(src, text)
Expand All @@ -15,10 +51,10 @@ def add_text(src, text)
end

def add_expr_literal(src, code)
if code =~ /\s*raw\s+(.*)/
src << "@output_buffer.safe_concat((" << $1 << ").to_s);"
if code =~ /(do|\{)(\s*\|[^|]*\|)?\s*\Z/
src << '@output_buffer << ' << code
else
src << '@output_buffer << ((' << code << ').to_s);'
src << '@output_buffer << (' << code << ');'
end
end

Expand All @@ -42,7 +78,7 @@ class ERB < Template::Handler
self.erb_trim_mode = '-'

self.default_format = Mime::HTML

cattr_accessor :erb_implementation
self.erb_implementation = Erubis

Expand Down
60 changes: 60 additions & 0 deletions actionpack/test/template/erb/tag_helper_test.rb
@@ -0,0 +1,60 @@
require "abstract_unit"

module ERBTest
module SharedTagHelpers
extend ActiveSupport::Testing::Declarative

def render_content(start, inside)
template = block_helper(start, inside)
ActionView::Template::Handlers::Erubis.new(template).evaluate(context.new)
end

test "percent equals works for content_tag" do
assert_equal "<div>Hello world</div>", render_content("content_tag(:div)", "Hello world")
end

test "percent equals works for javascript_tag" do
expected_output = "<script type=\"text/javascript\">\n//<![CDATA[\nalert('Hello')\n//]]>\n</script>"
assert_equal expected_output, render_content("javascript_tag", "alert('Hello')")
end

test "percent equals works for javascript_tag with options" do
expected_output = "<script id=\"the_js_tag\" type=\"text/javascript\">\n//<![CDATA[\nalert('Hello')\n//]]>\n</script>"
assert_equal expected_output, render_content("javascript_tag(:id => 'the_js_tag')", "alert('Hello')")
end
end

class TagHelperTest < ActiveSupport::TestCase
def context
Class.new do
include ActionView::Helpers::TagHelper
include ActionView::Helpers::JavaScriptHelper

attr_accessor :output_buffer
end
end

def block_helper(str, rest)
"<%= #{str} do %>#{rest}<% end %>"
end

include SharedTagHelpers
end

class DeprecatedTagHelperTest < ActiveSupport::TestCase
def context
Class.new do
include ActionView::Helpers::TagHelper
include ActionView::Helpers::JavaScriptHelper
include ActionView::Helpers::DeprecatedBlockHelpers
attr_accessor :output_buffer
end
end

def block_helper(str, rest)
"<% __in_erb_template=true %><% #{str} do %>#{rest}<% end %>"
end

include SharedTagHelpers
end
end
12 changes: 0 additions & 12 deletions actionpack/test/template/javascript_helper_test.rb
Expand Up @@ -74,18 +74,6 @@ def test_javascript_tag_with_options
javascript_tag("alert('hello')", :id => "the_js_tag")
end

def test_javascript_tag_with_block_in_erb
__in_erb_template = ''
javascript_tag { concat "alert('hello')" }
assert_dom_equal "<script type=\"text/javascript\">\n//<![CDATA[\nalert('hello')\n//]]>\n</script>", output_buffer
end

def test_javascript_tag_with_block_and_options_in_erb
__in_erb_template = ''
javascript_tag(:id => "the_js_tag") { concat "alert('hello')" }
assert_dom_equal "<script id=\"the_js_tag\" type=\"text/javascript\">\n//<![CDATA[\nalert('hello')\n//]]>\n</script>", output_buffer
end

def test_javascript_cdata_section
assert_dom_equal "\n//<![CDATA[\nalert('hello')\n//]]>\n", javascript_cdata_section("alert('hello')")
end
Expand Down
16 changes: 7 additions & 9 deletions actionpack/test/template/tag_helper_test.rb
Expand Up @@ -42,15 +42,13 @@ def test_content_tag
end

def test_content_tag_with_block_in_erb
__in_erb_template = ''
content_tag(:div) { concat "Hello world!" }
assert_dom_equal "<div>Hello world!</div>", output_buffer
buffer = content_tag(:div) { concat "Hello world!" }
assert_dom_equal "<div>Hello world!</div>", buffer
end

def test_content_tag_with_block_and_options_in_erb
__in_erb_template = ''
content_tag(:div, :class => "green") { concat "Hello world!" }
assert_dom_equal %(<div class="green">Hello world!</div>), output_buffer
buffer = content_tag(:div, :class => "green") { concat "Hello world!" }
assert_dom_equal %(<div class="green">Hello world!</div>), buffer
end

def test_content_tag_with_block_and_options_out_of_erb
Expand All @@ -68,10 +66,10 @@ def test_content_tag_nested_in_content_tag_out_of_erb
output_buffer
end

# TAG TODO: Move this into a real template
def test_content_tag_nested_in_content_tag_in_erb
__in_erb_template = true
content_tag("p") { concat content_tag("b", "Hello") }
assert_equal '<p><b>Hello</b></p>', output_buffer
buffer = content_tag("p") { concat content_tag("b", "Hello") }
assert_equal '<p><b>Hello</b></p>', buffer
end

def test_content_tag_with_escaped_array_class
Expand Down

0 comments on commit 4464b8e

Please sign in to comment.