update padrino to 0.10.6 vanilla
This commit is contained in:
parent
094de61e92
commit
b514b7ea6e
|
@ -112,21 +112,6 @@ module Padrino
|
|||
nil
|
||||
end
|
||||
|
||||
##
|
||||
# Determines whether the dependencies are locked by Bundler.
|
||||
# otherwise return nil
|
||||
#
|
||||
# @return [:locked, :unlocked, nil]
|
||||
# Returns +:locked+ if the +Gemfile.lock+ file exists, or +:unlocked+
|
||||
# if only the +Gemfile+ exists.
|
||||
#
|
||||
# @deprecated Will be removed in 1.0.0
|
||||
#
|
||||
def bundle
|
||||
return :locked if File.exist?(root('Gemfile.lock'))
|
||||
return :unlocked if File.exist?(root("Gemfile"))
|
||||
end
|
||||
|
||||
##
|
||||
# A Rack::Builder object that allows to add middlewares in front of all
|
||||
# Padrino applications.
|
||||
|
|
|
@ -22,16 +22,17 @@ module Padrino
|
|||
class << self
|
||||
|
||||
def inherited(base) # @private
|
||||
logger.devel "Setup #{base}"
|
||||
begun_at = Time.now
|
||||
CALLERS_TO_IGNORE.concat(PADRINO_IGNORE_CALLERS)
|
||||
base.default_configuration!
|
||||
base.prerequisites.concat([
|
||||
File.join(base.root, "/models.rb"),
|
||||
File.join(base.root, "/models/**/*.rb"),
|
||||
File.join(base.root, "/lib.rb"),
|
||||
File.join(base.root, "/lib/**/*.rb")
|
||||
File.join(base.root, '/models.rb'),
|
||||
File.join(base.root, '/models/**/*.rb'),
|
||||
File.join(base.root, '/lib.rb'),
|
||||
File.join(base.root, '/lib/**/*.rb')
|
||||
]).uniq!
|
||||
Padrino.require_dependencies(base.prerequisites)
|
||||
logger.devel :setup, begun_at, base
|
||||
super(base) # Loading the subclass inherited method
|
||||
end
|
||||
|
||||
|
@ -47,11 +48,10 @@ module Padrino
|
|||
# MyApp.reload!
|
||||
#
|
||||
def reload!
|
||||
logger.devel "Reloading #{self}"
|
||||
@_dependencies = nil # Reset dependencies
|
||||
logger.devel "Reloading #{settings}"
|
||||
reset! # Reset sinatra app
|
||||
reset_router! # Reset all routes
|
||||
Padrino.require_dependencies(self.app_file, :force => true) # Reload the app file
|
||||
Padrino.require_dependencies(settings.app_file, :force => true) # Reload the app file
|
||||
require_dependencies # Reload dependencies
|
||||
default_filters! # Reload filters
|
||||
default_routes! # Reload default routes
|
||||
|
@ -92,12 +92,12 @@ module Padrino
|
|||
#
|
||||
def setup_application!
|
||||
return if @_configured
|
||||
self.require_dependencies
|
||||
self.default_filters!
|
||||
self.default_routes!
|
||||
self.default_errors!
|
||||
settings.require_dependencies
|
||||
settings.default_filters!
|
||||
settings.default_routes!
|
||||
settings.default_errors!
|
||||
if defined?(I18n)
|
||||
I18n.load_path << self.locale_path
|
||||
I18n.load_path << settings.locale_path
|
||||
I18n.reload!
|
||||
end
|
||||
@_configured = true
|
||||
|
@ -112,7 +112,7 @@ module Padrino
|
|||
#
|
||||
def run!(options={})
|
||||
return unless Padrino.load!
|
||||
Padrino.mount(self.to_s).to("/")
|
||||
Padrino.mount(settings.to_s).to('/')
|
||||
Padrino.run!(options)
|
||||
end
|
||||
|
||||
|
@ -121,7 +121,7 @@ module Padrino
|
|||
# directory that need to be added to +$LOAD_PATHS+ from this application
|
||||
#
|
||||
def load_paths
|
||||
@_load_paths ||= %w(models lib mailers controllers helpers).map { |path| File.join(self.root, path) }
|
||||
@_load_paths ||= %w[models lib mailers controllers helpers].map { |path| File.join(settings.root, path) }
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -136,10 +136,10 @@ module Padrino
|
|||
# MyApp.dependencies << Padrino.root('other_app', 'controllers.rb')
|
||||
#
|
||||
def dependencies
|
||||
@_dependencies ||= [
|
||||
"urls.rb", "config/urls.rb", "mailers/*.rb", "mailers.rb",
|
||||
"controllers/**/*.rb", "controllers.rb", "helpers/**/*.rb", "helpers.rb"
|
||||
].map { |file| Dir[File.join(self.root, file)] }.flatten
|
||||
[
|
||||
'urls.rb', 'config/urls.rb', 'mailers/*.rb', 'mailers.rb',
|
||||
'controllers/**/*.rb', 'controllers.rb', 'helpers/**/*.rb', 'helpers.rb'
|
||||
].map { |file| Dir[File.join(settings.root, file)] }.flatten
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -177,13 +177,13 @@ module Padrino
|
|||
set :images_path, Proc.new { File.join(public, "images") }
|
||||
set :protection, false
|
||||
# Padrino specific
|
||||
set :uri_root, "/"
|
||||
set :app_name, self.to_s.underscore.to_sym
|
||||
set :uri_root, '/'
|
||||
set :app_name, settings.to_s.underscore.to_sym
|
||||
set :default_builder, 'StandardFormBuilder'
|
||||
set :flash, defined?(Sinatra::Flash) || defined?(Rack::Flash)
|
||||
set :authentication, false
|
||||
# Padrino locale
|
||||
set :locale_path, Proc.new { Dir[File.join(self.root, "/locale/**/*.{rb,yml}")] }
|
||||
set :locale_path, Proc.new { Dir[File.join(settings.root, '/locale/**/*.{rb,yml}')] }
|
||||
# Load the Global Configurations
|
||||
class_eval(&Padrino.apps_configuration) if Padrino.apps_configuration
|
||||
end
|
||||
|
@ -237,7 +237,6 @@ module Padrino
|
|||
end
|
||||
|
||||
private
|
||||
|
||||
# Overrides the default middleware for Sinatra based on Padrino conventions
|
||||
# Also initializes the application after setting up the middleware
|
||||
def setup_default_middleware(builder)
|
||||
|
|
|
@ -536,7 +536,7 @@ module Padrino
|
|||
# get :list, :provides => [:js, :json] # => "/list.{!format,js|json}"
|
||||
# get :list, :provides => [:html, :js, :json] # => "/list(.{!format,js|json})"
|
||||
# get :list, :priority => :low # Defers route to be last
|
||||
#
|
||||
# get /pattern/, :name => :foo, :generate_with => '/foo' # Generates :foo as /foo
|
||||
def route(verb, path, *args, &block)
|
||||
options = case args.size
|
||||
when 2
|
||||
|
@ -557,7 +557,7 @@ module Padrino
|
|||
route_options = options.dup
|
||||
route_options[:provides] = @_provides if @_provides
|
||||
path, *route_options[:with] = path if path.is_a?(Array)
|
||||
path, name, options = *parse_route(path, route_options, verb)
|
||||
path, name, options, route_options = *parse_route(path, route_options, verb)
|
||||
options.reverse_merge!(@_conditions) if @_conditions
|
||||
|
||||
# Sinatra defaults
|
||||
|
@ -571,7 +571,7 @@ module Padrino
|
|||
invoke_hook(:route_added, verb, path, block)
|
||||
|
||||
# HTTPRouter route construction
|
||||
route = router.add(path)
|
||||
route = router.add(path, route_options)
|
||||
route.name(name) if name
|
||||
priority_name = options.delete(:priority) || :normal
|
||||
priority = ROUTE_PRIORITY[priority_name] or raise("Priority #{priority_name} not recognized, try #{ROUTE_PRIORITY.keys.join(', ')}")
|
||||
|
@ -620,6 +620,9 @@ module Padrino
|
|||
# We need save our originals path/options so we can perform correctly cache.
|
||||
original = [path, options.dup]
|
||||
|
||||
# options for the route directly
|
||||
route_options = {}
|
||||
|
||||
# We need check if path is a symbol, if that it's a named route
|
||||
map = options.delete(:map)
|
||||
|
||||
|
@ -628,7 +631,11 @@ module Padrino
|
|||
path = map ? map.dup : (path == :index ? '/' : path.to_s) # The route path
|
||||
end
|
||||
|
||||
if path.kind_of?(String) # path i.e "/index" or "/show"
|
||||
# Build our controller
|
||||
controller = Array(@_controller).map { |c| c.to_s }
|
||||
|
||||
case path
|
||||
when String # path i.e "/index" or "/show"
|
||||
# Now we need to parse our 'with' params
|
||||
if with_params = options.delete(:with)
|
||||
path = process_path_for_with_params(path, with_params)
|
||||
|
@ -643,9 +650,6 @@ module Padrino
|
|||
options[:matching][:format] = /[^\.]+/
|
||||
end
|
||||
|
||||
# Build our controller
|
||||
controller = Array(@_controller).map { |c| c.to_s }
|
||||
|
||||
absolute_map = map && map[0] == ?/
|
||||
|
||||
unless controller.empty?
|
||||
|
@ -656,10 +660,6 @@ module Padrino
|
|||
path = File.join(controller_path, path)
|
||||
end
|
||||
# Here we build the correct name route
|
||||
if name
|
||||
controller_name = controller.join("_")
|
||||
name = "#{controller_name}_#{name}".to_sym unless controller_name.blank?
|
||||
end
|
||||
end
|
||||
|
||||
# Now we need to parse our 'parent' params and parent scope
|
||||
|
@ -678,12 +678,21 @@ module Padrino
|
|||
path.sub!(%r{/(\))?$}, '\\1') if path != "/" # Remove latest trailing delimiter
|
||||
path.gsub!(/\/(\(\.|$)/, '\\1') # Remove trailing slashes
|
||||
path.squeeze!('/')
|
||||
when Regexp
|
||||
route_options[:path_for_generation] = options.delete(:generate_with) if options.key?(:generate_with)
|
||||
end
|
||||
|
||||
name = options.delete(:route_name) if name.nil? && options.key?(:route_name)
|
||||
name = options.delete(:name) if name.nil? && options.key?(:name)
|
||||
if name
|
||||
controller_name = controller.join("_")
|
||||
name = "#{controller_name}_#{name}".to_sym unless controller_name.blank?
|
||||
end
|
||||
|
||||
# Merge in option defaults
|
||||
options.reverse_merge!(:default_values => @_defaults)
|
||||
|
||||
[path, name, options]
|
||||
[path, name, options, route_options]
|
||||
end
|
||||
|
||||
##
|
||||
|
|
|
@ -41,7 +41,6 @@ module Padrino
|
|||
method_option :environment, :type => :string, :aliases => "-e", :required => true, :default => :development
|
||||
method_option :list, :type => :string, :aliases => "-T", :desc => "Display the tasks (matching optional PATTERN) with descriptions, then exit."
|
||||
method_option :trace, :type => :boolean, :aliases => "-t", :desc => "Turn on invoke/execute tracing, enable full backtrace."
|
||||
method_option :verbose, :type => :boolean, :aliases => "-v", :desc => "Log message to standard output."
|
||||
def rake(*args)
|
||||
prepare :rake
|
||||
args << "-T" if options[:list]
|
||||
|
@ -51,9 +50,8 @@ module Padrino
|
|||
ARGV.clear
|
||||
ARGV.concat(args)
|
||||
puts "=> Executing Rake #{ARGV.join(' ')} ..."
|
||||
ENV['PADRINO_LOG_LEVEL'] ||= "test"
|
||||
load File.expand_path('../rake.rb', __FILE__)
|
||||
silence(:stdout) { require File.expand_path('config/boot.rb') }
|
||||
require File.expand_path('config/boot.rb')
|
||||
PadrinoTasks.init(true)
|
||||
end
|
||||
|
||||
|
@ -62,10 +60,10 @@ module Padrino
|
|||
prepare :console
|
||||
require File.expand_path("../../version", __FILE__)
|
||||
ARGV.clear
|
||||
puts "=> Loading #{options.environment} console (Padrino v.#{Padrino.version})"
|
||||
require 'irb'
|
||||
require "irb/completion"
|
||||
require File.expand_path('config/boot.rb')
|
||||
puts "=> Loading #{Padrino.env} console (Padrino v.#{Padrino.version})"
|
||||
require File.expand_path('../console', __FILE__)
|
||||
IRB.start
|
||||
end
|
||||
|
@ -80,7 +78,8 @@ module Padrino
|
|||
require 'padrino-core/command'
|
||||
require 'padrino-gen/command'
|
||||
ARGV.shift
|
||||
Padrino.bin_gen(ARGV)
|
||||
ARGV << 'help' if ARGV.empty?
|
||||
Padrino.bin_gen(*ARGV)
|
||||
rescue
|
||||
puts "<= You need padrino-gen! Run: gem install padrino-gen"
|
||||
end
|
||||
|
|
|
@ -94,6 +94,7 @@ module Padrino
|
|||
# Method for reloading required applications and their files.
|
||||
#
|
||||
def reload!
|
||||
return unless Padrino::Reloader.changed?
|
||||
Padrino.before_load.each(&:call) # Run before hooks
|
||||
Padrino::Reloader.reload! # detects the modified files
|
||||
Padrino.after_load.each(&:call) # Run after hooks
|
||||
|
|
|
@ -4,7 +4,7 @@ lv:
|
|||
# Use the strftime parameters for formats.
|
||||
# When no format has been given, it uses default.
|
||||
# You can provide other formats here if you like!
|
||||
default: "%d.%m.%Y."
|
||||
default: "%d.%m.%Y"
|
||||
short: "%e. %B"
|
||||
long: "%Y. gada %e. %B"
|
||||
only_day: "%e"
|
||||
|
@ -21,7 +21,7 @@ lv:
|
|||
time:
|
||||
formats:
|
||||
default: "%Y. gada %e. %B, %H:%M"
|
||||
short: "%d.%m.%Y., %H:%M"
|
||||
short: "%d.%m.%Y, %H:%M"
|
||||
long: "%Y. gada %e. %B, %H:%M:%S"
|
||||
am: "priekšpusdiena"
|
||||
pm: "pēcpusdiena"
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
# Defines the log level for a Padrino project.
|
||||
PADRINO_LOG_LEVEL = ENV['PADRINO_LOG_LEVEL'] unless defined?(PADRINO_LOG_LEVEL)
|
||||
|
||||
# Defines the logger used for a Padrino project.
|
||||
PADRINO_LOGGER = ENV['PADRINO_LOGGER'] unless defined?(PADRINO_LOGGER)
|
||||
|
||||
module Padrino
|
||||
|
||||
##
|
||||
# @return [Padrino::Logger]
|
||||
#
|
||||
|
@ -35,21 +35,14 @@ module Padrino
|
|||
# Padrino.logger = Buffered.new(STDOUT)
|
||||
#
|
||||
def self.logger=(value)
|
||||
value.extend(Padrino::Logger::Extensions) unless (Padrino::Logger::Extensions === value)
|
||||
Thread.current[:padrino_logger] = value
|
||||
end
|
||||
|
||||
##
|
||||
# Extensions to the built in Ruby logger.
|
||||
# Padrinos internal logger, using all of Padrino log extensions.
|
||||
#
|
||||
class Logger
|
||||
|
||||
attr_accessor :level
|
||||
attr_accessor :auto_flush
|
||||
attr_reader :buffer
|
||||
attr_reader :log
|
||||
attr_reader :init_args
|
||||
attr_accessor :log_static
|
||||
|
||||
##
|
||||
# Ruby (standard) logger levels:
|
||||
#
|
||||
|
@ -58,6 +51,7 @@ module Padrino
|
|||
# :warn:: A warning
|
||||
# :info:: generic (useful) information about system operation
|
||||
# :debug:: low-level information for developers
|
||||
# :devel:: Development-related information that is unnecessary in debug mode
|
||||
#
|
||||
Levels = {
|
||||
:fatal => 7,
|
||||
|
@ -68,6 +62,161 @@ module Padrino
|
|||
:devel => -1,
|
||||
} unless const_defined?(:Levels)
|
||||
|
||||
module Extensions
|
||||
##
|
||||
# Generate the logging methods for {Padrino.logger} for each log level.
|
||||
#
|
||||
Padrino::Logger::Levels.each_pair do |name, number|
|
||||
define_method(name) do |*args|
|
||||
return if number < level
|
||||
if args.size > 1
|
||||
bench(args[0], args[1], args[2], name)
|
||||
else
|
||||
push(args * '', name)
|
||||
end
|
||||
end
|
||||
|
||||
define_method(:"#{name}?") do
|
||||
number >= level
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Append a to development logger a given action with time
|
||||
#
|
||||
# @param [string] action
|
||||
# The action
|
||||
#
|
||||
# @param [float] time
|
||||
# Time duration for the given action
|
||||
#
|
||||
# @param [message] string
|
||||
# The message that you want to log
|
||||
#
|
||||
# @example
|
||||
# logger.bench 'GET', started_at, '/blog/categories'
|
||||
# # => DEBUG - GET (0.056ms) - /blog/categories
|
||||
#
|
||||
def bench(action, began_at, message, level=:debug, color=:yellow)
|
||||
@_pad ||= 8
|
||||
@_pad = action.to_s.size if action.to_s.size > @_pad
|
||||
duration = Time.now - began_at
|
||||
color = :red if duration > 1
|
||||
action = colorize(action.to_s.upcase.rjust(@_pad), color)
|
||||
duration = colorize('%0.4fms' % duration, :bold, color)
|
||||
push "#{action} (#{duration}) #{message}", level
|
||||
end
|
||||
|
||||
##
|
||||
# Appends a message to the log. The methods yield to an optional block and
|
||||
# the output of this block will be appended to the message.
|
||||
#
|
||||
# @param [String] message
|
||||
# The message that you want write to your stream
|
||||
#
|
||||
# @param [String] level
|
||||
# The level one of :debug, :warn etc...
|
||||
#
|
||||
#
|
||||
def push(message = nil, level = nil)
|
||||
add(Padrino::Logger::Levels[level], format(message, level))
|
||||
end
|
||||
|
||||
##
|
||||
# Formats the log message. This method is a noop and should be implemented by other
|
||||
# logger components such as {Padrino::Logger}.
|
||||
#
|
||||
# @param [String] message
|
||||
# The message to format
|
||||
#
|
||||
# @param [String,Symbol] level
|
||||
# The log level, one of :debug, :warn...
|
||||
def format(message, level)
|
||||
message
|
||||
end
|
||||
|
||||
##
|
||||
# The debug level, with some style added. May be reimplemented.
|
||||
#
|
||||
# @example
|
||||
# stylized_level(:debug) => DEBUG
|
||||
#
|
||||
# @param [String,Symbol] level
|
||||
# The log level
|
||||
#
|
||||
def stylized_level(level)
|
||||
level.to_s.upcase.rjust(7)
|
||||
end
|
||||
|
||||
##
|
||||
# Colorizes a string for colored console output. This is a noop and can be reimplemented
|
||||
# to colorize the string as needed.
|
||||
#
|
||||
# @see
|
||||
# ColorizedLogger
|
||||
#
|
||||
# @param [string]
|
||||
# The string to be colorized.
|
||||
#
|
||||
# @param [Array<Symbol>]
|
||||
# The colors to use. Should be applied in the order given.
|
||||
def colorize(string, *colors)
|
||||
string
|
||||
end
|
||||
|
||||
##
|
||||
# Turns a logger with LoggingExtensions into a logger with colorized output.
|
||||
#
|
||||
# @example
|
||||
# Padrino.logger = Logger.new($stdout)
|
||||
# Padrino.logger.colorize!
|
||||
# Padrino.logger.debug("Fancy Padrino debug string")
|
||||
def colorize!
|
||||
self.extend(Colorize)
|
||||
end
|
||||
end
|
||||
|
||||
module Colorize
|
||||
# Colors for levels
|
||||
ColoredLevels = {
|
||||
:fatal => [:bold, :red],
|
||||
:error => [:red],
|
||||
:warn => [:yellow],
|
||||
:info => [:green],
|
||||
:debug => [:cyan],
|
||||
:devel => [:magenta]
|
||||
} unless defined?(ColoredLevels)
|
||||
|
||||
##
|
||||
# Colorize our level
|
||||
#
|
||||
# @param [String, Symbol] level
|
||||
#
|
||||
# @see Padrino::Logging::ColorizedLogger::ColoredLevels
|
||||
#
|
||||
def colorize(string, *colors)
|
||||
colors.each do |c|
|
||||
string = string.send(c)
|
||||
end
|
||||
string
|
||||
end
|
||||
|
||||
def stylized_level(level)
|
||||
style = ColoredLevels[level].map { |c| "\e[%dm" % String.colors[c] } * ''
|
||||
[style, super, "\e[0m"] * ''
|
||||
end
|
||||
end
|
||||
|
||||
include Extensions
|
||||
include Colorize
|
||||
|
||||
attr_accessor :level
|
||||
attr_accessor :auto_flush
|
||||
attr_reader :buffer
|
||||
attr_reader :log
|
||||
attr_reader :init_args
|
||||
attr_accessor :log_static
|
||||
|
||||
@@mutex = {}
|
||||
|
||||
##
|
||||
|
@ -110,16 +259,6 @@ module Padrino
|
|||
}
|
||||
Config.merge!(PADRINO_LOGGER) if PADRINO_LOGGER
|
||||
|
||||
# Colors for levels
|
||||
ColoredLevels = {
|
||||
:fatal => [:bold, :red],
|
||||
:error => [:red],
|
||||
:warn => [:yellow],
|
||||
:info => [:green],
|
||||
:debug => [:cyan],
|
||||
:devel => [:magenta]
|
||||
} unless defined?(ColoredLevels)
|
||||
|
||||
##
|
||||
# Setup a new logger
|
||||
#
|
||||
|
@ -137,13 +276,14 @@ module Padrino
|
|||
|
||||
stream = case config[:stream]
|
||||
when :to_file
|
||||
FileUtils.mkdir_p(Padrino.root("log")) unless File.exists?(Padrino.root("log"))
|
||||
File.new(Padrino.root("log", "#{Padrino.env}.log"), "a+")
|
||||
FileUtils.mkdir_p(Padrino.root('log')) unless File.exists?(Padrino.root('log'))
|
||||
File.new(Padrino.root('log', "#{Padrino.env}.log"), 'a+')
|
||||
when :null then StringIO.new
|
||||
when :stdout then $stdout
|
||||
when :stderr then $stderr
|
||||
else config[:stream] # return itself, probabilly is a custom stream.
|
||||
end
|
||||
|
||||
Thread.current[:padrino_logger] = Padrino::Logger.new(config.merge(:stream => stream))
|
||||
end
|
||||
|
||||
|
@ -174,7 +314,7 @@ module Padrino
|
|||
def initialize(options={})
|
||||
@buffer = []
|
||||
@auto_flush = options.has_key?(:auto_flush) ? options[:auto_flush] : true
|
||||
@level = options[:log_level] ? Levels[options[:log_level]] : Levels[:debug]
|
||||
@level = options[:log_level] ? Padrino::Logger::Levels[options[:log_level]] : Padrino::Logger::Levels[:debug]
|
||||
@log = options[:stream] || $stdout
|
||||
@log.sync = true
|
||||
@mutex = @@mutex[@log] ||= Mutex.new
|
||||
|
@ -183,18 +323,6 @@ module Padrino
|
|||
@log_static = options.has_key?(:log_static) ? options[:log_static] : false
|
||||
end
|
||||
|
||||
##
|
||||
# Colorize our level
|
||||
#
|
||||
# @param [String, Symbol] level
|
||||
#
|
||||
# @see Padrino::Logger::ColoredLevels
|
||||
#
|
||||
def colored_level(level)
|
||||
style = ColoredLevels[level].map { |c| "\e[%dm" % String.colors[c] } * ''
|
||||
[style, level.to_s.upcase.rjust(7), "\e[0m"] * ''
|
||||
end
|
||||
|
||||
##
|
||||
# Flush the entire buffer to the log object.
|
||||
#
|
||||
|
@ -217,42 +345,11 @@ module Padrino
|
|||
end
|
||||
|
||||
##
|
||||
# Appends a message to the log. The methods yield to an optional block and
|
||||
# the output of this block will be appended to the message.
|
||||
# Adds a message to the log - for compatibility with other loggers.
|
||||
#
|
||||
# @param [String] message
|
||||
# The message that you want write to your stream
|
||||
#
|
||||
# @param [String] level
|
||||
# The level one of :debug, :warn etc...
|
||||
#
|
||||
#
|
||||
def push(message = nil, level = nil)
|
||||
write @format_message % [colored_level(level), Time.now.strftime(@format_datetime).yellow, message.to_s.strip]
|
||||
end
|
||||
|
||||
##
|
||||
# Append a to development logger a given action with time
|
||||
#
|
||||
# @param [string] action
|
||||
# The action
|
||||
#
|
||||
# @param [float] time
|
||||
# Time duration for the given action
|
||||
#
|
||||
# @param [message] string
|
||||
# The message that you want to log
|
||||
#
|
||||
# @example
|
||||
# logger.bench 'GET', started_at, '/blog/categories'
|
||||
# # => DEBUG - GET (0.056ms) - /blog/categories
|
||||
#
|
||||
def bench(action, began_at, message, level=:debug, color=:yellow)
|
||||
@_pad ||= 8
|
||||
@_pad = action.to_s.size if action.to_s.size > @_pad
|
||||
duration = Time.now - began_at
|
||||
color = :red if duration > 1
|
||||
push "%s (" % action.to_s.upcase.rjust(@_pad).send(color) + "%0.4fms".bold.send(color) % duration + ") %s" % message.to_s, level
|
||||
# @private
|
||||
def add(level, message = nil)
|
||||
write(message)
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -269,22 +366,8 @@ module Padrino
|
|||
end
|
||||
alias :write :<<
|
||||
|
||||
##
|
||||
# Generate the logging methods for {Padrino.logger} for each log level.
|
||||
#
|
||||
Levels.each_pair do |name, number|
|
||||
define_method(name) do |*args|
|
||||
return if number < level
|
||||
if args.size > 1
|
||||
bench(*args)
|
||||
else
|
||||
push(args * '', name)
|
||||
end
|
||||
end
|
||||
|
||||
define_method(:"#{name}?") do
|
||||
number >= level
|
||||
end
|
||||
def format(message, level)
|
||||
@format_message % [stylized_level(level), colorize(Time.now.strftime(@format_datetime), :yellow), message.to_s.strip]
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -301,7 +384,6 @@ module Padrino
|
|||
|
||||
def call(env) # @private
|
||||
env['rack.logger'] = Padrino.logger
|
||||
env['rack.errors'] = Padrino.logger.log
|
||||
began_at = Time.now
|
||||
status, header, body = @app.call(env)
|
||||
log(env, status, header, began_at)
|
||||
|
@ -310,7 +392,7 @@ module Padrino
|
|||
|
||||
private
|
||||
def log(env, status, header, began_at)
|
||||
return if env['sinatra.static_file'] and !logger.log_static
|
||||
return if env['sinatra.static_file'] && (!logger.respond_to?(:log_static) || !logger.log_static)
|
||||
logger.bench(
|
||||
env["REQUEST_METHOD"],
|
||||
began_at,
|
||||
|
@ -319,7 +401,7 @@ module Padrino
|
|||
env["PATH_INFO"],
|
||||
env["QUERY_STRING"].empty? ? "" : "?" + env["QUERY_STRING"],
|
||||
' - ',
|
||||
status.to_s[0..3].bold,
|
||||
logger.colorize(status.to_s[0..3], :bold),
|
||||
' ',
|
||||
code_to_name(status)
|
||||
] * '',
|
||||
|
@ -343,3 +425,4 @@ module Kernel # @private
|
|||
Padrino.logger
|
||||
end
|
||||
end # Kernel
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ module Padrino
|
|||
changed = false
|
||||
rotation do |file, mtime|
|
||||
new_file = MTIMES[file].nil?
|
||||
previous_mtime = MTIMES[file] ||= mtime
|
||||
previous_mtime = MTIMES[file]
|
||||
changed = true if new_file || mtime > previous_mtime
|
||||
end
|
||||
changed
|
||||
|
@ -103,7 +103,7 @@ module Padrino
|
|||
# We lock dependencies sets to prevent reloading of protected constants
|
||||
#
|
||||
def lock!
|
||||
klasses = ObjectSpace.classes.map { |klass| klass.name.to_s.split("::")[0] }.uniq
|
||||
klasses = ObjectSpace.classes.map { |klass| klass.name.split('::')[0] }.uniq
|
||||
klasses = klasses | Padrino.mounted_apps.map { |app| app.app_class }
|
||||
Padrino::Reloader.exclude_constants.concat(klasses)
|
||||
end
|
||||
|
@ -183,14 +183,14 @@ module Padrino
|
|||
# Removes the specified class and constant.
|
||||
#
|
||||
def remove_constant(const)
|
||||
return if exclude_constants.compact.uniq.any? { |c| (const.to_s =~ %r{^#{Regexp.escape(c)}}) } &&
|
||||
!include_constants.compact.uniq.any? { |c| (const.to_s =~ %r{^#{Regexp.escape(c)}}) }
|
||||
return if exclude_constants.compact.uniq.any? { |c| const.name.index(c) == 0 } &&
|
||||
!include_constants.compact.uniq.any? { |c| const.name.index(c) == 0 }
|
||||
begin
|
||||
parts = const.to_s.split("::")
|
||||
base = parts.size == 1 ? Object : parts[0..-2].join("::").constantize
|
||||
object = parts[-1].to_s
|
||||
base.send(:remove_const, object)
|
||||
logger.devel "Removed constant: #{const}"
|
||||
parts = const.to_s.sub(/^::(Object)?/, 'Object::').split('::')
|
||||
object = parts.pop
|
||||
base = parts.empty? ? Object : Inflector.constantize(parts * '::')
|
||||
base.send :remove_const, object
|
||||
logger.devel "Removed constant: #{const} from #{base}"
|
||||
rescue NameError; end
|
||||
end
|
||||
|
||||
|
@ -210,7 +210,7 @@ module Padrino
|
|||
def in_root?(file)
|
||||
# This is better but slow:
|
||||
# Pathname.new(Padrino.root).find { |f| File.identical?(Padrino.root(f), figure_path(file)) }
|
||||
figure_path(file) =~ %r{^#{Regexp.escape(Padrino.root)}}
|
||||
figure_path(file).index(Padrino.root) == 0
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -221,11 +221,11 @@ module Padrino
|
|||
files = Padrino.load_paths.map { |path| Dir["#{path}/**/*.rb"] }.flatten
|
||||
files = files | Padrino.mounted_apps.map { |app| app.app_file }
|
||||
files = files | Padrino.mounted_apps.map { |app| app.app_obj.dependencies }.flatten
|
||||
files.uniq.map { |file|
|
||||
files.uniq.map do |file|
|
||||
file = File.expand_path(file)
|
||||
next if Padrino::Reloader.exclude.any? { |base| file =~ %r{^#{Regexp.escape(base)}} } || !File.exist?(file)
|
||||
yield(file, File.mtime(file))
|
||||
}.compact
|
||||
next if Padrino::Reloader.exclude.any? { |base| file.index(base) == 0 } || !File.exist?(file)
|
||||
yield file, File.mtime(file)
|
||||
end.compact
|
||||
end
|
||||
end # self
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ module Padrino
|
|||
#
|
||||
class Server < Rack::Server
|
||||
# Server Handlers
|
||||
Handlers = [:thin, :mongrel, :webrick]
|
||||
Handlers = [:thin, :mongrel, :trinidad, :webrick]
|
||||
|
||||
# Starts the application on the available server with specified options.
|
||||
def self.start(app, opts={})
|
||||
|
@ -44,7 +44,7 @@ module Padrino
|
|||
[:INT, :TERM].each { |sig| trap(sig) { exit } }
|
||||
super
|
||||
ensure
|
||||
puts "<= Padrino has ended his set (crowd applauds)" unless options[:daemonize]
|
||||
puts "<= Padrino leaves the gun, takes the cannoli" unless options[:daemonize]
|
||||
end
|
||||
|
||||
# The application the server will run.
|
||||
|
|
|
@ -11,7 +11,7 @@ require 'active_support/inflector/methods' # constantize
|
|||
require 'active_support/inflector/inflections' # pluralize
|
||||
require 'active_support/inflections' # load default inflections
|
||||
require 'yaml' unless defined?(YAML) # load yaml for i18n
|
||||
require 'Win32/Console/ANSI' if RUBY_PLATFORM =~ /win32/ # ruby color suppor for win
|
||||
require 'win32console' if RUBY_PLATFORM =~ /(win|m)32/ # ruby color support for win
|
||||
|
||||
##
|
||||
# This is an adapted version of active_support/core_ext/string/inflections.rb
|
||||
|
@ -113,8 +113,8 @@ module ObjectSpace
|
|||
# Returns all the classes in the object space.
|
||||
def classes
|
||||
ObjectSpace.each_object(Module).select do |klass|
|
||||
# Why this? Ruby when you remove a constant don't clean it from
|
||||
# rb_tables, this mean that here we can found classes that was
|
||||
# Why? Ruby, when you remove a costant dosen't remove it from
|
||||
# rb_tables, this mean that here we can find classes that was
|
||||
# removed.
|
||||
klass.name rescue false
|
||||
end
|
||||
|
@ -191,8 +191,7 @@ end
|
|||
##
|
||||
# Loads our locale configuration files
|
||||
#
|
||||
|
||||
# I18n.load_path += Dir["#{File.dirname(__FILE__)}/locale/*.yml"] if defined?(I18n)
|
||||
I18n.load_path += Dir["#{File.dirname(__FILE__)}/locale/*.yml"] if defined?(I18n)
|
||||
|
||||
##
|
||||
# Used to determine if this file has already been required
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#
|
||||
module Padrino
|
||||
# The version constant for the current version of Padrino.
|
||||
VERSION = '0.10.5' unless defined?(Padrino::VERSION)
|
||||
VERSION = '0.10.6' unless defined?(Padrino::VERSION)
|
||||
|
||||
#
|
||||
# The current Padrino version.
|
||||
|
|
|
@ -34,5 +34,5 @@ Gem::Specification.new do |s|
|
|||
s.add_dependency("sinatra", "~> 1.3.1")
|
||||
s.add_dependency("http_router", "~> 0.10.2")
|
||||
s.add_dependency("thor", "~> 0.14.3")
|
||||
s.add_dependency("activesupport", "~> 3.1.0")
|
||||
s.add_dependency("activesupport", "~> 3.2.0")
|
||||
end
|
||||
|
|
|
@ -44,6 +44,8 @@ class MiniTest::Spec
|
|||
else
|
||||
super(name, *args, &block)
|
||||
end
|
||||
rescue Rack::Test::Error # no response yet
|
||||
super(name, *args, &block)
|
||||
end
|
||||
|
||||
alias :response :last_response
|
||||
|
|
|
@ -15,7 +15,6 @@ describe "Core" do
|
|||
assert_respond_to Padrino, :load!
|
||||
assert_respond_to Padrino, :reload!
|
||||
assert_respond_to Padrino, :version
|
||||
assert_respond_to Padrino, :bundle
|
||||
assert_respond_to Padrino, :configure_apps
|
||||
end
|
||||
|
||||
|
@ -23,7 +22,6 @@ describe "Core" do
|
|||
should 'validate global helpers' do
|
||||
assert_equal :test, Padrino.env
|
||||
assert_match /\/test/, Padrino.root
|
||||
assert_equal nil, Padrino.bundle
|
||||
assert_not_nil Padrino.version
|
||||
end
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
require File.expand_path(File.dirname(__FILE__) + '/helper')
|
||||
require 'lumberjack'
|
||||
require 'logger'
|
||||
|
||||
describe "PadrinoLogger" do
|
||||
|
||||
|
@ -98,3 +100,55 @@ describe "PadrinoLogger" do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "alternate logger: Lumberjack" do
|
||||
def setup_logger
|
||||
@log = StringIO.new
|
||||
Padrino.logger = Lumberjack::Logger.new(@log, :level => :debug)
|
||||
end
|
||||
|
||||
should "annotate the logger to support additional Padrino fancyness" do
|
||||
setup_logger
|
||||
Padrino.logger.debug("Debug message")
|
||||
assert_match(/Debug message/, @log.string)
|
||||
end
|
||||
|
||||
should "colorize log output after colorize! is called" do
|
||||
setup_logger
|
||||
Padrino.logger.colorize!
|
||||
|
||||
mock_app do
|
||||
enable :logging
|
||||
get("/"){ "Foo" }
|
||||
end
|
||||
get "/"
|
||||
|
||||
assert_match /\e\[1m200\e\[0m OK/, @log.string
|
||||
end
|
||||
end
|
||||
|
||||
describe "alternate logger: stdlib logger" do
|
||||
def setup_logger
|
||||
@log = StringIO.new
|
||||
Padrino.logger = Logger.new(@log)
|
||||
end
|
||||
|
||||
should "annotate the logger to support additional Padrino fancyness" do
|
||||
setup_logger
|
||||
Padrino.logger.debug("Debug message")
|
||||
assert_match(/Debug message/, @log.string)
|
||||
end
|
||||
|
||||
should "colorize log output after colorize! is called" do
|
||||
setup_logger
|
||||
Padrino.logger.colorize!
|
||||
|
||||
mock_app do
|
||||
enable :logging
|
||||
get("/"){ "Foo" }
|
||||
end
|
||||
get "/"
|
||||
|
||||
assert_match /\e\[1m200\e\[0m OK/, @log.string
|
||||
end
|
||||
end
|
||||
|
|
|
@ -78,6 +78,13 @@ describe "Routing" do
|
|||
assert_equal "My lucky number: 99 99", body
|
||||
end
|
||||
|
||||
should 'accept regexp routes with generate with :generate_with' do
|
||||
mock_app do
|
||||
get(%r{/fob|/baz}, :name => :foo, :generate_with => '/fob') { "regexp" }
|
||||
end
|
||||
assert_equal "/fob", @app.url(:foo)
|
||||
end
|
||||
|
||||
should "parse routes with question marks" do
|
||||
mock_app do
|
||||
get("/foo/?"){ "okey" }
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
require 'middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/support_lite' unless defined?(SupportLite)
|
||||
require 'padrino-core/support_lite' unless defined?(SupportLite)
|
||||
require 'cgi'
|
||||
# require 'i18n'
|
||||
require 'i18n'
|
||||
require 'enumerator'
|
||||
require 'active_support/core_ext/string/conversions' # to_date
|
||||
require 'active_support/core_ext/float/rounding' # round
|
||||
|
@ -11,7 +11,7 @@ require 'active_support/inflector' # humanize
|
|||
FileSet.glob_require('padrino-helpers/**/*.rb', __FILE__)
|
||||
|
||||
# Load our locales
|
||||
# I18n.load_path += Dir["#{File.dirname(__FILE__)}/padrino-helpers/locale/*.yml"]
|
||||
I18n.load_path += Dir["#{File.dirname(__FILE__)}/padrino-helpers/locale/*.yml"]
|
||||
|
||||
module Padrino
|
||||
##
|
||||
|
|
|
@ -17,13 +17,18 @@ module Padrino
|
|||
# @example
|
||||
# flash_tag(:notice, :id => 'flash-notice')
|
||||
# # Generates: <div class="notice">flash-notice</div>
|
||||
# flash_tag(:error, :success)
|
||||
# # Generates: <div class="error">flash-error</div>
|
||||
# # <div class="success">flash-success</div>
|
||||
#
|
||||
# @api public
|
||||
def flash_tag(kind, options={})
|
||||
def flash_tag(*args)
|
||||
options = args.extract_options!
|
||||
args.map do |kind|
|
||||
flash_text = flash[kind]
|
||||
return '' if flash_text.blank?
|
||||
options.reverse_merge!(:class => kind)
|
||||
content_tag(:div, flash_text, options)
|
||||
next if flash_text.blank?
|
||||
content_tag(:div, flash_text, options.reverse_merge(:class => kind))
|
||||
end.compact * "\n"
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -65,18 +70,17 @@ module Padrino
|
|||
# @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?
|
||||
url = args[0] ? args[0] + anchor.to_s : anchor || 'javascript:void(0);'
|
||||
url = args[0] ? args[0] + anchor.to_s : anchor || '#'
|
||||
options.reverse_merge!(:href => url)
|
||||
link_content = capture_html(&block)
|
||||
return '' unless parse_conditions(url, options)
|
||||
result_link = content_tag(:a, link_content, options)
|
||||
block_is_template?(block) ? concat_content(result_link) : result_link
|
||||
else
|
||||
name, url = args[0], (args[1] ? args[1] + anchor.to_s : anchor || 'javascript:void(0);')
|
||||
name, url = args[0], (args[1] ? args[1] + anchor.to_s : anchor || '#')
|
||||
return name unless parse_conditions(url, options)
|
||||
options.reverse_merge!(:href => url)
|
||||
content_tag(:a, name, options)
|
||||
|
@ -119,8 +123,8 @@ module Padrino
|
|||
desired_method = options[:method]
|
||||
options.delete(:method) if options[:method].to_s !~ /get|post/i
|
||||
options.reverse_merge!(:method => 'post', :action => url)
|
||||
options[:enctype] = "multipart/form-data" if options.delete(:multipart)
|
||||
options["data-remote"] = "true" if options.delete(:remote)
|
||||
options[:enctype] = 'multipart/form-data' if options.delete(:multipart)
|
||||
options['data-remote'] = 'true' if options.delete(:remote)
|
||||
inner_form_html = hidden_form_method_field(desired_method)
|
||||
inner_form_html += block_given? ? capture_html(&block) : submit_tag(name)
|
||||
content_tag('form', inner_form_html, options)
|
||||
|
@ -153,7 +157,7 @@ module Padrino
|
|||
# @api public
|
||||
def feed_tag(mime, url, options={})
|
||||
full_mime = (mime == :atom) ? 'application/atom+xml' : 'application/rss+xml'
|
||||
content_tag(:link, options.reverse_merge(:rel => 'alternate', :type => full_mime, :title => mime, :href => url))
|
||||
tag(:link, options.reverse_merge(:rel => 'alternate', :type => full_mime, :title => mime, :href => url))
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -291,9 +295,9 @@ module Padrino
|
|||
# @api public
|
||||
def javascript_include_tag(*sources)
|
||||
options = sources.extract_options!.symbolize_keys
|
||||
options.reverse_merge!(:type => 'text/javascript', :content => "")
|
||||
options.reverse_merge!(:type => 'text/javascript')
|
||||
sources.flatten.map { |source|
|
||||
tag(:script, options.reverse_merge(:src => asset_path(:js, source)))
|
||||
content_tag(:script, nil, options.reverse_merge(:src => asset_path(:js, source)))
|
||||
}.join("\n")
|
||||
end
|
||||
|
||||
|
@ -338,27 +342,23 @@ module Padrino
|
|||
# @api semipublic
|
||||
def asset_path(kind, source)
|
||||
return source if source =~ /^http/
|
||||
asset_folder = case kind
|
||||
when :css then 'stylesheets'
|
||||
when :js then 'javascripts'
|
||||
else kind.to_s
|
||||
end
|
||||
is_absolute = source =~ %r{^/}
|
||||
asset_folder = asset_folder_name(kind)
|
||||
source = source.to_s.gsub(/\s/, '%20')
|
||||
ignore_extension = (asset_folder.to_s == kind.to_s) # don't append extension
|
||||
ignore_extension = (asset_folder.to_s == kind.to_s) # don't append an extension
|
||||
source << ".#{kind}" unless ignore_extension or source =~ /\.#{kind}/
|
||||
result_path = source if source =~ %r{^/} # absolute path
|
||||
result_path ||= uri_root_path(asset_folder, source)
|
||||
timestamp = asset_timestamp(result_path)
|
||||
result_path = is_absolute ? source : uri_root_path(asset_folder, source)
|
||||
timestamp = asset_timestamp(result_path, is_absolute)
|
||||
"#{result_path}#{timestamp}"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
##
|
||||
# Returns the uri root of the application.
|
||||
# Returns the uri root of the application with optional paths appended.
|
||||
#
|
||||
# @example
|
||||
# uri_root_path("/some/path") => "/base/some/path"
|
||||
# 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)
|
||||
|
@ -370,13 +370,30 @@ module Padrino
|
|||
#
|
||||
# @example
|
||||
# asset_timestamp("some/path/to/file.png") => "?154543678"
|
||||
# asset_timestamp("/some/absolute/path.png", true) => nil
|
||||
#
|
||||
def asset_timestamp(file_path)
|
||||
def asset_timestamp(file_path, absolute=false)
|
||||
return nil if file_path =~ /\?/ || (self.class.respond_to?(:asset_stamp) && !self.class.asset_stamp)
|
||||
public_path = Padrino.root("public", file_path) if Padrino.respond_to?(:root)
|
||||
stamp = Time.now.to_i unless public_path && File.exist?(public_path)
|
||||
stamp ||= File.mtime(public_path).to_i
|
||||
"?#{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
|
||||
|
||||
##
|
||||
|
@ -395,26 +412,6 @@ module Padrino
|
|||
true
|
||||
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
|
||||
end
|
||||
end # AssetTagHelpers
|
||||
end # Helpers
|
||||
end # Padrino
|
||||
|
|
|
@ -42,6 +42,37 @@ module Padrino
|
|||
@template.text_field_tag field_name(field), options
|
||||
end
|
||||
|
||||
def number_field(field, options={})
|
||||
options.reverse_merge!(:value => field_value(field), :id => field_id(field))
|
||||
options.merge!(:class => field_error(field, options))
|
||||
@template.number_field_tag field_name(field), options
|
||||
end
|
||||
|
||||
def telephone_field(field, options={})
|
||||
options.reverse_merge!(:value => field_value(field), :id => field_id(field))
|
||||
options.merge!(:class => field_error(field, options))
|
||||
@template.telephone_field_tag field_name(field), options
|
||||
end
|
||||
alias_method :phone_field, :telephone_field
|
||||
|
||||
def email_field(field, options={})
|
||||
options.reverse_merge!(:value => field_value(field), :id => field_id(field))
|
||||
options.merge!(:class => field_error(field, options))
|
||||
@template.email_field_tag field_name(field), options
|
||||
end
|
||||
|
||||
def search_field(field, options={})
|
||||
options.reverse_merge!(:value => field_value(field), :id => field_id(field))
|
||||
options.merge!(:class => field_error(field, options))
|
||||
@template.search_field_tag field_name(field), options
|
||||
end
|
||||
|
||||
def url_field(field, options={})
|
||||
options.reverse_merge!(:value => field_value(field), :id => field_id(field))
|
||||
options.merge!(:class => field_error(field, options))
|
||||
@template.url_field_tag field_name(field), options
|
||||
end
|
||||
|
||||
# f.text_area :summary, :value => "(enter summary)", :id => 'summary'
|
||||
def text_area(field, options={})
|
||||
options.reverse_merge!(:value => field_value(field), :id => field_id(field))
|
||||
|
|
|
@ -74,13 +74,11 @@ module Padrino
|
|||
#
|
||||
# @api public
|
||||
def form_tag(url, options={}, &block)
|
||||
desired_method = options[:method]
|
||||
data_method = options.delete(:method) if options[:method].to_s !~ /get|post/i
|
||||
options.reverse_merge!(:method => "post", :action => url)
|
||||
options[:enctype] = "multipart/form-data" if options.delete(:multipart)
|
||||
options["data-remote"] = "true" if options.delete(:remote)
|
||||
options["data-method"] = data_method if data_method
|
||||
options["accept-charset"] ||= "UTF-8"
|
||||
desired_method = options[:method].to_s
|
||||
options.delete(:method) unless desired_method =~ /get|post/i
|
||||
options.reverse_merge!(:method => 'post', :action => url)
|
||||
options[:enctype] = 'multipart/form-data' if options.delete(:multipart)
|
||||
options['accept-charset'] ||= 'UTF-8'
|
||||
inner_form_html = hidden_form_method_field(desired_method)
|
||||
inner_form_html += capture_html(&block)
|
||||
concat_content content_tag(:form, inner_form_html, options)
|
||||
|
@ -140,9 +138,9 @@ module Padrino
|
|||
# @param [Hash] options Error message display options.
|
||||
# @option options [String] :header_tag ("h2")
|
||||
# Used for the header of the error div
|
||||
# @option options [String] :id ("errorExplanation")
|
||||
# @option options [String] :id ("field-errors")
|
||||
# The id of the error div.
|
||||
# @option options [String] :class ("errorExplanation")
|
||||
# @option options [String] :class ("field-errors")
|
||||
# The class of the error div.
|
||||
# @option options [Array<Object>] :object
|
||||
# The object (or array of objects) for which to display errors,
|
||||
|
@ -222,7 +220,7 @@ module Padrino
|
|||
# The field on the +object+ to display the error for.
|
||||
# @param [Hash] options
|
||||
# The options to control the error display.
|
||||
# @option options [String] :tag ("div")
|
||||
# @option options [String] :tag ("span")
|
||||
# The tag that encloses the error.
|
||||
# @option options [String] :prepend ("")
|
||||
# The text to prepend before the field error.
|
||||
|
@ -289,29 +287,216 @@ module Padrino
|
|||
end
|
||||
|
||||
##
|
||||
# Constructs a text field input from the given options
|
||||
# Creates a text field input with the given name and options
|
||||
#
|
||||
# @macro [new] input_field_doc
|
||||
# @param [String] name
|
||||
# The name of the input field.
|
||||
# @macro [new] text_field
|
||||
# @param [Symbol] name
|
||||
# The name of the input to create.
|
||||
# @param [Hash] options
|
||||
# The html options for the input field.
|
||||
# The HTML options to include in this field.
|
||||
#
|
||||
# @return [String] The html input field based on the +options+ specified
|
||||
# @option options [String] :id
|
||||
# Specifies a unique identifier for the field.
|
||||
# @option options [String] :class
|
||||
# Specifies the stylesheet class of the field.
|
||||
# @option options [String] :name
|
||||
# Specifies the name of the field.
|
||||
# @option options [String] :accesskey
|
||||
# Specifies a shortcut key to access the field.
|
||||
# @option options [Integer] :tabindex
|
||||
# Specifies the tab order of the field.
|
||||
# @option options [Integer] :maxlength
|
||||
# Specifies the maximum length, in characters, of the field.
|
||||
# @option options [Integer] :size
|
||||
# Specifies the width, in characters, of the field.
|
||||
# @option options [String] :placeholder
|
||||
# Specifies a short hint that describes the expected value of the field.
|
||||
# @option options [Boolean] :hidden
|
||||
# Specifies whether or not the field is hidden from view.
|
||||
# @option options [Boolean] :spellcheck
|
||||
# Specifies whether or not the field should have it's spelling and grammar checked for errors.
|
||||
# @option options [Boolean] :draggable
|
||||
# Specifies whether or not the field is draggable. (true, false, :auto)
|
||||
# @option options [String] :pattern
|
||||
# Specifies the regular expression pattern that the field's value is checked against.
|
||||
# @option options [Symbol] :autocomplete
|
||||
# Specifies whether or not the field should have autocomplete enabled. (:on, :off)
|
||||
# @option options [Boolean] :autofocus
|
||||
# Specifies whether or not the field should automatically get focus when the page loads.
|
||||
# @option options [Boolean] :required
|
||||
# Specifies whether or not the field is required to be completeled before the form is submitted.
|
||||
# @option options [Boolean] :readonly
|
||||
# Specifies whether or not the field is read only.
|
||||
# @option options [Boolean] :disabled
|
||||
# Specifies whether or not the field is disabled.
|
||||
#
|
||||
# @return [String]
|
||||
# Generated HTML with specified +options+
|
||||
#
|
||||
# @example
|
||||
# text_field_tag :username, :class => 'long'
|
||||
# text_field_tag :first_name, :maxlength => 40, :required => true
|
||||
# # => <input name="first_name" maxlength="40" required type="text">
|
||||
#
|
||||
# text_field_tag :last_name, :class => 'string', :size => 40
|
||||
# # => <input name="last_name" class="string" size="40" type="text">
|
||||
#
|
||||
# text_field_tag :username, :placeholder => 'Your Username'
|
||||
# # => <input name="username" placeholder="Your Username" type="text">
|
||||
#
|
||||
# @api public
|
||||
def text_field_tag(name, options={})
|
||||
options.reverse_merge!(:name => name)
|
||||
input_tag(:text, options)
|
||||
input_tag(:text, options.reverse_merge!(:name => name))
|
||||
end
|
||||
|
||||
##
|
||||
# Creates a number field input with the given name and options
|
||||
#
|
||||
# @macro [new] number_field
|
||||
# @param [Symbol] name
|
||||
# The name of the input to create.
|
||||
# @param [Hash] options
|
||||
# The HTML options to include in this field.
|
||||
#
|
||||
# @option options [String] :id
|
||||
# Specifies a unique identifier for the field.
|
||||
# @option options [String] :class
|
||||
# Specifies the stylesheet class of the field.
|
||||
# @option options [String] :name
|
||||
# Specifies the name of the field.
|
||||
# @option options [String] :accesskey
|
||||
# Specifies a shortcut key to access the field.
|
||||
# @option options [Integer] :tabindex
|
||||
# Specifies the tab order of the field.
|
||||
# @option options [Integer] :min
|
||||
# Specifies the minimum value of the field.
|
||||
# @option options [Integer] :max
|
||||
# Specifies the maximum value of the field.
|
||||
# @option options [Integer] :step
|
||||
# Specifies the legal number intervals of the field.
|
||||
# @option options [Boolean] :hidden
|
||||
# Specifies whether or not the field is hidden from view.
|
||||
# @option options [Boolean] :spellcheck
|
||||
# Specifies whether or not the field should have it's spelling and grammar checked for errors.
|
||||
# @option options [Boolean] :draggable
|
||||
# Specifies whether or not the field is draggable. (true, false, :auto)
|
||||
# @option options [String] :pattern
|
||||
# Specifies the regular expression pattern that the field's value is checked against.
|
||||
# @option options [Symbol] :autocomplete
|
||||
# Specifies whether or not the field should have autocomplete enabled. (:on, :off)
|
||||
# @option options [Boolean] :autofocus
|
||||
# Specifies whether or not the field should automatically get focus when the page loads.
|
||||
# @option options [Boolean] :required
|
||||
# Specifies whether or not the field is required to be completeled before the form is submitted.
|
||||
# @option options [Boolean] :readonly
|
||||
# Specifies whether or not the field is read only.
|
||||
# @option options [Boolean] :disabled
|
||||
# Specifies whether or not the field is disabled.
|
||||
#
|
||||
# @return [String]
|
||||
# Generated HTML with specified +options+
|
||||
#
|
||||
# @example
|
||||
# number_field_tag :quanity, :class => 'numeric'
|
||||
# # => <input name="quanity" class="numeric" type="number">
|
||||
#
|
||||
# number_field_tag :zip_code, :pattern => /[0-9]{5}/
|
||||
# # => <input name="zip_code" pattern="[0-9]{5}" type="number">
|
||||
#
|
||||
# number_field_tag :credit_card, :autocomplete => :off
|
||||
# # => <input name="credit_card" autocomplete="off" type="number">
|
||||
#
|
||||
# number_field_tag :age, :min => 18, :max => 120, :step => 1
|
||||
# # => <input name="age" min="18" max="120" step="1" type="number">
|
||||
#
|
||||
# @api public
|
||||
def number_field_tag(name, options={})
|
||||
input_tag(:number, options.reverse_merge(:name => name))
|
||||
end
|
||||
|
||||
##
|
||||
# Creates a telephone field input with the given name and options
|
||||
#
|
||||
# @macro text_field
|
||||
#
|
||||
# @example
|
||||
# telephone_field_tag :phone_number, :class => 'string'
|
||||
# # => <input name="phone_number" class="string" type="tel">
|
||||
#
|
||||
# telephone_field_tag :cell_phone, :tabindex => 1
|
||||
# telephone_field_tag :work_phone, :tabindex => 2
|
||||
# telephone_field_tag :home_phone, :tabindex => 3
|
||||
#
|
||||
# # => <input name="cell_phone" tabindex="1" type="tel">
|
||||
# # => <input name="work_phone" tabindex="2" type="tel">
|
||||
# # => <input name="home_phone" tabindex="3" type="tel">
|
||||
#
|
||||
# @api public
|
||||
def telephone_field_tag(name, options={})
|
||||
input_tag(:tel, options.reverse_merge(:name => name))
|
||||
end
|
||||
alias_method :phone_field_tag, :telephone_field_tag
|
||||
|
||||
##
|
||||
# Creates an email field input with the given name and options
|
||||
#
|
||||
# @macro text_field
|
||||
#
|
||||
# @example
|
||||
# email_field_tag :email, :placeholder => 'you@example.com'
|
||||
# # => <input name="email" placeholder="you@example.com" type="email">
|
||||
#
|
||||
# email_field_tag :email, :value => 'padrinorb@gmail.com', :readonly => true
|
||||
# # => <input name="email" value="padrinorb@gmail.com" readonly type="email">
|
||||
#
|
||||
# @api public
|
||||
def email_field_tag(name, options={})
|
||||
input_tag(:email, options.reverse_merge(:name => name))
|
||||
end
|
||||
|
||||
##
|
||||
# Creates a search field input with the given name and options
|
||||
#
|
||||
# @macro text_field
|
||||
#
|
||||
# @example
|
||||
# search_field_tag :search, :placeholder => 'Search this website...'
|
||||
# # => <input name="search" placeholder="Search this website..." type="search">
|
||||
#
|
||||
# search_field_tag :search, :maxlength => 15, :class => ['search', 'string']
|
||||
# # => <input name="search" maxlength="15" class="search string">
|
||||
#
|
||||
# search_field_tag :search, :id => 'search'
|
||||
# # => <input name="search" id="search" type="search">
|
||||
#
|
||||
# search_field_tag :search, :autofocus => true
|
||||
# # => <input name="search" autofocus type="search">
|
||||
#
|
||||
# @api public
|
||||
def search_field_tag(name, options={})
|
||||
input_tag(:search, options.reverse_merge(:name => name))
|
||||
end
|
||||
|
||||
##
|
||||
# Creates a url field input with the given name and options
|
||||
#
|
||||
# @macro text_field
|
||||
#
|
||||
# @example
|
||||
# url_field_tag :favorite_website, :placeholder => 'http://padrinorb.com'
|
||||
# <input name="favorite_website" placeholder="http://padrinorb.com." type="url">
|
||||
#
|
||||
# url_field_tag :home_page, :class => 'string url'
|
||||
# <input name="home_page" class="string url", type="url">
|
||||
#
|
||||
# @api public
|
||||
def url_field_tag(name, options={})
|
||||
input_tag(:url, options.reverse_merge(:name => name))
|
||||
end
|
||||
|
||||
##
|
||||
# Constructs a hidden field input from the given options
|
||||
#
|
||||
# @macro input_field_doc
|
||||
# @macro text_field
|
||||
#
|
||||
# @example
|
||||
# hidden_field_tag :session_key, :value => "__secret__"
|
||||
|
@ -325,7 +510,7 @@ module Padrino
|
|||
##
|
||||
# Constructs a text area input from the given options
|
||||
#
|
||||
# @macro input_field_doc
|
||||
# @macro text_field
|
||||
#
|
||||
# @example
|
||||
# text_area_tag :username, :class => 'long', :value => "Demo?"
|
||||
|
@ -339,7 +524,7 @@ module Padrino
|
|||
##
|
||||
# Constructs a password field input from the given options
|
||||
#
|
||||
# @macro input_field_doc
|
||||
# @macro text_field
|
||||
#
|
||||
# @example
|
||||
# password_field_tag :password, :class => 'long'
|
||||
|
@ -353,7 +538,7 @@ module Padrino
|
|||
##
|
||||
# Constructs a check_box from the given options
|
||||
#
|
||||
# @macro input_field_doc
|
||||
# @macro text_field
|
||||
#
|
||||
# @example
|
||||
# check_box_tag :remember_me, :value => 'Yes'
|
||||
|
@ -367,7 +552,7 @@ module Padrino
|
|||
##
|
||||
# Constructs a radio_button from the given options
|
||||
#
|
||||
# @macro input_field_doc
|
||||
# @macro text_field
|
||||
#
|
||||
# @example
|
||||
# radio_button_tag :remember_me, :value => 'true'
|
||||
|
@ -381,7 +566,7 @@ module Padrino
|
|||
##
|
||||
# Constructs a file field input from the given options
|
||||
#
|
||||
# @macro input_field_doc
|
||||
# @macro text_field
|
||||
#
|
||||
# @example
|
||||
# file_field_tag :photo, :class => 'long'
|
||||
|
|
|
@ -81,7 +81,7 @@ module Padrino
|
|||
# @api public
|
||||
def simple_format(text, options={})
|
||||
t = options.delete(:tag) || :p
|
||||
start_tag = tag(t, options.merge(:open => true))
|
||||
start_tag = tag(t, options, true)
|
||||
text = text.to_s.dup
|
||||
text.gsub!(/\r\n?/, "\n") # \r\n and \r -> \n
|
||||
text.gsub!(/\n\n+/, "</#{t}>\n\n#{start_tag}") # 2+ newline -> paragraph
|
||||
|
@ -375,7 +375,7 @@ module Padrino
|
|||
javascript_mapping = { '\\' => '\\\\', '</' => '<\/', "\r\n" => '\n', "\n" => '\n', "\r" => '\n', '"' => '\\"', "'" => "\\'" }
|
||||
html_content.gsub(/(\\|<\/|\r\n|[\n\r"'])/) { javascript_mapping[$1] }
|
||||
end
|
||||
|
||||
alias :escape_javascript :js_escape_html
|
||||
end # FormatHelpers
|
||||
end # Helpers
|
||||
end # Padrino
|
||||
|
|
|
@ -13,90 +13,247 @@ module Padrino
|
|||
'"' => """
|
||||
}
|
||||
|
||||
BOOLEAN_ATTRIBUTES = [
|
||||
:autoplay,
|
||||
:autofocus,
|
||||
:formnovalidate,
|
||||
:checked,
|
||||
:disabled,
|
||||
:hidden,
|
||||
:loop,
|
||||
:multiple,
|
||||
:muted,
|
||||
:readonly,
|
||||
:required,
|
||||
:selected
|
||||
]
|
||||
|
||||
##
|
||||
# Creates an html tag with given name, content and options
|
||||
# Custom data attributes,
|
||||
# feel free to update with yours:
|
||||
#
|
||||
# @overload content_tag(name, content, options)
|
||||
# @param [Symbol] name The html type of tag.
|
||||
# @param [String] content The contents in the tag.
|
||||
# @param [Hash] options The html options to include in this tag.
|
||||
# @overload content_tag(name, options, &block)
|
||||
# @param [Symbol] name The html type of tag.
|
||||
# @param [Hash] options The html options to include in this tag.
|
||||
# @param [Proc] block The block returning html content
|
||||
# Padrino::Helpers::TagHelpers::DATA_ATTRIBUTES.push(:dialog)
|
||||
# text_field :foo, :dialog => true
|
||||
# # Generates: <input type="text" data-dialog="true" name="foo" />
|
||||
#
|
||||
# @return [String] The html generated for the tag.
|
||||
DATA_ATTRIBUTES = [
|
||||
:method,
|
||||
:remote,
|
||||
:confirm
|
||||
]
|
||||
|
||||
##
|
||||
# Creates an HTML tag with given name, content, and options
|
||||
#
|
||||
# @overload content_tag(name, content, options = nil)
|
||||
# @param [Symbol] name
|
||||
# The name of the HTML tag to create.
|
||||
# @param [String] content
|
||||
# The content inside of the the tag.
|
||||
# @param [Hash] options
|
||||
# The HTML options to include in this tag.
|
||||
#
|
||||
# @overload content_tag(name, options = nil, &block)
|
||||
# @param [Symbol] name
|
||||
# The name of the HTML tag to create.
|
||||
# @param [Hash] options
|
||||
# The HTML options to include in this tag.
|
||||
# @param [Proc] block
|
||||
# The block returning HTML content.
|
||||
#
|
||||
# @macro [new] global_html_attributes
|
||||
# @option options [String] :id
|
||||
# Specifies a unique identifier for the element.
|
||||
# @option options [String] :class
|
||||
# Specifies the stylesheet class of the element.
|
||||
# @option options [String] :title
|
||||
# Specifies the title for the element.
|
||||
# @option options [String] :accesskey
|
||||
# Specifies a shortcut key to access the element.
|
||||
# @option options [Symbol] :dropzone
|
||||
# Specifies what happens when dragged items are dropped on the element. (:copy, :link, :move)
|
||||
# @option options [Boolean] :hidden
|
||||
# Specifies whether or not the element is hidden from view.
|
||||
# @option options [Boolean] :draggable
|
||||
# Specifies whether or not the element is draggable. (true, false, :auto)
|
||||
# @option options [Boolean] :contenteditable
|
||||
# Specifies whether or not the element is editable.
|
||||
#
|
||||
# @return [String]
|
||||
# Generated HTML with specified +options+
|
||||
#
|
||||
# @example
|
||||
# content_tag(:p, "hello", :class => 'light')
|
||||
# content_tag(:p, :class => 'dark') { ... }
|
||||
# content_tag(:p, 'Hello World', :class => 'light')
|
||||
#
|
||||
# # => <p class="light">
|
||||
# # => Hello World
|
||||
# # => </p>
|
||||
#
|
||||
# content_tag(:p, :class => 'dark') do
|
||||
# link_to 'Padrino', 'http://www.padrinorb.com'
|
||||
# end
|
||||
#
|
||||
# # => <p class="dark">
|
||||
# # => <a href="http://www.padrinorb.com">Padrino</a>
|
||||
# # => </p>
|
||||
#
|
||||
# @api public
|
||||
def content_tag(*args, &block)
|
||||
name = args.first
|
||||
options = args.extract_options!
|
||||
tag_html = block_given? ? capture_html(&block) : args[1]
|
||||
tag_result = tag(name, options.merge(:content => tag_html))
|
||||
block_is_template?(block) ? concat_content(tag_result) : tag_result
|
||||
def content_tag(name, content = nil, options = nil, &block)
|
||||
if block_given?
|
||||
options = content if content.is_a?(Hash)
|
||||
content = capture_html(&block)
|
||||
end
|
||||
|
||||
content = content.join("\n") if content.respond_to?(:join)
|
||||
|
||||
options = parse_data_options(name, options)
|
||||
attributes = tag_attributes(options)
|
||||
output = "<#{name}#{attributes}>#{content}</#{name}>"
|
||||
block_is_template?(block) ? concat_content(output) : output
|
||||
end
|
||||
|
||||
##
|
||||
# Creates an html input field with given type and options
|
||||
# Creates an HTML input field with the given type and options
|
||||
#
|
||||
# @param [Symbol] type
|
||||
# The html type of tag to create.
|
||||
# The type of input to create.
|
||||
# @param [Hash] options
|
||||
# The html options to include in this tag.
|
||||
# The HTML options to include in this input.
|
||||
#
|
||||
# @return [String] The html for the input tag.
|
||||
# @option options [String] :id
|
||||
# Specifies a unique identifier for the input.
|
||||
# @option options [String] :class
|
||||
# Specifies the stylesheet class of the input.
|
||||
# @option options [String] :name
|
||||
# Specifies the name of the input.
|
||||
# @option options [String] :accesskey
|
||||
# Specifies a shortcut key to access the input.
|
||||
# @option options [Integer] :tabindex
|
||||
# Specifies the tab order of the input.
|
||||
# @option options [Boolean] :hidden
|
||||
# Specifies whether or not the input is hidden from view.
|
||||
# @option options [Boolean] :spellcheck
|
||||
# Specifies whether or not the input should have it's spelling and grammar checked for errors.
|
||||
# @option options [Boolean] :draggable
|
||||
# Specifies whether or not the input is draggable. (true, false, :auto)
|
||||
# @option options [String] :pattern
|
||||
# Specifies the regular expression pattern that the input's value is checked against.
|
||||
# @option options [Symbol] :autocomplete
|
||||
# Specifies whether or not the input should have autocomplete enabled. (:on, :off)
|
||||
# @option options [Boolean] :autofocus
|
||||
# Specifies whether or not the input should automatically get focus when the page loads.
|
||||
# @option options [Boolean] :required
|
||||
# Specifies whether or not the input is required to be completeled before the form is submitted.
|
||||
# @option options [Boolean] :readonly
|
||||
# Specifies whether or not the input is read only.
|
||||
# @option options [Boolean] :disabled
|
||||
# Specifies whether or not the input is disabled.
|
||||
#
|
||||
# @return [String]
|
||||
# Generated HTML with specified +options+
|
||||
#
|
||||
# @example
|
||||
# input_tag :text, :class => "test"
|
||||
# input_tag :password, :size => "20"
|
||||
# input_tag :text, :name => 'handle'
|
||||
# # => <input type="test" name="handle" />
|
||||
#
|
||||
# input_tag :password, :name => 'password', :size => 20
|
||||
# # => <input type="password" name="password" size="20" />
|
||||
#
|
||||
# input_tag :text, :name => 'username', :required => true, :autofocus => true
|
||||
# # => <input type="text" name="username" required autofocus />
|
||||
#
|
||||
# input_tag :number, :name => 'credit_card', :autocomplete => :off
|
||||
# # => <input type="number" autocomplete="off" />
|
||||
#
|
||||
# @api semipublic
|
||||
def input_tag(type, options = {})
|
||||
options.reverse_merge!(:type => type)
|
||||
tag(:input, options)
|
||||
tag(:input, options.reverse_merge!(:type => type))
|
||||
end
|
||||
|
||||
##
|
||||
# Creates an html tag with the given name and options
|
||||
# Creates an HTML tag with the given name and options
|
||||
#
|
||||
# @param [Symbol] type
|
||||
# The html type of tag to create.
|
||||
# @param [Symbol] name
|
||||
# The name of the HTML tag to create.
|
||||
# @param [Hash] options
|
||||
# The html options to include in this tag.
|
||||
# The HTML options to include in this tag.
|
||||
#
|
||||
# @return [String] The html for the input tag.
|
||||
# @macro global_html_attributes
|
||||
#
|
||||
# @return [String]
|
||||
# Generated HTML with specified +options+
|
||||
#
|
||||
# @example
|
||||
# tag(:br, :style => 'clear:both')
|
||||
# tag(:p, :content => "hello", :class => 'large')
|
||||
# tag :hr, :class => 'dotted'
|
||||
# # => <hr class="dotted">
|
||||
#
|
||||
# tag :input, :name => 'username', :type => :text
|
||||
# # => <input name="username" type="text" />
|
||||
#
|
||||
# tag :img, :src => 'images/pony.jpg', :alt => 'My Little Pony'
|
||||
# # => <img src="images/pony.jpg" alt="My Little Pony" />
|
||||
#
|
||||
# tag :img, :src => 'sinatra.jpg, :data => { :nsfw => false, :geo => [34.087, -118.407] }
|
||||
# # => <img src="sinatra.jpg" data-nsfw="false" data-geo="34.087 -118.407" />
|
||||
#
|
||||
# @api public
|
||||
def tag(name, options={})
|
||||
content, open_tag = options.delete(:content), options.delete(:open)
|
||||
content = content.join("\n") if content.respond_to?(:join)
|
||||
identity_tag_attributes.each { |attr| options[attr] = attr.to_s if options[attr] }
|
||||
html_attrs = options.map { |a, v| v.nil? || v == false ? nil : "#{a}=\"#{escape_value(v)}\"" }.compact.join(" ")
|
||||
base_tag = (html_attrs.present? ? "<#{name} #{html_attrs}" : "<#{name}")
|
||||
base_tag << (open_tag ? ">" : (content ? ">#{content}</#{name}>" : " />"))
|
||||
def tag(name, options = nil, open = false)
|
||||
options = parse_data_options(name, options)
|
||||
attributes = tag_attributes(options)
|
||||
"<#{name}#{attributes}#{open ? '>' : ' />'}"
|
||||
end
|
||||
|
||||
private
|
||||
##
|
||||
# Returns a list of attributes which can only contain an identity value (i.e selected)
|
||||
#
|
||||
def identity_tag_attributes
|
||||
[:checked, :disabled, :selected, :multiple]
|
||||
# Returns a compiled list of HTML attributes
|
||||
##
|
||||
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
|
||||
%(#{k}="#{escape_value(v)}")
|
||||
end
|
||||
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
|
||||
|
||||
##
|
||||
# Iterate through nested values
|
||||
#
|
||||
def nested_values(attribute, hash)
|
||||
hash.map do |k, v|
|
||||
if v.is_a?(Hash)
|
||||
nested_values("#{attribute}-#{k.to_s.dasherize}", v)
|
||||
else
|
||||
%(#{attribute}-#{k.to_s.dasherize}="#{escape_value(v)}")
|
||||
end
|
||||
end * ' '
|
||||
end
|
||||
|
||||
##
|
||||
# Parses custom data attributes
|
||||
#
|
||||
def parse_data_options(tag, options)
|
||||
return if options.nil?
|
||||
parsed_options = options.dup
|
||||
options.each do |k, v|
|
||||
next if !DATA_ATTRIBUTES.include?(k) || (tag.to_s == 'form' && k == :method)
|
||||
parsed_options["data-#{k}"] = parsed_options.delete(k)
|
||||
parsed_options[:rel] = 'nofollow' if k == :method
|
||||
end
|
||||
parsed_options
|
||||
end
|
||||
end # TagHelpers
|
||||
end # Helpers
|
||||
|
|
24
middleman-core/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/form_for.erb
vendored
Normal file → Executable file
24
middleman-core/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/form_for.erb
vendored
Normal file → Executable file
|
@ -5,14 +5,30 @@
|
|||
<%= f.label :username, :caption => "Login: ", :class => 'user-label' %>
|
||||
<%= f.text_field :username, :class => 'user-text', :value => "John" %>
|
||||
</p>
|
||||
<p>
|
||||
<%= f.label :email, :caption => "Email", :class => 'user-email' %>
|
||||
<%= f.text_field :email %>
|
||||
</p>
|
||||
<p>
|
||||
<%= f.label :password %>
|
||||
<%= f.password_field :password, :class => 'user-password', :value => "secret" %>
|
||||
</p>
|
||||
<p>
|
||||
<%= f.label :age %>
|
||||
<%= f.number_field :age, :class => 'numeric '%>
|
||||
</p>
|
||||
<p>
|
||||
<%= f.label :telephone %>
|
||||
<%= f.telephone_field :telephone, :class => 'numeric' %>
|
||||
</p>
|
||||
<p>
|
||||
<%= f.label :email, :caption => 'Email Address: ' %>
|
||||
<%= f.email_field :email, :class => 'string' %>
|
||||
</p>
|
||||
<p>
|
||||
<%= f.label :webpage, :caption => 'Your Web Page: ' %>
|
||||
<%= f.url_field :webpage, :class => 'string' %>
|
||||
</p>
|
||||
<p>
|
||||
<%= f.label :search %>
|
||||
<%= f.search_field :search, :class => 'string' %>
|
||||
</p>
|
||||
<p>
|
||||
<%= f.label :photo %>
|
||||
<%= f.file_field :photo, :class => 'user-photo' %>
|
||||
|
|
18
middleman-core/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/form_for.haml
vendored
Normal file → Executable file
18
middleman-core/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/form_for.haml
vendored
Normal file → Executable file
|
@ -4,12 +4,24 @@
|
|||
%p
|
||||
= f.label :username, :caption => "Login: ", :class => 'user-label'
|
||||
= f.text_field :username, :class => 'user-text', :value => "John"
|
||||
%p
|
||||
= f.label :email, :caption => "Email", :class => 'user-email'
|
||||
= f.text_field :email
|
||||
%p
|
||||
= f.label :password
|
||||
= f.password_field :password, :class => 'user-password', :value => "secret"
|
||||
%p
|
||||
= f.label :age
|
||||
= f.number_field :age, :class => 'numeric'
|
||||
%p
|
||||
= f.label :telephone
|
||||
= f.telephone_field :telephone, :class => 'numeric'
|
||||
%p
|
||||
= f.label :email, :caption => 'Email Address: '
|
||||
= f.email_field :email, :class => 'string'
|
||||
%p
|
||||
= f.label :webpage, :caption => 'Your Web Page: '
|
||||
= f.url_field :webpage, :class => 'string'
|
||||
%p
|
||||
= f.label :search
|
||||
= f.search_field :search, :class => 'string'
|
||||
%p
|
||||
= f.label :photo
|
||||
= f.file_field :photo, :class => 'user-photo'
|
||||
|
|
18
middleman-core/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/form_for.slim
vendored
Normal file → Executable file
18
middleman-core/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/form_for.slim
vendored
Normal file → Executable file
|
@ -4,12 +4,24 @@
|
|||
p
|
||||
== f.label :username, :caption => "Login: ", :class => 'user-label'
|
||||
== f.text_field :username, :class => 'user-text', :value => "John"
|
||||
p
|
||||
== f.label :email, :caption => "Email", :class => 'user-email'
|
||||
== f.text_field :email
|
||||
p
|
||||
== f.label :password
|
||||
== f.password_field :password, :class => 'user-password', :value => "secret"
|
||||
p
|
||||
== f.label :age
|
||||
== f.number_field :age, :class => 'numeric'
|
||||
p
|
||||
== f.label :telephone
|
||||
== f.telephone_field :telephone, :class => 'numeric'
|
||||
p
|
||||
== f.label :email, :caption => 'Email Address: '
|
||||
== f.email_field :email, :class => 'string'
|
||||
p
|
||||
== f.label :webpage, :caption => 'Your Web Page: '
|
||||
== f.url_field :webpage, :class => 'string'
|
||||
p
|
||||
== f.label :search
|
||||
== f.search_field :search, :class => 'string'
|
||||
p
|
||||
== f.label :photo
|
||||
== f.file_field :photo, :class => 'user-photo'
|
||||
|
|
30
middleman-core/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/form_tag.erb
vendored
Normal file → Executable file
30
middleman-core/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/form_tag.erb
vendored
Normal file → Executable file
|
@ -5,6 +5,16 @@
|
|||
<%= text_field_tag :username %>
|
||||
<%= label_tag :password %>
|
||||
<%= password_field_tag :password %>
|
||||
<%= label_tag :email %>
|
||||
<%= email_field_tag :email %>
|
||||
<%= label_tag :age %>
|
||||
<%= number_field_tag :age %>
|
||||
<%= label_tag :telephone %>
|
||||
<%= telephone_field_tag :telephone %>
|
||||
<%= label_tag :webpage %>
|
||||
<%= url_field_tag :webpage %>
|
||||
<%= label_tag :search %>
|
||||
<%= search_field_tag :search %>
|
||||
<%= check_box_tag :remember_me %>
|
||||
<%= label_tag :gender %>
|
||||
<%= label_tag :color %>
|
||||
|
@ -27,6 +37,26 @@
|
|||
<%= label_tag :password, :class => 'first' %>
|
||||
<%= password_field_tag :password, :value => params[:password] %>
|
||||
</p>
|
||||
<p>
|
||||
<%= label_tag :email, :caption => 'Email Address' %>
|
||||
<%= email_field_tag :email, :class => 'string' %>
|
||||
</p>
|
||||
<p>
|
||||
<%= label_tag :age, :class => 'age' %>
|
||||
<%= number_field_tag :age, :class => 'numeric' %>
|
||||
</p>
|
||||
<p>
|
||||
<%= label_tag :telephone, :class => 'telephone' %>
|
||||
<%= telephone_field_tag :telephone, :class => 'numeric' %>
|
||||
</p>
|
||||
<p>
|
||||
<%= label_tag :webpage, :caption => 'Your Home Page' %>
|
||||
<%= url_field_tag :webpage, :class => 'string' %>
|
||||
</p>
|
||||
<p>
|
||||
<%= label_tag :search %>
|
||||
<%= search_field_tag :search, :class => 'string' %>
|
||||
</p>
|
||||
<p>
|
||||
<%= label_tag :about, :class => 'about', :caption => "About Me" %>
|
||||
<%= text_area_tag :about, :class => 'large' %>
|
||||
|
|
25
middleman-core/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/form_tag.haml
vendored
Normal file → Executable file
25
middleman-core/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/form_tag.haml
vendored
Normal file → Executable file
|
@ -6,6 +6,16 @@
|
|||
= text_field_tag :username
|
||||
= label_tag :password
|
||||
= password_field_tag :password
|
||||
= label_tag :email
|
||||
= email_field_tag :email
|
||||
= label_tag :age
|
||||
= number_field_tag :age
|
||||
= label_tag :telephone
|
||||
= telephone_field_tag :telephone
|
||||
= label_tag :webpage
|
||||
= url_field_tag :webpage
|
||||
= label_tag :search
|
||||
= search_field_tag :search
|
||||
= label_tag :color
|
||||
= select_tag :color, :options => ['green', 'orange', 'purple']
|
||||
= label_tag :gender
|
||||
|
@ -24,6 +34,21 @@
|
|||
%p
|
||||
= label_tag :password, :class => 'first'
|
||||
= password_field_tag :password, :value => params[:password]
|
||||
%p
|
||||
= label_tag :email, :caption => 'Email Address'
|
||||
= email_field_tag :email, :class => 'string'
|
||||
%p
|
||||
= label_tag :age, :class => 'age'
|
||||
= number_field_tag :age, :class => 'numeric'
|
||||
%p
|
||||
= label_tag :telephone, :class => 'telephone'
|
||||
= telephone_field_tag :telephone, :class => 'numeric'
|
||||
%p
|
||||
= label_tag :webpage, :caption => 'Your Home Page'
|
||||
= url_field_tag :webpage, :class => 'string'
|
||||
%p
|
||||
= label_tag :search
|
||||
= search_field_tag :search, :class => 'string'
|
||||
%p
|
||||
= label_tag :about, :class => 'about', :caption => "About Me"
|
||||
= text_area_tag :about, :class => 'large'
|
||||
|
|
25
middleman-core/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/form_tag.slim
vendored
Normal file → Executable file
25
middleman-core/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/form_tag.slim
vendored
Normal file → Executable file
|
@ -6,6 +6,16 @@
|
|||
== text_field_tag :username
|
||||
== label_tag :password
|
||||
== password_field_tag :password
|
||||
== label_tag :email
|
||||
== email_field_tag :email
|
||||
== label_tag :age
|
||||
== number_field_tag :age
|
||||
== label_tag :telephone
|
||||
== telephone_field_tag :telephone
|
||||
== label_tag :webpage
|
||||
== url_field_tag :webpage
|
||||
== label_tag :search
|
||||
== search_field_tag :search
|
||||
== label_tag :color
|
||||
== select_tag :color, :options => ['green', 'orange', 'purple']
|
||||
== label_tag :gender
|
||||
|
@ -24,6 +34,21 @@
|
|||
p
|
||||
== label_tag :password, :class => 'first'
|
||||
== password_field_tag :password, :value => params[:password]
|
||||
p
|
||||
== label_tag :email, :caption => 'Email Address'
|
||||
== email_field_tag :email, :class => 'string'
|
||||
p
|
||||
== label_tag :age, :class => 'age'
|
||||
== number_field_tag :age, :class => 'numeric'
|
||||
p
|
||||
== label_tag :telephone, :class => 'telephone'
|
||||
== telephone_field_tag :telephone, :class => 'numeric'
|
||||
p
|
||||
== label_tag :webpage, :caption => 'Your Home Page'
|
||||
== url_field_tag :webpage, :class => 'string'
|
||||
p
|
||||
== label_tag :search
|
||||
== search_field_tag :search, :class => 'string'
|
||||
p
|
||||
== label_tag :about, :class => 'about', :caption => "About Me"
|
||||
== text_area_tag :about, :class => 'large'
|
||||
|
|
|
@ -9,7 +9,7 @@ describe "AssetTagHelpers" do
|
|||
end
|
||||
|
||||
def flash
|
||||
{ :notice => "Demo notice" }
|
||||
@_flash ||= { :notice => "Demo notice" }
|
||||
end
|
||||
|
||||
context 'for #flash_tag method' do
|
||||
|
@ -20,6 +20,14 @@ describe "AssetTagHelpers" do
|
|||
actual_html = flash_tag(:notice, :class => 'notice', :id => 'notice-area')
|
||||
assert_has_tag('div.notice#notice-area', :content => "Demo notice") { actual_html }
|
||||
end
|
||||
should "display multiple flash tags with given attributes" do
|
||||
flash[:error] = 'wrong'
|
||||
flash[:success] = 'okey'
|
||||
actual_html = flash_tag(:success, :error, :id => 'area')
|
||||
assert_has_tag('div.success#area', :content => flash[:success]) { actual_html }
|
||||
assert_has_tag('div.error#area', :content => flash[:error]) { actual_html }
|
||||
assert_has_no_tag('div.notice') { actual_html }
|
||||
end
|
||||
end
|
||||
|
||||
context 'for #link_to method' do
|
||||
|
@ -39,7 +47,7 @@ describe "AssetTagHelpers" do
|
|||
|
||||
should "display link element with void url and options" do
|
||||
actual_link = link_to('Sign up', :class => "test")
|
||||
assert_has_tag('a', :content => "Sign up", :href => 'javascript:void(0);', :class => 'test') { actual_link }
|
||||
assert_has_tag('a', :content => "Sign up", :href => '#', :class => 'test') { actual_link }
|
||||
end
|
||||
|
||||
should "display link element with remote option" do
|
||||
|
@ -146,10 +154,10 @@ describe "AssetTagHelpers" do
|
|||
context 'for #image_tag method' do
|
||||
should "display image tag absolute link with no options" do
|
||||
time = stop_time_for_test
|
||||
assert_has_tag('img', :src => "/absolute/pic.gif?#{time.to_i}") { image_tag('/absolute/pic.gif') }
|
||||
assert_has_tag('img', :src => "/absolute/pic.gif") { image_tag('/absolute/pic.gif') }
|
||||
end
|
||||
|
||||
should "display image tag absolute link with specified uri root" do
|
||||
should "display image tag relative link with specified uri root" do
|
||||
time = stop_time_for_test
|
||||
self.class.stubs(:uri_root).returns("/blog")
|
||||
assert_has_tag('img', :src => "/blog/images/relative/pic.gif?#{time.to_i}") { image_tag('relative/pic.gif') }
|
||||
|
@ -201,7 +209,7 @@ describe "AssetTagHelpers" do
|
|||
time = stop_time_for_test
|
||||
expected_options = { :media => "screen", :rel => "stylesheet", :type => "text/css" }
|
||||
actual_html = stylesheet_link_tag('/css/style')
|
||||
assert_has_tag('link', expected_options.merge(:href => "/css/style.css?#{time.to_i}")) { actual_html }
|
||||
assert_has_tag('link', expected_options.merge(:href => "/css/style.css")) { actual_html }
|
||||
end
|
||||
|
||||
should "display stylesheet link item with uri root" do
|
||||
|
@ -257,7 +265,7 @@ describe "AssetTagHelpers" do
|
|||
should "display javascript item with absolute path" do
|
||||
time = stop_time_for_test
|
||||
actual_html = javascript_include_tag('/js/application')
|
||||
assert_has_tag('script', :src => "/js/application.js?#{time.to_i}", :type => "text/javascript") { actual_html }
|
||||
assert_has_tag('script', :src => "/js/application.js", :type => "text/javascript") { actual_html }
|
||||
end
|
||||
|
||||
should "display javascript item with uri root" do
|
||||
|
|
|
@ -63,7 +63,7 @@ describe "FormBuilder" do
|
|||
|
||||
should "display correct form html with remote option and method put" do
|
||||
actual_html = form_for(@user, '/update', :"accept-charset" => "UTF-8", :remote => true, :method => 'put') { "Demo" }
|
||||
assert_has_tag('form', :"accept-charset" => "UTF-8", :method => 'post', "data-method" => 'put', "data-remote" => 'true') { actual_html }
|
||||
assert_has_tag('form', :"accept-charset" => "UTF-8", :method => 'post', "data-remote" => 'true') { actual_html }
|
||||
assert_has_tag('form input', :type => 'hidden', :name => "_method", :value => 'put') { actual_html }
|
||||
end
|
||||
|
||||
|
@ -199,7 +199,7 @@ describe "FormBuilder" do
|
|||
assert_have_selector '#demo2 div.field-errors ul li', :content => "Fake must be valid"
|
||||
assert_have_selector '#demo2 div.field-errors ul li', :content => "Second must be present"
|
||||
assert_have_selector '#demo2 div.field-errors ul li', :content => "Third must be a number"
|
||||
assert_have_selector '#demo input', :name => 'markup_user[email]', :class => 'invalid'
|
||||
assert_have_selector '#demo input', :name => 'markup_user[email]', :class => 'string invalid'
|
||||
end
|
||||
|
||||
should "display correct form in erb" do
|
||||
|
@ -212,7 +212,7 @@ describe "FormBuilder" do
|
|||
assert_have_selector '#demo2 div.field-errors ul li', :content => "Fake must be valid"
|
||||
assert_have_selector '#demo2 div.field-errors ul li', :content => "Second must be present"
|
||||
assert_have_selector '#demo2 div.field-errors ul li', :content => "Third must be a number"
|
||||
assert_have_selector '#demo input', :name => 'markup_user[email]', :class => 'invalid'
|
||||
assert_have_selector '#demo input', :name => 'markup_user[email]', :class => 'string invalid'
|
||||
end
|
||||
|
||||
should "display correct form in slim" do
|
||||
|
@ -225,7 +225,7 @@ describe "FormBuilder" do
|
|||
assert_have_selector '#demo2 div.field-errors ul li', :content => "Fake must be valid"
|
||||
assert_have_selector '#demo2 div.field-errors ul li', :content => "Second must be present"
|
||||
assert_have_selector '#demo2 div.field-errors ul li', :content => "Third must be a number"
|
||||
assert_have_selector '#demo input', :name => 'markup_user[email]', :class => 'invalid'
|
||||
assert_have_selector '#demo input', :name => 'markup_user[email]', :class => 'string invalid'
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -325,6 +325,116 @@ describe "FormBuilder" do
|
|||
end
|
||||
end
|
||||
|
||||
context 'for #number_field method' do
|
||||
should "display correct number field html" do
|
||||
actual_html = standard_builder.number_field(:age, :class => 'numeric')
|
||||
assert_has_tag('input.numeric[type=number]', :id => 'user_age', :name => 'user[age]') { actual_html }
|
||||
end
|
||||
|
||||
should "display correct number field in haml" do
|
||||
visit '/haml/form_for'
|
||||
assert_have_selector '#demo input.numeric[type=number]', :id => 'markup_user_age'
|
||||
end
|
||||
|
||||
should "display correct number field in erb" do
|
||||
visit '/erb/form_for'
|
||||
assert_have_selector '#demo input.numeric[type=number]', :id => 'markup_user_age'
|
||||
end
|
||||
|
||||
should "display correct number field in slim" do
|
||||
visit '/slim/form_for'
|
||||
assert_have_selector '#demo input.numeric[type=number]', :id => 'markup_user_age'
|
||||
end
|
||||
end
|
||||
|
||||
context 'for #telephone_field method' do
|
||||
should "display correct telephone field html" do
|
||||
actual_html = standard_builder.telephone_field(:telephone, :class => 'numeric')
|
||||
assert_has_tag('input.numeric[type=tel]', :id => 'user_telephone', :name => 'user[telephone]') { actual_html }
|
||||
end
|
||||
|
||||
should "display correct telephone field in haml" do
|
||||
visit '/haml/form_for'
|
||||
assert_have_selector '#demo input.numeric[type=tel]', :id => 'markup_user_telephone'
|
||||
end
|
||||
|
||||
should "display correct telephone field in erb" do
|
||||
visit '/erb/form_for'
|
||||
assert_have_selector '#demo input.numeric[type=tel]', :id => 'markup_user_telephone'
|
||||
end
|
||||
|
||||
should "display correct telephone field in slim" do
|
||||
visit '/slim/form_for'
|
||||
assert_have_selector '#demo input.numeric[type=tel]', :id => 'markup_user_telephone'
|
||||
end
|
||||
end
|
||||
|
||||
context 'for #search_field method' do
|
||||
should "display correct search field html" do
|
||||
actual_html = standard_builder.search_field(:search, :class => 'string')
|
||||
assert_has_tag('input.string[type=search]', :id => 'user_search', :name => 'user[search]') { actual_html }
|
||||
end
|
||||
|
||||
should "display correct search field in haml" do
|
||||
visit '/haml/form_for'
|
||||
assert_have_selector '#demo input.string[type=search]', :id => 'markup_user_search'
|
||||
end
|
||||
|
||||
should "display correct search field in erb" do
|
||||
visit '/erb/form_for'
|
||||
assert_have_selector '#demo input.string[type=search]', :id => 'markup_user_search'
|
||||
end
|
||||
|
||||
should "display correct search field in slim" do
|
||||
visit '/slim/form_for'
|
||||
assert_have_selector '#demo input.string[type=search]', :id => 'markup_user_search'
|
||||
end
|
||||
end
|
||||
|
||||
context 'for #email_field method' do
|
||||
should "display correct email field html" do
|
||||
actual_html = standard_builder.email_field(:email, :class => 'string')
|
||||
assert_has_tag('input.string[type=email]', :id => 'user_email', :name => 'user[email]') { actual_html }
|
||||
end
|
||||
|
||||
should "display correct email field in haml" do
|
||||
visit '/haml/form_for'
|
||||
assert_have_selector '#demo input.string[type=email]', :id => 'markup_user_email'
|
||||
end
|
||||
|
||||
should "display correct email field in erb" do
|
||||
visit '/erb/form_for'
|
||||
assert_have_selector '#demo input.string[type=email]', :id => 'markup_user_email'
|
||||
end
|
||||
|
||||
should "display correct email field in slim" do
|
||||
visit '/slim/form_for'
|
||||
assert_have_selector '#demo input.string[type=email]', :id => 'markup_user_email'
|
||||
end
|
||||
end
|
||||
|
||||
context 'for #url_field method' do
|
||||
should "display correct url field html" do
|
||||
actual_html = standard_builder.url_field(:webpage, :class => 'string')
|
||||
assert_has_tag('input.string[type=url]', :id => 'user_webpage', :name => 'user[webpage]') { actual_html }
|
||||
end
|
||||
|
||||
should "display correct url field in haml" do
|
||||
visit '/haml/form_for'
|
||||
assert_have_selector '#demo input.string[type=url]', :id => 'markup_user_webpage'
|
||||
end
|
||||
|
||||
should "display correct url field in erb" do
|
||||
visit '/erb/form_for'
|
||||
assert_have_selector '#demo input.string[type=url]', :id => 'markup_user_webpage'
|
||||
end
|
||||
|
||||
should "display correct url field in slim" do
|
||||
visit '/slim/form_for'
|
||||
assert_have_selector '#demo input.string[type=url]', :id => 'markup_user_webpage'
|
||||
end
|
||||
end
|
||||
|
||||
context 'for #check_box method' do
|
||||
should "display correct checkbox html" do
|
||||
actual_html = standard_builder.check_box(:confirm_destroy, :class => 'large')
|
||||
|
@ -430,7 +540,7 @@ describe "FormBuilder" do
|
|||
context 'for #text_area method' do
|
||||
should "display correct text_area html" do
|
||||
actual_html = standard_builder.text_area(:about, :class => 'large')
|
||||
assert_has_tag('textarea.large', :id => 'user_about', :name => 'user[about]', :rows => '', :cols => '') { actual_html }
|
||||
assert_has_tag('textarea.large', :id => 'user_about', :name => 'user[about]') { actual_html }
|
||||
end
|
||||
|
||||
should "display correct text_area html and content" do
|
||||
|
@ -628,7 +738,7 @@ describe "FormBuilder" do
|
|||
|
||||
should "display correct image submit button html" do
|
||||
actual_html = standard_builder.image_submit('/system/ok.png', :class => 'large')
|
||||
assert_has_tag('input.large[type=image]', :src => "/system/ok.png?#{@stamp}") { actual_html }
|
||||
assert_has_tag('input.large[type=image]', :src => "/system/ok.png") { actual_html }
|
||||
end
|
||||
|
||||
should "display correct image submit button in haml" do
|
||||
|
|
|
@ -28,7 +28,7 @@ describe "FormHelpers" do
|
|||
|
||||
should "display correct form with remote and method is put" do
|
||||
actual_html = form_tag('/update', :"accept-charset" => "UTF-8", :method => 'put', :remote => true) { "Demo" }
|
||||
assert_has_tag(:form, "data-remote" => 'true', :"accept-charset" => "UTF-8", :"data-method" => 'put') { actual_html }
|
||||
assert_has_tag(:form, "data-remote" => 'true', :"accept-charset" => "UTF-8") { actual_html }
|
||||
assert_has_tag('form input', :type => 'hidden', :name => "_method", :value => 'put') { actual_html }
|
||||
end
|
||||
|
||||
|
@ -193,14 +193,14 @@ describe "FormHelpers" do
|
|||
|
||||
should "display label tag in erb for simple form" do
|
||||
visit '/erb/form_tag'
|
||||
assert_have_selector 'form.simple-form label', :count => 4
|
||||
assert_have_selector 'form.simple-form label', :count => 9
|
||||
assert_have_selector 'form.simple-form label', :content => "Username", :for => 'username'
|
||||
assert_have_selector 'form.simple-form label', :content => "Password", :for => 'password'
|
||||
assert_have_selector 'form.simple-form label', :content => "Gender", :for => 'gender'
|
||||
end
|
||||
should "display label tag in erb for advanced form" do
|
||||
visit '/erb/form_tag'
|
||||
assert_have_selector 'form.advanced-form label', :count => 6
|
||||
assert_have_selector 'form.advanced-form label', :count => 11
|
||||
assert_have_selector 'form.advanced-form label.first', :content => "Nickname", :for => 'username'
|
||||
assert_have_selector 'form.advanced-form label.first', :content => "Password", :for => 'password'
|
||||
assert_have_selector 'form.advanced-form label.about', :content => "About Me", :for => 'about'
|
||||
|
@ -210,7 +210,7 @@ describe "FormHelpers" do
|
|||
|
||||
should "display label tag in haml for simple form" do
|
||||
visit '/haml/form_tag'
|
||||
assert_have_selector 'form.simple-form label', :count => 4
|
||||
assert_have_selector 'form.simple-form label', :count => 9
|
||||
assert_have_selector 'form.simple-form label', :content => "Username", :for => 'username'
|
||||
assert_have_selector 'form.simple-form label', :content => "Password", :for => 'password'
|
||||
assert_have_selector 'form.simple-form label', :content => "Gender", :for => 'gender'
|
||||
|
@ -218,7 +218,7 @@ describe "FormHelpers" do
|
|||
|
||||
should "display label tag in haml for advanced form" do
|
||||
visit '/haml/form_tag'
|
||||
assert_have_selector 'form.advanced-form label', :count => 6
|
||||
assert_have_selector 'form.advanced-form label', :count => 11
|
||||
assert_have_selector 'form.advanced-form label.first', :content => "Nickname", :for => 'username'
|
||||
assert_have_selector 'form.advanced-form label.first', :content => "Password", :for => 'password'
|
||||
assert_have_selector 'form.advanced-form label.about', :content => "About Me", :for => 'about'
|
||||
|
@ -228,7 +228,7 @@ describe "FormHelpers" do
|
|||
|
||||
should "display label tag in slim for simple form" do
|
||||
visit '/slim/form_tag'
|
||||
assert_have_selector 'form.simple-form label', :count => 4
|
||||
assert_have_selector 'form.simple-form label', :count => 9
|
||||
assert_have_selector 'form.simple-form label', :content => "Username", :for => 'username'
|
||||
assert_have_selector 'form.simple-form label', :content => "Password", :for => 'password'
|
||||
assert_have_selector 'form.simple-form label', :content => "Gender", :for => 'gender'
|
||||
|
@ -236,7 +236,7 @@ describe "FormHelpers" do
|
|||
|
||||
should "display label tag in slim for advanced form" do
|
||||
visit '/slim/form_tag'
|
||||
assert_have_selector 'form.advanced-form label', :count => 6
|
||||
assert_have_selector 'form.advanced-form label', :count => 11
|
||||
assert_have_selector 'form.advanced-form label.first', :content => "Nickname", :for => 'username'
|
||||
assert_have_selector 'form.advanced-form label.first', :content => "Password", :for => 'password'
|
||||
assert_have_selector 'form.advanced-form label.about', :content => "About Me", :for => 'about'
|
||||
|
@ -295,10 +295,135 @@ describe "FormHelpers" do
|
|||
end
|
||||
end
|
||||
|
||||
context 'for #number_field_tag method' do
|
||||
should "display number field in ruby" do
|
||||
actual_html = number_field_tag(:age, :class => 'numeric')
|
||||
assert_has_tag(:input, :type => 'number', :class => 'numeric', :name => 'age') { actual_html }
|
||||
end
|
||||
|
||||
should "display number field in erb" do
|
||||
visit '/erb/form_tag'
|
||||
assert_have_selector 'form.simple-form input[type=number]', :count => 1, :name => 'age'
|
||||
assert_have_selector 'form.advanced-form fieldset input[type=number]', :count => 1, :name => 'age', :class => 'numeric'
|
||||
end
|
||||
|
||||
should "display number field in haml" do
|
||||
visit '/haml/form_tag'
|
||||
assert_have_selector 'form.simple-form input[type=number]', :count => 1, :name => 'age'
|
||||
assert_have_selector 'form.advanced-form fieldset input[type=number]', :count => 1, :name => 'age', :class => 'numeric'
|
||||
end
|
||||
|
||||
should "display number field in slim" do
|
||||
visit '/slim/form_tag'
|
||||
assert_have_selector 'form.simple-form input[type=number]', :count => 1, :name => 'age'
|
||||
assert_have_selector 'form.advanced-form fieldset input[type=number]', :count => 1, :name => 'age', :class => 'numeric'
|
||||
end
|
||||
end
|
||||
|
||||
context 'for #telephone_field_tag method' do
|
||||
should "display number field in ruby" do
|
||||
actual_html = telephone_field_tag(:telephone, :class => 'numeric')
|
||||
assert_has_tag(:input, :type => 'tel', :class => 'numeric', :name => 'telephone') { actual_html }
|
||||
end
|
||||
|
||||
should "display telephone field in erb" do
|
||||
visit '/erb/form_tag'
|
||||
assert_have_selector 'form.simple-form input[type=tel]', :count => 1, :name => 'telephone'
|
||||
assert_have_selector 'form.advanced-form fieldset input[type=tel]', :count => 1, :name => 'telephone', :class => 'numeric'
|
||||
end
|
||||
|
||||
should "display telephone field in haml" do
|
||||
visit '/haml/form_tag'
|
||||
assert_have_selector 'form.simple-form input[type=tel]', :count => 1, :name => 'telephone'
|
||||
assert_have_selector 'form.advanced-form fieldset input[type=tel]', :count => 1, :name => 'telephone', :class => 'numeric'
|
||||
end
|
||||
|
||||
should "display telephone field in slim" do
|
||||
visit '/slim/form_tag'
|
||||
assert_have_selector 'form.simple-form input[type=tel]', :count => 1, :name => 'telephone'
|
||||
assert_have_selector 'form.advanced-form fieldset input[type=tel]', :count => 1, :name => 'telephone', :class => 'numeric'
|
||||
end
|
||||
end
|
||||
|
||||
context 'for #search_field_tag method' do
|
||||
should "display search field in ruby" do
|
||||
actual_html = search_field_tag(:search, :class => 'string')
|
||||
assert_has_tag(:input, :type => 'search', :class => 'string', :name => 'search') { actual_html }
|
||||
end
|
||||
|
||||
should "display search field in erb" do
|
||||
visit '/erb/form_tag'
|
||||
assert_have_selector 'form.simple-form input[type=search]', :count => 1, :name => 'search'
|
||||
assert_have_selector 'form.advanced-form fieldset input[type=search]', :count => 1, :name => 'search', :class => 'string'
|
||||
end
|
||||
|
||||
should "display search field in haml" do
|
||||
visit '/haml/form_tag'
|
||||
assert_have_selector 'form.simple-form input[type=search]', :count => 1, :name => 'search'
|
||||
assert_have_selector 'form.advanced-form fieldset input[type=search]', :count => 1, :name => 'search', :class => 'string'
|
||||
end
|
||||
|
||||
should "display search field in slim" do
|
||||
visit '/slim/form_tag'
|
||||
assert_have_selector 'form.simple-form input[type=search]', :count => 1, :name => 'search'
|
||||
assert_have_selector 'form.advanced-form fieldset input[type=search]', :count => 1, :name => 'search', :class => 'string'
|
||||
end
|
||||
end
|
||||
|
||||
context 'for #email_field_tag method' do
|
||||
should "display email field in ruby" do
|
||||
actual_html = email_field_tag(:email, :class => 'string')
|
||||
assert_has_tag(:input, :type => 'email', :class => 'string', :name => 'email') { actual_html }
|
||||
end
|
||||
|
||||
should "display email field in erb" do
|
||||
visit '/erb/form_tag'
|
||||
assert_have_selector 'form.simple-form input[type=email]', :count => 1, :name => 'email'
|
||||
assert_have_selector 'form.advanced-form fieldset input[type=email]', :count => 1, :name => 'email', :class => 'string'
|
||||
end
|
||||
|
||||
should "display email field in haml" do
|
||||
visit '/haml/form_tag'
|
||||
assert_have_selector 'form.simple-form input[type=email]', :count => 1, :name => 'email'
|
||||
assert_have_selector 'form.advanced-form fieldset input[type=email]', :count => 1, :name => 'email', :class => 'string'
|
||||
end
|
||||
|
||||
should "display email field in slim" do
|
||||
visit '/slim/form_tag'
|
||||
assert_have_selector 'form.simple-form input[type=email]', :count => 1, :name => 'email'
|
||||
assert_have_selector 'form.advanced-form fieldset input[type=email]', :count => 1, :name => 'email', :class => 'string'
|
||||
end
|
||||
end
|
||||
|
||||
context 'for #url_field_tag method' do
|
||||
should "display url field in ruby" do
|
||||
actual_html = url_field_tag(:webpage, :class => 'string')
|
||||
assert_has_tag(:input, :type => 'url', :class => 'string', :name => 'webpage') { actual_html }
|
||||
end
|
||||
|
||||
should "display url field in erb" do
|
||||
visit '/erb/form_tag'
|
||||
assert_have_selector 'form.simple-form input[type=url]', :count => 1, :name => 'webpage'
|
||||
assert_have_selector 'form.advanced-form fieldset input[type=url]', :count => 1, :name => 'webpage', :class => 'string'
|
||||
end
|
||||
|
||||
should "display url field in haml" do
|
||||
visit '/haml/form_tag'
|
||||
assert_have_selector 'form.simple-form input[type=url]', :count => 1, :name => 'webpage'
|
||||
assert_have_selector 'form.advanced-form fieldset input[type=url]', :count => 1, :name => 'webpage', :class => 'string'
|
||||
end
|
||||
|
||||
should "display url field in slim" do
|
||||
visit '/slim/form_tag'
|
||||
assert_have_selector 'form.simple-form input[type=url]', :count => 1, :name => 'webpage'
|
||||
assert_have_selector 'form.advanced-form fieldset input[type=url]', :count => 1, :name => 'webpage', :class => 'string'
|
||||
end
|
||||
end
|
||||
|
||||
context 'for #text_area_tag method' do
|
||||
should "display text area in ruby" do
|
||||
actual_html = text_area_tag(:about, :class => 'long')
|
||||
assert_has_tag(:textarea, :class => "long", :name => 'about', :rows => '', :cols => '') { actual_html }
|
||||
assert_has_tag(:textarea, :class => "long", :name => 'about') { actual_html }
|
||||
end
|
||||
|
||||
should "display text area in ruby with specified content" do
|
||||
|
@ -624,7 +749,7 @@ describe "FormHelpers" do
|
|||
|
||||
should "display image submit tag in ruby with absolute path" do
|
||||
actual_html = image_submit_tag('/system/ok.png', :class => 'success')
|
||||
assert_has_tag(:input, :type => 'image', :class => "success", :src => "/system/ok.png?#{@stamp}") { actual_html }
|
||||
assert_has_tag(:input, :type => 'image', :class => "success", :src => "/system/ok.png") { actual_html }
|
||||
end
|
||||
|
||||
should "display image submit tag in erb" do
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
require File.expand_path(File.dirname(__FILE__) + '/helper')
|
||||
require File.expand_path(File.dirname(__FILE__) + '/fixtures/markup_app/app')
|
||||
|
||||
describe "NumberHelpers" do
|
||||
include Padrino::Helpers::NumberHelpers
|
||||
|
||||
|
|
|
@ -21,17 +21,18 @@ describe "TagHelpers" do
|
|||
assert_has_tag('option', :selected => 'selected') { actual_html }
|
||||
end
|
||||
|
||||
should "support tags with content no attributes" do
|
||||
assert_has_tag(:p, :content => "Demo String") { tag(:p, :content => "Demo String") }
|
||||
should "support data attributes" do
|
||||
actual_html = tag(:a, :data => { :remote => true, :method => 'post'})
|
||||
assert_has_tag(:a, 'data-remote' => 'true', 'data-method' => 'post') { actual_html }
|
||||
end
|
||||
|
||||
should "support tags with content and attributes" do
|
||||
actual_html = tag(:p, :content => "Demo", :class => 'large', :id => 'intro')
|
||||
assert_has_tag('p#intro.large', :content => "Demo") { actual_html }
|
||||
should "support nested attributes" do
|
||||
actual_html = tag(:div, :data => {:dojo => {:type => 'dijit.form.TextBox', :props => 'readOnly: true'}})
|
||||
assert_has_tag(:div, 'data-dojo-type' => 'dijit.form.TextBox', 'data-dojo-props' => 'readOnly: true') { actual_html }
|
||||
end
|
||||
|
||||
should "support open tags" do
|
||||
actual_html = tag(:p, :class => 'demo', :open => true)
|
||||
actual_html = tag(:p, { :class => 'demo' }, true)
|
||||
assert_equal "<p class=\"demo\">", actual_html
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue