diff options
Diffstat (limited to 'actionpack/lib/action_view/helpers')
9 files changed, 132 insertions, 50 deletions
diff --git a/actionpack/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb b/actionpack/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb index fc0cca28b9..52eb43a1cd 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb @@ -71,9 +71,21 @@ module ActionView if sources.first == :all collect_asset_files(custom_dir, ('**' if recursive), "*.#{extension}") else - sources.collect do |source| - determine_source(source, expansions) - end.flatten + sources.inject([]) do |list, source| + determined_source = determine_source(source, expansions) + update_source_list(list, determined_source) + end + end + end + + def update_source_list(list, source) + case source + when String + list.delete(source) + list << source + when Array + updated_sources = source - list + list.concat(updated_sources) end end diff --git a/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb b/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb index c95808a219..b9126af944 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb @@ -33,13 +33,21 @@ module ActionView all_asset_files = (collect_asset_files(custom_dir, ('**' if recursive), "*.#{extension}") - ['application']) << 'application' ((determine_source(:defaults, expansions).dup & all_asset_files) + all_asset_files).uniq else - expanded_sources = sources.collect do |source| - determine_source(source, expansions) - end.flatten - expanded_sources << "application" if sources.include?(:defaults) && File.exist?(File.join(custom_dir, "application.#{extension}")) + expanded_sources = sources.inject([]) do |list, source| + determined_source = determine_source(source, expansions) + update_source_list(list, determined_source) + end + add_application_js(expanded_sources, sources) expanded_sources end end + + def add_application_js(expanded_sources, sources) + if sources.include?(:defaults) && File.exist?(File.join(custom_dir, "application.#{extension}")) + expanded_sources.delete('application') + expanded_sources << "application" + end + end end diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb index 875ec9b77b..dc8e4bc316 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/date/conversions' require 'active_support/core_ext/hash/slice' require 'active_support/core_ext/object/with_options' @@ -566,6 +567,27 @@ module ActionView def select_year(date, options = {}, html_options = {}) DateTimeSelector.new(date, options, html_options).select_year end + + # Returns an html time tag for the given date or time. + # + # ==== Examples + # time_tag Date.today # => + # <time datetime="2010-11-04">November 04, 2010</time> + # time_tag Time.now # => + # <time datetime="2010-11-04T17:55:45+01:00">November 04, 2010 17:55</time> + # time_tag Date.yesterday, 'Yesterday' # => + # <time datetime="2010-11-03">Yesterday</time> + # time_tag Date.today, :pubdate => true # => + # <time datetime="2010-11-04" pubdate="pubdate">November 04, 2010</time> + # + def time_tag(date_or_time, *args) + options = args.extract_options! + format = options.delete(:format) || :long + content = args.first || I18n.l(date_or_time, :format => format) + datetime = date_or_time.acts_like?(:time) ? date_or_time.xmlschema : date_or_time.rfc3339 + + content_tag(:time, content, options.reverse_merge(:datetime => datetime)) + end end class DateTimeSelector #:nodoc: diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index d6edef0d34..befaa3e8d9 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -298,6 +298,23 @@ module ActionView # # If you don't need to attach a form to a model instance, then check out # FormTagHelper#form_tag. + # + # === Form to external resources + # + # When you build forms to external resources sometimes you need to set an authenticity token or just render a form + # without it, for example when you submit data to a payment gateway number and types of fields could be limited. + # + # To set an authenticity token you need to pass an <tt>:authenticity_token</tt> parameter + # + # <%= form_for @invoice, :url => external_url, :authenticity_token => 'external_token' do |f| + # ... + # <% end %> + # + # If you don't want to an authenticity token field be rendered at all just pass <tt>false</tt>: + # + # <%= form_for @invoice, :url => external_url, :authenticity_token => false do |f| + # ... + # <% end %> def form_for(record, options = {}, &proc) raise ArgumentError, "Missing block" unless block_given? @@ -314,6 +331,8 @@ module ActionView end options[:html][:remote] = options.delete(:remote) + options[:html][:authenticity_token] = options.delete(:authenticity_token) + builder = options[:parent_builder] = instantiate_builder(object_name, object, options, &proc) fields_for = fields_for(object_name, object, options, &proc) default_options = builder.multipart? ? { :multipart => true } : {} @@ -530,8 +549,11 @@ module ActionView # <% end %> # ... # <% end %> - def fields_for(record, record_object = nil, options = nil, &block) - capture(instantiate_builder(record, record_object, options, &block), &block) + def fields_for(record, record_object = nil, options = {}, &block) + builder = instantiate_builder(record, record_object, options, &block) + output = capture(builder, &block) + output.concat builder.hidden_field(:id) if output && options[:hidden_field_id] && !builder.emitted_hidden_id? + output end # Returns a label tag tailored for labelling an input field for a specified attribute (identified by +method+) on an object @@ -1304,14 +1326,8 @@ module ActionView def fields_for_nested_model(name, object, options, block) object = convert_to_model(object) - 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 + options[:hidden_field_id] = object.persisted? + @template.fields_for(name, object, options, &block) end def nested_child_index(name) diff --git a/actionpack/lib/action_view/helpers/form_tag_helper.rb b/actionpack/lib/action_view/helpers/form_tag_helper.rb index d6b74974e9..71f8534cbf 100644 --- a/actionpack/lib/action_view/helpers/form_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/form_tag_helper.rb @@ -414,7 +414,8 @@ module ActionView # <tt>reset</tt>button or a generic button which can be used in # JavaScript, for example. You can use the button tag as a regular # submit tag but it isn't supported in legacy browsers. However, - # button tag allows richer labels such as images and emphasis. + # the button tag allows richer labels such as images and emphasis, + # so this helper will also accept a block. # # ==== Options # * <tt>:confirm => 'question?'</tt> - If present, the @@ -431,18 +432,22 @@ module ActionView # # ==== Examples # button_tag - # # => <button name="button" type="button">Button</button> + # # => <button name="button" type="submit">Button</button> # - # button_tag "<strong>Ask me!</strong>" + # button_tag(:type => 'button') do + # content_tag(:strong, 'Ask me!') + # end # # => <button name="button" type="button"> # <strong>Ask me!</strong> # </button> # # button_tag "Checkout", :disable_with => "Please wait..." # # => <button data-disable-with="Please wait..." name="button" - # type="button">Checkout</button> + # type="submit">Checkout</button> # - def button_tag(label = "Button", options = {}) + def button_tag(content_or_options = nil, options = nil, &block) + options = content_or_options if block_given? && content_or_options.is_a?(Hash) + options ||= {} options.stringify_keys! if disable_with = options.delete("disable_with") @@ -453,11 +458,9 @@ module ActionView options["data-confirm"] = confirm end - ["type", "name"].each do |option| - options[option] = "button" unless options[option] - end + options.reverse_merge! 'name' => 'button', 'type' => 'submit' - content_tag :button, label, { "type" => options.delete("type") }.update(options) + content_tag :button, content_or_options || 'Button', options, &block end # Displays an image which when clicked will submit the form. diff --git a/actionpack/lib/action_view/helpers/output_safety_helper.rb b/actionpack/lib/action_view/helpers/output_safety_helper.rb new file mode 100644 index 0000000000..a035dd70ad --- /dev/null +++ b/actionpack/lib/action_view/helpers/output_safety_helper.rb @@ -0,0 +1,38 @@ +require 'active_support/core_ext/string/output_safety' + +module ActionView #:nodoc: + # = Action View Raw Output Helper + module Helpers #:nodoc: + module OutputSafetyHelper + # This method outputs without escaping a string. Since escaping tags is + # now default, this can be used when you don't want Rails to automatically + # escape tags. This is not recommended if the data is coming from the user's + # input. + # + # For example: + # + # <%=raw @user.name %> + def raw(stringish) + stringish.to_s.html_safe + end + + # This method returns a html safe string similar to what <tt>Array#join</tt> + # would return. All items in the array, including the supplied separator, are + # html escaped unless they are html safe, and the returned string is marked + # as html safe. + # + # safe_join(["<p>foo</p>".html_safe, "<p>bar</p>"], "<br />") + # # => "<p>foo</p><br /><p>bar</p>" + # + # safe_join(["<p>foo</p>".html_safe, "<p>bar</p>".html_safe], "<br />".html_safe) + # # => "<p>foo</p><br /><p>bar</p>" + # + def safe_join(array, sep=$,) + sep ||= "".html_safe + sep = ERB::Util.html_escape(sep) + + array.map { |i| ERB::Util.html_escape(i) }.join(sep).html_safe + end + end + end +end
\ No newline at end of file diff --git a/actionpack/lib/action_view/helpers/raw_output_helper.rb b/actionpack/lib/action_view/helpers/raw_output_helper.rb deleted file mode 100644 index 216683a2e0..0000000000 --- a/actionpack/lib/action_view/helpers/raw_output_helper.rb +++ /dev/null @@ -1,18 +0,0 @@ -module ActionView #:nodoc: - # = Action View Raw Output Helper - module Helpers #:nodoc: - module RawOutputHelper - # This method outputs without escaping a string. Since escaping tags is - # now default, this can be used when you don't want Rails to automatically - # escape tags. This is not recommended if the data is coming from the user's - # input. - # - # For example: - # - # <%=raw @user.name %> - def raw(stringish) - stringish.to_s.html_safe - end - end - end -end
\ No newline at end of file diff --git a/actionpack/lib/action_view/helpers/tag_helper.rb b/actionpack/lib/action_view/helpers/tag_helper.rb index ee51617a2b..786af5ca58 100644 --- a/actionpack/lib/action_view/helpers/tag_helper.rb +++ b/actionpack/lib/action_view/helpers/tag_helper.rb @@ -14,7 +14,7 @@ module ActionView BOOLEAN_ATTRIBUTES = %w(disabled readonly multiple checked autobuffer autoplay controls loop selected hidden scoped async defer reversed ismap seemless muted required - autofocus novalidate formnovalidate open).to_set + autofocus novalidate formnovalidate open pubdate).to_set BOOLEAN_ATTRIBUTES.merge(BOOLEAN_ATTRIBUTES.map {|attribute| attribute.to_sym }) # Returns an empty HTML tag of type +name+ which by default is XHTML diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb index cfa88c91e3..2cd2dca711 100644 --- a/actionpack/lib/action_view/helpers/url_helper.rb +++ b/actionpack/lib/action_view/helpers/url_helper.rb @@ -497,13 +497,14 @@ module ActionView email_address_obfuscated = email_address.dup email_address_obfuscated.gsub!(/@/, html_options.delete("replace_at")) if html_options.key?("replace_at") email_address_obfuscated.gsub!(/\./, html_options.delete("replace_dot")) if html_options.key?("replace_dot") - case encode when "javascript" - string = - "document.write('#{content_tag("a", name || email_address_obfuscated.html_safe, html_options.merge("href" => "mailto:#{email_address}#{extras}".html_safe))}');".unpack('C*').map { |c| - sprintf("%%%x", c) - }.join + string = '' + html = content_tag("a", name || email_address_obfuscated.html_safe, html_options.merge("href" => "mailto:#{email_address}#{extras}".html_safe)) + html = escape_javascript(html) + "document.write('#{html}');".each_byte do |c| + string << sprintf("%%%x", c) + end "<script type=\"#{Mime::JS}\">eval(decodeURIComponent('#{string}'))</script>".html_safe when "hex" email_address_encoded = email_address_obfuscated.unpack('C*').map {|c| |