actionview 4.1.0.beta1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of actionview might be problematic. Click here for more details.

Files changed (106) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +274 -0
  3. data/MIT-LICENSE +21 -0
  4. data/README.rdoc +34 -0
  5. data/lib/action_view.rb +97 -0
  6. data/lib/action_view/base.rb +205 -0
  7. data/lib/action_view/buffers.rb +49 -0
  8. data/lib/action_view/context.rb +36 -0
  9. data/lib/action_view/dependency_tracker.rb +93 -0
  10. data/lib/action_view/digestor.rb +116 -0
  11. data/lib/action_view/flows.rb +76 -0
  12. data/lib/action_view/helpers.rb +64 -0
  13. data/lib/action_view/helpers/active_model_helper.rb +49 -0
  14. data/lib/action_view/helpers/asset_tag_helper.rb +322 -0
  15. data/lib/action_view/helpers/asset_url_helper.rb +355 -0
  16. data/lib/action_view/helpers/atom_feed_helper.rb +203 -0
  17. data/lib/action_view/helpers/cache_helper.rb +200 -0
  18. data/lib/action_view/helpers/capture_helper.rb +216 -0
  19. data/lib/action_view/helpers/controller_helper.rb +25 -0
  20. data/lib/action_view/helpers/csrf_helper.rb +30 -0
  21. data/lib/action_view/helpers/date_helper.rb +1075 -0
  22. data/lib/action_view/helpers/debug_helper.rb +39 -0
  23. data/lib/action_view/helpers/form_helper.rb +1876 -0
  24. data/lib/action_view/helpers/form_options_helper.rb +843 -0
  25. data/lib/action_view/helpers/form_tag_helper.rb +746 -0
  26. data/lib/action_view/helpers/javascript_helper.rb +75 -0
  27. data/lib/action_view/helpers/number_helper.rb +425 -0
  28. data/lib/action_view/helpers/output_safety_helper.rb +38 -0
  29. data/lib/action_view/helpers/record_tag_helper.rb +108 -0
  30. data/lib/action_view/helpers/rendering_helper.rb +90 -0
  31. data/lib/action_view/helpers/sanitize_helper.rb +256 -0
  32. data/lib/action_view/helpers/tag_helper.rb +176 -0
  33. data/lib/action_view/helpers/tags.rb +41 -0
  34. data/lib/action_view/helpers/tags/base.rb +148 -0
  35. data/lib/action_view/helpers/tags/check_box.rb +64 -0
  36. data/lib/action_view/helpers/tags/checkable.rb +16 -0
  37. data/lib/action_view/helpers/tags/collection_check_boxes.rb +44 -0
  38. data/lib/action_view/helpers/tags/collection_helpers.rb +85 -0
  39. data/lib/action_view/helpers/tags/collection_radio_buttons.rb +36 -0
  40. data/lib/action_view/helpers/tags/collection_select.rb +28 -0
  41. data/lib/action_view/helpers/tags/color_field.rb +25 -0
  42. data/lib/action_view/helpers/tags/date_field.rb +13 -0
  43. data/lib/action_view/helpers/tags/date_select.rb +72 -0
  44. data/lib/action_view/helpers/tags/datetime_field.rb +22 -0
  45. data/lib/action_view/helpers/tags/datetime_local_field.rb +19 -0
  46. data/lib/action_view/helpers/tags/datetime_select.rb +8 -0
  47. data/lib/action_view/helpers/tags/email_field.rb +8 -0
  48. data/lib/action_view/helpers/tags/file_field.rb +8 -0
  49. data/lib/action_view/helpers/tags/grouped_collection_select.rb +29 -0
  50. data/lib/action_view/helpers/tags/hidden_field.rb +8 -0
  51. data/lib/action_view/helpers/tags/label.rb +65 -0
  52. data/lib/action_view/helpers/tags/month_field.rb +13 -0
  53. data/lib/action_view/helpers/tags/number_field.rb +18 -0
  54. data/lib/action_view/helpers/tags/password_field.rb +12 -0
  55. data/lib/action_view/helpers/tags/radio_button.rb +31 -0
  56. data/lib/action_view/helpers/tags/range_field.rb +8 -0
  57. data/lib/action_view/helpers/tags/search_field.rb +24 -0
  58. data/lib/action_view/helpers/tags/select.rb +41 -0
  59. data/lib/action_view/helpers/tags/tel_field.rb +8 -0
  60. data/lib/action_view/helpers/tags/text_area.rb +18 -0
  61. data/lib/action_view/helpers/tags/text_field.rb +29 -0
  62. data/lib/action_view/helpers/tags/time_field.rb +13 -0
  63. data/lib/action_view/helpers/tags/time_select.rb +8 -0
  64. data/lib/action_view/helpers/tags/time_zone_select.rb +20 -0
  65. data/lib/action_view/helpers/tags/url_field.rb +8 -0
  66. data/lib/action_view/helpers/tags/week_field.rb +13 -0
  67. data/lib/action_view/helpers/text_helper.rb +447 -0
  68. data/lib/action_view/helpers/translation_helper.rb +111 -0
  69. data/lib/action_view/helpers/url_helper.rb +625 -0
  70. data/lib/action_view/layouts.rb +426 -0
  71. data/lib/action_view/locale/en.yml +56 -0
  72. data/lib/action_view/log_subscriber.rb +44 -0
  73. data/lib/action_view/lookup_context.rb +249 -0
  74. data/lib/action_view/model_naming.rb +12 -0
  75. data/lib/action_view/path_set.rb +77 -0
  76. data/lib/action_view/railtie.rb +49 -0
  77. data/lib/action_view/record_identifier.rb +84 -0
  78. data/lib/action_view/renderer/abstract_renderer.rb +47 -0
  79. data/lib/action_view/renderer/partial_renderer.rb +492 -0
  80. data/lib/action_view/renderer/renderer.rb +50 -0
  81. data/lib/action_view/renderer/streaming_template_renderer.rb +103 -0
  82. data/lib/action_view/renderer/template_renderer.rb +96 -0
  83. data/lib/action_view/rendering.rb +145 -0
  84. data/lib/action_view/routing_url_for.rb +109 -0
  85. data/lib/action_view/tasks/dependencies.rake +17 -0
  86. data/lib/action_view/template.rb +340 -0
  87. data/lib/action_view/template/error.rb +141 -0
  88. data/lib/action_view/template/handlers.rb +53 -0
  89. data/lib/action_view/template/handlers/builder.rb +26 -0
  90. data/lib/action_view/template/handlers/erb.rb +145 -0
  91. data/lib/action_view/template/handlers/raw.rb +11 -0
  92. data/lib/action_view/template/resolver.rb +329 -0
  93. data/lib/action_view/template/text.rb +34 -0
  94. data/lib/action_view/template/types.rb +57 -0
  95. data/lib/action_view/test_case.rb +272 -0
  96. data/lib/action_view/testing/resolvers.rb +50 -0
  97. data/lib/action_view/vendor/html-scanner.rb +20 -0
  98. data/lib/action_view/vendor/html-scanner/html/document.rb +68 -0
  99. data/lib/action_view/vendor/html-scanner/html/node.rb +532 -0
  100. data/lib/action_view/vendor/html-scanner/html/sanitizer.rb +188 -0
  101. data/lib/action_view/vendor/html-scanner/html/selector.rb +830 -0
  102. data/lib/action_view/vendor/html-scanner/html/tokenizer.rb +107 -0
  103. data/lib/action_view/vendor/html-scanner/html/version.rb +11 -0
  104. data/lib/action_view/version.rb +11 -0
  105. data/lib/action_view/view_paths.rb +96 -0
  106. metadata +218 -0
@@ -0,0 +1,176 @@
1
+ require 'active_support/core_ext/string/output_safety'
2
+ require 'set'
3
+
4
+ module ActionView
5
+ # = Action View Tag Helpers
6
+ module Helpers #:nodoc:
7
+ # Provides methods to generate HTML tags programmatically when you can't use
8
+ # a Builder. By default, they output XHTML compliant tags.
9
+ module TagHelper
10
+ extend ActiveSupport::Concern
11
+ include CaptureHelper
12
+
13
+ BOOLEAN_ATTRIBUTES = %w(disabled readonly multiple checked autobuffer
14
+ autoplay controls loop selected hidden scoped async
15
+ defer reversed ismap seamless muted required
16
+ autofocus novalidate formnovalidate open pubdate
17
+ itemscope allowfullscreen default inert sortable
18
+ truespeed typemustmatch).to_set
19
+
20
+ BOOLEAN_ATTRIBUTES.merge(BOOLEAN_ATTRIBUTES.map {|attribute| attribute.to_sym })
21
+
22
+ PRE_CONTENT_STRINGS = {
23
+ :textarea => "\n"
24
+ }
25
+
26
+ # Returns an empty HTML tag of type +name+ which by default is XHTML
27
+ # compliant. Set +open+ to true to create an open tag compatible
28
+ # with HTML 4.0 and below. Add HTML attributes by passing an attributes
29
+ # hash to +options+. Set +escape+ to false to disable attribute value
30
+ # escaping.
31
+ #
32
+ # ==== Options
33
+ # You can use symbols or strings for the attribute names.
34
+ #
35
+ # Use +true+ with boolean attributes that can render with no value, like
36
+ # +disabled+ and +readonly+.
37
+ #
38
+ # HTML5 <tt>data-*</tt> attributes can be set with a single +data+ key
39
+ # pointing to a hash of sub-attributes.
40
+ #
41
+ # To play nicely with JavaScript conventions sub-attributes are dasherized.
42
+ # For example, a key +user_id+ would render as <tt>data-user-id</tt> and
43
+ # thus accessed as <tt>dataset.userId</tt>.
44
+ #
45
+ # Values are encoded to JSON, with the exception of strings and symbols.
46
+ # This may come in handy when using jQuery's HTML5-aware <tt>.data()</tt>
47
+ # from 1.4.3.
48
+ #
49
+ # ==== Examples
50
+ # tag("br")
51
+ # # => <br />
52
+ #
53
+ # tag("br", nil, true)
54
+ # # => <br>
55
+ #
56
+ # tag("input", type: 'text', disabled: true)
57
+ # # => <input type="text" disabled="disabled" />
58
+ #
59
+ # tag("img", src: "open & shut.png")
60
+ # # => <img src="open &amp; shut.png" />
61
+ #
62
+ # tag("img", {src: "open &amp; shut.png"}, false, false)
63
+ # # => <img src="open &amp; shut.png" />
64
+ #
65
+ # tag("div", data: {name: 'Stephen', city_state: %w(Chicago IL)})
66
+ # # => <div data-name="Stephen" data-city-state="[&quot;Chicago&quot;,&quot;IL&quot;]" />
67
+ def tag(name, options = nil, open = false, escape = true)
68
+ "<#{name}#{tag_options(options, escape) if options}#{open ? ">" : " />"}".html_safe
69
+ end
70
+
71
+ # Returns an HTML block tag of type +name+ surrounding the +content+. Add
72
+ # HTML attributes by passing an attributes hash to +options+.
73
+ # Instead of passing the content as an argument, you can also use a block
74
+ # in which case, you pass your +options+ as the second parameter.
75
+ # Set escape to false to disable attribute value escaping.
76
+ #
77
+ # ==== Options
78
+ # The +options+ hash is used with attributes with no value like (<tt>disabled</tt> and
79
+ # <tt>readonly</tt>), which you can give a value of true in the +options+ hash. You can use
80
+ # symbols or strings for the attribute names.
81
+ #
82
+ # ==== Examples
83
+ # content_tag(:p, "Hello world!")
84
+ # # => <p>Hello world!</p>
85
+ # content_tag(:div, content_tag(:p, "Hello world!"), class: "strong")
86
+ # # => <div class="strong"><p>Hello world!</p></div>
87
+ # content_tag("select", options, multiple: true)
88
+ # # => <select multiple="multiple">...options...</select>
89
+ #
90
+ # <%= content_tag :div, class: "strong" do -%>
91
+ # Hello world!
92
+ # <% end -%>
93
+ # # => <div class="strong">Hello world!</div>
94
+ def content_tag(name, content_or_options_with_block = nil, options = nil, escape = true, &block)
95
+ if block_given?
96
+ options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash)
97
+ content_tag_string(name, capture(&block), options, escape)
98
+ else
99
+ content_tag_string(name, content_or_options_with_block, options, escape)
100
+ end
101
+ end
102
+
103
+ # Returns a CDATA section with the given +content+. CDATA sections
104
+ # are used to escape blocks of text containing characters which would
105
+ # otherwise be recognized as markup. CDATA sections begin with the string
106
+ # <tt><![CDATA[</tt> and end with (and may not contain) the string <tt>]]></tt>.
107
+ #
108
+ # cdata_section("<hello world>")
109
+ # # => <![CDATA[<hello world>]]>
110
+ #
111
+ # cdata_section(File.read("hello_world.txt"))
112
+ # # => <![CDATA[<hello from a text file]]>
113
+ #
114
+ # cdata_section("hello]]>world")
115
+ # # => <![CDATA[hello]]]]><![CDATA[>world]]>
116
+ def cdata_section(content)
117
+ splitted = content.to_s.gsub(']]>', ']]]]><![CDATA[>')
118
+ "<![CDATA[#{splitted}]]>".html_safe
119
+ end
120
+
121
+ # Returns an escaped version of +html+ without affecting existing escaped entities.
122
+ #
123
+ # escape_once("1 < 2 &amp; 3")
124
+ # # => "1 &lt; 2 &amp; 3"
125
+ #
126
+ # escape_once("&lt;&lt; Accept & Checkout")
127
+ # # => "&lt;&lt; Accept &amp; Checkout"
128
+ def escape_once(html)
129
+ ERB::Util.html_escape_once(html)
130
+ end
131
+
132
+ private
133
+
134
+ def content_tag_string(name, content, options, escape = true)
135
+ tag_options = tag_options(options, escape) if options
136
+ content = ERB::Util.h(content) if escape
137
+ "<#{name}#{tag_options}>#{PRE_CONTENT_STRINGS[name.to_sym]}#{content}</#{name}>".html_safe
138
+ end
139
+
140
+ def tag_options(options, escape = true)
141
+ return if options.blank?
142
+ attrs = []
143
+ options.each_pair do |key, value|
144
+ if key.to_s == 'data' && value.is_a?(Hash)
145
+ value.each_pair do |k, v|
146
+ attrs << data_tag_option(k, v, escape)
147
+ end
148
+ elsif BOOLEAN_ATTRIBUTES.include?(key)
149
+ attrs << boolean_tag_option(key) if value
150
+ elsif !value.nil?
151
+ attrs << tag_option(key, value, escape)
152
+ end
153
+ end
154
+ " #{attrs.sort! * ' '}" unless attrs.empty?
155
+ end
156
+
157
+ def data_tag_option(key, value, escape)
158
+ key = "data-#{key.to_s.dasherize}"
159
+ unless value.is_a?(String) || value.is_a?(Symbol) || value.is_a?(BigDecimal)
160
+ value = value.to_json
161
+ end
162
+ tag_option(key, value, escape)
163
+ end
164
+
165
+ def boolean_tag_option(key)
166
+ %(#{key}="#{key}")
167
+ end
168
+
169
+ def tag_option(key, value, escape)
170
+ value = value.join(" ") if value.is_a?(Array)
171
+ value = ERB::Util.h(value) if escape
172
+ %(#{key}="#{value}")
173
+ end
174
+ end
175
+ end
176
+ end
@@ -0,0 +1,41 @@
1
+ module ActionView
2
+ module Helpers
3
+ module Tags #:nodoc:
4
+ extend ActiveSupport::Autoload
5
+
6
+ eager_autoload do
7
+ autoload :Base
8
+ autoload :CheckBox
9
+ autoload :CollectionCheckBoxes
10
+ autoload :CollectionRadioButtons
11
+ autoload :CollectionSelect
12
+ autoload :ColorField
13
+ autoload :DateField
14
+ autoload :DateSelect
15
+ autoload :DatetimeField
16
+ autoload :DatetimeLocalField
17
+ autoload :DatetimeSelect
18
+ autoload :EmailField
19
+ autoload :FileField
20
+ autoload :GroupedCollectionSelect
21
+ autoload :HiddenField
22
+ autoload :Label
23
+ autoload :MonthField
24
+ autoload :NumberField
25
+ autoload :PasswordField
26
+ autoload :RadioButton
27
+ autoload :RangeField
28
+ autoload :SearchField
29
+ autoload :Select
30
+ autoload :TelField
31
+ autoload :TextArea
32
+ autoload :TextField
33
+ autoload :TimeField
34
+ autoload :TimeSelect
35
+ autoload :TimeZoneSelect
36
+ autoload :UrlField
37
+ autoload :WeekField
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,148 @@
1
+ module ActionView
2
+ module Helpers
3
+ module Tags # :nodoc:
4
+ class Base # :nodoc:
5
+ include Helpers::ActiveModelInstanceTag, Helpers::TagHelper, Helpers::FormTagHelper
6
+ include FormOptionsHelper
7
+
8
+ attr_reader :object
9
+
10
+ def initialize(object_name, method_name, template_object, options = {})
11
+ @object_name, @method_name = object_name.to_s.dup, method_name.to_s.dup
12
+ @template_object = template_object
13
+
14
+ @object_name.sub!(/\[\]$/,"") || @object_name.sub!(/\[\]\]$/,"]")
15
+ @object = retrieve_object(options.delete(:object))
16
+ @options = options
17
+ @auto_index = retrieve_autoindex(Regexp.last_match.pre_match) if Regexp.last_match
18
+ end
19
+
20
+ # This is what child classes implement.
21
+ def render
22
+ raise NotImplementedError, "Subclasses must implement a render method"
23
+ end
24
+
25
+ private
26
+
27
+ def value(object)
28
+ object.send @method_name if object
29
+ end
30
+
31
+ def value_before_type_cast(object)
32
+ unless object.nil?
33
+ method_before_type_cast = @method_name + "_before_type_cast"
34
+
35
+ object.respond_to?(method_before_type_cast) ?
36
+ object.send(method_before_type_cast) :
37
+ value(object)
38
+ end
39
+ end
40
+
41
+ def retrieve_object(object)
42
+ if object
43
+ object
44
+ elsif @template_object.instance_variable_defined?("@#{@object_name}")
45
+ @template_object.instance_variable_get("@#{@object_name}")
46
+ end
47
+ rescue NameError
48
+ # As @object_name may contain the nested syntax (item[subobject]) we need to fallback to nil.
49
+ nil
50
+ end
51
+
52
+ def retrieve_autoindex(pre_match)
53
+ object = self.object || @template_object.instance_variable_get("@#{pre_match}")
54
+ if object && object.respond_to?(:to_param)
55
+ object.to_param
56
+ else
57
+ raise ArgumentError, "object[] naming but object param and @object var don't exist or don't respond to to_param: #{object.inspect}"
58
+ end
59
+ end
60
+
61
+ def add_default_name_and_id_for_value(tag_value, options)
62
+ if tag_value.nil?
63
+ add_default_name_and_id(options)
64
+ else
65
+ specified_id = options["id"]
66
+ add_default_name_and_id(options)
67
+
68
+ if specified_id.blank? && options["id"].present?
69
+ options["id"] += "_#{sanitized_value(tag_value)}"
70
+ end
71
+ end
72
+ end
73
+
74
+ def add_default_name_and_id(options)
75
+ if options.has_key?("index")
76
+ options["name"] ||= options.fetch("name"){ tag_name_with_index(options["index"], options["multiple"]) }
77
+ options["id"] = options.fetch("id"){ tag_id_with_index(options["index"]) }
78
+ options.delete("index")
79
+ elsif defined?(@auto_index)
80
+ options["name"] ||= options.fetch("name"){ tag_name_with_index(@auto_index, options["multiple"]) }
81
+ options["id"] = options.fetch("id"){ tag_id_with_index(@auto_index) }
82
+ else
83
+ options["name"] ||= options.fetch("name"){ tag_name(options["multiple"]) }
84
+ options["id"] = options.fetch("id"){ tag_id }
85
+ end
86
+
87
+ options["id"] = [options.delete('namespace'), options["id"]].compact.join("_").presence
88
+ end
89
+
90
+ def tag_name(multiple = false)
91
+ "#{@object_name}[#{sanitized_method_name}]#{"[]" if multiple}"
92
+ end
93
+
94
+ def tag_name_with_index(index, multiple = false)
95
+ "#{@object_name}[#{index}][#{sanitized_method_name}]#{"[]" if multiple}"
96
+ end
97
+
98
+ def tag_id
99
+ "#{sanitized_object_name}_#{sanitized_method_name}"
100
+ end
101
+
102
+ def tag_id_with_index(index)
103
+ "#{sanitized_object_name}_#{index}_#{sanitized_method_name}"
104
+ end
105
+
106
+ def sanitized_object_name
107
+ @sanitized_object_name ||= @object_name.gsub(/\]\[|[^-a-zA-Z0-9:.]/, "_").sub(/_$/, "")
108
+ end
109
+
110
+ def sanitized_method_name
111
+ @sanitized_method_name ||= @method_name.sub(/\?$/,"")
112
+ end
113
+
114
+ def sanitized_value(value)
115
+ value.to_s.gsub(/\s/, "_").gsub(/[^-\w]/, "").downcase
116
+ end
117
+
118
+ def select_content_tag(option_tags, options, html_options)
119
+ html_options = html_options.stringify_keys
120
+ add_default_name_and_id(html_options)
121
+ options[:include_blank] ||= true unless options[:prompt] || select_not_required?(html_options)
122
+ value = options.fetch(:selected) { value(object) }
123
+ select = content_tag("select", add_options(option_tags, options, value), html_options)
124
+
125
+ if html_options["multiple"] && options.fetch(:include_hidden, true)
126
+ tag("input", :disabled => html_options["disabled"], :name => html_options["name"], :type => "hidden", :value => "") + select
127
+ else
128
+ select
129
+ end
130
+ end
131
+
132
+ def select_not_required?(html_options)
133
+ !html_options["required"] || html_options["multiple"] || html_options["size"].to_i > 1
134
+ end
135
+
136
+ def add_options(option_tags, options, value = nil)
137
+ if options[:include_blank]
138
+ option_tags = content_tag_string('option', options[:include_blank].kind_of?(String) ? options[:include_blank] : nil, :value => '') + "\n" + option_tags
139
+ end
140
+ if value.blank? && options[:prompt]
141
+ option_tags = content_tag_string('option', prompt_text(options[:prompt]), :value => '') + "\n" + option_tags
142
+ end
143
+ option_tags
144
+ end
145
+ end
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,64 @@
1
+ require 'action_view/helpers/tags/checkable'
2
+
3
+ module ActionView
4
+ module Helpers
5
+ module Tags # :nodoc:
6
+ class CheckBox < Base #:nodoc:
7
+ include Checkable
8
+
9
+ def initialize(object_name, method_name, template_object, checked_value, unchecked_value, options)
10
+ @checked_value = checked_value
11
+ @unchecked_value = unchecked_value
12
+ super(object_name, method_name, template_object, options)
13
+ end
14
+
15
+ def render
16
+ options = @options.stringify_keys
17
+ options["type"] = "checkbox"
18
+ options["value"] = @checked_value
19
+ options["checked"] = "checked" if input_checked?(object, options)
20
+
21
+ if options["multiple"]
22
+ add_default_name_and_id_for_value(@checked_value, options)
23
+ options.delete("multiple")
24
+ else
25
+ add_default_name_and_id(options)
26
+ end
27
+
28
+ include_hidden = options.delete("include_hidden") { true }
29
+ checkbox = tag("input", options)
30
+
31
+ if include_hidden
32
+ hidden = hidden_field_for_checkbox(options)
33
+ hidden + checkbox
34
+ else
35
+ checkbox
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ def checked?(value)
42
+ case value
43
+ when TrueClass, FalseClass
44
+ value == !!@checked_value
45
+ when NilClass
46
+ false
47
+ when String
48
+ value == @checked_value
49
+ else
50
+ if value.respond_to?(:include?)
51
+ value.include?(@checked_value)
52
+ else
53
+ value.to_i == @checked_value.to_i
54
+ end
55
+ end
56
+ end
57
+
58
+ def hidden_field_for_checkbox(options)
59
+ @unchecked_value ? tag("input", options.slice("name", "disabled", "form").merge!("type" => "hidden", "value" => @unchecked_value)) : "".html_safe
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,16 @@
1
+ module ActionView
2
+ module Helpers
3
+ module Tags # :nodoc:
4
+ module Checkable # :nodoc:
5
+ def input_checked?(object, options)
6
+ if options.has_key?("checked")
7
+ checked = options.delete "checked"
8
+ checked == true || checked == "checked"
9
+ else
10
+ checked?(value(object))
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end