diff options
author | Pratik Naik <pratiknaik@gmail.com> | 2009-07-25 12:55:01 +0100 |
---|---|---|
committer | Pratik Naik <pratiknaik@gmail.com> | 2009-07-25 12:55:01 +0100 |
commit | c6b16fc2aada37aab1949cd9a1e46a2d9ccc8381 (patch) | |
tree | ea13a4e420a94ed7b552529ca9dc4b02680203d2 /actionpack/lib/action_view | |
parent | f2d65a456fd93fd3a220f85c1001f0180bfdd6be (diff) | |
parent | 0c68d23f19010379a9320690ca17a26743c8f071 (diff) | |
download | rails-c6b16fc2aada37aab1949cd9a1e46a2d9ccc8381.tar.gz rails-c6b16fc2aada37aab1949cd9a1e46a2d9ccc8381.tar.bz2 rails-c6b16fc2aada37aab1949cd9a1e46a2d9ccc8381.zip |
Merge commit 'mainstream/master'
Diffstat (limited to 'actionpack/lib/action_view')
-rw-r--r-- | actionpack/lib/action_view/base.rb | 13 | ||||
-rw-r--r-- | actionpack/lib/action_view/context.rb | 44 | ||||
-rw-r--r-- | actionpack/lib/action_view/helpers.rb | 5 | ||||
-rw-r--r-- | actionpack/lib/action_view/helpers/active_model_helper.rb (renamed from actionpack/lib/action_view/helpers/active_record_helper.rb) | 26 | ||||
-rw-r--r-- | actionpack/lib/action_view/helpers/ajax_helper.rb | 68 | ||||
-rw-r--r-- | actionpack/lib/action_view/helpers/asset_tag_helper.rb | 38 | ||||
-rw-r--r-- | actionpack/lib/action_view/helpers/form_helper.rb | 35 | ||||
-rw-r--r-- | actionpack/lib/action_view/helpers/tag_helper.rb | 3 | ||||
-rw-r--r-- | actionpack/lib/action_view/render/partials.rb | 6 | ||||
-rw-r--r-- | actionpack/lib/action_view/template/renderable.rb | 8 | ||||
-rw-r--r-- | actionpack/lib/action_view/template/template.rb | 2 | ||||
-rw-r--r-- | actionpack/lib/action_view/test_case.rb | 1 |
12 files changed, 213 insertions, 36 deletions
diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 45184f58fb..9e696af83b 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -172,8 +172,6 @@ module ActionView #:nodoc: attr_accessor :controller attr_internal :captures - attr_accessor :output_buffer - class << self delegate :erb_trim_mode=, :to => 'ActionView::TemplateHandlers::ERB' delegate :logger, :to => 'ActionController::Base', :allow_nil => true @@ -206,10 +204,7 @@ module ActionView #:nodoc: delegate :find_by_parts, :to => :view_paths - module CompiledTemplates #:nodoc: - # holds compiled template code - end - include CompiledTemplates + include Context def self.process_view_paths(value) ActionView::PathSet.new(Array(value)) @@ -228,6 +223,12 @@ module ActionView #:nodoc: end end + def self.for_controller(controller) + new(controller.class.view_paths, {}, controller).tap do |view| + view.helpers.include(controller._helpers) if controller.respond_to?(:_helpers) + end + end + def initialize(view_paths = [], assigns_for_first_render = {}, controller = nil, formats = nil)#:nodoc: @formats = formats || [:html] @assigns = assigns_for_first_render.each { |key, value| instance_variable_set("@#{key}", value) } diff --git a/actionpack/lib/action_view/context.rb b/actionpack/lib/action_view/context.rb new file mode 100644 index 0000000000..f212fe25eb --- /dev/null +++ b/actionpack/lib/action_view/context.rb @@ -0,0 +1,44 @@ +module ActionView + module CompiledTemplates #:nodoc: + # holds compiled template code + end + + # ActionView contexts are supplied to ActionController + # to render template. The default ActionView context + # is ActionView::Base. + # + # In order to work with ActionController, a Context + # must implement: + # + # Context.for_controller[controller] Create a new ActionView instance for a + # controller + # Context#_render_partial_from_controller[options] + # - responsible for setting options[:_template] + # - Returns String with the rendered partial + # options<Hash>:: see _render_partial in ActionView::Base + # Context#_render_template_from_controller[template, layout, options, partial] + # - Returns String with the rendered template + # template<ActionView::Template>:: The template to render + # layout<ActionView::Template>:: The layout to render around the template + # options<Hash>:: See _render_template_with_layout in ActionView::Base + # partial<Boolean>:: Whether or not the template to render is a partial + # + # An ActionView context can also mix in ActionView's + # helpers. In order to mix in helpers, a context must + # implement: + # + # Context#controller + # - Returns an instance of AbstractController + # + # In any case, a context must mix in ActionView::Context, + # which stores compiled template and provides the output + # buffer. + module Context + include CompiledTemplates + attr_accessor :output_buffer + + def convert_to_model(object) + object.respond_to?(:to_model) ? object.to_model : object + end + end +end
\ No newline at end of file diff --git a/actionpack/lib/action_view/helpers.rb b/actionpack/lib/action_view/helpers.rb index 97fa2d80e9..652561f7f8 100644 --- a/actionpack/lib/action_view/helpers.rb +++ b/actionpack/lib/action_view/helpers.rb @@ -1,6 +1,7 @@ module ActionView #:nodoc: module Helpers #:nodoc: - autoload :ActiveRecordHelper, 'action_view/helpers/active_record_helper' + autoload :ActiveModelHelper, 'action_view/helpers/active_model_helper' + autoload :AjaxHelper, 'action_view/helpers/ajax_helper' autoload :AssetTagHelper, 'action_view/helpers/asset_tag_helper' autoload :AtomFeedHelper, 'action_view/helpers/atom_feed_helper' autoload :BenchmarkHelper, 'action_view/helpers/benchmark_helper' @@ -31,7 +32,7 @@ module ActionView #:nodoc: include SanitizeHelper::ClassMethods end - include ActiveRecordHelper + include ActiveModelHelper include AssetTagHelper include AtomFeedHelper include BenchmarkHelper diff --git a/actionpack/lib/action_view/helpers/active_record_helper.rb b/actionpack/lib/action_view/helpers/active_model_helper.rb index 75cc651968..0f122d9232 100644 --- a/actionpack/lib/action_view/helpers/active_record_helper.rb +++ b/actionpack/lib/action_view/helpers/active_model_helper.rb @@ -15,7 +15,7 @@ module ActionView # method that creates a complete form for all the basic content types of the record (not associations or aggregations, though). This # is a great way of making the record quickly available for editing, but likely to prove lackluster for a complicated real-world form. # In that case, it's better to use the +input+ method and the specialized +form+ methods in link:classes/ActionView/Helpers/FormHelper.html - module ActiveRecordHelper + module ActiveModelHelper # Returns a default input tag for the type of object returned by the method. For example, if <tt>@post</tt> # has an attribute +title+ mapped to a +VARCHAR+ column that holds "Hello World": # @@ -77,6 +77,7 @@ module ActionView # * <tt>:submit_value</tt> - The text of the submit button (default: "Create" if a new record, otherwise "Update"). def form(record_name, options = {}) record = instance_variable_get("@#{record_name}") + record = convert_to_model(record) options = options.symbolize_keys options[:action] ||= record.new_record? ? "create" : "update" @@ -121,6 +122,8 @@ module ActionView end options.reverse_merge!(:prepend_text => '', :append_text => '', :css_class => 'formError') + object = convert_to_model(object) + if (obj = (object.respond_to?(:errors) ? object : instance_variable_get("@#{object}"))) && (errors = obj.errors[method]) content_tag("div", @@ -179,6 +182,8 @@ module ActionView objects = params.collect {|object_name| instance_variable_get("@#{object_name}") }.compact end + objects.map! {|o| convert_to_model(o) } + count = objects.inject(0) {|sum, object| sum + object.errors.count } unless count.zero? html = {} @@ -226,7 +231,14 @@ module ActionView end end - class InstanceTag #:nodoc: + module ActiveRecordInstanceTag + def object + @active_model_object ||= begin + object = super + object.respond_to?(:to_model) ? object.to_model : object + end + end + def to_tag(options = {}) case column_type when :string @@ -248,11 +260,9 @@ module ActionView end %w(tag content_tag to_date_select_tag to_datetime_select_tag to_time_select_tag).each do |meth| - without = "#{meth}_without_error_wrapping" - define_method "#{meth}_with_error_wrapping" do |*args| - error_wrapping(send(without, *args)) + define_method meth do |*| + error_wrapping(super) end - alias_method_chain meth, :error_wrapping end def error_wrapping(html_tag) @@ -267,5 +277,9 @@ module ActionView object.send(:column_for_attribute, @method_name).type end end + + class InstanceTag + include ActiveRecordInstanceTag + end end end diff --git a/actionpack/lib/action_view/helpers/ajax_helper.rb b/actionpack/lib/action_view/helpers/ajax_helper.rb new file mode 100644 index 0000000000..9cc2acc239 --- /dev/null +++ b/actionpack/lib/action_view/helpers/ajax_helper.rb @@ -0,0 +1,68 @@ +module ActionView + module Helpers + module AjaxHelper + include UrlHelper + + def link_to_remote(name, url, options = {}) + html = options.delete(:html) || {} + + update = options.delete(:update) + if update.is_a?(Hash) + html["data-update-success"] = update[:success] + html["data-update-failure"] = update[:failure] + else + html["data-update-success"] = update + end + + html["data-update-position"] = options.delete(:position) + html["data-method"] = options.delete(:method) + html["data-remote"] = "true" + + html.merge!(options) + + url = url_for(url) if url.is_a?(Hash) + link_to(name, url, html) + end + + def button_to_remote(name, options = {}, html_options = {}) + url = options.delete(:url) + url = url_for(url) if url.is_a?(Hash) + + html_options.merge!(:type => "button", :value => name, + :"data-url" => url) + + tag(:input, html_options) + end + + module Rails2Compatibility + def set_callbacks(options, html) + [:complete, :failure, :success, :interactive, :loaded, :loading].each do |type| + html["data-#{type}-code"] = options.delete(type.to_sym) + end + + options.each do |option, value| + if option.is_a?(Integer) + html["data-#{option}-code"] = options.delete(option) + end + end + end + + def link_to_remote(name, url, options = nil) + if !options && url.is_a?(Hash) && url.key?(:url) + url, options = url.delete(:url), url + end + + set_callbacks(options, options[:html] ||= {}) + + super + end + + def button_to_remote(name, options = {}, html_options = {}) + set_callbacks(options, html_options) + super + end + end + + end + end +end
\ No newline at end of file diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb index 898da3c7e4..5025891d25 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb @@ -465,12 +465,27 @@ module ActionView # video_path("hd") # => /videos/hd # video_path("hd.avi") # => /videos/hd.avi # video_path("trailers/hd.avi") # => /videos/trailers/hd.avi - # video_path("/trailers/hd.avi") # => /videos/hd.avi + # video_path("/trailers/hd.avi") # => /trailers/hd.avi # video_path("http://www.railsapplication.com/vid/hd.avi") # => http://www.railsapplication.com/vid/hd.avi def video_path(source) compute_public_path(source, 'videos') end - alias_method :path_to_video, :video_path # aliased to avoid conflicts with an video_path named route + alias_method :path_to_video, :video_path # aliased to avoid conflicts with a video_path named route + + # Computes the path to an audio asset in the public audios directory. + # Full paths from the document root will be passed through. + # Used internally by +audio_tag+ to build the audio path. + # + # ==== Examples + # audio_path("horse") # => /audios/horse + # audio_path("horse.wav") # => /audios/horse.avi + # audio_path("sounds/horse.wav") # => /audios/sounds/horse.avi + # audio_path("/sounds/horse.wav") # => /sounds/horse.avi + # audio_path("http://www.railsapplication.com/sounds/horse.wav") # => http://www.railsapplication.com/sounds/horse.wav + def audio_path(source) + compute_public_path(source, 'audios') + end + alias_method :path_to_audio, :audio_path # aliased to avoid conflicts with an audio_path named route # Returns an html image tag for the +source+. The +source+ can be a full # path or a file that exists in your public images directory. @@ -545,7 +560,7 @@ module ActionView # video_tag("trailer.ogg") # => # <video src="/videos/trailer.ogg" /> # video_tag("trailer.ogg", :controls => true, :autobuffer => true) # => - # <video autobuffer="autobuffer" controls="controls" src="/videos/trailer.ogg" /> + # <video autobuffer="true" controls="true" src="/videos/trailer.ogg" /> # video_tag("trailer.m4v", :size => "16x10", :poster => "screenshot.png") # => # <video src="/videos/trailer.m4v" width="16" height="10" poster="/images/screenshot.png" /> # video_tag("/trailers/hd.avi", :size => "16x16") # => @@ -575,6 +590,23 @@ module ActionView end end + # Returns an html audio tag for the +source+. + # The +source+ can be full path or file that exists in + # your public audios directory. + # + # ==== Examples + # audio_tag("sound") # => + # <audio src="/audios/sound" /> + # audio_tag("sound.wav") # => + # <audio src="/audios/sound.wav" /> + # audio_tag("sound.wav", :autoplay => true, :controls => true) # => + # <audio autoplay="autoplay" controls="controls" src="/audios/sound.wav" /> + def audio_tag(source, options = {}) + options.symbolize_keys! + options[:src] = path_to_audio(source) + tag("audio", options) + end + def self.cache_asset_timestamps @@cache_asset_timestamps end diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index 6d6d623938..2d1d19d5f3 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -288,6 +288,8 @@ module ActionView 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 } @@ -488,7 +490,7 @@ module ActionView object_name = ActionController::RecordIdentifier.singular_class_name(object) end - builder = options[:builder] || ActionView::Base.default_form_builder + builder = options[:builder] || ActionView.default_form_builder yield builder.new(object_name, object, self, options, block) end @@ -626,8 +628,8 @@ module ActionView # Returns a checkbox tag tailored for accessing a specified attribute (identified by +method+) on an object # assigned to the template (identified by +object+). This object must be an instance object (@object) and not a local object. - # It's intended that +method+ returns an integer and if that integer is above zero, then the checkbox is checked. - # Additional options on the input tag can be passed as a hash with +options+. The +checked_value+ defaults to 1 + # It's intended that +method+ returns an integer and if that integer is above zero, then the checkbox is checked. + # Additional options on the input tag can be passed as a hash with +options+. The +checked_value+ defaults to 1 # while the default +unchecked_value+ is set to 0 which is convenient for boolean values. # # ==== Gotcha @@ -709,7 +711,8 @@ module ActionView end end - class InstanceTag #:nodoc: + module InstanceTagMethods #:nodoc: + extend ActiveSupport::Concern include Helpers::TagHelper, Helpers::FormTagHelper attr_reader :method_name, :object_name @@ -832,7 +835,7 @@ module ActionView self.class.value_before_type_cast(object, @method_name) end - class << self + module ClassMethods def value(object, method_name) object.send method_name unless object.nil? end @@ -918,6 +921,10 @@ module ActionView end end + class InstanceTag + include InstanceTagMethods + end + class FormBuilder #:nodoc: # The methods which wrap a form helper call. class_inheritable_accessor :field_helpers @@ -1022,7 +1029,7 @@ module ActionView def fields_for_with_nested_attributes(association_name, args, block) name = "#{object_name}[#{association_name}_attributes]" association = @object.send(association_name) - explicit_object = args.first if args.first.respond_to?(:new_record?) + explicit_object = args.first.to_model if args.first.respond_to?(:to_model) if association.is_a?(Array) children = explicit_object ? [explicit_object] : association @@ -1054,9 +1061,21 @@ module ActionView end end - class << Base + class << ActionView attr_accessor :default_form_builder end - Base.default_form_builder = ::ActionView::Helpers::FormBuilder + self.default_form_builder = ::ActionView::Helpers::FormBuilder + + # 2.3 compatibility + class << Base + def default_form_builder=(builder) + ActionView.default_form_builder = builder + end + + def default_form_builder + ActionView.default_form_builder + end + end + end diff --git a/actionpack/lib/action_view/helpers/tag_helper.rb b/actionpack/lib/action_view/helpers/tag_helper.rb index 9b6e9d201f..66d7592874 100644 --- a/actionpack/lib/action_view/helpers/tag_helper.rb +++ b/actionpack/lib/action_view/helpers/tag_helper.rb @@ -8,8 +8,7 @@ module ActionView module TagHelper include ERB::Util - BOOLEAN_ATTRIBUTES = %w(disabled readonly multiple checked autobuffer - autoplay controls loop).to_set + BOOLEAN_ATTRIBUTES = %w(disabled readonly multiple checked).to_set BOOLEAN_ATTRIBUTES.merge(BOOLEAN_ATTRIBUTES.map {|attr| attr.to_sym }) # Returns an empty HTML tag of type +name+ which by default is XHTML diff --git a/actionpack/lib/action_view/render/partials.rb b/actionpack/lib/action_view/render/partials.rb index a80ffe3c20..ccb14d513a 100644 --- a/actionpack/lib/action_view/render/partials.rb +++ b/actionpack/lib/action_view/render/partials.rb @@ -259,7 +259,7 @@ module ActionView _set_locals(object, locals, template, options) - self._partial = template + options[:_template] = template _render_template(template, locals) end @@ -278,7 +278,7 @@ module ActionView locals = (options[:locals] ||= {}) index, @_partial_path = 0, nil collection.map do |object| - template = passed_template || begin + options[:_template] = template = passed_template || begin _partial_path = ActionController::RecordIdentifier.partial_path(object, controller_path) template = _pick_partial_template(_partial_path) @@ -289,8 +289,6 @@ module ActionView index += 1 - self._partial = template - _render_template(template, locals) end.join(spacer) end diff --git a/actionpack/lib/action_view/template/renderable.rb b/actionpack/lib/action_view/template/renderable.rb index 54857516ab..7687578165 100644 --- a/actionpack/lib/action_view/template/renderable.rb +++ b/actionpack/lib/action_view/template/renderable.rb @@ -12,9 +12,9 @@ module ActionView end def load! - names = Base::CompiledTemplates.instance_methods.grep(/#{method_name_without_locals}/) + names = CompiledTemplates.instance_methods.grep(/#{method_name_without_locals}/) names.each do |name| - Base::CompiledTemplates.class_eval do + CompiledTemplates.class_eval do remove_method(name) end end @@ -56,7 +56,7 @@ module ActionView def compile(local_assigns) render_symbol = method_name(local_assigns) - if !Base::CompiledTemplates.method_defined?(render_symbol) || recompile? + if !CompiledTemplates.method_defined?(render_symbol) || recompile? compile!(render_symbol, local_assigns) end end @@ -74,7 +74,7 @@ module ActionView end_src begin - ActionView::Base::CompiledTemplates.module_eval(source, filename.to_s, 0) + ActionView::CompiledTemplates.module_eval(source, filename.to_s, 0) rescue Exception => e # errors from template code if logger = defined?(ActionController) && Base.logger logger.debug "ERROR: compiling #{render_symbol} RAISED #{e}" diff --git a/actionpack/lib/action_view/template/template.rb b/actionpack/lib/action_view/template/template.rb index fac50cd692..4145045e2d 100644 --- a/actionpack/lib/action_view/template/template.rb +++ b/actionpack/lib/action_view/template/template.rb @@ -75,7 +75,7 @@ module ActionView end begin - ActionView::Base::CompiledTemplates.module_eval(source, identifier, line) + ActionView::CompiledTemplates.module_eval(source, identifier, line) method_name rescue Exception => e # errors from template code if logger = (view && view.logger) diff --git a/actionpack/lib/action_view/test_case.rb b/actionpack/lib/action_view/test_case.rb index 7355af4192..3f3951509a 100644 --- a/actionpack/lib/action_view/test_case.rb +++ b/actionpack/lib/action_view/test_case.rb @@ -23,6 +23,7 @@ module ActionView class TestCase < ActiveSupport::TestCase include ActionDispatch::Assertions include ActionController::TestProcess + include ActionView::Context class_inheritable_accessor :helper_class @@helper_class = nil |