diff options
Diffstat (limited to 'actionview/lib')
-rw-r--r-- | actionview/lib/action_view/base.rb | 6 | ||||
-rw-r--r-- | actionview/lib/action_view/gem_version.rb | 4 | ||||
-rw-r--r-- | actionview/lib/action_view/helpers/asset_url_helper.rb | 2 | ||||
-rw-r--r-- | actionview/lib/action_view/helpers/form_tag_helper.rb | 2 | ||||
-rw-r--r-- | actionview/lib/action_view/helpers/sanitize_helper.rb | 43 | ||||
-rw-r--r-- | actionview/lib/action_view/helpers/tag_helper.rb | 10 | ||||
-rw-r--r-- | actionview/lib/action_view/helpers/tags/label.rb | 68 | ||||
-rw-r--r-- | actionview/lib/action_view/helpers/tags/placeholderable.rb | 34 | ||||
-rw-r--r-- | actionview/lib/action_view/helpers/tags/text_area.rb | 4 | ||||
-rw-r--r-- | actionview/lib/action_view/helpers/tags/text_field.rb | 4 | ||||
-rw-r--r-- | actionview/lib/action_view/helpers/translation_helper.rb | 1 | ||||
-rw-r--r-- | actionview/lib/action_view/template.rb | 18 | ||||
-rw-r--r-- | actionview/lib/action_view/test_case.rb | 3 |
13 files changed, 121 insertions, 78 deletions
diff --git a/actionview/lib/action_view/base.rb b/actionview/lib/action_view/base.rb index 86c55ffb51..d1bade0d3d 100644 --- a/actionview/lib/action_view/base.rb +++ b/actionview/lib/action_view/base.rb @@ -10,8 +10,10 @@ require 'action_view/lookup_context' module ActionView #:nodoc: # = Action View Base # - # Action View templates can be written in several ways. If the template file has a <tt>.erb</tt> extension then it uses a mixture of ERB - # (included in Ruby) and HTML. If the template file has a <tt>.builder</tt> extension then Jim Weirich's Builder::XmlMarkup library is used. + # Action View templates can be written in several ways. + # If the template file has a <tt>.erb</tt> extension, then it uses the erubis[https://rubygems.org/gems/erubis] + # template system which can embed Ruby into an HTML document. + # If the template file has a <tt>.builder</tt> extension, then Jim Weirich's Builder::XmlMarkup library is used. # # == ERB # diff --git a/actionview/lib/action_view/gem_version.rb b/actionview/lib/action_view/gem_version.rb index 9266e55c47..1f506866e9 100644 --- a/actionview/lib/action_view/gem_version.rb +++ b/actionview/lib/action_view/gem_version.rb @@ -1,5 +1,5 @@ module ActionView - # Returns the version of the currently loaded ActionView as a <tt>Gem::Version</tt> + # Returns the version of the currently loaded Action View as a <tt>Gem::Version</tt> def self.gem_version Gem::Version.new VERSION::STRING end @@ -8,7 +8,7 @@ module ActionView MAJOR = 4 MINOR = 2 TINY = 0 - PRE = "alpha" + PRE = "beta1" STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".") end diff --git a/actionview/lib/action_view/helpers/asset_url_helper.rb b/actionview/lib/action_view/helpers/asset_url_helper.rb index 9e8d005ec7..29733442c1 100644 --- a/actionview/lib/action_view/helpers/asset_url_helper.rb +++ b/actionview/lib/action_view/helpers/asset_url_helper.rb @@ -121,8 +121,8 @@ module ActionView # asset_path "application", type: :stylesheet # => /assets/application.css # asset_path "http://www.example.com/js/xmlhr.js" # => http://www.example.com/js/xmlhr.js def asset_path(source, options = {}) - return "" unless source.present? source = source.to_s + return "" unless source.present? return source if source =~ URI_REGEXP tail, source = source[/([\?#].+)$/], source.sub(/([\?#].+)$/, '') diff --git a/actionview/lib/action_view/helpers/form_tag_helper.rb b/actionview/lib/action_view/helpers/form_tag_helper.rb index b18f578183..7d1cdc5a68 100644 --- a/actionview/lib/action_view/helpers/form_tag_helper.rb +++ b/actionview/lib/action_view/helpers/form_tag_helper.rb @@ -35,10 +35,10 @@ module ActionView # This is helpful when you're fragment-caching the form. Remote forms get the # authenticity token from the <tt>meta</tt> tag, so embedding is unnecessary unless you # support browsers without JavaScript. - # * A list of parameters to feed to the URL the form will be posted to. # * <tt>:remote</tt> - If set to true, will allow the Unobtrusive JavaScript drivers to control the # submit behavior. By default this behavior is an ajax submit. # * <tt>:enforce_utf8</tt> - If set to false, a hidden input with name utf8 is not output. + # * Any other key creates standard HTML attributes for the tag. # # ==== Examples # form_tag('/posts') diff --git a/actionview/lib/action_view/helpers/sanitize_helper.rb b/actionview/lib/action_view/helpers/sanitize_helper.rb index dfbc52e3ac..4f2db0a0c4 100644 --- a/actionview/lib/action_view/helpers/sanitize_helper.rb +++ b/actionview/lib/action_view/helpers/sanitize_helper.rb @@ -1,6 +1,6 @@ require 'active_support/core_ext/object/try' require 'active_support/deprecation' -require 'rails-deprecated_sanitizer' +require 'rails-html-sanitizer' module ActionView # = Action View Sanitize Helpers @@ -121,31 +121,10 @@ module ActionView module ClassMethods #:nodoc: attr_writer :full_sanitizer, :link_sanitizer, :white_list_sanitizer - [:protocol_separator, - :uri_attributes, - :bad_tags, - :allowed_css_properties, - :allowed_css_keywords, - :shorthand_css_properties, - :allowed_protocols].each do |meth| - meth_name = "sanitized_#{meth}" - imp = lambda do |name| - ActiveSupport::Deprecation.warn("#{name} is deprecated and has no effect.") - end - - define_method(meth_name) { imp.(meth_name) } - define_method("#{meth_name}=") { |value| imp.("#{meth_name}=") } - end - # Vendors the full, link and white list sanitizers. - # This uses html-scanner for the HTML sanitization. - # In the next Rails version this will use Rails::Html::Sanitizer instead. - # To get this new behavior now, in your Gemfile, add: - # - # gem 'rails-html-sanitizer' - # + # Provided strictly for compabitility and can be removed in Rails 5. def sanitizer_vendor - Rails::DeprecatedSanitizer + Rails::Html::Sanitizer end def sanitized_allowed_tags @@ -189,25 +168,29 @@ module ActionView @white_list_sanitizer ||= sanitizer_vendor.white_list_sanitizer.new end + ## + # :method: sanitized_allowed_tags= + # + # :call-seq: sanitized_allowed_tags=(tags) + # # Replaces the allowed tags for the +sanitize+ helper. # # class Application < Rails::Application # config.action_view.sanitized_allowed_tags = 'table', 'tr', 'td' # end # - def sanitized_allowed_tags=(tags) - sanitizer_vendor.white_list_sanitizer.allowed_tags = tags - end + ## + # :method: sanitized_allowed_attributes= + # + # :call-seq: sanitized_allowed_attributes=(attributes) + # # Replaces the allowed HTML attributes for the +sanitize+ helper. # # class Application < Rails::Application # config.action_view.sanitized_allowed_attributes = ['onclick', 'longdesc'] # end # - def sanitized_allowed_attributes=(attributes) - sanitizer_vendor.white_list_sanitizer.allowed_attributes = attributes - end end end end diff --git a/actionview/lib/action_view/helpers/tag_helper.rb b/actionview/lib/action_view/helpers/tag_helper.rb index 268558669e..c20800598f 100644 --- a/actionview/lib/action_view/helpers/tag_helper.rb +++ b/actionview/lib/action_view/helpers/tag_helper.rb @@ -20,6 +20,8 @@ module ActionView BOOLEAN_ATTRIBUTES.merge(BOOLEAN_ATTRIBUTES.map {|attribute| attribute.to_sym }) + TAG_PREFIXES = ['aria', 'data', :aria, :data].to_set + PRE_CONTENT_STRINGS = { :textarea => "\n" } @@ -148,9 +150,9 @@ module ActionView return if options.blank? attrs = [] options.each_pair do |key, value| - if key.to_s == 'data' && value.is_a?(Hash) + if TAG_PREFIXES.include?(key) && value.is_a?(Hash) value.each_pair do |k, v| - attrs << data_tag_option(k, v, escape) + attrs << prefix_tag_option(key, k, v, escape) end elsif BOOLEAN_ATTRIBUTES.include?(key) attrs << boolean_tag_option(key) if value @@ -161,8 +163,8 @@ module ActionView " #{attrs.sort! * ' '}" unless attrs.empty? end - def data_tag_option(key, value, escape) - key = "data-#{key.to_s.dasherize}" + def prefix_tag_option(prefix, key, value, escape) + key = "#{prefix}-#{key.to_s.dasherize}" unless value.is_a?(String) || value.is_a?(Symbol) || value.is_a?(BigDecimal) value = value.to_json end diff --git a/actionview/lib/action_view/helpers/tags/label.rb b/actionview/lib/action_view/helpers/tags/label.rb index 39b2f48c39..08a23e497e 100644 --- a/actionview/lib/action_view/helpers/tags/label.rb +++ b/actionview/lib/action_view/helpers/tags/label.rb @@ -2,6 +2,39 @@ module ActionView module Helpers module Tags # :nodoc: class Label < Base # :nodoc: + class LabelBuilder # :nodoc: + attr_reader :object + + def initialize(template_object, object_name, method_name, object, tag_value) + @template_object = template_object + @object_name = object_name + @method_name = method_name + @object = object + @tag_value = tag_value + end + + def translation + method_and_value = @tag_value.present? ? "#{@method_name}.#{@tag_value}" : @method_name + @object_name.gsub!(/\[(.*)_attributes\]\[\d+\]/, '.\1') + + if object.respond_to?(:to_model) + key = object.model_name.i18n_key + i18n_default = ["#{key}.#{method_and_value}".to_sym, ""] + end + + i18n_default ||= "" + content = I18n.t("#{@object_name}.#{method_and_value}", :default => i18n_default, :scope => "helpers.label").presence + + content ||= if object && object.class.respond_to?(:human_attribute_name) + object.class.human_attribute_name(method_and_value) + end + + content ||= @method_name.humanize + + content + end + end + def initialize(object_name, method_name, template_object, content_or_options = nil, options = nil) options ||= {} @@ -32,33 +65,24 @@ module ActionView options.delete("namespace") options["for"] = name_and_id["id"] unless options.key?("for") - if block_given? - content = @template_object.capture(&block) - else - method_and_value = tag_value.present? ? "#{@method_name}.#{tag_value}" : @method_name - content = if @content.blank? - @object_name.gsub!(/\[(.*)_attributes\]\[\d+\]/, '.\1') - - if object.respond_to?(:to_model) - key = object.model_name.i18n_key - i18n_default = ["#{key}.#{method_and_value}".to_sym, ""] - end - - i18n_default ||= "" - I18n.t("#{@object_name}.#{method_and_value}", :default => i18n_default, :scope => "helpers.label").presence - else - @content.to_s - end - - content ||= if object && object.class.respond_to?(:human_attribute_name) - object.class.human_attribute_name(method_and_value) - end + builder = LabelBuilder.new(@template_object, @object_name, @method_name, @object, tag_value) - content ||= @method_name.humanize + content = if block_given? + @template_object.capture(builder, &block) + elsif @content.present? + @content.to_s + else + render_component(builder) end label_tag(name_and_id["id"], content, options) end + + private + + def render_component(builder) + builder.translation + end end end end diff --git a/actionview/lib/action_view/helpers/tags/placeholderable.rb b/actionview/lib/action_view/helpers/tags/placeholderable.rb new file mode 100644 index 0000000000..ae67bc13af --- /dev/null +++ b/actionview/lib/action_view/helpers/tags/placeholderable.rb @@ -0,0 +1,34 @@ +module ActionView + module Helpers + module Tags # :nodoc: + module Placeholderable # :nodoc: + def initialize(*) + super + + if tag_value = @options[:placeholder] + placeholder = tag_value if tag_value.is_a?(String) + + object_name = @object_name.gsub(/\[(.*)_attributes\]\[\d+\]/, '.\1') + method_and_value = tag_value.is_a?(TrueClass) ? @method_name : "#{@method_name}.#{tag_value}" + + if object.respond_to?(:to_model) + key = object.class.model_name.i18n_key + i18n_default = ["#{key}.#{method_and_value}".to_sym, ""] + end + + i18n_default ||= "" + placeholder ||= I18n.t("#{object_name}.#{method_and_value}", :default => i18n_default, :scope => "helpers.placeholder").presence + + placeholder ||= if object && object.class.respond_to?(:human_attribute_name) + object.class.human_attribute_name(method_and_value) + end + + placeholder ||= @method_name.humanize + + @options[:placeholder] = placeholder + end + end + end + end + end +end diff --git a/actionview/lib/action_view/helpers/tags/text_area.rb b/actionview/lib/action_view/helpers/tags/text_area.rb index 9ee83ee7c2..69038c1498 100644 --- a/actionview/lib/action_view/helpers/tags/text_area.rb +++ b/actionview/lib/action_view/helpers/tags/text_area.rb @@ -1,7 +1,11 @@ +require 'action_view/helpers/tags/placeholderable' + module ActionView module Helpers module Tags # :nodoc: class TextArea < Base # :nodoc: + include Placeholderable + def render options = @options.stringify_keys add_default_name_and_id(options) diff --git a/actionview/lib/action_view/helpers/tags/text_field.rb b/actionview/lib/action_view/helpers/tags/text_field.rb index e0b80d81c2..5c576a20ca 100644 --- a/actionview/lib/action_view/helpers/tags/text_field.rb +++ b/actionview/lib/action_view/helpers/tags/text_field.rb @@ -1,7 +1,11 @@ +require 'action_view/helpers/tags/placeholderable' + module ActionView module Helpers module Tags # :nodoc: class TextField < Base # :nodoc: + include Placeholderable + def render options = @options.stringify_keys options["size"] = options["maxlength"] unless options.key?("size") diff --git a/actionview/lib/action_view/helpers/translation_helper.rb b/actionview/lib/action_view/helpers/translation_helper.rb index 1d50ea2ff5..c2fda42396 100644 --- a/actionview/lib/action_view/helpers/translation_helper.rb +++ b/actionview/lib/action_view/helpers/translation_helper.rb @@ -6,6 +6,7 @@ module ActionView # = Action View Translation Helpers module Helpers module TranslationHelper + include TagHelper # Delegates to <tt>I18n#translate</tt> but also performs three additional functions. # # First, it will ensure that any thrown +MissingTranslation+ messages will be turned diff --git a/actionview/lib/action_view/template.rb b/actionview/lib/action_view/template.rb index 9d39d02a37..eb0f2e8a57 100644 --- a/actionview/lib/action_view/template.rb +++ b/actionview/lib/action_view/template.rb @@ -242,7 +242,7 @@ module ActionView end instrument("!compile_template") do - compile(view, mod) + compile(mod) end # Just discard the source if we have a virtual path. This @@ -264,7 +264,7 @@ module ActionView # encode the source into <tt>Encoding.default_internal</tt>. # In general, this means that templates will be UTF-8 inside of Rails, # regardless of the original source encoding. - def compile(view, mod) #:nodoc: + def compile(mod) #:nodoc: encode! method_name = self.method_name code = @handler.call(self) @@ -293,18 +293,8 @@ module ActionView raise WrongEncodingError.new(@source, Encoding.default_internal) end - begin - mod.module_eval(source, identifier, 0) - ObjectSpace.define_finalizer(self, Finalizer[method_name, mod]) - rescue => e # errors from template code - if logger = (view && view.logger) - logger.debug "ERROR: compiling #{method_name} RAISED #{e}" - logger.debug "Function body: #{source}" - logger.debug "Backtrace: #{e.backtrace.join("\n")}" - end - - raise ActionView::Template::Error.new(self, e) - end + mod.module_eval(source, identifier, 0) + ObjectSpace.define_finalizer(self, Finalizer[method_name, mod]) end def handle_render_error(view, e) #:nodoc: diff --git a/actionview/lib/action_view/test_case.rb b/actionview/lib/action_view/test_case.rb index 7edfc436a6..af34d2ce5a 100644 --- a/actionview/lib/action_view/test_case.rb +++ b/actionview/lib/action_view/test_case.rb @@ -158,8 +158,7 @@ module ActionView # Need to experiment if this priority is the best one: rendered => output_buffer def document_root_element - @html_document ||= Nokogiri::HTML::Document.parse(@rendered.blank? ? @output_buffer : @rendered) - @html_document.root + Nokogiri::HTML::Document.parse(@rendered.blank? ? @output_buffer : @rendered).root end def say_no_to_protect_against_forgery! |