eactionpack 2.1.2
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.
- data/CHANGELOG +7 -0
- data/MIT-LICENSE +21 -0
- data/README +469 -0
- data/RUNNING_UNIT_TESTS +24 -0
- data/Rakefile +146 -0
- data/install.rb +30 -0
- data/lib/action_controller.rb +79 -0
- data/lib/action_controller/assertions.rb +69 -0
- data/lib/action_controller/assertions/dom_assertions.rb +39 -0
- data/lib/action_controller/assertions/model_assertions.rb +20 -0
- data/lib/action_controller/assertions/response_assertions.rb +172 -0
- data/lib/action_controller/assertions/routing_assertions.rb +146 -0
- data/lib/action_controller/assertions/selector_assertions.rb +491 -0
- data/lib/action_controller/assertions/tag_assertions.rb +130 -0
- data/lib/action_controller/base.rb +1288 -0
- data/lib/action_controller/benchmarking.rb +94 -0
- data/lib/action_controller/caching.rb +72 -0
- data/lib/action_controller/caching/actions.rb +144 -0
- data/lib/action_controller/caching/fragments.rb +138 -0
- data/lib/action_controller/caching/pages.rb +154 -0
- data/lib/action_controller/caching/sql_cache.rb +18 -0
- data/lib/action_controller/caching/sweeping.rb +97 -0
- data/lib/action_controller/cgi_ext.rb +16 -0
- data/lib/action_controller/cgi_ext/cookie.rb +110 -0
- data/lib/action_controller/cgi_ext/query_extension.rb +22 -0
- data/lib/action_controller/cgi_ext/session.rb +73 -0
- data/lib/action_controller/cgi_ext/stdinput.rb +24 -0
- data/lib/action_controller/cgi_process.rb +223 -0
- data/lib/action_controller/components.rb +166 -0
- data/lib/action_controller/cookies.rb +96 -0
- data/lib/action_controller/dispatcher.rb +162 -0
- data/lib/action_controller/filters.rb +642 -0
- data/lib/action_controller/flash.rb +172 -0
- data/lib/action_controller/headers.rb +31 -0
- data/lib/action_controller/helpers.rb +221 -0
- data/lib/action_controller/http_authentication.rb +124 -0
- data/lib/action_controller/integration.rb +634 -0
- data/lib/action_controller/layout.rb +309 -0
- data/lib/action_controller/mime_responds.rb +173 -0
- data/lib/action_controller/mime_type.rb +186 -0
- data/lib/action_controller/mime_types.rb +20 -0
- data/lib/action_controller/polymorphic_routes.rb +191 -0
- data/lib/action_controller/record_identifier.rb +102 -0
- data/lib/action_controller/request.rb +764 -0
- data/lib/action_controller/request_forgery_protection.rb +140 -0
- data/lib/action_controller/request_profiler.rb +169 -0
- data/lib/action_controller/rescue.rb +258 -0
- data/lib/action_controller/resources.rb +572 -0
- data/lib/action_controller/response.rb +76 -0
- data/lib/action_controller/routing.rb +387 -0
- data/lib/action_controller/routing/builder.rb +203 -0
- data/lib/action_controller/routing/optimisations.rb +120 -0
- data/lib/action_controller/routing/recognition_optimisation.rb +162 -0
- data/lib/action_controller/routing/route.rb +240 -0
- data/lib/action_controller/routing/route_set.rb +436 -0
- data/lib/action_controller/routing/routing_ext.rb +46 -0
- data/lib/action_controller/routing/segments.rb +283 -0
- data/lib/action_controller/session/active_record_store.rb +340 -0
- data/lib/action_controller/session/cookie_store.rb +166 -0
- data/lib/action_controller/session/drb_server.rb +32 -0
- data/lib/action_controller/session/drb_store.rb +35 -0
- data/lib/action_controller/session/mem_cache_store.rb +98 -0
- data/lib/action_controller/session_management.rb +158 -0
- data/lib/action_controller/status_codes.rb +88 -0
- data/lib/action_controller/streaming.rb +155 -0
- data/lib/action_controller/templates/rescues/_request_and_response.erb +24 -0
- data/lib/action_controller/templates/rescues/_trace.erb +26 -0
- data/lib/action_controller/templates/rescues/diagnostics.erb +11 -0
- data/lib/action_controller/templates/rescues/layout.erb +29 -0
- data/lib/action_controller/templates/rescues/missing_template.erb +2 -0
- data/lib/action_controller/templates/rescues/routing_error.erb +10 -0
- data/lib/action_controller/templates/rescues/template_error.erb +21 -0
- data/lib/action_controller/templates/rescues/unknown_action.erb +2 -0
- data/lib/action_controller/test_case.rb +83 -0
- data/lib/action_controller/test_process.rb +526 -0
- data/lib/action_controller/url_rewriter.rb +142 -0
- data/lib/action_controller/vendor/html-scanner/html/document.rb +68 -0
- data/lib/action_controller/vendor/html-scanner/html/node.rb +537 -0
- data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +173 -0
- data/lib/action_controller/vendor/html-scanner/html/selector.rb +828 -0
- data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +105 -0
- data/lib/action_controller/vendor/html-scanner/html/version.rb +11 -0
- data/lib/action_controller/verification.rb +130 -0
- data/lib/action_pack.rb +24 -0
- data/lib/action_pack/version.rb +9 -0
- data/lib/action_view.rb +44 -0
- data/lib/action_view/base.rb +335 -0
- data/lib/action_view/helpers/active_record_helper.rb +276 -0
- data/lib/action_view/helpers/asset_tag_helper.rb +599 -0
- data/lib/action_view/helpers/atom_feed_helper.rb +143 -0
- data/lib/action_view/helpers/benchmark_helper.rb +33 -0
- data/lib/action_view/helpers/cache_helper.rb +40 -0
- data/lib/action_view/helpers/capture_helper.rb +161 -0
- data/lib/action_view/helpers/date_helper.rb +711 -0
- data/lib/action_view/helpers/debug_helper.rb +31 -0
- data/lib/action_view/helpers/form_helper.rb +767 -0
- data/lib/action_view/helpers/form_options_helper.rb +458 -0
- data/lib/action_view/helpers/form_tag_helper.rb +458 -0
- data/lib/action_view/helpers/javascript_helper.rb +148 -0
- data/lib/action_view/helpers/number_helper.rb +186 -0
- data/lib/action_view/helpers/record_identification_helper.rb +20 -0
- data/lib/action_view/helpers/record_tag_helper.rb +59 -0
- data/lib/action_view/helpers/sanitize_helper.rb +229 -0
- data/lib/action_view/helpers/tag_helper.rb +134 -0
- data/lib/action_view/helpers/text_helper.rb +507 -0
- data/lib/action_view/helpers/url_helper.rb +573 -0
- data/lib/action_view/inline_template.rb +20 -0
- data/lib/action_view/partial_template.rb +70 -0
- data/lib/action_view/partials.rb +158 -0
- data/lib/action_view/template.rb +125 -0
- data/lib/action_view/template_error.rb +110 -0
- data/lib/action_view/template_finder.rb +176 -0
- data/lib/action_view/template_handler.rb +34 -0
- data/lib/action_view/template_handlers/builder.rb +27 -0
- data/lib/action_view/template_handlers/compilable.rb +128 -0
- data/lib/action_view/template_handlers/erb.rb +56 -0
- data/lib/action_view/test_case.rb +58 -0
- data/lib/actionpack.rb +1 -0
- data/test/abstract_unit.rb +36 -0
- data/test/active_record_unit.rb +105 -0
- data/test/activerecord/active_record_store_test.rb +141 -0
- data/test/activerecord/render_partial_with_record_identification_test.rb +191 -0
- data/test/adv_attr_test.rb +20 -0
- data/test/controller/action_pack_assertions_test.rb +543 -0
- data/test/controller/addresses_render_test.rb +43 -0
- data/test/controller/assert_select_test.rb +331 -0
- data/test/controller/base_test.rb +219 -0
- data/test/controller/benchmark_test.rb +32 -0
- data/test/controller/caching_test.rb +581 -0
- data/test/controller/capture_test.rb +89 -0
- data/test/controller/cgi_test.rb +116 -0
- data/test/controller/components_test.rb +140 -0
- data/test/controller/content_type_test.rb +139 -0
- data/test/controller/controller_fixtures/app/controllers/admin/user_controller.rb +0 -0
- data/test/controller/controller_fixtures/app/controllers/user_controller.rb +0 -0
- data/test/controller/controller_fixtures/vendor/plugins/bad_plugin/lib/plugin_controller.rb +0 -0
- data/test/controller/cookie_test.rb +146 -0
- data/test/controller/custom_handler_test.rb +45 -0
- data/test/controller/deprecation/deprecated_base_methods_test.rb +37 -0
- data/test/controller/dispatcher_test.rb +105 -0
- data/test/controller/fake_controllers.rb +33 -0
- data/test/controller/fake_models.rb +11 -0
- data/test/controller/filter_params_test.rb +49 -0
- data/test/controller/filters_test.rb +881 -0
- data/test/controller/flash_test.rb +146 -0
- data/test/controller/header_test.rb +14 -0
- data/test/controller/helper_test.rb +210 -0
- data/test/controller/html-scanner/cdata_node_test.rb +15 -0
- data/test/controller/html-scanner/document_test.rb +148 -0
- data/test/controller/html-scanner/node_test.rb +89 -0
- data/test/controller/html-scanner/sanitizer_test.rb +269 -0
- data/test/controller/html-scanner/tag_node_test.rb +238 -0
- data/test/controller/html-scanner/text_node_test.rb +50 -0
- data/test/controller/html-scanner/tokenizer_test.rb +131 -0
- data/test/controller/http_authentication_test.rb +54 -0
- data/test/controller/integration_test.rb +252 -0
- data/test/controller/integration_upload_test.rb +43 -0
- data/test/controller/layout_test.rb +255 -0
- data/test/controller/mime_responds_test.rb +514 -0
- data/test/controller/mime_type_test.rb +84 -0
- data/test/controller/new_render_test.rb +843 -0
- data/test/controller/polymorphic_routes_test.rb +174 -0
- data/test/controller/record_identifier_test.rb +139 -0
- data/test/controller/redirect_test.rb +289 -0
- data/test/controller/render_test.rb +484 -0
- data/test/controller/request_forgery_protection_test.rb +305 -0
- data/test/controller/request_test.rb +928 -0
- data/test/controller/rescue_test.rb +517 -0
- data/test/controller/resources_test.rb +873 -0
- data/test/controller/routing_test.rb +2464 -0
- data/test/controller/selector_test.rb +628 -0
- data/test/controller/send_file_test.rb +138 -0
- data/test/controller/session/cookie_store_test.rb +258 -0
- data/test/controller/session/mem_cache_store_test.rb +181 -0
- data/test/controller/session_fixation_test.rb +89 -0
- data/test/controller/session_management_test.rb +178 -0
- data/test/controller/test_test.rb +695 -0
- data/test/controller/url_rewriter_test.rb +310 -0
- data/test/controller/verification_test.rb +270 -0
- data/test/controller/view_paths_test.rb +140 -0
- data/test/controller/webservice_test.rb +229 -0
- data/test/fixtures/addresses/list.erb +1 -0
- data/test/fixtures/bad_customers/_bad_customer.html.erb +1 -0
- data/test/fixtures/companies.yml +24 -0
- data/test/fixtures/company.rb +10 -0
- data/test/fixtures/content_type/render_default_content_types_for_respond_to.rhtml +1 -0
- data/test/fixtures/content_type/render_default_for_js.js.erb +1 -0
- data/test/fixtures/content_type/render_default_for_rhtml.rhtml +1 -0
- data/test/fixtures/content_type/render_default_for_rxml.rxml +1 -0
- data/test/fixtures/customers/_customer.html.erb +1 -0
- data/test/fixtures/db_definitions/sqlite.sql +49 -0
- data/test/fixtures/developer.rb +9 -0
- data/test/fixtures/developers.yml +21 -0
- data/test/fixtures/developers_projects.yml +13 -0
- data/test/fixtures/fun/games/hello_world.erb +1 -0
- data/test/fixtures/functional_caching/_partial.erb +3 -0
- data/test/fixtures/functional_caching/fragment_cached.html.erb +2 -0
- data/test/fixtures/functional_caching/html_fragment_cached_with_partial.html.erb +1 -0
- data/test/fixtures/functional_caching/js_fragment_cached_with_partial.js.rjs +1 -0
- data/test/fixtures/good_customers/_good_customer.html.erb +1 -0
- data/test/fixtures/helpers/abc_helper.rb +5 -0
- data/test/fixtures/helpers/fun/games_helper.rb +3 -0
- data/test/fixtures/helpers/fun/pdf_helper.rb +3 -0
- data/test/fixtures/layout_tests/alt/hello.rhtml +1 -0
- data/test/fixtures/layout_tests/layouts/controller_name_space/nested.rhtml +1 -0
- data/test/fixtures/layout_tests/layouts/item.rhtml +1 -0
- data/test/fixtures/layout_tests/layouts/layout_test.rhtml +1 -0
- data/test/fixtures/layout_tests/layouts/multiple_extensions.html.erb +1 -0
- data/test/fixtures/layout_tests/layouts/third_party_template_library.mab +1 -0
- data/test/fixtures/layout_tests/views/hello.rhtml +1 -0
- data/test/fixtures/layouts/block_with_layout.erb +3 -0
- data/test/fixtures/layouts/builder.builder +3 -0
- data/test/fixtures/layouts/partial_with_layout.erb +3 -0
- data/test/fixtures/layouts/standard.erb +1 -0
- data/test/fixtures/layouts/talk_from_action.erb +2 -0
- data/test/fixtures/layouts/yield.erb +2 -0
- data/test/fixtures/mascot.rb +3 -0
- data/test/fixtures/mascots.yml +4 -0
- data/test/fixtures/mascots/_mascot.html.erb +1 -0
- data/test/fixtures/multipart/binary_file +0 -0
- data/test/fixtures/multipart/boundary_problem_file +10 -0
- data/test/fixtures/multipart/bracketed_param +5 -0
- data/test/fixtures/multipart/large_text_file +10 -0
- data/test/fixtures/multipart/mixed_files +0 -0
- data/test/fixtures/multipart/mona_lisa.jpg +0 -0
- data/test/fixtures/multipart/single_parameter +5 -0
- data/test/fixtures/multipart/text_file +10 -0
- data/test/fixtures/override/test/hello_world.erb +1 -0
- data/test/fixtures/override2/layouts/test/sub.erb +1 -0
- data/test/fixtures/post_test/layouts/post.html.erb +1 -0
- data/test/fixtures/post_test/layouts/super_post.iphone.erb +1 -0
- data/test/fixtures/post_test/post/index.html.erb +1 -0
- data/test/fixtures/post_test/post/index.iphone.erb +1 -0
- data/test/fixtures/post_test/super_post/index.html.erb +1 -0
- data/test/fixtures/post_test/super_post/index.iphone.erb +1 -0
- data/test/fixtures/project.rb +3 -0
- data/test/fixtures/projects.yml +7 -0
- data/test/fixtures/public/404.html +1 -0
- data/test/fixtures/public/500.html +1 -0
- data/test/fixtures/public/images/rails.png +0 -0
- data/test/fixtures/public/javascripts/application.js +1 -0
- data/test/fixtures/public/javascripts/bank.js +1 -0
- data/test/fixtures/public/javascripts/robber.js +1 -0
- data/test/fixtures/public/javascripts/version.1.0.js +1 -0
- data/test/fixtures/public/stylesheets/bank.css +1 -0
- data/test/fixtures/public/stylesheets/robber.css +1 -0
- data/test/fixtures/public/stylesheets/version.1.0.css +1 -0
- data/test/fixtures/replies.yml +15 -0
- data/test/fixtures/reply.rb +7 -0
- data/test/fixtures/respond_to/all_types_with_layout.html.erb +1 -0
- data/test/fixtures/respond_to/custom_constant_handling_without_block.mobile.erb +1 -0
- data/test/fixtures/respond_to/iphone_with_html_response_type.html.erb +1 -0
- data/test/fixtures/respond_to/iphone_with_html_response_type.iphone.erb +1 -0
- data/test/fixtures/respond_to/layouts/missing.html.erb +1 -0
- data/test/fixtures/respond_to/layouts/standard.html.erb +1 -0
- data/test/fixtures/respond_to/layouts/standard.iphone.erb +1 -0
- data/test/fixtures/respond_to/using_defaults.html.erb +1 -0
- data/test/fixtures/respond_to/using_defaults.js.rjs +1 -0
- data/test/fixtures/respond_to/using_defaults.xml.builder +1 -0
- data/test/fixtures/respond_to/using_defaults_with_type_list.html.erb +1 -0
- data/test/fixtures/respond_to/using_defaults_with_type_list.js.rjs +1 -0
- data/test/fixtures/respond_to/using_defaults_with_type_list.xml.builder +1 -0
- data/test/fixtures/scope/test/modgreet.erb +1 -0
- data/test/fixtures/shared.html.erb +1 -0
- data/test/fixtures/symlink_parent/symlinked_layout.erb +5 -0
- data/test/fixtures/test/_customer.erb +1 -0
- data/test/fixtures/test/_customer_counter.erb +1 -0
- data/test/fixtures/test/_customer_greeting.erb +1 -0
- data/test/fixtures/test/_form.erb +1 -0
- data/test/fixtures/test/_hash_greeting.erb +1 -0
- data/test/fixtures/test/_hash_object.erb +2 -0
- data/test/fixtures/test/_hello.builder +1 -0
- data/test/fixtures/test/_labelling_form.erb +1 -0
- data/test/fixtures/test/_layout_for_partial.html.erb +3 -0
- data/test/fixtures/test/_partial.erb +1 -0
- data/test/fixtures/test/_partial.html.erb +1 -0
- data/test/fixtures/test/_partial.js.erb +1 -0
- data/test/fixtures/test/_partial_for_use_in_layout.html.erb +1 -0
- data/test/fixtures/test/_partial_only.erb +1 -0
- data/test/fixtures/test/_person.erb +2 -0
- data/test/fixtures/test/_raise.html.erb +1 -0
- data/test/fixtures/test/action_talk_to_layout.erb +2 -0
- data/test/fixtures/test/block_content_for.erb +2 -0
- data/test/fixtures/test/calling_partial_with_layout.html.erb +1 -0
- data/test/fixtures/test/capturing.erb +4 -0
- data/test/fixtures/test/content_for.erb +2 -0
- data/test/fixtures/test/content_for_concatenated.erb +3 -0
- data/test/fixtures/test/content_for_with_parameter.erb +2 -0
- data/test/fixtures/test/delete_with_js.rjs +2 -0
- data/test/fixtures/test/dot.directory/render_file_with_ivar.erb +1 -0
- data/test/fixtures/test/enum_rjs_test.rjs +6 -0
- data/test/fixtures/test/erb_content_for.erb +2 -0
- data/test/fixtures/test/formatted_html_erb.html.erb +1 -0
- data/test/fixtures/test/formatted_xml_erb.builder +1 -0
- data/test/fixtures/test/formatted_xml_erb.html.erb +1 -0
- data/test/fixtures/test/formatted_xml_erb.xml.erb +1 -0
- data/test/fixtures/test/greeting.erb +1 -0
- data/test/fixtures/test/greeting.js.rjs +1 -0
- data/test/fixtures/test/hello.builder +4 -0
- data/test/fixtures/test/hello_world.erb +1 -0
- data/test/fixtures/test/hello_world_container.builder +3 -0
- data/test/fixtures/test/hello_world_from_rxml.builder +4 -0
- data/test/fixtures/test/hello_world_with_layout_false.erb +1 -0
- data/test/fixtures/test/hello_xml_world.builder +11 -0
- data/test/fixtures/test/list.erb +1 -0
- data/test/fixtures/test/non_erb_block_content_for.builder +4 -0
- data/test/fixtures/test/potential_conflicts.erb +4 -0
- data/test/fixtures/test/render_file_from_template.html.erb +1 -0
- data/test/fixtures/test/render_file_with_ivar.erb +1 -0
- data/test/fixtures/test/render_file_with_locals.erb +1 -0
- data/test/fixtures/test/render_to_string_test.erb +1 -0
- data/test/fixtures/test/update_element_with_capture.erb +9 -0
- data/test/fixtures/test/using_layout_around_block.html.erb +1 -0
- data/test/fixtures/topic.rb +3 -0
- data/test/fixtures/topics.yml +22 -0
- data/test/fixtures/topics/_topic.html.erb +1 -0
- data/test/template/active_record_helper_test.rb +268 -0
- data/test/template/asset_tag_helper_test.rb +514 -0
- data/test/template/atom_feed_helper_test.rb +179 -0
- data/test/template/benchmark_helper_test.rb +60 -0
- data/test/template/date_helper_test.rb +1791 -0
- data/test/template/deprecated_erb_variable_test.rb +9 -0
- data/test/template/erb_util_test.rb +24 -0
- data/test/template/form_helper_test.rb +885 -0
- data/test/template/form_options_helper_test.rb +1333 -0
- data/test/template/form_tag_helper_test.rb +272 -0
- data/test/template/javascript_helper_test.rb +73 -0
- data/test/template/number_helper_test.rb +97 -0
- data/test/template/record_tag_helper_test.rb +54 -0
- data/test/template/sanitize_helper_test.rb +48 -0
- data/test/template/tag_helper_test.rb +77 -0
- data/test/template/template_finder_test.rb +73 -0
- data/test/template/template_object_test.rb +95 -0
- data/test/template/test_test.rb +56 -0
- data/test/template/text_helper_test.rb +367 -0
- data/test/template/url_helper_test.rb +544 -0
- data/test/testing_sandbox.rb +15 -0
- metadata +469 -0
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
require 'action_view/helpers/tag_helper'
|
|
2
|
+
|
|
3
|
+
module ActionView
|
|
4
|
+
module Helpers
|
|
5
|
+
# Provides functionality for working with JavaScript in your views.
|
|
6
|
+
#
|
|
7
|
+
# == Ajax, controls and visual effects
|
|
8
|
+
#
|
|
9
|
+
# * For information on using Ajax, see
|
|
10
|
+
# ActionView::Helpers::PrototypeHelper.
|
|
11
|
+
# * For information on using controls and visual effects, see
|
|
12
|
+
# ActionView::Helpers::ScriptaculousHelper.
|
|
13
|
+
#
|
|
14
|
+
# == Including the JavaScript libraries into your pages
|
|
15
|
+
#
|
|
16
|
+
# Rails includes the Prototype JavaScript framework and the Scriptaculous
|
|
17
|
+
# JavaScript controls and visual effects library. If you wish to use
|
|
18
|
+
# these libraries and their helpers (ActionView::Helpers::PrototypeHelper
|
|
19
|
+
# and ActionView::Helpers::ScriptaculousHelper), you must do one of the
|
|
20
|
+
# following:
|
|
21
|
+
#
|
|
22
|
+
# * Use <tt><%= javascript_include_tag 'prototype' %></tt>: As above, but
|
|
23
|
+
# will only include the Prototype core library, which means you are able
|
|
24
|
+
# to use all basic AJAX functionality. For the Scriptaculous-based
|
|
25
|
+
# JavaScript helpers, like visual effects, autocompletion, drag and drop
|
|
26
|
+
# and so on, you should use the method described above.
|
|
27
|
+
#
|
|
28
|
+
# For documentation on +javascript_include_tag+ see
|
|
29
|
+
# ActionView::Helpers::AssetTagHelper.
|
|
30
|
+
module JavaScriptHelper
|
|
31
|
+
# Returns a link that will trigger a JavaScript +function+ using the
|
|
32
|
+
# onclick handler and return false after the fact.
|
|
33
|
+
#
|
|
34
|
+
# The +function+ argument can be omitted in favor of an +update_page+
|
|
35
|
+
# block, which evaluates to a string when the template is rendered
|
|
36
|
+
# (instead of making an Ajax request first).
|
|
37
|
+
#
|
|
38
|
+
# Examples:
|
|
39
|
+
# link_to_function "Greeting", "alert('Hello world!')"
|
|
40
|
+
# Produces:
|
|
41
|
+
# <a onclick="alert('Hello world!'); return false;" href="#">Greeting</a>
|
|
42
|
+
#
|
|
43
|
+
# link_to_function(image_tag("delete"), "if (confirm('Really?')) do_delete()")
|
|
44
|
+
# Produces:
|
|
45
|
+
# <a onclick="if (confirm('Really?')) do_delete(); return false;" href="#">
|
|
46
|
+
# <img src="/images/delete.png?" alt="Delete"/>
|
|
47
|
+
# </a>
|
|
48
|
+
def link_to_function(name, *args, &block)
|
|
49
|
+
html_options = args.extract_options!.symbolize_keys
|
|
50
|
+
function = args[0] || ''
|
|
51
|
+
|
|
52
|
+
function = update_page(&block) if block_given?
|
|
53
|
+
content_tag(
|
|
54
|
+
"a", name,
|
|
55
|
+
html_options.merge({
|
|
56
|
+
:href => html_options[:href] || "#",
|
|
57
|
+
:onclick => (html_options[:onclick] ? "#{html_options[:onclick]}; " : "") + "#{function}; return false;"
|
|
58
|
+
})
|
|
59
|
+
)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Returns a button that'll trigger a JavaScript +function+ using the
|
|
63
|
+
# onclick handler.
|
|
64
|
+
#
|
|
65
|
+
# The +function+ argument can be omitted in favor of an +update_page+
|
|
66
|
+
# block, which evaluates to a string when the template is rendered
|
|
67
|
+
# (instead of making an Ajax request first).
|
|
68
|
+
#
|
|
69
|
+
# Examples:
|
|
70
|
+
# button_to_function "Greeting", "alert('Hello world!')"
|
|
71
|
+
# button_to_function "Delete", "if (confirm('Really?')) do_delete()"
|
|
72
|
+
def button_to_function(name, *args, &block)
|
|
73
|
+
html_options = args.extract_options!.symbolize_keys
|
|
74
|
+
function = args[0] || ''
|
|
75
|
+
|
|
76
|
+
function = update_page(&block) if block_given?
|
|
77
|
+
tag(:input, html_options.merge({
|
|
78
|
+
:type => "button", :value => name,
|
|
79
|
+
:onclick => (html_options[:onclick] ? "#{html_options[:onclick]}; " : "") + "#{function};"
|
|
80
|
+
}))
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Escape carrier returns and single and double quotes for JavaScript segments.
|
|
84
|
+
def escape_javascript(javascript)
|
|
85
|
+
(javascript || '').gsub('\\','\0\0').gsub('</','<\/').gsub(/\r\n|\n|\r/, "\\n").gsub(/["']/) { |m| "\\#{m}" }
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Returns a JavaScript tag with the +content+ inside. Example:
|
|
89
|
+
# javascript_tag "alert('All is good')"
|
|
90
|
+
#
|
|
91
|
+
# Returns:
|
|
92
|
+
# <script type="text/javascript">
|
|
93
|
+
# //<![CDATA[
|
|
94
|
+
# alert('All is good')
|
|
95
|
+
# //]]>
|
|
96
|
+
# </script>
|
|
97
|
+
#
|
|
98
|
+
# +html_options+ may be a hash of attributes for the <script> tag. Example:
|
|
99
|
+
# javascript_tag "alert('All is good')", :defer => 'defer'
|
|
100
|
+
# # => <script defer="defer" type="text/javascript">alert('All is good')</script>
|
|
101
|
+
#
|
|
102
|
+
# Instead of passing the content as an argument, you can also use a block
|
|
103
|
+
# in which case, you pass your +html_options+ as the first parameter.
|
|
104
|
+
# <% javascript_tag :defer => 'defer' do -%>
|
|
105
|
+
# alert('All is good')
|
|
106
|
+
# <% end -%>
|
|
107
|
+
def javascript_tag(content_or_options_with_block = nil, html_options = {}, &block)
|
|
108
|
+
if block_given?
|
|
109
|
+
html_options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash)
|
|
110
|
+
content = capture(&block)
|
|
111
|
+
else
|
|
112
|
+
content = content_or_options_with_block
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
javascript_tag = content_tag("script", javascript_cdata_section(content), html_options.merge(:type => Mime::JS))
|
|
116
|
+
|
|
117
|
+
if block_given? && block_is_within_action_view?(block)
|
|
118
|
+
concat(javascript_tag, block.binding)
|
|
119
|
+
else
|
|
120
|
+
javascript_tag
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def javascript_cdata_section(content) #:nodoc:
|
|
125
|
+
"\n//#{cdata_section("\n#{content}\n//")}\n"
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
protected
|
|
129
|
+
def options_for_javascript(options)
|
|
130
|
+
'{' + options.map {|k, v| "#{k}:#{v}"}.sort.join(', ') + '}'
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def array_or_string_for_javascript(option)
|
|
134
|
+
js_option = if option.kind_of?(Array)
|
|
135
|
+
"['#{option.join('\',\'')}']"
|
|
136
|
+
elsif !option.nil?
|
|
137
|
+
"'#{option}'"
|
|
138
|
+
end
|
|
139
|
+
js_option
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
private
|
|
143
|
+
def block_is_within_action_view?(block)
|
|
144
|
+
eval("defined? _erbout", block.binding)
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
module ActionView
|
|
2
|
+
module Helpers #:nodoc:
|
|
3
|
+
# Provides methods for converting numbers into formatted strings.
|
|
4
|
+
# Methods are provided for phone numbers, currency, percentage,
|
|
5
|
+
# precision, positional notation, and file size.
|
|
6
|
+
module NumberHelper
|
|
7
|
+
# Formats a +number+ into a US phone number (e.g., (555) 123-9876). You can customize the format
|
|
8
|
+
# in the +options+ hash.
|
|
9
|
+
#
|
|
10
|
+
# ==== Options
|
|
11
|
+
# * <tt>:area_code</tt> - Adds parentheses around the area code.
|
|
12
|
+
# * <tt>:delimiter</tt> - Specifies the delimiter to use (defaults to "-").
|
|
13
|
+
# * <tt>:extension</tt> - Specifies an extension to add to the end of the
|
|
14
|
+
# generated number.
|
|
15
|
+
# * <tt>:country_code</tt> - Sets the country code for the phone number.
|
|
16
|
+
#
|
|
17
|
+
# ==== Examples
|
|
18
|
+
# number_to_phone(1235551234) # => 123-555-1234
|
|
19
|
+
# number_to_phone(1235551234, :area_code => true) # => (123) 555-1234
|
|
20
|
+
# number_to_phone(1235551234, :delimiter => " ") # => 123 555 1234
|
|
21
|
+
# number_to_phone(1235551234, :area_code => true, :extension => 555) # => (123) 555-1234 x 555
|
|
22
|
+
# number_to_phone(1235551234, :country_code => 1) # => +1-123-555-1234
|
|
23
|
+
#
|
|
24
|
+
# number_to_phone(1235551234, :country_code => 1, :extension => 1343, :delimiter => ".")
|
|
25
|
+
# => +1.123.555.1234 x 1343
|
|
26
|
+
def number_to_phone(number, options = {})
|
|
27
|
+
number = number.to_s.strip unless number.nil?
|
|
28
|
+
options = options.stringify_keys
|
|
29
|
+
area_code = options["area_code"] || nil
|
|
30
|
+
delimiter = options["delimiter"] || "-"
|
|
31
|
+
extension = options["extension"].to_s.strip || nil
|
|
32
|
+
country_code = options["country_code"] || nil
|
|
33
|
+
|
|
34
|
+
begin
|
|
35
|
+
str = ""
|
|
36
|
+
str << "+#{country_code}#{delimiter}" unless country_code.blank?
|
|
37
|
+
str << if area_code
|
|
38
|
+
number.gsub!(/([0-9]{1,3})([0-9]{3})([0-9]{4}$)/,"(\\1) \\2#{delimiter}\\3")
|
|
39
|
+
else
|
|
40
|
+
number.gsub!(/([0-9]{1,3})([0-9]{3})([0-9]{4})$/,"\\1#{delimiter}\\2#{delimiter}\\3")
|
|
41
|
+
end
|
|
42
|
+
str << " x #{extension}" unless extension.blank?
|
|
43
|
+
str
|
|
44
|
+
rescue
|
|
45
|
+
number
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Formats a +number+ into a currency string (e.g., $13.65). You can customize the format
|
|
50
|
+
# in the +options+ hash.
|
|
51
|
+
#
|
|
52
|
+
# ==== Options
|
|
53
|
+
# * <tt>:precision</tt> - Sets the level of precision (defaults to 2).
|
|
54
|
+
# * <tt>:unit</tt> - Sets the denomination of the currency (defaults to "$").
|
|
55
|
+
# * <tt>:separator</tt> - Sets the separator between the units (defaults to ".").
|
|
56
|
+
# * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults to ",").
|
|
57
|
+
# * <tt>:format</tt> - Sets the format of the output string (defaults to "%u%n"). The field types are:
|
|
58
|
+
#
|
|
59
|
+
# %u The currency unit
|
|
60
|
+
# %n The number
|
|
61
|
+
#
|
|
62
|
+
# ==== Examples
|
|
63
|
+
# number_to_currency(1234567890.50) # => $1,234,567,890.50
|
|
64
|
+
# number_to_currency(1234567890.506) # => $1,234,567,890.51
|
|
65
|
+
# number_to_currency(1234567890.506, :precision => 3) # => $1,234,567,890.506
|
|
66
|
+
#
|
|
67
|
+
# number_to_currency(1234567890.50, :unit => "£", :separator => ",", :delimiter => "")
|
|
68
|
+
# # => £1234567890,50
|
|
69
|
+
# number_to_currency(1234567890.50, :unit => "£", :separator => ",", :delimiter => "", :format => "%n %u")
|
|
70
|
+
# # => 1234567890,50 £
|
|
71
|
+
def number_to_currency(number, options = {})
|
|
72
|
+
options = options.stringify_keys
|
|
73
|
+
precision = options["precision"] || 2
|
|
74
|
+
unit = options["unit"] || "$"
|
|
75
|
+
separator = precision > 0 ? options["separator"] || "." : ""
|
|
76
|
+
delimiter = options["delimiter"] || ","
|
|
77
|
+
format = options["format"] || "%u%n"
|
|
78
|
+
|
|
79
|
+
begin
|
|
80
|
+
parts = number_with_precision(number, precision).split('.')
|
|
81
|
+
format.gsub(/%n/, number_with_delimiter(parts[0], delimiter) + separator + parts[1].to_s).gsub(/%u/, unit)
|
|
82
|
+
rescue
|
|
83
|
+
number
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Formats a +number+ as a percentage string (e.g., 65%). You can customize the
|
|
88
|
+
# format in the +options+ hash.
|
|
89
|
+
#
|
|
90
|
+
# ==== Options
|
|
91
|
+
# * <tt>:precision</tt> - Sets the level of precision (defaults to 3).
|
|
92
|
+
# * <tt>:separator</tt> - Sets the separator between the units (defaults to ".").
|
|
93
|
+
#
|
|
94
|
+
# ==== Examples
|
|
95
|
+
# number_to_percentage(100) # => 100.000%
|
|
96
|
+
# number_to_percentage(100, :precision => 0) # => 100%
|
|
97
|
+
#
|
|
98
|
+
# number_to_percentage(302.24398923423, :precision => 5)
|
|
99
|
+
# # => 302.24399%
|
|
100
|
+
def number_to_percentage(number, options = {})
|
|
101
|
+
options = options.stringify_keys
|
|
102
|
+
precision = options["precision"] || 3
|
|
103
|
+
separator = options["separator"] || "."
|
|
104
|
+
|
|
105
|
+
begin
|
|
106
|
+
number = number_with_precision(number, precision)
|
|
107
|
+
parts = number.split('.')
|
|
108
|
+
if parts.at(1).nil?
|
|
109
|
+
parts[0] + "%"
|
|
110
|
+
else
|
|
111
|
+
parts[0] + separator + parts[1].to_s + "%"
|
|
112
|
+
end
|
|
113
|
+
rescue
|
|
114
|
+
number
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# Formats a +number+ with grouped thousands using +delimiter+ (e.g., 12,324). You
|
|
119
|
+
# can customize the format using optional <em>delimiter</em> and <em>separator</em> parameters.
|
|
120
|
+
#
|
|
121
|
+
# ==== Options
|
|
122
|
+
# * <tt>delimiter</tt> - Sets the thousands delimiter (defaults to ",").
|
|
123
|
+
# * <tt>separator</tt> - Sets the separator between the units (defaults to ".").
|
|
124
|
+
#
|
|
125
|
+
# ==== Examples
|
|
126
|
+
# number_with_delimiter(12345678) # => 12,345,678
|
|
127
|
+
# number_with_delimiter(12345678.05) # => 12,345,678.05
|
|
128
|
+
# number_with_delimiter(12345678, ".") # => 12.345.678
|
|
129
|
+
#
|
|
130
|
+
# number_with_delimiter(98765432.98, " ", ",")
|
|
131
|
+
# # => 98 765 432,98
|
|
132
|
+
def number_with_delimiter(number, delimiter=",", separator=".")
|
|
133
|
+
begin
|
|
134
|
+
parts = number.to_s.split('.')
|
|
135
|
+
parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{delimiter}")
|
|
136
|
+
parts.join separator
|
|
137
|
+
rescue
|
|
138
|
+
number
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# Formats a +number+ with the specified level of +precision+ (e.g., 112.32 has a precision of 2). The default
|
|
143
|
+
# level of precision is 3.
|
|
144
|
+
#
|
|
145
|
+
# ==== Examples
|
|
146
|
+
# number_with_precision(111.2345) # => 111.235
|
|
147
|
+
# number_with_precision(111.2345, 2) # => 111.23
|
|
148
|
+
# number_with_precision(13, 5) # => 13.00000
|
|
149
|
+
# number_with_precision(389.32314, 0) # => 389
|
|
150
|
+
def number_with_precision(number, precision=3)
|
|
151
|
+
"%01.#{precision}f" % ((Float(number) * (10 ** precision)).round.to_f / 10 ** precision)
|
|
152
|
+
rescue
|
|
153
|
+
number
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# Formats the bytes in +size+ into a more understandable representation
|
|
157
|
+
# (e.g., giving it 1500 yields 1.5 KB). This method is useful for
|
|
158
|
+
# reporting file sizes to users. This method returns nil if
|
|
159
|
+
# +size+ cannot be converted into a number. You can change the default
|
|
160
|
+
# precision of 1 using the precision parameter +precision+.
|
|
161
|
+
#
|
|
162
|
+
# ==== Examples
|
|
163
|
+
# number_to_human_size(123) # => 123 Bytes
|
|
164
|
+
# number_to_human_size(1234) # => 1.2 KB
|
|
165
|
+
# number_to_human_size(12345) # => 12.1 KB
|
|
166
|
+
# number_to_human_size(1234567) # => 1.2 MB
|
|
167
|
+
# number_to_human_size(1234567890) # => 1.1 GB
|
|
168
|
+
# number_to_human_size(1234567890123) # => 1.1 TB
|
|
169
|
+
# number_to_human_size(1234567, 2) # => 1.18 MB
|
|
170
|
+
# number_to_human_size(483989, 0) # => 4 MB
|
|
171
|
+
def number_to_human_size(size, precision=1)
|
|
172
|
+
size = Kernel.Float(size)
|
|
173
|
+
case
|
|
174
|
+
when size.to_i == 1; "1 Byte"
|
|
175
|
+
when size < 1.kilobyte; "%d Bytes" % size
|
|
176
|
+
when size < 1.megabyte; "%.#{precision}f KB" % (size / 1.0.kilobyte)
|
|
177
|
+
when size < 1.gigabyte; "%.#{precision}f MB" % (size / 1.0.megabyte)
|
|
178
|
+
when size < 1.terabyte; "%.#{precision}f GB" % (size / 1.0.gigabyte)
|
|
179
|
+
else "%.#{precision}f TB" % (size / 1.0.terabyte)
|
|
180
|
+
end.sub(/([0-9]\.\d*?)0+ /, '\1 ' ).sub(/\. /,' ')
|
|
181
|
+
rescue
|
|
182
|
+
nil
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module ActionView
|
|
2
|
+
module Helpers
|
|
3
|
+
module RecordIdentificationHelper
|
|
4
|
+
# See ActionController::RecordIdentifier.partial_path -- this is just a delegate to that for convenient access in the view.
|
|
5
|
+
def partial_path(*args, &block)
|
|
6
|
+
ActionController::RecordIdentifier.partial_path(*args, &block)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# See ActionController::RecordIdentifier.dom_class -- this is just a delegate to that for convenient access in the view.
|
|
10
|
+
def dom_class(*args, &block)
|
|
11
|
+
ActionController::RecordIdentifier.dom_class(*args, &block)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# See ActionController::RecordIdentifier.dom_id -- this is just a delegate to that for convenient access in the view.
|
|
15
|
+
def dom_id(*args, &block)
|
|
16
|
+
ActionController::RecordIdentifier.dom_id(*args, &block)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
module ActionView
|
|
2
|
+
module Helpers
|
|
3
|
+
module RecordTagHelper
|
|
4
|
+
# Produces a wrapper DIV element with id and class parameters that
|
|
5
|
+
# relate to the specified Active Record object. Usage example:
|
|
6
|
+
#
|
|
7
|
+
# <% div_for(@person, :class => "foo") do %>
|
|
8
|
+
# <%=h @person.name %>
|
|
9
|
+
# <% end %>
|
|
10
|
+
#
|
|
11
|
+
# produces:
|
|
12
|
+
#
|
|
13
|
+
# <div id="person_123" class="person foo"> Joe Bloggs </div>
|
|
14
|
+
#
|
|
15
|
+
def div_for(record, *args, &block)
|
|
16
|
+
content_tag_for(:div, record, *args, &block)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# content_tag_for creates an HTML element with id and class parameters
|
|
20
|
+
# that relate to the specified Active Record object. For example:
|
|
21
|
+
#
|
|
22
|
+
# <% content_tag_for(:tr, @person) do %>
|
|
23
|
+
# <td><%=h @person.first_name %></td>
|
|
24
|
+
# <td><%=h @person.last_name %></td>
|
|
25
|
+
# <% end %>
|
|
26
|
+
#
|
|
27
|
+
# would produce the following HTML (assuming @person is an instance of
|
|
28
|
+
# a Person object, with an id value of 123):
|
|
29
|
+
#
|
|
30
|
+
# <tr id="person_123" class="person">....</tr>
|
|
31
|
+
#
|
|
32
|
+
# If you require the HTML id attribute to have a prefix, you can specify it:
|
|
33
|
+
#
|
|
34
|
+
# <% content_tag_for(:tr, @person, :foo) do %> ...
|
|
35
|
+
#
|
|
36
|
+
# produces:
|
|
37
|
+
#
|
|
38
|
+
# <tr id="foo_person_123" class="person">...
|
|
39
|
+
#
|
|
40
|
+
# content_tag_for also accepts a hash of options, which will be converted to
|
|
41
|
+
# additional HTML attributes. If you specify a <tt>:class</tt> value, it will be combined
|
|
42
|
+
# with the default class name for your object. For example:
|
|
43
|
+
#
|
|
44
|
+
# <% content_tag_for(:li, @person, :class => "bar") %>...
|
|
45
|
+
#
|
|
46
|
+
# produces:
|
|
47
|
+
#
|
|
48
|
+
# <li id="person_123" class="person bar">...
|
|
49
|
+
#
|
|
50
|
+
def content_tag_for(tag_name, record, *args, &block)
|
|
51
|
+
prefix = args.first.is_a?(Hash) ? nil : args.shift
|
|
52
|
+
options = args.first.is_a?(Hash) ? args.shift : {}
|
|
53
|
+
concat content_tag(tag_name, capture(&block),
|
|
54
|
+
options.merge({ :class => "#{dom_class(record)} #{options[:class]}".strip, :id => dom_id(record, prefix) })),
|
|
55
|
+
block.binding
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
require 'action_view/helpers/tag_helper'
|
|
2
|
+
require 'html/document'
|
|
3
|
+
|
|
4
|
+
module ActionView
|
|
5
|
+
module Helpers #:nodoc:
|
|
6
|
+
# The SanitizeHelper module provides a set of methods for scrubbing text of undesired HTML elements.
|
|
7
|
+
# These helper methods extend ActionView making them callable within your template files.
|
|
8
|
+
module SanitizeHelper
|
|
9
|
+
def self.included(base)
|
|
10
|
+
base.extend(ClassMethods)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# This +sanitize+ helper will html encode all tags and strip all attributes that aren't specifically allowed.
|
|
14
|
+
# It also strips href/src tags with invalid protocols, like javascript: especially. It does its best to counter any
|
|
15
|
+
# tricks that hackers may use, like throwing in unicode/ascii/hex values to get past the javascript: filters. Check out
|
|
16
|
+
# the extensive test suite.
|
|
17
|
+
#
|
|
18
|
+
# <%= sanitize @article.body %>
|
|
19
|
+
#
|
|
20
|
+
# You can add or remove tags/attributes if you want to customize it a bit. See ActionView::Base for full docs on the
|
|
21
|
+
# available options. You can add tags/attributes for single uses of +sanitize+ by passing either the <tt>:attributes</tt> or <tt>:tags</tt> options:
|
|
22
|
+
#
|
|
23
|
+
# Normal Use
|
|
24
|
+
#
|
|
25
|
+
# <%= sanitize @article.body %>
|
|
26
|
+
#
|
|
27
|
+
# Custom Use (only the mentioned tags and attributes are allowed, nothing else)
|
|
28
|
+
#
|
|
29
|
+
# <%= sanitize @article.body, :tags => %w(table tr td), :attributes => %w(id class style)
|
|
30
|
+
#
|
|
31
|
+
# Add table tags to the default allowed tags
|
|
32
|
+
#
|
|
33
|
+
# Rails::Initializer.run do |config|
|
|
34
|
+
# config.action_view.sanitized_allowed_tags = 'table', 'tr', 'td'
|
|
35
|
+
# end
|
|
36
|
+
#
|
|
37
|
+
# Remove tags to the default allowed tags
|
|
38
|
+
#
|
|
39
|
+
# Rails::Initializer.run do |config|
|
|
40
|
+
# config.after_initialize do
|
|
41
|
+
# ActionView::Base.sanitized_allowed_tags.delete 'div'
|
|
42
|
+
# end
|
|
43
|
+
# end
|
|
44
|
+
#
|
|
45
|
+
# Change allowed default attributes
|
|
46
|
+
#
|
|
47
|
+
# Rails::Initializer.run do |config|
|
|
48
|
+
# config.action_view.sanitized_allowed_attributes = 'id', 'class', 'style'
|
|
49
|
+
# end
|
|
50
|
+
#
|
|
51
|
+
# Please note that sanitizing user-provided text does not guarantee that the
|
|
52
|
+
# resulting markup is valid (conforming to a document type) or even well-formed.
|
|
53
|
+
# The output may still contain e.g. unescaped '<', '>', '&' characters and
|
|
54
|
+
# confuse browsers.
|
|
55
|
+
#
|
|
56
|
+
def sanitize(html, options = {})
|
|
57
|
+
self.class.white_list_sanitizer.sanitize(html, options)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Sanitizes a block of CSS code. Used by +sanitize+ when it comes across a style attribute.
|
|
61
|
+
def sanitize_css(style)
|
|
62
|
+
self.class.white_list_sanitizer.sanitize_css(style)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Strips all HTML tags from the +html+, including comments. This uses the
|
|
66
|
+
# html-scanner tokenizer and so its HTML parsing ability is limited by
|
|
67
|
+
# that of html-scanner.
|
|
68
|
+
#
|
|
69
|
+
# ==== Examples
|
|
70
|
+
#
|
|
71
|
+
# strip_tags("Strip <i>these</i> tags!")
|
|
72
|
+
# # => Strip these tags!
|
|
73
|
+
#
|
|
74
|
+
# strip_tags("<b>Bold</b> no more! <a href='more.html'>See more here</a>...")
|
|
75
|
+
# # => Bold no more! See more here...
|
|
76
|
+
#
|
|
77
|
+
# strip_tags("<div id='top-bar'>Welcome to my website!</div>")
|
|
78
|
+
# # => Welcome to my website!
|
|
79
|
+
def strip_tags(html)
|
|
80
|
+
self.class.full_sanitizer.sanitize(html)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Strips all link tags from +text+ leaving just the link text.
|
|
84
|
+
#
|
|
85
|
+
# ==== Examples
|
|
86
|
+
# strip_links('<a href="http://www.rubyonrails.org">Ruby on Rails</a>')
|
|
87
|
+
# # => Ruby on Rails
|
|
88
|
+
#
|
|
89
|
+
# strip_links('Please e-mail me at <a href="mailto:me@email.com">me@email.com</a>.')
|
|
90
|
+
# # => Please e-mail me at me@email.com.
|
|
91
|
+
#
|
|
92
|
+
# strip_links('Blog: <a href="http://www.myblog.com/" class="nav" target=\"_blank\">Visit</a>.')
|
|
93
|
+
# # => Blog: Visit
|
|
94
|
+
def strip_links(html)
|
|
95
|
+
self.class.link_sanitizer.sanitize(html)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
module ClassMethods #:nodoc:
|
|
99
|
+
def self.extended(base)
|
|
100
|
+
class << base
|
|
101
|
+
attr_writer :full_sanitizer, :link_sanitizer, :white_list_sanitizer
|
|
102
|
+
|
|
103
|
+
# we want these to be class methods on ActionView::Base, they'll get mattr_readers for these below.
|
|
104
|
+
helper_def = [:sanitized_protocol_separator, :sanitized_uri_attributes, :sanitized_bad_tags, :sanitized_allowed_tags,
|
|
105
|
+
:sanitized_allowed_attributes, :sanitized_allowed_css_properties, :sanitized_allowed_css_keywords,
|
|
106
|
+
:sanitized_shorthand_css_properties, :sanitized_allowed_protocols, :sanitized_protocol_separator=].collect! do |prop|
|
|
107
|
+
prop = prop.to_s
|
|
108
|
+
"def #{prop}(#{:value if prop =~ /=$/}) white_list_sanitizer.#{prop.sub /sanitized_/, ''} #{:value if prop =~ /=$/} end"
|
|
109
|
+
end.join("\n")
|
|
110
|
+
eval helper_def
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Gets the HTML::FullSanitizer instance used by +strip_tags+. Replace with
|
|
115
|
+
# any object that responds to +sanitize+.
|
|
116
|
+
#
|
|
117
|
+
# Rails::Initializer.run do |config|
|
|
118
|
+
# config.action_view.full_sanitizer = MySpecialSanitizer.new
|
|
119
|
+
# end
|
|
120
|
+
#
|
|
121
|
+
def full_sanitizer
|
|
122
|
+
@full_sanitizer ||= HTML::FullSanitizer.new
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# Gets the HTML::LinkSanitizer instance used by +strip_links+. Replace with
|
|
126
|
+
# any object that responds to +sanitize+.
|
|
127
|
+
#
|
|
128
|
+
# Rails::Initializer.run do |config|
|
|
129
|
+
# config.action_view.link_sanitizer = MySpecialSanitizer.new
|
|
130
|
+
# end
|
|
131
|
+
#
|
|
132
|
+
def link_sanitizer
|
|
133
|
+
@link_sanitizer ||= HTML::LinkSanitizer.new
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Gets the HTML::WhiteListSanitizer instance used by sanitize and +sanitize_css+.
|
|
137
|
+
# Replace with any object that responds to +sanitize+.
|
|
138
|
+
#
|
|
139
|
+
# Rails::Initializer.run do |config|
|
|
140
|
+
# config.action_view.white_list_sanitizer = MySpecialSanitizer.new
|
|
141
|
+
# end
|
|
142
|
+
#
|
|
143
|
+
def white_list_sanitizer
|
|
144
|
+
@white_list_sanitizer ||= HTML::WhiteListSanitizer.new
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# Adds valid HTML attributes that the +sanitize+ helper checks for URIs.
|
|
148
|
+
#
|
|
149
|
+
# Rails::Initializer.run do |config|
|
|
150
|
+
# config.action_view.sanitized_uri_attributes = 'lowsrc', 'target'
|
|
151
|
+
# end
|
|
152
|
+
#
|
|
153
|
+
def sanitized_uri_attributes=(attributes)
|
|
154
|
+
HTML::WhiteListSanitizer.uri_attributes.merge(attributes)
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# Adds to the Set of 'bad' tags for the +sanitize+ helper.
|
|
158
|
+
#
|
|
159
|
+
# Rails::Initializer.run do |config|
|
|
160
|
+
# config.action_view.sanitized_bad_tags = 'embed', 'object'
|
|
161
|
+
# end
|
|
162
|
+
#
|
|
163
|
+
def sanitized_bad_tags=(attributes)
|
|
164
|
+
HTML::WhiteListSanitizer.bad_tags.merge(attributes)
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
# Adds to the Set of allowed tags for the +sanitize+ helper.
|
|
168
|
+
#
|
|
169
|
+
# Rails::Initializer.run do |config|
|
|
170
|
+
# config.action_view.sanitized_allowed_tags = 'table', 'tr', 'td'
|
|
171
|
+
# end
|
|
172
|
+
#
|
|
173
|
+
def sanitized_allowed_tags=(attributes)
|
|
174
|
+
HTML::WhiteListSanitizer.allowed_tags.merge(attributes)
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# Adds to the Set of allowed HTML attributes for the +sanitize+ helper.
|
|
178
|
+
#
|
|
179
|
+
# Rails::Initializer.run do |config|
|
|
180
|
+
# config.action_view.sanitized_allowed_attributes = 'onclick', 'longdesc'
|
|
181
|
+
# end
|
|
182
|
+
#
|
|
183
|
+
def sanitized_allowed_attributes=(attributes)
|
|
184
|
+
HTML::WhiteListSanitizer.allowed_attributes.merge(attributes)
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
# Adds to the Set of allowed CSS properties for the #sanitize and +sanitize_css+ heleprs.
|
|
188
|
+
#
|
|
189
|
+
# Rails::Initializer.run do |config|
|
|
190
|
+
# config.action_view.sanitized_allowed_css_properties = 'expression'
|
|
191
|
+
# end
|
|
192
|
+
#
|
|
193
|
+
def sanitized_allowed_css_properties=(attributes)
|
|
194
|
+
HTML::WhiteListSanitizer.allowed_css_properties.merge(attributes)
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
# Adds to the Set of allowed CSS keywords for the +sanitize+ and +sanitize_css+ helpers.
|
|
198
|
+
#
|
|
199
|
+
# Rails::Initializer.run do |config|
|
|
200
|
+
# config.action_view.sanitized_allowed_css_keywords = 'expression'
|
|
201
|
+
# end
|
|
202
|
+
#
|
|
203
|
+
def sanitized_allowed_css_keywords=(attributes)
|
|
204
|
+
HTML::WhiteListSanitizer.allowed_css_keywords.merge(attributes)
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
# Adds to the Set of allowed shorthand CSS properties for the +sanitize+ and +sanitize_css+ helpers.
|
|
208
|
+
#
|
|
209
|
+
# Rails::Initializer.run do |config|
|
|
210
|
+
# config.action_view.sanitized_shorthand_css_properties = 'expression'
|
|
211
|
+
# end
|
|
212
|
+
#
|
|
213
|
+
def sanitized_shorthand_css_properties=(attributes)
|
|
214
|
+
HTML::WhiteListSanitizer.shorthand_css_properties.merge(attributes)
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
# Adds to the Set of allowed protocols for the +sanitize+ helper.
|
|
218
|
+
#
|
|
219
|
+
# Rails::Initializer.run do |config|
|
|
220
|
+
# config.action_view.sanitized_allowed_protocols = 'ssh', 'feed'
|
|
221
|
+
# end
|
|
222
|
+
#
|
|
223
|
+
def sanitized_allowed_protocols=(attributes)
|
|
224
|
+
HTML::WhiteListSanitizer.allowed_protocols.merge(attributes)
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
end
|