diff options
Diffstat (limited to 'actionpack/lib/action_view/helpers')
15 files changed, 211 insertions, 172 deletions
diff --git a/actionpack/lib/action_view/helpers/active_model_helper.rb b/actionpack/lib/action_view/helpers/active_model_helper.rb index e106bb0897..4e12cdab54 100644 --- a/actionpack/lib/action_view/helpers/active_model_helper.rb +++ b/actionpack/lib/action_view/helpers/active_model_helper.rb @@ -5,9 +5,11 @@ require 'active_support/core_ext/enumerable' require 'active_support/core_ext/kernel/reporting' module ActionView - class Base - @@field_error_proc = Proc.new{ |html_tag, instance| "<div class=\"fieldWithErrors\">#{html_tag}</div>".html_safe } - cattr_accessor :field_error_proc + ActionView.base_hook do + class ActionView::Base + @@field_error_proc = Proc.new{ |html_tag, instance| "<div class=\"fieldWithErrors\">#{html_tag}</div>".html_safe } + cattr_accessor :field_error_proc + end end module Helpers @@ -80,13 +82,13 @@ module ActionView record = convert_to_model(record) options = options.symbolize_keys - options[:action] ||= record.new_record? ? "create" : "update" + options[:action] ||= record.persisted? ? "update" : "create" action = url_for(:action => options[:action], :id => record) submit_value = options[:submit_value] || options[:action].gsub(/[^\w]/, '').capitalize contents = form_tag({:action => action}, :method =>(options[:method] || 'post'), :enctype => options[:multipart] ? 'multipart/form-data': nil) - contents.safe_concat hidden_field(record_name, :id) unless record.new_record? + contents.safe_concat hidden_field(record_name, :id) if record.persisted? contents.safe_concat all_input_tags(record, record_name, options) yield contents if block_given? contents.safe_concat submit_tag(submit_value) @@ -127,7 +129,7 @@ module ActionView if (obj = (object.respond_to?(:errors) ? object : instance_variable_get("@#{object}"))) && (errors = obj.errors[method]) content_tag("div", - "#{options[:prepend_text]}#{ERB::Util.html_escape(errors.first)}#{options[:append_text]}", + (options[:prepend_text].html_safe << errors.first).safe_concat(options[:append_text]), :class => options[:css_class] ) else @@ -226,16 +228,16 @@ module ActionView error_messages = objects.sum do |object| object.errors.full_messages.map do |msg| - content_tag(:li, ERB::Util.html_escape(msg)) + content_tag(:li, msg) end - end.join + end.join.html_safe contents = '' contents << content_tag(options[:header_tag] || :h2, header_message) unless header_message.blank? contents << content_tag(:p, message) unless message.blank? contents << content_tag(:ul, error_messages) - content_tag(:div, contents, html) + content_tag(:div, contents.html_safe, html) end else '' diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb index 96976ce45f..0c488b6793 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb @@ -11,7 +11,7 @@ module ActionView # the assets exist before linking to them: # # image_tag("rails.png") - # # => <img alt="Rails src="/images/rails.png?1230601161" /> + # # => <img alt="Rails" src="/images/rails.png?1230601161" /> # stylesheet_link_tag("application") # # => <link href="/stylesheets/application.css?1232285206" media="screen" rel="stylesheet" type="text/css" /> # @@ -133,13 +133,6 @@ module ActionView # change. You can use something like Live HTTP Headers for Firefox to verify # that the cache is indeed working. module AssetTagHelper - assets_dir = defined?(Rails.public_path) ? Rails.public_path : "public" - ActionView::DEFAULT_CONFIG = { - :assets_dir => assets_dir, - :javascripts_dir => "#{assets_dir}/javascripts", - :stylesheets_dir => "#{assets_dir}/stylesheets", - } - JAVASCRIPT_DEFAULT_SOURCES = ['prototype', 'effects', 'dragdrop', 'controls', 'rails'].freeze unless const_defined?(:JAVASCRIPT_DEFAULT_SOURCES) # Returns a link tag that browsers and news readers can use to auto-detect @@ -530,7 +523,7 @@ module ActionView options.symbolize_keys! src = options[:src] = path_to_image(source) - options[:alt] ||= File.basename(src, '.*').split('.').first.to_s.capitalize + options[:alt] ||= File.basename(src, '.*').capitalize if size = options.delete(:size) options[:width], options[:height] = size.split("x") if size =~ %r{^\d+x\d+$} @@ -648,8 +641,8 @@ module ActionView source = rewrite_asset_path(source) if has_request && include_host - unless source =~ %r{^#{ActionController::Base.relative_url_root}/} - source = "#{ActionController::Base.relative_url_root}#{source}" + unless source =~ %r{^#{controller.config.relative_url_root}/} + source = "#{controller.config.relative_url_root}#{source}" end end end @@ -677,7 +670,7 @@ module ActionView # or the value returned from invoking the proc if it's a proc or the value from # invoking call if it's an object responding to call. def compute_asset_host(source) - if host = ActionController::Base.asset_host + if host = config.asset_host if host.is_a?(Proc) || host.respond_to?(:call) case host.is_a?(Proc) ? host.arity : host.method(:call).arity when 2 diff --git a/actionpack/lib/action_view/helpers/atom_feed_helper.rb b/actionpack/lib/action_view/helpers/atom_feed_helper.rb index 9951e11a37..58c3a8752e 100644 --- a/actionpack/lib/action_view/helpers/atom_feed_helper.rb +++ b/actionpack/lib/action_view/helpers/atom_feed_helper.rb @@ -8,7 +8,7 @@ module ActionView # Full usage example: # # config/routes.rb: - # ActionController::Routing::Routes.draw do |map| + # Basecamp::Application.routes.draw do |map| # map.resources :posts # map.root :controller => "posts" # end @@ -114,7 +114,7 @@ module ActionView feed_opts.merge!(options).reject!{|k,v| !k.to_s.match(/^xml/)} xml.feed(feed_opts) do - xml.id(options[:id] || "tag:#{request.host},#{options[:schema_date]}:#{request.request_uri.split(".")[0]}") + xml.id(options[:id] || "tag:#{request.host},#{options[:schema_date]}:#{request.fullpath.split(".")[0]}") xml.link(:rel => 'alternate', :type => 'text/html', :href => options[:root_url] || (request.protocol + request.host_with_port)) xml.link(:rel => 'self', :type => 'application/atom+xml', :href => options[:url] || request.url) diff --git a/actionpack/lib/action_view/helpers/capture_helper.rb b/actionpack/lib/action_view/helpers/capture_helper.rb index 8c48300ed3..75fc2fddeb 100644 --- a/actionpack/lib/action_view/helpers/capture_helper.rb +++ b/actionpack/lib/action_view/helpers/capture_helper.rb @@ -30,14 +30,10 @@ module ActionView # <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. @@ -143,7 +139,7 @@ module ActionView # 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 diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb index 8be2f76bd6..42018ee261 100644 --- a/actionpack/lib/action_view/helpers/date_helper.rb +++ b/actionpack/lib/action_view/helpers/date_helper.rb @@ -1,5 +1,6 @@ require "date" require 'action_view/helpers/tag_helper' +require 'active_support/core_ext/hash/slice' module ActionView module Helpers @@ -815,7 +816,7 @@ module ActionView tag_options[:selected] = "selected" if selected == i select_options << content_tag(:option, value, tag_options) end - select_options.join("\n") + "\n" + (select_options.join("\n") + "\n").html_safe end # Builds select tag from date type and html select options @@ -833,9 +834,9 @@ module ActionView select_html = "\n" select_html << content_tag(:option, '', :value => '') + "\n" if @options[:include_blank] select_html << prompt_option_tag(type, @options[:prompt]) + "\n" if @options[:prompt] - select_html << select_options_as_html.to_s + select_html << select_options_as_html - (content_tag(:select, select_html, select_options) + "\n").html_safe + (content_tag(:select, select_html.html_safe, select_options) + "\n").html_safe end # Builds a prompt option tag with supplied options or from default options @@ -865,7 +866,7 @@ module ActionView :id => input_id_from_type(type), :name => input_name_from_type(type), :value => value - }) + "\n").html_safe + }.merge(@html_options.slice(:disabled))) + "\n").html_safe end # Returns the name attribute for the input tag @@ -907,7 +908,7 @@ module ActionView when :hour (@options[:discard_year] && @options[:discard_day]) ? "" : @options[:datetime_separator] when :minute - @options[:time_separator] + @options[:discard_minute] ? "" : @options[:time_separator] when :second @options[:include_seconds] ? @options[:time_separator] : "" end diff --git a/actionpack/lib/action_view/helpers/deprecated_block_helpers.rb b/actionpack/lib/action_view/helpers/deprecated_block_helpers.rb new file mode 100644 index 0000000000..3d0657e873 --- /dev/null +++ b/actionpack/lib/action_view/helpers/deprecated_block_helpers.rb @@ -0,0 +1,52 @@ +module ActionView + module Helpers + module DeprecatedBlockHelpers + extend ActiveSupport::Concern + + include ActionView::Helpers::TagHelper + include ActionView::Helpers::TextHelper + include ActionView::Helpers::JavaScriptHelper + include ActionView::Helpers::FormHelper + + 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 + + def form_for(*, &block) + block_called_from_erb?(block) ? safe_concat(super) : super + end + + def form_tag(*, &block) + block_called_from_erb?(block) ? safe_concat(super) : super + end + + def fields_for(*, &block) + block_called_from_erb?(block) ? safe_concat(super) : super + end + + def field_set_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
\ No newline at end of file diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index 305d6b3128..7293145964 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -92,6 +92,10 @@ module ActionView # link:classes/ActionView/Helpers/DateHelper.html, and # link:classes/ActionView/Helpers/ActiveRecordHelper.html module FormHelper + extend ActiveSupport::Concern + + include FormTagHelper + # Creates a form and a scope around a specific model object that is used # as a base for questioning about values for the fields. # @@ -309,21 +313,20 @@ module ActionView options[:html][:remote] = true if options.delete(:remote) - safe_concat(form_tag(options.delete(:url) || {}, options.delete(:html) || {})) - fields_for(object_name, *(args << options), &proc) - safe_concat('</form>') + output = form_tag(options.delete(:url) || {}, options.delete(:html) || {}) + output << fields_for(object_name, *(args << options), &proc) + output.safe_concat('</form>') end def apply_form_for_options!(object_or_array, options) #:nodoc: object = object_or_array.is_a?(Array) ? object_or_array.last : object_or_array - object = convert_to_model(object) html_options = - if object.respond_to?(:new_record?) && object.new_record? - { :class => dom_class(object, :new), :id => dom_id(object), :method => :post } - else + if object.respond_to?(:persisted?) && object.persisted? { :class => dom_class(object, :edit), :id => dom_id(object, :edit), :method => :put } + else + { :class => dom_class(object, :new), :id => dom_id(object), :method => :post } end options[:html] ||= {} @@ -529,7 +532,10 @@ module ActionView end builder = options[:builder] || ActionView::Base.default_form_builder - yield builder.new(object_name, object, self, options, block) + + with_output_buffer do + yield builder.new(object_name, object, self, options, block) + end end # Returns a label tag tailored for labelling an input field for a specified attribute (identified by +method+) on an object @@ -1150,7 +1156,7 @@ module ActionView def submit_default_value object = @object.respond_to?(:to_model) ? @object.to_model : @object - key = object ? (object.new_record? ? :create : :update) : :submit + key = object ? (object.persisted? ? :update : :create) : :submit model = if object.class.respond_to?(:model_name) object.class.model_name.human @@ -1176,7 +1182,7 @@ module ActionView association = args.shift association = association.to_model if association.respond_to?(:to_model) - if association.respond_to?(:new_record?) + if association.respond_to?(:persisted?) association = [association] if @object.send(association_name).is_a?(Array) elsif !association.is_a?(Array) association = @object.send(association_name) @@ -1184,9 +1190,11 @@ module ActionView if association.is_a?(Array) explicit_child_index = options[:child_index] - association.map do |child| - fields_for_nested_model("#{name}[#{explicit_child_index || nested_child_index(name)}]", child, options, block) - end.join + output = ActiveSupport::SafeBuffer.new + association.each do |child| + output << fields_for_nested_model("#{name}[#{explicit_child_index || nested_child_index(name)}]", child, options, block) + end + output elsif association fields_for_nested_model(name, association, options, block) end @@ -1195,13 +1203,13 @@ module ActionView def fields_for_nested_model(name, object, options, block) object = object.to_model if object.respond_to?(:to_model) - if object.new_record? - @template.fields_for(name, object, options, &block) - else + if object.persisted? @template.fields_for(name, object, options) do |builder| block.call(builder) @template.concat builder.hidden_field(:id) unless builder.emitted_hidden_id? end + else + @template.fields_for(name, object, options, &block) end end @@ -1212,8 +1220,10 @@ module ActionView end end - class Base - cattr_accessor :default_form_builder - @@default_form_builder = ::ActionView::Helpers::FormBuilder + ActionView.base_hook do + class ActionView::Base + cattr_accessor :default_form_builder + @@default_form_builder = ::ActionView::Helpers::FormBuilder + end end end diff --git a/actionpack/lib/action_view/helpers/form_options_helper.rb b/actionpack/lib/action_view/helpers/form_options_helper.rb index 21acfbbee8..4c523d4b20 100644 --- a/actionpack/lib/action_view/helpers/form_options_helper.rb +++ b/actionpack/lib/action_view/helpers/form_options_helper.rb @@ -97,7 +97,9 @@ module ActionView # </select> # module FormOptionsHelper + # ERB::Util can mask some helpers like textilize. Make sure to include them. include ERB::Util + include TextHelper # Create a select tag and a series of contained option tags for the provided object and method. # The option currently held by the object will be selected, provided that the object is available. @@ -572,10 +574,9 @@ module ActionView end if value.blank? && options[:prompt] prompt = options[:prompt].kind_of?(String) ? options[:prompt] : I18n.translate('helpers.select.prompt', :default => 'Please select') - "<option value=\"\">#{prompt}</option>\n" + option_tags - else - option_tags + option_tags = "<option value=\"\">#{prompt}</option>\n" + option_tags end + option_tags.html_safe end end diff --git a/actionpack/lib/action_view/helpers/form_tag_helper.rb b/actionpack/lib/action_view/helpers/form_tag_helper.rb index 9d76870646..07694f5ebb 100644 --- a/actionpack/lib/action_view/helpers/form_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/form_tag_helper.rb @@ -10,6 +10,11 @@ module ActionView # NOTE: The HTML options <tt>disabled</tt>, <tt>readonly</tt>, and <tt>multiple</tt> can all be treated as booleans. So specifying # <tt>:disabled => true</tt> will give <tt>disabled="disabled"</tt>. module FormTagHelper + extend ActiveSupport::Concern + + include UrlHelper + include TextHelper + # Starts a form tag that points the action to an url configured with <tt>url_for_options</tt> just like # ActionController::Base#url_for. The method for the form defaults to POST. # @@ -90,9 +95,9 @@ module ActionView html_name = (options[:multiple] == true && !name.to_s.ends_with?("[]")) ? "#{name}[]" : name if blank = options.delete(:include_blank) if blank.kind_of?(String) - option_tags = "<option value=\"\">#{blank}</option>" + option_tags + option_tags = "<option value=\"\">#{blank}</option>".html_safe + option_tags else - option_tags = "<option value=\"\"></option>" + option_tags + option_tags = "<option value=\"\"></option>".html_safe + option_tags end end content_tag :select, option_tags, { "name" => html_name, "id" => sanitize_to_id(name) }.update(options.stringify_keys) @@ -279,7 +284,7 @@ module ActionView escape = options.key?("escape") ? options.delete("escape") : true content = html_escape(content) if escape - content_tag :textarea, content, { "name" => name, "id" => sanitize_to_id(name) }.update(options) + content_tag :textarea, content.html_safe, { "name" => name, "id" => sanitize_to_id(name) }.update(options) end # Creates a check box form input tag. @@ -441,10 +446,10 @@ module ActionView # # => <fieldset class="format"><p><input id="name" name="name" type="text" /></p></fieldset> def field_set_tag(legend = nil, options = nil, &block) content = capture(&block) - safe_concat(tag(:fieldset, options, true)) - safe_concat(content_tag(:legend, legend)) unless legend.blank? - concat(content) - safe_concat("</fieldset>") + output = tag(:fieldset, options, true) + output.safe_concat(content_tag(:legend, legend)) unless legend.blank? + output.concat(content) + output.safe_concat("</fieldset>") end private @@ -477,9 +482,10 @@ module ActionView def form_tag_in_block(html_options, &block) content = capture(&block) - safe_concat(form_tag_html(html_options)) - concat(content) - safe_concat("</form>") + output = ActiveSupport::SafeBuffer.new + output.safe_concat(form_tag_html(html_options)) + output << content + output.safe_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 0a901b2d2b..07eee3b399 100644 --- a/actionpack/lib/action_view/helpers/javascript_helper.rb +++ b/actionpack/lib/action_view/helpers/javascript_helper.rb @@ -83,17 +83,11 @@ module ActionView 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: - "\n//#{cdata_section("\n#{content}\n//")}\n" + "\n//#{cdata_section("\n#{content}\n//")}\n".html_safe end end end diff --git a/actionpack/lib/action_view/helpers/number_helper.rb b/actionpack/lib/action_view/helpers/number_helper.rb index 3d3502a08b..46e41bc406 100644 --- a/actionpack/lib/action_view/helpers/number_helper.rb +++ b/actionpack/lib/action_view/helpers/number_helper.rb @@ -28,27 +28,25 @@ module ActionView # number_to_phone(1235551234, :country_code => 1, :extension => 1343, :delimiter => ".") # => +1.123.555.1234 x 1343 def number_to_phone(number, options = {}) - number = number.to_s.strip unless number.nil? + return nil if number.nil? + + number = number.to_s.strip options = options.symbolize_keys area_code = options[:area_code] || nil delimiter = options[:delimiter] || "-" extension = options[:extension].to_s.strip || nil country_code = options[:country_code] || nil - begin - str = "" - str << "+#{country_code}#{delimiter}" unless country_code.blank? - str << if area_code - number.gsub!(/([0-9]{1,3})([0-9]{3})([0-9]{4}$)/,"(\\1) \\2#{delimiter}\\3") - else - number.gsub!(/([0-9]{0,3})([0-9]{3})([0-9]{4})$/,"\\1#{delimiter}\\2#{delimiter}\\3") - number.starts_with?('-') ? number.slice!(1..-1) : number - end - str << " x #{extension}" unless extension.blank? - str - rescue - number + str = "" + str << "+#{country_code}#{delimiter}" unless country_code.blank? + str << if area_code + number.gsub!(/([0-9]{1,3})([0-9]{3})([0-9]{4}$)/,"(\\1) \\2#{delimiter}\\3") + else + number.gsub!(/([0-9]{0,3})([0-9]{3})([0-9]{4})$/,"\\1#{delimiter}\\2#{delimiter}\\3") + number.starts_with?('-') ? number.slice!(1..-1) : number end + str << " x #{extension}" unless extension.blank? + str end # Formats a +number+ into a currency string (e.g., $13.65). You can customize the format @@ -87,13 +85,14 @@ module ActionView format = options[:format] || defaults[:format] separator = '' if precision == 0 - begin - format.gsub(/%n/, number_with_precision(number, - :precision => precision, - :delimiter => delimiter, - :separator => separator) - ).gsub(/%u/, unit).html_safe - rescue + value = number_with_precision(number, + :precision => precision, + :delimiter => delimiter, + :separator => separator) + + if value + format.gsub(/%n/, value).gsub(/%u/, unit).html_safe + else number end end @@ -122,14 +121,11 @@ module ActionView separator = options[:separator] || defaults[:separator] delimiter = options[:delimiter] || defaults[:delimiter] - begin - number_with_precision(number, - :precision => precision, - :separator => separator, - :delimiter => delimiter) + "%" - rescue - number - end + value = number_with_precision(number, + :precision => precision, + :separator => separator, + :delimiter => delimiter) + value ? value + "%" : number end # Formats a +number+ with grouped thousands using +delimiter+ (e.g., 12,324). You can @@ -168,11 +164,11 @@ module ActionView delimiter ||= (options[:delimiter] || defaults[:delimiter]) separator ||= (options[:separator] || defaults[:separator]) - begin - parts = number.to_s.split('.') + parts = number.to_s.split('.') + if parts[0] parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{delimiter}") parts.join(separator) - rescue + else number end end @@ -216,11 +212,17 @@ module ActionView delimiter ||= (options[:delimiter] || defaults[:delimiter]) begin + value = Float(number) + rescue ArgumentError, TypeError + value = nil + end + + if value rounded_number = BigDecimal.new((Float(number) * (10 ** precision)).to_s).round.to_f / 10 ** precision number_with_delimiter("%01.#{precision}f" % rounded_number, :separator => separator, :delimiter => delimiter) - rescue + else number end end @@ -293,17 +295,13 @@ module ActionView unit_key = STORAGE_UNITS[exponent] unit = I18n.translate(:"number.human.storage_units.units.#{unit_key}", :locale => options[:locale], :count => number, :raise => true) - begin - escaped_separator = Regexp.escape(separator) - formatted_number = number_with_precision(number, - :precision => precision, - :separator => separator, - :delimiter => delimiter - ).sub(/(#{escaped_separator})(\d*[1-9])?0+\z/, '\1\2').sub(/#{escaped_separator}\z/, '') - storage_units_format.gsub(/%n/, formatted_number).gsub(/%u/, unit) - rescue - number - end + escaped_separator = Regexp.escape(separator) + formatted_number = number_with_precision(number, + :precision => precision, + :separator => separator, + :delimiter => delimiter + ).sub(/(#{escaped_separator})(\d*[1-9])?0+\z/, '\1\2').sub(/#{escaped_separator}\z/, '') + storage_units_format.gsub(/%n/, formatted_number).gsub(/%u/, unit) end end end diff --git a/actionpack/lib/action_view/helpers/prototype_helper.rb b/actionpack/lib/action_view/helpers/prototype_helper.rb index 51510449bd..4d6ea7dfb2 100644 --- a/actionpack/lib/action_view/helpers/prototype_helper.rb +++ b/actionpack/lib/action_view/helpers/prototype_helper.rb @@ -182,9 +182,11 @@ module ActionView def initialize(context, &block) #:nodoc: context._evaluate_assigns_and_ivars @context, @lines = context, [] - include_helpers_from_context - @context.with_output_buffer(@lines) do - @context.instance_exec(self, &block) + @context.update_details(:formats => [:js, :html]) do + include_helpers_from_context + @context.with_output_buffer(@lines) do + @context.instance_exec(self, &block) + end end end @@ -569,15 +571,19 @@ module ActionView end end - def render(*options_for_render) - old_formats = @context && @context.formats + def render(*options) + with_formats(:html) do + case option = options.first + when Hash + @context.render(*options) + else + option.to_s + end + end + end - @context.reset_formats([:html]) if @context - Hash === options_for_render.first ? - @context.render(*options_for_render) : - options_for_render.first.to_s - ensure - @context.reset_formats(old_formats) if @context + def with_formats(*args) + @context ? @context.update_details(:formats => args) { yield } : yield end def javascript_object_for(object) diff --git a/actionpack/lib/action_view/helpers/tag_helper.rb b/actionpack/lib/action_view/helpers/tag_helper.rb index ee10f8f3bb..8ae2e5f28f 100644 --- a/actionpack/lib/action_view/helpers/tag_helper.rb +++ b/actionpack/lib/action_view/helpers/tag_helper.rb @@ -7,6 +7,9 @@ module ActionView 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 @@ -69,13 +72,7 @@ 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_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 @@ -109,25 +106,10 @@ module ActionView 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 - "<#{name}#{tag_options}>#{content}</#{name}>".html_safe + ("<#{name}#{tag_options}>".html_safe << content.to_s).safe_concat("</#{name}>") end def tag_options(options, escape = true) diff --git a/actionpack/lib/action_view/helpers/translation_helper.rb b/actionpack/lib/action_view/helpers/translation_helper.rb index c348ea7a0d..8a89ee58a0 100644 --- a/actionpack/lib/action_view/helpers/translation_helper.rb +++ b/actionpack/lib/action_view/helpers/translation_helper.rb @@ -12,9 +12,10 @@ module ActionView # prepend the key with a period, nothing is converted. def translate(key, options = {}) options[:raise] = true - I18n.translate(scope_key_by_partial(key), options).html_safe + translation = I18n.translate(scope_key_by_partial(key), options) + translation.is_a?(Array) ? translation.map { |entry| entry.html_safe } : translation.html_safe rescue I18n::MissingTranslationData => e - keys = I18n.send(:normalize_translation_keys, e.locale, e.key, e.options[:scope]) + keys = I18n.normalize_keys(e.locale, e.key, e.options[:scope]) content_tag('span', keys.join(', '), :class => 'translation_missing') end alias :t :translate @@ -28,7 +29,7 @@ module ActionView private def scope_key_by_partial(key) - if key.to_s.first == "." + if (key.respond_to?(:join) ? key.join : key.to_s).first == "." if @_virtual_path @_virtual_path.gsub(%r{/_?}, ".") + key.to_s else @@ -40,4 +41,4 @@ module ActionView end end end -end
\ No newline at end of file +end diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb index fde4bfa4ce..ae1385f3b7 100644 --- a/actionpack/lib/action_view/helpers/url_helper.rb +++ b/actionpack/lib/action_view/helpers/url_helper.rb @@ -5,7 +5,7 @@ require 'active_support/core_ext/hash/keys' module ActionView module Helpers #:nodoc: # Provides a set of methods for making links and getting URLs that - # depend on the routing subsystem (see ActionController::Routing). + # depend on the routing subsystem (see ActionDispatch::Routing). # This allows you to use the same format for links in views # and controllers. module UrlHelper @@ -63,7 +63,7 @@ module ActionView # # => /testing/jump/#tax&ship # # <%= url_for(Workshop.new) %> - # # relies on Workshop answering a new_record? call (and in this case returning true) + # # relies on Workshop answering a persisted? call (and in this case returning false) # # => /workshops # # <%= url_for(@workshop) %> @@ -202,8 +202,6 @@ module ActionView # # link_to("Destroy", "http://www.example.com", :method => :delete, :confirm => "Are you sure?") # # => <a href='http://www.example.com' rel="nofollow" data-method="delete" data-confirm="Are you sure?">Destroy</a> - - # def link_to(*args, &block) if block_given? options = args.first || {} @@ -226,7 +224,7 @@ module ActionView end href_attr = "href=\"#{url}\"" unless href - "<a #{href_attr}#{tag_options}>#{ERB::Util.h(name || url)}</a>".html_safe + ("<a #{href_attr}#{tag_options}>".html_safe << (name || url)).safe_concat("</a>") end end @@ -469,14 +467,12 @@ module ActionView extras << "subject=#{Rack::Utils.escape(subject).gsub("+", "%20")}&" unless subject.nil? extras = "?" << extras.gsub!(/&?$/,"") unless extras.empty? - email_address = email_address.to_s - - email_address_obfuscated = email_address.dup + email_address_obfuscated = html_escape(email_address) email_address_obfuscated.gsub!(/@/, html_options.delete("replace_at")) if html_options.has_key?("replace_at") email_address_obfuscated.gsub!(/\./, html_options.delete("replace_dot")) if html_options.has_key?("replace_dot") if encode == "javascript" - "document.write('#{content_tag("a", name || email_address_obfuscated, html_options.merge({ "href" => "mailto:"+email_address+extras }))}');".each_byte do |c| + "document.write('#{content_tag("a", name || email_address_obfuscated.html_safe, html_options.merge({ "href" => "mailto:"+email_address+extras }))}');".each_byte do |c| string << sprintf("%%%x", c) end "<script type=\"#{Mime::JS}\">eval(decodeURIComponent('#{string}'))</script>" @@ -493,9 +489,9 @@ module ActionView char = c.chr string << (char =~ /\w/ ? sprintf("%%%x", c) : char) end - content_tag "a", name || email_address_encoded, html_options.merge({ "href" => "#{string}#{extras}" }) + content_tag "a", name || email_address_encoded.html_safe, html_options.merge({ "href" => "#{string}#{extras}" }) else - content_tag "a", name || email_address_obfuscated, html_options.merge({ "href" => "mailto:#{email_address}#{extras}" }) + content_tag "a", name || email_address_obfuscated.html_safe, html_options.merge({ "href" => "mailto:#{email_address}#{extras}" }) end end @@ -548,10 +544,11 @@ module ActionView # submitted url doesn't have any either. This lets the function # work with things like ?order=asc if url_string.index("?") - request_uri = request.request_uri + request_uri = request.fullpath else - request_uri = request.request_uri.split('?').first + request_uri = request.path end + if url_string =~ /^\w+:\/\// url_string == "#{request.protocol}#{request.host_with_port}#{request_uri}" else |