Fix JavaScriptHelper capitalization and make it compatible with Prototype #1545 [Sam Stephenson]

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@1561 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
上级 0ffcceff
......@@ -168,13 +168,13 @@ A short rundown of the major features:
{Learn more}[link:classes/ActionController/Base.html]
* Javascript and Ajax integration.
* JavaScript and Ajax integration.
link_to_function "Greeting", "alert('Hello world!')"
link_to_remote "Delete this post", :update => "posts",
:url => { :action => "destroy", :id => post.id }
{Learn more}[link:classes/ActionView/Helpers/JavascriptHelper.html]
{Learn more}[link:classes/ActionView/Helpers/JavaScriptHelper.html]
* Pagination for navigating lists of results.
......
......@@ -2,19 +2,19 @@
module ActionView
module Helpers
# Provides a set of helpers for calling Javascript functions and, most importantly, to call remote methods using what has
# Provides a set of helpers for calling JavaScript functions and, most importantly, to call remote methods using what has
# been labelled Ajax[http://www.adaptivepath.com/publications/essays/archives/000385.php]. This means that you can call
# actions in your controllers without reloading the page, but still update certain parts of it using injections into the
# DOM. The common use case is having a form that adds a new element to a list without reloading the page.
#
# To be able to use the Javascript helpers, you must either call <tt><%= define_javascript_functions %></tt> (which returns all
# the Javascript support functions in a <script> block) or reference the Javascript library using
# To be able to use the JavaScript helpers, you must either call <tt><%= define_javascript_functions %></tt> (which returns all
# the JavaScript support functions in a <script> block) or reference the JavaScript library using
# <tt><%= javascript_include_tag "prototype" %></tt> (which looks for the library in /javascripts/prototype.js). The latter is
# recommended as the browser can then cache the library instead of fetching all the functions anew on every request.
#
# If you're the visual type, there's an Ajax movie[http://www.rubyonrails.com/media/video/rails-ajax.mov] demonstrating
# the use of form_remote_tag.
module JavascriptHelper
module JavaScriptHelper
unless const_defined? :CALLBACKS
CALLBACKS =
[:uninitialized, :loading, :loaded, :interactive, :complete, :failure].push((100..599).to_a).flatten
......@@ -101,7 +101,7 @@ def link_to_function(name, function, html_options = {})
# <tt>options[:type] = :synchronous</tt>.
#
# You can customize further browser side call logic by passing
# in Javascript code snippets via some optional parameters. In
# in JavaScript code snippets via some optional parameters. In
# their order of use these are:
#
# <tt>:confirm</tt>:: Adds confirmation dialog.
......@@ -126,11 +126,11 @@ def periodically_call_remote(options = {})
end
# Returns a form tag that will submit using XMLHttpRequest in the background instead of the regular
# reloading POST arrangement. Even though it's using Javascript to serialize the form elements, the form submission
# reloading POST arrangement. Even though it's using JavaScript to serialize the form elements, the form submission
# will work just like a regular submission as viewed by the receiving side (all elements available in @params).
# The options for specifying the target with :url and defining callbacks is the same as link_to_remote.
#
# A "fall-through" target for browsers that doesn't do Javascript can be specified with the :action/:method options on :html
# A "fall-through" target for browsers that doesn't do JavaScript can be specified with the :action/:method options on :html
#
# form_remote_tag :html => { :action => url_for(:controller => "some", :action => "place") }
#
......@@ -186,7 +186,7 @@ def remote_function(options) #:nodoc: for now
return function
end
# Includes the Action Pack Javascript libraries inside a single <script>
# Includes the Action Pack JavaScript libraries inside a single <script>
# tag. The function first includes prototype.js and then its core extensions,
# (determined by filenames starting with "prototype").
# Afterwards, any additional scripts will be included in random order.
......@@ -226,7 +226,7 @@ def define_javascript_functions
# <tt>:update</tt>:: Specifies the DOM ID of the element whose
# innerHTML should be updated with the
# XMLHttpRequest response text.
# <tt>:with</tt>:: A Javascript expression specifying the
# <tt>:with</tt>:: A JavaScript expression specifying the
# parameters for the XMLHttpRequest. This defaults
# to 'value', which in the evaluated context
# refers to the new field value.
......@@ -270,7 +270,7 @@ def observe_form(form_id, options = {})
# innerHTML should be updated with the autocomplete
# entries returned by the Ajax request.
# Defaults to field_id + '_auto_complete'
# <tt>:with</tt>:: A Javascript expression specifying the
# <tt>:with</tt>:: A JavaScript expression specifying the
# parameters for the XMLHttpRequest. This defaults
# to 'value', which in the evaluated context
# refers to the new field value.
......@@ -351,12 +351,12 @@ def sortable_element(element_id, options = {})
javascript_tag("Sortable.create('#{element_id}', #{options_for_javascript(options)})")
end
# Escape carrier returns and single and double quotes for Javascript segments.
# Escape carrier returns and single and double quotes for JavaScript segments.
def escape_javascript(javascript)
(javascript || '').gsub(/\r\n|\n|\r/, "\\n").gsub(/["']/) { |m| "\\#{m}" }
end
# Returns a Javascript tag with the +content+ inside. Example:
# Returns a JavaScript tag with the +content+ inside. Example:
# javascript_tag "alert('All is good')" # => <script type="text/javascript">alert('All is good')</script>
def javascript_tag(content)
content_tag("script", content, :type => "text/javascript")
......@@ -373,7 +373,7 @@ def options_for_ajax(options)
js_options['asynchronous'] = options[:type] != :synchronous
js_options['method'] = method_option_to_s(options[:method]) if options[:method]
js_options['insertion'] = "Insertion.#{options[:position].to_s.camelize}" if options[:position]
js_options['script'] = options[:script] == true if options[:script]
js_options['evalScripts'] = options[:script] == true if options[:script]
if options[:form]
js_options['parameters'] = 'Form.serialize(this)'
......@@ -437,5 +437,7 @@ def auto_complete_stylesheet
)
end
end
JavascriptHelper = JavaScriptHelper unless const_defined? :JavascriptHelper
end
end
require File.dirname(__FILE__) + '/../abstract_unit'
class JavascriptHelperTest < Test::Unit::TestCase
include ActionView::Helpers::JavascriptHelper
class JavaScriptHelperTest < Test::Unit::TestCase
include ActionView::Helpers::JavaScriptHelper
include ActionView::Helpers::UrlHelper
include ActionView::Helpers::TagHelper
......@@ -19,7 +19,7 @@ def url_for(options, *parameters_for_method_reference)
def test_define_javascript_functions
# check if prototype.js is included first
assert_not_nil define_javascript_functions.split("\n")[1].match(/Prototype: an object-oriented Javascript library/)
assert_not_nil define_javascript_functions.split("\n")[1].match(/Prototype JavaScript framework/)
end
def test_escape_javascript
......
......@@ -39,7 +39,7 @@ class UploadProgressHelperTest < Test::Unit::TestCase
include ActionView::Helpers::FormTagHelper
include ActionView::Helpers::TagHelper
include ActionView::Helpers::UrlHelper
include ActionView::Helpers::JavascriptHelper
include ActionView::Helpers::JavaScriptHelper
include ActionView::Helpers::UploadProgressHelper
def next_upload_id; @upload_id = last_upload_id.succ; end
......@@ -175,7 +175,7 @@ class UploadProgressHelperTest < Test::Unit::TestCase
include ActionView::Helpers::FormTagHelper
include ActionView::Helpers::TagHelper
include ActionView::Helpers::UrlHelper
include ActionView::Helpers::JavascriptHelper
include ActionView::Helpers::JavaScriptHelper
include ActionView::Helpers::UploadProgressHelper
def next_upload_id; @upload_id = last_upload_id.succ; end
......@@ -258,14 +258,14 @@ def test_finish_upload_status
def test_form_tag_with_upload_progress
assert_equal(
"<form action=\"http://www.example.com\" enctype=\"multipart/form-data\" method=\"post\" onsubmit=\"if (this.action.indexOf('upload_id') &lt; 0){ this.action += '?upload_id=1'; }this.target = 'UploadTarget1';$('UploadStatus1').innerHTML='Upload starting...'; $('UploadProgressBar1').firstChild.firstChild.style.width='0%'; if (document.uploadStatus1) { document.uploadStatus1.stop(); }document.uploadStatus1 = new Ajax.PeriodicalUpdater('UploadStatus1','http://www.example.com', {script:true, onComplete:function(request){$('UploadStatus1').innerHTML='A message';$('UploadProgressBar1').firstChild.firstChild.style.width='100%';document.uploadStatus1 = null}, asynchronous:true}.extend({decay:1.8,freqency:2.0})); return true\"><iframe id=\"UploadTarget1\" name=\"UploadTarget1\" src=\"\" style=\"width:0px;height:0px;border:0\"></iframe>",
"<form action=\"http://www.example.com\" enctype=\"multipart/form-data\" method=\"post\" onsubmit=\"if (this.action.indexOf('upload_id') &lt; 0){ this.action += '?upload_id=1'; }this.target = 'UploadTarget1';$('UploadStatus1').innerHTML='Upload starting...'; $('UploadProgressBar1').firstChild.firstChild.style.width='0%'; if (document.uploadStatus1) { document.uploadStatus1.stop(); }document.uploadStatus1 = new Ajax.PeriodicalUpdater('UploadStatus1','http://www.example.com', {onComplete:function(request){$('UploadStatus1').innerHTML='A message';$('UploadProgressBar1').firstChild.firstChild.style.width='100%';document.uploadStatus1 = null}, evalScripts:true, asynchronous:true}.extend({decay:1.8,freqency:2.0})); return true\"><iframe id=\"UploadTarget1\" name=\"UploadTarget1\" src=\"\" style=\"width:0px;height:0px;border:0\"></iframe>",
form_tag_with_upload_progress
)
end
def test_form_tag_with_upload_progress_custom
assert_equal(
"<form action=\"http://www.example.com\" enctype=\"multipart/form-data\" method=\"post\" onsubmit=\"if (this.action.indexOf('upload_id') &lt; 0){ this.action += '?upload_id=5'; }this.target = 'awindow';$('UploadStatus0').innerHTML='Upload starting...'; $('UploadProgressBar0').firstChild.firstChild.style.width='0%'; alert('foo'); if (document.uploadStatus0) { document.uploadStatus0.stop(); }document.uploadStatus0 = new Ajax.PeriodicalUpdater('UploadStatus0','http://www.example.com', {script:true, onComplete:function(request){$('UploadStatus0').innerHTML='A message';$('UploadProgressBar0').firstChild.firstChild.style.width='100%';document.uploadStatus0 = null; alert('bar')}, asynchronous:true}.extend({decay:7,freqency:6})); return true\" target=\"awindow\">",
"<form action=\"http://www.example.com\" enctype=\"multipart/form-data\" method=\"post\" onsubmit=\"if (this.action.indexOf('upload_id') &lt; 0){ this.action += '?upload_id=5'; }this.target = 'awindow';$('UploadStatus0').innerHTML='Upload starting...'; $('UploadProgressBar0').firstChild.firstChild.style.width='0%'; alert('foo'); if (document.uploadStatus0) { document.uploadStatus0.stop(); }document.uploadStatus0 = new Ajax.PeriodicalUpdater('UploadStatus0','http://www.example.com', {onComplete:function(request){$('UploadStatus0').innerHTML='A message';$('UploadProgressBar0').firstChild.firstChild.style.width='100%';document.uploadStatus0 = null; alert('bar')}, evalScripts:true, asynchronous:true}.extend({decay:7,freqency:6})); return true\" target=\"awindow\">",
form_tag_with_upload_progress({:upload_id => 5}, {:begin => "alert('foo')", :finish => "alert('bar')", :frequency => 6, :decay => 7, :target => 'awindow'})
)
end
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册