actionpack 2.3.18 → 3.0.0.beta
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of actionpack might be problematic. Click here for more details.
- data/CHANGELOG +15 -64
- data/README +39 -48
- data/lib/abstract_controller.rb +22 -0
- data/lib/abstract_controller/base.rb +191 -0
- data/lib/abstract_controller/callbacks.rb +113 -0
- data/lib/abstract_controller/collector.rb +30 -0
- data/lib/abstract_controller/compatibility.rb +18 -0
- data/lib/abstract_controller/helpers.rb +163 -0
- data/lib/abstract_controller/layouts.rb +413 -0
- data/lib/abstract_controller/localized_cache.rb +49 -0
- data/lib/abstract_controller/logger.rb +13 -0
- data/lib/abstract_controller/rendering.rb +238 -0
- data/lib/{action_controller → abstract_controller}/translation.rb +1 -1
- data/lib/action_controller.rb +68 -102
- data/lib/action_controller/base.rb +77 -1409
- data/lib/action_controller/caching.rb +58 -45
- data/lib/action_controller/caching/actions.rb +100 -114
- data/lib/action_controller/caching/fragments.rb +17 -19
- data/lib/action_controller/caching/pages.rb +12 -6
- data/lib/action_controller/caching/sweeping.rb +42 -0
- data/lib/action_controller/deprecated.rb +5 -0
- data/lib/action_controller/deprecated/dispatcher.rb +28 -0
- data/lib/action_controller/deprecated/integration_test.rb +2 -0
- data/lib/action_controller/deprecated/performance_test.rb +1 -0
- data/lib/action_controller/metal.rb +125 -0
- data/lib/action_controller/metal/compatibility.rb +141 -0
- data/lib/action_controller/metal/conditional_get.rb +86 -0
- data/lib/action_controller/metal/configuration.rb +28 -0
- data/lib/action_controller/metal/cookies.rb +17 -0
- data/lib/action_controller/metal/exceptions.rb +46 -0
- data/lib/action_controller/metal/flash.rb +28 -0
- data/lib/action_controller/metal/head.rb +33 -0
- data/lib/action_controller/metal/helpers.rb +116 -0
- data/lib/action_controller/metal/hide_actions.rb +50 -0
- data/lib/action_controller/{http_authentication.rb → metal/http_authentication.rb} +18 -15
- data/lib/action_controller/metal/instrumentation.rb +99 -0
- data/lib/action_controller/metal/mime_responds.rb +300 -0
- data/lib/action_controller/metal/rack_delegation.rb +35 -0
- data/lib/action_controller/metal/redirecting.rb +90 -0
- data/lib/action_controller/metal/renderers.rb +95 -0
- data/lib/action_controller/metal/rendering.rb +69 -0
- data/lib/action_controller/metal/request_forgery_protection.rb +115 -0
- data/lib/action_controller/metal/rescue.rb +13 -0
- data/lib/action_controller/metal/responder.rb +220 -0
- data/lib/action_controller/{session_management.rb → metal/session_management.rb} +5 -14
- data/lib/action_controller/{streaming.rb → metal/streaming.rb} +13 -12
- data/lib/action_controller/metal/testing.rb +42 -0
- data/lib/action_controller/metal/url_for.rb +157 -0
- data/lib/action_controller/{verification.rb → metal/verification.rb} +41 -41
- data/lib/action_controller/middleware.rb +38 -0
- data/lib/action_controller/polymorphic_routes.rb +20 -26
- data/lib/action_controller/railtie.rb +30 -0
- data/lib/action_controller/railties/subscriber.rb +63 -0
- data/lib/action_controller/record_identifier.rb +3 -16
- data/lib/action_controller/test_case.rb +156 -18
- data/lib/action_controller/url_rewriter.rb +47 -200
- data/lib/action_controller/vendor/html-scanner.rb +16 -12
- data/lib/action_controller/vendor/html-scanner/html/node.rb +1 -1
- data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +12 -9
- data/lib/action_dispatch.rb +88 -0
- data/lib/action_dispatch/http/cache.rb +123 -0
- data/lib/action_dispatch/http/filter_parameters.rb +98 -0
- data/lib/{action_controller → action_dispatch/http}/headers.rb +8 -8
- data/lib/action_dispatch/http/mime_negotiation.rb +101 -0
- data/lib/{action_controller → action_dispatch/http}/mime_type.rb +30 -11
- data/lib/{action_controller → action_dispatch/http}/mime_types.rb +5 -3
- data/lib/action_dispatch/http/parameters.rb +49 -0
- data/lib/action_dispatch/http/request.rb +223 -0
- data/lib/action_dispatch/http/response.rb +209 -0
- data/lib/action_dispatch/http/upload.rb +48 -0
- data/lib/action_dispatch/http/url.rb +129 -0
- data/lib/action_dispatch/middleware/callbacks.rb +50 -0
- data/lib/action_dispatch/middleware/cascade.rb +29 -0
- data/lib/action_dispatch/middleware/cookies.rb +216 -0
- data/lib/{action_controller → action_dispatch/middleware}/flash.rb +51 -90
- data/lib/action_dispatch/middleware/head.rb +18 -0
- data/lib/action_dispatch/middleware/params_parser.rb +78 -0
- data/lib/action_dispatch/middleware/rescue.rb +26 -0
- data/lib/action_dispatch/middleware/session/abstract_store.rb +209 -0
- data/lib/{action_controller → action_dispatch/middleware}/session/cookie_store.rb +56 -60
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +47 -0
- data/lib/action_dispatch/middleware/show_exceptions.rb +173 -0
- data/lib/{action_controller/middleware_stack.rb → action_dispatch/middleware/stack.rb} +23 -13
- data/lib/action_dispatch/middleware/static.rb +44 -0
- data/lib/{action_controller → action_dispatch/middleware}/templates/rescues/_request_and_response.erb +10 -3
- data/lib/{action_controller → action_dispatch/middleware}/templates/rescues/_trace.erb +4 -4
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +10 -0
- data/lib/{action_controller → action_dispatch/middleware}/templates/rescues/layout.erb +2 -2
- data/lib/{action_controller → action_dispatch/middleware}/templates/rescues/missing_template.erb +0 -0
- data/lib/{action_controller → action_dispatch/middleware}/templates/rescues/routing_error.erb +0 -0
- data/lib/{action_controller → action_dispatch/middleware}/templates/rescues/template_error.erb +3 -3
- data/lib/{action_controller → action_dispatch/middleware}/templates/rescues/unknown_action.erb +0 -0
- data/lib/action_dispatch/railtie.rb +15 -0
- data/lib/action_dispatch/routing.rb +217 -0
- data/lib/action_dispatch/routing/deprecated_mapper.rb +877 -0
- data/lib/action_dispatch/routing/mapper.rb +649 -0
- data/lib/action_dispatch/routing/route.rb +55 -0
- data/lib/action_dispatch/routing/route_set.rb +445 -0
- data/lib/action_dispatch/testing/assertions.rb +21 -0
- data/lib/action_dispatch/testing/assertions/dom.rb +37 -0
- data/lib/{action_controller/assertions/model_assertions.rb → action_dispatch/testing/assertions/model.rb} +2 -4
- data/lib/action_dispatch/testing/assertions/response.rb +154 -0
- data/lib/{action_controller/assertions/routing_assertions.rb → action_dispatch/testing/assertions/routing.rb} +72 -34
- data/lib/{action_controller/assertions/selector_assertions.rb → action_dispatch/testing/assertions/selector.rb} +14 -11
- data/lib/{action_controller/assertions/tag_assertions.rb → action_dispatch/testing/assertions/tag.rb} +25 -14
- data/lib/{action_controller → action_dispatch/testing}/integration.rb +173 -406
- data/lib/action_dispatch/testing/performance_test.rb +17 -0
- data/lib/action_dispatch/testing/test_process.rb +42 -0
- data/lib/action_dispatch/testing/test_request.rb +83 -0
- data/lib/action_dispatch/testing/test_response.rb +136 -0
- data/lib/action_pack/version.rb +3 -3
- data/lib/action_view.rb +29 -26
- data/lib/action_view/base.rb +101 -148
- data/lib/action_view/context.rb +44 -0
- data/lib/action_view/helpers.rb +6 -4
- data/lib/action_view/helpers/{active_record_helper.rb → active_model_helper.rb} +63 -63
- data/lib/action_view/helpers/asset_tag_helper.rb +166 -31
- data/lib/action_view/helpers/cache_helper.rb +1 -1
- data/lib/action_view/helpers/capture_helper.rb +40 -8
- data/lib/action_view/helpers/csrf_helper.rb +2 -4
- data/lib/action_view/helpers/date_helper.rb +14 -15
- data/lib/action_view/helpers/form_helper.rb +121 -24
- data/lib/action_view/helpers/form_options_helper.rb +26 -25
- data/lib/action_view/helpers/form_tag_helper.rb +42 -33
- data/lib/action_view/helpers/javascript_helper.rb +1 -109
- data/lib/action_view/helpers/number_helper.rb +4 -1
- data/lib/action_view/helpers/prototype_helper.rb +75 -499
- data/lib/action_view/helpers/raw_output_helper.rb +1 -1
- data/lib/action_view/helpers/record_tag_helper.rb +3 -3
- data/lib/action_view/helpers/sanitize_helper.rb +3 -2
- data/lib/action_view/helpers/scriptaculous_helper.rb +89 -53
- data/lib/action_view/helpers/tag_helper.rb +12 -13
- data/lib/action_view/helpers/text_helper.rb +33 -38
- data/lib/action_view/helpers/translation_helper.rb +11 -35
- data/lib/action_view/helpers/url_helper.rb +140 -134
- data/lib/action_view/locale/en.yml +34 -28
- data/lib/action_view/paths.rb +27 -24
- data/lib/action_view/railtie.rb +17 -0
- data/lib/action_view/railties/subscriber.rb +24 -0
- data/lib/action_view/{partials.rb → render/partials.rb} +161 -51
- data/lib/action_view/render/rendering.rb +117 -0
- data/lib/action_view/template.rb +88 -217
- data/lib/action_view/template/error.rb +105 -0
- data/lib/action_view/template/handler.rb +41 -0
- data/lib/action_view/template/handlers.rb +54 -0
- data/lib/action_view/{template_handlers → template/handlers}/builder.rb +6 -6
- data/lib/action_view/template/handlers/erb.rb +58 -0
- data/lib/action_view/{template_handlers → template/handlers}/rjs.rb +8 -3
- data/lib/action_view/template/resolver.rb +164 -0
- data/lib/action_view/template/text.rb +40 -0
- data/lib/action_view/test_case.rb +18 -18
- metadata +165 -420
- data/RUNNING_UNIT_TESTS +0 -24
- data/Rakefile +0 -158
- data/install.rb +0 -30
- data/lib/action_controller/assertions/dom_assertions.rb +0 -55
- data/lib/action_controller/assertions/response_assertions.rb +0 -169
- data/lib/action_controller/benchmarking.rb +0 -107
- data/lib/action_controller/caching/sweeper.rb +0 -45
- data/lib/action_controller/cgi_ext.rb +0 -15
- data/lib/action_controller/cgi_ext/cookie.rb +0 -112
- data/lib/action_controller/cgi_ext/query_extension.rb +0 -22
- data/lib/action_controller/cgi_ext/stdinput.rb +0 -24
- data/lib/action_controller/cgi_process.rb +0 -77
- data/lib/action_controller/cookies.rb +0 -197
- data/lib/action_controller/dispatcher.rb +0 -133
- data/lib/action_controller/failsafe.rb +0 -87
- data/lib/action_controller/filters.rb +0 -680
- data/lib/action_controller/helpers.rb +0 -225
- data/lib/action_controller/layout.rb +0 -286
- data/lib/action_controller/middlewares.rb +0 -14
- data/lib/action_controller/mime_responds.rb +0 -193
- data/lib/action_controller/params_parser.rb +0 -77
- data/lib/action_controller/performance_test.rb +0 -15
- data/lib/action_controller/rack_lint_patch.rb +0 -36
- data/lib/action_controller/reloader.rb +0 -54
- data/lib/action_controller/request.rb +0 -518
- data/lib/action_controller/request_forgery_protection.rb +0 -116
- data/lib/action_controller/rescue.rb +0 -183
- data/lib/action_controller/resources.rb +0 -682
- data/lib/action_controller/response.rb +0 -237
- data/lib/action_controller/routing.rb +0 -388
- data/lib/action_controller/routing/builder.rb +0 -197
- data/lib/action_controller/routing/optimisations.rb +0 -130
- data/lib/action_controller/routing/recognition_optimisation.rb +0 -167
- data/lib/action_controller/routing/route.rb +0 -265
- data/lib/action_controller/routing/route_set.rb +0 -503
- data/lib/action_controller/routing/routing_ext.rb +0 -49
- data/lib/action_controller/routing/segments.rb +0 -343
- data/lib/action_controller/session/abstract_store.rb +0 -276
- data/lib/action_controller/session/mem_cache_store.rb +0 -60
- data/lib/action_controller/status_codes.rb +0 -88
- data/lib/action_controller/string_coercion.rb +0 -29
- data/lib/action_controller/templates/rescues/diagnostics.erb +0 -11
- data/lib/action_controller/test_process.rb +0 -580
- data/lib/action_controller/uploaded_file.rb +0 -44
- data/lib/action_view/helpers/benchmark_helper.rb +0 -54
- data/lib/action_view/inline_template.rb +0 -19
- data/lib/action_view/reloadable_template.rb +0 -117
- data/lib/action_view/renderable.rb +0 -109
- data/lib/action_view/renderable_partial.rb +0 -53
- data/lib/action_view/template_error.rb +0 -99
- data/lib/action_view/template_handler.rb +0 -34
- data/lib/action_view/template_handlers.rb +0 -48
- data/lib/action_view/template_handlers/erb.rb +0 -25
- data/lib/actionpack.rb +0 -2
- data/test/abstract_unit.rb +0 -78
- data/test/active_record_unit.rb +0 -104
- data/test/activerecord/active_record_store_test.rb +0 -221
- data/test/activerecord/render_partial_with_record_identification_test.rb +0 -188
- data/test/adv_attr_test.rb +0 -20
- data/test/controller/action_pack_assertions_test.rb +0 -545
- data/test/controller/addresses_render_test.rb +0 -37
- data/test/controller/assert_select_test.rb +0 -735
- data/test/controller/base_test.rb +0 -217
- data/test/controller/benchmark_test.rb +0 -32
- data/test/controller/caching_test.rb +0 -743
- data/test/controller/capture_test.rb +0 -66
- data/test/controller/content_type_test.rb +0 -178
- 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 +0 -208
- data/test/controller/deprecation/deprecated_base_methods_test.rb +0 -32
- data/test/controller/dispatcher_test.rb +0 -144
- data/test/controller/dom_assertions_test.rb +0 -53
- data/test/controller/failsafe_test.rb +0 -60
- data/test/controller/fake_controllers.rb +0 -33
- data/test/controller/fake_models.rb +0 -19
- data/test/controller/filter_params_test.rb +0 -52
- data/test/controller/filters_test.rb +0 -885
- data/test/controller/flash_test.rb +0 -174
- data/test/controller/header_test.rb +0 -14
- data/test/controller/helper_test.rb +0 -224
- data/test/controller/html-scanner/cdata_node_test.rb +0 -15
- data/test/controller/html-scanner/document_test.rb +0 -148
- data/test/controller/html-scanner/node_test.rb +0 -89
- data/test/controller/html-scanner/sanitizer_test.rb +0 -300
- data/test/controller/html-scanner/tag_node_test.rb +0 -238
- data/test/controller/html-scanner/text_node_test.rb +0 -50
- data/test/controller/html-scanner/tokenizer_test.rb +0 -131
- data/test/controller/http_basic_authentication_test.rb +0 -113
- data/test/controller/http_digest_authentication_test.rb +0 -254
- data/test/controller/integration_test.rb +0 -526
- data/test/controller/layout_test.rb +0 -215
- data/test/controller/localized_templates_test.rb +0 -24
- data/test/controller/logging_test.rb +0 -46
- data/test/controller/middleware_stack_test.rb +0 -90
- data/test/controller/mime_responds_test.rb +0 -536
- data/test/controller/mime_type_test.rb +0 -93
- data/test/controller/output_escaping_test.rb +0 -19
- data/test/controller/polymorphic_routes_test.rb +0 -297
- data/test/controller/rack_test.rb +0 -308
- data/test/controller/record_identifier_test.rb +0 -139
- data/test/controller/redirect_test.rb +0 -285
- data/test/controller/reloader_test.rb +0 -125
- data/test/controller/render_test.rb +0 -1783
- data/test/controller/request/json_params_parsing_test.rb +0 -65
- data/test/controller/request/multipart_params_parsing_test.rb +0 -177
- data/test/controller/request/query_string_parsing_test.rb +0 -129
- data/test/controller/request/test_request_test.rb +0 -35
- data/test/controller/request/url_encoded_params_parsing_test.rb +0 -146
- data/test/controller/request/xml_params_parsing_test.rb +0 -103
- data/test/controller/request_forgery_protection_test.rb +0 -233
- data/test/controller/request_test.rb +0 -398
- data/test/controller/rescue_test.rb +0 -541
- data/test/controller/resources_test.rb +0 -1393
- data/test/controller/routing_test.rb +0 -2592
- data/test/controller/selector_test.rb +0 -628
- data/test/controller/send_file_test.rb +0 -171
- data/test/controller/session/abstract_store_test.rb +0 -64
- data/test/controller/session/cookie_store_test.rb +0 -354
- data/test/controller/session/mem_cache_store_test.rb +0 -187
- data/test/controller/session/test_session_test.rb +0 -58
- data/test/controller/test_test.rb +0 -700
- data/test/controller/translation_test.rb +0 -26
- data/test/controller/url_rewriter_test.rb +0 -395
- data/test/controller/verification_test.rb +0 -270
- data/test/controller/view_paths_test.rb +0 -141
- data/test/controller/webservice_test.rb +0 -273
- data/test/fixtures/_top_level_partial.html.erb +0 -1
- data/test/fixtures/_top_level_partial_only.erb +0 -1
- data/test/fixtures/addresses/list.erb +0 -1
- data/test/fixtures/alternate_helpers/foo_helper.rb +0 -3
- data/test/fixtures/bad_customers/_bad_customer.html.erb +0 -1
- data/test/fixtures/companies.yml +0 -24
- data/test/fixtures/company.rb +0 -10
- data/test/fixtures/content_type/render_default_content_types_for_respond_to.rhtml +0 -1
- data/test/fixtures/content_type/render_default_for_rhtml.rhtml +0 -1
- data/test/fixtures/content_type/render_default_for_rjs.rjs +0 -1
- data/test/fixtures/content_type/render_default_for_rxml.rxml +0 -1
- data/test/fixtures/customers/_customer.html.erb +0 -1
- data/test/fixtures/db_definitions/sqlite.sql +0 -49
- data/test/fixtures/developer.rb +0 -9
- data/test/fixtures/developers.yml +0 -21
- data/test/fixtures/developers/_developer.erb +0 -1
- data/test/fixtures/developers_projects.yml +0 -13
- data/test/fixtures/failsafe/500.html +0 -1
- data/test/fixtures/fun/games/_game.erb +0 -1
- data/test/fixtures/fun/games/hello_world.erb +0 -1
- data/test/fixtures/fun/serious/games/_game.erb +0 -1
- data/test/fixtures/functional_caching/_partial.erb +0 -3
- data/test/fixtures/functional_caching/formatted_fragment_cached.html.erb +0 -3
- data/test/fixtures/functional_caching/formatted_fragment_cached.js.rjs +0 -6
- data/test/fixtures/functional_caching/formatted_fragment_cached.xml.builder +0 -5
- data/test/fixtures/functional_caching/fragment_cached.html.erb +0 -2
- data/test/fixtures/functional_caching/html_fragment_cached_with_partial.html.erb +0 -1
- data/test/fixtures/functional_caching/inline_fragment_cached.html.erb +0 -2
- data/test/fixtures/functional_caching/js_fragment_cached_with_partial.js.rjs +0 -1
- data/test/fixtures/good_customers/_good_customer.html.erb +0 -1
- data/test/fixtures/helpers/abc_helper.rb +0 -5
- data/test/fixtures/helpers/fun/games_helper.rb +0 -3
- data/test/fixtures/helpers/fun/pdf_helper.rb +0 -3
- data/test/fixtures/layout_tests/abs_path_layout.rhtml +0 -1
- data/test/fixtures/layout_tests/alt/hello.rhtml +0 -1
- data/test/fixtures/layout_tests/alt/layouts/alt.rhtml +0 -0
- data/test/fixtures/layout_tests/layouts/controller_name_space/nested.rhtml +0 -1
- data/test/fixtures/layout_tests/layouts/item.rhtml +0 -1
- data/test/fixtures/layout_tests/layouts/layout_test.rhtml +0 -1
- data/test/fixtures/layout_tests/layouts/multiple_extensions.html.erb +0 -1
- data/test/fixtures/layout_tests/layouts/third_party_template_library.mab +0 -1
- data/test/fixtures/layout_tests/views/hello.rhtml +0 -1
- data/test/fixtures/layouts/_column.html.erb +0 -2
- data/test/fixtures/layouts/block_with_layout.erb +0 -3
- data/test/fixtures/layouts/builder.builder +0 -3
- data/test/fixtures/layouts/default_html.html.erb +0 -1
- data/test/fixtures/layouts/partial_with_layout.erb +0 -3
- data/test/fixtures/layouts/standard.erb +0 -1
- data/test/fixtures/layouts/talk_from_action.erb +0 -2
- data/test/fixtures/layouts/xhr.html.erb +0 -2
- data/test/fixtures/layouts/yield.erb +0 -2
- data/test/fixtures/localized/hello_world.de.html +0 -1
- data/test/fixtures/localized/hello_world.en.html +0 -1
- data/test/fixtures/mascot.rb +0 -3
- data/test/fixtures/mascots.yml +0 -4
- data/test/fixtures/mascots/_mascot.html.erb +0 -1
- data/test/fixtures/multipart/binary_file +0 -0
- data/test/fixtures/multipart/boundary_problem_file +0 -10
- data/test/fixtures/multipart/bracketed_param +0 -5
- data/test/fixtures/multipart/empty +0 -10
- data/test/fixtures/multipart/hello.txt +0 -1
- data/test/fixtures/multipart/large_text_file +0 -10
- data/test/fixtures/multipart/mixed_files +0 -0
- data/test/fixtures/multipart/mona_lisa.jpg +0 -0
- data/test/fixtures/multipart/none +0 -9
- data/test/fixtures/multipart/single_parameter +0 -5
- data/test/fixtures/multipart/text_file +0 -10
- data/test/fixtures/override/test/hello_world.erb +0 -1
- data/test/fixtures/override2/layouts/test/sub.erb +0 -1
- data/test/fixtures/post_test/layouts/post.html.erb +0 -1
- data/test/fixtures/post_test/layouts/super_post.iphone.erb +0 -1
- data/test/fixtures/post_test/post/index.html.erb +0 -1
- data/test/fixtures/post_test/post/index.iphone.erb +0 -1
- data/test/fixtures/post_test/super_post/index.html.erb +0 -1
- data/test/fixtures/post_test/super_post/index.iphone.erb +0 -1
- data/test/fixtures/project.rb +0 -3
- data/test/fixtures/projects.yml +0 -7
- data/test/fixtures/projects/_project.erb +0 -1
- data/test/fixtures/public/404.html +0 -1
- data/test/fixtures/public/500.da.html +0 -1
- data/test/fixtures/public/500.html +0 -1
- data/test/fixtures/public/absolute/test.css +0 -23
- data/test/fixtures/public/absolute/test.js +0 -63
- data/test/fixtures/public/images/rails.png +0 -0
- data/test/fixtures/public/javascripts/application.js +0 -1
- data/test/fixtures/public/javascripts/bank.js +0 -1
- data/test/fixtures/public/javascripts/controls.js +0 -1
- data/test/fixtures/public/javascripts/dragdrop.js +0 -1
- data/test/fixtures/public/javascripts/effects.js +0 -1
- data/test/fixtures/public/javascripts/prototype.js +0 -1
- data/test/fixtures/public/javascripts/robber.js +0 -1
- data/test/fixtures/public/javascripts/subdir/subdir.js +0 -1
- data/test/fixtures/public/javascripts/version.1.0.js +0 -1
- data/test/fixtures/public/stylesheets/bank.css +0 -1
- data/test/fixtures/public/stylesheets/robber.css +0 -1
- data/test/fixtures/public/stylesheets/subdir/subdir.css +0 -1
- data/test/fixtures/public/stylesheets/version.1.0.css +0 -1
- data/test/fixtures/quiz/questions/_question.html.erb +0 -1
- data/test/fixtures/replies.yml +0 -15
- data/test/fixtures/replies/_reply.erb +0 -1
- data/test/fixtures/reply.rb +0 -7
- data/test/fixtures/respond_to/all_types_with_layout.html.erb +0 -1
- data/test/fixtures/respond_to/all_types_with_layout.js.rjs +0 -1
- data/test/fixtures/respond_to/custom_constant_handling_without_block.mobile.erb +0 -1
- data/test/fixtures/respond_to/iphone_with_html_response_type.html.erb +0 -1
- data/test/fixtures/respond_to/iphone_with_html_response_type.iphone.erb +0 -1
- data/test/fixtures/respond_to/layouts/missing.html.erb +0 -1
- data/test/fixtures/respond_to/layouts/standard.html.erb +0 -1
- data/test/fixtures/respond_to/layouts/standard.iphone.erb +0 -1
- data/test/fixtures/respond_to/using_defaults.html.erb +0 -1
- data/test/fixtures/respond_to/using_defaults.js.rjs +0 -1
- data/test/fixtures/respond_to/using_defaults.xml.builder +0 -1
- data/test/fixtures/respond_to/using_defaults_with_type_list.html.erb +0 -1
- data/test/fixtures/respond_to/using_defaults_with_type_list.js.rjs +0 -1
- data/test/fixtures/respond_to/using_defaults_with_type_list.xml.builder +0 -1
- data/test/fixtures/scope/test/modgreet.erb +0 -1
- data/test/fixtures/session_autoload_test/session_autoload_test/foo.rb +0 -10
- data/test/fixtures/shared.html.erb +0 -1
- data/test/fixtures/symlink_parent/symlinked_layout.erb +0 -5
- data/test/fixtures/test/_counter.html.erb +0 -1
- data/test/fixtures/test/_customer.erb +0 -1
- data/test/fixtures/test/_customer_counter.erb +0 -1
- data/test/fixtures/test/_customer_counter_with_as.erb +0 -1
- data/test/fixtures/test/_customer_greeting.erb +0 -1
- data/test/fixtures/test/_customer_with_var.erb +0 -1
- data/test/fixtures/test/_form.erb +0 -1
- data/test/fixtures/test/_from_helper.erb +0 -1
- data/test/fixtures/test/_hash_greeting.erb +0 -1
- data/test/fixtures/test/_hash_object.erb +0 -2
- data/test/fixtures/test/_hello.builder +0 -1
- data/test/fixtures/test/_labelling_form.erb +0 -1
- data/test/fixtures/test/_layout_for_block_with_args.html.erb +0 -3
- data/test/fixtures/test/_layout_for_partial.html.erb +0 -3
- data/test/fixtures/test/_local_inspector.html.erb +0 -1
- data/test/fixtures/test/_one.html.erb +0 -1
- data/test/fixtures/test/_partial.erb +0 -1
- data/test/fixtures/test/_partial.html.erb +0 -1
- data/test/fixtures/test/_partial.js.erb +0 -1
- data/test/fixtures/test/_partial_for_use_in_layout.html.erb +0 -1
- data/test/fixtures/test/_partial_only.erb +0 -1
- data/test/fixtures/test/_partial_with_only_html_version.html.erb +0 -1
- data/test/fixtures/test/_person.erb +0 -2
- data/test/fixtures/test/_raise.html.erb +0 -1
- data/test/fixtures/test/_two.html.erb +0 -1
- data/test/fixtures/test/_utf8_partial.html.erb +0 -1
- data/test/fixtures/test/_utf8_partial_magic.html.erb +0 -2
- data/test/fixtures/test/action_talk_to_layout.erb +0 -2
- data/test/fixtures/test/array_translation.erb +0 -1
- data/test/fixtures/test/calling_partial_with_layout.html.erb +0 -1
- data/test/fixtures/test/capturing.erb +0 -4
- data/test/fixtures/test/content_for.erb +0 -2
- data/test/fixtures/test/content_for_concatenated.erb +0 -3
- data/test/fixtures/test/content_for_with_parameter.erb +0 -2
- data/test/fixtures/test/delete_with_js.rjs +0 -2
- data/test/fixtures/test/dont_pick_me +0 -1
- data/test/fixtures/test/dot.directory/render_file_with_ivar.erb +0 -1
- data/test/fixtures/test/enum_rjs_test.rjs +0 -6
- data/test/fixtures/test/formatted_html_erb.html.erb +0 -1
- data/test/fixtures/test/formatted_xml_erb.builder +0 -1
- data/test/fixtures/test/formatted_xml_erb.html.erb +0 -1
- data/test/fixtures/test/formatted_xml_erb.xml.erb +0 -1
- data/test/fixtures/test/greeting.erb +0 -1
- data/test/fixtures/test/greeting.js.rjs +0 -1
- data/test/fixtures/test/hello.builder +0 -4
- data/test/fixtures/test/hello_world.da.html.erb +0 -1
- data/test/fixtures/test/hello_world.erb +0 -1
- data/test/fixtures/test/hello_world.erb~ +0 -1
- data/test/fixtures/test/hello_world.pt-BR.html.erb +0 -1
- data/test/fixtures/test/hello_world_container.builder +0 -3
- data/test/fixtures/test/hello_world_from_rxml.builder +0 -4
- data/test/fixtures/test/hello_world_with_layout_false.erb +0 -1
- data/test/fixtures/test/hello_xml_world.builder +0 -11
- data/test/fixtures/test/hyphen-ated.erb +0 -1
- data/test/fixtures/test/implicit_content_type.atom.builder +0 -2
- data/test/fixtures/test/list.erb +0 -1
- data/test/fixtures/test/malformed/malformed.en.html.erb~ +0 -1
- data/test/fixtures/test/malformed/malformed.erb~ +0 -1
- data/test/fixtures/test/malformed/malformed.html.erb~ +0 -1
- data/test/fixtures/test/nested_layout.erb +0 -3
- data/test/fixtures/test/non_erb_block_content_for.builder +0 -4
- data/test/fixtures/test/potential_conflicts.erb +0 -4
- data/test/fixtures/test/render_explicit_html_template.js.rjs +0 -1
- data/test/fixtures/test/render_file_from_template.html.erb +0 -1
- data/test/fixtures/test/render_file_with_ivar.erb +0 -1
- data/test/fixtures/test/render_file_with_locals.erb +0 -1
- data/test/fixtures/test/render_implicit_html_template.js.rjs +0 -1
- data/test/fixtures/test/render_implicit_html_template_from_xhr_request.da.html.erb +0 -1
- data/test/fixtures/test/render_implicit_html_template_from_xhr_request.html.erb +0 -1
- data/test/fixtures/test/render_implicit_js_template_without_layout.js.erb +0 -1
- data/test/fixtures/test/render_to_string_test.erb +0 -1
- data/test/fixtures/test/scoped_array_translation.erb +0 -1
- data/test/fixtures/test/sub_template_raise.html.erb +0 -1
- data/test/fixtures/test/template.erb +0 -1
- data/test/fixtures/test/translation.erb +0 -1
- data/test/fixtures/test/update_element_with_capture.erb +0 -9
- data/test/fixtures/test/using_layout_around_block.html.erb +0 -1
- data/test/fixtures/test/using_layout_around_block_with_args.html.erb +0 -1
- data/test/fixtures/test/utf8.html.erb +0 -4
- data/test/fixtures/test/utf8_magic.html.erb +0 -5
- data/test/fixtures/test/utf8_magic_with_bare_partial.html.erb +0 -5
- data/test/fixtures/topic.rb +0 -3
- data/test/fixtures/topics.yml +0 -22
- data/test/fixtures/topics/_topic.html.erb +0 -1
- data/test/template/active_record_helper_i18n_test.rb +0 -51
- data/test/template/active_record_helper_test.rb +0 -302
- data/test/template/asset_tag_helper_test.rb +0 -770
- data/test/template/atom_feed_helper_test.rb +0 -315
- data/test/template/benchmark_helper_test.rb +0 -86
- data/test/template/compiled_templates_test.rb +0 -204
- data/test/template/date_helper_i18n_test.rb +0 -121
- data/test/template/date_helper_test.rb +0 -2603
- data/test/template/erb_util_test.rb +0 -36
- data/test/template/form_helper_test.rb +0 -1447
- data/test/template/form_options_helper_i18n_test.rb +0 -27
- data/test/template/form_options_helper_test.rb +0 -811
- data/test/template/form_tag_helper_test.rb +0 -356
- data/test/template/javascript_helper_test.rb +0 -106
- data/test/template/number_helper_i18n_test.rb +0 -69
- data/test/template/number_helper_test.rb +0 -132
- data/test/template/prototype_helper_test.rb +0 -639
- data/test/template/raw_output_helper_test.rb +0 -21
- data/test/template/record_tag_helper_test.rb +0 -58
- data/test/template/render_test.rb +0 -329
- data/test/template/sanitize_helper_test.rb +0 -57
- data/test/template/scriptaculous_helper_test.rb +0 -90
- data/test/template/tag_helper_test.rb +0 -98
- data/test/template/template_test.rb +0 -32
- data/test/template/test_test.rb +0 -54
- data/test/template/text_helper_test.rb +0 -601
- data/test/template/translation_helper_test.rb +0 -95
- data/test/template/url_helper_test.rb +0 -641
- data/test/testing_sandbox.rb +0 -15
- data/test/view/test_case_test.rb +0 -176
@@ -221,31 +221,31 @@ module ActionView
|
|
221
221
|
#
|
222
222
|
# In addition to the <tt>:include_blank</tt> option documented above,
|
223
223
|
# this method also supports a <tt>:model</tt> option, which defaults
|
224
|
-
# to TimeZone. This may be used by users to specify a
|
225
|
-
# zone model object. (See +time_zone_options_for_select+
|
226
|
-
# information.)
|
224
|
+
# to ActiveSupport::TimeZone. This may be used by users to specify a
|
225
|
+
# different time zone model object. (See +time_zone_options_for_select+
|
226
|
+
# for more information.)
|
227
227
|
#
|
228
|
-
# You can also supply an array of TimeZone objects
|
228
|
+
# You can also supply an array of ActiveSupport::TimeZone objects
|
229
229
|
# as +priority_zones+, so that they will be listed above the rest of the
|
230
|
-
# (long) list. (You can use TimeZone.us_zones as a convenience
|
231
|
-
# obtaining a list of the US time zones, or a Regexp to select the zones
|
230
|
+
# (long) list. (You can use ActiveSupport::TimeZone.us_zones as a convenience
|
231
|
+
# for obtaining a list of the US time zones, or a Regexp to select the zones
|
232
232
|
# of your choice)
|
233
233
|
#
|
234
234
|
# Finally, this method supports a <tt>:default</tt> option, which selects
|
235
|
-
# a default TimeZone if the object's time zone is +nil+.
|
235
|
+
# a default ActiveSupport::TimeZone if the object's time zone is +nil+.
|
236
236
|
#
|
237
237
|
# Examples:
|
238
238
|
# time_zone_select( "user", "time_zone", nil, :include_blank => true)
|
239
239
|
#
|
240
240
|
# time_zone_select( "user", "time_zone", nil, :default => "Pacific Time (US & Canada)" )
|
241
241
|
#
|
242
|
-
# time_zone_select( "user", 'time_zone', TimeZone.us_zones, :default => "Pacific Time (US & Canada)")
|
242
|
+
# time_zone_select( "user", 'time_zone', ActiveSupport::TimeZone.us_zones, :default => "Pacific Time (US & Canada)")
|
243
243
|
#
|
244
|
-
# time_zone_select( "user", 'time_zone', [ TimeZone['Alaska'], TimeZone['Hawaii'] ])
|
244
|
+
# time_zone_select( "user", 'time_zone', [ ActiveSupport::TimeZone['Alaska'], ActiveSupport::TimeZone['Hawaii'] ])
|
245
245
|
#
|
246
246
|
# time_zone_select( "user", 'time_zone', /Australia/)
|
247
247
|
#
|
248
|
-
# time_zone_select( "user", "time_zone",
|
248
|
+
# time_zone_select( "user", "time_zone", ActiveSupport::Timezone.all.sort, :model => ActiveSupport::Timezone)
|
249
249
|
def time_zone_select(object, method, priority_zones = nil, options = {}, html_options = {})
|
250
250
|
InstanceTag.new(object, method, self, options.delete(:object)).to_time_zone_select_tag(priority_zones, options, html_options)
|
251
251
|
end
|
@@ -447,20 +447,20 @@ module ActionView
|
|
447
447
|
end
|
448
448
|
|
449
449
|
# Returns a string of option tags for pretty much any time zone in the
|
450
|
-
# world. Supply a TimeZone name as +selected+ to have it
|
451
|
-
# selected option tag. You can also supply an array of
|
452
|
-
# as +priority_zones+, so that they will
|
453
|
-
# (long) list. (You can use
|
454
|
-
#
|
455
|
-
# of your choice)
|
450
|
+
# world. Supply a ActiveSupport::TimeZone name as +selected+ to have it
|
451
|
+
# marked as the selected option tag. You can also supply an array of
|
452
|
+
# ActiveSupport::TimeZone objects as +priority_zones+, so that they will
|
453
|
+
# be listed above the rest of the (long) list. (You can use
|
454
|
+
# ActiveSupport::TimeZone.us_zones as a convenience for obtaining a list
|
455
|
+
# of the US time zones, or a Regexp to select the zones of your choice)
|
456
456
|
#
|
457
457
|
# The +selected+ parameter must be either +nil+, or a string that names
|
458
|
-
# a TimeZone.
|
458
|
+
# a ActiveSupport::TimeZone.
|
459
459
|
#
|
460
|
-
# By default, +model+ is the TimeZone constant (which can
|
461
|
-
# in Active Record as a value object). The only requirement
|
462
|
-
# +model+ parameter be an object that responds to +all+, and
|
463
|
-
# an array of objects that represent time zones.
|
460
|
+
# By default, +model+ is the ActiveSupport::TimeZone constant (which can
|
461
|
+
# be obtained in Active Record as a value object). The only requirement
|
462
|
+
# is that the +model+ parameter be an object that responds to +all+, and
|
463
|
+
# returns an array of objects that represent time zones.
|
464
464
|
#
|
465
465
|
# NOTE: Only the option tags are returned, you have to wrap this call in
|
466
466
|
# a regular HTML select tag.
|
@@ -481,7 +481,7 @@ module ActionView
|
|
481
481
|
end
|
482
482
|
|
483
483
|
zone_options += options_for_select(convert_zones[zones], selected)
|
484
|
-
zone_options
|
484
|
+
zone_options
|
485
485
|
end
|
486
486
|
|
487
487
|
private
|
@@ -571,10 +571,11 @@ module ActionView
|
|
571
571
|
option_tags = "<option value=\"\">#{options[:include_blank] if options[:include_blank].kind_of?(String)}</option>\n" + option_tags
|
572
572
|
end
|
573
573
|
if value.blank? && options[:prompt]
|
574
|
-
prompt = options[:prompt].kind_of?(String) ? options[:prompt] : I18n.translate('
|
575
|
-
|
574
|
+
prompt = options[:prompt].kind_of?(String) ? options[:prompt] : I18n.translate('helpers.select.prompt', :default => 'Please select')
|
575
|
+
"<option value=\"\">#{prompt}</option>\n" + option_tags
|
576
|
+
else
|
577
|
+
option_tags
|
576
578
|
end
|
577
|
-
option_tags.html_safe
|
578
579
|
end
|
579
580
|
end
|
580
581
|
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'cgi'
|
2
2
|
require 'action_view/helpers/tag_helper'
|
3
|
+
require 'active_support/core_ext/object/returning'
|
3
4
|
|
4
5
|
module ActionView
|
5
6
|
module Helpers
|
@@ -18,6 +19,8 @@ module ActionView
|
|
18
19
|
# If "put", "delete", or another verb is used, a hidden input with name <tt>_method</tt>
|
19
20
|
# is added to simulate the verb over post.
|
20
21
|
# * A list of parameters to feed to the URL the form will be posted to.
|
22
|
+
# * <tt>:remote</tt> - If set to true, will allow the Unobtrusive JavaScript drivers to control the
|
23
|
+
# submit behaviour. By default this behaviour is an ajax submit.
|
21
24
|
#
|
22
25
|
# ==== Examples
|
23
26
|
# form_tag('/posts')
|
@@ -29,10 +32,14 @@ module ActionView
|
|
29
32
|
# form_tag('/upload', :multipart => true)
|
30
33
|
# # => <form action="/upload" method="post" enctype="multipart/form-data">
|
31
34
|
#
|
32
|
-
# <% form_tag
|
35
|
+
# <% form_tag('/posts')do -%>
|
33
36
|
# <div><%= submit_tag 'Save' %></div>
|
34
37
|
# <% end -%>
|
35
38
|
# # => <form action="/posts" method="post"><div><input type="submit" name="submit" value="Save" /></div></form>
|
39
|
+
#
|
40
|
+
# <% form_tag('/posts', :remote => true) %>
|
41
|
+
# # => <form action="/posts" method="post" data-remote="true">
|
42
|
+
#
|
36
43
|
def form_tag(url_for_options = {}, options = {}, *parameters_for_url, &block)
|
37
44
|
html_options = html_options_for_form(url_for_options, options, *parameters_for_url)
|
38
45
|
if block_given?
|
@@ -54,6 +61,9 @@ module ActionView
|
|
54
61
|
# * Any other key creates standard HTML attributes for the tag.
|
55
62
|
#
|
56
63
|
# ==== Examples
|
64
|
+
# select_tag "people", options_from_collection_for_select(@people, "name", "id")
|
65
|
+
# # <select id="people" name="people"><option value="1">David</option></select>
|
66
|
+
#
|
57
67
|
# select_tag "people", "<option>David</option>"
|
58
68
|
# # => <select id="people" name="people"><option>David</option></select>
|
59
69
|
#
|
@@ -78,8 +88,12 @@ module ActionView
|
|
78
88
|
# # <option>Paris</option><option>Rome</option></select>
|
79
89
|
def select_tag(name, option_tags = nil, options = {})
|
80
90
|
html_name = (options[:multiple] == true && !name.to_s.ends_with?("[]")) ? "#{name}[]" : name
|
81
|
-
if
|
82
|
-
|
91
|
+
if blank = options.delete(:include_blank)
|
92
|
+
if blank.kind_of?(String)
|
93
|
+
option_tags = "<option value=\"\">#{blank}</option>" + option_tags
|
94
|
+
else
|
95
|
+
option_tags = "<option value=\"\"></option>" + option_tags
|
96
|
+
end
|
83
97
|
end
|
84
98
|
content_tag :select, option_tags, { "name" => html_name, "id" => sanitize_to_id(name) }.update(options.stringify_keys)
|
85
99
|
end
|
@@ -120,7 +134,7 @@ module ActionView
|
|
120
134
|
|
121
135
|
# Creates a label field
|
122
136
|
#
|
123
|
-
# ==== Options
|
137
|
+
# ==== Options
|
124
138
|
# * Creates standard HTML attributes for the tag.
|
125
139
|
#
|
126
140
|
# ==== Examples
|
@@ -265,7 +279,7 @@ module ActionView
|
|
265
279
|
escape = options.key?("escape") ? options.delete("escape") : true
|
266
280
|
content = html_escape(content) if escape
|
267
281
|
|
268
|
-
content_tag :textarea, content
|
282
|
+
content_tag :textarea, content, { "name" => name, "id" => sanitize_to_id(name) }.update(options)
|
269
283
|
end
|
270
284
|
|
271
285
|
# Creates a check box form input tag.
|
@@ -315,9 +329,7 @@ module ActionView
|
|
315
329
|
# radio_button_tag 'color', "green", true, :class => "color_input"
|
316
330
|
# # => <input checked="checked" class="color_input" id="color_green" name="color" type="radio" value="green" />
|
317
331
|
def radio_button_tag(name, value, checked = false, options = {})
|
318
|
-
|
319
|
-
pretty_name = name.to_s.gsub(/\[/, "_").gsub(/\]/, "")
|
320
|
-
html_options = { "type" => "radio", "name" => name, "id" => "#{pretty_name}_#{pretty_tag_value}", "value" => value }.update(options.stringify_keys)
|
332
|
+
html_options = { "type" => "radio", "name" => name, "id" => "#{sanitize_to_id(name)}_#{sanitize_to_id(value)}", "value" => value }.update(options.stringify_keys)
|
321
333
|
html_options["checked"] = "checked" if checked
|
322
334
|
tag :input, html_options
|
323
335
|
end
|
@@ -325,12 +337,13 @@ module ActionView
|
|
325
337
|
# Creates a submit button with the text <tt>value</tt> as the caption.
|
326
338
|
#
|
327
339
|
# ==== Options
|
328
|
-
# * <tt>:confirm => 'question?'</tt> -
|
329
|
-
# prompt with the question specified. If the user accepts,
|
330
|
-
# processed normally, otherwise no action is taken.
|
340
|
+
# * <tt>:confirm => 'question?'</tt> - If present the unobtrusive JavaScript
|
341
|
+
# drivers will provide a prompt with the question specified. If the user accepts,
|
342
|
+
# the form is processed normally, otherwise no action is taken.
|
331
343
|
# * <tt>:disabled</tt> - If true, the user will not be able to use this input.
|
332
|
-
# * <tt>:disable_with</tt> - Value of this parameter will be used as the value for a
|
333
|
-
# of the submit button when the form is submitted.
|
344
|
+
# * <tt>:disable_with</tt> - Value of this parameter will be used as the value for a
|
345
|
+
# disabled version of the submit button when the form is submitted. This feature is
|
346
|
+
# provided by the unobtrusive JavaScript driver.
|
334
347
|
# * Any other key creates standard HTML options for the tag.
|
335
348
|
#
|
336
349
|
# ==== Examples
|
@@ -343,34 +356,31 @@ module ActionView
|
|
343
356
|
# submit_tag "Save edits", :disabled => true
|
344
357
|
# # => <input disabled="disabled" name="commit" type="submit" value="Save edits" />
|
345
358
|
#
|
359
|
+
#
|
346
360
|
# submit_tag "Complete sale", :disable_with => "Please wait..."
|
347
|
-
# # => <input name="commit"
|
361
|
+
# # => <input name="commit" data-disable-with="Please wait..."
|
348
362
|
# # type="submit" value="Complete sale" />
|
349
363
|
#
|
350
364
|
# submit_tag nil, :class => "form_submit"
|
351
365
|
# # => <input class="form_submit" name="commit" type="submit" />
|
352
366
|
#
|
353
367
|
# submit_tag "Edit", :disable_with => "Editing...", :class => "edit-button"
|
354
|
-
# # => <input class="edit-button"
|
368
|
+
# # => <input class="edit-button" data-disable_with="Editing..."
|
355
369
|
# # name="commit" type="submit" value="Edit" />
|
370
|
+
#
|
371
|
+
# submit_tag "Save", :confirm => "Are you sure?"
|
372
|
+
# # => <input name='commit' type='submit' value='Save'
|
373
|
+
# data-confirm="Are you sure?" />
|
374
|
+
#
|
356
375
|
def submit_tag(value = "Save changes", options = {})
|
357
376
|
options.stringify_keys!
|
358
377
|
|
359
378
|
if disable_with = options.delete("disable_with")
|
360
|
-
|
361
|
-
disable_with << ";#{options.delete('onclick')}" if options['onclick']
|
362
|
-
|
363
|
-
options["onclick"] = "if (window.hiddenCommit) { window.hiddenCommit.setAttribute('value', this.value); }"
|
364
|
-
options["onclick"] << "else { hiddenCommit = document.createElement('input');hiddenCommit.type = 'hidden';"
|
365
|
-
options["onclick"] << "hiddenCommit.value = this.value;hiddenCommit.name = this.name;this.form.appendChild(hiddenCommit); }"
|
366
|
-
options["onclick"] << "this.setAttribute('originalValue', this.value);this.disabled = true;#{disable_with};"
|
367
|
-
options["onclick"] << "result = (this.form.onsubmit ? (this.form.onsubmit() ? this.form.submit() : false) : this.form.submit());"
|
368
|
-
options["onclick"] << "if (result == false) { this.value = this.getAttribute('originalValue');this.disabled = false; }return result;"
|
379
|
+
options["data-disable-with"] = disable_with if disable_with
|
369
380
|
end
|
370
381
|
|
371
382
|
if confirm = options.delete("confirm")
|
372
|
-
options
|
373
|
-
options["onclick"] = "if (!#{confirm_javascript_function(confirm)}) return false; #{options['onclick']}"
|
383
|
+
add_confirm_to_attributes!(options, confirm)
|
374
384
|
end
|
375
385
|
|
376
386
|
tag :input, { "type" => "submit", "name" => "commit", "value" => value }.update(options.stringify_keys)
|
@@ -403,8 +413,7 @@ module ActionView
|
|
403
413
|
options.stringify_keys!
|
404
414
|
|
405
415
|
if confirm = options.delete("confirm")
|
406
|
-
options
|
407
|
-
options["onclick"] += "return #{confirm_javascript_function(confirm)};"
|
416
|
+
add_confirm_to_attributes!(options, confirm)
|
408
417
|
end
|
409
418
|
|
410
419
|
tag :input, { "type" => "image", "src" => path_to_image(source) }.update(options.stringify_keys)
|
@@ -415,7 +424,7 @@ module ActionView
|
|
415
424
|
# <tt>legend</tt> will become the fieldset's title (optional as per W3C).
|
416
425
|
# <tt>options</tt> accept the same values as tag.
|
417
426
|
#
|
418
|
-
#
|
427
|
+
# ==== Examples
|
419
428
|
# <% field_set_tag do %>
|
420
429
|
# <p><%= text_field_tag 'name' %></p>
|
421
430
|
# <% end %>
|
@@ -435,14 +444,15 @@ module ActionView
|
|
435
444
|
concat(tag(:fieldset, options, true))
|
436
445
|
concat(content_tag(:legend, legend)) unless legend.blank?
|
437
446
|
concat(content)
|
438
|
-
|
447
|
+
safe_concat("</fieldset>")
|
439
448
|
end
|
440
449
|
|
441
450
|
private
|
442
451
|
def html_options_for_form(url_for_options, options, *parameters_for_url)
|
443
|
-
options.stringify_keys
|
452
|
+
returning options.stringify_keys do |html_options|
|
444
453
|
html_options["enctype"] = "multipart/form-data" if html_options.delete("multipart")
|
445
454
|
html_options["action"] = url_for(url_for_options, *parameters_for_url)
|
455
|
+
html_options["data-remote"] = true if html_options.delete("remote")
|
446
456
|
end
|
447
457
|
end
|
448
458
|
|
@@ -469,7 +479,7 @@ module ActionView
|
|
469
479
|
content = capture(&block)
|
470
480
|
concat(form_tag_html(html_options))
|
471
481
|
concat(content)
|
472
|
-
|
482
|
+
safe_concat("</form>")
|
473
483
|
end
|
474
484
|
|
475
485
|
def token_tag
|
@@ -484,7 +494,6 @@ module ActionView
|
|
484
494
|
def sanitize_to_id(name)
|
485
495
|
name.to_s.gsub(']','').gsub(/[^-a-zA-Z0-9:.]/, "_")
|
486
496
|
end
|
487
|
-
|
488
497
|
end
|
489
498
|
end
|
490
499
|
end
|
@@ -35,99 +35,8 @@ module ActionView
|
|
35
35
|
# For documentation on +javascript_include_tag+ see
|
36
36
|
# ActionView::Helpers::AssetTagHelper.
|
37
37
|
module JavaScriptHelper
|
38
|
-
unless const_defined? :JAVASCRIPT_PATH
|
39
|
-
JAVASCRIPT_PATH = File.join(File.dirname(__FILE__), 'javascripts')
|
40
|
-
end
|
41
|
-
|
42
38
|
include PrototypeHelper
|
43
39
|
|
44
|
-
# Returns a link of the given +name+ that will trigger a JavaScript +function+ using the
|
45
|
-
# onclick handler and return false after the fact.
|
46
|
-
#
|
47
|
-
# The first argument +name+ is used as the link text.
|
48
|
-
#
|
49
|
-
# The next arguments are optional and may include the javascript function definition and a hash of html_options.
|
50
|
-
#
|
51
|
-
# The +function+ argument can be omitted in favor of an +update_page+
|
52
|
-
# block, which evaluates to a string when the template is rendered
|
53
|
-
# (instead of making an Ajax request first).
|
54
|
-
#
|
55
|
-
# The +html_options+ will accept a hash of html attributes for the link tag. Some examples are :class => "nav_button", :id => "articles_nav_button"
|
56
|
-
#
|
57
|
-
# Note: if you choose to specify the javascript function in a block, but would like to pass html_options, set the +function+ parameter to nil
|
58
|
-
#
|
59
|
-
#
|
60
|
-
# Examples:
|
61
|
-
# link_to_function "Greeting", "alert('Hello world!')"
|
62
|
-
# Produces:
|
63
|
-
# <a onclick="alert('Hello world!'); return false;" href="#">Greeting</a>
|
64
|
-
#
|
65
|
-
# link_to_function(image_tag("delete"), "if (confirm('Really?')) do_delete()")
|
66
|
-
# Produces:
|
67
|
-
# <a onclick="if (confirm('Really?')) do_delete(); return false;" href="#">
|
68
|
-
# <img src="/images/delete.png?" alt="Delete"/>
|
69
|
-
# </a>
|
70
|
-
#
|
71
|
-
# link_to_function("Show me more", nil, :id => "more_link") do |page|
|
72
|
-
# page[:details].visual_effect :toggle_blind
|
73
|
-
# page[:more_link].replace_html "Show me less"
|
74
|
-
# end
|
75
|
-
# Produces:
|
76
|
-
# <a href="#" id="more_link" onclick="try {
|
77
|
-
# $("details").visualEffect("toggle_blind");
|
78
|
-
# $("more_link").update("Show me less");
|
79
|
-
# }
|
80
|
-
# catch (e) {
|
81
|
-
# alert('RJS error:\n\n' + e.toString());
|
82
|
-
# alert('$(\"details\").visualEffect(\"toggle_blind\");
|
83
|
-
# \n$(\"more_link\").update(\"Show me less\");');
|
84
|
-
# throw e
|
85
|
-
# };
|
86
|
-
# return false;">Show me more</a>
|
87
|
-
#
|
88
|
-
def link_to_function(name, *args, &block)
|
89
|
-
html_options = args.extract_options!.symbolize_keys
|
90
|
-
|
91
|
-
function = block_given? ? update_page(&block) : args[0] || ''
|
92
|
-
onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function}; return false;"
|
93
|
-
href = html_options[:href] || '#'
|
94
|
-
|
95
|
-
content_tag(:a, name, html_options.merge(:href => href, :onclick => onclick))
|
96
|
-
end
|
97
|
-
|
98
|
-
# Returns a button with the given +name+ text that'll trigger a JavaScript +function+ using the
|
99
|
-
# onclick handler.
|
100
|
-
#
|
101
|
-
# The first argument +name+ is used as the button's value or display text.
|
102
|
-
#
|
103
|
-
# The next arguments are optional and may include the javascript function definition and a hash of html_options.
|
104
|
-
#
|
105
|
-
# The +function+ argument can be omitted in favor of an +update_page+
|
106
|
-
# block, which evaluates to a string when the template is rendered
|
107
|
-
# (instead of making an Ajax request first).
|
108
|
-
#
|
109
|
-
# The +html_options+ will accept a hash of html attributes for the link tag. Some examples are :class => "nav_button", :id => "articles_nav_button"
|
110
|
-
#
|
111
|
-
# Note: if you choose to specify the javascript function in a block, but would like to pass html_options, set the +function+ parameter to nil
|
112
|
-
#
|
113
|
-
# Examples:
|
114
|
-
# button_to_function "Greeting", "alert('Hello world!')"
|
115
|
-
# button_to_function "Delete", "if (confirm('Really?')) do_delete()"
|
116
|
-
# button_to_function "Details" do |page|
|
117
|
-
# page[:details].visual_effect :toggle_slide
|
118
|
-
# end
|
119
|
-
# button_to_function "Details", :class => "details_button" do |page|
|
120
|
-
# page[:details].visual_effect :toggle_slide
|
121
|
-
# end
|
122
|
-
def button_to_function(name, *args, &block)
|
123
|
-
html_options = args.extract_options!.symbolize_keys
|
124
|
-
|
125
|
-
function = block_given? ? update_page(&block) : args[0] || ''
|
126
|
-
onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function};"
|
127
|
-
|
128
|
-
tag(:input, html_options.merge(:type => 'button', :value => name, :onclick => onclick))
|
129
|
-
end
|
130
|
-
|
131
40
|
JS_ESCAPE_MAP = {
|
132
41
|
'\\' => '\\\\',
|
133
42
|
'</' => '<\/',
|
@@ -184,24 +93,7 @@ module ActionView
|
|
184
93
|
end
|
185
94
|
|
186
95
|
def javascript_cdata_section(content) #:nodoc:
|
187
|
-
"\n//#{cdata_section("\n#{content}\n//")}\n"
|
188
|
-
end
|
189
|
-
|
190
|
-
protected
|
191
|
-
def options_for_javascript(options)
|
192
|
-
if options.empty?
|
193
|
-
'{}'
|
194
|
-
else
|
195
|
-
"{#{options.keys.map { |k| "#{k}:#{options[k]}" }.sort.join(', ')}}"
|
196
|
-
end
|
197
|
-
end
|
198
|
-
|
199
|
-
def array_or_string_for_javascript(option)
|
200
|
-
if option.kind_of?(Array)
|
201
|
-
"['#{option.join('\',\'')}']"
|
202
|
-
elsif !option.nil?
|
203
|
-
"'#{option}'"
|
204
|
-
end
|
96
|
+
"\n//#{cdata_section("\n#{content}\n//")}\n"
|
205
97
|
end
|
206
98
|
end
|
207
99
|
end
|
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'active_support/core_ext/big_decimal/conversions'
|
2
|
+
require 'active_support/core_ext/float/rounding'
|
3
|
+
|
1
4
|
module ActionView
|
2
5
|
module Helpers #:nodoc:
|
3
6
|
# Provides methods for converting numbers into formatted strings.
|
@@ -213,7 +216,7 @@ module ActionView
|
|
213
216
|
delimiter ||= (options[:delimiter] || defaults[:delimiter])
|
214
217
|
|
215
218
|
begin
|
216
|
-
rounded_number = (Float(number) * (10 ** precision)).round.to_f / 10 ** precision
|
219
|
+
rounded_number = BigDecimal.new((Float(number) * (10 ** precision)).to_s).round.to_f / 10 ** precision
|
217
220
|
number_with_delimiter("%01.#{precision}f" % rounded_number,
|
218
221
|
:separator => separator,
|
219
222
|
:delimiter => delimiter)
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'set'
|
2
2
|
require 'active_support/json'
|
3
|
+
require 'active_support/core_ext/object/returning'
|
3
4
|
|
4
5
|
module ActionView
|
5
6
|
module Helpers
|
@@ -38,20 +39,6 @@ module ActionView
|
|
38
39
|
# <div><%= submit_tag 'Recalculate Shipping' %></div>
|
39
40
|
# <% end -%>
|
40
41
|
#
|
41
|
-
# ...periodically...
|
42
|
-
#
|
43
|
-
# periodically_call_remote(:url => 'update', :frequency => '5', :update => 'ticker')
|
44
|
-
#
|
45
|
-
# ...or through an observer (i.e., a form or field that is observed and calls a remote
|
46
|
-
# action when changed).
|
47
|
-
#
|
48
|
-
# <%= observe_field(:searchbox,
|
49
|
-
# :url => { :action => :live_search }),
|
50
|
-
# :frequency => 0.5,
|
51
|
-
# :update => :hits,
|
52
|
-
# :with => 'query'
|
53
|
-
# %>
|
54
|
-
#
|
55
42
|
# As you can see, there are numerous ways to use Prototype's Ajax functions (and actually more than
|
56
43
|
# are listed here); check out the documentation for each method to find out more about its usage and options.
|
57
44
|
#
|
@@ -115,323 +102,37 @@ module ActionView
|
|
115
102
|
:form, :with, :update, :script, :type ]).merge(CALLBACKS)
|
116
103
|
end
|
117
104
|
|
118
|
-
# Returns a
|
119
|
-
#
|
120
|
-
# XMLHttpRequest. The result of that request can then be inserted into a
|
121
|
-
# DOM object whose id can be specified with <tt>options[:update]</tt>.
|
122
|
-
# Usually, the result would be a partial prepared by the controller with
|
123
|
-
# render :partial.
|
105
|
+
# Returns a button with the given +name+ text that'll trigger a JavaScript +function+ using the
|
106
|
+
# onclick handler.
|
124
107
|
#
|
125
|
-
#
|
126
|
-
# # Generates: <a href="#" onclick="new Ajax.Updater('posts', '/blog/destroy/3', {asynchronous:true, evalScripts:true});
|
127
|
-
# # return false;">Delete this post</a>
|
128
|
-
# link_to_remote "Delete this post", :update => "posts",
|
129
|
-
# :url => { :action => "destroy", :id => post.id }
|
130
|
-
#
|
131
|
-
# # Generates: <a href="#" onclick="new Ajax.Updater('emails', '/mail/list_emails', {asynchronous:true, evalScripts:true});
|
132
|
-
# # return false;"><img alt="Refresh" src="/images/refresh.png?" /></a>
|
133
|
-
# link_to_remote(image_tag("refresh"), :update => "emails",
|
134
|
-
# :url => { :action => "list_emails" })
|
108
|
+
# The first argument +name+ is used as the button's value or display text.
|
135
109
|
#
|
136
|
-
#
|
137
|
-
# <tt>options[:html]</tt>.
|
110
|
+
# The next arguments are optional and may include the javascript function definition and a hash of html_options.
|
138
111
|
#
|
139
|
-
#
|
140
|
-
#
|
141
|
-
#
|
112
|
+
# The +function+ argument can be omitted in favor of an +update_page+
|
113
|
+
# block, which evaluates to a string when the template is rendered
|
114
|
+
# (instead of making an Ajax request first).
|
142
115
|
#
|
143
|
-
#
|
144
|
-
# easy redirection of output to an other DOM element if a server-side
|
145
|
-
# error occurs:
|
146
|
-
#
|
147
|
-
# Example:
|
148
|
-
# # Generates: <a href="#" onclick="new Ajax.Updater({success:'posts',failure:'error'}, '/blog/destroy/5',
|
149
|
-
# # {asynchronous:true, evalScripts:true}); return false;">Delete this post</a>
|
150
|
-
# link_to_remote "Delete this post",
|
151
|
-
# :url => { :action => "destroy", :id => post.id },
|
152
|
-
# :update => { :success => "posts", :failure => "error" }
|
116
|
+
# The +html_options+ will accept a hash of html attributes for the link tag. Some examples are :class => "nav_button", :id => "articles_nav_button"
|
153
117
|
#
|
154
|
-
#
|
155
|
-
# influence how the target DOM element is updated. It must be one of
|
156
|
-
# <tt>:before</tt>, <tt>:top</tt>, <tt>:bottom</tt>, or <tt>:after</tt>.
|
157
|
-
#
|
158
|
-
# The method used is by default POST. You can also specify GET or you
|
159
|
-
# can simulate PUT or DELETE over POST. All specified with <tt>options[:method]</tt>
|
160
|
-
#
|
161
|
-
# Example:
|
162
|
-
# # Generates: <a href="#" onclick="new Ajax.Request('/person/4', {asynchronous:true, evalScripts:true, method:'delete'});
|
163
|
-
# # return false;">Destroy</a>
|
164
|
-
# link_to_remote "Destroy", :url => person_url(:id => person), :method => :delete
|
165
|
-
#
|
166
|
-
# By default, these remote requests are processed asynchronous during
|
167
|
-
# which various JavaScript callbacks can be triggered (for progress
|
168
|
-
# indicators and the likes). All callbacks get access to the
|
169
|
-
# <tt>request</tt> object, which holds the underlying XMLHttpRequest.
|
170
|
-
#
|
171
|
-
# To access the server response, use <tt>request.responseText</tt>, to
|
172
|
-
# find out the HTTP status, use <tt>request.status</tt>.
|
173
|
-
#
|
174
|
-
# Example:
|
175
|
-
# # Generates: <a href="#" onclick="new Ajax.Request('/words/undo?n=33', {asynchronous:true, evalScripts:true,
|
176
|
-
# # onComplete:function(request){undoRequestCompleted(request)}}); return false;">hello</a>
|
177
|
-
# word = 'hello'
|
178
|
-
# link_to_remote word,
|
179
|
-
# :url => { :action => "undo", :n => word_counter },
|
180
|
-
# :complete => "undoRequestCompleted(request)"
|
118
|
+
# Note: if you choose to specify the javascript function in a block, but would like to pass html_options, set the +function+ parameter to nil
|
181
119
|
#
|
182
|
-
# The callbacks that may be specified are (in order):
|
183
|
-
#
|
184
|
-
# <tt>:loading</tt>:: Called when the remote document is being
|
185
|
-
# loaded with data by the browser.
|
186
|
-
# <tt>:loaded</tt>:: Called when the browser has finished loading
|
187
|
-
# the remote document.
|
188
|
-
# <tt>:interactive</tt>:: Called when the user can interact with the
|
189
|
-
# remote document, even though it has not
|
190
|
-
# finished loading.
|
191
|
-
# <tt>:success</tt>:: Called when the XMLHttpRequest is completed,
|
192
|
-
# and the HTTP status code is in the 2XX range.
|
193
|
-
# <tt>:failure</tt>:: Called when the XMLHttpRequest is completed,
|
194
|
-
# and the HTTP status code is not in the 2XX
|
195
|
-
# range.
|
196
|
-
# <tt>:complete</tt>:: Called when the XMLHttpRequest is complete
|
197
|
-
# (fires after success/failure if they are
|
198
|
-
# present).
|
199
|
-
#
|
200
|
-
# You can further refine <tt>:success</tt> and <tt>:failure</tt> by
|
201
|
-
# adding additional callbacks for specific status codes.
|
202
|
-
#
|
203
|
-
# Example:
|
204
|
-
# # Generates: <a href="#" onclick="new Ajax.Request('/testing/action', {asynchronous:true, evalScripts:true,
|
205
|
-
# # on404:function(request){alert('Not found...? Wrong URL...?')},
|
206
|
-
# # onFailure:function(request){alert('HTTP Error ' + request.status + '!')}}); return false;">hello</a>
|
207
|
-
# link_to_remote word,
|
208
|
-
# :url => { :action => "action" },
|
209
|
-
# 404 => "alert('Not found...? Wrong URL...?')",
|
210
|
-
# :failure => "alert('HTTP Error ' + request.status + '!')"
|
211
|
-
#
|
212
|
-
# A status code callback overrides the success/failure handlers if
|
213
|
-
# present.
|
214
|
-
#
|
215
|
-
# If you for some reason or another need synchronous processing (that'll
|
216
|
-
# block the browser while the request is happening), you can specify
|
217
|
-
# <tt>options[:type] = :synchronous</tt>.
|
218
|
-
#
|
219
|
-
# You can customize further browser side call logic by passing in
|
220
|
-
# JavaScript code snippets via some optional parameters. In their order
|
221
|
-
# of use these are:
|
222
|
-
#
|
223
|
-
# <tt>:confirm</tt>:: Adds confirmation dialog.
|
224
|
-
# <tt>:condition</tt>:: Perform remote request conditionally
|
225
|
-
# by this expression. Use this to
|
226
|
-
# describe browser-side conditions when
|
227
|
-
# request should not be initiated.
|
228
|
-
# <tt>:before</tt>:: Called before request is initiated.
|
229
|
-
# <tt>:after</tt>:: Called immediately after request was
|
230
|
-
# initiated and before <tt>:loading</tt>.
|
231
|
-
# <tt>:submit</tt>:: Specifies the DOM element ID that's used
|
232
|
-
# as the parent of the form elements. By
|
233
|
-
# default this is the current form, but
|
234
|
-
# it could just as well be the ID of a
|
235
|
-
# table row or any other DOM element.
|
236
|
-
# <tt>:with</tt>:: A JavaScript expression specifying
|
237
|
-
# the parameters for the XMLHttpRequest.
|
238
|
-
# Any expressions should return a valid
|
239
|
-
# URL query string.
|
240
|
-
#
|
241
|
-
# Example:
|
242
|
-
#
|
243
|
-
# :with => "'name=' + $('name').value"
|
244
|
-
#
|
245
|
-
# You can generate a link that uses AJAX in the general case, while
|
246
|
-
# degrading gracefully to plain link behavior in the absence of
|
247
|
-
# JavaScript by setting <tt>html_options[:href]</tt> to an alternate URL.
|
248
|
-
# Note the extra curly braces around the <tt>options</tt> hash separate
|
249
|
-
# it as the second parameter from <tt>html_options</tt>, the third.
|
250
|
-
#
|
251
|
-
# Example:
|
252
|
-
# link_to_remote "Delete this post",
|
253
|
-
# { :update => "posts", :url => { :action => "destroy", :id => post.id } },
|
254
|
-
# :href => url_for(:action => "destroy", :id => post.id)
|
255
|
-
def link_to_remote(name, options = {}, html_options = nil)
|
256
|
-
link_to_function(name, remote_function(options), html_options || options.delete(:html))
|
257
|
-
end
|
258
|
-
|
259
|
-
# Creates a button with an onclick event which calls a remote action
|
260
|
-
# via XMLHttpRequest
|
261
|
-
# The options for specifying the target with :url
|
262
|
-
# and defining callbacks is the same as link_to_remote.
|
263
|
-
def button_to_remote(name, options = {}, html_options = {})
|
264
|
-
button_to_function(name, remote_function(options), html_options)
|
265
|
-
end
|
266
|
-
|
267
|
-
# Periodically calls the specified url (<tt>options[:url]</tt>) every
|
268
|
-
# <tt>options[:frequency]</tt> seconds (default is 10). Usually used to
|
269
|
-
# update a specified div (<tt>options[:update]</tt>) with the results
|
270
|
-
# of the remote call. The options for specifying the target with <tt>:url</tt>
|
271
|
-
# and defining callbacks is the same as link_to_remote.
|
272
120
|
# Examples:
|
273
|
-
#
|
274
|
-
#
|
275
|
-
#
|
276
|
-
#
|
277
|
-
#
|
278
|
-
#
|
279
|
-
#
|
280
|
-
#
|
281
|
-
|
282
|
-
|
283
|
-
# # '/testing/invoice/16', {asynchronous:true, evalScripts:true})}, 10)
|
284
|
-
# periodically_call_remote(:url => { :action => 'invoice', :id => customer.id },
|
285
|
-
# :update => { :success => "invoice", :failure => "error" }
|
286
|
-
#
|
287
|
-
# # Call update every 20 seconds and update the new_block DIV
|
288
|
-
# # Generates:
|
289
|
-
# # new PeriodicalExecuter(function() {new Ajax.Updater('news_block', 'update', {asynchronous:true, evalScripts:true})}, 20)
|
290
|
-
# periodically_call_remote(:url => 'update', :frequency => '20', :update => 'news_block')
|
291
|
-
#
|
292
|
-
def periodically_call_remote(options = {})
|
293
|
-
frequency = options[:frequency] || 10 # every ten seconds by default
|
294
|
-
code = "new PeriodicalExecuter(function() {#{remote_function(options)}}, #{frequency})"
|
295
|
-
javascript_tag(code)
|
296
|
-
end
|
297
|
-
|
298
|
-
# Returns a form tag that will submit using XMLHttpRequest in the
|
299
|
-
# background instead of the regular reloading POST arrangement. Even
|
300
|
-
# though it's using JavaScript to serialize the form elements, the form
|
301
|
-
# submission will work just like a regular submission as viewed by the
|
302
|
-
# receiving side (all elements available in <tt>params</tt>). The options for
|
303
|
-
# specifying the target with <tt>:url</tt> and defining callbacks is the same as
|
304
|
-
# +link_to_remote+.
|
305
|
-
#
|
306
|
-
# A "fall-through" target for browsers that doesn't do JavaScript can be
|
307
|
-
# specified with the <tt>:action</tt>/<tt>:method</tt> options on <tt>:html</tt>.
|
308
|
-
#
|
309
|
-
# Example:
|
310
|
-
# # Generates:
|
311
|
-
# # <form action="/some/place" method="post" onsubmit="new Ajax.Request('',
|
312
|
-
# # {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;">
|
313
|
-
# form_remote_tag :html => { :action =>
|
314
|
-
# url_for(:controller => "some", :action => "place") }
|
315
|
-
#
|
316
|
-
# The Hash passed to the <tt>:html</tt> key is equivalent to the options (2nd)
|
317
|
-
# argument in the FormTagHelper.form_tag method.
|
318
|
-
#
|
319
|
-
# By default the fall-through action is the same as the one specified in
|
320
|
-
# the <tt>:url</tt> (and the default method is <tt>:post</tt>).
|
321
|
-
#
|
322
|
-
# form_remote_tag also takes a block, like form_tag:
|
323
|
-
# # Generates:
|
324
|
-
# # <form action="/" method="post" onsubmit="new Ajax.Request('/',
|
325
|
-
# # {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)});
|
326
|
-
# # return false;"> <div><input name="commit" type="submit" value="Save" /></div>
|
327
|
-
# # </form>
|
328
|
-
# <% form_remote_tag :url => '/posts' do -%>
|
329
|
-
# <div><%= submit_tag 'Save' %></div>
|
330
|
-
# <% end -%>
|
331
|
-
def form_remote_tag(options = {}, &block)
|
332
|
-
options[:form] = true
|
333
|
-
|
334
|
-
options[:html] ||= {}
|
335
|
-
options[:html][:onsubmit] =
|
336
|
-
(options[:html][:onsubmit] ? options[:html][:onsubmit] + "; " : "") +
|
337
|
-
"#{remote_function(options)}; return false;"
|
338
|
-
|
339
|
-
form_tag(options[:html].delete(:action) || url_for(options[:url]), options[:html], &block)
|
340
|
-
end
|
341
|
-
|
342
|
-
# Creates a form that will submit using XMLHttpRequest in the background
|
343
|
-
# instead of the regular reloading POST arrangement and a scope around a
|
344
|
-
# specific resource that is used as a base for questioning about
|
345
|
-
# values for the fields.
|
346
|
-
#
|
347
|
-
# === Resource
|
348
|
-
#
|
349
|
-
# Example:
|
350
|
-
# <% remote_form_for(@post) do |f| %>
|
351
|
-
# ...
|
352
|
-
# <% end %>
|
353
|
-
#
|
354
|
-
# This will expand to be the same as:
|
355
|
-
#
|
356
|
-
# <% remote_form_for :post, @post, :url => post_path(@post), :html => { :method => :put, :class => "edit_post", :id => "edit_post_45" } do |f| %>
|
357
|
-
# ...
|
358
|
-
# <% end %>
|
359
|
-
#
|
360
|
-
# === Nested Resource
|
361
|
-
#
|
362
|
-
# Example:
|
363
|
-
# <% remote_form_for([@post, @comment]) do |f| %>
|
364
|
-
# ...
|
365
|
-
# <% end %>
|
366
|
-
#
|
367
|
-
# This will expand to be the same as:
|
368
|
-
#
|
369
|
-
# <% remote_form_for :comment, @comment, :url => post_comment_path(@post, @comment), :html => { :method => :put, :class => "edit_comment", :id => "edit_comment_45" } do |f| %>
|
370
|
-
# ...
|
371
|
-
# <% end %>
|
372
|
-
#
|
373
|
-
# If you don't need to attach a form to a resource, then check out form_remote_tag.
|
374
|
-
#
|
375
|
-
# See FormHelper#form_for for additional semantics.
|
376
|
-
def remote_form_for(record_or_name_or_array, *args, &proc)
|
377
|
-
options = args.extract_options!
|
378
|
-
|
379
|
-
case record_or_name_or_array
|
380
|
-
when String, Symbol
|
381
|
-
object_name = record_or_name_or_array
|
382
|
-
when Array
|
383
|
-
object = record_or_name_or_array.last
|
384
|
-
object_name = ActionController::RecordIdentifier.singular_class_name(object)
|
385
|
-
apply_form_for_options!(record_or_name_or_array, options)
|
386
|
-
args.unshift object
|
387
|
-
else
|
388
|
-
object = record_or_name_or_array
|
389
|
-
object_name = ActionController::RecordIdentifier.singular_class_name(record_or_name_or_array)
|
390
|
-
apply_form_for_options!(object, options)
|
391
|
-
args.unshift object
|
392
|
-
end
|
393
|
-
|
394
|
-
concat(form_remote_tag(options))
|
395
|
-
fields_for(object_name, *(args << options), &proc)
|
396
|
-
concat('</form>'.html_safe)
|
397
|
-
end
|
398
|
-
alias_method :form_remote_for, :remote_form_for
|
399
|
-
|
400
|
-
# Returns a button input tag with the element name of +name+ and a value (i.e., display text) of +value+
|
401
|
-
# that will submit form using XMLHttpRequest in the background instead of a regular POST request that
|
402
|
-
# reloads the page.
|
403
|
-
#
|
404
|
-
# # Create a button that submits to the create action
|
405
|
-
# #
|
406
|
-
# # Generates: <input name="create_btn" onclick="new Ajax.Request('/testing/create',
|
407
|
-
# # {asynchronous:true, evalScripts:true, parameters:Form.serialize(this.form)});
|
408
|
-
# # return false;" type="button" value="Create" />
|
409
|
-
# <%= submit_to_remote 'create_btn', 'Create', :url => { :action => 'create' } %>
|
410
|
-
#
|
411
|
-
# # Submit to the remote action update and update the DIV succeed or fail based
|
412
|
-
# # on the success or failure of the request
|
413
|
-
# #
|
414
|
-
# # Generates: <input name="update_btn" onclick="new Ajax.Updater({success:'succeed',failure:'fail'},
|
415
|
-
# # '/testing/update', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this.form)});
|
416
|
-
# # return false;" type="button" value="Update" />
|
417
|
-
# <%= submit_to_remote 'update_btn', 'Update', :url => { :action => 'update' },
|
418
|
-
# :update => { :success => "succeed", :failure => "fail" }
|
419
|
-
#
|
420
|
-
# <tt>options</tt> argument is the same as in form_remote_tag.
|
421
|
-
def submit_to_remote(name, value, options = {})
|
422
|
-
options[:with] ||= 'Form.serialize(this.form)'
|
423
|
-
|
424
|
-
html_options = options.delete(:html) || {}
|
425
|
-
html_options[:name] = name
|
121
|
+
# button_to_function "Greeting", "alert('Hello world!')"
|
122
|
+
# button_to_function "Delete", "if (confirm('Really?')) do_delete()"
|
123
|
+
# button_to_function "Details" do |page|
|
124
|
+
# page[:details].visual_effect :toggle_slide
|
125
|
+
# end
|
126
|
+
# button_to_function "Details", :class => "details_button" do |page|
|
127
|
+
# page[:details].visual_effect :toggle_slide
|
128
|
+
# end
|
129
|
+
def button_to_function(name, *args, &block)
|
130
|
+
html_options = args.extract_options!.symbolize_keys
|
426
131
|
|
427
|
-
|
428
|
-
|
132
|
+
function = block_given? ? update_page(&block) : args[0] || ''
|
133
|
+
onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function};"
|
429
134
|
|
430
|
-
|
431
|
-
# that +form_remote_tag+ can call in <tt>:complete</tt> to evaluate a multiple
|
432
|
-
# update return document using +update_element_function+ calls.
|
433
|
-
def evaluate_remote_response
|
434
|
-
"eval(request.responseText)"
|
135
|
+
tag(:input, html_options.merge(:type => 'button', :value => name, :onclick => onclick))
|
435
136
|
end
|
436
137
|
|
437
138
|
# Returns the JavaScript needed for a remote function.
|
@@ -475,103 +176,11 @@ module ActionView
|
|
475
176
|
return function
|
476
177
|
end
|
477
178
|
|
478
|
-
# Observes the field with the DOM ID specified by +field_id+ and calls a
|
479
|
-
# callback when its contents have changed. The default callback is an
|
480
|
-
# Ajax call. By default the value of the observed field is sent as a
|
481
|
-
# parameter with the Ajax call.
|
482
|
-
#
|
483
|
-
# Example:
|
484
|
-
# # Generates: new Form.Element.Observer('suggest', 0.25, function(element, value) {new Ajax.Updater('suggest',
|
485
|
-
# # '/testing/find_suggestion', {asynchronous:true, evalScripts:true, parameters:'q=' + value})})
|
486
|
-
# <%= observe_field :suggest, :url => { :action => :find_suggestion },
|
487
|
-
# :frequency => 0.25,
|
488
|
-
# :update => :suggest,
|
489
|
-
# :with => 'q'
|
490
|
-
# %>
|
491
|
-
#
|
492
|
-
# Required +options+ are either of:
|
493
|
-
# <tt>:url</tt>:: +url_for+-style options for the action to call
|
494
|
-
# when the field has changed.
|
495
|
-
# <tt>:function</tt>:: Instead of making a remote call to a URL, you
|
496
|
-
# can specify javascript code to be called instead.
|
497
|
-
# Note that the value of this option is used as the
|
498
|
-
# *body* of the javascript function, a function definition
|
499
|
-
# with parameters named element and value will be generated for you
|
500
|
-
# for example:
|
501
|
-
# observe_field("glass", :frequency => 1, :function => "alert('Element changed')")
|
502
|
-
# will generate:
|
503
|
-
# new Form.Element.Observer('glass', 1, function(element, value) {alert('Element changed')})
|
504
|
-
# The element parameter is the DOM element being observed, and the value is its value at the
|
505
|
-
# time the observer is triggered.
|
506
|
-
#
|
507
|
-
# Additional options are:
|
508
|
-
# <tt>:frequency</tt>:: The frequency (in seconds) at which changes to
|
509
|
-
# this field will be detected. Not setting this
|
510
|
-
# option at all or to a value equal to or less than
|
511
|
-
# zero will use event based observation instead of
|
512
|
-
# time based observation.
|
513
|
-
# <tt>:update</tt>:: Specifies the DOM ID of the element whose
|
514
|
-
# innerHTML should be updated with the
|
515
|
-
# XMLHttpRequest response text.
|
516
|
-
# <tt>:with</tt>:: A JavaScript expression specifying the parameters
|
517
|
-
# for the XMLHttpRequest. The default is to send the
|
518
|
-
# key and value of the observed field. Any custom
|
519
|
-
# expressions should return a valid URL query string.
|
520
|
-
# The value of the field is stored in the JavaScript
|
521
|
-
# variable +value+.
|
522
|
-
#
|
523
|
-
# Examples
|
524
|
-
#
|
525
|
-
# :with => "'my_custom_key=' + value"
|
526
|
-
# :with => "'person[name]=' + prompt('New name')"
|
527
|
-
# :with => "Form.Element.serialize('other-field')"
|
528
|
-
#
|
529
|
-
# Finally
|
530
|
-
# :with => 'name'
|
531
|
-
# is shorthand for
|
532
|
-
# :with => "'name=' + value"
|
533
|
-
# This essentially just changes the key of the parameter.
|
534
|
-
#
|
535
|
-
# Additionally, you may specify any of the options documented in the
|
536
|
-
# <em>Common options</em> section at the top of this document.
|
537
|
-
#
|
538
|
-
# Example:
|
539
|
-
#
|
540
|
-
# # Sends params: {:title => 'Title of the book'} when the book_title input
|
541
|
-
# # field is changed.
|
542
|
-
# observe_field 'book_title',
|
543
|
-
# :url => 'http://example.com/books/edit/1',
|
544
|
-
# :with => 'title'
|
545
|
-
#
|
546
|
-
#
|
547
|
-
def observe_field(field_id, options = {})
|
548
|
-
if options[:frequency] && options[:frequency] > 0
|
549
|
-
build_observer('Form.Element.Observer', field_id, options)
|
550
|
-
else
|
551
|
-
build_observer('Form.Element.EventObserver', field_id, options)
|
552
|
-
end
|
553
|
-
end
|
554
|
-
|
555
|
-
# Observes the form with the DOM ID specified by +form_id+ and calls a
|
556
|
-
# callback when its contents have changed. The default callback is an
|
557
|
-
# Ajax call. By default all fields of the observed field are sent as
|
558
|
-
# parameters with the Ajax call.
|
559
|
-
#
|
560
|
-
# The +options+ for +observe_form+ are the same as the options for
|
561
|
-
# +observe_field+. The JavaScript variable +value+ available to the
|
562
|
-
# <tt>:with</tt> option is set to the serialized form by default.
|
563
|
-
def observe_form(form_id, options = {})
|
564
|
-
if options[:frequency]
|
565
|
-
build_observer('Form.Observer', form_id, options)
|
566
|
-
else
|
567
|
-
build_observer('Form.EventObserver', form_id, options)
|
568
|
-
end
|
569
|
-
end
|
570
|
-
|
571
179
|
# All the methods were moved to GeneratorMethods so that
|
572
180
|
# #include_helpers_from_context has nothing to overwrite.
|
573
181
|
class JavaScriptGenerator #:nodoc:
|
574
182
|
def initialize(context, &block) #:nodoc:
|
183
|
+
context._evaluate_assigns_and_ivars
|
575
184
|
@context, @lines = context, []
|
576
185
|
include_helpers_from_context
|
577
186
|
@context.with_output_buffer(@lines) do
|
@@ -653,7 +262,7 @@ module ActionView
|
|
653
262
|
# <script> tag.
|
654
263
|
module GeneratorMethods
|
655
264
|
def to_s #:nodoc:
|
656
|
-
|
265
|
+
returning javascript = @lines * $/ do
|
657
266
|
if ActionView::Base.debug_rjs
|
658
267
|
source = javascript.dup
|
659
268
|
javascript.replace "try {\n#{source}\n} catch (e) "
|
@@ -943,37 +552,11 @@ module ActionView
|
|
943
552
|
record "}, #{(seconds * 1000).to_i})"
|
944
553
|
end
|
945
554
|
|
946
|
-
# Starts a script.aculo.us visual effect. See
|
947
|
-
# ActionView::Helpers::ScriptaculousHelper for more information.
|
948
|
-
def visual_effect(name, id = nil, options = {})
|
949
|
-
record @context.send(:visual_effect, name, id, options)
|
950
|
-
end
|
951
|
-
|
952
|
-
# Creates a script.aculo.us sortable element. Useful
|
953
|
-
# to recreate sortable elements after items get added
|
954
|
-
# or deleted.
|
955
|
-
# See ActionView::Helpers::ScriptaculousHelper for more information.
|
956
|
-
def sortable(id, options = {})
|
957
|
-
record @context.send(:sortable_element_js, id, options)
|
958
|
-
end
|
959
|
-
|
960
|
-
# Creates a script.aculo.us draggable element.
|
961
|
-
# See ActionView::Helpers::ScriptaculousHelper for more information.
|
962
|
-
def draggable(id, options = {})
|
963
|
-
record @context.send(:draggable_element_js, id, options)
|
964
|
-
end
|
965
|
-
|
966
|
-
# Creates a script.aculo.us drop receiving element.
|
967
|
-
# See ActionView::Helpers::ScriptaculousHelper for more information.
|
968
|
-
def drop_receiving(id, options = {})
|
969
|
-
record @context.send(:drop_receiving_element_js, id, options)
|
970
|
-
end
|
971
|
-
|
972
555
|
private
|
973
556
|
def loop_on_multiple_args(method, ids)
|
974
557
|
record(ids.size>1 ?
|
975
558
|
"#{javascript_object_for(ids)}.each(#{method})" :
|
976
|
-
"#{method}(#{
|
559
|
+
"#{method}(#{javascript_object_for(ids.first)})")
|
977
560
|
end
|
978
561
|
|
979
562
|
def page
|
@@ -981,19 +564,20 @@ module ActionView
|
|
981
564
|
end
|
982
565
|
|
983
566
|
def record(line)
|
984
|
-
"#{line.to_s.chomp.gsub(/\;\z/, '')};"
|
985
|
-
self <<
|
567
|
+
returning line = "#{line.to_s.chomp.gsub(/\;\z/, '')};" do
|
568
|
+
self << line
|
986
569
|
end
|
987
570
|
end
|
988
571
|
|
989
572
|
def render(*options_for_render)
|
990
|
-
|
991
|
-
|
573
|
+
old_formats = @context && @context.formats
|
574
|
+
|
575
|
+
@context.reset_formats([:html]) if @context
|
992
576
|
Hash === options_for_render.first ?
|
993
577
|
@context.render(*options_for_render) :
|
994
578
|
options_for_render.first.to_s
|
995
579
|
ensure
|
996
|
-
@context.
|
580
|
+
@context.reset_formats(old_formats) if @context
|
997
581
|
end
|
998
582
|
|
999
583
|
def javascript_object_for(object)
|
@@ -1039,65 +623,57 @@ module ActionView
|
|
1039
623
|
javascript_tag update_page(&block), html_options
|
1040
624
|
end
|
1041
625
|
|
1042
|
-
|
1043
|
-
|
1044
|
-
|
1045
|
-
|
1046
|
-
js_options['asynchronous'] = options[:type] != :synchronous
|
1047
|
-
js_options['method'] = method_option_to_s(options[:method]) if options[:method]
|
1048
|
-
js_options['insertion'] = "'#{options[:position].to_s.downcase}'" if options[:position]
|
1049
|
-
js_options['evalScripts'] = options[:script].nil? || options[:script]
|
1050
|
-
|
1051
|
-
if options[:form]
|
1052
|
-
js_options['parameters'] = 'Form.serialize(this)'
|
1053
|
-
elsif options[:submit]
|
1054
|
-
js_options['parameters'] = "Form.serialize('#{options[:submit]}')"
|
1055
|
-
elsif options[:with]
|
1056
|
-
js_options['parameters'] = options[:with]
|
1057
|
-
end
|
1058
|
-
|
1059
|
-
if protect_against_forgery? && !options[:form]
|
1060
|
-
if js_options['parameters']
|
1061
|
-
js_options['parameters'] << " + '&"
|
626
|
+
protected
|
627
|
+
def options_for_javascript(options)
|
628
|
+
if options.empty?
|
629
|
+
'{}'
|
1062
630
|
else
|
1063
|
-
|
631
|
+
"{#{options.keys.map { |k| "#{k}:#{options[k]}" }.sort.join(', ')}}"
|
1064
632
|
end
|
1065
|
-
js_options['parameters'] << "#{request_forgery_protection_token}=' + encodeURIComponent('#{escape_javascript form_authenticity_token}')"
|
1066
633
|
end
|
1067
634
|
|
1068
|
-
|
1069
|
-
|
635
|
+
def options_for_ajax(options)
|
636
|
+
js_options = build_callbacks(options)
|
1070
637
|
|
1071
|
-
|
1072
|
-
|
1073
|
-
|
638
|
+
js_options['asynchronous'] = options[:type] != :synchronous
|
639
|
+
js_options['method'] = method_option_to_s(options[:method]) if options[:method]
|
640
|
+
js_options['insertion'] = "'#{options[:position].to_s.downcase}'" if options[:position]
|
641
|
+
js_options['evalScripts'] = options[:script].nil? || options[:script]
|
1074
642
|
|
1075
|
-
|
1076
|
-
|
1077
|
-
|
1078
|
-
|
1079
|
-
options[:with]
|
643
|
+
if options[:form]
|
644
|
+
js_options['parameters'] = 'Form.serialize(this)'
|
645
|
+
elsif options[:submit]
|
646
|
+
js_options['parameters'] = "Form.serialize('#{options[:submit]}')"
|
647
|
+
elsif options[:with]
|
648
|
+
js_options['parameters'] = options[:with]
|
649
|
+
end
|
650
|
+
|
651
|
+
if protect_against_forgery? && !options[:form]
|
652
|
+
if js_options['parameters']
|
653
|
+
js_options['parameters'] << " + '&"
|
654
|
+
else
|
655
|
+
js_options['parameters'] = "'"
|
656
|
+
end
|
657
|
+
js_options['parameters'] << "#{request_forgery_protection_token}=' + encodeURIComponent('#{escape_javascript form_authenticity_token}')"
|
658
|
+
end
|
659
|
+
|
660
|
+
options_for_javascript(js_options)
|
1080
661
|
end
|
1081
662
|
|
1082
|
-
|
1083
|
-
|
1084
|
-
|
1085
|
-
javascript << "function(element, value) {"
|
1086
|
-
javascript << "#{callback}}"
|
1087
|
-
javascript << ")"
|
1088
|
-
javascript_tag(javascript)
|
1089
|
-
end
|
663
|
+
def method_option_to_s(method)
|
664
|
+
(method.is_a?(String) and !method.index("'").nil?) ? method : "'#{method}'"
|
665
|
+
end
|
1090
666
|
|
1091
|
-
|
1092
|
-
|
1093
|
-
|
1094
|
-
|
1095
|
-
|
1096
|
-
|
667
|
+
def build_callbacks(options)
|
668
|
+
callbacks = {}
|
669
|
+
options.each do |callback, code|
|
670
|
+
if CALLBACKS.include?(callback)
|
671
|
+
name = 'on' + callback.to_s.capitalize
|
672
|
+
callbacks[name] = "function(request){#{code}}"
|
673
|
+
end
|
1097
674
|
end
|
675
|
+
callbacks
|
1098
676
|
end
|
1099
|
-
callbacks
|
1100
|
-
end
|
1101
677
|
end
|
1102
678
|
|
1103
679
|
# Converts chained method calls on DOM proxy elements into JavaScript chains
|
@@ -1173,18 +749,18 @@ module ActionView
|
|
1173
749
|
|
1174
750
|
class JavaScriptVariableProxy < JavaScriptProxy #:nodoc:
|
1175
751
|
def initialize(generator, variable)
|
1176
|
-
@variable = variable
|
752
|
+
@variable = ::ActiveSupport::JSON::Variable.new(variable)
|
1177
753
|
@empty = true # only record lines if we have to. gets rid of unnecessary linebreaks
|
1178
754
|
super(generator)
|
1179
755
|
end
|
1180
756
|
|
1181
757
|
# The JSON Encoder calls this to check for the +to_json+ method
|
1182
758
|
# Since it's a blank slate object, I suppose it responds to anything.
|
1183
|
-
def respond_to?(
|
759
|
+
def respond_to?(*)
|
1184
760
|
true
|
1185
761
|
end
|
1186
762
|
|
1187
|
-
def
|
763
|
+
def as_json(options = nil)
|
1188
764
|
@variable
|
1189
765
|
end
|
1190
766
|
|