From d0845dce852ae495118c7b6c3d656f2ee59583be Mon Sep 17 00:00:00 2001 From: Davide D'Agostino Date: Mon, 12 Mar 2012 13:27:45 +0100 Subject: [PATCH] Make 'data' attributes also available in all tags. --- .../lib/padrino-helpers/asset_tag_helpers.rb | 130 ++++++++---------- .../lib/padrino-helpers/tag_helpers.rb | 53 +++++-- 2 files changed, 92 insertions(+), 91 deletions(-) diff --git a/padrino-helpers/lib/padrino-helpers/asset_tag_helpers.rb b/padrino-helpers/lib/padrino-helpers/asset_tag_helpers.rb index 0f34e95a2..5616c8360 100644 --- a/padrino-helpers/lib/padrino-helpers/asset_tag_helpers.rb +++ b/padrino-helpers/lib/padrino-helpers/asset_tag_helpers.rb @@ -70,7 +70,6 @@ def flash_tag(*args) # @api public def link_to(*args, &block) options = args.extract_options! - options = parse_js_attributes(options) # parses remote, method and confirm options anchor = "##{CGI.escape options.delete(:anchor).to_s}" if options[:anchor] if block_given? @@ -354,86 +353,65 @@ def asset_path(kind, source) end private + ## + # Returns the uri root of the application with optional paths appended. + # + # @example + # uri_root_path("/some/path") => "/root/some/path" + # uri_root_path("javascripts", "test.js") => "/uri/root/javascripts/test.js" + # + def uri_root_path(*paths) + root_uri = self.class.uri_root if self.class.respond_to?(:uri_root) + File.join(ENV['RACK_BASE_URI'].to_s, root_uri || '/', *paths) + end - ## - # Returns the uri root of the application with optional paths appended. - # - # @example - # uri_root_path("/some/path") => "/root/some/path" - # uri_root_path("javascripts", "test.js") => "/uri/root/javascripts/test.js" - # - def uri_root_path(*paths) - root_uri = self.class.uri_root if self.class.respond_to?(:uri_root) - File.join(ENV['RACK_BASE_URI'].to_s, root_uri || '/', *paths) - end - - ## - # Returns the timestamp mtime for an asset - # - # @example - # asset_timestamp("some/path/to/file.png") => "?154543678" - # asset_timestamp("/some/absolute/path.png", true) => nil - # - def asset_timestamp(file_path, absolute=false) - return nil if file_path =~ /\?/ || (self.class.respond_to?(:asset_stamp) && !self.class.asset_stamp) - public_file_path = Padrino.root("public", file_path) if Padrino.respond_to?(:root) - stamp = File.mtime(public_file_path).to_i if public_file_path && File.exist?(public_file_path) - stamp ||= Time.now.to_i unless absolute - "?#{stamp}" if stamp - end - - ### - # Returns the asset folder given a kind. - # - # @example - # asset_folder_name(:css) => 'stylesheets' - # asset_folder_name(:js) => 'javascripts' - # asset_folder_name(:images) => 'images' - # - def asset_folder_name(kind) - case kind - when :css then 'stylesheets' - when :js then 'javascripts' - else kind.to_s - end - end + ## + # Returns the timestamp mtime for an asset + # + # @example + # asset_timestamp("some/path/to/file.png") => "?154543678" + # asset_timestamp("/some/absolute/path.png", true) => nil + # + def asset_timestamp(file_path, absolute=false) + return nil if file_path =~ /\?/ || (self.class.respond_to?(:asset_stamp) && !self.class.asset_stamp) + public_file_path = Padrino.root("public", file_path) if Padrino.respond_to?(:root) + stamp = File.mtime(public_file_path).to_i if public_file_path && File.exist?(public_file_path) + stamp ||= Time.now.to_i unless absolute + "?#{stamp}" if stamp + end - ## - # Parses link_to options for given correct conditions - # - # @example - # parse_conditions("/some/url", :if => false) => true - # - def parse_conditions(url, options) - if options.has_key?(:if) - condition = options.delete(:if) - condition == :current ? url == request.path_info : condition - elsif condition = options.delete(:unless) - condition == :current ? url != request.path_info : !condition - else - true - end + ### + # Returns the asset folder given a kind. + # + # @example + # asset_folder_name(:css) => 'stylesheets' + # asset_folder_name(:js) => 'javascripts' + # asset_folder_name(:images) => 'images' + # + def asset_folder_name(kind) + case kind + when :css then 'stylesheets' + when :js then 'javascripts' + else kind.to_s end + end - ## - # Parses link_to options for given js declarations (remote, method, confirm) - # Not destructive on options; returns updated options - # - # parse_js_attributes(:remote => true, :confirm => "test", :method => :delete) - # => { "data-remote" => true, "data-method" => "delete", "data-confirm" => "test" } - # - def parse_js_attributes(options) - options = options.dup - options['data-remote'] = 'true' if options.delete(:remote) - if link_confirm = options.delete(:confirm) - options['data-confirm'] = link_confirm - end - if link_method = options.delete(:method) - options['data-method'] = link_method - options['rel'] = 'nofollow' - end - options + ## + # Parses link_to options for given correct conditions + # + # @example + # parse_conditions("/some/url", :if => false) => true + # + def parse_conditions(url, options) + if options.has_key?(:if) + condition = options.delete(:if) + condition == :current ? url == request.path_info : condition + elsif condition = options.delete(:unless) + condition == :current ? url != request.path_info : !condition + else + true end + end end # AssetTagHelpers end # Helpers end # Padrino diff --git a/padrino-helpers/lib/padrino-helpers/tag_helpers.rb b/padrino-helpers/lib/padrino-helpers/tag_helpers.rb index ca82e0ff7..3788f0645 100644 --- a/padrino-helpers/lib/padrino-helpers/tag_helpers.rb +++ b/padrino-helpers/lib/padrino-helpers/tag_helpers.rb @@ -28,6 +28,12 @@ module TagHelpers :selected ] + DATA_ATTRIBUTES = [ + :method, + :remote, + :confirm + ] + ## # Creates an HTML tag with given name, content, and options # @@ -92,7 +98,9 @@ def content_tag(name, content = nil, options = nil, &block) content = content.join("\n") if content.respond_to?(:join) - output = "<#{name}#{tag_options(options) if options}>#{content}" + options = parse_data_options(name, options) + attributes = tag_attributes(options) + output = "<#{name}#{attributes}>#{content}" block_is_template?(block) ? concat_content(output) : output end @@ -182,34 +190,35 @@ def input_tag(type, options = {}) # # @api public def tag(name, options = nil, open = false) - "<#{name}#{tag_options(options) if options}#{open ? '>' : ' />'}" + options = parse_data_options(name, options) + attributes = tag_attributes(options) + "<#{name}#{attributes}#{open ? '>' : ' />'}" end private ## # Returns a compiled list of HTML attributes ## - def tag_options(options) - return if options.blank? - attributes = [] - options.each do |attribute, value| - next if value.nil? || value == false - if value.is_a?(Hash) - attributes << nested_values(attribute, value) - elsif BOOLEAN_ATTRIBUTES.include?(attribute) - attributes << attribute.to_s + def tag_attributes(options) + return '' if options.nil? + attributes = options.map do |k, v| + next if v.nil? || v == false + if v.is_a?(Hash) + nested_values(k, v) + elsif BOOLEAN_ATTRIBUTES.include?(k) + k.to_s else - attributes << %(#{attribute}="#{escape_value(value)}") + %(#{k}="#{escape_value(v)}") end - end - " #{attributes.join(' ')}" + end.compact + attributes.empty? ? '' : " #{attributes * ' '}" end ## # Escape tag values to their HTML/XML entities. ## def escape_value(string) - string.to_s.gsub(Regexp.union(*ESCAPE_VALUES.keys)){|c| ESCAPE_VALUES[c] } + string.to_s.gsub(Regexp.union(*ESCAPE_VALUES.keys)) { |c| ESCAPE_VALUES[c] } end ## @@ -224,6 +233,20 @@ def nested_values(attribute, hash) end end * ' ' end + + ## + # Parses custom data attributes + # + def parse_data_options(tag, options) + return if options.nil? + options = options.dup + options.each do |k, v| + next if !DATA_ATTRIBUTES.include?(k) || (tag.to_s == 'form' && k == :method) + options["data-#{k}"] = options.delete(k) + options[:rel] = 'nofollow' if k == :method + end + options + end end # TagHelpers end # Helpers end # Padrino