actionpack 2.0.5 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +149 -7
- data/MIT-LICENSE +1 -1
- data/README +1 -1
- data/Rakefile +5 -6
- data/lib/action_controller.rb +2 -2
- data/lib/action_controller/assertions/model_assertions.rb +2 -1
- data/lib/action_controller/assertions/response_assertions.rb +4 -2
- data/lib/action_controller/assertions/routing_assertions.rb +3 -3
- data/lib/action_controller/assertions/selector_assertions.rb +30 -27
- data/lib/action_controller/assertions/tag_assertions.rb +3 -3
- data/lib/action_controller/base.rb +103 -129
- data/lib/action_controller/benchmarking.rb +3 -3
- data/lib/action_controller/caching.rb +41 -652
- 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/cookie.rb +27 -23
- data/lib/action_controller/cgi_ext/stdinput.rb +1 -0
- data/lib/action_controller/cgi_process.rb +6 -4
- data/lib/action_controller/components.rb +7 -6
- data/lib/action_controller/cookies.rb +31 -19
- data/lib/action_controller/dispatcher.rb +51 -84
- data/lib/action_controller/filters.rb +295 -421
- data/lib/action_controller/flash.rb +1 -6
- data/lib/action_controller/headers.rb +31 -0
- data/lib/action_controller/helpers.rb +26 -9
- data/lib/action_controller/http_authentication.rb +1 -1
- data/lib/action_controller/integration.rb +65 -13
- data/lib/action_controller/layout.rb +24 -39
- data/lib/action_controller/mime_responds.rb +7 -3
- data/lib/action_controller/mime_type.rb +25 -9
- data/lib/action_controller/mime_types.rb +1 -1
- data/lib/action_controller/polymorphic_routes.rb +32 -17
- data/lib/action_controller/record_identifier.rb +10 -4
- data/lib/action_controller/request.rb +46 -30
- data/lib/action_controller/request_forgery_protection.rb +10 -9
- data/lib/action_controller/request_profiler.rb +29 -8
- data/lib/action_controller/rescue.rb +24 -24
- data/lib/action_controller/resources.rb +66 -23
- data/lib/action_controller/response.rb +2 -2
- data/lib/action_controller/routing.rb +113 -1229
- data/lib/action_controller/routing/builder.rb +204 -0
- data/lib/action_controller/{routing_optimisation.rb → routing/optimisations.rb} +13 -12
- data/lib/action_controller/routing/recognition_optimisation.rb +158 -0
- data/lib/action_controller/routing/route.rb +240 -0
- data/lib/action_controller/routing/route_set.rb +435 -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 +13 -8
- data/lib/action_controller/session/cookie_store.rb +20 -17
- data/lib/action_controller/session_management.rb +10 -3
- data/lib/action_controller/streaming.rb +45 -31
- data/lib/action_controller/test_case.rb +33 -23
- data/lib/action_controller/test_process.rb +39 -35
- data/lib/action_controller/url_rewriter.rb +18 -12
- data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +1 -1
- data/lib/action_pack.rb +1 -1
- data/lib/action_pack/version.rb +2 -2
- data/lib/action_view.rb +11 -3
- data/lib/action_view/base.rb +73 -390
- data/lib/action_view/helpers/active_record_helper.rb +83 -62
- data/lib/action_view/helpers/asset_tag_helper.rb +101 -44
- data/lib/action_view/helpers/atom_feed_helper.rb +35 -7
- data/lib/action_view/helpers/benchmark_helper.rb +5 -3
- data/lib/action_view/helpers/cache_helper.rb +3 -2
- data/lib/action_view/helpers/capture_helper.rb +1 -2
- data/lib/action_view/helpers/date_helper.rb +104 -82
- data/lib/action_view/helpers/form_helper.rb +148 -75
- data/lib/action_view/helpers/form_options_helper.rb +44 -23
- data/lib/action_view/helpers/form_tag_helper.rb +22 -13
- data/lib/action_view/helpers/javascripts/controls.js +1 -1
- data/lib/action_view/helpers/javascripts/dragdrop.js +1 -1
- data/lib/action_view/helpers/javascripts/effects.js +1 -1
- data/lib/action_view/helpers/number_helper.rb +10 -3
- data/lib/action_view/helpers/prototype_helper.rb +61 -29
- data/lib/action_view/helpers/record_tag_helper.rb +3 -3
- data/lib/action_view/helpers/sanitize_helper.rb +23 -17
- data/lib/action_view/helpers/scriptaculous_helper.rb +86 -60
- data/lib/action_view/helpers/text_helper.rb +153 -125
- data/lib/action_view/helpers/url_helper.rb +83 -28
- data/lib/action_view/inline_template.rb +20 -0
- data/lib/action_view/partial_template.rb +70 -0
- data/lib/action_view/partials.rb +31 -73
- data/lib/action_view/template.rb +127 -0
- data/lib/action_view/template_error.rb +8 -7
- data/lib/action_view/template_finder.rb +177 -0
- data/lib/action_view/template_handler.rb +18 -1
- data/lib/action_view/template_handlers/builder.rb +10 -2
- data/lib/action_view/template_handlers/compilable.rb +128 -0
- data/lib/action_view/template_handlers/erb.rb +37 -2
- data/lib/action_view/template_handlers/rjs.rb +14 -1
- data/lib/action_view/test_case.rb +58 -0
- data/test/abstract_unit.rb +1 -1
- data/test/active_record_unit.rb +3 -6
- data/test/activerecord/active_record_store_test.rb +1 -2
- data/test/activerecord/render_partial_with_record_identification_test.rb +158 -41
- data/test/adv_attr_test.rb +20 -0
- data/test/controller/action_pack_assertions_test.rb +16 -19
- data/test/controller/addresses_render_test.rb +1 -1
- data/test/controller/assert_select_test.rb +13 -6
- data/test/controller/base_test.rb +48 -2
- data/test/controller/benchmark_test.rb +1 -2
- data/test/controller/caching_test.rb +282 -21
- data/test/controller/capture_test.rb +1 -1
- data/test/controller/cgi_test.rb +1 -1
- data/test/controller/components_test.rb +1 -1
- data/test/controller/content_type_test.rb +2 -2
- data/test/controller/cookie_test.rb +13 -2
- data/test/controller/custom_handler_test.rb +14 -10
- data/test/controller/deprecation/deprecated_base_methods_test.rb +1 -1
- data/test/controller/dispatcher_test.rb +31 -49
- data/test/controller/fake_controllers.rb +17 -0
- data/test/controller/fake_models.rb +6 -0
- data/test/controller/filter_params_test.rb +14 -8
- data/test/controller/filters_test.rb +44 -16
- data/test/controller/flash_test.rb +2 -2
- data/test/controller/header_test.rb +14 -0
- data/test/controller/helper_test.rb +19 -15
- data/test/controller/html-scanner/document_test.rb +1 -2
- data/test/controller/html-scanner/node_test.rb +1 -2
- data/test/controller/html-scanner/sanitizer_test.rb +8 -5
- data/test/controller/html-scanner/tag_node_test.rb +1 -2
- data/test/controller/html-scanner/text_node_test.rb +2 -3
- data/test/controller/html-scanner/tokenizer_test.rb +8 -2
- data/test/controller/http_authentication_test.rb +1 -1
- data/test/controller/integration_test.rb +14 -16
- data/test/controller/integration_upload_test.rb +43 -0
- data/test/controller/layout_test.rb +26 -6
- data/test/controller/mime_responds_test.rb +39 -7
- data/test/controller/mime_type_test.rb +29 -5
- data/test/controller/new_render_test.rb +105 -34
- data/test/controller/polymorphic_routes_test.rb +32 -20
- data/test/controller/record_identifier_test.rb +38 -2
- data/test/controller/redirect_test.rb +21 -1
- data/test/controller/render_test.rb +59 -15
- data/test/controller/request_forgery_protection_test.rb +92 -5
- data/test/controller/request_test.rb +64 -6
- data/test/controller/rescue_test.rb +22 -6
- data/test/controller/resources_test.rb +102 -14
- data/test/controller/routing_test.rb +231 -19
- data/test/controller/selector_test.rb +2 -2
- data/test/controller/send_file_test.rb +14 -3
- data/test/controller/session/cookie_store_test.rb +16 -4
- data/test/controller/session/mem_cache_store_test.rb +3 -4
- data/test/controller/session_fixation_test.rb +1 -1
- data/test/controller/session_management_test.rb +23 -1
- data/test/controller/test_test.rb +39 -18
- data/test/controller/url_rewriter_test.rb +35 -1
- data/test/controller/verification_test.rb +1 -1
- data/test/controller/view_paths_test.rb +15 -12
- data/test/controller/webservice_test.rb +48 -3
- data/test/fixtures/bad_customers/_bad_customer.html.erb +1 -0
- data/test/fixtures/company.rb +1 -0
- data/test/fixtures/customers/_customer.html.erb +1 -0
- data/test/fixtures/db_definitions/sqlite.sql +6 -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/mascot.rb +3 -0
- data/test/fixtures/mascots.yml +4 -0
- data/test/fixtures/mascots/_mascot.html.erb +1 -0
- data/test/fixtures/multipart/boundary_problem_file +10 -0
- data/test/fixtures/public/javascripts/application.js +1 -0
- data/test/fixtures/public/javascripts/controls.js +1 -0
- data/test/fixtures/public/javascripts/dragdrop.js +1 -0
- data/test/fixtures/public/javascripts/effects.js +1 -0
- data/test/fixtures/public/javascripts/prototype.js +1 -0
- data/test/fixtures/public/javascripts/version.1.0.js +1 -0
- data/test/fixtures/public/stylesheets/version.1.0.css +1 -0
- data/test/fixtures/reply.rb +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_counter.erb +1 -0
- data/test/fixtures/test/_form.erb +1 -0
- data/test/fixtures/test/_labelling_form.erb +1 -0
- data/test/fixtures/test/_raise.html.erb +1 -0
- data/test/fixtures/test/greeting.js.rjs +1 -0
- data/test/fixtures/topics/_topic.html.erb +1 -0
- data/test/template/active_record_helper_test.rb +25 -8
- data/test/template/asset_tag_helper_test.rb +100 -17
- data/test/template/atom_feed_helper_test.rb +29 -1
- data/test/template/benchmark_helper_test.rb +10 -22
- data/test/template/date_helper_test.rb +455 -153
- data/test/template/erb_util_test.rb +10 -42
- data/test/template/form_helper_test.rb +192 -66
- data/test/template/form_options_helper_test.rb +19 -8
- data/test/template/form_tag_helper_test.rb +11 -8
- data/test/template/javascript_helper_test.rb +3 -9
- data/test/template/number_helper_test.rb +6 -3
- data/test/template/prototype_helper_test.rb +27 -40
- data/test/template/record_tag_helper_test.rb +54 -0
- data/test/template/sanitize_helper_test.rb +5 -6
- data/test/template/scriptaculous_helper_test.rb +7 -13
- data/test/template/tag_helper_test.rb +3 -6
- 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 +46 -33
- data/test/template/url_helper_test.rb +8 -10
- metadata +65 -12
- data/lib/action_view/compiled_templates.rb +0 -69
- data/test/action_view_test.rb +0 -44
- data/test/activerecord/fixtures_test.rb +0 -24
- data/test/controller/fragment_store_setting_test.rb +0 -47
- data/test/template/compiled_templates_test.rb +0 -197
- data/test/template/deprecate_ivars_test.rb +0 -51
|
@@ -3,7 +3,7 @@ require 'action_view/helpers/tag_helper'
|
|
|
3
3
|
|
|
4
4
|
module ActionView
|
|
5
5
|
module Helpers
|
|
6
|
-
# Provides a number of methods for creating form tags that doesn't rely on an
|
|
6
|
+
# Provides a number of methods for creating form tags that doesn't rely on an Active Record object assigned to the template like
|
|
7
7
|
# FormHelper does. Instead, you provide the names and values manually.
|
|
8
8
|
#
|
|
9
9
|
# NOTE: The HTML options <tt>disabled</tt>, <tt>readonly</tt>, and <tt>multiple</tt> can all be treated as booleans. So specifying
|
|
@@ -14,9 +14,9 @@ module ActionView
|
|
|
14
14
|
#
|
|
15
15
|
# ==== Options
|
|
16
16
|
# * <tt>:multipart</tt> - If set to true, the enctype is set to "multipart/form-data".
|
|
17
|
-
# * <tt>:method</tt>
|
|
18
|
-
#
|
|
19
|
-
#
|
|
17
|
+
# * <tt>:method</tt> - The method to use when submitting the form, usually either "get" or "post".
|
|
18
|
+
# If "put", "delete", or another verb is used, a hidden input with name <tt>_method</tt>
|
|
19
|
+
# is added to simulate the verb over post.
|
|
20
20
|
# * A list of parameters to feed to the URL the form will be posted to.
|
|
21
21
|
#
|
|
22
22
|
# ==== Examples
|
|
@@ -316,9 +316,12 @@ module ActionView
|
|
|
316
316
|
# Creates a submit button with the text <tt>value</tt> as the caption.
|
|
317
317
|
#
|
|
318
318
|
# ==== Options
|
|
319
|
-
# * <tt>:
|
|
319
|
+
# * <tt>:confirm => 'question?'</tt> - This will add a JavaScript confirm
|
|
320
|
+
# prompt with the question specified. If the user accepts, the form is
|
|
321
|
+
# processed normally, otherwise no action is taken.
|
|
322
|
+
# * <tt>:disabled</tt> - If true, the user will not be able to use this input.
|
|
320
323
|
# * <tt>:disable_with</tt> - Value of this parameter will be used as the value for a disabled version
|
|
321
|
-
#
|
|
324
|
+
# of the submit button when the form is submitted.
|
|
322
325
|
# * Any other key creates standard HTML options for the tag.
|
|
323
326
|
#
|
|
324
327
|
# ==== Examples
|
|
@@ -338,8 +341,9 @@ module ActionView
|
|
|
338
341
|
# submit_tag nil, :class => "form_submit"
|
|
339
342
|
# # => <input class="form_submit" name="commit" type="submit" />
|
|
340
343
|
#
|
|
341
|
-
# submit_tag "Edit", :disable_with => "Editing...", :class =>
|
|
342
|
-
# # => <input class="edit-button"
|
|
344
|
+
# submit_tag "Edit", :disable_with => "Editing...", :class => "edit-button"
|
|
345
|
+
# # => <input class="edit-button" onclick="this.disabled=true;this.value='Editing...';this.form.submit();"
|
|
346
|
+
# # name="commit" type="submit" value="Edit" />
|
|
343
347
|
def submit_tag(value = "Save changes", options = {})
|
|
344
348
|
options.stringify_keys!
|
|
345
349
|
|
|
@@ -351,10 +355,15 @@ module ActionView
|
|
|
351
355
|
"#{options["onclick"]}",
|
|
352
356
|
"result = (this.form.onsubmit ? (this.form.onsubmit() ? this.form.submit() : false) : this.form.submit())",
|
|
353
357
|
"if (result == false) { this.value = this.getAttribute('originalValue'); this.disabled = false }",
|
|
354
|
-
"return result",
|
|
358
|
+
"return result;",
|
|
355
359
|
].join(";")
|
|
356
360
|
end
|
|
357
|
-
|
|
361
|
+
|
|
362
|
+
if confirm = options.delete("confirm")
|
|
363
|
+
options["onclick"] ||= ''
|
|
364
|
+
options["onclick"] += "return #{confirm_javascript_function(confirm)};"
|
|
365
|
+
end
|
|
366
|
+
|
|
358
367
|
tag :input, { "type" => "submit", "name" => "commit", "value" => value }.update(options.stringify_keys)
|
|
359
368
|
end
|
|
360
369
|
|
|
@@ -370,13 +379,13 @@ module ActionView
|
|
|
370
379
|
# image_submit_tag("login.png")
|
|
371
380
|
# # => <input src="/images/login.png" type="image" />
|
|
372
381
|
#
|
|
373
|
-
# image_submit_tag("purchase.png"
|
|
382
|
+
# image_submit_tag("purchase.png", :disabled => true)
|
|
374
383
|
# # => <input disabled="disabled" src="/images/purchase.png" type="image" />
|
|
375
384
|
#
|
|
376
|
-
# image_submit_tag("search.png"
|
|
385
|
+
# image_submit_tag("search.png", :class => 'search-button')
|
|
377
386
|
# # => <input class="search-button" src="/images/search.png" type="image" />
|
|
378
387
|
#
|
|
379
|
-
# image_submit_tag("agree.png"
|
|
388
|
+
# image_submit_tag("agree.png", :disabled => true, :class => "agree-disagree-button")
|
|
380
389
|
# # => <input class="agree-disagree-button" disabled="disabled" src="/images/agree.png" type="image" />
|
|
381
390
|
def image_submit_tag(source, options = {})
|
|
382
391
|
tag :input, { "type" => "image", "src" => path_to_image(source) }.update(options.stringify_keys)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2005-
|
|
1
|
+
// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
|
|
2
2
|
// (c) 2005-2007 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
|
|
3
3
|
// (c) 2005-2007 Jon Tirsen (http://www.tirsen.com)
|
|
4
4
|
// Contributors:
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2005-
|
|
1
|
+
// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
|
|
2
2
|
// (c) 2005-2007 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz)
|
|
3
3
|
//
|
|
4
4
|
// script.aculo.us is freely distributable under the terms of an MIT-style license.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2005-
|
|
1
|
+
// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
|
|
2
2
|
// Contributors:
|
|
3
3
|
// Justin Palmer (http://encytemedia.com/)
|
|
4
4
|
// Mark Pilgrim (http://diveintomark.org/)
|
|
@@ -54,6 +54,10 @@ module ActionView
|
|
|
54
54
|
# * <tt>:unit</tt> - Sets the denomination of the currency (defaults to "$").
|
|
55
55
|
# * <tt>:separator</tt> - Sets the separator between the units (defaults to ".").
|
|
56
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
|
|
57
61
|
#
|
|
58
62
|
# ==== Examples
|
|
59
63
|
# number_to_currency(1234567890.50) # => $1,234,567,890.50
|
|
@@ -62,16 +66,19 @@ module ActionView
|
|
|
62
66
|
#
|
|
63
67
|
# number_to_currency(1234567890.50, :unit => "£", :separator => ",", :delimiter => "")
|
|
64
68
|
# # => £1234567890,50
|
|
69
|
+
# number_to_currency(1234567890.50, :unit => "£", :separator => ",", :delimiter => "", :format => "%n %u")
|
|
70
|
+
# # => 1234567890,50 £
|
|
65
71
|
def number_to_currency(number, options = {})
|
|
66
72
|
options = options.stringify_keys
|
|
67
73
|
precision = options["precision"] || 2
|
|
68
74
|
unit = options["unit"] || "$"
|
|
69
75
|
separator = precision > 0 ? options["separator"] || "." : ""
|
|
70
76
|
delimiter = options["delimiter"] || ","
|
|
77
|
+
format = options["format"] || "%u%n"
|
|
71
78
|
|
|
72
79
|
begin
|
|
73
80
|
parts = number_with_precision(number, precision).split('.')
|
|
74
|
-
|
|
81
|
+
format.gsub(/%n/, number_with_delimiter(parts[0], delimiter) + separator + parts[1].to_s).gsub(/%u/, unit)
|
|
75
82
|
rescue
|
|
76
83
|
number
|
|
77
84
|
end
|
|
@@ -137,11 +144,11 @@ module ActionView
|
|
|
137
144
|
#
|
|
138
145
|
# ==== Examples
|
|
139
146
|
# number_with_precision(111.2345) # => 111.235
|
|
140
|
-
# number_with_precision(111.2345, 2) # => 111.
|
|
147
|
+
# number_with_precision(111.2345, 2) # => 111.23
|
|
141
148
|
# number_with_precision(13, 5) # => 13.00000
|
|
142
149
|
# number_with_precision(389.32314, 0) # => 389
|
|
143
150
|
def number_with_precision(number, precision=3)
|
|
144
|
-
"%01.#{precision}f" % number
|
|
151
|
+
"%01.#{precision}f" % ((Float(number) * (10 ** precision)).round.to_f / 10 ** precision)
|
|
145
152
|
rescue
|
|
146
153
|
number
|
|
147
154
|
end
|
|
@@ -255,10 +255,10 @@ module ActionView
|
|
|
255
255
|
link_to_function(name, remote_function(options), html_options || options.delete(:html))
|
|
256
256
|
end
|
|
257
257
|
|
|
258
|
-
# Periodically calls the specified url (<tt>options[:url]</tt>) every
|
|
258
|
+
# Periodically calls the specified url (<tt>options[:url]</tt>) every
|
|
259
259
|
# <tt>options[:frequency]</tt> seconds (default is 10). Usually used to
|
|
260
|
-
# update a specified div (<tt>options[:update]</tt>) with the results
|
|
261
|
-
# of the remote call. The options for specifying the target with
|
|
260
|
+
# update a specified div (<tt>options[:update]</tt>) with the results
|
|
261
|
+
# of the remote call. The options for specifying the target with <tt>:url</tt>
|
|
262
262
|
# and defining callbacks is the same as link_to_remote.
|
|
263
263
|
# Examples:
|
|
264
264
|
# # Call get_averages and put its results in 'avg' every 10 seconds
|
|
@@ -291,11 +291,11 @@ module ActionView
|
|
|
291
291
|
# though it's using JavaScript to serialize the form elements, the form
|
|
292
292
|
# submission will work just like a regular submission as viewed by the
|
|
293
293
|
# receiving side (all elements available in <tt>params</tt>). The options for
|
|
294
|
-
# specifying the target with
|
|
295
|
-
# link_to_remote
|
|
294
|
+
# specifying the target with <tt>:url</tt> and defining callbacks is the same as
|
|
295
|
+
# +link_to_remote+.
|
|
296
296
|
#
|
|
297
297
|
# A "fall-through" target for browsers that doesn't do JavaScript can be
|
|
298
|
-
# specified with the
|
|
298
|
+
# specified with the <tt>:action</tt>/<tt>:method</tt> options on <tt>:html</tt>.
|
|
299
299
|
#
|
|
300
300
|
# Example:
|
|
301
301
|
# # Generates:
|
|
@@ -304,11 +304,11 @@ module ActionView
|
|
|
304
304
|
# form_remote_tag :html => { :action =>
|
|
305
305
|
# url_for(:controller => "some", :action => "place") }
|
|
306
306
|
#
|
|
307
|
-
# The Hash passed to the
|
|
307
|
+
# The Hash passed to the <tt>:html</tt> key is equivalent to the options (2nd)
|
|
308
308
|
# argument in the FormTagHelper.form_tag method.
|
|
309
309
|
#
|
|
310
310
|
# By default the fall-through action is the same as the one specified in
|
|
311
|
-
# the
|
|
311
|
+
# the <tt>:url</tt> (and the default method is <tt>:post</tt>).
|
|
312
312
|
#
|
|
313
313
|
# form_remote_tag also takes a block, like form_tag:
|
|
314
314
|
# # Generates:
|
|
@@ -422,8 +422,8 @@ module ActionView
|
|
|
422
422
|
end
|
|
423
423
|
|
|
424
424
|
# Returns '<tt>eval(request.responseText)</tt>' which is the JavaScript function
|
|
425
|
-
# that form_remote_tag can call in
|
|
426
|
-
# update return document using update_element_function calls.
|
|
425
|
+
# that +form_remote_tag+ can call in <tt>:complete</tt> to evaluate a multiple
|
|
426
|
+
# update return document using +update_element_function+ calls.
|
|
427
427
|
def evaluate_remote_response
|
|
428
428
|
"eval(request.responseText)"
|
|
429
429
|
end
|
|
@@ -458,7 +458,7 @@ module ActionView
|
|
|
458
458
|
|
|
459
459
|
url_options = options[:url]
|
|
460
460
|
url_options = url_options.merge(:escape => false) if url_options.is_a?(Hash)
|
|
461
|
-
function << "'#{url_for(url_options)}'"
|
|
461
|
+
function << "'#{escape_javascript(url_for(url_options))}'"
|
|
462
462
|
function << ", #{javascript_options})"
|
|
463
463
|
|
|
464
464
|
function = "#{options[:before]}; #{function}" if options[:before]
|
|
@@ -595,8 +595,8 @@ module ActionView
|
|
|
595
595
|
# JavaScript sent with a Content-type of "text/javascript".
|
|
596
596
|
#
|
|
597
597
|
# Create new instances with PrototypeHelper#update_page or with
|
|
598
|
-
# ActionController::Base#render, then call
|
|
599
|
-
#
|
|
598
|
+
# ActionController::Base#render, then call +insert_html+, +replace_html+,
|
|
599
|
+
# +remove+, +show+, +hide+, +visual_effect+, or any other of the built-in
|
|
600
600
|
# methods on the yielded generator in any order you like to modify the
|
|
601
601
|
# content and appearance of the current page.
|
|
602
602
|
#
|
|
@@ -631,6 +631,27 @@ module ActionView
|
|
|
631
631
|
# render(:update) { |page| page.update_time }
|
|
632
632
|
# end
|
|
633
633
|
#
|
|
634
|
+
# Calls to JavaScriptGenerator not matching a helper method below
|
|
635
|
+
# generate a proxy to the JavaScript Class named by the method called.
|
|
636
|
+
#
|
|
637
|
+
# Examples:
|
|
638
|
+
#
|
|
639
|
+
# # Generates:
|
|
640
|
+
# # Foo.init();
|
|
641
|
+
# update_page do |page|
|
|
642
|
+
# page.foo.init
|
|
643
|
+
# end
|
|
644
|
+
#
|
|
645
|
+
# # Generates:
|
|
646
|
+
# # Event.observe('one', 'click', function () {
|
|
647
|
+
# # $('two').show();
|
|
648
|
+
# # });
|
|
649
|
+
# update_page do |page|
|
|
650
|
+
# page.event.observe('one', 'click') do |p|
|
|
651
|
+
# p[:two].show
|
|
652
|
+
# end
|
|
653
|
+
# end
|
|
654
|
+
#
|
|
634
655
|
# You can also use PrototypeHelper#update_page_tag instead of
|
|
635
656
|
# PrototypeHelper#update_page to wrap the generated JavaScript in a
|
|
636
657
|
# <script> tag.
|
|
@@ -666,7 +687,7 @@ module ActionView
|
|
|
666
687
|
end
|
|
667
688
|
end
|
|
668
689
|
|
|
669
|
-
# Returns an object whose <tt
|
|
690
|
+
# Returns an object whose <tt>to_json</tt> evaluates to +code+. Use this to pass a literal JavaScript
|
|
670
691
|
# expression as an argument to another JavaScriptGenerator method.
|
|
671
692
|
def literal(code)
|
|
672
693
|
ActiveSupport::JSON::Variable.new(code.to_s)
|
|
@@ -716,11 +737,11 @@ module ActionView
|
|
|
716
737
|
# # Insert the rendered 'navigation' partial just before the DOM
|
|
717
738
|
# # element with ID 'content'.
|
|
718
739
|
# # Generates: new Insertion.Before("content", "-- Contents of 'navigation' partial --");
|
|
719
|
-
# insert_html :before, 'content', :partial => 'navigation'
|
|
740
|
+
# page.insert_html :before, 'content', :partial => 'navigation'
|
|
720
741
|
#
|
|
721
742
|
# # Add a list item to the bottom of the <ul> with ID 'list'.
|
|
722
743
|
# # Generates: new Insertion.Bottom("list", "<li>Last item</li>");
|
|
723
|
-
# insert_html :bottom, 'list', '<li>Last item</li>'
|
|
744
|
+
# page.insert_html :bottom, 'list', '<li>Last item</li>'
|
|
724
745
|
#
|
|
725
746
|
def insert_html(position, id, *options_for_render)
|
|
726
747
|
insertion = position.to_s.camelize
|
|
@@ -735,7 +756,7 @@ module ActionView
|
|
|
735
756
|
# # Replace the HTML of the DOM element having ID 'person-45' with the
|
|
736
757
|
# # 'person' partial for the appropriate object.
|
|
737
758
|
# # Generates: Element.update("person-45", "-- Contents of 'person' partial --");
|
|
738
|
-
# replace_html 'person-45', :partial => 'person', :object => @person
|
|
759
|
+
# page.replace_html 'person-45', :partial => 'person', :object => @person
|
|
739
760
|
#
|
|
740
761
|
def replace_html(id, *options_for_render)
|
|
741
762
|
call 'Element.update', id, render(*options_for_render)
|
|
@@ -749,7 +770,7 @@ module ActionView
|
|
|
749
770
|
#
|
|
750
771
|
# # Replace the DOM element having ID 'person-45' with the
|
|
751
772
|
# # 'person' partial for the appropriate object.
|
|
752
|
-
# replace 'person-45', :partial => 'person', :object => @person
|
|
773
|
+
# page.replace 'person-45', :partial => 'person', :object => @person
|
|
753
774
|
#
|
|
754
775
|
# This allows the same partial that is used for the +insert_html+ to
|
|
755
776
|
# be also used for the input to +replace+ without resorting to
|
|
@@ -843,7 +864,8 @@ module ActionView
|
|
|
843
864
|
# # Generates: window.location.href = "/account/signup";
|
|
844
865
|
# page.redirect_to(:controller => 'account', :action => 'signup')
|
|
845
866
|
def redirect_to(location)
|
|
846
|
-
|
|
867
|
+
url = location.is_a?(String) ? location : @context.url_for(location)
|
|
868
|
+
record "window.location.href = #{url.inspect}"
|
|
847
869
|
end
|
|
848
870
|
|
|
849
871
|
# Calls the JavaScript +function+, optionally with the given +arguments+.
|
|
@@ -854,12 +876,21 @@ module ActionView
|
|
|
854
876
|
#
|
|
855
877
|
# Examples:
|
|
856
878
|
#
|
|
857
|
-
#
|
|
858
|
-
#
|
|
859
|
-
#
|
|
860
|
-
#
|
|
861
|
-
#
|
|
862
|
-
#
|
|
879
|
+
# # Generates: Element.replace(my_element, "My content to replace with.")
|
|
880
|
+
# page.call 'Element.replace', 'my_element', "My content to replace with."
|
|
881
|
+
#
|
|
882
|
+
# # Generates: alert('My message!')
|
|
883
|
+
# page.call 'alert', 'My message!'
|
|
884
|
+
#
|
|
885
|
+
# # Generates:
|
|
886
|
+
# # my_method(function() {
|
|
887
|
+
# # $("one").show();
|
|
888
|
+
# # $("two").hide();
|
|
889
|
+
# # });
|
|
890
|
+
# page.call(:my_method) do |p|
|
|
891
|
+
# p[:one].show
|
|
892
|
+
# p[:two].hide
|
|
893
|
+
# end
|
|
863
894
|
def call(function, *arguments, &block)
|
|
864
895
|
record "#{function}(#{arguments_for_call(arguments, block)})"
|
|
865
896
|
end
|
|
@@ -1037,7 +1068,7 @@ module ActionView
|
|
|
1037
1068
|
|
|
1038
1069
|
def build_observer(klass, name, options = {})
|
|
1039
1070
|
if options[:with] && (options[:with] !~ /[\{=(.]/)
|
|
1040
|
-
options[:with] = "'#{options[:with]}=' + value"
|
|
1071
|
+
options[:with] = "'#{options[:with]}=' + encodeURIComponent(value)"
|
|
1041
1072
|
else
|
|
1042
1073
|
options[:with] ||= 'value' unless options[:function]
|
|
1043
1074
|
end
|
|
@@ -1065,7 +1096,8 @@ module ActionView
|
|
|
1065
1096
|
end
|
|
1066
1097
|
|
|
1067
1098
|
# Converts chained method calls on DOM proxy elements into JavaScript chains
|
|
1068
|
-
class JavaScriptProxy < BasicObject #:nodoc:
|
|
1099
|
+
class JavaScriptProxy < ActiveSupport::BasicObject #:nodoc:
|
|
1100
|
+
|
|
1069
1101
|
def initialize(generator, root = nil)
|
|
1070
1102
|
@generator = generator
|
|
1071
1103
|
@generator << root if root
|
|
@@ -1141,7 +1173,7 @@ module ActionView
|
|
|
1141
1173
|
super(generator)
|
|
1142
1174
|
end
|
|
1143
1175
|
|
|
1144
|
-
# The JSON Encoder calls this to check for the
|
|
1176
|
+
# The JSON Encoder calls this to check for the +to_json+ method
|
|
1145
1177
|
# Since it's a blank slate object, I suppose it responds to anything.
|
|
1146
1178
|
def respond_to?(method)
|
|
1147
1179
|
true
|
|
@@ -1203,7 +1235,7 @@ module ActionView
|
|
|
1203
1235
|
append_enumerable_function!("zip(#{arguments_for_call arguments}")
|
|
1204
1236
|
if block
|
|
1205
1237
|
function_chain[-1] += ", function(array) {"
|
|
1206
|
-
yield ActiveSupport::JSON::Variable.new('array')
|
|
1238
|
+
yield ::ActiveSupport::JSON::Variable.new('array')
|
|
1207
1239
|
add_return_statement!
|
|
1208
1240
|
@generator << '});'
|
|
1209
1241
|
else
|
|
@@ -2,7 +2,7 @@ module ActionView
|
|
|
2
2
|
module Helpers
|
|
3
3
|
module RecordTagHelper
|
|
4
4
|
# Produces a wrapper DIV element with id and class parameters that
|
|
5
|
-
# relate to the specified
|
|
5
|
+
# relate to the specified Active Record object. Usage example:
|
|
6
6
|
#
|
|
7
7
|
# <% div_for(@person, :class => "foo") do %>
|
|
8
8
|
# <%=h @person.name %>
|
|
@@ -17,14 +17,14 @@ module ActionView
|
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
# content_tag_for creates an HTML element with id and class parameters
|
|
20
|
-
# that relate to the specified
|
|
20
|
+
# that relate to the specified Active Record object. For example:
|
|
21
21
|
#
|
|
22
22
|
# <% content_tag_for(:tr, @person) do %>
|
|
23
23
|
# <td><%=h @person.first_name %></td>
|
|
24
24
|
# <td><%=h @person.last_name %></td>
|
|
25
25
|
# <% end %>
|
|
26
26
|
#
|
|
27
|
-
# would produce
|
|
27
|
+
# would produce the following HTML (assuming @person is an instance of
|
|
28
28
|
# a Person object, with an id value of 123):
|
|
29
29
|
#
|
|
30
30
|
# <tr id="person_123" class="person">....</tr>
|
|
@@ -10,7 +10,7 @@ module ActionView
|
|
|
10
10
|
base.extend(ClassMethods)
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
# This
|
|
13
|
+
# This +sanitize+ helper will html encode all tags and strip all attributes that aren't specifically allowed.
|
|
14
14
|
# It also strips href/src tags with invalid protocols, like javascript: especially. It does its best to counter any
|
|
15
15
|
# tricks that hackers may use, like throwing in unicode/ascii/hex values to get past the javascript: filters. Check out
|
|
16
16
|
# the extensive test suite.
|
|
@@ -18,7 +18,7 @@ module ActionView
|
|
|
18
18
|
# <%= sanitize @article.body %>
|
|
19
19
|
#
|
|
20
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
|
|
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
22
|
#
|
|
23
23
|
# Normal Use
|
|
24
24
|
#
|
|
@@ -48,11 +48,16 @@ module ActionView
|
|
|
48
48
|
# config.action_view.sanitized_allowed_attributes = 'id', 'class', 'style'
|
|
49
49
|
# end
|
|
50
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
|
+
#
|
|
51
56
|
def sanitize(html, options = {})
|
|
52
57
|
self.class.white_list_sanitizer.sanitize(html, options)
|
|
53
58
|
end
|
|
54
59
|
|
|
55
|
-
# Sanitizes a block of
|
|
60
|
+
# Sanitizes a block of CSS code. Used by +sanitize+ when it comes across a style attribute.
|
|
56
61
|
def sanitize_css(style)
|
|
57
62
|
self.class.white_list_sanitizer.sanitize_css(style)
|
|
58
63
|
end
|
|
@@ -106,8 +111,8 @@ module ActionView
|
|
|
106
111
|
end
|
|
107
112
|
end
|
|
108
113
|
|
|
109
|
-
# Gets the HTML::FullSanitizer instance used by strip_tags
|
|
110
|
-
# any object that responds to
|
|
114
|
+
# Gets the HTML::FullSanitizer instance used by +strip_tags+. Replace with
|
|
115
|
+
# any object that responds to +sanitize+.
|
|
111
116
|
#
|
|
112
117
|
# Rails::Initializer.run do |config|
|
|
113
118
|
# config.action_view.full_sanitizer = MySpecialSanitizer.new
|
|
@@ -117,8 +122,8 @@ module ActionView
|
|
|
117
122
|
@full_sanitizer ||= HTML::FullSanitizer.new
|
|
118
123
|
end
|
|
119
124
|
|
|
120
|
-
# Gets the HTML::LinkSanitizer instance used by strip_links
|
|
121
|
-
# any object that responds to
|
|
125
|
+
# Gets the HTML::LinkSanitizer instance used by +strip_links+. Replace with
|
|
126
|
+
# any object that responds to +sanitize+.
|
|
122
127
|
#
|
|
123
128
|
# Rails::Initializer.run do |config|
|
|
124
129
|
# config.action_view.link_sanitizer = MySpecialSanitizer.new
|
|
@@ -128,8 +133,8 @@ module ActionView
|
|
|
128
133
|
@link_sanitizer ||= HTML::LinkSanitizer.new
|
|
129
134
|
end
|
|
130
135
|
|
|
131
|
-
# Gets the HTML::WhiteListSanitizer instance used by sanitize and sanitize_css
|
|
132
|
-
# Replace with any object that responds to
|
|
136
|
+
# Gets the HTML::WhiteListSanitizer instance used by sanitize and +sanitize_css+.
|
|
137
|
+
# Replace with any object that responds to +sanitize+.
|
|
133
138
|
#
|
|
134
139
|
# Rails::Initializer.run do |config|
|
|
135
140
|
# config.action_view.white_list_sanitizer = MySpecialSanitizer.new
|
|
@@ -139,7 +144,7 @@ module ActionView
|
|
|
139
144
|
@white_list_sanitizer ||= HTML::WhiteListSanitizer.new
|
|
140
145
|
end
|
|
141
146
|
|
|
142
|
-
# Adds valid HTML attributes that the
|
|
147
|
+
# Adds valid HTML attributes that the +sanitize+ helper checks for URIs.
|
|
143
148
|
#
|
|
144
149
|
# Rails::Initializer.run do |config|
|
|
145
150
|
# config.action_view.sanitized_uri_attributes = 'lowsrc', 'target'
|
|
@@ -149,7 +154,7 @@ module ActionView
|
|
|
149
154
|
HTML::WhiteListSanitizer.uri_attributes.merge(attributes)
|
|
150
155
|
end
|
|
151
156
|
|
|
152
|
-
# Adds to the Set of 'bad' tags for the
|
|
157
|
+
# Adds to the Set of 'bad' tags for the +sanitize+ helper.
|
|
153
158
|
#
|
|
154
159
|
# Rails::Initializer.run do |config|
|
|
155
160
|
# config.action_view.sanitized_bad_tags = 'embed', 'object'
|
|
@@ -158,7 +163,8 @@ module ActionView
|
|
|
158
163
|
def sanitized_bad_tags=(attributes)
|
|
159
164
|
HTML::WhiteListSanitizer.bad_tags.merge(attributes)
|
|
160
165
|
end
|
|
161
|
-
|
|
166
|
+
|
|
167
|
+
# Adds to the Set of allowed tags for the +sanitize+ helper.
|
|
162
168
|
#
|
|
163
169
|
# Rails::Initializer.run do |config|
|
|
164
170
|
# config.action_view.sanitized_allowed_tags = 'table', 'tr', 'td'
|
|
@@ -168,7 +174,7 @@ module ActionView
|
|
|
168
174
|
HTML::WhiteListSanitizer.allowed_tags.merge(attributes)
|
|
169
175
|
end
|
|
170
176
|
|
|
171
|
-
# Adds to the Set of allowed
|
|
177
|
+
# Adds to the Set of allowed HTML attributes for the +sanitize+ helper.
|
|
172
178
|
#
|
|
173
179
|
# Rails::Initializer.run do |config|
|
|
174
180
|
# config.action_view.sanitized_allowed_attributes = 'onclick', 'longdesc'
|
|
@@ -178,7 +184,7 @@ module ActionView
|
|
|
178
184
|
HTML::WhiteListSanitizer.allowed_attributes.merge(attributes)
|
|
179
185
|
end
|
|
180
186
|
|
|
181
|
-
# Adds to the Set of allowed
|
|
187
|
+
# Adds to the Set of allowed CSS properties for the #sanitize and +sanitize_css+ heleprs.
|
|
182
188
|
#
|
|
183
189
|
# Rails::Initializer.run do |config|
|
|
184
190
|
# config.action_view.sanitized_allowed_css_properties = 'expression'
|
|
@@ -188,7 +194,7 @@ module ActionView
|
|
|
188
194
|
HTML::WhiteListSanitizer.allowed_css_properties.merge(attributes)
|
|
189
195
|
end
|
|
190
196
|
|
|
191
|
-
# Adds to the Set of allowed
|
|
197
|
+
# Adds to the Set of allowed CSS keywords for the +sanitize+ and +sanitize_css+ helpers.
|
|
192
198
|
#
|
|
193
199
|
# Rails::Initializer.run do |config|
|
|
194
200
|
# config.action_view.sanitized_allowed_css_keywords = 'expression'
|
|
@@ -198,7 +204,7 @@ module ActionView
|
|
|
198
204
|
HTML::WhiteListSanitizer.allowed_css_keywords.merge(attributes)
|
|
199
205
|
end
|
|
200
206
|
|
|
201
|
-
# Adds to the Set of allowed shorthand
|
|
207
|
+
# Adds to the Set of allowed shorthand CSS properties for the +sanitize+ and +sanitize_css+ helpers.
|
|
202
208
|
#
|
|
203
209
|
# Rails::Initializer.run do |config|
|
|
204
210
|
# config.action_view.sanitized_shorthand_css_properties = 'expression'
|
|
@@ -208,7 +214,7 @@ module ActionView
|
|
|
208
214
|
HTML::WhiteListSanitizer.shorthand_css_properties.merge(attributes)
|
|
209
215
|
end
|
|
210
216
|
|
|
211
|
-
# Adds to the Set of allowed protocols for the
|
|
217
|
+
# Adds to the Set of allowed protocols for the +sanitize+ helper.
|
|
212
218
|
#
|
|
213
219
|
# Rails::Initializer.run do |config|
|
|
214
220
|
# config.action_view.sanitized_allowed_protocols = 'ssh', 'feed'
|