actionpack 3.2.19 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +850 -401
- data/MIT-LICENSE +1 -1
- data/README.rdoc +5 -288
- data/lib/abstract_controller/asset_paths.rb +2 -2
- data/lib/abstract_controller/base.rb +39 -37
- data/lib/abstract_controller/callbacks.rb +101 -82
- data/lib/abstract_controller/collector.rb +7 -3
- data/lib/abstract_controller/helpers.rb +25 -13
- data/lib/abstract_controller/layouts.rb +74 -74
- data/lib/abstract_controller/logger.rb +1 -2
- data/lib/abstract_controller/rendering.rb +30 -13
- data/lib/abstract_controller/translation.rb +16 -1
- data/lib/abstract_controller/url_for.rb +6 -6
- data/lib/abstract_controller/view_paths.rb +1 -1
- data/lib/abstract_controller.rb +1 -8
- data/lib/action_controller/base.rb +46 -22
- data/lib/action_controller/caching/fragments.rb +23 -53
- data/lib/action_controller/caching.rb +46 -33
- data/lib/action_controller/deprecated/integration_test.rb +3 -0
- data/lib/action_controller/deprecated.rb +5 -1
- data/lib/action_controller/log_subscriber.rb +16 -8
- data/lib/action_controller/metal/conditional_get.rb +76 -32
- data/lib/action_controller/metal/data_streaming.rb +20 -26
- data/lib/action_controller/metal/exceptions.rb +19 -6
- data/lib/action_controller/metal/flash.rb +24 -9
- data/lib/action_controller/metal/force_ssl.rb +70 -12
- data/lib/action_controller/metal/head.rb +25 -4
- data/lib/action_controller/metal/helpers.rb +5 -9
- data/lib/action_controller/metal/hide_actions.rb +0 -1
- data/lib/action_controller/metal/http_authentication.rb +107 -83
- data/lib/action_controller/metal/implicit_render.rb +1 -1
- data/lib/action_controller/metal/instrumentation.rb +2 -1
- data/lib/action_controller/metal/live.rb +175 -0
- data/lib/action_controller/metal/mime_responds.rb +161 -47
- data/lib/action_controller/metal/params_wrapper.rb +112 -74
- data/lib/action_controller/metal/rack_delegation.rb +9 -3
- data/lib/action_controller/metal/redirecting.rb +15 -20
- data/lib/action_controller/metal/renderers.rb +11 -9
- data/lib/action_controller/metal/rendering.rb +9 -1
- data/lib/action_controller/metal/request_forgery_protection.rb +112 -19
- data/lib/action_controller/metal/responder.rb +20 -19
- data/lib/action_controller/metal/streaming.rb +12 -18
- data/lib/action_controller/metal/strong_parameters.rb +520 -0
- data/lib/action_controller/metal/testing.rb +13 -18
- data/lib/action_controller/metal/url_for.rb +28 -25
- data/lib/action_controller/metal.rb +17 -32
- data/lib/action_controller/model_naming.rb +12 -0
- data/lib/action_controller/railtie.rb +33 -17
- data/lib/action_controller/railties/helpers.rb +22 -0
- data/lib/action_controller/record_identifier.rb +18 -72
- data/lib/action_controller/test_case.rb +251 -131
- data/lib/action_controller/vendor/html-scanner.rb +4 -19
- data/lib/action_controller.rb +15 -6
- data/lib/action_dispatch/http/cache.rb +63 -11
- data/lib/action_dispatch/http/filter_parameters.rb +18 -8
- data/lib/action_dispatch/http/filter_redirect.rb +37 -0
- data/lib/action_dispatch/http/headers.rb +49 -17
- data/lib/action_dispatch/http/mime_negotiation.rb +24 -1
- data/lib/action_dispatch/http/mime_type.rb +154 -100
- data/lib/action_dispatch/http/mime_types.rb +1 -1
- data/lib/action_dispatch/http/parameter_filter.rb +44 -46
- data/lib/action_dispatch/http/parameters.rb +28 -28
- data/lib/action_dispatch/http/rack_cache.rb +2 -3
- data/lib/action_dispatch/http/request.rb +64 -18
- data/lib/action_dispatch/http/response.rb +130 -35
- data/lib/action_dispatch/http/upload.rb +63 -20
- data/lib/action_dispatch/http/url.rb +98 -35
- data/lib/action_dispatch/journey/backwards.rb +5 -0
- data/lib/action_dispatch/journey/formatter.rb +146 -0
- data/lib/action_dispatch/journey/gtg/builder.rb +162 -0
- data/lib/action_dispatch/journey/gtg/simulator.rb +44 -0
- data/lib/action_dispatch/journey/gtg/transition_table.rb +156 -0
- data/lib/action_dispatch/journey/nfa/builder.rb +76 -0
- data/lib/action_dispatch/journey/nfa/dot.rb +36 -0
- data/lib/action_dispatch/journey/nfa/simulator.rb +47 -0
- data/lib/action_dispatch/journey/nfa/transition_table.rb +163 -0
- data/lib/action_dispatch/journey/nodes/node.rb +124 -0
- data/lib/action_dispatch/journey/parser.rb +206 -0
- data/lib/action_dispatch/journey/parser.y +47 -0
- data/lib/action_dispatch/journey/parser_extras.rb +23 -0
- data/lib/action_dispatch/journey/path/pattern.rb +196 -0
- data/lib/action_dispatch/journey/route.rb +124 -0
- data/lib/action_dispatch/journey/router/strexp.rb +24 -0
- data/lib/action_dispatch/journey/router/utils.rb +54 -0
- data/lib/action_dispatch/journey/router.rb +166 -0
- data/lib/action_dispatch/journey/routes.rb +75 -0
- data/lib/action_dispatch/journey/scanner.rb +61 -0
- data/lib/action_dispatch/journey/visitors.rb +197 -0
- data/lib/action_dispatch/journey/visualizer/fsm.css +34 -0
- data/lib/action_dispatch/journey/visualizer/fsm.js +134 -0
- data/lib/action_dispatch/journey/visualizer/index.html.erb +52 -0
- data/lib/action_dispatch/journey.rb +5 -0
- data/lib/action_dispatch/middleware/callbacks.rb +9 -4
- data/lib/action_dispatch/middleware/cookies.rb +259 -114
- data/lib/action_dispatch/middleware/debug_exceptions.rb +26 -17
- data/lib/action_dispatch/middleware/exception_wrapper.rb +29 -3
- data/lib/action_dispatch/middleware/flash.rb +58 -58
- data/lib/action_dispatch/middleware/params_parser.rb +14 -29
- data/lib/action_dispatch/middleware/public_exceptions.rb +30 -14
- data/lib/action_dispatch/middleware/reloader.rb +6 -6
- data/lib/action_dispatch/middleware/remote_ip.rb +145 -39
- data/lib/action_dispatch/middleware/request_id.rb +2 -6
- data/lib/action_dispatch/middleware/session/abstract_store.rb +22 -20
- data/lib/action_dispatch/middleware/session/cookie_store.rb +82 -28
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +8 -3
- data/lib/action_dispatch/middleware/show_exceptions.rb +12 -45
- data/lib/action_dispatch/middleware/ssl.rb +70 -0
- data/lib/action_dispatch/middleware/stack.rb +6 -1
- data/lib/action_dispatch/middleware/static.rb +2 -1
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +14 -11
- data/lib/action_dispatch/middleware/templates/rescues/_source.erb +25 -0
- data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +7 -9
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +15 -9
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +127 -5
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.erb +7 -2
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.erb +30 -15
- data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +39 -13
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.erb +6 -2
- data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +16 -0
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +144 -0
- data/lib/action_dispatch/railtie.rb +16 -6
- data/lib/action_dispatch/request/session.rb +181 -0
- data/lib/action_dispatch/routing/inspector.rb +240 -0
- data/lib/action_dispatch/routing/mapper.rb +540 -291
- data/lib/action_dispatch/routing/polymorphic_routes.rb +16 -20
- data/lib/action_dispatch/routing/redirection.rb +46 -29
- data/lib/action_dispatch/routing/route_set.rb +207 -164
- data/lib/action_dispatch/routing/routes_proxy.rb +2 -0
- data/lib/action_dispatch/routing/url_for.rb +48 -33
- data/lib/action_dispatch/routing.rb +48 -83
- data/lib/action_dispatch/testing/assertions/dom.rb +3 -13
- data/lib/action_dispatch/testing/assertions/response.rb +32 -40
- data/lib/action_dispatch/testing/assertions/routing.rb +42 -41
- data/lib/action_dispatch/testing/assertions/selector.rb +17 -22
- data/lib/action_dispatch/testing/assertions/tag.rb +20 -23
- data/lib/action_dispatch/testing/integration.rb +65 -51
- data/lib/action_dispatch/testing/test_process.rb +9 -6
- data/lib/action_dispatch/testing/test_request.rb +7 -3
- data/lib/action_dispatch.rb +21 -15
- data/lib/action_pack/version.rb +7 -6
- data/lib/action_pack.rb +1 -1
- data/lib/action_view/base.rb +15 -34
- data/lib/action_view/buffers.rb +7 -1
- data/lib/action_view/context.rb +4 -4
- data/lib/action_view/dependency_tracker.rb +93 -0
- data/lib/action_view/digestor.rb +85 -0
- data/lib/action_view/flows.rb +1 -4
- data/lib/action_view/helpers/active_model_helper.rb +3 -4
- data/lib/action_view/helpers/asset_tag_helper.rb +215 -352
- data/lib/action_view/helpers/asset_url_helper.rb +355 -0
- data/lib/action_view/helpers/atom_feed_helper.rb +13 -10
- data/lib/action_view/helpers/cache_helper.rb +150 -18
- data/lib/action_view/helpers/capture_helper.rb +44 -31
- data/lib/action_view/helpers/csrf_helper.rb +0 -2
- data/lib/action_view/helpers/date_helper.rb +269 -248
- data/lib/action_view/helpers/debug_helper.rb +10 -11
- data/lib/action_view/helpers/form_helper.rb +931 -537
- data/lib/action_view/helpers/form_options_helper.rb +341 -166
- data/lib/action_view/helpers/form_tag_helper.rb +190 -90
- data/lib/action_view/helpers/javascript_helper.rb +23 -16
- data/lib/action_view/helpers/number_helper.rb +148 -329
- data/lib/action_view/helpers/output_safety_helper.rb +3 -3
- data/lib/action_view/helpers/record_tag_helper.rb +17 -22
- data/lib/action_view/helpers/rendering_helper.rb +2 -2
- data/lib/action_view/helpers/sanitize_helper.rb +3 -6
- data/lib/action_view/helpers/tag_helper.rb +46 -33
- data/lib/action_view/helpers/tags/base.rb +147 -0
- data/lib/action_view/helpers/tags/check_box.rb +64 -0
- data/lib/action_view/helpers/tags/checkable.rb +16 -0
- data/lib/action_view/helpers/tags/collection_check_boxes.rb +43 -0
- data/lib/action_view/helpers/tags/collection_helpers.rb +83 -0
- data/lib/action_view/helpers/tags/collection_radio_buttons.rb +36 -0
- data/lib/action_view/helpers/tags/collection_select.rb +28 -0
- data/lib/action_view/helpers/tags/color_field.rb +25 -0
- data/lib/action_view/helpers/tags/date_field.rb +13 -0
- data/lib/action_view/helpers/tags/date_select.rb +72 -0
- data/lib/action_view/helpers/tags/datetime_field.rb +22 -0
- data/lib/action_view/helpers/tags/datetime_local_field.rb +19 -0
- data/lib/action_view/helpers/tags/datetime_select.rb +8 -0
- data/lib/action_view/helpers/tags/email_field.rb +8 -0
- data/lib/action_view/helpers/tags/file_field.rb +8 -0
- data/lib/action_view/helpers/tags/grouped_collection_select.rb +29 -0
- data/lib/action_view/helpers/tags/hidden_field.rb +8 -0
- data/lib/action_view/helpers/tags/label.rb +65 -0
- data/lib/action_view/helpers/tags/month_field.rb +13 -0
- data/lib/action_view/helpers/tags/number_field.rb +18 -0
- data/lib/action_view/helpers/tags/password_field.rb +12 -0
- data/lib/action_view/helpers/tags/radio_button.rb +31 -0
- data/lib/action_view/helpers/tags/range_field.rb +8 -0
- data/lib/action_view/helpers/tags/search_field.rb +24 -0
- data/lib/action_view/helpers/tags/select.rb +40 -0
- data/lib/action_view/helpers/tags/tel_field.rb +8 -0
- data/lib/action_view/helpers/tags/text_area.rb +18 -0
- data/lib/action_view/helpers/tags/text_field.rb +29 -0
- data/lib/action_view/helpers/tags/time_field.rb +13 -0
- data/lib/action_view/helpers/tags/time_select.rb +8 -0
- data/lib/action_view/helpers/tags/time_zone_select.rb +20 -0
- data/lib/action_view/helpers/tags/url_field.rb +8 -0
- data/lib/action_view/helpers/tags/week_field.rb +13 -0
- data/lib/action_view/helpers/tags.rb +39 -0
- data/lib/action_view/helpers/text_helper.rb +130 -114
- data/lib/action_view/helpers/translation_helper.rb +32 -16
- data/lib/action_view/helpers/url_helper.rb +211 -270
- data/lib/action_view/helpers.rb +2 -4
- data/lib/action_view/locale/en.yml +1 -105
- data/lib/action_view/log_subscriber.rb +6 -4
- data/lib/action_view/lookup_context.rb +15 -28
- data/lib/action_view/model_naming.rb +12 -0
- data/lib/action_view/path_set.rb +8 -20
- data/lib/action_view/railtie.rb +6 -22
- data/lib/action_view/record_identifier.rb +84 -0
- data/lib/action_view/renderer/abstract_renderer.rb +25 -19
- data/lib/action_view/renderer/partial_renderer.rb +158 -81
- data/lib/action_view/renderer/renderer.rb +8 -12
- data/lib/action_view/renderer/streaming_template_renderer.rb +2 -5
- data/lib/action_view/renderer/template_renderer.rb +12 -10
- data/lib/action_view/routing_url_for.rb +107 -0
- data/lib/action_view/template/error.rb +22 -12
- data/lib/action_view/template/handlers/builder.rb +1 -1
- data/lib/action_view/template/handlers/erb.rb +40 -19
- data/lib/action_view/template/handlers/raw.rb +11 -0
- data/lib/action_view/template/handlers.rb +12 -9
- data/lib/action_view/template/resolver.rb +107 -53
- data/lib/action_view/template/text.rb +12 -8
- data/lib/action_view/template/types.rb +57 -0
- data/lib/action_view/template.rb +25 -23
- data/lib/action_view/test_case.rb +67 -42
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/document.rb +0 -0
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/node.rb +12 -12
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/sanitizer.rb +13 -2
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/selector.rb +9 -9
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/tokenizer.rb +1 -1
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/version.rb +0 -0
- data/lib/action_view/vendor/html-scanner.rb +20 -0
- data/lib/action_view.rb +17 -8
- metadata +184 -214
- data/lib/action_controller/caching/actions.rb +0 -185
- data/lib/action_controller/caching/pages.rb +0 -187
- data/lib/action_controller/caching/sweeping.rb +0 -97
- data/lib/action_controller/deprecated/performance_test.rb +0 -1
- data/lib/action_controller/metal/compatibility.rb +0 -65
- data/lib/action_controller/metal/session_management.rb +0 -14
- data/lib/action_controller/railties/paths.rb +0 -25
- data/lib/action_dispatch/middleware/best_standards_support.rb +0 -30
- data/lib/action_dispatch/middleware/body_proxy.rb +0 -30
- data/lib/action_dispatch/middleware/head.rb +0 -18
- data/lib/action_dispatch/middleware/rescue.rb +0 -26
- data/lib/action_dispatch/testing/performance_test.rb +0 -10
- data/lib/action_view/asset_paths.rb +0 -142
- data/lib/action_view/helpers/asset_paths.rb +0 -7
- data/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb +0 -146
- data/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb +0 -93
- data/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb +0 -193
- data/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb +0 -148
- data/lib/sprockets/assets.rake +0 -99
- data/lib/sprockets/bootstrap.rb +0 -37
- data/lib/sprockets/compressors.rb +0 -83
- data/lib/sprockets/helpers/isolated_helper.rb +0 -13
- data/lib/sprockets/helpers/rails_helper.rb +0 -182
- data/lib/sprockets/helpers.rb +0 -6
- data/lib/sprockets/railtie.rb +0 -62
- data/lib/sprockets/static_compiler.rb +0 -56
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
require 'action_controller/record_identifier'
|
|
2
|
-
|
|
3
1
|
module ActionView
|
|
4
2
|
# = Action View Record Tag Helpers
|
|
5
3
|
module Helpers
|
|
6
4
|
module RecordTagHelper
|
|
7
|
-
include
|
|
5
|
+
include ActionView::RecordIdentifier
|
|
8
6
|
|
|
9
7
|
# Produces a wrapper DIV element with id and class parameters that
|
|
10
8
|
# relate to the specified Active Record object. Usage example:
|
|
11
9
|
#
|
|
12
|
-
# <%= div_for(@person, :
|
|
10
|
+
# <%= div_for(@person, class: "foo") do %>
|
|
13
11
|
# <%= @person.name %>
|
|
14
12
|
# <% end %>
|
|
15
13
|
#
|
|
@@ -21,7 +19,7 @@ module ActionView
|
|
|
21
19
|
# get iterated over and yield each record as an argument for the block.
|
|
22
20
|
# For example:
|
|
23
21
|
#
|
|
24
|
-
# <%= div_for(@people, :
|
|
22
|
+
# <%= div_for(@people, class: "foo") do |person| %>
|
|
25
23
|
# <%= person.name %>
|
|
26
24
|
# <% end %>
|
|
27
25
|
#
|
|
@@ -67,27 +65,25 @@ module ActionView
|
|
|
67
65
|
#
|
|
68
66
|
# produces:
|
|
69
67
|
#
|
|
70
|
-
#
|
|
71
|
-
#
|
|
68
|
+
# <tr id="person_123" class="person">...</tr>
|
|
69
|
+
# <tr id="person_124" class="person">...</tr>
|
|
72
70
|
#
|
|
73
71
|
# content_tag_for also accepts a hash of options, which will be converted to
|
|
74
72
|
# additional HTML attributes. If you specify a <tt>:class</tt> value, it will be combined
|
|
75
73
|
# with the default class name for your object. For example:
|
|
76
74
|
#
|
|
77
|
-
# <%= content_tag_for(:li, @person, :
|
|
75
|
+
# <%= content_tag_for(:li, @person, class: "bar") %>...
|
|
78
76
|
#
|
|
79
77
|
# produces:
|
|
80
78
|
#
|
|
81
79
|
# <li id="person_123" class="person bar">...
|
|
82
80
|
#
|
|
83
81
|
def content_tag_for(tag_name, single_or_multiple_records, prefix = nil, options = nil, &block)
|
|
84
|
-
if
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
content_tag_for_single_record(tag_name, single_or_multiple_records, prefix, options, &block)
|
|
90
|
-
end
|
|
82
|
+
options, prefix = prefix, nil if prefix.is_a?(Hash)
|
|
83
|
+
|
|
84
|
+
Array(single_or_multiple_records).map do |single_record|
|
|
85
|
+
content_tag_for_single_record(tag_name, single_record, prefix, options, &block)
|
|
86
|
+
end.join("\n").html_safe
|
|
91
87
|
end
|
|
92
88
|
|
|
93
89
|
private
|
|
@@ -95,15 +91,14 @@ module ActionView
|
|
|
95
91
|
# Called by <tt>content_tag_for</tt> internally to render a content tag
|
|
96
92
|
# for each record.
|
|
97
93
|
def content_tag_for_single_record(tag_name, record, prefix, options, &block)
|
|
98
|
-
options, prefix = prefix, nil if prefix.is_a?(Hash)
|
|
99
94
|
options = options ? options.dup : {}
|
|
100
|
-
options
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
content_tag(tag_name, capture(&block), options)
|
|
105
|
-
else
|
|
95
|
+
options[:class] = [ dom_class(record, prefix), options[:class] ].compact
|
|
96
|
+
options[:id] = dom_id(record, prefix)
|
|
97
|
+
|
|
98
|
+
if block_given?
|
|
106
99
|
content_tag(tag_name, capture(record, &block), options)
|
|
100
|
+
else
|
|
101
|
+
content_tag(tag_name, "", options)
|
|
107
102
|
end
|
|
108
103
|
end
|
|
109
104
|
end
|
|
@@ -39,7 +39,7 @@ module ActionView
|
|
|
39
39
|
# The user can override this default by passing a block to the layout:
|
|
40
40
|
#
|
|
41
41
|
# # The template
|
|
42
|
-
# <%= render :
|
|
42
|
+
# <%= render layout: "my_layout" do %>
|
|
43
43
|
# Content
|
|
44
44
|
# <% end %>
|
|
45
45
|
#
|
|
@@ -59,7 +59,7 @@ module ActionView
|
|
|
59
59
|
# Finally, the block can take block arguments, which can be passed in by +yield+:
|
|
60
60
|
#
|
|
61
61
|
# # The template
|
|
62
|
-
# <%= render :
|
|
62
|
+
# <%= render layout: "my_layout" do |customer| %>
|
|
63
63
|
# Hello <%= customer.name %>
|
|
64
64
|
# <% end %>
|
|
65
65
|
#
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
require 'active_support/core_ext/object/try'
|
|
2
|
-
require '
|
|
2
|
+
require 'action_view/vendor/html-scanner'
|
|
3
3
|
|
|
4
4
|
module ActionView
|
|
5
5
|
# = Action View Sanitize Helpers
|
|
6
|
-
module Helpers
|
|
6
|
+
module Helpers
|
|
7
7
|
# The SanitizeHelper module provides a set of methods for scrubbing text of undesired HTML elements.
|
|
8
8
|
# These helper methods extend Action View making them callable within your template files.
|
|
9
9
|
module SanitizeHelper
|
|
@@ -29,7 +29,7 @@ module ActionView
|
|
|
29
29
|
#
|
|
30
30
|
# Custom Use (only the mentioned tags and attributes are allowed, nothing else)
|
|
31
31
|
#
|
|
32
|
-
# <%= sanitize @article.body, :
|
|
32
|
+
# <%= sanitize @article.body, tags: %w(table tr td), attributes: %w(id class style) %>
|
|
33
33
|
#
|
|
34
34
|
# Add table tags to the default allowed tags
|
|
35
35
|
#
|
|
@@ -69,8 +69,6 @@ module ActionView
|
|
|
69
69
|
# html-scanner tokenizer and so its HTML parsing ability is limited by
|
|
70
70
|
# that of html-scanner.
|
|
71
71
|
#
|
|
72
|
-
# ==== Examples
|
|
73
|
-
#
|
|
74
72
|
# strip_tags("Strip <i>these</i> tags!")
|
|
75
73
|
# # => Strip these tags!
|
|
76
74
|
#
|
|
@@ -85,7 +83,6 @@ module ActionView
|
|
|
85
83
|
|
|
86
84
|
# Strips all link tags from +text+ leaving just the link text.
|
|
87
85
|
#
|
|
88
|
-
# ==== Examples
|
|
89
86
|
# strip_links('<a href="http://www.rubyonrails.org">Ruby on Rails</a>')
|
|
90
87
|
# # => Ruby on Rails
|
|
91
88
|
#
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
require 'active_support/core_ext/object/blank'
|
|
2
1
|
require 'active_support/core_ext/string/output_safety'
|
|
3
2
|
require 'set'
|
|
4
3
|
|
|
@@ -14,7 +13,7 @@ module ActionView
|
|
|
14
13
|
BOOLEAN_ATTRIBUTES = %w(disabled readonly multiple checked autobuffer
|
|
15
14
|
autoplay controls loop selected hidden scoped async
|
|
16
15
|
defer reversed ismap seemless muted required
|
|
17
|
-
autofocus novalidate formnovalidate open pubdate).to_set
|
|
16
|
+
autofocus novalidate formnovalidate open pubdate itemscope).to_set
|
|
18
17
|
BOOLEAN_ATTRIBUTES.merge(BOOLEAN_ATTRIBUTES.map {|attribute| attribute.to_sym })
|
|
19
18
|
|
|
20
19
|
PRE_CONTENT_STRINGS = {
|
|
@@ -41,7 +40,7 @@ module ActionView
|
|
|
41
40
|
# thus accessed as <tt>dataset.userId</tt>.
|
|
42
41
|
#
|
|
43
42
|
# Values are encoded to JSON, with the exception of strings and symbols.
|
|
44
|
-
# This may come in handy when using jQuery's HTML5-aware <tt>.data()
|
|
43
|
+
# This may come in handy when using jQuery's HTML5-aware <tt>.data()</tt>
|
|
45
44
|
# from 1.4.3.
|
|
46
45
|
#
|
|
47
46
|
# ==== Examples
|
|
@@ -51,16 +50,16 @@ module ActionView
|
|
|
51
50
|
# tag("br", nil, true)
|
|
52
51
|
# # => <br>
|
|
53
52
|
#
|
|
54
|
-
# tag("input", :
|
|
53
|
+
# tag("input", type: 'text', disabled: true)
|
|
55
54
|
# # => <input type="text" disabled="disabled" />
|
|
56
55
|
#
|
|
57
|
-
# tag("img", :
|
|
56
|
+
# tag("img", src: "open & shut.png")
|
|
58
57
|
# # => <img src="open & shut.png" />
|
|
59
58
|
#
|
|
60
|
-
# tag("img", {:
|
|
59
|
+
# tag("img", {src: "open & shut.png"}, false, false)
|
|
61
60
|
# # => <img src="open & shut.png" />
|
|
62
61
|
#
|
|
63
|
-
# tag("div", :
|
|
62
|
+
# tag("div", data: {name: 'Stephen', city_state: %w(Chicago IL)})
|
|
64
63
|
# # => <div data-name="Stephen" data-city-state="["Chicago","IL"]" />
|
|
65
64
|
def tag(name, options = nil, open = false, escape = true)
|
|
66
65
|
"<#{name}#{tag_options(options, escape) if options}#{open ? ">" : " />"}".html_safe
|
|
@@ -80,12 +79,12 @@ module ActionView
|
|
|
80
79
|
# ==== Examples
|
|
81
80
|
# content_tag(:p, "Hello world!")
|
|
82
81
|
# # => <p>Hello world!</p>
|
|
83
|
-
# content_tag(:div, content_tag(:p, "Hello world!"), :
|
|
82
|
+
# content_tag(:div, content_tag(:p, "Hello world!"), class: "strong")
|
|
84
83
|
# # => <div class="strong"><p>Hello world!</p></div>
|
|
85
|
-
# content_tag("select", options, :
|
|
84
|
+
# content_tag("select", options, multiple: true)
|
|
86
85
|
# # => <select multiple="multiple">...options...</select>
|
|
87
86
|
#
|
|
88
|
-
# <%= content_tag :div, :
|
|
87
|
+
# <%= content_tag :div, class: "strong" do -%>
|
|
89
88
|
# Hello world!
|
|
90
89
|
# <% end -%>
|
|
91
90
|
# # => <div class="strong">Hello world!</div>
|
|
@@ -103,57 +102,71 @@ module ActionView
|
|
|
103
102
|
# otherwise be recognized as markup. CDATA sections begin with the string
|
|
104
103
|
# <tt><![CDATA[</tt> and end with (and may not contain) the string <tt>]]></tt>.
|
|
105
104
|
#
|
|
106
|
-
# ==== Examples
|
|
107
105
|
# cdata_section("<hello world>")
|
|
108
106
|
# # => <![CDATA[<hello world>]]>
|
|
109
107
|
#
|
|
110
108
|
# cdata_section(File.read("hello_world.txt"))
|
|
111
109
|
# # => <![CDATA[<hello from a text file]]>
|
|
110
|
+
#
|
|
111
|
+
# cdata_section("hello]]>world")
|
|
112
|
+
# # => <![CDATA[hello]]]]><![CDATA[>world]]>
|
|
112
113
|
def cdata_section(content)
|
|
113
|
-
|
|
114
|
+
splitted = content.gsub(']]>', ']]]]><![CDATA[>')
|
|
115
|
+
"<![CDATA[#{splitted}]]>".html_safe
|
|
114
116
|
end
|
|
115
117
|
|
|
116
118
|
# Returns an escaped version of +html+ without affecting existing escaped entities.
|
|
117
119
|
#
|
|
118
|
-
# ==== Examples
|
|
119
120
|
# escape_once("1 < 2 & 3")
|
|
120
121
|
# # => "1 < 2 & 3"
|
|
121
122
|
#
|
|
122
123
|
# escape_once("<< Accept & Checkout")
|
|
123
124
|
# # => "<< Accept & Checkout"
|
|
124
125
|
def escape_once(html)
|
|
125
|
-
|
|
126
|
+
ERB::Util.html_escape_once(html)
|
|
126
127
|
end
|
|
127
128
|
|
|
128
129
|
private
|
|
129
130
|
|
|
130
131
|
def content_tag_string(name, content, options, escape = true)
|
|
131
132
|
tag_options = tag_options(options, escape) if options
|
|
132
|
-
|
|
133
|
+
content = ERB::Util.h(content) if escape
|
|
134
|
+
"<#{name}#{tag_options}>#{PRE_CONTENT_STRINGS[name.to_sym]}#{content}</#{name}>".html_safe
|
|
133
135
|
end
|
|
134
136
|
|
|
135
137
|
def tag_options(options, escape = true)
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
v = v.to_json
|
|
143
|
-
end
|
|
144
|
-
v = ERB::Util.html_escape(v) if escape
|
|
145
|
-
attrs << %(data-#{k.to_s.dasherize}="#{v}")
|
|
146
|
-
end
|
|
147
|
-
elsif BOOLEAN_ATTRIBUTES.include?(key)
|
|
148
|
-
attrs << %(#{key}="#{key}") if value
|
|
149
|
-
elsif !value.nil?
|
|
150
|
-
final_value = value.is_a?(Array) ? value.join(" ") : value
|
|
151
|
-
final_value = ERB::Util.html_escape(final_value) if escape
|
|
152
|
-
attrs << %(#{key}="#{final_value}")
|
|
138
|
+
return if options.blank?
|
|
139
|
+
attrs = []
|
|
140
|
+
options.each_pair do |key, value|
|
|
141
|
+
if key.to_s == 'data' && value.is_a?(Hash)
|
|
142
|
+
value.each_pair do |k, v|
|
|
143
|
+
attrs << data_tag_option(k, v, escape)
|
|
153
144
|
end
|
|
145
|
+
elsif BOOLEAN_ATTRIBUTES.include?(key)
|
|
146
|
+
attrs << boolean_tag_option(key) if value
|
|
147
|
+
elsif !value.nil?
|
|
148
|
+
attrs << tag_option(key, value, escape)
|
|
154
149
|
end
|
|
155
|
-
" #{attrs.sort * ' '}".html_safe unless attrs.empty?
|
|
156
150
|
end
|
|
151
|
+
" #{attrs.sort * ' '}".html_safe unless attrs.empty?
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def data_tag_option(key, value, escape)
|
|
155
|
+
key = "data-#{key.to_s.dasherize}"
|
|
156
|
+
unless value.is_a?(String) || value.is_a?(Symbol) || value.is_a?(BigDecimal)
|
|
157
|
+
value = value.to_json
|
|
158
|
+
end
|
|
159
|
+
tag_option(key, value, escape)
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def boolean_tag_option(key)
|
|
163
|
+
%(#{key}="#{key}")
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def tag_option(key, value, escape)
|
|
167
|
+
value = value.join(" ") if value.is_a?(Array)
|
|
168
|
+
value = ERB::Util.h(value) if escape
|
|
169
|
+
%(#{key}="#{value}")
|
|
157
170
|
end
|
|
158
171
|
end
|
|
159
172
|
end
|
|
@@ -0,0 +1,147 @@
|
|
|
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
|
+
select = content_tag("select", add_options(option_tags, options, value(object)), html_options)
|
|
123
|
+
|
|
124
|
+
if html_options["multiple"] && options.fetch(:include_hidden, true)
|
|
125
|
+
tag("input", :disabled => html_options["disabled"], :name => html_options["name"], :type => "hidden", :value => "") + select
|
|
126
|
+
else
|
|
127
|
+
select
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def select_not_required?(html_options)
|
|
132
|
+
!html_options["required"] || html_options["multiple"] || html_options["size"].to_i > 1
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def add_options(option_tags, options, value = nil)
|
|
136
|
+
if options[:include_blank]
|
|
137
|
+
option_tags = content_tag_string('option', options[:include_blank].kind_of?(String) ? options[:include_blank] : nil, :value => '') + "\n" + option_tags
|
|
138
|
+
end
|
|
139
|
+
if value.blank? && options[:prompt]
|
|
140
|
+
option_tags = content_tag_string('option', prompt_text(options[:prompt]), :value => '') + "\n" + option_tags
|
|
141
|
+
end
|
|
142
|
+
option_tags
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
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
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require 'action_view/helpers/tags/collection_helpers'
|
|
2
|
+
|
|
3
|
+
module ActionView
|
|
4
|
+
module Helpers
|
|
5
|
+
module Tags # :nodoc:
|
|
6
|
+
class CollectionCheckBoxes < Base # :nodoc:
|
|
7
|
+
include CollectionHelpers
|
|
8
|
+
|
|
9
|
+
class CheckBoxBuilder < Builder # :nodoc:
|
|
10
|
+
def check_box(extra_html_options={})
|
|
11
|
+
html_options = extra_html_options.merge(@input_html_options)
|
|
12
|
+
@template_object.check_box(@object_name, @method_name, html_options, @value, nil)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def render(&block)
|
|
17
|
+
rendered_collection = render_collection do |item, value, text, default_html_options|
|
|
18
|
+
default_html_options[:multiple] = true
|
|
19
|
+
builder = instantiate_builder(CheckBoxBuilder, item, value, text, default_html_options)
|
|
20
|
+
|
|
21
|
+
if block_given?
|
|
22
|
+
@template_object.capture(builder, &block)
|
|
23
|
+
else
|
|
24
|
+
render_component(builder)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Append a hidden field to make sure something will be sent back to the
|
|
29
|
+
# server if all check boxes are unchecked.
|
|
30
|
+
hidden = @template_object.hidden_field_tag("#{tag_name}[]", "", :id => nil)
|
|
31
|
+
|
|
32
|
+
rendered_collection + hidden
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
def render_component(builder)
|
|
38
|
+
builder.check_box + builder.label
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
module ActionView
|
|
2
|
+
module Helpers
|
|
3
|
+
module Tags # :nodoc:
|
|
4
|
+
module CollectionHelpers # :nodoc:
|
|
5
|
+
class Builder # :nodoc:
|
|
6
|
+
attr_reader :object, :text, :value
|
|
7
|
+
|
|
8
|
+
def initialize(template_object, object_name, method_name, object,
|
|
9
|
+
sanitized_attribute_name, text, value, input_html_options)
|
|
10
|
+
@template_object = template_object
|
|
11
|
+
@object_name = object_name
|
|
12
|
+
@method_name = method_name
|
|
13
|
+
@object = object
|
|
14
|
+
@sanitized_attribute_name = sanitized_attribute_name
|
|
15
|
+
@text = text
|
|
16
|
+
@value = value
|
|
17
|
+
@input_html_options = input_html_options
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def label(label_html_options={}, &block)
|
|
21
|
+
@template_object.label(@object_name, @sanitized_attribute_name, @text, label_html_options, &block)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def initialize(object_name, method_name, template_object, collection, value_method, text_method, options, html_options)
|
|
26
|
+
@collection = collection
|
|
27
|
+
@value_method = value_method
|
|
28
|
+
@text_method = text_method
|
|
29
|
+
@html_options = html_options
|
|
30
|
+
|
|
31
|
+
super(object_name, method_name, template_object, options)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
def instantiate_builder(builder_class, item, value, text, html_options)
|
|
37
|
+
builder_class.new(@template_object, @object_name, @method_name, item,
|
|
38
|
+
sanitize_attribute_name(value), text, value, html_options)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Generate default options for collection helpers, such as :checked and
|
|
42
|
+
# :disabled.
|
|
43
|
+
def default_html_options_for_collection(item, value) #:nodoc:
|
|
44
|
+
html_options = @html_options.dup
|
|
45
|
+
|
|
46
|
+
[:checked, :selected, :disabled].each do |option|
|
|
47
|
+
current_value = @options[option]
|
|
48
|
+
next if current_value.nil?
|
|
49
|
+
|
|
50
|
+
accept = if current_value.respond_to?(:call)
|
|
51
|
+
current_value.call(item)
|
|
52
|
+
else
|
|
53
|
+
Array(current_value).map(&:to_s).include?(value.to_s)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
if accept
|
|
57
|
+
html_options[option] = true
|
|
58
|
+
elsif option == :checked
|
|
59
|
+
html_options[option] = false
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
html_options[:object] = @object
|
|
64
|
+
html_options
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def sanitize_attribute_name(value) #:nodoc:
|
|
68
|
+
"#{sanitized_method_name}_#{sanitized_value(value)}"
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def render_collection #:nodoc:
|
|
72
|
+
@collection.map do |item|
|
|
73
|
+
value = value_for_collection(item, @value_method)
|
|
74
|
+
text = value_for_collection(item, @text_method)
|
|
75
|
+
default_html_options = default_html_options_for_collection(item, value)
|
|
76
|
+
|
|
77
|
+
yield item, value, text, default_html_options
|
|
78
|
+
end.join.html_safe
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|