actionpack 3.2.22.5 → 4.0.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 actionpack might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +641 -418
- data/MIT-LICENSE +1 -1
- data/README.rdoc +5 -288
- data/lib/abstract_controller.rb +1 -8
- 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 +23 -11
- data/lib/abstract_controller/layouts.rb +68 -73
- data/lib/abstract_controller/logger.rb +1 -2
- data/lib/abstract_controller/rendering.rb +22 -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/action_controller.rb +15 -6
- data/lib/action_controller/base.rb +46 -22
- data/lib/action_controller/caching.rb +46 -33
- data/lib/action_controller/caching/fragments.rb +23 -53
- data/lib/action_controller/deprecated.rb +5 -1
- data/lib/action_controller/deprecated/integration_test.rb +3 -0
- data/lib/action_controller/log_subscriber.rb +11 -8
- data/lib/action_controller/metal.rb +16 -30
- 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 +32 -9
- data/lib/action_controller/metal/head.rb +25 -4
- data/lib/action_controller/metal/helpers.rb +6 -9
- data/lib/action_controller/metal/hide_actions.rb +1 -2
- data/lib/action_controller/metal/http_authentication.rb +105 -87
- 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 +141 -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 +8 -0
- 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 +516 -0
- data/lib/action_controller/metal/testing.rb +13 -18
- data/lib/action_controller/metal/url_for.rb +27 -25
- 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 +215 -123
- data/lib/action_controller/vendor/html-scanner.rb +4 -19
- data/lib/action_dispatch.rb +27 -19
- 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 +27 -19
- data/lib/action_dispatch/http/mime_negotiation.rb +25 -2
- data/lib/action_dispatch/http/mime_type.rb +145 -113
- 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 +12 -5
- data/lib/action_dispatch/http/rack_cache.rb +2 -3
- data/lib/action_dispatch/http/request.rb +49 -18
- data/lib/action_dispatch/http/response.rb +129 -35
- data/lib/action_dispatch/http/upload.rb +60 -17
- data/lib/action_dispatch/http/url.rb +53 -31
- data/lib/action_dispatch/journey.rb +5 -0
- 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 +116 -0
- data/lib/action_dispatch/journey/router.rb +164 -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/routes.rb +75 -0
- data/lib/action_dispatch/journey/scanner.rb +61 -0
- data/lib/action_dispatch/journey/visitors.rb +189 -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/middleware/callbacks.rb +9 -4
- data/lib/action_dispatch/middleware/cookies.rb +168 -57
- data/lib/action_dispatch/middleware/debug_exceptions.rb +26 -17
- data/lib/action_dispatch/middleware/exception_wrapper.rb +27 -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 +31 -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/cache_store.rb +3 -3
- data/lib/action_dispatch/middleware/session/cookie_store.rb +81 -7
- 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 +5 -24
- 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 +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +15 -9
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +121 -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.rb +41 -40
- data/lib/action_dispatch/routing/inspector.rb +240 -0
- data/lib/action_dispatch/routing/mapper.rb +501 -273
- 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 +203 -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/testing/assertions/dom.rb +3 -13
- data/lib/action_dispatch/testing/assertions/response.rb +32 -40
- data/lib/action_dispatch/testing/assertions/routing.rb +40 -39
- data/lib/action_dispatch/testing/assertions/selector.rb +15 -20
- data/lib/action_dispatch/testing/assertions/tag.rb +20 -23
- data/lib/action_dispatch/testing/integration.rb +41 -22
- data/lib/action_dispatch/testing/test_process.rb +9 -6
- data/lib/action_dispatch/testing/test_request.rb +7 -3
- data/lib/action_pack.rb +1 -1
- data/lib/action_pack/version.rb +4 -4
- data/lib/action_view.rb +17 -8
- data/lib/action_view/base.rb +15 -34
- data/lib/action_view/buffers.rb +1 -1
- data/lib/action_view/context.rb +4 -4
- data/lib/action_view/dependency_tracker.rb +91 -0
- data/lib/action_view/digestor.rb +85 -0
- data/lib/action_view/flows.rb +1 -4
- data/lib/action_view/helpers.rb +2 -4
- data/lib/action_view/helpers/active_model_helper.rb +3 -4
- data/lib/action_view/helpers/asset_tag_helper.rb +211 -353
- data/lib/action_view/helpers/asset_url_helper.rb +354 -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 +42 -29
- data/lib/action_view/helpers/csrf_helper.rb +0 -2
- data/lib/action_view/helpers/date_helper.rb +268 -247
- data/lib/action_view/helpers/debug_helper.rb +10 -11
- data/lib/action_view/helpers/form_helper.rb +904 -547
- data/lib/action_view/helpers/form_options_helper.rb +341 -166
- data/lib/action_view/helpers/form_tag_helper.rb +188 -88
- data/lib/action_view/helpers/javascript_helper.rb +23 -16
- data/lib/action_view/helpers/number_helper.rb +148 -354
- 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 -4
- data/lib/action_view/helpers/sanitize_helper.rb +3 -6
- data/lib/action_view/helpers/tag_helper.rb +43 -37
- data/lib/action_view/helpers/tags.rb +39 -0
- data/lib/action_view/helpers/tags/base.rb +148 -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 +41 -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/text_helper.rb +126 -113
- data/lib/action_view/helpers/translation_helper.rb +32 -16
- data/lib/action_view/helpers/url_helper.rb +200 -271
- 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 -39
- data/lib/action_view/model_naming.rb +12 -0
- data/lib/action_view/path_set.rb +9 -39
- 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 +10 -19
- data/lib/action_view/renderer/partial_renderer.rb +144 -81
- data/lib/action_view/renderer/renderer.rb +2 -19
- data/lib/action_view/renderer/streaming_template_renderer.rb +2 -5
- data/lib/action_view/renderer/template_renderer.rb +14 -13
- data/lib/action_view/routing_url_for.rb +107 -0
- data/lib/action_view/template.rb +22 -21
- data/lib/action_view/template/error.rb +22 -12
- data/lib/action_view/template/handlers.rb +12 -9
- data/lib/action_view/template/handlers/builder.rb +1 -1
- data/lib/action_view/template/handlers/erb.rb +11 -16
- data/lib/action_view/template/handlers/raw.rb +11 -0
- data/lib/action_view/template/resolver.rb +111 -83
- data/lib/action_view/template/text.rb +12 -8
- data/lib/action_view/template/types.rb +57 -0
- data/lib/action_view/test_case.rb +66 -43
- data/lib/action_view/testing/resolvers.rb +3 -2
- data/lib/action_view/vendor/html-scanner.rb +20 -0
- 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 +18 -7
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/selector.rb +1 -1
- 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
- metadata +135 -125
- 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.rb +0 -6
- data/lib/sprockets/helpers/isolated_helper.rb +0 -13
- data/lib/sprockets/helpers/rails_helper.rb +0 -182
- data/lib/sprockets/railtie.rb +0 -62
- data/lib/sprockets/static_compiler.rb +0 -56
@@ -11,7 +11,8 @@ module ActionView #:nodoc:
|
|
11
11
|
#
|
12
12
|
# For example:
|
13
13
|
#
|
14
|
-
#
|
14
|
+
# raw @user.name
|
15
|
+
# # => 'Jimmy <alert>Tables</alert>'
|
15
16
|
def raw(stringish)
|
16
17
|
stringish.to_s.html_safe
|
17
18
|
end
|
@@ -28,11 +29,10 @@ module ActionView #:nodoc:
|
|
28
29
|
# # => "<p>foo</p><br /><p>bar</p>"
|
29
30
|
#
|
30
31
|
def safe_join(array, sep=$,)
|
31
|
-
sep ||= "".html_safe
|
32
32
|
sep = ERB::Util.html_escape(sep)
|
33
33
|
|
34
34
|
array.map { |i| ERB::Util.html_escape(i) }.join(sep).html_safe
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
38
|
-
end
|
38
|
+
end
|
@@ -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
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require "active_support/core_ext/hash/indifferent_access"
|
2
|
-
|
3
1
|
module ActionView
|
4
2
|
module Helpers
|
5
3
|
# = Action View Rendering
|
@@ -41,7 +39,7 @@ module ActionView
|
|
41
39
|
# The user can override this default by passing a block to the layout:
|
42
40
|
#
|
43
41
|
# # The template
|
44
|
-
# <%= render :
|
42
|
+
# <%= render layout: "my_layout" do %>
|
45
43
|
# Content
|
46
44
|
# <% end %>
|
47
45
|
#
|
@@ -61,7 +59,7 @@ module ActionView
|
|
61
59
|
# Finally, the block can take block arguments, which can be passed in by +yield+:
|
62
60
|
#
|
63
61
|
# # The template
|
64
|
-
# <%= render :
|
62
|
+
# <%= render layout: "my_layout" do |customer| %>
|
65
63
|
# Hello <%= customer.name %>
|
66
64
|
# <% end %>
|
67
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
|
|
@@ -10,12 +9,11 @@ module ActionView
|
|
10
9
|
module TagHelper
|
11
10
|
extend ActiveSupport::Concern
|
12
11
|
include CaptureHelper
|
13
|
-
include OutputSafetyHelper
|
14
12
|
|
15
13
|
BOOLEAN_ATTRIBUTES = %w(disabled readonly multiple checked autobuffer
|
16
14
|
autoplay controls loop selected hidden scoped async
|
17
15
|
defer reversed ismap seemless muted required
|
18
|
-
autofocus novalidate formnovalidate open pubdate).to_set
|
16
|
+
autofocus novalidate formnovalidate open pubdate itemscope).to_set
|
19
17
|
BOOLEAN_ATTRIBUTES.merge(BOOLEAN_ATTRIBUTES.map {|attribute| attribute.to_sym })
|
20
18
|
|
21
19
|
PRE_CONTENT_STRINGS = {
|
@@ -42,7 +40,7 @@ module ActionView
|
|
42
40
|
# thus accessed as <tt>dataset.userId</tt>.
|
43
41
|
#
|
44
42
|
# Values are encoded to JSON, with the exception of strings and symbols.
|
45
|
-
# 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>
|
46
44
|
# from 1.4.3.
|
47
45
|
#
|
48
46
|
# ==== Examples
|
@@ -52,16 +50,16 @@ module ActionView
|
|
52
50
|
# tag("br", nil, true)
|
53
51
|
# # => <br>
|
54
52
|
#
|
55
|
-
# tag("input", :
|
53
|
+
# tag("input", type: 'text', disabled: true)
|
56
54
|
# # => <input type="text" disabled="disabled" />
|
57
55
|
#
|
58
|
-
# tag("img", :
|
56
|
+
# tag("img", src: "open & shut.png")
|
59
57
|
# # => <img src="open & shut.png" />
|
60
58
|
#
|
61
|
-
# tag("img", {:
|
59
|
+
# tag("img", {src: "open & shut.png"}, false, false)
|
62
60
|
# # => <img src="open & shut.png" />
|
63
61
|
#
|
64
|
-
# tag("div", :
|
62
|
+
# tag("div", data: {name: 'Stephen', city_state: %w(Chicago IL)})
|
65
63
|
# # => <div data-name="Stephen" data-city-state="["Chicago","IL"]" />
|
66
64
|
def tag(name, options = nil, open = false, escape = true)
|
67
65
|
"<#{name}#{tag_options(options, escape) if options}#{open ? ">" : " />"}".html_safe
|
@@ -81,12 +79,12 @@ module ActionView
|
|
81
79
|
# ==== Examples
|
82
80
|
# content_tag(:p, "Hello world!")
|
83
81
|
# # => <p>Hello world!</p>
|
84
|
-
# content_tag(:div, content_tag(:p, "Hello world!"), :
|
82
|
+
# content_tag(:div, content_tag(:p, "Hello world!"), class: "strong")
|
85
83
|
# # => <div class="strong"><p>Hello world!</p></div>
|
86
|
-
# content_tag("select", options, :
|
84
|
+
# content_tag("select", options, multiple: true)
|
87
85
|
# # => <select multiple="multiple">...options...</select>
|
88
86
|
#
|
89
|
-
# <%= content_tag :div, :
|
87
|
+
# <%= content_tag :div, class: "strong" do -%>
|
90
88
|
# Hello world!
|
91
89
|
# <% end -%>
|
92
90
|
# # => <div class="strong">Hello world!</div>
|
@@ -104,63 +102,71 @@ module ActionView
|
|
104
102
|
# otherwise be recognized as markup. CDATA sections begin with the string
|
105
103
|
# <tt><![CDATA[</tt> and end with (and may not contain) the string <tt>]]></tt>.
|
106
104
|
#
|
107
|
-
# ==== Examples
|
108
105
|
# cdata_section("<hello world>")
|
109
106
|
# # => <![CDATA[<hello world>]]>
|
110
107
|
#
|
111
108
|
# cdata_section(File.read("hello_world.txt"))
|
112
109
|
# # => <![CDATA[<hello from a text file]]>
|
110
|
+
#
|
111
|
+
# cdata_section("hello]]>world")
|
112
|
+
# # => <![CDATA[hello]]]]><![CDATA[>world]]>
|
113
113
|
def cdata_section(content)
|
114
|
-
|
114
|
+
splitted = content.gsub(']]>', ']]]]><![CDATA[>')
|
115
|
+
"<![CDATA[#{splitted}]]>".html_safe
|
115
116
|
end
|
116
117
|
|
117
118
|
# Returns an escaped version of +html+ without affecting existing escaped entities.
|
118
119
|
#
|
119
|
-
# ==== Examples
|
120
120
|
# escape_once("1 < 2 & 3")
|
121
121
|
# # => "1 < 2 & 3"
|
122
122
|
#
|
123
123
|
# escape_once("<< Accept & Checkout")
|
124
124
|
# # => "<< Accept & Checkout"
|
125
125
|
def escape_once(html)
|
126
|
-
|
126
|
+
ERB::Util.html_escape_once(html)
|
127
127
|
end
|
128
128
|
|
129
129
|
private
|
130
130
|
|
131
131
|
def content_tag_string(name, content, options, escape = true)
|
132
132
|
tag_options = tag_options(options, escape) if options
|
133
|
-
|
133
|
+
content = ERB::Util.h(content) if escape
|
134
|
+
"<#{name}#{tag_options}>#{PRE_CONTENT_STRINGS[name.to_sym]}#{content}</#{name}>".html_safe
|
134
135
|
end
|
135
136
|
|
136
137
|
def tag_options(options, escape = true)
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
v = v.to_json
|
144
|
-
end
|
145
|
-
attrs << tag_option("data-#{k.to_s.dasherize}", v, escape)
|
146
|
-
end
|
147
|
-
elsif BOOLEAN_ATTRIBUTES.include?(key)
|
148
|
-
attrs << %(#{key}="#{key}") if value
|
149
|
-
elsif !value.nil?
|
150
|
-
attrs << tag_option(key, value, escape)
|
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)
|
151
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)
|
152
149
|
end
|
153
|
-
" #{attrs.sort * ' '}".html_safe unless attrs.empty?
|
154
150
|
end
|
151
|
+
" #{attrs.sort * ' '}".html_safe unless attrs.empty?
|
155
152
|
end
|
156
153
|
|
157
|
-
def
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
value = escape ? ERB::Util.html_escape(value) : value.to_s
|
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
|
162
158
|
end
|
163
|
-
|
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}")
|
164
170
|
end
|
165
171
|
end
|
166
172
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module ActionView
|
2
|
+
module Helpers
|
3
|
+
module Tags #:nodoc:
|
4
|
+
extend ActiveSupport::Autoload
|
5
|
+
|
6
|
+
autoload :Base
|
7
|
+
autoload :CheckBox
|
8
|
+
autoload :CollectionCheckBoxes
|
9
|
+
autoload :CollectionRadioButtons
|
10
|
+
autoload :CollectionSelect
|
11
|
+
autoload :ColorField
|
12
|
+
autoload :DateField
|
13
|
+
autoload :DateSelect
|
14
|
+
autoload :DatetimeField
|
15
|
+
autoload :DatetimeLocalField
|
16
|
+
autoload :DatetimeSelect
|
17
|
+
autoload :EmailField
|
18
|
+
autoload :FileField
|
19
|
+
autoload :GroupedCollectionSelect
|
20
|
+
autoload :HiddenField
|
21
|
+
autoload :Label
|
22
|
+
autoload :MonthField
|
23
|
+
autoload :NumberField
|
24
|
+
autoload :PasswordField
|
25
|
+
autoload :RadioButton
|
26
|
+
autoload :RangeField
|
27
|
+
autoload :SearchField
|
28
|
+
autoload :Select
|
29
|
+
autoload :TelField
|
30
|
+
autoload :TextArea
|
31
|
+
autoload :TextField
|
32
|
+
autoload :TimeField
|
33
|
+
autoload :TimeSelect
|
34
|
+
autoload :TimeZoneSelect
|
35
|
+
autoload :UrlField
|
36
|
+
autoload :WeekField
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
module ActionView
|
2
|
+
module Helpers
|
3
|
+
module Tags
|
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"]) }
|
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) }
|
81
|
+
options["id"] = options.fetch("id"){ tag_id_with_index(@auto_index) }
|
82
|
+
else
|
83
|
+
options["name"] ||= options.fetch("name"){ tag_name }
|
84
|
+
options["id"] = options.fetch("id"){ tag_id }
|
85
|
+
end
|
86
|
+
|
87
|
+
options["name"] += "[]" if options["multiple"]
|
88
|
+
options["id"] = [options.delete('namespace'), options["id"]].compact.join("_").presence
|
89
|
+
end
|
90
|
+
|
91
|
+
def tag_name
|
92
|
+
"#{@object_name}[#{sanitized_method_name}]"
|
93
|
+
end
|
94
|
+
|
95
|
+
def tag_name_with_index(index)
|
96
|
+
"#{@object_name}[#{index}][#{sanitized_method_name}]"
|
97
|
+
end
|
98
|
+
|
99
|
+
def tag_id
|
100
|
+
"#{sanitized_object_name}_#{sanitized_method_name}"
|
101
|
+
end
|
102
|
+
|
103
|
+
def tag_id_with_index(index)
|
104
|
+
"#{sanitized_object_name}_#{index}_#{sanitized_method_name}"
|
105
|
+
end
|
106
|
+
|
107
|
+
def sanitized_object_name
|
108
|
+
@sanitized_object_name ||= @object_name.gsub(/\]\[|[^-a-zA-Z0-9:.]/, "_").sub(/_$/, "")
|
109
|
+
end
|
110
|
+
|
111
|
+
def sanitized_method_name
|
112
|
+
@sanitized_method_name ||= @method_name.sub(/\?$/,"")
|
113
|
+
end
|
114
|
+
|
115
|
+
def sanitized_value(value)
|
116
|
+
value.to_s.gsub(/\s/, "_").gsub(/[^-\w]/, "").downcase
|
117
|
+
end
|
118
|
+
|
119
|
+
def select_content_tag(option_tags, options, html_options)
|
120
|
+
html_options = html_options.stringify_keys
|
121
|
+
add_default_name_and_id(html_options)
|
122
|
+
options[:include_blank] ||= true unless options[:prompt] || select_not_required?(html_options)
|
123
|
+
select = content_tag("select", add_options(option_tags, options, value(object)), 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
|