actionpack 1.7.0 → 1.8.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of actionpack might be problematic. Click here for more details.
- data/CHANGELOG +109 -0
- data/README +2 -2
- data/RUNNING_UNIT_TESTS +1 -1
- data/install.rb +8 -77
- data/lib/action_controller/assertions.rb +203 -0
- data/lib/action_controller/base.rb +15 -7
- data/lib/action_controller/benchmarking.rb +10 -4
- data/lib/action_controller/caching.rb +28 -17
- data/lib/action_controller/cgi_ext/raw_post_data_fix.rb +5 -9
- data/lib/action_controller/cgi_process.rb +5 -1
- data/lib/action_controller/cookies.rb +3 -2
- data/lib/action_controller/deprecated_assertions.rb +204 -0
- data/lib/action_controller/flash.rb +30 -36
- data/lib/action_controller/pagination.rb +4 -4
- data/lib/action_controller/request.rb +18 -2
- data/lib/action_controller/routing.rb +6 -2
- data/lib/action_controller/scaffolding.rb +1 -1
- data/lib/action_controller/templates/rescues/diagnostics.rhtml +1 -1
- data/lib/action_controller/templates/rescues/routing_error.rhtml +4 -2
- data/lib/action_controller/templates/rescues/template_error.rhtml +5 -4
- data/lib/action_controller/templates/scaffolds/list.rhtml +3 -0
- data/lib/action_controller/test_process.rb +60 -17
- data/lib/action_controller/url_rewriter.rb +3 -3
- data/lib/action_controller/vendor/html-scanner/html/document.rb +63 -0
- data/lib/action_controller/vendor/html-scanner/html/node.rb +431 -0
- data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +95 -0
- data/lib/action_controller/vendor/html-scanner/html/version.rb +11 -0
- data/lib/action_controller/verification.rb +13 -4
- data/lib/action_view/base.rb +3 -2
- data/lib/action_view/helpers/active_record_helper.rb +1 -1
- data/lib/action_view/helpers/asset_tag_helper.rb +31 -9
- data/lib/action_view/helpers/date_helper.rb +25 -22
- data/lib/action_view/helpers/form_helper.rb +6 -5
- data/lib/action_view/helpers/form_options_helper.rb +4 -4
- data/lib/action_view/helpers/javascript_helper.rb +28 -6
- data/lib/action_view/helpers/javascripts/prototype.js +340 -30
- data/lib/action_view/helpers/number_helper.rb +110 -0
- data/lib/action_view/helpers/pagination_helper.rb +1 -1
- data/lib/action_view/helpers/text_helper.rb +8 -21
- data/lib/action_view/helpers/url_helper.rb +21 -4
- data/lib/action_view/partials.rb +39 -9
- data/rakefile +29 -5
- data/test/abstract_unit.rb +1 -0
- data/test/controller/action_pack_assertions_test.rb +1 -2
- data/test/controller/active_record_assertions_test.rb +1 -1
- data/test/controller/cgi_test.rb +0 -1
- data/test/controller/cookie_test.rb +11 -1
- data/test/controller/helper_test.rb +0 -12
- data/test/controller/render_test.rb +9 -0
- data/test/controller/request_test.rb +44 -1
- data/test/controller/routing_tests.rb +4 -1
- data/test/controller/test_test.rb +62 -0
- data/test/controller/verification_test.rb +21 -0
- data/test/fixtures/test/_partial_only.rhtml +1 -0
- data/test/template/active_record_helper_test.rb +2 -2
- data/test/template/asset_tag_helper_test.rb +52 -4
- data/test/template/date_helper_test.rb +163 -32
- data/test/template/form_helper_test.rb +9 -6
- data/test/template/form_options_helper_test.rb +18 -15
- data/test/template/number_helper_test.rb +51 -0
- data/test/template/text_helper_test.rb +17 -20
- data/test/template/url_helper_test.rb +7 -1
- metadata +15 -6
- data/lib/action_controller/assertions/action_pack_assertions.rb +0 -260
- data/lib/action_controller/assertions/active_record_assertions.rb +0 -65
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'strscan'
|
2
|
+
|
3
|
+
module HTML#:nodoc:
|
4
|
+
|
5
|
+
# A simple HTML tokenizer. It simply breaks a stream of text into tokens, where each
|
6
|
+
# token is a string. Each string represents either "text", or an HTML element.
|
7
|
+
#
|
8
|
+
# This currently assumes valid XHTML, which means no free < or > characters.
|
9
|
+
#
|
10
|
+
# Usage:
|
11
|
+
#
|
12
|
+
# tokenizer = HTML::Tokenizer.new(text)
|
13
|
+
# while token = tokenizer.next
|
14
|
+
# p token
|
15
|
+
# end
|
16
|
+
class Tokenizer#:nodoc:
|
17
|
+
|
18
|
+
# The current (byte) position in the text
|
19
|
+
attr_reader :position
|
20
|
+
|
21
|
+
# The current line number
|
22
|
+
attr_reader :line
|
23
|
+
|
24
|
+
# Create a new Tokenizer for the given text.
|
25
|
+
def initialize(text)
|
26
|
+
@scanner = StringScanner.new(text)
|
27
|
+
@position = 0
|
28
|
+
@line = 0
|
29
|
+
@current_line = 1
|
30
|
+
end
|
31
|
+
|
32
|
+
# Return the next token in the sequence, or +nil+ if there are no more tokens in
|
33
|
+
# the stream.
|
34
|
+
def next
|
35
|
+
return nil if @scanner.eos?
|
36
|
+
@position = @scanner.pos
|
37
|
+
@line = @current_line
|
38
|
+
if @scanner.check(/<\S/)
|
39
|
+
update_current_line(scan_tag)
|
40
|
+
else
|
41
|
+
update_current_line(scan_text)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
# Treat the text at the current position as a tag, and scan it. Supports
|
48
|
+
# comments, doctype tags, and regular tags, and ignores less-than and
|
49
|
+
# greater-than characters within quoted strings.
|
50
|
+
def scan_tag
|
51
|
+
tag = @scanner.getch
|
52
|
+
if @scanner.scan(/!--/) # comment
|
53
|
+
tag << @scanner.matched
|
54
|
+
tag << @scanner.scan_until(/--\s*>/)
|
55
|
+
elsif @scanner.scan(/!/) # doctype
|
56
|
+
tag << @scanner.matched
|
57
|
+
tag << consume_quoted_regions
|
58
|
+
else
|
59
|
+
tag << consume_quoted_regions
|
60
|
+
end
|
61
|
+
tag
|
62
|
+
end
|
63
|
+
|
64
|
+
# Scan all text up to the next < character and return it.
|
65
|
+
def scan_text
|
66
|
+
@scanner.scan(/[^<]*/)
|
67
|
+
end
|
68
|
+
|
69
|
+
# Counts the number of newlines in the text and updates the current line
|
70
|
+
# accordingly.
|
71
|
+
def update_current_line(text)
|
72
|
+
@current_line += text.scan(/\r\n|\r|\n/).length
|
73
|
+
text
|
74
|
+
end
|
75
|
+
|
76
|
+
# Skips over quoted strings, so that less-than and greater-than characters
|
77
|
+
# within the strings are ignored.
|
78
|
+
def consume_quoted_regions
|
79
|
+
text = ""
|
80
|
+
loop do
|
81
|
+
match = @scanner.scan_until(/['">]/) or break
|
82
|
+
text << match
|
83
|
+
break if (delim = @scanner.matched) == ">"
|
84
|
+
# consume the conqued region
|
85
|
+
while match = @scanner.scan_until(/[\\#{delim}]/)
|
86
|
+
text << match
|
87
|
+
break if @scanner.matched == delim
|
88
|
+
text << @scanner.getch # skip the escaped character
|
89
|
+
end
|
90
|
+
end
|
91
|
+
text
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
@@ -44,14 +44,18 @@ module ActionController #:nodoc:
|
|
44
44
|
# be in the @session in order for the action(s) to be safely called.
|
45
45
|
# * <tt>:flash</tt>: a single key or an array of keys that must
|
46
46
|
# be in the flash in order for the action(s) to be safely called.
|
47
|
+
# * <tt>:method</tt>: a single key or an array of keys--any one of which
|
48
|
+
# must match the current request method in order for the action(s) to
|
49
|
+
# be safely called. (The key should be a symbol: <tt>:get</tt> or
|
50
|
+
# <tt>:post</tt>, for example.)
|
47
51
|
# * <tt>:add_flash</tt>: a hash of name/value pairs that should be merged
|
48
52
|
# into the session's flash if the prerequisites cannot be satisfied.
|
49
53
|
# * <tt>:redirect_to</tt>: the redirection parameters to be used when
|
50
54
|
# redirecting if the prerequisites cannot be satisfied.
|
51
|
-
# * <tt>:only</tt>: only apply this verification to the actions specified
|
52
|
-
# the associated array (may also be a single value).
|
53
|
-
# * <tt>:except</tt>: do not apply this verification to the actions
|
54
|
-
# the associated array (may also be a single value).
|
55
|
+
# * <tt>:only</tt>: only apply this verification to the actions specified
|
56
|
+
# in the associated array (may also be a single value).
|
57
|
+
# * <tt>:except</tt>: do not apply this verification to the actions
|
58
|
+
# specified in the associated array (may also be a single value).
|
55
59
|
def verify(options={})
|
56
60
|
filter_opts = { :only => options[:only], :except => options[:except] }
|
57
61
|
before_filter(filter_opts) do |c|
|
@@ -65,6 +69,11 @@ module ActionController #:nodoc:
|
|
65
69
|
[*options[:params] ].find { |v| @params[v].nil? } ||
|
66
70
|
[*options[:session]].find { |v| @session[v].nil? } ||
|
67
71
|
[*options[:flash] ].find { |v| flash[v].nil? }
|
72
|
+
|
73
|
+
if !prereqs_invalid && options[:method]
|
74
|
+
prereqs_invalid ||=
|
75
|
+
[*options[:method]].all? { |v| @request.method != v.to_sym }
|
76
|
+
end
|
68
77
|
|
69
78
|
if prereqs_invalid
|
70
79
|
flash.update(options[:add_flash]) if options[:add_flash]
|
data/lib/action_view/base.rb
CHANGED
@@ -119,7 +119,7 @@ module ActionView #:nodoc:
|
|
119
119
|
class Base
|
120
120
|
include ERB::Util
|
121
121
|
|
122
|
-
attr_reader
|
122
|
+
attr_reader :first_render
|
123
123
|
attr_accessor :base_path, :assigns, :template_extension
|
124
124
|
attr_accessor :controller
|
125
125
|
|
@@ -157,7 +157,7 @@ module ActionView #:nodoc:
|
|
157
157
|
end
|
158
158
|
|
159
159
|
def initialize(base_path = nil, assigns_for_first_render = {}, controller = nil)#:nodoc:
|
160
|
-
@base_path, @assigns = base_path, assigns_for_first_render
|
160
|
+
@base_path, @assigns = base_path, assigns_for_first_render.with_indifferent_access
|
161
161
|
@controller = controller
|
162
162
|
end
|
163
163
|
|
@@ -264,6 +264,7 @@ module ActionView #:nodoc:
|
|
264
264
|
def evaluate_locals(local_assigns = {})
|
265
265
|
b = binding
|
266
266
|
|
267
|
+
local_assigns.stringify_keys!
|
267
268
|
local_assigns.each { |key, value| eval "#{key} = local_assigns[\"#{key}\"]", b }
|
268
269
|
@assigns.each { |key, value| instance_variable_set "@#{key}", value }
|
269
270
|
xml = Builder::XmlMarkup.new(:indent => 2)
|
@@ -101,7 +101,7 @@ module ActionView
|
|
101
101
|
content_tag("div",
|
102
102
|
content_tag(
|
103
103
|
options[:header_tag] || "h2",
|
104
|
-
"#{pluralize(object.errors.count, "error")} prohibited this #{object_name.gsub("_", " ")} from being saved"
|
104
|
+
"#{pluralize(object.errors.count, "error")} prohibited this #{object_name.to_s.gsub("_", " ")} from being saved"
|
105
105
|
) +
|
106
106
|
content_tag("p", "There were problems with the following fields:") +
|
107
107
|
content_tag("ul", object.errors.full_messages.collect { |msg| content_tag("li", msg) }),
|
@@ -23,21 +23,35 @@ module ActionView
|
|
23
23
|
)
|
24
24
|
end
|
25
25
|
|
26
|
+
# Returns path to a javascript asset. Example:
|
27
|
+
#
|
28
|
+
# javascript_path "xmlhr" # => /javascripts/xmlhr.js
|
29
|
+
def javascript_path(source)
|
30
|
+
compute_public_path(source, 'javascripts', 'js')
|
31
|
+
end
|
32
|
+
|
26
33
|
# Returns a script include tag per source given as argument. Examples:
|
27
34
|
#
|
28
35
|
# javascript_include_tag "xmlhr" # =>
|
29
|
-
# <script
|
36
|
+
# <script type="text/javascript" src="/javascripts/xmlhr.js"></script>
|
30
37
|
#
|
31
38
|
# javascript_include_tag "common.javascript", "/elsewhere/cools" # =>
|
32
|
-
# <script
|
33
|
-
# <script
|
39
|
+
# <script type="text/javascript" src="/javascripts/common.javascript"></script>
|
40
|
+
# <script type="text/javascript" src="/elsewhere/cools.js"></script>
|
34
41
|
def javascript_include_tag(*sources)
|
35
42
|
sources.collect { |source|
|
36
|
-
source =
|
37
|
-
content_tag("script", "", "
|
43
|
+
source = javascript_path(source)
|
44
|
+
content_tag("script", "", "type" => "text/javascript", "src" => source)
|
38
45
|
}.join("\n")
|
39
46
|
end
|
40
47
|
|
48
|
+
# Returns path to a stylesheet asset. Example:
|
49
|
+
#
|
50
|
+
# stylesheet_path "style" # => /stylesheets/style.css
|
51
|
+
def stylesheet_path(source)
|
52
|
+
compute_public_path(source, 'stylesheets', 'css')
|
53
|
+
end
|
54
|
+
|
41
55
|
# Returns a css link tag per source given as argument. Examples:
|
42
56
|
#
|
43
57
|
# stylesheet_link_tag "style" # =>
|
@@ -48,11 +62,21 @@ module ActionView
|
|
48
62
|
# <link href="/css/stylish.css" media="screen" rel="Stylesheet" type="text/css" />
|
49
63
|
def stylesheet_link_tag(*sources)
|
50
64
|
sources.collect { |source|
|
51
|
-
source =
|
65
|
+
source = stylesheet_path(source)
|
52
66
|
tag("link", "rel" => "Stylesheet", "type" => "text/css", "media" => "screen", "href" => source)
|
53
67
|
}.join("\n")
|
54
68
|
end
|
55
69
|
|
70
|
+
# Returns path to an image asset. Example:
|
71
|
+
#
|
72
|
+
# The +src+ can be supplied as a...
|
73
|
+
# * full path, like "/my_images/image.gif"
|
74
|
+
# * file name, like "rss.gif", that gets expanded to "/images/rss.gif"
|
75
|
+
# * file name without extension, like "logo", that gets expanded to "/images/logo.png"
|
76
|
+
def image_path(source)
|
77
|
+
compute_public_path(source, 'images', 'png')
|
78
|
+
end
|
79
|
+
|
56
80
|
# Returns an image tag converting the +options+ instead html options on the tag, but with these special cases:
|
57
81
|
#
|
58
82
|
# * <tt>:alt</tt> - If no alt text is given, the file name part of the +src+ is used (capitalized and without the extension)
|
@@ -65,7 +89,7 @@ module ActionView
|
|
65
89
|
def image_tag(source, options = {})
|
66
90
|
options.symbolize_keys
|
67
91
|
|
68
|
-
options[:src] =
|
92
|
+
options[:src] = image_path(source)
|
69
93
|
options[:alt] ||= source.split("/").last.split(".").first.capitalize
|
70
94
|
|
71
95
|
if options[:size]
|
@@ -77,14 +101,12 @@ module ActionView
|
|
77
101
|
end
|
78
102
|
|
79
103
|
private
|
80
|
-
|
81
104
|
def compute_public_path(source, dir, ext)
|
82
105
|
source = "/#{dir}/#{source}" unless source.include?("/")
|
83
106
|
source = "#{source}.#{ext}" unless source.include?(".")
|
84
107
|
source = "#{@request.relative_url_root}#{source}"
|
85
108
|
source
|
86
109
|
end
|
87
|
-
|
88
110
|
end
|
89
111
|
end
|
90
112
|
end
|
@@ -41,9 +41,11 @@ module ActionView
|
|
41
41
|
end
|
42
42
|
|
43
43
|
# Like distance_of_time_in_words, but where <tt>to_time</tt> is fixed to <tt>Time.now</tt>.
|
44
|
-
def
|
44
|
+
def time_ago_in_words(from_time, include_seconds = false)
|
45
45
|
distance_of_time_in_words(from_time, Time.now, include_seconds)
|
46
46
|
end
|
47
|
+
|
48
|
+
alias_method :distance_of_time_in_words_to_now, :time_ago_in_words
|
47
49
|
|
48
50
|
# Returns a set of select tags (one for year, month, and day) pre-selected for accessing a specified date-based attribute (identified by
|
49
51
|
# +method+) on an object assigned to the template (identified by +object+). It's possible to tailor the selects through the +options+ hash,
|
@@ -102,9 +104,9 @@ module ActionView
|
|
102
104
|
second_options = []
|
103
105
|
|
104
106
|
0.upto(59) do |second|
|
105
|
-
second_options << ((datetime.kind_of?(Fixnum) ? datetime : datetime.sec) == second ?
|
106
|
-
"<option selected=\"selected\">#{leading_zero_on_single_digits(second)}</option>\n" :
|
107
|
-
"<option>#{leading_zero_on_single_digits(second)}</option>\n"
|
107
|
+
second_options << ((datetime && (datetime.kind_of?(Fixnum) ? datetime : datetime.sec) == second) ?
|
108
|
+
"<option value=\"#{leading_zero_on_single_digits(second)}\" selected=\"selected\">#{leading_zero_on_single_digits(second)}</option>\n" :
|
109
|
+
"<option value=\"#{leading_zero_on_single_digits(second)}\">#{leading_zero_on_single_digits(second)}</option>\n"
|
108
110
|
)
|
109
111
|
end
|
110
112
|
|
@@ -112,14 +114,15 @@ module ActionView
|
|
112
114
|
end
|
113
115
|
|
114
116
|
# Returns a select tag with options for each of the minutes 0 through 59 with the current minute selected.
|
117
|
+
# Also can return a select tag with options by <tt>minute_step</tt> from 0 through 59 with the 00 minute selected
|
115
118
|
# The <tt>minute</tt> can also be substituted for a minute number.
|
116
119
|
def select_minute(datetime, options = {})
|
117
120
|
minute_options = []
|
118
121
|
|
119
|
-
0.
|
120
|
-
minute_options << ((datetime.kind_of?(Fixnum) ? datetime : datetime.min) == minute ?
|
121
|
-
"<option selected=\"selected\">#{leading_zero_on_single_digits(minute)}</option>\n" :
|
122
|
-
"<option>#{leading_zero_on_single_digits(minute)}</option>\n"
|
122
|
+
0.step(59, options[:minute_step] || 1) do |minute|
|
123
|
+
minute_options << ((datetime && (datetime.kind_of?(Fixnum) ? datetime : datetime.min) == minute) ?
|
124
|
+
"<option value=\"#{leading_zero_on_single_digits(minute)}\" selected=\"selected\">#{leading_zero_on_single_digits(minute)}</option>\n" :
|
125
|
+
"<option value=\"#{leading_zero_on_single_digits(minute)}\">#{leading_zero_on_single_digits(minute)}</option>\n"
|
123
126
|
)
|
124
127
|
end
|
125
128
|
|
@@ -132,9 +135,9 @@ module ActionView
|
|
132
135
|
hour_options = []
|
133
136
|
|
134
137
|
0.upto(23) do |hour|
|
135
|
-
hour_options << ((datetime.kind_of?(Fixnum) ? datetime : datetime.hour) == hour ?
|
136
|
-
"<option selected=\"selected\">#{leading_zero_on_single_digits(hour)}</option>\n" :
|
137
|
-
"<option>#{leading_zero_on_single_digits(hour)}</option>\n"
|
138
|
+
hour_options << ((datetime && (datetime.kind_of?(Fixnum) ? datetime : datetime.hour) == hour) ?
|
139
|
+
"<option value=\"#{leading_zero_on_single_digits(hour)}\" selected=\"selected\">#{leading_zero_on_single_digits(hour)}</option>\n" :
|
140
|
+
"<option value=\"#{leading_zero_on_single_digits(hour)}\">#{leading_zero_on_single_digits(hour)}</option>\n"
|
138
141
|
)
|
139
142
|
end
|
140
143
|
|
@@ -147,9 +150,9 @@ module ActionView
|
|
147
150
|
day_options = []
|
148
151
|
|
149
152
|
1.upto(31) do |day|
|
150
|
-
day_options << ((date.kind_of?(Fixnum) ? date : date.day) == day ?
|
151
|
-
"<option selected=\"selected\">#{day}</option>\n" :
|
152
|
-
"<option>#{day}</option>\n"
|
153
|
+
day_options << ((date && (date.kind_of?(Fixnum) ? date : date.day) == day) ?
|
154
|
+
"<option value=\"#{day}\" selected=\"selected\">#{day}</option>\n" :
|
155
|
+
"<option value=\"#{day}\">#{day}</option>\n"
|
153
156
|
)
|
154
157
|
end
|
155
158
|
|
@@ -177,7 +180,7 @@ module ActionView
|
|
177
180
|
Date::MONTHNAMES[month_number]
|
178
181
|
end
|
179
182
|
|
180
|
-
month_options << ((date.kind_of?(Fixnum) ? date : date.month) == month_number ?
|
183
|
+
month_options << ((date && (date.kind_of?(Fixnum) ? date : date.month) == month_number) ?
|
181
184
|
%(<option value="#{month_number}" selected="selected">#{month_name}</option>\n) :
|
182
185
|
%(<option value="#{month_number}">#{month_name}</option>\n)
|
183
186
|
)
|
@@ -193,13 +196,13 @@ module ActionView
|
|
193
196
|
# select_year(Date.today, :start_year => 1992, :end_year => 2007)
|
194
197
|
def select_year(date, options = {})
|
195
198
|
year_options = []
|
196
|
-
y = date.kind_of?(Fixnum) ? (y = (date == 0) ? Date.today.year : date) : date.year
|
199
|
+
y = date ? (date.kind_of?(Fixnum) ? (y = (date == 0) ? Date.today.year : date) : date.year) : Date.today.year
|
197
200
|
default_start_year, default_end_year = y-5, y+5
|
198
201
|
|
199
202
|
(options[:start_year] || default_start_year).upto(options[:end_year] || default_end_year) do |year|
|
200
|
-
year_options << ((date.kind_of?(Fixnum) ? date : date.year) == year ?
|
201
|
-
"<option selected=\"selected\">#{year}</option>\n" :
|
202
|
-
"<option>#{year}</option>\n"
|
203
|
+
year_options << ((date && (date.kind_of?(Fixnum) ? date : date.year) == year) ?
|
204
|
+
"<option value=\"#{year}\" selected=\"selected\">#{year}</option>\n" :
|
205
|
+
"<option value=\"#{year}\">#{year}</option>\n"
|
203
206
|
)
|
204
207
|
end
|
205
208
|
|
@@ -211,7 +214,7 @@ module ActionView
|
|
211
214
|
select_html = %(<select name="#{prefix || DEFAULT_PREFIX})
|
212
215
|
select_html << "[#{type}]" unless discard_type
|
213
216
|
select_html << %(">\n)
|
214
|
-
select_html << "<option></option>\n" if include_blank
|
217
|
+
select_html << "<option value=\"\"></option>\n" if include_blank
|
215
218
|
select_html << options.to_s
|
216
219
|
select_html << "</select>\n"
|
217
220
|
|
@@ -254,7 +257,7 @@ module ActionView
|
|
254
257
|
defaults = { :discard_type => true }
|
255
258
|
options = defaults.merge(options)
|
256
259
|
options_with_prefix = Proc.new { |position| options.merge(:prefix => "#{@object_name}[#{@method_name}(#{position}i)]") }
|
257
|
-
datetime = options[:include_blank] ? (value ||
|
260
|
+
datetime = options[:include_blank] ? (value || nil) : (value || Time.now)
|
258
261
|
|
259
262
|
datetime_select = select_year(datetime, options_with_prefix.call(1))
|
260
263
|
datetime_select << select_month(datetime, options_with_prefix.call(2)) unless options[:discard_month]
|
@@ -266,4 +269,4 @@ module ActionView
|
|
266
269
|
end
|
267
270
|
end
|
268
271
|
end
|
269
|
-
end
|
272
|
+
end
|
@@ -145,11 +145,12 @@ module ActionView
|
|
145
145
|
attr_reader :method_name, :object_name
|
146
146
|
|
147
147
|
DEFAULT_FIELD_OPTIONS = { "size" => 30 }.freeze unless const_defined?(:DEFAULT_FIELD_OPTIONS)
|
148
|
+
DEFAULT_RADIO_OPTIONS = { }.freeze unless const_defined?(:DEFAULT_RADIO_OPTIONS)
|
148
149
|
DEFAULT_TEXT_AREA_OPTIONS = { "wrap" => "virtual", "cols" => 40, "rows" => 20 }.freeze unless const_defined?(:DEFAULT_TEXT_AREA_OPTIONS)
|
149
150
|
DEFAULT_DATE_OPTIONS = { :discard_type => true }.freeze unless const_defined?(:DEFAULT_DATE_OPTIONS)
|
150
151
|
|
151
152
|
def initialize(object_name, method_name, template_object, local_binding = nil)
|
152
|
-
@object_name, @method_name = object_name, method_name
|
153
|
+
@object_name, @method_name = object_name.to_s, method_name.to_s
|
153
154
|
@template_object, @local_binding = template_object, local_binding
|
154
155
|
if @object_name.sub!(/\[\]$/,"")
|
155
156
|
@auto_index = @template_object.instance_variable_get("@#{Regexp.last_match.pre_match}").id_before_type_cast
|
@@ -158,10 +159,10 @@ module ActionView
|
|
158
159
|
|
159
160
|
def to_input_field_tag(field_type, options = {})
|
160
161
|
options = options.stringify_keys
|
162
|
+
options["size"] ||= options["maxlength"] || DEFAULT_FIELD_OPTIONS["size"]
|
163
|
+
options = DEFAULT_FIELD_OPTIONS.merge(options)
|
161
164
|
if field_type == "hidden"
|
162
165
|
options.delete("size")
|
163
|
-
else
|
164
|
-
options["size"] ||= options["maxlength"] || DEFAULT_FIELD_OPTIONS["size"]
|
165
166
|
end
|
166
167
|
options["type"] = field_type
|
167
168
|
options["value"] ||= value_before_type_cast unless field_type == "file"
|
@@ -170,7 +171,7 @@ module ActionView
|
|
170
171
|
end
|
171
172
|
|
172
173
|
def to_radio_button_tag(tag_value, options = {})
|
173
|
-
options =
|
174
|
+
options = DEFAULT_RADIO_OPTIONS.merge(options.stringify_keys)
|
174
175
|
options["type"] = "radio"
|
175
176
|
options["value"] = tag_value
|
176
177
|
options["checked"] = "checked" if value == tag_value
|
@@ -198,7 +199,7 @@ module ActionView
|
|
198
199
|
else
|
199
200
|
value.to_i != 0
|
200
201
|
end
|
201
|
-
if checked
|
202
|
+
if checked || options["checked"] == "checked"
|
202
203
|
options["checked"] = "checked"
|
203
204
|
else
|
204
205
|
options.delete("checked")
|
@@ -92,7 +92,7 @@ module ActionView
|
|
92
92
|
else
|
93
93
|
is_selected = ( (selected.respond_to?(:include?) ? selected.include?(element) : element == selected) )
|
94
94
|
is_selected = ( (selected.respond_to?(:include?) && !selected.is_a?(String) ? selected.include?(element) : element == selected) )
|
95
|
-
options << ((is_selected) ? "<option selected=\"selected\">#{html_escape(element.to_s)}</option>" : "<option>#{html_escape(element.to_s)}</option>")
|
95
|
+
options << ((is_selected) ? "<option value=\"#{html_escape(element.to_s)}\" selected=\"selected\">#{html_escape(element.to_s)}</option>" : "<option value=\"#{html_escape(element.to_s)}\">#{html_escape(element.to_s)}</option>")
|
96
96
|
end
|
97
97
|
end
|
98
98
|
|
@@ -168,7 +168,7 @@ module ActionView
|
|
168
168
|
|
169
169
|
if priority_countries
|
170
170
|
country_options += options_for_select(priority_countries, selected)
|
171
|
-
country_options += "<option>-------------</option>\n"
|
171
|
+
country_options += "<option value=\"\">-------------</option>\n"
|
172
172
|
end
|
173
173
|
|
174
174
|
if priority_countries && priority_countries.include?(selected)
|
@@ -205,7 +205,7 @@ module ActionView
|
|
205
205
|
|
206
206
|
if priority_zones
|
207
207
|
zone_options += options_for_select(convert_zones[priority_zones], selected)
|
208
|
-
zone_options += "<option>-------------</option>\n"
|
208
|
+
zone_options += "<option value=\"\">-------------</option>\n"
|
209
209
|
|
210
210
|
zones = zones.reject { |z| priority_zones.include?( z ) }
|
211
211
|
end
|
@@ -298,7 +298,7 @@ module ActionView
|
|
298
298
|
|
299
299
|
private
|
300
300
|
def add_blank_option(option_tags, add_blank)
|
301
|
-
add_blank ? "<option></option>\n" + option_tags : option_tags
|
301
|
+
add_blank ? "<option value=\"\"></option>\n" + option_tags : option_tags
|
302
302
|
end
|
303
303
|
end
|
304
304
|
end
|