aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib')
-rw-r--r--actionpack/lib/action_view/base.rb18
-rw-r--r--actionpack/lib/action_view/helpers/capture_helper.rb54
-rw-r--r--actionpack/lib/action_view/helpers/form_helper.rb4
-rw-r--r--actionpack/lib/action_view/helpers/form_tag_helper.rb14
-rw-r--r--actionpack/lib/action_view/helpers/javascript_helper.rb25
-rw-r--r--actionpack/lib/action_view/helpers/prototype_helper.rb4
-rw-r--r--actionpack/lib/action_view/helpers/record_tag_helper.rb5
-rw-r--r--actionpack/lib/action_view/helpers/tag_helper.rb9
-rw-r--r--actionpack/lib/action_view/helpers/text_helper.rb14
-rw-r--r--actionpack/lib/action_view/template_handlers/builder.rb7
-rw-r--r--actionpack/lib/action_view/template_handlers/compilable.rb4
-rw-r--r--actionpack/lib/action_view/template_handlers/erb.rb6
12 files changed, 65 insertions, 99 deletions
diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb
index b2fcbfa554..eeebf335dc 100644
--- a/actionpack/lib/action_view/base.rb
+++ b/actionpack/lib/action_view/base.rb
@@ -156,10 +156,12 @@ module ActionView #:nodoc:
attr_reader :finder
attr_accessor :base_path, :assigns, :template_extension, :first_render
attr_accessor :controller
-
+
attr_writer :template_format
attr_accessor :current_render_extension
+ attr_accessor :output_buffer
+
# Specify trim mode for the ERB compiler. Defaults to '-'.
# See ERb documentation for suitable values.
@@erb_trim_mode = '-'
@@ -178,10 +180,7 @@ module ActionView #:nodoc:
# that alert()s the caught exception (and then re-raises it).
@@debug_rjs = false
cattr_accessor :debug_rjs
-
- @@erb_variable = '_erbout'
- cattr_accessor :erb_variable
-
+
attr_internal :request
delegate :request_forgery_protection_token, :template, :params, :session, :cookies, :response, :headers,
@@ -259,7 +258,7 @@ If you are rendering a subtemplate, you must now use controller-like partial syn
if partial_layout = options.delete(:layout)
if block_given?
wrap_content_for_layout capture(&block) do
- concat(render(options.merge(:partial => partial_layout)), block.binding)
+ concat(render(options.merge(:partial => partial_layout)))
end
else
wrap_content_for_layout render(options) do
@@ -317,9 +316,10 @@ If you are rendering a subtemplate, you must now use controller-like partial syn
private
def wrap_content_for_layout(content)
- original_content_for_layout = @content_for_layout
- @content_for_layout = content
- returning(yield) { @content_for_layout = original_content_for_layout }
+ original_content_for_layout, @content_for_layout = @content_for_layout, content
+ yield
+ ensure
+ @content_for_layout = original_content_for_layout
end
# Evaluate the local assigns and pushes them to the view.
diff --git a/actionpack/lib/action_view/helpers/capture_helper.rb b/actionpack/lib/action_view/helpers/capture_helper.rb
index 9ea06568cf..25e62f78fb 100644
--- a/actionpack/lib/action_view/helpers/capture_helper.rb
+++ b/actionpack/lib/action_view/helpers/capture_helper.rb
@@ -31,20 +31,13 @@ module ActionView
# </body></html>
#
def capture(*args, &block)
- # execute the block
- begin
- buffer = eval(ActionView::Base.erb_variable, block.binding)
- rescue
- buffer = nil
- end
-
- if buffer.nil?
- capture_block(*args, &block).to_s
+ if @output_buffer
+ with_output_buffer { block.call(*args) }
else
- capture_erb_with_buffer(buffer, *args, &block).to_s
+ block.call(*args)
end
end
-
+
# Calling content_for stores a block of markup in an identifier for later use.
# You can make subsequent calls to the stored content in other templates or the layout
# by passing the identifier as an argument to <tt>yield</tt>.
@@ -121,40 +114,17 @@ module ActionView
# named <tt>@content_for_#{name_of_the_content_block}</tt>. The preferred usage is now
# <tt><%= yield :footer %></tt>.
def content_for(name, content = nil, &block)
- existing_content_for = instance_variable_get("@content_for_#{name}").to_s
- new_content_for = existing_content_for + (block_given? ? capture(&block) : content)
- instance_variable_set("@content_for_#{name}", new_content_for)
+ ivar = "@content_for_#{name}"
+ content = capture(&block) if block_given?
+ instance_variable_set(ivar, "#{instance_variable_get(ivar)}#{content}")
end
private
- def capture_block(*args, &block)
- block.call(*args)
- end
-
- def capture_erb(*args, &block)
- buffer = eval(ActionView::Base.erb_variable, block.binding)
- capture_erb_with_buffer(buffer, *args, &block)
- end
-
- def capture_erb_with_buffer(buffer, *args, &block)
- pos = buffer.length
- block.call(*args)
-
- # extract the block
- data = buffer[pos..-1]
-
- # replace it in the original with empty string
- buffer[pos..-1] = ''
-
- data
- end
-
- def erb_content_for(name, &block)
- eval "@content_for_#{name} = (@content_for_#{name} || '') + capture_erb(&block)"
- end
-
- def block_content_for(name, &block)
- eval "@content_for_#{name} = (@content_for_#{name} || '') + capture_block(&block)"
+ def with_output_buffer(buf = '')
+ @output_buffer, old_buffer = buf, @output_buffer
+ yield
+ ensure
+ @output_buffer = old_buffer
end
end
end
diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb
index 0791feb9ac..63a932320e 100644
--- a/actionpack/lib/action_view/helpers/form_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_helper.rb
@@ -249,9 +249,9 @@ module ActionView
args.unshift object
end
- concat(form_tag(options.delete(:url) || {}, options.delete(:html) || {}), proc.binding)
+ concat(form_tag(options.delete(:url) || {}, options.delete(:html) || {}))
fields_for(object_name, *(args << options), &proc)
- concat('</form>', proc.binding)
+ concat('</form>')
end
def apply_form_for_options!(object_or_array, options) #:nodoc:
diff --git a/actionpack/lib/action_view/helpers/form_tag_helper.rb b/actionpack/lib/action_view/helpers/form_tag_helper.rb
index ca58f4ba26..3a97f1390f 100644
--- a/actionpack/lib/action_view/helpers/form_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_tag_helper.rb
@@ -407,10 +407,10 @@ module ActionView
# # => <fieldset><legend>Your details</legend><p><input id="name" name="name" type="text" /></p></fieldset>
def field_set_tag(legend = nil, &block)
content = capture(&block)
- concat(tag(:fieldset, {}, true), block.binding)
- concat(content_tag(:legend, legend), block.binding) unless legend.blank?
- concat(content, block.binding)
- concat("</fieldset>", block.binding)
+ concat(tag(:fieldset, {}, true))
+ concat(content_tag(:legend, legend)) unless legend.blank?
+ concat(content)
+ concat("</fieldset>")
end
private
@@ -442,9 +442,9 @@ module ActionView
def form_tag_in_block(html_options, &block)
content = capture(&block)
- concat(form_tag_html(html_options), block.binding)
- concat(content, block.binding)
- concat("</form>", block.binding)
+ concat(form_tag_html(html_options))
+ concat(content)
+ concat("</form>")
end
def token_tag
diff --git a/actionpack/lib/action_view/helpers/javascript_helper.rb b/actionpack/lib/action_view/helpers/javascript_helper.rb
index 1ea3cbd74e..85b205c264 100644
--- a/actionpack/lib/action_view/helpers/javascript_helper.rb
+++ b/actionpack/lib/action_view/helpers/javascript_helper.rb
@@ -172,20 +172,17 @@ module ActionView
# alert('All is good')
# <% end -%>
def javascript_tag(content_or_options_with_block = nil, html_options = {}, &block)
- if block_given?
- html_options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash)
- content = capture(&block)
- else
- content = content_or_options_with_block
- end
+ content =
+ if block_given?
+ html_options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash)
+ capture(&block)
+ else
+ content_or_options_with_block
+ end
- javascript_tag = content_tag("script", javascript_cdata_section(content), html_options.merge(:type => Mime::JS))
-
- if block_given? && block_is_within_action_view?(block)
- concat(javascript_tag, block.binding)
- else
- javascript_tag
- end
+ tag = content_tag("script", javascript_cdata_section(content), html_options.merge(:type => Mime::JS))
+
+ block_given? ? concat(tag) : tag
end
def javascript_cdata_section(content) #:nodoc:
@@ -208,7 +205,7 @@ module ActionView
private
def block_is_within_action_view?(block)
- eval("defined? _erbout", block.binding)
+ !@output_buffer.nil?
end
end
diff --git a/actionpack/lib/action_view/helpers/prototype_helper.rb b/actionpack/lib/action_view/helpers/prototype_helper.rb
index 5a1012954e..a7c3b9ddc3 100644
--- a/actionpack/lib/action_view/helpers/prototype_helper.rb
+++ b/actionpack/lib/action_view/helpers/prototype_helper.rb
@@ -382,9 +382,9 @@ module ActionView
args.unshift object
end
- concat(form_remote_tag(options), proc.binding)
+ concat(form_remote_tag(options))
fields_for(object_name, *(args << options), &proc)
- concat('</form>', proc.binding)
+ concat('</form>')
end
alias_method :form_remote_for, :remote_form_for
diff --git a/actionpack/lib/action_view/helpers/record_tag_helper.rb b/actionpack/lib/action_view/helpers/record_tag_helper.rb
index 66c596f3a9..9bb235175e 100644
--- a/actionpack/lib/action_view/helpers/record_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/record_tag_helper.rb
@@ -51,9 +51,8 @@ module ActionView
prefix = args.first.is_a?(Hash) ? nil : args.shift
options = args.first.is_a?(Hash) ? args.shift : {}
concat content_tag(tag_name, capture(&block),
- options.merge({ :class => "#{dom_class(record)} #{options[:class]}".strip, :id => dom_id(record, prefix) })),
- block.binding
+ options.merge({ :class => "#{dom_class(record)} #{options[:class]}".strip, :id => dom_id(record, prefix) }))
end
end
end
-end \ No newline at end of file
+end
diff --git a/actionpack/lib/action_view/helpers/tag_helper.rb b/actionpack/lib/action_view/helpers/tag_helper.rb
index ba43b5e8ef..a8a5987b1f 100644
--- a/actionpack/lib/action_view/helpers/tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/tag_helper.rb
@@ -68,12 +68,9 @@ module ActionView
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 = capture(&block)
- content_tag = content_tag_string(name, content, options, escape)
- block_is_within_action_view?(block) ? concat(content_tag, block.binding) : content_tag
+ concat(content_tag_string(name, capture(&block), options, escape))
else
- content = content_or_options_with_block
- content_tag_string(name, content, options, escape)
+ content_tag_string(name, content_or_options_with_block, options, escape)
end
end
@@ -127,7 +124,7 @@ module ActionView
end
def block_is_within_action_view?(block)
- eval("defined? _erbout", block.binding)
+ !@output_buffer.nil?
end
end
end
diff --git a/actionpack/lib/action_view/helpers/text_helper.rb b/actionpack/lib/action_view/helpers/text_helper.rb
index 669a285424..f81f7eded6 100644
--- a/actionpack/lib/action_view/helpers/text_helper.rb
+++ b/actionpack/lib/action_view/helpers/text_helper.rb
@@ -15,18 +15,22 @@ module ActionView
#
# ==== Examples
# <%
- # concat "hello", binding
+ # concat "hello"
# # is the equivalent of <%= "hello" %>
#
# if (logged_in == true):
- # concat "Logged in!", binding
+ # concat "Logged in!"
# else
- # concat link_to('login', :action => login), binding
+ # concat link_to('login', :action => login)
# end
# # will either display "Logged in!" or a login link
# %>
- def concat(string, binding)
- eval(ActionView::Base.erb_variable, binding) << string
+ def concat(string)
+ if @output_buffer && string
+ @output_buffer << string
+ else
+ string
+ end
end
if RUBY_VERSION < '1.9'
diff --git a/actionpack/lib/action_view/template_handlers/builder.rb b/actionpack/lib/action_view/template_handlers/builder.rb
index f76d89777a..ee02ce1a6f 100644
--- a/actionpack/lib/action_view/template_handlers/builder.rb
+++ b/actionpack/lib/action_view/template_handlers/builder.rb
@@ -11,10 +11,11 @@ module ActionView
def compile(template)
content_type_handler = (@view.send!(:controller).respond_to?(:response) ? "controller.response" : "controller")
+
"#{content_type_handler}.content_type ||= Mime::XML\n" +
- "xml = ::Builder::XmlMarkup.new(:indent => 2)\n" +
- template.source +
- "\nxml.target!\n"
+ "xml = ::Builder::XmlMarkup.new(:indent => 2)\n" +
+ template.source +
+ "\nxml.target!\n"
end
def cache_fragment(block, name = {}, options = nil)
diff --git a/actionpack/lib/action_view/template_handlers/compilable.rb b/actionpack/lib/action_view/template_handlers/compilable.rb
index 25bd0fea7f..28c72172a0 100644
--- a/actionpack/lib/action_view/template_handlers/compilable.rb
+++ b/actionpack/lib/action_view/template_handlers/compilable.rb
@@ -106,7 +106,7 @@ module ActionView
locals_code << "#{key} = local_assigns[:#{key}]\n"
end
- "def #{render_symbol}(local_assigns)\n#{locals_code}#{body}\nend"
+ "def #{render_symbol}(local_assigns)\nold_output_buffer = @output_buffer;#{locals_code}#{body}\nensure\n@output_buffer = old_output_buffer\nend"
end
# Return true if the given template was compiled for a superset of the keys in local_assigns
@@ -125,4 +125,4 @@ module ActionView
end
end
-end \ No newline at end of file
+end
diff --git a/actionpack/lib/action_view/template_handlers/erb.rb b/actionpack/lib/action_view/template_handlers/erb.rb
index 15a9064461..ad4ccc7c42 100644
--- a/actionpack/lib/action_view/template_handlers/erb.rb
+++ b/actionpack/lib/action_view/template_handlers/erb.rb
@@ -43,13 +43,11 @@ module ActionView
include Compilable
def compile(template)
- ::ERB.new(template.source, nil, @view.erb_trim_mode).src
+ ::ERB.new(template.source, nil, @view.erb_trim_mode, '@output_buffer').src
end
def cache_fragment(block, name = {}, options = nil) #:nodoc:
- @view.fragment_for(block, name, options) do
- eval(ActionView::Base.erb_variable, block.binding)
- end
+ @view.fragment_for(block, name, options) { @view.response.template.output_buffer ||= '' }
end
end
end