diff options
-rw-r--r-- | actionpack/README | 77 | ||||
-rw-r--r-- | actionpack/lib/action_view/helpers/javascript_helper.rb | 54 | ||||
-rw-r--r-- | actionpack/lib/action_view/helpers/prototype_helper.rb | 141 | ||||
-rw-r--r-- | actionpack/lib/action_view/helpers/scriptaculous_helper.rb | 101 | ||||
-rw-r--r-- | actionpack/test/template/javascript_helper_test.rb | 29 | ||||
-rw-r--r-- | actionpack/test/template/prototype_helper_test.rb | 28 |
6 files changed, 82 insertions, 348 deletions
diff --git a/actionpack/README b/actionpack/README index e4ce4aa044..8bdcb9120a 100644 --- a/actionpack/README +++ b/actionpack/README @@ -37,15 +37,15 @@ A short rundown of the major features: def show @customer = find_customer end - + def update @customer = find_customer @customer.attributes = params[:customer] - @customer.save ? + @customer.save ? redirect_to(:action => "show") : render(:action => "edit") end - + private def find_customer() Customer.find(params[:id]) end end @@ -64,7 +64,7 @@ A short rundown of the major features: <% unless @person.is_client? %> Not for clients to see... <% end %> - + {Learn more}[link:classes/ActionView.html] @@ -99,24 +99,24 @@ A short rundown of the major features: before_filter :authenticate, :cache, :audit after_filter { |c| c.response.body = Gzip::compress(c.response.body) } after_filter LocalizeFilter - + def index # Before this action is run, the user will be authenticated, the cache # will be examined to see if a valid copy of the results already # exists, and the action will be logged for auditing. - - # After this action has run, the output will first be localized then + + # After this action has run, the output will first be localized then # compressed to minimize bandwidth usage end - + private def authenticate # Implement the filter with full access to both request and response end end - + {Learn more}[link:classes/ActionController/Filters/ClassMethods.html] - + * Helpers for forms, dates, action links, and text @@ -124,26 +124,26 @@ A short rundown of the major features: <%= html_date_select(Date.today) %> <%= link_to "New post", :controller => "post", :action => "new" %> <%= truncate(post.title, :length => 25) %> - + {Learn more}[link:classes/ActionView/Helpers.html] -* Layout sharing for template reuse (think simple version of Struts +* Layout sharing for template reuse (think simple version of Struts Tiles[http://jakarta.apache.org/struts/userGuide/dev_tiles.html]) class WeblogController < ActionController::Base layout "weblog_layout" - + def hello_world end end Layout file (called weblog_layout): <html><body><%= yield %></body></html> - + Template for hello_world action: <h1>Hello world</h1> - + Result of running hello_world action: <html><body><h1>Hello world</h1></body></html> @@ -156,9 +156,9 @@ A short rundown of the major features: Accessing /clients/37signals/basecamp/project/dash calls ProjectController#dash with { "client_name" => "37signals", "project_name" => "basecamp" } in params[:params] - + From that URL, you can rewrite the redirect in a number of ways: - + redirect_to(:action => "edit") => /clients/37signals/basecamp/project/dash @@ -168,15 +168,6 @@ A short rundown of the major features: {Learn more}[link:classes/ActionController/Base.html] -* 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] - - * Easy testing of both controller and rendered template through ActionController::TestCase class LoginControllerTest < ActionController::TestCase @@ -218,18 +209,18 @@ A short rundown of the major features: class WeblogController < ActionController::Base caches_page :show caches_action :account - + def show - # the output of the method will be cached as + # the output of the method will be cached as # ActionController::Base.page_cache_directory + "/weblog/show/n.html" # and the web server will pick it up without even hitting Rails end - + def account # the output of the method will be cached in the fragment store # but Rails is hit to retrieve it, so filters are run end - + def update List.update(params[:list][:id], params[:list]) expire_page :action => "show", :id => params[:list][:id] @@ -256,26 +247,26 @@ A short rundown of the major features: class AccountController < ActionController::Base scaffold :account end - + The AccountController now has the full CRUD range of actions and default templates: list, show, destroy, new, create, edit, update - + {Learn more}[link:classes/ActionController/Scaffolding/ClassMethods.html] * Form building for Active Record model objects - The post object has a title (varchar), content (text), and + The post object has a title (varchar), content (text), and written_on (date) <%= form "post" %> - + ...will generate something like (the selects will have more options, of course): - + <form action="create" method="POST"> <p> - <b>Title:</b><br/> + <b>Title:</b><br/> <input type="text" name="post[title]" value="<%= @post.title %>" /> </p> <p> @@ -293,7 +284,7 @@ A short rundown of the major features: </form> This form generates a params[:post] array that can be used directly in a save action: - + class WeblogController < ActionController::Base def create post = Post.create(params[:post]) @@ -318,19 +309,19 @@ methods: class WeblogController < ActionController::Base layout "weblog/layout" - + def index @posts = Post.find(:all) end - + def show @post = Post.find(params[:id]) end - + def new @post = Post.new end - + def create @post = Post.create(params[:post]) redirect_to :action => "show", :id => @post.id @@ -364,7 +355,7 @@ And the templates look like this: weblog/new.html.erb: <%= form "post" %> - + This simple setup will list all the posts in the system on the index page, which is called by accessing /weblog/. It uses the form builder for the Active Record model to make the new screen, which in turn hands everything over to @@ -379,7 +370,7 @@ The latest version of Action Pack can be found at * http://rubyforge.org/project/showfiles.php?group_id=249 -Documentation can be found at +Documentation can be found at * http://api.rubyonrails.com diff --git a/actionpack/lib/action_view/helpers/javascript_helper.rb b/actionpack/lib/action_view/helpers/javascript_helper.rb index 06a9d3405a..f9249e667d 100644 --- a/actionpack/lib/action_view/helpers/javascript_helper.rb +++ b/actionpack/lib/action_view/helpers/javascript_helper.rb @@ -41,60 +41,6 @@ module ActionView include PrototypeHelper - # Returns a link of the given +name+ that will trigger a JavaScript +function+ using the - # onclick handler and return false after the fact. - # - # The first argument +name+ is used as the link text. - # - # The next arguments are optional and may include the javascript function definition and a hash of html_options. - # - # The +function+ argument can be omitted in favor of an +update_page+ - # block, which evaluates to a string when the template is rendered - # (instead of making an Ajax request first). - # - # The +html_options+ will accept a hash of html attributes for the link tag. Some examples are :class => "nav_button", :id => "articles_nav_button" - # - # 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 - # - # - # Examples: - # link_to_function "Greeting", "alert('Hello world!')" - # Produces: - # <a onclick="alert('Hello world!'); return false;" href="#">Greeting</a> - # - # link_to_function(image_tag("delete"), "if (confirm('Really?')) do_delete()") - # Produces: - # <a onclick="if (confirm('Really?')) do_delete(); return false;" href="#"> - # <img src="/images/delete.png?" alt="Delete"/> - # </a> - # - # link_to_function("Show me more", nil, :id => "more_link") do |page| - # page[:details].visual_effect :toggle_blind - # page[:more_link].replace_html "Show me less" - # end - # Produces: - # <a href="#" id="more_link" onclick="try { - # $("details").visualEffect("toggle_blind"); - # $("more_link").update("Show me less"); - # } - # catch (e) { - # alert('RJS error:\n\n' + e.toString()); - # alert('$(\"details\").visualEffect(\"toggle_blind\"); - # \n$(\"more_link\").update(\"Show me less\");'); - # throw e - # }; - # return false;">Show me more</a> - # - def link_to_function(name, *args, &block) - html_options = args.extract_options!.symbolize_keys - - function = block_given? ? update_page(&block) : args[0] || '' - onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function}; return false;" - href = html_options[:href] || '#' - - content_tag(:a, name, html_options.merge(:href => href, :onclick => onclick)) - end - # Returns a button with the given +name+ text that'll trigger a JavaScript +function+ using the # onclick handler. # diff --git a/actionpack/lib/action_view/helpers/prototype_helper.rb b/actionpack/lib/action_view/helpers/prototype_helper.rb index 0ec7b48c25..56a7198792 100644 --- a/actionpack/lib/action_view/helpers/prototype_helper.rb +++ b/actionpack/lib/action_view/helpers/prototype_helper.rb @@ -102,147 +102,6 @@ module ActionView :form, :with, :update, :script, :type ]).merge(CALLBACKS) end - # Returns a link to a remote action defined by <tt>options[:url]</tt> - # (using the url_for format) that's called in the background using - # XMLHttpRequest. The result of that request can then be inserted into a - # DOM object whose id can be specified with <tt>options[:update]</tt>. - # Usually, the result would be a partial prepared by the controller with - # render :partial. - # - # Examples: - # # Generates: <a href="#" onclick="new Ajax.Updater('posts', '/blog/destroy/3', {asynchronous:true, evalScripts:true}); - # # return false;">Delete this post</a> - # link_to_remote "Delete this post", :update => "posts", - # :url => { :action => "destroy", :id => post.id } - # - # # Generates: <a href="#" onclick="new Ajax.Updater('emails', '/mail/list_emails', {asynchronous:true, evalScripts:true}); - # # return false;"><img alt="Refresh" src="/images/refresh.png?" /></a> - # link_to_remote(image_tag("refresh"), :update => "emails", - # :url => { :action => "list_emails" }) - # - # You can override the generated HTML options by specifying a hash in - # <tt>options[:html]</tt>. - # - # link_to_remote "Delete this post", :update => "posts", - # :url => post_url(@post), :method => :delete, - # :html => { :class => "destructive" } - # - # You can also specify a hash for <tt>options[:update]</tt> to allow for - # easy redirection of output to an other DOM element if a server-side - # error occurs: - # - # Example: - # # Generates: <a href="#" onclick="new Ajax.Updater({success:'posts',failure:'error'}, '/blog/destroy/5', - # # {asynchronous:true, evalScripts:true}); return false;">Delete this post</a> - # link_to_remote "Delete this post", - # :url => { :action => "destroy", :id => post.id }, - # :update => { :success => "posts", :failure => "error" } - # - # Optionally, you can use the <tt>options[:position]</tt> parameter to - # influence how the target DOM element is updated. It must be one of - # <tt>:before</tt>, <tt>:top</tt>, <tt>:bottom</tt>, or <tt>:after</tt>. - # - # The method used is by default POST. You can also specify GET or you - # can simulate PUT or DELETE over POST. All specified with <tt>options[:method]</tt> - # - # Example: - # # Generates: <a href="#" onclick="new Ajax.Request('/person/4', {asynchronous:true, evalScripts:true, method:'delete'}); - # # return false;">Destroy</a> - # link_to_remote "Destroy", :url => person_url(:id => person), :method => :delete - # - # By default, these remote requests are processed asynchronous during - # which various JavaScript callbacks can be triggered (for progress - # indicators and the likes). All callbacks get access to the - # <tt>request</tt> object, which holds the underlying XMLHttpRequest. - # - # To access the server response, use <tt>request.responseText</tt>, to - # find out the HTTP status, use <tt>request.status</tt>. - # - # Example: - # # Generates: <a href="#" onclick="new Ajax.Request('/words/undo?n=33', {asynchronous:true, evalScripts:true, - # # onComplete:function(request){undoRequestCompleted(request)}}); return false;">hello</a> - # word = 'hello' - # link_to_remote word, - # :url => { :action => "undo", :n => word_counter }, - # :complete => "undoRequestCompleted(request)" - # - # The callbacks that may be specified are (in order): - # - # <tt>:loading</tt>:: Called when the remote document is being - # loaded with data by the browser. - # <tt>:loaded</tt>:: Called when the browser has finished loading - # the remote document. - # <tt>:interactive</tt>:: Called when the user can interact with the - # remote document, even though it has not - # finished loading. - # <tt>:success</tt>:: Called when the XMLHttpRequest is completed, - # and the HTTP status code is in the 2XX range. - # <tt>:failure</tt>:: Called when the XMLHttpRequest is completed, - # and the HTTP status code is not in the 2XX - # range. - # <tt>:complete</tt>:: Called when the XMLHttpRequest is complete - # (fires after success/failure if they are - # present). - # - # You can further refine <tt>:success</tt> and <tt>:failure</tt> by - # adding additional callbacks for specific status codes. - # - # Example: - # # Generates: <a href="#" onclick="new Ajax.Request('/testing/action', {asynchronous:true, evalScripts:true, - # # on404:function(request){alert('Not found...? Wrong URL...?')}, - # # onFailure:function(request){alert('HTTP Error ' + request.status + '!')}}); return false;">hello</a> - # link_to_remote word, - # :url => { :action => "action" }, - # 404 => "alert('Not found...? Wrong URL...?')", - # :failure => "alert('HTTP Error ' + request.status + '!')" - # - # A status code callback overrides the success/failure handlers if - # present. - # - # If you for some reason or another need synchronous processing (that'll - # block the browser while the request is happening), you can specify - # <tt>options[:type] = :synchronous</tt>. - # - # You can customize further browser side call logic by passing in - # JavaScript code snippets via some optional parameters. In their order - # of use these are: - # - # <tt>:confirm</tt>:: Adds confirmation dialog. - # <tt>:condition</tt>:: Perform remote request conditionally - # by this expression. Use this to - # describe browser-side conditions when - # request should not be initiated. - # <tt>:before</tt>:: Called before request is initiated. - # <tt>:after</tt>:: Called immediately after request was - # initiated and before <tt>:loading</tt>. - # <tt>:submit</tt>:: Specifies the DOM element ID that's used - # as the parent of the form elements. By - # default this is the current form, but - # it could just as well be the ID of a - # table row or any other DOM element. - # <tt>:with</tt>:: A JavaScript expression specifying - # the parameters for the XMLHttpRequest. - # Any expressions should return a valid - # URL query string. - # - # Example: - # - # :with => "'name=' + $('name').value" - # - # You can generate a link that uses AJAX in the general case, while - # degrading gracefully to plain link behavior in the absence of - # JavaScript by setting <tt>html_options[:href]</tt> to an alternate URL. - # Note the extra curly braces around the <tt>options</tt> hash separate - # it as the second parameter from <tt>html_options</tt>, the third. - # - # Example: - # link_to_remote "Delete this post", - # { :update => "posts", :url => { :action => "destroy", :id => post.id } }, - # :href => url_for(:action => "destroy", :id => post.id) - def link_to_remote(name, options = {}, html_options = nil) - link_to_function(name, remote_function(options), html_options || options.delete(:html)) - end - # Creates a button with an onclick event which calls a remote action # via XMLHttpRequest # The options for specifying the target with :url diff --git a/actionpack/lib/action_view/helpers/scriptaculous_helper.rb b/actionpack/lib/action_view/helpers/scriptaculous_helper.rb index 04af2781d7..d30164e402 100644 --- a/actionpack/lib/action_view/helpers/scriptaculous_helper.rb +++ b/actionpack/lib/action_view/helpers/scriptaculous_helper.rb @@ -3,11 +3,11 @@ require 'active_support/json' module ActionView module Helpers - # Provides a set of helpers for calling Scriptaculous JavaScript + # Provides a set of helpers for calling Scriptaculous JavaScript # functions, including those which create Ajax controls and visual effects. # - # To be able to use these helpers, you must include the Prototype - # JavaScript framework and the Scriptaculous JavaScript library in your + # To be able to use these helpers, you must include the Prototype + # JavaScript framework and the Scriptaculous JavaScript library in your # pages. See the documentation for ActionView::Helpers::JavaScriptHelper # for more information on including the necessary JavaScript. # @@ -18,22 +18,17 @@ module ActionView unless const_defined? :TOGGLE_EFFECTS TOGGLE_EFFECTS = [:toggle_appear, :toggle_slide, :toggle_blind] end - + # Returns a JavaScript snippet to be used on the Ajax callbacks for # starting visual effects. # - # Example: - # <%= link_to_remote "Reload", :update => "posts", - # :url => { :action => "reload" }, - # :complete => visual_effect(:highlight, "posts", :duration => 0.5) - # # If no +element_id+ is given, it assumes "element" which should be a local - # variable in the generated JavaScript execution context. This can be + # variable in the generated JavaScript execution context. This can be # used for example with +drop_receiving_element+: # # <%= drop_receiving_element (...), :loading => visual_effect(:fade) %> # - # This would fade the element that was dropped on the drop receiving + # This would fade the element that was dropped on the drop receiving # element. # # For toggling visual effects, you can use <tt>:toggle_appear</tt>, <tt>:toggle_slide</tt>, and @@ -44,13 +39,13 @@ module ActionView # http://script.aculo.us for more documentation. def visual_effect(name, element_id = false, js_options = {}) element = element_id ? ActiveSupport::JSON.encode(element_id) : "element" - + js_options[:queue] = if js_options[:queue].is_a?(Hash) '{' + js_options[:queue].map {|k, v| k == :limit ? "#{k}:#{v}" : "#{k}:'#{v}'" }.join(',') + '}' elsif js_options[:queue] "'#{js_options[:queue]}'" end if js_options[:queue] - + [:endcolor, :direction, :startcolor, :scaleMode, :restorecolor].each do |option| js_options[option] = "'#{js_options[option]}'" if js_options[option] end @@ -61,7 +56,7 @@ module ActionView "new Effect.#{name.to_s.camelize}(#{element},#{options_for_javascript(js_options)});" end end - + # Makes the element with the DOM ID specified by +element_id+ sortable # by drag-and-drop and make an Ajax call whenever the sort order has # changed. By default, the action called gets the serialized sortable @@ -71,84 +66,84 @@ module ActionView # # <%= sortable_element("my_list", :url => { :action => "order" }) %> # - # In the example, the action gets a "my_list" array parameter - # containing the values of the ids of elements the sortable consists + # In the example, the action gets a "my_list" array parameter + # containing the values of the ids of elements the sortable consists # of, in the current order. # # Important: For this to work, the sortable elements must have id # attributes in the form "string_identifier". For example, "item_1". Only # the identifier part of the id attribute will be serialized. - # + # # Additional +options+ are: # # * <tt>:format</tt> - A regular expression to determine what to send as the # serialized id to the server (the default is <tt>/^[^_]*_(.*)$/</tt>). - # + # # * <tt>:constraint</tt> - Whether to constrain the dragging to either # <tt>:horizontal</tt> or <tt>:vertical</tt> (or false to make it unconstrained). - # + # # * <tt>:overlap</tt> - Calculate the item overlap in the <tt>:horizontal</tt> # or <tt>:vertical</tt> direction. - # + # # * <tt>:tag</tt> - Which children of the container element to treat as # sortable (default is <tt>li</tt>). - # + # # * <tt>:containment</tt> - Takes an element or array of elements to treat as # potential drop targets (defaults to the original target element). - # + # # * <tt>:only</tt> - A CSS class name or array of class names used to filter # out child elements as candidates. - # + # # * <tt>:scroll</tt> - Determines whether to scroll the list during drag # operations if the list runs past the visual border. - # + # # * <tt>:tree</tt> - Determines whether to treat nested lists as part of the # main sortable list. This means that you can create multi-layer lists, # and not only sort items at the same level, but drag and sort items # between levels. - # + # # * <tt>:hoverclass</tt> - If set, the Droppable will have this additional CSS class - # when an accepted Draggable is hovered over it. - # + # when an accepted Draggable is hovered over it. + # # * <tt>:handle</tt> - Sets whether the element should only be draggable by an # embedded handle. The value may be a string referencing a CSS class value # (as of script.aculo.us V1.5). The first child/grandchild/etc. element # found within the element that has this CSS class value will be used as # the handle. - # + # # * <tt>:ghosting</tt> - Clones the element and drags the clone, leaving # the original in place until the clone is dropped (default is <tt>false</tt>). - # + # # * <tt>:dropOnEmpty</tt> - If true the Sortable container will be made into # a Droppable, that can receive a Draggable (as according to the containment # rules) as a child element when there are no more elements inside (default # is <tt>false</tt>). - # + # # * <tt>:onChange</tt> - Called whenever the sort order changes while dragging. When # dragging from one Sortable to another, the callback is called once on each # Sortable. Gets the affected element as its parameter. - # + # # * <tt>:onUpdate</tt> - Called when the drag ends and the Sortable's order is # changed in any way. When dragging from one Sortable to another, the callback # is called once on each Sortable. Gets the container as its parameter. - # + # # See http://script.aculo.us for more documentation. def sortable_element(element_id, options = {}) javascript_tag(sortable_element_js(element_id, options).chop!) end - + def sortable_element_js(element_id, options = {}) #:nodoc: options[:with] ||= "Sortable.serialize(#{ActiveSupport::JSON.encode(element_id)})" options[:onUpdate] ||= "function(){" + remote_function(options) + "}" options.delete_if { |key, value| PrototypeHelper::AJAX_OPTIONS.include?(key) } - + [:tag, :overlap, :constraint, :handle].each do |option| options[option] = "'#{options[option]}'" if options[option] end - + options[:containment] = array_or_string_for_javascript(options[:containment]) if options[:containment] options[:only] = array_or_string_for_javascript(options[:only]) if options[:only] - + %(Sortable.create(#{ActiveSupport::JSON.encode(element_id)}, #{options_for_javascript(options)});) end @@ -156,24 +151,24 @@ module ActionView # # Example: # <%= draggable_element("my_image", :revert => true) - # + # # You can change the behaviour with various options, see # http://script.aculo.us for more documentation. def draggable_element(element_id, options = {}) javascript_tag(draggable_element_js(element_id, options).chop!) end - + def draggable_element_js(element_id, options = {}) #:nodoc: %(new Draggable(#{ActiveSupport::JSON.encode(element_id)}, #{options_for_javascript(options)});) end # Makes the element with the DOM ID specified by +element_id+ receive # dropped draggable elements (created by +draggable_element+). - # and make an AJAX call. By default, the action called gets the DOM ID + # and make an AJAX call. By default, the action called gets the DOM ID # of the element as parameter. # # Example: - # <%= drop_receiving_element("my_cart", :url => + # <%= drop_receiving_element("my_cart", :url => # { :controller => "cart", :action => "add" }) %> # # You can change the behaviour with various options, see @@ -181,41 +176,41 @@ module ActionView # # Some of these +options+ include: # * <tt>:accept</tt> - Set this to a string or an array of strings describing the - # allowable CSS classes that the +draggable_element+ must have in order + # allowable CSS classes that the +draggable_element+ must have in order # to be accepted by this +drop_receiving_element+. - # + # # * <tt>:confirm</tt> - Adds a confirmation dialog. Example: - # + # # :confirm => "Are you sure you want to do this?" - # + # # * <tt>:hoverclass</tt> - If set, the +drop_receiving_element+ will have # this additional CSS class when an accepted +draggable_element+ is - # hovered over it. - # + # hovered over it. + # # * <tt>:onDrop</tt> - Called when a +draggable_element+ is dropped onto - # this element. Override this callback with a JavaScript expression to + # this element. Override this callback with a JavaScript expression to # change the default drop behaviour. Example: - # + # # :onDrop => "function(draggable_element, droppable_element, event) { alert('I like bananas') }" - # + # # This callback gets three parameters: The Draggable element, the Droppable # element and the Event object. You can extract additional information about # the drop - like if the Ctrl or Shift keys were pressed - from the Event object. - # + # # * <tt>:with</tt> - A JavaScript expression specifying the parameters for # the XMLHttpRequest. Any expressions should return a valid URL query string. def drop_receiving_element(element_id, options = {}) javascript_tag(drop_receiving_element_js(element_id, options).chop!) end - + def drop_receiving_element_js(element_id, options = {}) #:nodoc: options[:with] ||= "'id=' + encodeURIComponent(element.id)" options[:onDrop] ||= "function(element){" + remote_function(options) + "}" options.delete_if { |key, value| PrototypeHelper::AJAX_OPTIONS.include?(key) } - options[:accept] = array_or_string_for_javascript(options[:accept]) if options[:accept] + options[:accept] = array_or_string_for_javascript(options[:accept]) if options[:accept] options[:hoverclass] = "'#{options[:hoverclass]}'" if options[:hoverclass] - + # Confirmation happens during the onDrop callback, so it can be removed from the options options.delete(:confirm) if options[:confirm] diff --git a/actionpack/test/template/javascript_helper_test.rb b/actionpack/test/template/javascript_helper_test.rb index 03caad3d46..b3e7abc387 100644 --- a/actionpack/test/template/javascript_helper_test.rb +++ b/actionpack/test/template/javascript_helper_test.rb @@ -30,35 +30,6 @@ class JavaScriptHelperTest < ActionView::TestCase assert_equal %(dont <\\/close> tags), escape_javascript(%(dont </close> tags)) end - def test_link_to_function - assert_dom_equal %(<a href="#" onclick="alert('Hello world!'); return false;">Greeting</a>), - link_to_function("Greeting", "alert('Hello world!')") - end - - def test_link_to_function_with_existing_onclick - assert_dom_equal %(<a href="#" onclick="confirm('Sanity!'); alert('Hello world!'); return false;">Greeting</a>), - link_to_function("Greeting", "alert('Hello world!')", :onclick => "confirm('Sanity!')") - end - - def test_link_to_function_with_rjs_block - html = link_to_function( "Greet me!" ) do |page| - page.replace_html 'header', "<h1>Greetings</h1>" - end - assert_dom_equal %(<a href="#" onclick="Element.update("header", "\\u003Ch1\\u003EGreetings\\u003C/h1\\u003E");; return false;">Greet me!</a>), html - end - - def test_link_to_function_with_rjs_block_and_options - html = link_to_function( "Greet me!", :class => "updater" ) do |page| - page.replace_html 'header', "<h1>Greetings</h1>" - end - assert_dom_equal %(<a href="#" class="updater" onclick="Element.update("header", "\\u003Ch1\\u003EGreetings\\u003C/h1\\u003E");; return false;">Greet me!</a>), html - end - - def test_link_to_function_with_href - assert_dom_equal %(<a href="http://example.com/" onclick="alert('Hello world!'); return false;">Greeting</a>), - link_to_function("Greeting", "alert('Hello world!')", :href => 'http://example.com/') - end - def test_button_to_function assert_dom_equal %(<input type="button" onclick="alert('Hello world!');" value="Greeting" />), button_to_function("Greeting", "alert('Hello world!')") diff --git a/actionpack/test/template/prototype_helper_test.rb b/actionpack/test/template/prototype_helper_test.rb index 4e37de2aef..fd868efecd 100644 --- a/actionpack/test/template/prototype_helper_test.rb +++ b/actionpack/test/template/prototype_helper_test.rb @@ -82,33 +82,6 @@ class PrototypeHelperTest < PrototypeHelperBaseTest super end - def test_link_to_remote - assert_dom_equal %(<a class=\"fine\" href=\"#\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true}); return false;\">Remote outauthor</a>), - link_to_remote("Remote outauthor", { :url => { :action => "whatnot" }}, { :class => "fine" }) - assert_dom_equal %(<a href=\"#\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true, onComplete:function(request){alert(request.responseText)}}); return false;\">Remote outauthor</a>), - link_to_remote("Remote outauthor", :complete => "alert(request.responseText)", :url => { :action => "whatnot" }) - assert_dom_equal %(<a href=\"#\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true, onSuccess:function(request){alert(request.responseText)}}); return false;\">Remote outauthor</a>), - link_to_remote("Remote outauthor", :success => "alert(request.responseText)", :url => { :action => "whatnot" }) - assert_dom_equal %(<a href=\"#\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true, onFailure:function(request){alert(request.responseText)}}); return false;\">Remote outauthor</a>), - link_to_remote("Remote outauthor", :failure => "alert(request.responseText)", :url => { :action => "whatnot" }) - assert_dom_equal %(<a href=\"#\" onclick=\"new Ajax.Request('http://www.example.com/whatnot?a=10&b=20', {asynchronous:true, evalScripts:true, onFailure:function(request){alert(request.responseText)}}); return false;\">Remote outauthor</a>), - link_to_remote("Remote outauthor", :failure => "alert(request.responseText)", :url => { :action => "whatnot", :a => '10', :b => '20' }) - assert_dom_equal %(<a href=\"#\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:false, evalScripts:true}); return false;\">Remote outauthor</a>), - link_to_remote("Remote outauthor", :url => { :action => "whatnot" }, :type => :synchronous) - assert_dom_equal %(<a href=\"#\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true, insertion:'bottom'}); return false;\">Remote outauthor</a>), - link_to_remote("Remote outauthor", :url => { :action => "whatnot" }, :position => :bottom) - end - - def test_link_to_remote_html_options - assert_dom_equal %(<a class=\"fine\" href=\"#\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true}); return false;\">Remote outauthor</a>), - link_to_remote("Remote outauthor", { :url => { :action => "whatnot" }, :html => { :class => "fine" } }) - end - - def test_link_to_remote_url_quote_escaping - assert_dom_equal %(<a href="#" onclick="new Ajax.Request('http://www.example.com/whatnot\\\'s', {asynchronous:true, evalScripts:true}); return false;">Remote</a>), - link_to_remote("Remote", { :url => { :action => "whatnot's" } }) - end - def test_button_to_remote assert_dom_equal %(<input class=\"fine\" type=\"button\" value=\"Remote outpost\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true});\" />), button_to_remote("Remote outpost", { :url => { :action => "whatnot" }}, { :class => "fine" }) @@ -610,4 +583,3 @@ return value.reverse(); assert_equal "MyObject.myMethod(function() { $(\"one\").show();\n$(\"two\").hide(); });", @generator.to_s end end - |