aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack
diff options
context:
space:
mode:
authorPratik Naik <pratiknaik@gmail.com>2010-01-31 14:32:26 +0000
committerPratik Naik <pratiknaik@gmail.com>2010-01-31 14:32:26 +0000
commited60021f39f7913537dcad181e4061e423dc6c3d (patch)
tree86532c43aabe9125422f84b48a899f2672900bf5 /actionpack
parentc6af337d2d6c86792cdc8132224ebe9294d35774 (diff)
parentb3a028259f373fd58fea2171a1e9e8b2fe3e253a (diff)
downloadrails-ed60021f39f7913537dcad181e4061e423dc6c3d.tar.gz
rails-ed60021f39f7913537dcad181e4061e423dc6c3d.tar.bz2
rails-ed60021f39f7913537dcad181e4061e423dc6c3d.zip
Merge remote branch 'mainstream/master'
Conflicts: activemodel/lib/active_model/state_machine.rb
Diffstat (limited to 'actionpack')
-rw-r--r--actionpack/README77
-rw-r--r--actionpack/lib/abstract_controller.rb3
-rw-r--r--actionpack/lib/abstract_controller/compatibility.rb18
-rw-r--r--actionpack/lib/abstract_controller/helpers.rb12
-rw-r--r--actionpack/lib/abstract_controller/rendering.rb14
-rw-r--r--actionpack/lib/abstract_controller/url_for.rb156
-rw-r--r--actionpack/lib/action_controller.rb10
-rw-r--r--actionpack/lib/action_controller/base.rb8
-rw-r--r--actionpack/lib/action_controller/deprecated.rb2
-rw-r--r--actionpack/lib/action_controller/metal/compatibility.rb15
-rw-r--r--actionpack/lib/action_controller/metal/helpers.rb17
-rw-r--r--actionpack/lib/action_controller/metal/rendering.rb5
-rw-r--r--actionpack/lib/action_controller/metal/url_for.rb149
-rw-r--r--actionpack/lib/action_dispatch.rb1
-rw-r--r--actionpack/lib/action_dispatch/testing/test_response.rb5
-rw-r--r--actionpack/lib/action_view/base.rb17
-rw-r--r--actionpack/lib/action_view/helpers.rb7
-rw-r--r--actionpack/lib/action_view/helpers/ajax_helper.rb713
-rw-r--r--actionpack/lib/action_view/helpers/asset_tag_helper.rb2
-rw-r--r--actionpack/lib/action_view/helpers/form_helper.rb36
-rw-r--r--actionpack/lib/action_view/helpers/form_tag_helper.rb11
-rw-r--r--actionpack/lib/action_view/helpers/javascript_helper.rb152
-rw-r--r--actionpack/lib/action_view/helpers/prototype_helper.rb170
-rw-r--r--actionpack/lib/action_view/helpers/scriptaculous_helper.rb142
-rw-r--r--actionpack/lib/action_view/helpers/url_helper.rb80
-rw-r--r--actionpack/lib/action_view/paths.rb2
-rw-r--r--actionpack/test/abstract/render_test.rb43
-rw-r--r--actionpack/test/controller/assert_select_test.rb4
-rw-r--r--actionpack/test/controller/helper_test.rb21
-rw-r--r--actionpack/test/controller/mime_responds_test.rb2
-rw-r--r--actionpack/test/controller/request_forgery_protection_test.rb45
-rw-r--r--actionpack/test/controller/url_for_test.rb (renamed from actionpack/test/abstract/url_for_test.rb)14
-rw-r--r--actionpack/test/template/ajax_helper_test.rb452
-rw-r--r--actionpack/test/template/asset_tag_helper_test.rb15
-rw-r--r--actionpack/test/template/form_helper_test.rb29
-rw-r--r--actionpack/test/template/form_tag_helper_test.rb10
-rw-r--r--actionpack/test/template/javascript_helper_test.rb29
-rw-r--r--actionpack/test/template/prototype_helper_test.rb2
-rw-r--r--actionpack/test/template/url_helper_test.rb43
39 files changed, 628 insertions, 1905 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/abstract_controller.rb b/actionpack/lib/abstract_controller.rb
index 2c2ef16622..1e15ab090c 100644
--- a/actionpack/lib/abstract_controller.rb
+++ b/actionpack/lib/abstract_controller.rb
@@ -2,6 +2,7 @@ activesupport_path = File.expand_path('../../../activesupport/lib', __FILE__)
$:.unshift(activesupport_path) if File.directory?(activesupport_path) && !$:.include?(activesupport_path)
require 'active_support/ruby/shim'
+require 'active_support/dependencies/autoload'
require 'active_support/core_ext/module/attr_internal'
require 'active_support/core_ext/module/delegation'
@@ -11,11 +12,11 @@ module AbstractController
autoload :Base
autoload :Callbacks
autoload :Collector
+ autoload :Compatibility
autoload :Helpers
autoload :Layouts
autoload :LocalizedCache
autoload :Logger
autoload :Rendering
autoload :Translation
- autoload :UrlFor
end
diff --git a/actionpack/lib/abstract_controller/compatibility.rb b/actionpack/lib/abstract_controller/compatibility.rb
new file mode 100644
index 0000000000..7fb93a0eb5
--- /dev/null
+++ b/actionpack/lib/abstract_controller/compatibility.rb
@@ -0,0 +1,18 @@
+module AbstractController
+ module Compatibility
+ extend ActiveSupport::Concern
+
+ def _find_layout(name, details)
+ details[:prefix] = nil if name =~ /\blayouts/
+ super
+ end
+
+ # Move this into a "don't run in production" module
+ def _default_layout(details, require_layout = false)
+ super
+ rescue ActionView::MissingTemplate
+ _find_layout(_layout({}), {})
+ nil
+ end
+ end
+end
diff --git a/actionpack/lib/abstract_controller/helpers.rb b/actionpack/lib/abstract_controller/helpers.rb
index 1d898d1a4c..eb621c0865 100644
--- a/actionpack/lib/abstract_controller/helpers.rb
+++ b/actionpack/lib/abstract_controller/helpers.rb
@@ -25,7 +25,7 @@ module AbstractController
def inherited(klass)
helpers = _helpers
klass._helpers = Module.new { include helpers }
-
+ klass.class_eval { default_helper_module! unless name.blank? }
super
end
@@ -146,6 +146,16 @@ module AbstractController
end
end
end
+
+ def default_helper_module!
+ module_name = name.sub(/Controller$/, '')
+ module_path = module_name.underscore
+ helper module_path
+ rescue MissingSourceFile => e
+ raise e unless e.is_missing? "helpers/#{module_path}_helper"
+ rescue NameError => e
+ raise e unless e.missing_name? "#{module_name}Helper"
+ end
end
end
end
diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb
index 1dec3f2c3e..ac407bda5e 100644
--- a/actionpack/lib/abstract_controller/rendering.rb
+++ b/actionpack/lib/abstract_controller/rendering.rb
@@ -157,13 +157,23 @@ module AbstractController
options[:_template_name] = options[:file]
end
- name = (options[:_template_name] || action_name).to_s
+ name = (options[:_template_name] || options[:action] || action_name).to_s
+ options[:_prefix] ||= _prefix if (options.keys & [:partial, :file, :template]).empty?
+
+ details = _normalize_details(options)
options[:_template] ||= with_template_cache(name) do
- find_template(name, { :formats => formats }, options)
+ find_template(name, details, options)
end
end
+ def _normalize_details(options)
+ details = { :formats => formats }
+ details[:formats] = Array(options[:format]) if options[:format]
+ details[:locale] = Array(options[:locale]) if options[:locale]
+ details
+ end
+
def find_template(name, details, options)
view_paths.find(name, details, options[:_prefix], options[:_partial])
end
diff --git a/actionpack/lib/abstract_controller/url_for.rb b/actionpack/lib/abstract_controller/url_for.rb
deleted file mode 100644
index 6b7d2b1f34..0000000000
--- a/actionpack/lib/abstract_controller/url_for.rb
+++ /dev/null
@@ -1,156 +0,0 @@
-module AbstractController
- # In <b>routes.rb</b> one defines URL-to-controller mappings, but the reverse
- # is also possible: an URL can be generated from one of your routing definitions.
- # URL generation functionality is centralized in this module.
- #
- # See AbstractController::Routing and AbstractController::Resources for general
- # information about routing and routes.rb.
- #
- # <b>Tip:</b> If you need to generate URLs from your models or some other place,
- # then AbstractController::UrlFor is what you're looking for. Read on for
- # an introduction.
- #
- # == URL generation from parameters
- #
- # As you may know, some functions - such as AbstractController::Base#url_for
- # and ActionView::Helpers::UrlHelper#link_to, can generate URLs given a set
- # of parameters. For example, you've probably had the chance to write code
- # like this in one of your views:
- #
- # <%= link_to('Click here', :controller => 'users',
- # :action => 'new', :message => 'Welcome!') %>
- #
- # #=> Generates a link to: /users/new?message=Welcome%21
- #
- # link_to, and all other functions that require URL generation functionality,
- # actually use AbstractController::UrlFor under the hood. And in particular,
- # they use the AbstractController::UrlFor#url_for method. One can generate
- # the same path as the above example by using the following code:
- #
- # include UrlFor
- # url_for(:controller => 'users',
- # :action => 'new',
- # :message => 'Welcome!',
- # :only_path => true)
- # # => "/users/new?message=Welcome%21"
- #
- # Notice the <tt>:only_path => true</tt> part. This is because UrlFor has no
- # information about the website hostname that your Rails app is serving. So if you
- # want to include the hostname as well, then you must also pass the <tt>:host</tt>
- # argument:
- #
- # include UrlFor
- # url_for(:controller => 'users',
- # :action => 'new',
- # :message => 'Welcome!',
- # :host => 'www.example.com') # Changed this.
- # # => "http://www.example.com/users/new?message=Welcome%21"
- #
- # By default, all controllers and views have access to a special version of url_for,
- # that already knows what the current hostname is. So if you use url_for in your
- # controllers or your views, then you don't need to explicitly pass the <tt>:host</tt>
- # argument.
- #
- # For convenience reasons, mailers provide a shortcut for AbstractController::UrlFor#url_for.
- # So within mailers, you only have to type 'url_for' instead of 'AbstractController::UrlFor#url_for'
- # in full. However, mailers don't have hostname information, and what's why you'll still
- # have to specify the <tt>:host</tt> argument when generating URLs in mailers.
- #
- #
- # == URL generation for named routes
- #
- # UrlFor also allows one to access methods that have been auto-generated from
- # named routes. For example, suppose that you have a 'users' resource in your
- # <b>routes.rb</b>:
- #
- # map.resources :users
- #
- # This generates, among other things, the method <tt>users_path</tt>. By default,
- # this method is accessible from your controllers, views and mailers. If you need
- # to access this auto-generated method from other places (such as a model), then
- # you can do that by including AbstractController::UrlFor in your class:
- #
- # class User < ActiveRecord::Base
- # include AbstractController::UrlFor
- #
- # def base_uri
- # user_path(self)
- # end
- # end
- #
- # User.find(1).base_uri # => "/users/1"
- #
- module UrlFor
- extend ActiveSupport::Concern
-
- included do
- ActionController::Routing::Routes.install_helpers(self)
- extlib_inheritable_accessor :default_url_options,
- :instance_writer => false, :instance_reader => false
- self.default_url_options ||= {}
- end
-
- # Overwrite to implement a number of default options that all url_for-based methods will use. The default options should come in
- # the form of a hash, just like the one you would use for url_for directly. Example:
- #
- # def default_url_options(options)
- # { :project => @project.active? ? @project.url_name : "unknown" }
- # end
- #
- # As you can infer from the example, this is mostly useful for situations where you want to centralize dynamic decisions about the
- # urls as they stem from the business domain. Please note that any individual url_for call can always override the defaults set
- # by this method.
- def default_url_options(options = nil)
- self.class.default_url_options
- end
-
- def rewrite_options(options) #:nodoc:
- if options.delete(:use_defaults) != false && (defaults = default_url_options(options))
- defaults.merge(options)
- else
- options
- end
- end
-
- # Generate a url based on the options provided, default_url_options and the
- # routes defined in routes.rb. The following options are supported:
- #
- # * <tt>:only_path</tt> - If true, the relative url is returned. Defaults to +false+.
- # * <tt>:protocol</tt> - The protocol to connect to. Defaults to 'http'.
- # * <tt>:host</tt> - Specifies the host the link should be targeted at.
- # If <tt>:only_path</tt> is false, this option must be
- # provided either explicitly, or via +default_url_options+.
- # * <tt>:port</tt> - Optionally specify the port to connect to.
- # * <tt>:anchor</tt> - An anchor name to be appended to the path.
- # * <tt>:skip_relative_url_root</tt> - If true, the url is not constructed using the
- # +relative_url_root+ set in AbstractController::Base.relative_url_root.
- # * <tt>:trailing_slash</tt> - If true, adds a trailing slash, as in "/archive/2009/"
- #
- # Any other key (<tt>:controller</tt>, <tt>:action</tt>, etc.) given to
- # +url_for+ is forwarded to the Routes module.
- #
- # Examples:
- #
- # url_for :controller => 'tasks', :action => 'testing', :host=>'somehost.org', :port=>'8080' # => 'http://somehost.org:8080/tasks/testing'
- # url_for :controller => 'tasks', :action => 'testing', :host=>'somehost.org', :anchor => 'ok', :only_path => true # => '/tasks/testing#ok'
- # url_for :controller => 'tasks', :action => 'testing', :trailing_slash=>true # => 'http://somehost.org/tasks/testing/'
- # url_for :controller => 'tasks', :action => 'testing', :host=>'somehost.org', :number => '33' # => 'http://somehost.org/tasks/testing?number=33'
- def url_for(options = {})
- options ||= {}
- case options
- when String
- options
- when Hash
- _url_rewriter.rewrite(rewrite_options(options))
- else
- polymorphic_url(options)
- end
- end
-
- protected
-
- def _url_rewriter
- ActionController::UrlRewriter
- end
- end
-end
diff --git a/actionpack/lib/action_controller.rb b/actionpack/lib/action_controller.rb
index 33e107d216..759e52b135 100644
--- a/actionpack/lib/action_controller.rb
+++ b/actionpack/lib/action_controller.rb
@@ -1,6 +1,5 @@
-activesupport_path = File.expand_path('../../../activesupport/lib', __FILE__)
-$:.unshift(activesupport_path) if File.directory?(activesupport_path) && !$:.include?(activesupport_path)
-require 'active_support/ruby/shim'
+require 'abstract_controller'
+require 'action_dispatch'
module ActionController
extend ActiveSupport::Autoload
@@ -41,6 +40,7 @@ module ActionController
autoload :Integration, 'action_controller/deprecated/integration_test'
autoload :IntegrationTest, 'action_controller/deprecated/integration_test'
autoload :PerformanceTest, 'action_controller/deprecated/performance_test'
+ autoload :UrlWriter, 'action_controller/deprecated'
autoload :Routing, 'action_controller/deprecated'
autoload :TestCase, 'action_controller/test_case'
@@ -66,13 +66,11 @@ module ActionController
end
# All of these simply register additional autoloads
-require 'abstract_controller'
-require 'action_dispatch'
require 'action_view'
require 'action_controller/vendor/html-scanner'
# Common ActiveSupport usage in ActionController
-require "active_support/concern"
+require 'active_support/concern'
require 'active_support/core_ext/class/attribute_accessors'
require 'active_support/core_ext/load_error'
require 'active_support/core_ext/module/attr_internal'
diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb
index 215b70734c..10244f8216 100644
--- a/actionpack/lib/action_controller/base.rb
+++ b/actionpack/lib/action_controller/base.rb
@@ -81,5 +81,13 @@ module ActionController
filter << block if block
filter
end
+
+ protected
+
+ # Overwrite url rewriter to use request.
+ def _url_rewriter
+ return ActionController::UrlRewriter unless request
+ @_url_rewriter ||= ActionController::UrlRewriter.new(request, params)
+ end
end
end
diff --git a/actionpack/lib/action_controller/deprecated.rb b/actionpack/lib/action_controller/deprecated.rb
index edc0e5b3fe..a4eef07841 100644
--- a/actionpack/lib/action_controller/deprecated.rb
+++ b/actionpack/lib/action_controller/deprecated.rb
@@ -2,4 +2,4 @@ ActionController::AbstractRequest = ActionController::Request = ActionDispatch::
ActionController::AbstractResponse = ActionController::Response = ActionDispatch::Response
ActionController::Routing = ActionDispatch::Routing
ActionController::Routing::Routes = ActionDispatch::Routing::RouteSet.new
-ActionController::UrlWriter = AbstractController::UrlFor
+ActionController::UrlWriter = ActionController::UrlFor
diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb
index 0e869e4e87..2be0fa097e 100644
--- a/actionpack/lib/action_controller/metal/compatibility.rb
+++ b/actionpack/lib/action_controller/metal/compatibility.rb
@@ -2,6 +2,8 @@ module ActionController
module Compatibility
extend ActiveSupport::Concern
+ include AbstractController::Compatibility
+
class ::ActionController::ActionControllerError < StandardError #:nodoc:
end
@@ -103,19 +105,6 @@ module ActionController
super || (respond_to?(:method_missing) && "_handle_method_missing")
end
- def _find_layout(name, details)
- details[:prefix] = nil if name =~ /\blayouts/
- super
- end
-
- # Move this into a "don't run in production" module
- def _default_layout(details, require_layout = false)
- super
- rescue ActionView::MissingTemplate
- _find_layout(_layout({}), {})
- nil
- end
-
def performed?
response_body
end
diff --git a/actionpack/lib/action_controller/metal/helpers.rb b/actionpack/lib/action_controller/metal/helpers.rb
index 03ba4b3f83..05843a061b 100644
--- a/actionpack/lib/action_controller/metal/helpers.rb
+++ b/actionpack/lib/action_controller/metal/helpers.rb
@@ -56,18 +56,15 @@ module ActionController
module ClassMethods
def helpers_dir
+ ActiveSupport::Deprecation.warn "helpers_dir is deprecated, use helpers_path instead"
self.helpers_path
end
def helpers_dir=(value)
+ ActiveSupport::Deprecation.warn "helpers_dir= is deprecated, use helpers_path= instead"
self.helpers_path = Array(value)
end
- def inherited(klass)
- klass.class_eval { default_helper_module! unless name.blank? }
- super
- end
-
# Declares helper accessors for controller attributes. For example, the
# following adds new +name+ and <tt>name=</tt> instance methods to a
# controller and makes them available to the view:
@@ -101,16 +98,6 @@ module ActionController
super(args)
end
- def default_helper_module!
- module_name = name.sub(/Controller$/, '')
- module_path = module_name.underscore
- helper module_path
- rescue MissingSourceFile => e
- raise e unless e.is_missing? "helpers/#{module_path}_helper"
- rescue NameError => e
- raise e unless e.missing_name? "#{module_name}Helper"
- end
-
# Extract helper names from files in app/helpers/**/*_helper.rb
def all_application_helpers
helpers = []
diff --git a/actionpack/lib/action_controller/metal/rendering.rb b/actionpack/lib/action_controller/metal/rendering.rb
index 8f03035b2b..0aae9f8579 100644
--- a/actionpack/lib/action_controller/metal/rendering.rb
+++ b/actionpack/lib/action_controller/metal/rendering.rb
@@ -58,11 +58,6 @@ module ActionController
options.merge! :partial => action
end
- if (options.keys & [:partial, :file, :template, :text, :inline]).empty?
- options[:_template_name] ||= options[:action]
- options[:_prefix] = _prefix
- end
-
if options[:status]
options[:status] = Rack::Utils.status_code(options[:status])
end
diff --git a/actionpack/lib/action_controller/metal/url_for.rb b/actionpack/lib/action_controller/metal/url_for.rb
index 73feacb872..387e6a554b 100644
--- a/actionpack/lib/action_controller/metal/url_for.rb
+++ b/actionpack/lib/action_controller/metal/url_for.rb
@@ -1,15 +1,156 @@
module ActionController
+ # In <b>routes.rb</b> one defines URL-to-controller mappings, but the reverse
+ # is also possible: an URL can be generated from one of your routing definitions.
+ # URL generation functionality is centralized in this module.
+ #
+ # See ActionController::Routing and ActionController::Resources for general
+ # information about routing and routes.rb.
+ #
+ # <b>Tip:</b> If you need to generate URLs from your models or some other place,
+ # then ActionController::UrlFor is what you're looking for. Read on for
+ # an introduction.
+ #
+ # == URL generation from parameters
+ #
+ # As you may know, some functions - such as ActionController::Base#url_for
+ # and ActionView::Helpers::UrlHelper#link_to, can generate URLs given a set
+ # of parameters. For example, you've probably had the chance to write code
+ # like this in one of your views:
+ #
+ # <%= link_to('Click here', :controller => 'users',
+ # :action => 'new', :message => 'Welcome!') %>
+ #
+ # #=> Generates a link to: /users/new?message=Welcome%21
+ #
+ # link_to, and all other functions that require URL generation functionality,
+ # actually use ActionController::UrlFor under the hood. And in particular,
+ # they use the ActionController::UrlFor#url_for method. One can generate
+ # the same path as the above example by using the following code:
+ #
+ # include UrlFor
+ # url_for(:controller => 'users',
+ # :action => 'new',
+ # :message => 'Welcome!',
+ # :only_path => true)
+ # # => "/users/new?message=Welcome%21"
+ #
+ # Notice the <tt>:only_path => true</tt> part. This is because UrlFor has no
+ # information about the website hostname that your Rails app is serving. So if you
+ # want to include the hostname as well, then you must also pass the <tt>:host</tt>
+ # argument:
+ #
+ # include UrlFor
+ # url_for(:controller => 'users',
+ # :action => 'new',
+ # :message => 'Welcome!',
+ # :host => 'www.example.com') # Changed this.
+ # # => "http://www.example.com/users/new?message=Welcome%21"
+ #
+ # By default, all controllers and views have access to a special version of url_for,
+ # that already knows what the current hostname is. So if you use url_for in your
+ # controllers or your views, then you don't need to explicitly pass the <tt>:host</tt>
+ # argument.
+ #
+ # For convenience reasons, mailers provide a shortcut for ActionController::UrlFor#url_for.
+ # So within mailers, you only have to type 'url_for' instead of 'ActionController::UrlFor#url_for'
+ # in full. However, mailers don't have hostname information, and what's why you'll still
+ # have to specify the <tt>:host</tt> argument when generating URLs in mailers.
+ #
+ #
+ # == URL generation for named routes
+ #
+ # UrlFor also allows one to access methods that have been auto-generated from
+ # named routes. For example, suppose that you have a 'users' resource in your
+ # <b>routes.rb</b>:
+ #
+ # map.resources :users
+ #
+ # This generates, among other things, the method <tt>users_path</tt>. By default,
+ # this method is accessible from your controllers, views and mailers. If you need
+ # to access this auto-generated method from other places (such as a model), then
+ # you can do that by including ActionController::UrlFor in your class:
+ #
+ # class User < ActiveRecord::Base
+ # include ActionController::UrlFor
+ #
+ # def base_uri
+ # user_path(self)
+ # end
+ # end
+ #
+ # User.find(1).base_uri # => "/users/1"
+ #
module UrlFor
extend ActiveSupport::Concern
- include AbstractController::UrlFor
- include ActionController::RackDelegation
+ included do
+ ActionController::Routing::Routes.install_helpers(self)
+ extlib_inheritable_accessor :default_url_options,
+ :instance_writer => false, :instance_reader => false
+ self.default_url_options ||= {}
+ end
+
+ # Overwrite to implement a number of default options that all url_for-based methods will use. The default options should come in
+ # the form of a hash, just like the one you would use for url_for directly. Example:
+ #
+ # def default_url_options(options)
+ # { :project => @project.active? ? @project.url_name : "unknown" }
+ # end
+ #
+ # As you can infer from the example, this is mostly useful for situations where you want to centralize dynamic decisions about the
+ # urls as they stem from the business domain. Please note that any individual url_for call can always override the defaults set
+ # by this method.
+ def default_url_options(options = nil)
+ self.class.default_url_options
+ end
+
+ def rewrite_options(options) #:nodoc:
+ if options.delete(:use_defaults) != false && (defaults = default_url_options(options))
+ defaults.merge(options)
+ else
+ options
+ end
+ end
+
+ # Generate a url based on the options provided, default_url_options and the
+ # routes defined in routes.rb. The following options are supported:
+ #
+ # * <tt>:only_path</tt> - If true, the relative url is returned. Defaults to +false+.
+ # * <tt>:protocol</tt> - The protocol to connect to. Defaults to 'http'.
+ # * <tt>:host</tt> - Specifies the host the link should be targeted at.
+ # If <tt>:only_path</tt> is false, this option must be
+ # provided either explicitly, or via +default_url_options+.
+ # * <tt>:port</tt> - Optionally specify the port to connect to.
+ # * <tt>:anchor</tt> - An anchor name to be appended to the path.
+ # * <tt>:skip_relative_url_root</tt> - If true, the url is not constructed using the
+ # +relative_url_root+ set in ActionController::Base.relative_url_root.
+ # * <tt>:trailing_slash</tt> - If true, adds a trailing slash, as in "/archive/2009/"
+ #
+ # Any other key (<tt>:controller</tt>, <tt>:action</tt>, etc.) given to
+ # +url_for+ is forwarded to the Routes module.
+ #
+ # Examples:
+ #
+ # url_for :controller => 'tasks', :action => 'testing', :host=>'somehost.org', :port=>'8080' # => 'http://somehost.org:8080/tasks/testing'
+ # url_for :controller => 'tasks', :action => 'testing', :host=>'somehost.org', :anchor => 'ok', :only_path => true # => '/tasks/testing#ok'
+ # url_for :controller => 'tasks', :action => 'testing', :trailing_slash=>true # => 'http://somehost.org/tasks/testing/'
+ # url_for :controller => 'tasks', :action => 'testing', :host=>'somehost.org', :number => '33' # => 'http://somehost.org/tasks/testing?number=33'
+ def url_for(options = {})
+ options ||= {}
+ case options
+ when String
+ options
+ when Hash
+ _url_rewriter.rewrite(rewrite_options(options))
+ else
+ polymorphic_url(options)
+ end
+ end
protected
def _url_rewriter
- return ActionController::UrlRewriter unless request
- @_url_rewriter ||= ActionController::UrlRewriter.new(request, params)
+ ActionController::UrlRewriter
end
end
end
diff --git a/actionpack/lib/action_dispatch.rb b/actionpack/lib/action_dispatch.rb
index f0490a5619..c6eb097ee5 100644
--- a/actionpack/lib/action_dispatch.rb
+++ b/actionpack/lib/action_dispatch.rb
@@ -23,6 +23,7 @@
activesupport_path = File.expand_path('../../../activesupport/lib', __FILE__)
$:.unshift(activesupport_path) if File.directory?(activesupport_path) && !$:.include?(activesupport_path)
+
require 'active_support'
require 'active_support/dependencies/autoload'
diff --git a/actionpack/lib/action_dispatch/testing/test_response.rb b/actionpack/lib/action_dispatch/testing/test_response.rb
index 6d019023ce..9a51a32899 100644
--- a/actionpack/lib/action_dispatch/testing/test_response.rb
+++ b/actionpack/lib/action_dispatch/testing/test_response.rb
@@ -36,6 +36,11 @@ module ActionDispatch
@template.layout
end
+ def redirected_to
+ ::ActiveSupport::Deprecation.warn("response.redirected_to is deprecated. Use response.redirect_url instead", caller)
+ redirect_url
+ end
+
def redirect_url_match?(pattern)
::ActiveSupport::Deprecation.warn("response.redirect_url_match? is deprecated. Use assert_match(/foo/, response.redirect_url) instead", caller)
return false if redirect_url.nil?
diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb
index af13f2cd3e..07ef3f2140 100644
--- a/actionpack/lib/action_view/base.rb
+++ b/actionpack/lib/action_view/base.rb
@@ -6,15 +6,20 @@ module ActionView #:nodoc:
end
class MissingTemplate < ActionViewError #:nodoc:
- attr_reader :path, :action_name
+ attr_reader :path
- def initialize(paths, path, template_format = nil)
+ def initialize(paths, path, details, partial)
@path = path
- @action_name = path.split("/").last.split(".")[0...-1].join(".")
- full_template_path = path.include?('.') ? path : "#{path}.erb"
display_paths = paths.compact.join(":")
- template_type = (path =~ /layouts/i) ? 'layout' : 'template'
- super("Missing #{template_type} #{full_template_path} in view path #{display_paths}")
+ template_type = if partial
+ "partial"
+ elsif path =~ /layouts/i
+ 'layout'
+ else
+ 'template'
+ end
+
+ super("Missing #{template_type} #{path} with #{details.inspect} in view path #{display_paths}")
end
end
diff --git a/actionpack/lib/action_view/helpers.rb b/actionpack/lib/action_view/helpers.rb
index 080eb87445..ceb0e18d80 100644
--- a/actionpack/lib/action_view/helpers.rb
+++ b/actionpack/lib/action_view/helpers.rb
@@ -3,7 +3,6 @@ require 'active_support/benchmarkable'
module ActionView #:nodoc:
module Helpers #:nodoc:
autoload :ActiveModelHelper, 'action_view/helpers/active_model_helper'
- autoload :AjaxHelperCompat, 'action_view/helpers/ajax_helper'
autoload :AssetTagHelper, 'action_view/helpers/asset_tag_helper'
autoload :AtomFeedHelper, 'action_view/helpers/atom_feed_helper'
autoload :CacheHelper, 'action_view/helpers/cache_helper'
@@ -15,11 +14,12 @@ module ActionView #:nodoc:
autoload :FormTagHelper, 'action_view/helpers/form_tag_helper'
autoload :JavaScriptHelper, 'action_view/helpers/javascript_helper'
autoload :NumberHelper, 'action_view/helpers/number_helper'
- autoload :AjaxHelper, 'action_view/helpers/ajax_helper'
+ autoload :PrototypeHelper, 'action_view/helpers/prototype_helper'
autoload :RawOutputHelper, 'action_view/helpers/raw_output_helper'
autoload :RecordIdentificationHelper, 'action_view/helpers/record_identification_helper'
autoload :RecordTagHelper, 'action_view/helpers/record_tag_helper'
autoload :SanitizeHelper, 'action_view/helpers/sanitize_helper'
+ autoload :ScriptaculousHelper, 'action_view/helpers/scriptaculous_helper'
autoload :TagHelper, 'action_view/helpers/tag_helper'
autoload :TextHelper, 'action_view/helpers/text_helper'
autoload :TranslationHelper, 'action_view/helpers/translation_helper'
@@ -47,11 +47,12 @@ module ActionView #:nodoc:
include FormTagHelper
include JavaScriptHelper
include NumberHelper
- include AjaxHelperCompat
+ include PrototypeHelper
include RawOutputHelper
include RecordIdentificationHelper
include RecordTagHelper
include SanitizeHelper
+ include ScriptaculousHelper
include TagHelper
include TextHelper
include TranslationHelper
diff --git a/actionpack/lib/action_view/helpers/ajax_helper.rb b/actionpack/lib/action_view/helpers/ajax_helper.rb
deleted file mode 100644
index 169a803848..0000000000
--- a/actionpack/lib/action_view/helpers/ajax_helper.rb
+++ /dev/null
@@ -1,713 +0,0 @@
-module ActionView
- module Helpers
- module AjaxHelper
- # Included for backwards compatibility / RJS functionality
- # Rails classes should not be aware of individual JS frameworks
- include PrototypeHelper
-
- # Returns a form that will allow the unobtrusive JavaScript drivers to submit the
- # form dynamically. The default driver behaviour is an XMLHttpRequest in the background
- # instead of the regular 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 <tt>params</tt>). The options
- # for specifying the target with <tt>:url</tt> anddefining callbacks is the same as +link_to_remote+.
- #
- # === Resource
- #
- # Example:
- #
- # # Generates:
- # # <form action='/authors'
- # # data-remote='true'
- # # class='new_author'
- # # id='create-author'
- # # method='post'> ... </form>
- # #
- # <% remote_form_for(@record, {:html => { :id => 'create-author' }}) do |f| %>
- # ...
- # <% end %>
- #
- # This will expand to be the same as:
- #
- # <% remote_form_for :post, @post, :url => post_path(@post),
- # :html => { :method => :put,
- # :class => "edit_post",
- # :id => "edit_post_45" } do |f| %>
- # ...
- # <% end %>
- #
- # === Nested Resource
- #
- # Example:
- # # Generates:
- # # <form action='/authors/1/articles'
- # # data-remote="true"
- # # class='new_article'
- # # method='post'
- # # id='new_article'></form>
- # #
- # <% remote_form_for([@author, @article]) do |f| %>
- # ...
- # <% end %>
- #
- # This will expand to be the same as:
- #
- # <% remote_form_for :article, @article, :url => author_article_path(@author, @article),
- # :html => { :method => :put,
- # :class => "new_article",
- # :id => "new_comment" } do |f| %>
- # ...
- # <% end %>
- #
- # If you don't need to attach a form to a resource, then check out form_remote_tag.
- #
- # See FormHelper#form_for for additional semantics.
- def remote_form_for(record_or_name_or_array, *args, &proc)
- options = args.extract_options!
-
- if confirm = options.delete(:confirm)
- add_confirm_to_attributes!(options, confirm)
- end
-
- object_name = extract_object_name_for_form!(args, options, record_or_name_or_array)
-
- concat(form_remote_tag(options))
- fields_for(object_name, *(args << options), &proc)
- concat('</form>'.html_safe!)
- end
- alias_method :form_remote_for, :remote_form_for
-
- # Returns a form tag that will allow the unobtrusive JavaScript drivers to submit the
- # form dynamically. The default JavaScript driver behaviour is an XMLHttpRequest
- # in the background instead of the regular 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
- # <tt>params</tt>). The options for specifying the target with <tt>:url</tt> 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 <tt>:action</tt>/<tt>:method</tt> options on <tt>:html</tt>.
- #
- # Example:
- #
- # # Generates:
- # # <form action="http://www.example.com/fast"
- # # method="post"
- # # data-remote="true"
- # # data-update-success="glass_of_beer"></form>
- # #
- # form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }) {}
- #
- # The Hash passed to the <tt>:html</tt> key is equivalent to the options (2nd)
- # argument in the FormTagHelper.form_tag method.
- #
- # By default the fall-through action is the same as the one specified in
- # the <tt>:url</tt> (and the default method is <tt>:post</tt>).
- #
- # form_remote_tag also takes a block, like form_tag:
- # # Generates:
- # # <form action='/posts'
- # # method='post'
- # # data-remote='true'>
- # # <input name="commit" type="submit" value="Save" />
- # # </form>
- # #
- # <% form_remote_tag :url => '/posts' do -%>
- # <%= submit_tag 'Save' %>
- # <% end -%>
- #
- # # Generates:
- # # <form action="http://www.example.com/fast"
- # # method="post"
- # # data-remote="true"
- # # data-update-success="glass_of_beer">Hello world!</form>
- # #
- # <% form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }) do -%>
- # "Hello world!"
- # <% end -%>
- #
- def form_remote_tag(options = {}, &block)
- html_options = options.delete(:callbacks)
-
- attributes = {}
- attributes.merge!(extract_remote_attributes!(options))
- attributes.merge!(html_options) if html_options
- attributes.merge!(options)
- attributes.delete(:builder)
-
- form_tag(attributes.delete(:action) || attributes.delete("data-url"), attributes, &block)
- end
-
- # Returns a link that will allow unobtrusive JavaScript to dynamical adjust its
- # behaviour. The default behaviour is an XMLHttpRequest in the background instead
- # of the regular GET arrangement. 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="#"
- # # data-remote="true"
- # # data-url="http://www.example.com/whatnot"
- # # data-method="delete"
- # # rel="nofollow">Remove Author</a>
- # #
- # link_to_remote("Remove Author", { :url => { :action => "whatnot" },
- # :method => "delete"})
- #
- #
- # You can override the generated HTML options by specifying a hash in
- # <tt>options[:html]</tt>.
- #
- # # Generates:
- # # <a class="fine"
- # # href="#"
- # # data-remote="true"
- # # data-url="http://www.example.com/whatnot"
- # # data-method="delete"
- # # rel="nofollow">Remove Author</a>
- # #
- # link_to_remote("Remove Author", { :url => { :action => "whatnot" },
- # :method => "delete",
- # :html => { :class => "fine" }})
- #
- #
- # 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="#"
- # # data-url="http://www.example.com/destroy"
- # # data-update-success="posts"
- # # data-update-failure="error"
- # # data-remote="true">Delete this Post</a>'
- # #
- # link_to_remote "Delete this post",
- # :url => { :action => "destroy"},
- # :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>.
- #
- # Example:
- # # Generates:
- # # <a href="#"
- # # data-remote="true"
- # # data-url="http://www.example.com/whatnot"
- # # data-update-position="bottom">Remove Author</a>
- # #
- # link_to_remote("Remove Author", :url => { :action => "whatnot" }, :position => :bottom)
- #
- #
- # 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='#'
- # # data-url='/person/4'
- # # rel='nofollow'
- # # data-remote='true'
- # # data-method='delete'>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='#'
- # # data-url='http://www.example.com/undo?n=5'
- # # data-oncomplete='undoRequestCompleted(request)'
- # # data-remote='true'>undo</a>
- # #
- # link_to_remote "undo",
- # :url => { :controller => "words", :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='/testing/action'
- # # date-remote='true'
- # # data-failure="function(request){alert('HTTP Error '+ request.status +'+!');return false}"
- # # data-404="function(request){alert('Not found...? Wrong URL...?')}"> 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 the UJS drivers 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:
- #
- # # Generates:
- # # <a href='/posts/1'
- # # rel='nofollow'
- # # data-remote='true'
- # # data-method='delete'> Delete this post</a>
- # #
- # link_to_remote "Delete this post",
- # { :update => "posts", :url => { :action => "destroy", :id => post.id } }
- #
- def link_to_remote(name, options, html_options = {})
- attributes = {}
-
- attributes.merge!(:rel => "nofollow") if options[:method] && options[:method].to_s.downcase == "delete"
- attributes.merge!(extract_remote_attributes!(options))
-
- if confirm = options.delete(:confirm)
- add_confirm_to_attributes!(attributes, confirm)
- end
-
- attributes.merge!(html_options)
- href = html_options[:href].nil? ? "#" : html_options[:href]
- attributes.merge!(:href => href)
-
- content_tag(:a, name, attributes)
- end
-
- # Returns an input of type button, which allows the unobtrusive JavaScript driver
- # to dynamically adjust its behaviour. The default driver behaviour is to call a
- # remote action via XMLHttpRequest in the background.
- # The options for specifying the target with :url and defining callbacks is the same
- # as link_to_remote.
- #
- # Example:
- #
- # # Generates:
- # # <input class="fine"
- # # type="button"
- # # value="Remote outpost"
- # # data-remote="true"
- # # data-url="http://www.example.com/whatnot" />
- # #
- # button_to_remote("Remote outpost", { :url => { :action => "whatnot" }}, { :class => "fine" })
- #
- def button_to_remote(name, options = {}, html_options = {})
- attributes = html_options.merge!(:type => "button", :value => name)
-
- if confirm = options.delete(:confirm)
- add_confirm_to_attributes!(attributes, confirm)
- end
-
- if disable_with = options.delete(:disable_with)
- add_disable_with_to_attributes!(attributes, disable_with)
- end
-
- attributes.merge!(extract_remote_attributes!(options))
-
- tag(:input, attributes)
- end
-
- # Returns an input tag of type button, with the element name of +name+ and a value (i.e., display text)
- # of +value+ which will allow the unobtrusive JavaScript driver to dynamically adjust its behaviour
- # The default behaviour is to call a remote action via XMLHttpRequest in the background.
- #
- # request that reloads the page.
- #
- # # Create a button that submits to the create action
- # #
- # # Generates:
- # # <input name='create_btn'
- # # type='button'
- # # value='Create'
- # # data-remote='true'
- # # data-url='/create' />
- # #
- # <%= submit_to_remote 'create_btn', 'Create', :url => { :action => 'create' } %>
- #
- # # Submit to the remote action update and update the DIV succeed or fail based
- # # on the success or failure of the request
- # #
- # # Generates:
- # # <input name='update_btn'
- # # type='button'
- # # value='Update'
- # # date-remote-submit='true'
- # # data-url='/testing/update'
- # # data-success='succeed'
- # # data-failure='fail' />
- # #
- # <%= submit_to_remote 'update_btn', 'Update', :url => { :action => 'update' },
- # :update => { :success => "succeed", :failure => "fail" }
- #
- # <tt>options</tt> argument is the same as in form_remote_tag.
- def submit_to_remote(name, value, options = {})
- html_options = options.delete(:html) || {}
- html_options.merge!(:name => name, :value => value, :type => "button")
-
- attributes = extract_remote_attributes!(options)
- attributes.merge!(html_options)
- attributes["data-remote-submit"] = true
- attributes.delete("data-remote")
-
- tag(:input, attributes)
- end
-
- # Periodically provides the UJS driver with the information to call the specified
- # url (<tt>options[:url]</tt>) every <tt>options[:frequency]</tt> seconds (default is 10). Usually used to
- # update a specified div (<tt>options[:update]</tt>) with the results
- # of the remote call. The options for specifying the target with <tt>:url</tt>
- # and defining callbacks is the same as link_to_remote.
- # Examples:
- # # Call get_averages and put its results in 'avg' every 10 seconds
- # # Generates:
- # # <script data-periodical='true'
- # # data-url='/get_averages'
- # # type='application/json'
- # # data-update-success='avg'
- # # data-frequency='10'></script>
- # #
- # periodically_call_remote(:url => { :action => 'get_averages' }, :update => 'avg')
- #
- # # Call invoice every 10 seconds with the id of the customer
- # # If it succeeds, update the invoice DIV; if it fails, update the error DIV
- # # Generates:
- # # <script data-periodical='true'
- # # data-url='/invoice/1'
- # # type='application/json'
- # # data-update-success='invoice'
- # # data-update-failure='error'
- # # data-frequency='10'></script>"
- # #
- # periodically_call_remote(:url => { :action => 'invoice', :id => 1 },
- # :update => { :success => "invoice", :failure => "error" }
- #
- # # Call update every 20 seconds and update the new_block DIV
- # # Generates:
- # # <script data-periodical='true'
- # # data-url='update'
- # # type='application/json'
- # # data-update-success='news_block'
- # # data-frequency='20'></script>
- # #
- # periodically_call_remote(:url => 'update', :frequency => '20', :update => 'news_block')
- #
- def periodically_call_remote(options = {})
- attributes = extract_observer_attributes!(options)
- attributes["data-periodical"] = true
- attributes["data-frequency"] ||= 10
-
- # periodically_call_remote does not need data-observe=true
- attributes.delete('data-observe')
-
- script_decorator(attributes).html_safe!
- end
-
- # Observes the field with the DOM ID specified by +field_id+ and calls a
- # callback when its contents have changed. The default callback is an
- # Ajax call. By default the value of the observed field is sent as a
- # parameter with the Ajax call.
- #
- # Example:
- # # Generates:
- # # "<script type='text/javascript'
- # # data-observe='true'
- # # data-observed='suggest'
- # # data-frequency='0.25'
- # # type='application/json'
- # # data-url='/find_suggestion'
- # # data-update-success='suggest'
- # # data-with='q'></script>"
- # #
- # <%= observe_field :suggest, :url => { :action => :find_suggestion },
- # :frequency => 0.25,
- # :update => :suggest,
- # :with => 'q'
- # %>
- #
- # Required +options+ are either of:
- # <tt>:url</tt>:: +url_for+-style options for the action to call
- # when the field has changed.
- # <tt>:function</tt>:: Instead of making a remote call to a URL, you
- # can specify javascript code to be called instead.
- # Note that the value of this option is used as the
- # *body* of the javascript function, a function definition
- # with parameters named element and value will be generated for you
- # for example:
- # observe_field("glass", :frequency => 1, :function => "alert('Element changed')")
- # will generate:
- # new Form.Element.Observer('glass', 1, function(element, value) {alert('Element changed')})
- # The element parameter is the DOM element being observed, and the value is its value at the
- # time the observer is triggered.
- #
- # Additional options are:
- # <tt>:frequency</tt>:: The frequency (in seconds) at which changes to
- # this field will be detected. Not setting this
- # option at all or to a value equal to or less than
- # zero will use event based observation instead of
- # time based observation.
- # <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 parameters
- # for the XMLHttpRequest. The default is to send the
- # key and value of the observed field. Any custom
- # expressions should return a valid URL query string.
- # The value of the field is stored in the JavaScript
- # variable +value+.
- #
- # Examples
- #
- # :with => "'my_custom_key=' + value"
- # :with => "'person[name]=' + prompt('New name')"
- # :with => "Form.Element.serialize('other-field')"
- #
- # Finally
- # :with => 'name'
- # is shorthand for
- # :with => "'name=' + value"
- # This essentially just changes the key of the parameter.
- #
- # Additionally, you may specify any of the options documented in the
- # <em>Common options</em> section at the top of this document.
- #
- # Example:
- #
- # # Sends params: {:title => 'Title of the book'} when the book_title input
- # # field is changed.
- # observe_field 'book_title',
- # :url => 'http://example.com/books/edit/1',
- # :with => 'title'
- #
- #
- def observe_field(name, options = {})
- html_options = options.delete(:callbacks)
-
- options[:observed] = name
- attributes = extract_observer_attributes!(options)
- attributes.merge!(html_options) if html_options
-
- script_decorator(attributes).html_safe!
- end
-
- # Observes the form with the DOM ID specified by +form_id+ and calls a
- # callback when its contents have changed. The default callback is an
- # Ajax call. By default all fields of the observed field are sent as
- # parameters with the Ajax call.
- #
- # The +options+ for +observe_form+ are the same as the options for
- # +observe_field+. The JavaScript variable +value+ available to the
- # <tt>:with</tt> option is set to the serialized form by default.
- def observe_form(name, options = {})
- html_options = options.delete(:callbacks)
-
- options[:observed] = name
- attributes = extract_observer_attributes!(options)
- attributes.merge!(html_options) if html_options
-
- script_decorator(attributes).html_safe!
- end
-
- def script_decorator(options)
- attributes = %w(type="application/json")
- attributes += options.map{|k, v| k + '="' + v.to_s + '"'}
- "<script " + attributes.join(" ") + "></script>"
- end
-
- private
-
- def extract_remote_attributes!(options)
- attributes = options.delete(:html) || {}
-
- attributes.merge!(extract_update_attributes!(options))
- attributes.merge!(extract_request_attributes!(options))
- attributes["data-remote"] = true
-
- if submit = options.delete(:submit)
- attributes["data-submit"] = submit
- end
-
- attributes
- end
-
- def extract_request_attributes!(options)
- attributes = {}
- if method = options.delete(:method)
- attributes["data-method"] = method.to_s
- end
-
- if type = options.delete(:type)
- attributes["data-remote-type"] = type.to_s
- end
-
- url_options = options.delete(:url)
- url_options = url_options.merge(:escape => false) if url_options.is_a?(Hash)
- attributes["data-url"] = escape_javascript(url_for(url_options)) if url_options
-
- purge_unused_attributes!(attributes)
- end
-
- def extract_update_attributes!(options)
- attributes = {}
- update = options.delete(:update)
- if update.is_a?(Hash)
- attributes["data-update-success"] = update[:success]
- attributes["data-update-failure"] = update[:failure]
- else
- attributes["data-update-success"] = update
- end
-
- if position = options.delete(:position)
- attributes["data-update-position"] = position.to_s
- end
-
- purge_unused_attributes!(attributes)
- end
-
- def extract_observer_attributes!(options)
- callback = options.delete(:function)
- frequency = options.delete(:frequency) || 10
-
-
- attributes = extract_remote_attributes!(options)
- attributes["data-observe"] = true
- attributes["data-observed"] = options.delete(:observed)
- attributes["data-onobserve"] = callback if callback
- attributes["data-frequency"] = frequency if frequency && frequency.to_f != 0
- attributes.delete("data-remote")
-
- purge_unused_attributes!(attributes)
- end
-
- def purge_unused_attributes!(attributes)
- attributes.delete_if {|key, value| value.nil? }
- attributes
- end
- end
-
- # TODO: All evaled goes here per wycat
- module AjaxHelperCompat
- include AjaxHelper
-
- def link_to_remote(name, options, html_options = {})
- set_callbacks(options, html_options)
- set_with_and_condition_attributes(options, html_options)
- super
- end
-
- def button_to_remote(name, options = {}, html_options = {})
- set_callbacks(options, html_options)
- set_with_and_condition_attributes(options, html_options)
- super
- end
-
- def form_remote_tag(options, &block)
- html = {}
- set_callbacks(options, html)
- set_with_and_condition_attributes(options, html)
- options.merge!(:callbacks => html)
- super
- end
-
- def observe_field(name, options = {})
- html = {}
- set_with_and_condition_attributes(options, html)
- options.merge!(:callbacks => html)
- super
- end
-
- def observe_form(name, options = {})
- html = {}
- set_with_and_condition_attributes(options, html)
- options.merge!(:callbacks => html)
- super
- end
-
- private
- def set_callbacks(options, html)
- [:before, :after, :uninitialized, :complete, :failure, :success, :interactive, :loaded, :loading].each do |type|
- html["data-on#{type}"] = options.delete(type.to_sym)
- end
-
- options.each do |option, value|
- if option.is_a?(Integer)
- html["data-on#{option}"] = options.delete(option)
- end
- end
- end
-
- def set_with_and_condition_attributes(options, html)
- if with = options.delete(:with)
- html["data-with"] = with
- end
-
- if condition = options.delete(:condition)
- html["data-condition"] = condition
- end
- end
- end
- end
-end
diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
index 83357dd76f..4df99f8293 100644
--- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
@@ -140,7 +140,7 @@ module ActionView
:stylesheets_dir => "#{assets_dir}/stylesheets",
}
- JAVASCRIPT_DEFAULT_SOURCES = ['prototype', 'effects', 'dragdrop', 'controls'].freeze unless const_defined?(:JAVASCRIPT_DEFAULT_SOURCES)
+ JAVASCRIPT_DEFAULT_SOURCES = ['prototype', 'effects', 'dragdrop', 'controls', 'rails'].freeze unless const_defined?(:JAVASCRIPT_DEFAULT_SOURCES)
# Returns a link tag that browsers and news readers can use to auto-detect
# an RSS or ATOM feed. The +type+ can either be <tt>:rss</tt> (default) or
diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb
index b81925c7e7..157deebe40 100644
--- a/actionpack/lib/action_view/helpers/form_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_helper.rb
@@ -262,8 +262,23 @@ module ActionView
# FormTagHelper#form_tag.
def form_for(record_or_name_or_array, *args, &proc)
raise ArgumentError, "Missing block" unless block_given?
+
options = args.extract_options!
- object_name = extract_object_name_for_form!(args, options, record_or_name_or_array)
+
+ case record_or_name_or_array
+ when String, Symbol
+ object_name = record_or_name_or_array
+ when Array
+ object = record_or_name_or_array.last
+ object_name = ActionController::RecordIdentifier.singular_class_name(object)
+ apply_form_for_options!(record_or_name_or_array, options)
+ args.unshift object
+ else
+ object = record_or_name_or_array
+ object_name = ActionController::RecordIdentifier.singular_class_name(object)
+ apply_form_for_options!([object], options)
+ args.unshift object
+ end
concat(form_tag(options.delete(:url) || {}, options.delete(:html) || {}))
fields_for(object_name, *(args << options), &proc)
@@ -727,25 +742,6 @@ module ActionView
def radio_button(object_name, method, tag_value, options = {})
InstanceTag.new(object_name, method, self, options.delete(:object)).to_radio_button_tag(tag_value, options)
end
-
- private
- def extract_object_name_for_form!(args, options, record_or_name_or_array)
- case record_or_name_or_array
- when String, Symbol
- object_name = record_or_name_or_array
- when Array
- object = record_or_name_or_array.last
- object_name = ActionController::RecordIdentifier.singular_class_name(object)
- apply_form_for_options!(record_or_name_or_array, options)
- args.unshift object
- else
- object = record_or_name_or_array
- object_name = ActionController::RecordIdentifier.singular_class_name(object)
- apply_form_for_options!([object], options)
- args.unshift object
- end
- object_name
- end
end
module InstanceTagMethods #:nodoc:
diff --git a/actionpack/lib/action_view/helpers/form_tag_helper.rb b/actionpack/lib/action_view/helpers/form_tag_helper.rb
index ebce5c1513..fb32f78e5b 100644
--- a/actionpack/lib/action_view/helpers/form_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_tag_helper.rb
@@ -57,7 +57,7 @@ module ActionView
# ==== Examples
# select_tag "people", options_from_collection_for_select(@people, "name", "id")
# # <select id="people" name="people"><option value="1">David</option></select>
- #
+ #
# select_tag "people", "<option>David</option>"
# # => <select id="people" name="people"><option>David</option></select>
#
@@ -128,7 +128,7 @@ module ActionView
# Creates a label field
#
- # ==== Options
+ # ==== Options
# * Creates standard HTML attributes for the tag.
#
# ==== Examples
@@ -352,20 +352,20 @@ module ActionView
# # => <input disabled="disabled" name="commit" type="submit" value="Save edits" />
#
# submit_tag "Complete sale", :disable_with => "Please wait..."
- # # => <input name="commit" data-disable-with="Please wait..."
+ # # => <input name="commit" onclick="this.disabled=true;this.value='Please wait...';this.form.submit();"
# # type="submit" value="Complete sale" />
#
# submit_tag nil, :class => "form_submit"
# # => <input class="form_submit" name="commit" type="submit" />
#
# submit_tag "Edit", :disable_with => "Editing...", :class => "edit-button"
- # # => <input class="edit-button" data-disable-with="Editing..."
+ # # => <input class="edit-button" onclick="this.disabled=true;this.value='Editing...';this.form.submit();"
# # name="commit" type="submit" value="Edit" />
def submit_tag(value = "Save changes", options = {})
options.stringify_keys!
if disable_with = options.delete("disable_with")
- add_disable_with_to_attributes!(options, disable_with)
+ options["data-disable-with"] = disable_with if disable_with
end
if confirm = options.delete("confirm")
@@ -482,7 +482,6 @@ module ActionView
def sanitize_to_id(name)
name.to_s.gsub(']','').gsub(/[^-a-zA-Z0-9:.]/, "_")
end
-
end
end
end
diff --git a/actionpack/lib/action_view/helpers/javascript_helper.rb b/actionpack/lib/action_view/helpers/javascript_helper.rb
index ee6481b86d..7dca9849c0 100644
--- a/actionpack/lib/action_view/helpers/javascript_helper.rb
+++ b/actionpack/lib/action_view/helpers/javascript_helper.rb
@@ -35,98 +35,7 @@ module ActionView
# For documentation on +javascript_include_tag+ see
# ActionView::Helpers::AssetTagHelper.
module JavaScriptHelper
- unless const_defined? :JAVASCRIPT_PATH
- JAVASCRIPT_PATH = File.join(File.dirname(__FILE__), 'javascripts')
- end
-
- include AjaxHelperCompat
-
- # 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 {
- # $(&quot;details&quot;).visualEffect(&quot;toggle_blind&quot;);
- # $(&quot;more_link&quot;).update(&quot;Show me less&quot;);
- # }
- # catch (e) {
- # alert('RJS error:\n\n' + e.toString());
- # alert('$(\&quot;details\&quot;).visualEffect(\&quot;toggle_blind\&quot;);
- # \n$(\&quot;more_link\&quot;).update(\&quot;Show me less\&quot;);');
- # 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.
- #
- # The first argument +name+ is used as the button's value or display 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:
- # button_to_function "Greeting", "alert('Hello world!')"
- # button_to_function "Delete", "if (confirm('Really?')) do_delete()"
- # button_to_function "Details" do |page|
- # page[:details].visual_effect :toggle_slide
- # end
- # button_to_function "Details", :class => "details_button" do |page|
- # page[:details].visual_effect :toggle_slide
- # end
- def button_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};"
-
- tag(:input, html_options.merge(:type => 'button', :value => name, :onclick => onclick))
- end
+ include PrototypeHelper
JS_ESCAPE_MAP = {
'\\' => '\\\\',
@@ -186,65 +95,6 @@ module ActionView
def javascript_cdata_section(content) #:nodoc:
"\n//#{cdata_section("\n#{content}\n//")}\n"
end
-
- protected
- def convert_options_to_javascript!(html_options, url = '')
- confirm, popup = html_options.delete("confirm"), html_options.delete("popup")
-
- method, href = html_options.delete("method"), html_options['href']
-
- if popup && method
- raise ActionView::ActionViewError, "You can't use :popup and :method in the same link"
- elsif confirm && popup
- add_confirm_to_attributes!(html_options, confirm)
- html_options["data-popup"] = popup_attributes(popup)
- elsif confirm && method
- add_confirm_to_attributes!(html_options, confirm)
- add_method_to_attributes!(html_options, method, url)
- elsif confirm
- add_confirm_to_attributes!(html_options, confirm)
- elsif method
- add_method_to_attributes!(html_options, method, url)
- elsif popup
- html_options["data-popup"] = popup_attributes(popup)
- end
- end
-
- def add_confirm_to_attributes!(html_options, confirm)
- html_options["data-confirm"] = confirm if confirm
- end
-
- def add_method_to_attributes!(html_options, method, url = nil)
- html_options["rel"] = "nofollow" if method.to_s.downcase == "delete"
- html_options["data-method"] = method
- if url.size > 0
- html_options["data-url"] = url
- end
- end
-
- def add_disable_with_to_attributes!(html_options, disable_with)
- html_options["data-disable-with"] = disable_with if disable_with
- end
-
- def popup_attributes(popup)
- popup.is_a?(Array) ? "{title: '#{popup.first}', options: '#{popup.last}'}" : "true"
- end
-
- def options_for_javascript(options)
- if options.empty?
- '{}'
- else
- "{#{options.keys.map { |k| "#{k}:#{options[k]}" }.sort.join(', ')}}"
- end
- end
-
- def array_or_string_for_javascript(option)
- if option.kind_of?(Array)
- "['#{option.join('\',\'')}']"
- elsif !option.nil?
- "'#{option}'"
- end
- end
end
end
end
diff --git a/actionpack/lib/action_view/helpers/prototype_helper.rb b/actionpack/lib/action_view/helpers/prototype_helper.rb
index d861810f19..d335d89274 100644
--- a/actionpack/lib/action_view/helpers/prototype_helper.rb
+++ b/actionpack/lib/action_view/helpers/prototype_helper.rb
@@ -1,7 +1,6 @@
require 'set'
require 'active_support/json'
require 'active_support/core_ext/object/returning'
-require 'action_view/helpers/scriptaculous_helper'
module ActionView
module Helpers
@@ -28,6 +27,26 @@ module ActionView
# ActionView::Helpers::JavaScriptHelper for more information on including
# this and other JavaScript files in your Rails templates.)
#
+ # Now you're ready to call a remote action either through a link...
+ #
+ # link_to_remote "Add to cart",
+ # :url => { :action => "add", :id => product.id },
+ # :update => { :success => "cart", :failure => "error" }
+ #
+ # ...through a form...
+ #
+ # <% form_remote_tag :url => '/shipping' do -%>
+ # <div><%= submit_tag 'Recalculate Shipping' %></div>
+ # <% end -%>
+ #
+ # As you can see, there are numerous ways to use Prototype's Ajax functions (and actually more than
+ # are listed here); check out the documentation for each method to find out more about its usage and options.
+ #
+ # === Common Options
+ # See link_to_remote for documentation of options common to all Ajax
+ # helpers; any of the options specified by link_to_remote can be used
+ # by the other helpers.
+ #
# == Designing your Rails actions for Ajax
# When building your action handlers (that is, the Rails actions that receive your background requests), it's
# important to remember a few things. First, whatever your action would normally return to the browser, it will
@@ -74,8 +93,6 @@ module ActionView
# See JavaScriptGenerator for information on updating multiple elements
# on the page in an Ajax response.
module PrototypeHelper
- include ScriptaculousHelper
-
unless const_defined? :CALLBACKS
CALLBACKS = Set.new([ :create, :uninitialized, :loading, :loaded,
:interactive, :complete, :failure, :success ] +
@@ -85,6 +102,39 @@ module ActionView
:form, :with, :update, :script, :type ]).merge(CALLBACKS)
end
+ # Returns a button with the given +name+ text that'll trigger a JavaScript +function+ using the
+ # onclick handler.
+ #
+ # The first argument +name+ is used as the button's value or display 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:
+ # button_to_function "Greeting", "alert('Hello world!')"
+ # button_to_function "Delete", "if (confirm('Really?')) do_delete()"
+ # button_to_function "Details" do |page|
+ # page[:details].visual_effect :toggle_slide
+ # end
+ # button_to_function "Details", :class => "details_button" do |page|
+ # page[:details].visual_effect :toggle_slide
+ # end
+ def button_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};"
+
+ tag(:input, html_options.merge(:type => 'button', :value => name, :onclick => onclick))
+ end
+
# Returns the JavaScript needed for a remote function.
# Takes the same arguments as link_to_remote.
#
@@ -502,32 +552,6 @@ module ActionView
record "}, #{(seconds * 1000).to_i})"
end
- # Starts a script.aculo.us visual effect. See
- # ActionView::Helpers::ScriptaculousHelper for more information.
- def visual_effect(name, id = nil, options = {})
- record @context.send(:visual_effect, name, id, options)
- end
-
- # Creates a script.aculo.us sortable element. Useful
- # to recreate sortable elements after items get added
- # or deleted.
- # See ActionView::Helpers::ScriptaculousHelper for more information.
- def sortable(id, options = {})
- record @context.send(:sortable_element_js, id, options)
- end
-
- # Creates a script.aculo.us draggable element.
- # See ActionView::Helpers::ScriptaculousHelper for more information.
- def draggable(id, options = {})
- record @context.send(:draggable_element_js, id, options)
- end
-
- # Creates a script.aculo.us drop receiving element.
- # See ActionView::Helpers::ScriptaculousHelper for more information.
- def drop_receiving(id, options = {})
- record @context.send(:drop_receiving_element_js, id, options)
- end
-
private
def loop_on_multiple_args(method, ids)
record(ids.size>1 ?
@@ -599,65 +623,57 @@ module ActionView
javascript_tag update_page(&block), html_options
end
- protected
- def options_for_ajax(options)
- js_options = build_callbacks(options)
-
- js_options['asynchronous'] = options[:type] != :synchronous
- js_options['method'] = method_option_to_s(options[:method]) if options[:method]
- js_options['insertion'] = "'#{options[:position].to_s.downcase}'" if options[:position]
- js_options['evalScripts'] = options[:script].nil? || options[:script]
-
- if options[:form]
- js_options['parameters'] = 'Form.serialize(this)'
- elsif options[:submit]
- js_options['parameters'] = "Form.serialize('#{options[:submit]}')"
- elsif options[:with]
- js_options['parameters'] = options[:with]
- end
-
- if protect_against_forgery? && !options[:form]
- if js_options['parameters']
- js_options['parameters'] << " + '&"
+ protected
+ def options_for_javascript(options)
+ if options.empty?
+ '{}'
else
- js_options['parameters'] = "'"
+ "{#{options.keys.map { |k| "#{k}:#{options[k]}" }.sort.join(', ')}}"
end
- js_options['parameters'] << "#{request_forgery_protection_token}=' + encodeURIComponent('#{escape_javascript form_authenticity_token}')"
end
- options_for_javascript(js_options)
- end
+ def options_for_ajax(options)
+ js_options = build_callbacks(options)
- def method_option_to_s(method)
- (method.is_a?(String) and !method.index("'").nil?) ? method : "'#{method}'"
- end
+ js_options['asynchronous'] = options[:type] != :synchronous
+ js_options['method'] = method_option_to_s(options[:method]) if options[:method]
+ js_options['insertion'] = "'#{options[:position].to_s.downcase}'" if options[:position]
+ js_options['evalScripts'] = options[:script].nil? || options[:script]
- def build_observer(klass, name, options = {})
- if options[:with] && (options[:with] !~ /[\{=(.]/)
- options[:with] = "'#{options[:with]}=' + encodeURIComponent(value)"
- else
- options[:with] ||= 'value' unless options[:function]
+ if options[:form]
+ js_options['parameters'] = 'Form.serialize(this)'
+ elsif options[:submit]
+ js_options['parameters'] = "Form.serialize('#{options[:submit]}')"
+ elsif options[:with]
+ js_options['parameters'] = options[:with]
+ end
+
+ if protect_against_forgery? && !options[:form]
+ if js_options['parameters']
+ js_options['parameters'] << " + '&"
+ else
+ js_options['parameters'] = "'"
+ end
+ js_options['parameters'] << "#{request_forgery_protection_token}=' + encodeURIComponent('#{escape_javascript form_authenticity_token}')"
+ end
+
+ options_for_javascript(js_options)
end
- callback = options[:function] || remote_function(options)
- javascript = "new #{klass}('#{name}', "
- javascript << "#{options[:frequency]}, " if options[:frequency]
- javascript << "function(element, value) {"
- javascript << "#{callback}}"
- javascript << ")"
- javascript_tag(javascript)
- end
+ def method_option_to_s(method)
+ (method.is_a?(String) and !method.index("'").nil?) ? method : "'#{method}'"
+ end
- def build_callbacks(options)
- callbacks = {}
- options.each do |callback, code|
- if CALLBACKS.include?(callback)
- name = 'on' + callback.to_s.capitalize
- callbacks[name] = "function(request){#{code}}"
+ def build_callbacks(options)
+ callbacks = {}
+ options.each do |callback, code|
+ if CALLBACKS.include?(callback)
+ name = 'on' + callback.to_s.capitalize
+ callbacks[name] = "function(request){#{code}}"
+ end
end
+ callbacks
end
- callbacks
- end
end
# Converts chained method calls on DOM proxy elements into JavaScript chains
diff --git a/actionpack/lib/action_view/helpers/scriptaculous_helper.rb b/actionpack/lib/action_view/helpers/scriptaculous_helper.rb
index 04af2781d7..37319cca1b 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,46 +176,87 @@ 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]
%(Droppables.add(#{ActiveSupport::JSON.encode(element_id)}, #{options_for_javascript(options)});)
end
+
+ protected
+ def array_or_string_for_javascript(option)
+ if option.kind_of?(Array)
+ "['#{option.join('\',\'')}']"
+ elsif !option.nil?
+ "'#{option}'"
+ end
+ end
+ end
+
+ module PrototypeHelper
+ class JavaScriptGenerator
+ module GeneratorMethods
+ # Starts a script.aculo.us visual effect. See
+ # ActionView::Helpers::ScriptaculousHelper for more information.
+ def visual_effect(name, id = nil, options = {})
+ record @context.send(:visual_effect, name, id, options)
+ end
+
+ # Creates a script.aculo.us sortable element. Useful
+ # to recreate sortable elements after items get added
+ # or deleted.
+ # See ActionView::Helpers::ScriptaculousHelper for more information.
+ def sortable(id, options = {})
+ record @context.send(:sortable_element_js, id, options)
+ end
+
+ # Creates a script.aculo.us draggable element.
+ # See ActionView::Helpers::ScriptaculousHelper for more information.
+ def draggable(id, options = {})
+ record @context.send(:draggable_element_js, id, options)
+ end
+
+ # Creates a script.aculo.us drop receiving element.
+ # See ActionView::Helpers::ScriptaculousHelper for more information.
+ def drop_receiving(id, options = {})
+ record @context.send(:drop_receiving_element_js, id, options)
+ end
+ end
+ end
end
end
end
diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb
index 4424dbba42..bd179ef0b3 100644
--- a/actionpack/lib/action_view/helpers/url_helper.rb
+++ b/actionpack/lib/action_view/helpers/url_helper.rb
@@ -120,10 +120,6 @@ module ActionView
# * <tt>:confirm => 'question?'</tt> - This will add a JavaScript confirm
# prompt with the question specified. If the user accepts, the link is
# processed normally, otherwise no action is taken.
- # * <tt>:popup => true || array of window options</tt> - This will force the
- # link to open in a popup window. By passing true, a default browser window
- # will be opened with the URL. You can also specify an array of options
- # that are passed to the <tt>window.open</tt> JavaScript call.
# * <tt>:method => symbol of HTTP verb</tt> - This modifier will dynamically
# create an HTML form and immediately submit the form for processing using
# the HTTP verb specified. Useful for having links perform a POST operation
@@ -136,10 +132,6 @@ module ActionView
# the request object's methods for <tt>post?</tt>, <tt>delete?</tt> or <tt>put?</tt>.
# * The +html_options+ will accept a hash of html attributes for the link tag.
#
- # You can mix and match the +html_options+ with the exception of
- # <tt>:popup</tt> and <tt>:method</tt> which will raise an
- # <tt>ActionView::ActionViewError</tt> exception.
- #
# ==== Examples
# Because it relies on +url_for+, +link_to+ supports both older-style controller/action/id arguments
# and newer RESTful routes. Current Rails style favors RESTful routes whenever possible, so base
@@ -203,17 +195,11 @@ module ActionView
# link_to "Nonsense search", searches_path(:foo => "bar", :baz => "quux")
# # => <a href="/searches?foo=bar&amp;baz=quux">Nonsense search</a>
#
- # The three options specific to +link_to+ (<tt>:confirm</tt>, <tt>:popup</tt>, and <tt>:method</tt>) are used as follows:
+ # The three options specific to +link_to+ (<tt>:confirm</tt> and <tt>:method</tt>) are used as follows:
#
# link_to "Visit Other Site", "http://www.rubyonrails.org/", :confirm => "Are you sure?"
# # => <a href="http://www.rubyonrails.org/" onclick="return confirm('Are you sure?');">Visit Other Site</a>
#
- # link_to "Help", { :action => "help" }, :popup => true
- # # => <a href="/testing/help/" onclick="window.open(this.href);return false;">Help</a>
- #
- # link_to "View Image", @image, :popup => ['new_window_name', 'height=300,width=600']
- # # => <a href="/images/9" onclick="window.open(this.href,'new_window_name','height=300,width=600');return false;">View Image</a>
- #
# link_to "Delete Image", @image, :confirm => "Are you sure?", :method => :delete
# # => <a href="/images/9" onclick="if (confirm('Are you sure?')) { var f = document.createElement('form');
# f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = this.href;
@@ -232,11 +218,11 @@ module ActionView
html_options = args[2]
url = url_for(options)
+ html_options = convert_options_to_data_attributes(options, html_options)
if html_options
html_options = html_options.stringify_keys
href = html_options['href']
- convert_options_to_javascript!(html_options, url)
tag_options = tag_options(html_options)
else
tag_options = nil
@@ -305,11 +291,10 @@ module ActionView
request_token_tag = tag(:input, :type => "hidden", :name => request_forgery_protection_token.to_s, :value => form_authenticity_token)
end
-
url = options.is_a?(String) ? options : self.url_for(options)
name ||= url
-
- convert_options_to_javascript!(html_options, url)
+
+ html_options = convert_options_to_data_attributes(options, html_options)
html_options.merge!("type" => "submit", "value" => name)
@@ -562,6 +547,63 @@ module ActionView
end
private
+ def convert_options_to_data_attributes(options, html_options)
+ html_options = {} if html_options.nil?
+ html_options = html_options.stringify_keys
+
+ if (options.is_a?(Hash) && options.key?('remote')) || (html_options.is_a?(Hash) && html_options.key?('remote'))
+ html_options['data-remote'] = 'true'
+ options.delete('remote') if options.is_a?(Hash)
+ html_options.delete('remote') if html_options.is_a?(Hash)
+ end
+
+ confirm = html_options.delete("confirm")
+
+ if html_options.key?("popup")
+ ActiveSupport::Deprecation.warn(":popup has been deprecated", caller)
+ end
+
+ method, href = html_options.delete("method"), html_options['href']
+
+ if confirm && method
+ add_confirm_to_attributes!(html_options, confirm)
+ add_method_to_attributes!(html_options, method)
+ elsif confirm
+ add_confirm_to_attributes!(html_options, confirm)
+ elsif method
+ add_method_to_attributes!(html_options, method)
+ end
+
+ html_options["data-url"] = options[:url] if options.is_a?(Hash) && options[:url]
+
+ html_options
+ end
+
+ def add_confirm_to_attributes!(html_options, confirm)
+ html_options["data-confirm"] = confirm if confirm
+ end
+
+ def add_method_to_attributes!(html_options, method)
+ html_options["rel"] = "nofollow" if method && method.to_s.downcase != "get"
+ html_options["data-method"] = method if method
+ end
+
+ def options_for_javascript(options)
+ if options.empty?
+ '{}'
+ else
+ "{#{options.keys.map { |k| "#{k}:#{options[k]}" }.sort.join(', ')}}"
+ end
+ end
+
+ def array_or_string_for_javascript(option)
+ if option.kind_of?(Array)
+ "['#{option.join('\',\'')}']"
+ elsif !option.nil?
+ "'#{option}'"
+ end
+ end
+
# Processes the +html_options+ hash, converting the boolean
# attributes from true/false form into the form required by
# HTML/XHTML. (An attribute is considered to be boolean if
diff --git a/actionpack/lib/action_view/paths.rb b/actionpack/lib/action_view/paths.rb
index 0059b79e5f..6e55d69d00 100644
--- a/actionpack/lib/action_view/paths.rb
+++ b/actionpack/lib/action_view/paths.rb
@@ -45,7 +45,7 @@ module ActionView #:nodoc:
end
end
- raise ActionView::MissingTemplate.new(self, "#{prefix}/#{path} - #{details.inspect} - partial: #{!!partial}")
+ raise ActionView::MissingTemplate.new(self, "#{prefix}/#{path}", details, partial)
end
def exists?(path, extension = nil, prefix = nil, partial = false)
diff --git a/actionpack/test/abstract/render_test.rb b/actionpack/test/abstract/render_test.rb
index ffd430fa86..db924633ca 100644
--- a/actionpack/test/abstract/render_test.rb
+++ b/actionpack/test/abstract/render_test.rb
@@ -11,13 +11,17 @@ module AbstractController
end
self.view_paths = [ActionView::FixtureResolver.new(
- "default.erb" => "With Default",
"template.erb" => "With Template",
+ "renderer/default.erb" => "With Default",
"renderer/string.erb" => "With String",
"renderer/symbol.erb" => "With Symbol",
+ "renderer/template_name.erb" => "With Template Name",
"string/with_path.erb" => "With String With Path",
"some/file.erb" => "With File",
- "template_name.erb" => "With Template Name"
+ "with_format.html.erb" => "With html format",
+ "with_format.xml.erb" => "With xml format",
+ "with_locale.en.erb" => "With en locale",
+ "with_locale.pl.erb" => "With pl locale"
)]
def template
@@ -59,6 +63,22 @@ module AbstractController
def object
render :_template => ActionView::Template::Text.new("With Object")
end
+
+ def with_html_format
+ render :template => "with_format", :format => :html
+ end
+
+ def with_xml_format
+ render :template => "with_format", :format => :xml
+ end
+
+ def with_en_locale
+ render :template => "with_locale"
+ end
+
+ def with_pl_locale
+ render :template => "with_locale", :locale => :pl
+ end
end
class TestRenderer < ActiveSupport::TestCase
@@ -117,6 +137,25 @@ module AbstractController
assert_equal "With Object", @controller.response_body
end
+ def test_render_with_html_format
+ @controller.process(:with_html_format)
+ assert_equal "With html format", @controller.response_body
+ end
+
+ def test_render_with_xml_format
+ @controller.process(:with_xml_format)
+ assert_equal "With xml format", @controller.response_body
+ end
+
+ def test_render_with_en_locale
+ @controller.process(:with_en_locale)
+ assert_equal "With en locale", @controller.response_body
+ end
+
+ def test_render_with_pl_locale
+ @controller.process(:with_pl_locale)
+ assert_equal "With pl locale", @controller.response_body
+ end
end
end
end
diff --git a/actionpack/test/controller/assert_select_test.rb b/actionpack/test/controller/assert_select_test.rb
index 2e77d2f8ad..612827dd41 100644
--- a/actionpack/test/controller/assert_select_test.rb
+++ b/actionpack/test/controller/assert_select_test.rb
@@ -18,7 +18,7 @@ unless defined?(ActionMailer)
end
end
-ActionMailer::Base.template_root = FIXTURE_LOAD_PATH
+ActionMailer::Base.view_paths = FIXTURE_LOAD_PATH
class AssertSelectTest < ActionController::TestCase
Assertion = ActiveSupport::TestCase::Assertion
@@ -716,7 +716,7 @@ EOF
def test_assert_select_email
assert_raise(Assertion) { assert_select_email {} }
- AssertSelectMailer.deliver_test "<div><p>foo</p><p>bar</p></div>"
+ AssertSelectMailer.test("<div><p>foo</p><p>bar</p></div>").deliver
assert_select_email do
assert_select "div:root" do
assert_select "p:first-child", "foo"
diff --git a/actionpack/test/controller/helper_test.rb b/actionpack/test/controller/helper_test.rb
index e53e62d1ff..75a96d6497 100644
--- a/actionpack/test/controller/helper_test.rb
+++ b/actionpack/test/controller/helper_test.rb
@@ -135,17 +135,16 @@ class HelperTest < ActiveSupport::TestCase
assert methods.include?('foobar')
end
- # TODO Add this deprecation back before Rails 3.0 final release
- # def test_deprecation
- # assert_deprecated do
- # ActionController::Base.helpers_dir = "some/foo/bar"
- # end
- # assert_deprecated do
- # assert_equal ["some/foo/bar"], ActionController::Base.helpers_dir
- # end
- # ensure
- # ActionController::Base.helpers_path = [File.dirname(__FILE__) + '/../fixtures/helpers']
- # end
+ def test_deprecation
+ assert_deprecated do
+ ActionController::Base.helpers_dir = "some/foo/bar"
+ end
+ assert_deprecated do
+ assert_equal ["some/foo/bar"], ActionController::Base.helpers_dir
+ end
+ ensure
+ ActionController::Base.helpers_path = [File.dirname(__FILE__) + '/../fixtures/helpers']
+ end
private
def expected_helper_methods
diff --git a/actionpack/test/controller/mime_responds_test.rb b/actionpack/test/controller/mime_responds_test.rb
index ba2347e4e2..3bd3369242 100644
--- a/actionpack/test/controller/mime_responds_test.rb
+++ b/actionpack/test/controller/mime_responds_test.rb
@@ -499,7 +499,7 @@ class RespondWithController < ActionController::Base
def using_resource_with_action
respond_with(resource, :action => :foo) do |format|
- format.html { raise ActionView::MissingTemplate.new([], "method") }
+ format.html { raise ActionView::MissingTemplate.new([], "foo/bar", {}, false) }
end
end
diff --git a/actionpack/test/controller/request_forgery_protection_test.rb b/actionpack/test/controller/request_forgery_protection_test.rb
index 09003adf73..b2a0e2e2a3 100644
--- a/actionpack/test/controller/request_forgery_protection_test.rb
+++ b/actionpack/test/controller/request_forgery_protection_test.rb
@@ -6,14 +6,10 @@ module RequestForgeryProtectionActions
def index
render :inline => "<%= form_tag('/') {} %>"
end
-
+
def show_button
render :inline => "<%= button_to('New', '/') {} %>"
end
-
- def remote_form
- render :inline => "<% form_remote_tag(:url => '/') {} %>"
- end
def unsafe
render :text => 'pwn'
@@ -30,11 +26,11 @@ end
class FreeCookieController < RequestForgeryProtectionController
self.allow_forgery_protection = false
-
+
def index
render :inline => "<%= form_tag('/') {} %>"
end
-
+
def show_button
render :inline => "<%= button_to('New', '/') {} %>"
end
@@ -65,11 +61,6 @@ module RequestForgeryProtectionTests
assert_select 'form>div>input[name=?][value=?]', 'authenticity_token', @token
end
- def test_should_render_remote_form_with_only_one_token_parameter
- get :remote_form
- assert_equal 1, @response.body.scan(@token).size
- end
-
def test_should_allow_get
get :index
assert_response :success
@@ -84,12 +75,12 @@ module RequestForgeryProtectionTests
@request.env['CONTENT_TYPE'] = Mime::URL_ENCODED_FORM.to_s
assert_raise(ActionController::InvalidAuthenticityToken) { post :index, :format => :html }
end
-
+
def test_should_not_allow_html_put_without_token
@request.env['CONTENT_TYPE'] = Mime::URL_ENCODED_FORM.to_s
assert_raise(ActionController::InvalidAuthenticityToken) { put :index, :format => :html }
end
-
+
def test_should_not_allow_html_delete_without_token
@request.env['CONTENT_TYPE'] = Mime::URL_ENCODED_FORM.to_s
assert_raise(ActionController::InvalidAuthenticityToken) { delete :index, :format => :html }
@@ -154,51 +145,51 @@ module RequestForgeryProtectionTests
delete :index, :format => 'xml'
end
end
-
+
def test_should_allow_xhr_post_without_token
assert_nothing_raised { xhr :post, :index }
end
-
+
def test_should_allow_xhr_put_without_token
assert_nothing_raised { xhr :put, :index }
end
-
+
def test_should_allow_xhr_delete_without_token
assert_nothing_raised { xhr :delete, :index }
end
-
+
def test_should_allow_xhr_post_with_encoded_form_content_type_without_token
@request.env['CONTENT_TYPE'] = Mime::URL_ENCODED_FORM.to_s
assert_nothing_raised { xhr :post, :index }
end
-
+
def test_should_allow_post_with_token
post :index, :authenticity_token => @token
assert_response :success
end
-
+
def test_should_allow_put_with_token
put :index, :authenticity_token => @token
assert_response :success
end
-
+
def test_should_allow_delete_with_token
delete :index, :authenticity_token => @token
assert_response :success
end
-
+
def test_should_allow_post_with_xml
@request.env['CONTENT_TYPE'] = Mime::XML.to_s
post :index, :format => 'xml'
assert_response :success
end
-
+
def test_should_allow_put_with_xml
@request.env['CONTENT_TYPE'] = Mime::XML.to_s
put :index, :format => 'xml'
assert_response :success
end
-
+
def test_should_allow_delete_with_xml
@request.env['CONTENT_TYPE'] = Mime::XML.to_s
delete :index, :format => 'xml'
@@ -231,17 +222,17 @@ class FreeCookieControllerTest < ActionController::TestCase
ActiveSupport::SecureRandom.stubs(:base64).returns(@token)
end
-
+
def test_should_not_render_form_with_token_tag
get :index
assert_select 'form>div>input[name=?][value=?]', 'authenticity_token', @token, false
end
-
+
def test_should_not_render_button_to_with_token_tag
get :show_button
assert_select 'form>div>input[name=?][value=?]', 'authenticity_token', @token, false
end
-
+
def test_should_allow_all_methods_without_token
[:post, :put, :delete].each do |method|
assert_nothing_raised { send(method, :index)}
diff --git a/actionpack/test/abstract/url_for_test.rb b/actionpack/test/controller/url_for_test.rb
index e5570349b8..749fa5861f 100644
--- a/actionpack/test/abstract/url_for_test.rb
+++ b/actionpack/test/controller/url_for_test.rb
@@ -5,7 +5,7 @@ module AbstractController
class UrlForTests < ActionController::TestCase
class W
- include AbstractController::UrlFor
+ include ActionController::UrlFor
end
def teardown
@@ -132,7 +132,7 @@ module AbstractController
end
# We need to create a new class in order to install the new named route.
- kls = Class.new { include AbstractController::UrlFor }
+ kls = Class.new { include ActionController::UrlFor }
controller = kls.new
assert controller.respond_to?(:home_url)
assert_equal 'http://www.basecamphq.com/home/sweet/home/again',
@@ -153,7 +153,7 @@ module AbstractController
match '/home/sweet/home/:user', :to => 'home#index', :as => :home
end
- kls = Class.new { include AbstractController::UrlFor }
+ kls = Class.new { include ActionController::UrlFor }
controller = kls.new
assert_equal 'http://www.basecamphq.com/subdir/home/sweet/home/again',
@@ -171,7 +171,7 @@ module AbstractController
end
# We need to create a new class in order to install the new named route.
- kls = Class.new { include AbstractController::UrlFor }
+ kls = Class.new { include ActionController::UrlFor }
controller = kls.new
assert controller.respond_to?(:home_url)
assert_equal '/brave/new/world',
@@ -239,7 +239,7 @@ module AbstractController
end
# We need to create a new class in order to install the new named route.
- kls = Class.new { include AbstractController::UrlFor }
+ kls = Class.new { include ActionController::UrlFor }
kls.default_url_options[:host] = 'www.basecamphq.com'
controller = kls.new
@@ -251,8 +251,8 @@ module AbstractController
end
def test_multiple_includes_maintain_distinct_options
- first_class = Class.new { include AbstractController::UrlFor }
- second_class = Class.new { include AbstractController::UrlFor }
+ first_class = Class.new { include ActionController::UrlFor }
+ second_class = Class.new { include ActionController::UrlFor }
first_host, second_host = 'firsthost.com', 'secondhost.com'
diff --git a/actionpack/test/template/ajax_helper_test.rb b/actionpack/test/template/ajax_helper_test.rb
deleted file mode 100644
index c925dbb8f6..0000000000
--- a/actionpack/test/template/ajax_helper_test.rb
+++ /dev/null
@@ -1,452 +0,0 @@
-require 'abstract_unit'
-require 'active_model'
-
-class Author
- extend ActiveModel::Naming
- include ActiveModel::Conversion
-
- attr_reader :id
- def save
- @id = 1
- end
-
- def new_record?
- @id.nil?
- end
-
- def name
- @id.nil? ? 'new author' : "author ##{@id}"
- end
-end
-
-class Article
- extend ActiveModel::Naming
- include ActiveModel::Conversion
- attr_reader :id
- attr_reader :author_id
-
- def save
- @id = 1
- @author_id = 1
- end
-
- def new_record?
- @id.nil?
- end
-
- def name
- @id.nil? ? 'new article' : "article ##{@id}"
- end
-end
-
-class AjaxHelperBaseTest < ActionView::TestCase
- attr_accessor :formats, :output_buffer
-
- def reset_formats(format)
- @format = format
- end
-
- def setup
- super
- @template = self
- @controller = Class.new do
-
- def url_for(options)
- return optons unless options.is_a?(Hash)
-
- url = options.delete(:only_path) ? '/' : 'http://www.example.com'
-
- if controller = options.delete(:controller)
- url << '/' << controller.to_s
- end
- if action = options.delete(:action)
- url << '/' << action.to_s
- end
-
- if id = options.delete(:id)
- url << '/' << id.to_s
- end
-
- url << hash_to_param(options) if options.any?
-
- url.gsub!(/\/\/+/,'/')
-
- url
- end
-
- private
- def hash_to_param(hash)
- hash.map { |k,v| "#{k}=#{v}" }.join('&').insert(0,'?')
- end
- end.new
- end
-
- protected
- def request_forgery_protection_token
- nil
- end
-
- def protect_against_forgery?
- false
- end
-end
-
-class AjaxHelperTest < AjaxHelperBaseTest
- def _evaluate_assigns_and_ivars() end
-
- def setup
- @record = @author = Author.new
- @article = Article.new
- super
- end
-
- test "link_to_remote" do
- assert_dom_equal %(<a class=\"fine\" href=\"#\" data-remote=\"true\" data-url=\"/whatnot\">Remove Author</a>),
- link_to_remote("Remove Author", { :url => { :action => "whatnot" }}, { :class => "fine" })
- assert_dom_equal %(<a href=\"#\" data-remote=\"true\" data-url=\"/whatnot\" data-oncomplete=\"alert(request.responseText)\">Remove Author</a>),
- link_to_remote("Remove Author", :complete => "alert(request.responseText)", :url => { :action => "whatnot" })
- assert_dom_equal %(<a href=\"#\" data-remote=\"true\" data-url=\"/whatnot\" data-onsuccess=\"alert(request.responseText)\">Remove Author</a>),
- link_to_remote("Remove Author", :success => "alert(request.responseText)", :url => { :action => "whatnot" })
- assert_dom_equal %(<a href=\"#\" data-remote=\"true\" data-url=\"/whatnot\" data-onfailure=\"alert(request.responseText)\">Remove Author</a>),
- link_to_remote("Remove Author", :failure => "alert(request.responseText)", :url => { :action => "whatnot" })
- assert_dom_equal %(<a href=\"#\" data-remote=\"true\" data-url=\"/whatnot?a=10&amp;b=20\" data-onfailure=\"alert(request.responseText)\">Remove Author</a>),
- link_to_remote("Remove Author", :failure => "alert(request.responseText)", :url => { :action => "whatnot", :a => '10', :b => '20' })
- assert_dom_equal %(<a href=\"#\" data-remote=\"true\" data-url=\"/whatnot\" data-remote-type=\"synchronous\">Remove Author</a>),
- link_to_remote("Remove Author", :url => { :action => "whatnot" }, :type => :synchronous)
- assert_dom_equal %(<a href=\"#\" data-remote=\"true\" data-url=\"/whatnot\" data-update-position=\"bottom\">Remove Author</a>),
- link_to_remote("Remove Author", :url => { :action => "whatnot" }, :position => :bottom)
- end
-
- test "link_to_remote with url and oncomplete" do
- actual = link_to_remote "undo", :url => { :controller => "words", :action => "undo", :n => 5 }, :complete => "undoRequestCompleted(request)"
- expected = '<a href="#" data-url="/words/undo?n=5" data-remote="true" data-oncomplete="undoRequestCompleted(request)">undo</a>'
- assert_dom_equal expected, actual
- end
-
- test "link_to_remote with delete" do
- actual = link_to_remote("Remove Author", { :url => { :action => "whatnot" }, :method => 'delete'}, { :class => "fine" })
- expected = '<a class="fine" rel="nofollow" href="#" data-remote="true" data-method="delete" data-url="/whatnot">Remove Author</a>'
- assert_dom_equal expected, actual
- end
-
- test "link_to_remote using both url and href" do
- expected = '<a href="/destroy" data-url="/destroy" data-update-success="posts" data-remote="true">Delete this Post</a>'
- assert_dom_equal expected, link_to_remote( "Delete this Post",
- { :update => "posts",
- :url => { :action => "destroy" } },
- :href => url_for(:action => "destroy"))
- end
-
- test "link_to_remote with update-success and url" do
- expected = '<a href="#" data-url="/destroy" data-update-success="posts" data-update-failure="error" data-remote="true">Delete this Post</a>'
- assert_dom_equal expected, link_to_remote( "Delete this Post", :url => { :action => "destroy"},
- :update => { :success => "posts", :failure => "error" })
- end
-
- test "link_to_remote with before/after callbacks" do
- assert_dom_equal %(<a href=\"#\" data-remote=\"true\" data-url=\"/whatnot\" data-onbefore=\"before();\" data-onafter=\"after();\">Remote outauthor</a>),
- link_to_remote("Remote outauthor", :url => { :action => "whatnot" }, :before => "before();", :after => "after();")
- end
-
- test "link_to_remote using :with expression" do
- expected = %(<a href=\"#\" data-remote=\"true\" data-url=\"/whatnot\" data-with=\"id=123\">Remote outauthor</a>)
- assert_dom_equal expected, link_to_remote("Remote outauthor", :url => { :action => "whatnot" }, :with => "id=123")
- end
-
- test "link_to_remote using :condition expression" do
- expected = %(<a href=\"#\" data-remote=\"true\" data-url=\"/whatnot\" data-condition=\"$('foo').val() == true\">Remote outauthor</a>)
- assert_dom_equal expected, link_to_remote("Remote outauthor", :url => { :action => "whatnot" }, :condition => '$(\'foo\').val() == true')
- end
-
- test "link_to_remote using explicit :href" do
- expected = %(<a href=\"http://www.example.com/testhref\" data-remote=\"true\" data-url=\"/whatnot\" data-condition=\"$('foo').val() == true\">Remote outauthor</a>)
- assert_dom_equal expected, link_to_remote("Remote outauthor", {:url => { :action => "whatnot" }, :condition => '$(\'foo\').val() == true'}, :href => 'http://www.example.com/testhref')
- end
-
- test "link_to_remote using :submit" do
- expected = %(<a href=\"#\" data-remote=\"true\" data-url=\"/whatnot\" data-submit=\"myForm\">Remote outauthor</a>)
- assert_dom_equal expected, link_to_remote("Remote outauthor", :url => { :action => "whatnot" }, :submit => 'myForm')
- end
-
- test "link_to_remote with method delete" do
- assert_dom_equal %(<a class=\"fine\" href=\"#\" data-remote=\"true\" data-url=\"/whatnot\" data-method=\"delete\" rel=\"nofollow\">Remote outauthor</a>),
- link_to_remote("Remote outauthor", { :url => { :action => "whatnot" }, :method => "delete"}, { :class => "fine" })
- end
-
- test "link_to_remote with method delete as symbol" do
- assert_dom_equal %(<a class=\"fine\" href=\"#\" data-remote=\"true\" data-url=\"/whatnot\" data-method=\"delete\" rel=\"nofollow\">Remote outauthor</a>),
- link_to_remote("Remote outauthor", { :url => { :action => "whatnot" }, :method => :delete}, { :class => "fine" })
- end
-
- test "link_to_remote html options" do
- assert_dom_equal %(<a class=\"fine\" href=\"#\" data-remote=\"true\" data-url=\"/whatnot\">Remote outauthor</a>),
- link_to_remote("Remote outauthor", { :url => { :action => "whatnot" }, :html => { :class => "fine" } })
- end
-
- test "link_to_remote url quote escaping" do
- assert_dom_equal %(<a href="#" data-remote=\"true\" data-url=\"/whatnot\\\'s\">Remote</a>),
- link_to_remote("Remote", { :url => { :action => "whatnot's" } })
- end
-
- test "link_to_remote with confirm" do
- assert_dom_equal %(<a class=\"fine\" href=\"#\" data-remote=\"true\" data-url=\"/whatnot\" data-method=\"delete\" rel=\"nofollow\" data-confirm="Are you sure?">Remote confirm</a>),
- link_to_remote("Remote confirm", { :url => { :action => "whatnot" }, :method => "delete", :confirm => "Are you sure?"}, { :class => "fine" })
- end
-
- test "button_to_remote" do
- assert_dom_equal %(<input class=\"fine\" type=\"button\" value=\"Remote outpost\" data-remote=\"true\" data-url=\"/whatnot\" />),
- button_to_remote("Remote outpost", { :url => { :action => "whatnot" }}, { :class => "fine" })
- assert_dom_equal %(<input type=\"button\" value=\"Remote outpost\" data-remote=\"true\" data-url=\"/whatnot\" data-oncomplete=\"alert(request.reponseText)\" />),
- button_to_remote("Remote outpost", :complete => "alert(request.reponseText)", :url => { :action => "whatnot" })
- assert_dom_equal %(<input type=\"button\" value=\"Remote outpost\" data-remote=\"true\" data-url=\"/whatnot\" data-onsuccess=\"alert(request.reponseText)\" />),
- button_to_remote("Remote outpost", :success => "alert(request.reponseText)", :url => { :action => "whatnot" })
- assert_dom_equal %(<input type=\"button\" value=\"Remote outpost\" data-remote=\"true\" data-url=\"/whatnot\" data-onfailure=\"alert(request.reponseText)\" />),
- button_to_remote("Remote outpost", :failure => "alert(request.reponseText)", :url => { :action => "whatnot" })
- assert_dom_equal %(<input type=\"button\" value=\"Remote outpost\" data-remote=\"true\" data-url=\"/whatnot?a=10&amp;b=20\" data-onfailure=\"alert(request.reponseText)\" />),
- button_to_remote("Remote outpost", :failure => "alert(request.reponseText)", :url => { :action => "whatnot", :a => '10', :b => '20' })
- end
-
- test "button_to_remote with confirm" do
- assert_dom_equal %(<input class=\"fine\" type=\"button\" value=\"Remote outpost\" data-remote=\"true\" data-url=\"/whatnot\" data-confirm="Are you sure?" />),
- button_to_remote("Remote outpost", { :url => { :action => "whatnot" }, :confirm => "Are you sure?"}, { :class => "fine" })
- end
-
- test "button_to_remote with :submit" do
- assert_dom_equal %(<input class=\"fine\" type=\"button\" value=\"Remote outpost\" data-remote=\"true\" data-url=\"/whatnot\" data-submit="myForm" />),
- button_to_remote("Remote outpost", { :url => { :action => "whatnot" }, :submit => "myForm"}, { :class => "fine" })
- end
-
- test "periodically_call_remote" do
- expected = "<script data-url='/mehr_bier' data-update-success='schremser_bier' type='application/json' data-frequency='10' data-periodical='true'></script>"
- actual = periodically_call_remote(:update => "schremser_bier", :url => { :action => "mehr_bier" })
- assert_dom_equal expected, actual
- end
-
- test "periodically_call_remote_with_frequency" do
- expected = "<script data-periodical='true' type='application/json' data-frequency='2'></script>"
- actual = periodically_call_remote(:frequency => 2)
- assert_dom_equal expected, actual
- end
-
- test "periodically_call_remote_with_function" do
- expected = "<script data-periodical=\"true\" type=\"application/json\" data-onobserve=\"alert('test')\" data-frequency='2'></script>"
- actual = periodically_call_remote(:frequency => 2, :function => "alert('test')")
- assert_dom_equal expected, actual
- end
-
- test "periodically_call_remote_with_update" do
- actual = periodically_call_remote(:url => { :action => 'get_averages' }, :update => 'avg')
- expected = "<script data-periodical='true' data-url='/get_averages' type='application/json' data-update-success='avg' data-frequency='10'></script>"
- assert_dom_equal expected, actual
- end
-
- test "periodically_call_remote with update success and failure" do
- actual = periodically_call_remote(:url => { :action => 'invoice', :id => 1 },:update => { :success => "invoice", :failure => "error" })
- expected = "<script data-periodical='true' data-url='/invoice/1' type='application/json' data-update-success='invoice' data-frequency='10' data-update-failure='error'></script>"
- assert_dom_equal expected, actual
- end
-
- test "periodically_call_remote with frequency and update" do
- actual = periodically_call_remote(:url => 'update', :frequency => '20', :update => 'news_block')
- expected = "<script data-periodical='true' data-url='update' type='application/json' data-update-success='news_block' data-frequency='20'></script>"
- assert_dom_equal expected, actual
- end
-
- test "form_remote_tag" do
- assert_dom_equal %(<form action=\"/fast\" method=\"post\" data-remote=\"true\" data-update-success=\"glass_of_beer\">),
- form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast } )
- assert_dom_equal %(<form action=\"/fast\" method=\"post\" data-remote=\"true\" data-update-success=\"glass_of_beer\">),
- form_remote_tag(:update => { :success => "glass_of_beer" }, :url => { :action => :fast })
- assert_dom_equal %(<form action=\"/fast\" method=\"post\" data-remote=\"true\" data-update-failure=\"glass_of_water\">),
- form_remote_tag(:update => { :failure => "glass_of_water" }, :url => { :action => :fast })
- assert_dom_equal %(<form action=\"/fast\" method=\"post\" data-remote=\"true\" data-update-success=\"glass_of_beer\" data-update-failure=\"glass_of_water\">),
- form_remote_tag(:update => { :success => 'glass_of_beer', :failure => "glass_of_water" }, :url => { :action => :fast })
- end
-
- test "form_remote_tag with method" do
- assert_dom_equal %(<form action=\"/fast\" method=\"post\" data-remote=\"true\" data-update-success=\"glass_of_beer\"><div style='margin:0;padding:0;display:inline'><input name='_method' type='hidden' value='put' /></div>),
- form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }, :html => { :method => :put })
- end
-
- test "form_remote_tag with url" do
- form_remote_tag(:url => '/posts' ){}
- expected = "<form action='/posts' method='post' data-remote='true'></form>"
- assert_dom_equal expected, output_buffer
- end
-
- test "form_remote_tag with block in erb" do
- __in_erb_template = ''
- form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }) { concat "Hello world!" }
- assert_dom_equal %(<form action=\"/fast\" method=\"post\" data-remote=\"true\" data-update-success=\"glass_of_beer\">Hello world!</form>), output_buffer
- end
-
- test "remote_form_for with record identification with new record" do
- remote_form_for(@record, {:html => { :id => 'create-author' }}) {}
- expected = %(<form action='#{authors_path}' data-remote=\"true\" class='new_author' id='create-author' method='post'></form>)
- assert_dom_equal expected, output_buffer
- end
-
- test "remote_form_for with url" do
- remote_form_for(@record, {:html => { :id => 'create-author' }}) {}
- expected = "<form action='/authors' data-remote='true' class='new_author' id='create-author' method='post'></form>"
- assert_dom_equal expected, output_buffer
- end
-
- test "remote_form_for with record identification without html options" do
- remote_form_for(@record) {}
- expected = %(<form action='#{authors_path}' data-remote=\"true\" class='new_author' method='post' id='new_author'></form>)
- assert_dom_equal expected, output_buffer
- end
-
- test "remote_form_for with record identification with existing record" do
- @record.save
- remote_form_for(@record) {}
-
- expected = %(<form action='#{author_path(@record)}' id='edit_author_1' method='post' data-remote=\"true\" class='edit_author'><div style='margin:0;padding:0;display:inline'><input name='_method' type='hidden' value='put' /></div></form>)
- assert_dom_equal expected, output_buffer
- end
-
- test "remote_form_for with new nested object and an excisting parent" do
- @author.save
- remote_form_for([@author, @article]) {}
-
- expected = %(<form action='#{author_articles_path(@author)}' data-remote=\"true\" class='new_article' method='post' id='new_article'></form>)
- assert_dom_equal expected, output_buffer
- end
-
- test "remote_form_for with existing object in list" do
- @author.save
- @article.save
-
- remote_form_for([@author, @article]) {}
-
- expected = %(<form action='#{author_article_path(@author, @article)}' id='edit_article_#{@article.id}' method='post' data-remote=\"true\" class='edit_article'><div style='margin:0;padding:0;display:inline'><input name='_method' type='hidden' value='put' /></div></form>)
- assert_dom_equal expected, output_buffer
- end
-
- test "on callbacks" do
- callbacks = [:uninitialized, :loading, :loaded, :interactive, :complete, :success, :failure]
- callbacks.each do |callback|
- assert_dom_equal %(<form action=\"/fast\" method=\"post\" data-remote=\"true\" data-update-success=\"glass_of_beer\" data-on#{callback}=\"monkeys();\">),
- form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }, callback=>"monkeys();")
- assert_dom_equal %(<form action=\"/fast\" method=\"post\" data-remote=\"true\" data-update-success=\"glass_of_beer\" data-on#{callback}=\"monkeys();\">),
- form_remote_tag(:update => { :success => "glass_of_beer" }, :url => { :action => :fast }, callback=>"monkeys();")
- assert_dom_equal %(<form action=\"/fast\" method=\"post\" data-remote=\"true\" data-update-failure=\"glass_of_beer\" data-on#{callback}=\"monkeys();\">),
- form_remote_tag(:update => { :failure => "glass_of_beer" }, :url => { :action => :fast }, callback=>"monkeys();")
- assert_dom_equal %(<form action=\"/fast\" method=\"post\" data-remote=\"true\" data-update-failure=\"glass_of_water\" data-update-success=\"glass_of_beer\" data-on#{callback}=\"monkeys();\">),
- form_remote_tag(:update => { :success => "glass_of_beer", :failure => "glass_of_water" }, :url => { :action => :fast }, callback=>"monkeys();")
- end
-
- #HTTP status codes 200 up to 599 have callbacks
- #these should work
- 100.upto(599) do |callback|
- assert_dom_equal %(<form action=\"/fast\" method=\"post\" data-remote=\"true\" data-update-success=\"glass_of_beer\" data-on#{callback}=\"monkeys();\">),
- form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }, callback=>"monkeys();")
- end
-
- #test 200 and 404
- assert_dom_equal %(<form action=\"/fast\" method=\"post\" data-remote=\"true\" data-update-success=\"glass_of_beer\" data-on200=\"monkeys();\" data-on404=\"bananas();\">),
- form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }, 200=>"monkeys();", 404=>"bananas();")
-
- #these shouldn't
- 1.upto(99) do |callback|
- assert_dom_equal %(<form action=\"/fast\" method=\"post\" data-remote=\"true\" data-update-success=\"glass_of_beer\" data-on#{callback}=\"monkeys();\">),
- form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }, callback=>"monkeys();")
- end
- 600.upto(999) do |callback|
- assert_dom_equal %(<form action=\"/fast\" method=\"post\" data-remote=\"true\" data-update-success=\"glass_of_beer\" data-on#{callback}=\"monkeys();\">),
- form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }, callback=>"monkeys();")
- end
-
- #test ultimate combo
- assert_dom_equal %(<form data-on404=\"bananas();\" method=\"post\" data-onsuccess=\"s()\" action=\"/fast\" data-oncomplete=\"c();\" data-update-success=\"glass_of_beer\" data-on200=\"monkeys();\" data-onloading=\"c1()\" data-remote=\"true\" data-onfailure=\"f();\">),
- form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }, :loading => "c1()", :success => "s()", :failure => "f();", :complete => "c();", 200=>"monkeys();", 404=>"bananas();")
-
- end
-
- test "submit_to_remote" do
- assert_dom_equal %(<input name=\"More beer!\" type=\"button\" value=\"1000000\" data-url=\"/empty_bottle\" data-remote-submit=\"true\" data-update-success=\"empty_bottle\" />),
- submit_to_remote("More beer!", 1_000_000, :url => { :action => 'empty_bottle' }, :update => "empty_bottle")
- end
-
- test "submit_to_remote simple" do
- expected = "<input name='create_btn' type='button' value='Create' data-remote-submit='true' data-url='/create' />"
- actual = submit_to_remote 'create_btn', 'Create', :url => { :action => 'create' }
- assert_dom_equal expected, actual
- end
-
- test "submit_to_remote with success and failure" do
- expected = "<input name='update_btn' data-url='/update' data-remote-submit='true' data-update-failure='fail' data-update-success='succeed' value='Update' type='button' />"
- actual = submit_to_remote 'update_btn', 'Update', :url => { :action => 'update' }, :update => { :success => "succeed", :failure => "fail" }
- assert_dom_equal expected, actual
- end
-
- test "observe_field" do
- assert_dom_equal %(<script type=\"text/javascript\" data-observe=\"true\" data-observed=\"glass\" data-frequency=\"300\" type=\"application/json\" data-url=\"/reorder_if_empty\"></script>),
- observe_field("glass", :frequency => 5.minutes, :url => { :action => "reorder_if_empty" })
- end
-
- test "observe_field with url, frequency, update and with" do
- actual = observe_field :suggest, :url => { :action => :find_suggestion }, :frequency => 0.25, :update => :suggest, :with => 'q'
- expected = "<script type='text/javascript' data-observe='true' data-observed='suggest' data-frequency='0.25' type='application/json' data-url='/find_suggestion' data-update-success='suggest' data-with='q'></script>"
- assert_dom_equal actual, expected
- end
-
- test "observe_field default frequency" do
- actual = observe_field :suggest
- expected = "<script type='text/javascript' data-observe='true' data-observed='suggest' data-frequency='10' type='application/json'></script>"
- assert_dom_equal actual, expected
- end
-
- test "observe_field using with option" do
- expected = %(<script type=\"text/javascript\" data-observe=\"true\" data-observed=\"glass\" data-frequency=\"300\" type=\"application/json\" data-url=\"/check_value\" data-with=\"id=123\"></script>)
- assert_dom_equal expected, observe_field("glass", :frequency => 5.minutes, :url => { :action => "check_value" }, :with => 'id=123')
- end
-
- test "observe_field using condition option" do
- expected = %(<script type=\"text/javascript\" data-observe=\"true\" data-observed=\"glass\" data-frequency=\"300\" type=\"application/json\" data-url=\"/check_value\" data-condition=\"$('foo').val() == true\"></script>)
- assert_dom_equal expected, observe_field("glass", :frequency => 5.minutes, :url => { :action => "check_value" }, :condition => '$(\'foo\').val() == true')
- end
-
- test "observe_field using json in with option" do
- expected = %(<script data-with=\"{'id':value}\" data-observed=\"glass\" data-url=\"/check_value\" data-observe=\"true\" type=\"application/json\" data-frequency=\"300\"></script>)
- assert_dom_equal expected, observe_field("glass", :frequency => 5.minutes, :url => { :action => "check_value" }, :with => "{'id':value}")
- end
-
- test "observe_field using function for callback" do
- assert_dom_equal %(<script data-observed=\"glass\" data-observe=\"true\" type=\"application/json\" data-onobserve=\"alert('Element changed')\" data-frequency=\"300\"></script>),
- observe_field("glass", :frequency => 5.minutes, :function => "alert('Element changed')")
- end
-
- test "observe_form" do
- assert_dom_equal %(<script data-observed=\"cart\" data-url=\"/cart_changed\" data-observe=\"true\" type=\"application/json\" data-frequency=\"2\"></script>),
- observe_form("cart", :frequency => 2, :url => { :action => "cart_changed" })
- end
-
- test "observe_form using function for callback" do
- assert_dom_equal %(<script data-observed=\"cart\" data-observe=\"true\" type=\"application/json\" data-onobserve=\"alert('Form changed')\" data-frequency=\"2\"></script>),
- observe_form("cart", :frequency => 2, :function => "alert('Form changed')")
- end
-
- test "observe_field without frequency" do
- assert_dom_equal %(<script data-observed=\"glass\" data-observe=\"true\" type=\"application/json\" data-frequency='10'></script>),
- observe_field("glass")
- end
-
- protected
- def author_path(record)
- "/authors/#{record.id}"
- end
-
- def authors_path
- "/authors"
- end
-
- def author_articles_path(author)
- "/authors/#{author.id}/articles"
- end
-
- def author_article_path(author, article)
- "/authors/#{author.id}/articles/#{article.id}"
- end
-end
diff --git a/actionpack/test/template/asset_tag_helper_test.rb b/actionpack/test/template/asset_tag_helper_test.rb
index 57802ebf42..586de66714 100644
--- a/actionpack/test/template/asset_tag_helper_test.rb
+++ b/actionpack/test/template/asset_tag_helper_test.rb
@@ -86,11 +86,11 @@ class AssetTagHelperTest < ActionView::TestCase
%(javascript_include_tag("bank.js")) => %(<script src="/javascripts/bank.js" type="text/javascript"></script>),
%(javascript_include_tag("bank", :lang => "vbscript")) => %(<script lang="vbscript" src="/javascripts/bank.js" type="text/javascript"></script>),
%(javascript_include_tag("common.javascript", "/elsewhere/cools")) => %(<script src="/javascripts/common.javascript" type="text/javascript"></script>\n<script src="/elsewhere/cools.js" type="text/javascript"></script>),
- %(javascript_include_tag(:defaults)) => %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>),
+ %(javascript_include_tag(:defaults)) => %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/rails.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>),
%(javascript_include_tag(:all)) => %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/robber.js" type="text/javascript"></script>\n<script src="/javascripts/version.1.0.js" type="text/javascript"></script>),
%(javascript_include_tag(:all, :recursive => true)) => %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/robber.js" type="text/javascript"></script>\n<script src="/javascripts/subdir/subdir.js" type="text/javascript"></script>\n<script src="/javascripts/version.1.0.js" type="text/javascript"></script>),
- %(javascript_include_tag(:defaults, "bank")) => %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>),
- %(javascript_include_tag("bank", :defaults)) => %(<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>),
+ %(javascript_include_tag(:defaults, "bank")) => %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/rails.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>),
+ %(javascript_include_tag("bank", :defaults)) => %(<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/rails.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>),
%(javascript_include_tag("http://example.com/all")) => %(<script src="http://example.com/all" type="text/javascript"></script>),
%(javascript_include_tag("http://example.com/all.js")) => %(<script src="http://example.com/all.js" type="text/javascript"></script>),
@@ -235,7 +235,7 @@ class AssetTagHelperTest < ActionView::TestCase
def test_javascript_include_tag_with_given_asset_id
ENV["RAILS_ASSET_ID"] = "1"
- assert_dom_equal(%(<script src="/javascripts/prototype.js?1" type="text/javascript"></script>\n<script src="/javascripts/effects.js?1" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js?1" type="text/javascript"></script>\n<script src="/javascripts/controls.js?1" type="text/javascript"></script>\n<script src="/javascripts/application.js?1" type="text/javascript"></script>), javascript_include_tag(:defaults))
+ assert_dom_equal(%(<script src="/javascripts/prototype.js?1" type="text/javascript"></script>\n<script src="/javascripts/effects.js?1" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js?1" type="text/javascript"></script>\n<script src="/javascripts/controls.js?1" type="text/javascript"></script>\n<script src="/javascripts/rails.js?1" type="text/javascript"></script>\n<script src="/javascripts/application.js?1" type="text/javascript"></script>), javascript_include_tag(:defaults))
end
def test_javascript_include_tag_is_html_safe
@@ -246,14 +246,14 @@ class AssetTagHelperTest < ActionView::TestCase
def test_register_javascript_include_default
ENV["RAILS_ASSET_ID"] = ""
ActionView::Helpers::AssetTagHelper::register_javascript_include_default 'bank'
- assert_dom_equal %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>), javascript_include_tag(:defaults)
+ assert_dom_equal %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/rails.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>), javascript_include_tag(:defaults)
end
def test_register_javascript_include_default_mixed_defaults
ENV["RAILS_ASSET_ID"] = ""
ActionView::Helpers::AssetTagHelper::register_javascript_include_default 'bank'
ActionView::Helpers::AssetTagHelper::register_javascript_include_default 'robber', '/elsewhere/cools.js'
- assert_dom_equal %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/robber.js" type="text/javascript"></script>\n<script src="/elsewhere/cools.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>), javascript_include_tag(:defaults)
+ assert_dom_equal %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/rails.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/robber.js" type="text/javascript"></script>\n<script src="/elsewhere/cools.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>), javascript_include_tag(:defaults)
end
def test_custom_javascript_expansions
@@ -265,7 +265,7 @@ class AssetTagHelperTest < ActionView::TestCase
def test_custom_javascript_expansions_and_defaults_puts_application_js_at_the_end
ENV["RAILS_ASSET_ID"] = ""
ActionView::Helpers::AssetTagHelper::register_javascript_expansion :robbery => ["bank", "robber"]
- assert_dom_equal %(<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/robber.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>), javascript_include_tag('controls',:defaults, :robbery, 'effects')
+ assert_dom_equal %(<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/rails.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/robber.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>), javascript_include_tag('controls',:defaults, :robbery, 'effects')
end
def test_custom_javascript_expansions_with_undefined_symbol
@@ -965,6 +965,5 @@ class AssetTagHelperNonVhostTest < ActionView::TestCase
def test_assert_css_and_js_of_the_same_name_return_correct_extension
assert_dom_equal(%(/collaboration/hieraki/javascripts/foo.js), javascript_path("foo"))
assert_dom_equal(%(/collaboration/hieraki/stylesheets/foo.css), stylesheet_path("foo"))
-
end
end
diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb
index 147d3dc05d..c97343fbe5 100644
--- a/actionpack/test/template/form_helper_test.rb
+++ b/actionpack/test/template/form_helper_test.rb
@@ -1230,26 +1230,6 @@ class FormHelperTest < ActionView::TestCase
end
- # Perhaps this test should be moved to prototype helper tests.
- def test_remote_form_for_with_labelled_builder
- self.extend ActionView::Helpers::AjaxHelper
-
- remote_form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
- concat f.text_field(:title)
- concat f.text_area(:body)
- concat f.check_box(:secret)
- end
-
- expected =
- %(<form action="http://www.example.com" data-remote="true" method="post">) +
- "<label for='title'>Title:</label> <input name='post[title]' size='30' type='text' id='post_title' value='Hello World' /><br/>" +
- "<label for='body'>Body:</label> <textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea><br/>" +
- "<label for='secret'>Secret:</label> <input name='post[secret]' type='hidden' value='0' /><input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' /><br/>" +
- "</form>"
-
- assert_dom_equal expected, output_buffer
- end
-
def test_fields_for_with_labelled_builder
fields_for(:post, @post, :builder => LabelledFormBuilder) do |f|
concat f.text_field(:title)
@@ -1396,15 +1376,6 @@ class FormHelperTest < ActionView::TestCase
assert_equal expected, output_buffer
end
- def test_remote_form_for_with_html_options_adds_options_to_form_tag
- self.extend ActionView::Helpers::AjaxHelper
-
- remote_form_for(:post, @post, :html => {:id => 'some_form', :class => 'some_class'}) do |f| end
- expected = "<form action=\"http://www.example.com\" class=\"some_class\" id=\"some_form\" method=\"post\" data-remote=\"true\"></form>"
-
- assert_dom_equal expected, output_buffer
- end
-
protected
def comments_path(post)
"/posts/#{post.id}/comments"
diff --git a/actionpack/test/template/form_tag_helper_test.rb b/actionpack/test/template/form_tag_helper_test.rb
index c8d929cee8..01bde8ea04 100644
--- a/actionpack/test/template/form_tag_helper_test.rb
+++ b/actionpack/test/template/form_tag_helper_test.rb
@@ -285,8 +285,8 @@ class FormTagHelperTest < ActionView::TestCase
def test_submit_tag
assert_dom_equal(
- %(<input name='commit' data-disable-with="Saving..." onclick="alert('hello!');" type="submit" value="Save" />),
- submit_tag("Save", :disable_with => "Saving...", :onclick => "alert('hello!');")
+ %(<input name='commit' data-disable-with="Saving..." onclick="alert('hello!')" type="submit" value="Save" />),
+ submit_tag("Save", :disable_with => "Saving...", :onclick => "alert('hello!')")
)
end
@@ -299,21 +299,21 @@ class FormTagHelperTest < ActionView::TestCase
def test_submit_tag_with_confirmation
assert_dom_equal(
- %(<input name='commit' type='submit' value='Save' data-confirm="Are you sure?"/>),
+ %(<input name='commit' type='submit' value='Save' data-confirm="Are you sure?" />),
submit_tag("Save", :confirm => "Are you sure?")
)
end
def test_submit_tag_with_confirmation_and_with_disable_with
assert_dom_equal(
- %(<input name="commit" data-confirm="Are you sure?" data-disable-with="Saving..." type="submit" value="Save" />),
+ %(<input name="commit" data-disable-with="Saving..." data-confirm="Are you sure?" type="submit" value="Save" />),
submit_tag("Save", :disable_with => "Saving...", :confirm => "Are you sure?")
)
end
def test_image_submit_tag_with_confirmation
assert_dom_equal(
- %(<input type="image" src="/images/save.gif" data-confirm="Are you sure?"/>),
+ %(<input type="image" src="/images/save.gif" data-confirm="Are you sure?" />),
image_submit_tag("save.gif", :confirm => "Are you sure?")
)
end
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(&quot;header&quot;, &quot;\\u003Ch1\\u003EGreetings\\u003C/h1\\u003E&quot;);; 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(&quot;header&quot;, &quot;\\u003Ch1\\u003EGreetings\\u003C/h1\\u003E&quot;);; 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 86f9c231c0..d95bdc2b90 100644
--- a/actionpack/test/template/prototype_helper_test.rb
+++ b/actionpack/test/template/prototype_helper_test.rb
@@ -101,7 +101,6 @@ class PrototypeHelperTest < PrototypeHelperBaseTest
assert_equal javascript_tag(create_generator(&block).to_s, {:defer => 'true'}), update_page_tag({:defer => 'true'}, &block)
end
-
protected
def author_path(record)
"/authors/#{record.id}"
@@ -466,4 +465,3 @@ return value.reverse();
assert_equal "MyObject.myMethod(function() { $(\"one\").show();\n$(\"two\").hide(); });", @generator.to_s
end
end
-
diff --git a/actionpack/test/template/url_helper_test.rb b/actionpack/test/template/url_helper_test.rb
index c0e6826ec5..b498ec8429 100644
--- a/actionpack/test/template/url_helper_test.rb
+++ b/actionpack/test/template/url_helper_test.rb
@@ -174,81 +174,58 @@ class UrlHelperTest < ActionView::TestCase
link_to("Hello", "http://www.example.com", :confirm => "Are you sure?")
)
assert_dom_equal(
- "<a href=\"http://www.example.com\" data-confirm=\"You can\'t possibly be sure, can you?\">Hello</a>",
+ "<a href=\"http://www.example.com\" data-confirm=\"You can't possibly be sure, can you?\">Hello</a>",
link_to("Hello", "http://www.example.com", :confirm => "You can't possibly be sure, can you?")
)
assert_dom_equal(
- "<a href=\"http://www.example.com\" data-confirm=\"You can\'t possibly be sure,\n can you?\">Hello</a>",
+ "<a href=\"http://www.example.com\" data-confirm=\"You can't possibly be sure,\n can you?\">Hello</a>",
link_to("Hello", "http://www.example.com", :confirm => "You can't possibly be sure,\n can you?")
)
end
- def test_link_tag_with_popup
+ def test_link_to_with_remote
assert_dom_equal(
- "<a href=\"http://www.example.com\" data-popup=\"true\">Hello</a>",
- link_to("Hello", "http://www.example.com", :popup => true)
- )
- assert_dom_equal(
- "<a href=\"http://www.example.com\" data-popup=\"true\">Hello</a>",
- link_to("Hello", "http://www.example.com", :popup => 'true')
- )
- assert_dom_equal(
- "<a href=\"http://www.example.com\" data-popup=\"{title: 'window_name', options: 'width=300,height=300'}\">Hello</a>",
- link_to("Hello", "http://www.example.com", :popup => ['window_name', 'width=300,height=300'])
- )
- end
-
- def test_link_tag_with_popup_and_javascript_confirm
- assert_dom_equal(
- "<a href=\"http://www.example.com\" data-confirm=\"Fo\' sho\'?\" data-popup=\"true\">Hello</a>",
- link_to("Hello", "http://www.example.com", { :popup => true, :confirm => "Fo' sho'?" })
- )
- assert_dom_equal(
- "<a href=\"http://www.example.com\" data-confirm=\"Are you serious?\" data-popup=\"{title: 'window_name', options: 'width=300,height=300'}\">Hello</a>",
- link_to("Hello", "http://www.example.com", { :popup => ['window_name', 'width=300,height=300'], :confirm => "Are you serious?" })
+ "<a href=\"http://www.example.com\" data-remote=\"true\">Hello</a>",
+ link_to("Hello", "http://www.example.com", :remote => true)
)
end
def test_link_tag_using_post_javascript
assert_dom_equal(
- "<a href='http://www.example.com' data-url='http://www.example.com' data-method=\"post\">Hello</a>",
+ "<a href='http://www.example.com' data-method=\"post\" rel=\"nofollow\">Hello</a>",
link_to("Hello", "http://www.example.com", :method => :post)
)
end
def test_link_tag_using_delete_javascript
assert_dom_equal(
- "<a href='http://www.example.com' data-url='http://www.example.com' rel=\"nofollow\" data-method=\"delete\">Destroy</a>",
+ "<a href='http://www.example.com' rel=\"nofollow\" data-method=\"delete\">Destroy</a>",
link_to("Destroy", "http://www.example.com", :method => :delete)
)
end
def test_link_tag_using_delete_javascript_and_href
assert_dom_equal(
- "<a href='\#' data-url='http://www.example.com' rel=\"nofollow\" data-method=\"delete\">Destroy</a>",
+ "<a href='\#' rel=\"nofollow\" data-method=\"delete\">Destroy</a>",
link_to("Destroy", "http://www.example.com", :method => :delete, :href => '#')
)
end
def test_link_tag_using_post_javascript_and_confirm
assert_dom_equal(
- "<a href=\"http://www.example.com\" data-url='http://www.example.com' data-method=\"post\" data-confirm=\"Are you serious?\">Hello</a>",
+ "<a href=\"http://www.example.com\" data-method=\"post\" rel=\"nofollow\" data-confirm=\"Are you serious?\">Hello</a>",
link_to("Hello", "http://www.example.com", :method => :post, :confirm => "Are you serious?")
)
end
def test_link_tag_using_delete_javascript_and_href_and_confirm
assert_dom_equal(
- "<a href=\"#\" data-url='http://www.example.com' rel=\"nofollow\" data-method=\"delete\" data-confirm=\"Are you serious?\">Destroy</a>",
+ "<a href='\#' rel=\"nofollow\" data-confirm=\"Are you serious?\" data-method=\"delete\">Destroy</a>",
link_to("Destroy", "http://www.example.com", :method => :delete, :href => '#', :confirm => "Are you serious?"),
"When specifying url, form should be generated with it, but not this.href"
)
end
- def test_link_tag_using_post_javascript_and_popup
- assert_raise(ActionView::ActionViewError) { link_to("Hello", "http://www.example.com", :popup => true, :method => :post, :confirm => "Are you serious?") }
- end
-
def test_link_tag_using_block_in_erb
__in_erb_template = ''