mirror of
https://github.com/github/rails.git
synced 2026-04-26 03:00:59 -04:00
Merge branch 'master' of github.com:rails/rails
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
*Rails 3.0.0 [Edge] (pending)*
|
||||
|
||||
* New helpers #favicon_link_tag and #apple_touch_icon_link_tag [fxn]
|
||||
|
||||
* Added all the new HTML5 form types as individual form tag methods (search, url, number, etc) #3646 [Stephen Celis]
|
||||
|
||||
* Changed the object used in routing constraints to be an instance of
|
||||
|
||||
@@ -38,22 +38,22 @@ module ActionController #:nodoc:
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
@@page_cache_directory = defined?(Rails.public_path) ? Rails.public_path : ""
|
||||
##
|
||||
# :singleton-method:
|
||||
# The cache directory should be the document root for the web server and is set using <tt>Base.page_cache_directory = "/document/root"</tt>.
|
||||
# For Rails, this directory has already been set to Rails.public_path (which is usually set to <tt>RAILS_ROOT + "/public"</tt>). Changing
|
||||
# this setting can be useful to avoid naming conflicts with files in <tt>public/</tt>, but doing so will likely require configuring your
|
||||
# web server to look in the new location for cached files.
|
||||
@@page_cache_directory = ''
|
||||
cattr_accessor :page_cache_directory
|
||||
|
||||
@@page_cache_extension = '.html'
|
||||
##
|
||||
# :singleton-method:
|
||||
# Most Rails requests do not have an extension, such as <tt>/weblog/new</tt>. In these cases, the page caching mechanism will add one in
|
||||
# order to make it easy for the cached files to be picked up properly by the web server. By default, this cache extension is <tt>.html</tt>.
|
||||
# If you want something else, like <tt>.php</tt> or <tt>.shtml</tt>, just set Base.page_cache_extension. In cases where a request already has an
|
||||
# extension, such as <tt>.xml</tt> or <tt>.rss</tt>, page caching will not add an extension. This allows it to work well with RESTful apps.
|
||||
@@page_cache_extension = '.html'
|
||||
cattr_accessor :page_cache_extension
|
||||
end
|
||||
|
||||
|
||||
@@ -32,8 +32,6 @@ module ActionController
|
||||
def rescue_action(env)
|
||||
raise env["action_dispatch.rescue.exception"]
|
||||
end
|
||||
|
||||
self.page_cache_directory = defined?(Rails.public_path) ? Rails.public_path : ""
|
||||
end
|
||||
|
||||
# For old tests
|
||||
|
||||
@@ -44,6 +44,12 @@ module ActionController
|
||||
ActiveSupport.on_load(:action_controller) { self.logger ||= Rails.logger }
|
||||
end
|
||||
|
||||
initializer "action_controller.page_cache_directory" do
|
||||
ActiveSupport.on_load(:action_controller) do
|
||||
self.page_cache_directory = Rails.public_path
|
||||
end
|
||||
end
|
||||
|
||||
initializer "action_controller.set_configs" do |app|
|
||||
paths = app.config.paths
|
||||
ac = app.config.action_controller
|
||||
|
||||
@@ -501,6 +501,50 @@ module ActionView
|
||||
end
|
||||
end
|
||||
|
||||
# Returns a link tag for a favicon.
|
||||
#
|
||||
# <%= favicon_link_tag %>
|
||||
#
|
||||
# generates
|
||||
#
|
||||
# <link href="/favicon.ico?4649789979" rel="shortcut icon" type="image/vnd.microsoft.icon" />
|
||||
#
|
||||
# You can specify a different icon file in the first argument:
|
||||
#
|
||||
# <%= favicon_link_tag 'favicon.ico' %>
|
||||
#
|
||||
# That's passed to +image_path+ as is, so the example above would render
|
||||
#
|
||||
# <link href="/images/favicon.ico?4649789979" rel="shortcut icon" type="image/vnd.microsoft.icon" />
|
||||
#
|
||||
# The helper accepts an additional options hash where you can override "rel" and "type".
|
||||
def favicon_link_tag(source='/favicon.ico', options={})
|
||||
tag('link', {
|
||||
:rel => 'shortcut icon',
|
||||
:type => 'image/vnd.microsoft.icon',
|
||||
:href => image_path(source)
|
||||
}.merge(options.symbolize_keys))
|
||||
end
|
||||
|
||||
# Returns a link tag for an icon targetted at iPod Touch, iPhone, and iPad.
|
||||
#
|
||||
# <%= apple_touch_icon_link_tag %>
|
||||
#
|
||||
# generates
|
||||
#
|
||||
# <link href="/apple-touch-icon.png?4233872383" rel="apple-touch-icon" />
|
||||
#
|
||||
# You can specify a different icon file:
|
||||
#
|
||||
# <%= apple_touch_icon_link_tag "my_site.png" %>
|
||||
#
|
||||
# That's passed to +image_path+ as is, so the example above would render
|
||||
#
|
||||
# <link href="/images/my_site.png?4233872383" rel="apple-touch-icon" />
|
||||
def apple_touch_icon_link_tag(source='/apple-touch-icon.png')
|
||||
tag('link', :rel => 'apple-touch-icon', :href => image_path(source))
|
||||
end
|
||||
|
||||
# Computes the path to an image asset in the public images directory.
|
||||
# Full paths from the document root will be passed through.
|
||||
# Used internally by +image_tag+ to build the image path.
|
||||
|
||||
@@ -157,6 +157,18 @@ class AssetTagHelperTest < ActionView::TestCase
|
||||
%(image_tag("mouse.png", :mouseover => image_path("mouse_over.png"))) => %(<img alt="Mouse" onmouseover="this.src='/images/mouse_over.png'" onmouseout="this.src='/images/mouse.png'" src="/images/mouse.png" />)
|
||||
}
|
||||
|
||||
FaviconLinkToTag = {
|
||||
%(favicon_link_tag) => %(<link href="/favicon.ico" rel="shortcut icon" type="image/vnd.microsoft.icon" />),
|
||||
%(favicon_link_tag 'favicon.ico') => %(<link href="/images/favicon.ico" rel="shortcut icon" type="image/vnd.microsoft.icon" />),
|
||||
%(favicon_link_tag 'favicon.ico', :rel => 'foo') => %(<link href="/images/favicon.ico" rel="foo" type="image/vnd.microsoft.icon" />),
|
||||
%(favicon_link_tag 'favicon.ico', :rel => 'foo', :type => 'bar') => %(<link href="/images/favicon.ico" rel="foo" type="bar" />)
|
||||
}
|
||||
|
||||
AppleTouchIconLinkToTag = {
|
||||
%(apple_touch_icon_link_tag) => %(<link href="/apple-touch-icon.png" rel="apple-touch-icon" />),
|
||||
%(apple_touch_icon_link_tag 'my_site.png') => %(<link href="/images/my_site.png" rel="apple-touch-icon" />)
|
||||
}
|
||||
|
||||
VideoPathToTag = {
|
||||
%(video_path("xml")) => %(/videos/xml),
|
||||
%(video_path("xml.ogg")) => %(/videos/xml.ogg),
|
||||
@@ -331,6 +343,14 @@ class AssetTagHelperTest < ActionView::TestCase
|
||||
ImageLinkToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) }
|
||||
end
|
||||
|
||||
def test_favicon_link_tag
|
||||
FaviconLinkToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) }
|
||||
end
|
||||
|
||||
def test_apple_touch_link_tag
|
||||
AppleTouchIconLinkToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) }
|
||||
end
|
||||
|
||||
def test_image_tag_windows_behaviour
|
||||
old_asset_id, ENV["RAILS_ASSET_ID"] = ENV["RAILS_ASSET_ID"], "1"
|
||||
# This simulates the behaviour of File#exist? on windows when testing a file ending in "."
|
||||
|
||||
@@ -147,7 +147,7 @@ module ActiveRecord
|
||||
# has_many :books
|
||||
# end
|
||||
#
|
||||
# Author.find(:first).books.transaction do
|
||||
# Author.first.books.transaction do
|
||||
# # same effect as calling Book.transaction
|
||||
# end
|
||||
def transaction(*args)
|
||||
|
||||
@@ -56,15 +56,15 @@ module ActiveRecord #:nodoc:
|
||||
#
|
||||
# class User < ActiveRecord::Base
|
||||
# def self.authenticate_unsafely(user_name, password)
|
||||
# find(:first, :conditions => "user_name = '#{user_name}' AND password = '#{password}'")
|
||||
# where("user_name = '#{user_name}' AND password = '#{password}'").first
|
||||
# end
|
||||
#
|
||||
# def self.authenticate_safely(user_name, password)
|
||||
# find(:first, :conditions => [ "user_name = ? AND password = ?", user_name, password ])
|
||||
# where("user_name = ? AND password = ?", user_name, password).first
|
||||
# end
|
||||
#
|
||||
# def self.authenticate_safely_simply(user_name, password)
|
||||
# find(:first, :conditions => { :user_name => user_name, :password => password })
|
||||
# where(:user_name => user_name, :password => password).first
|
||||
# end
|
||||
# end
|
||||
#
|
||||
@@ -77,30 +77,30 @@ module ActiveRecord #:nodoc:
|
||||
# question mark is supposed to represent. In those cases, you can resort to named bind variables instead. That's done by replacing
|
||||
# the question marks with symbols and supplying a hash with values for the matching symbol keys:
|
||||
#
|
||||
# Company.find(:first, :conditions => [
|
||||
# Company.where(
|
||||
# "id = :id AND name = :name AND division = :division AND created_at > :accounting_date",
|
||||
# { :id => 3, :name => "37signals", :division => "First", :accounting_date => '2005-01-01' }
|
||||
# ])
|
||||
# ).first
|
||||
#
|
||||
# Similarly, a simple hash without a statement will generate conditions based on equality with the SQL AND
|
||||
# operator. For instance:
|
||||
#
|
||||
# Student.find(:all, :conditions => { :first_name => "Harvey", :status => 1 })
|
||||
# Student.find(:all, :conditions => params[:student])
|
||||
# Student.where(:first_name => "Harvey", :status => 1)
|
||||
# Student.where(params[:student])
|
||||
#
|
||||
# A range may be used in the hash to use the SQL BETWEEN operator:
|
||||
#
|
||||
# Student.find(:all, :conditions => { :grade => 9..12 })
|
||||
# Student.where(:grade => 9..12)
|
||||
#
|
||||
# An array may be used in the hash to use the SQL IN operator:
|
||||
#
|
||||
# Student.find(:all, :conditions => { :grade => [9,11,12] })
|
||||
# Student.where(:grade => [9,11,12])
|
||||
#
|
||||
# When joining tables, nested hashes or keys written in the form 'table_name.column_name' can be used to qualify the table name of a
|
||||
# particular condition. For instance:
|
||||
#
|
||||
# Student.find(:all, :conditions => { :schools => { :type => 'public' }}, :joins => :schools)
|
||||
# Student.find(:all, :conditions => { 'schools.type' => 'public' }, :joins => :schools)
|
||||
# Student.joins(:schools).where(:schools => { :type => 'public' })
|
||||
# Student.joins(:schools).where('schools.type' => 'public' )
|
||||
#
|
||||
# == Overwriting default accessors
|
||||
#
|
||||
@@ -153,18 +153,18 @@ module ActiveRecord #:nodoc:
|
||||
# Dynamic attribute-based finders are a cleaner way of getting (and/or creating) objects by simple queries without turning to SQL. They work by
|
||||
# appending the name of an attribute to <tt>find_by_</tt>, <tt>find_last_by_</tt>, or <tt>find_all_by_</tt>, so you get finders like <tt>Person.find_by_user_name</tt>,
|
||||
# <tt>Person.find_all_by_last_name</tt>, and <tt>Payment.find_by_transaction_id</tt>. So instead of writing
|
||||
# <tt>Person.find(:first, :conditions => ["user_name = ?", user_name])</tt>, you just do <tt>Person.find_by_user_name(user_name)</tt>.
|
||||
# And instead of writing <tt>Person.find(:all, :conditions => ["last_name = ?", last_name])</tt>, you just do <tt>Person.find_all_by_last_name(last_name)</tt>.
|
||||
# <tt>Person.where(:user_name => user_name).first</tt>, you just do <tt>Person.find_by_user_name(user_name)</tt>.
|
||||
# And instead of writing <tt>Person.where(:last_name => last_name).all</tt>, you just do <tt>Person.find_all_by_last_name(last_name)</tt>.
|
||||
#
|
||||
# It's also possible to use multiple attributes in the same find by separating them with "_and_", so you get finders like
|
||||
# <tt>Person.find_by_user_name_and_password</tt> or even <tt>Payment.find_by_purchaser_and_state_and_country</tt>. So instead of writing
|
||||
# <tt>Person.find(:first, :conditions => ["user_name = ? AND password = ?", user_name, password])</tt>, you just do
|
||||
# <tt>Person.where(:user_name => user_name, :password => password).first</tt>, you just do
|
||||
# <tt>Person.find_by_user_name_and_password(user_name, password)</tt>.
|
||||
#
|
||||
# It's even possible to use all the additional parameters to find. For example, the full interface for <tt>Payment.find_all_by_amount</tt>
|
||||
# is actually <tt>Payment.find_all_by_amount(amount, options)</tt>. And the full interface to <tt>Person.find_by_user_name</tt> is
|
||||
# actually <tt>Person.find_by_user_name(user_name, options)</tt>. So you could call <tt>Payment.find_all_by_amount(50, :order => "created_on")</tt>.
|
||||
# Also you may call <tt>Payment.find_last_by_amount(amount, options)</tt> returning the last record matching that amount and options.
|
||||
# It's even possible to call these dynamic finder methods on relations and named scopes. For example :
|
||||
#
|
||||
# Payment.order("created_on").find_all_by_amount(50)
|
||||
# Payment.pending.find_last_by_amount(100)
|
||||
#
|
||||
# The same dynamic finder style can be used to create the object if it doesn't already exist. This dynamic finder is called with
|
||||
# <tt>find_or_create_by_</tt> and will return the object if it already exists and otherwise creates it, then returns it. Protected attributes won't be set unless they are given in a block. For example:
|
||||
@@ -224,7 +224,7 @@ module ActiveRecord #:nodoc:
|
||||
# class PriorityClient < Client; end
|
||||
#
|
||||
# When you do <tt>Firm.create(:name => "37signals")</tt>, this record will be saved in the companies table with type = "Firm". You can then
|
||||
# fetch this row again using <tt>Company.find(:first, "name = '37signals'")</tt> and it will return a Firm object.
|
||||
# fetch this row again using <tt>Company.where(:name => '37signals').first</tt> and it will return a Firm object.
|
||||
#
|
||||
# If you don't have a type column defined in your table, single-table inheritance won't be triggered. In that case, it'll work just
|
||||
# like normal subclasses with no special magic for differentiating between them or reloading the right type with find.
|
||||
@@ -1117,10 +1117,6 @@ module ActiveRecord #:nodoc:
|
||||
# It's even possible to use all the additional parameters to +find+. For example, the full interface for +find_all_by_amount+
|
||||
# is actually <tt>find_all_by_amount(amount, options)</tt>.
|
||||
#
|
||||
# Also enables dynamic scopes like scoped_by_user_name(user_name) and scoped_by_user_name_and_password(user_name, password) that
|
||||
# are turned into scoped(:conditions => ["user_name = ?", user_name]) and scoped(:conditions => ["user_name = ? AND password = ?", user_name, password])
|
||||
# respectively.
|
||||
#
|
||||
# Each dynamic finder, scope or initializer/creator is also defined in the class after it is first invoked, so that future
|
||||
# attempts to use it do not run through method_missing.
|
||||
def method_missing(method_id, *arguments, &block)
|
||||
@@ -1196,12 +1192,12 @@ module ActiveRecord #:nodoc:
|
||||
|
||||
protected
|
||||
# Scope parameters to method calls within the block. Takes a hash of method_name => parameters hash.
|
||||
# method_name may be <tt>:find</tt> or <tt>:create</tt>. <tt>:find</tt> parameters may include the <tt>:conditions</tt>, <tt>:joins</tt>,
|
||||
# <tt>:include</tt>, <tt>:offset</tt>, <tt>:limit</tt>, and <tt>:readonly</tt> options. <tt>:create</tt> parameters are an attributes hash.
|
||||
# method_name may be <tt>:find</tt> or <tt>:create</tt>. <tt>:find</tt> parameter is <tt>Relation</tt> while
|
||||
# <tt>:create</tt> parameters are an attributes hash.
|
||||
#
|
||||
# class Article < ActiveRecord::Base
|
||||
# def self.create_with_scope
|
||||
# with_scope(:find => { :conditions => "blog_id = 1" }, :create => { :blog_id => 1 }) do
|
||||
# with_scope(:find => where(:blog_id => 1), :create => { :blog_id => 1 }) do
|
||||
# find(1) # => SELECT * from articles WHERE blog_id = 1 AND id = 1
|
||||
# a = create(1)
|
||||
# a.blog_id # => 1
|
||||
@@ -1210,20 +1206,20 @@ module ActiveRecord #:nodoc:
|
||||
# end
|
||||
#
|
||||
# In nested scopings, all previous parameters are overwritten by the innermost rule, with the exception of
|
||||
# <tt>:conditions</tt>, <tt>:include</tt>, and <tt>:joins</tt> options in <tt>:find</tt>, which are merged.
|
||||
# <tt>where</tt>, <tt>includes</tt>, and <tt>joins</tt> operations in <tt>Relation</tt>, which are merged.
|
||||
#
|
||||
# <tt>:joins</tt> options are uniqued so multiple scopes can join in the same table without table aliasing
|
||||
# <tt>joins</tt> operations are uniqued so multiple scopes can join in the same table without table aliasing
|
||||
# problems. If you need to join multiple tables, but still want one of the tables to be uniqued, use the
|
||||
# array of strings format for your joins.
|
||||
#
|
||||
# class Article < ActiveRecord::Base
|
||||
# def self.find_with_scope
|
||||
# with_scope(:find => { :conditions => "blog_id = 1", :limit => 1 }, :create => { :blog_id => 1 }) do
|
||||
# with_scope(:find => { :limit => 10 }) do
|
||||
# find(:all) # => SELECT * from articles WHERE blog_id = 1 LIMIT 10
|
||||
# with_scope(:find => where(:blog_id => 1).limit(1), :create => { :blog_id => 1 }) do
|
||||
# with_scope(:find => limit(10)) do
|
||||
# all # => SELECT * from articles WHERE blog_id = 1 LIMIT 10
|
||||
# end
|
||||
# with_scope(:find => { :conditions => "author_id = 3" }) do
|
||||
# find(:all) # => SELECT * from articles WHERE blog_id = 1 AND author_id = 3 LIMIT 1
|
||||
# with_scope(:find => where(:author_id => 3)) do
|
||||
# all # => SELECT * from articles WHERE blog_id = 1 AND author_id = 3 LIMIT 1
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
@@ -1233,9 +1229,9 @@ module ActiveRecord #:nodoc:
|
||||
#
|
||||
# class Article < ActiveRecord::Base
|
||||
# def self.find_with_exclusive_scope
|
||||
# with_scope(:find => { :conditions => "blog_id = 1", :limit => 1 }) do
|
||||
# with_exclusive_scope(:find => { :limit => 10 })
|
||||
# find(:all) # => SELECT * from articles LIMIT 10
|
||||
# with_scope(:find => where(:blog_id => 1).limit(1)) do
|
||||
# with_exclusive_scope(:find => limit(10))
|
||||
# all # => SELECT * from articles LIMIT 10
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
|
||||
@@ -64,7 +64,7 @@ module ActiveSupport
|
||||
@data.get(key, raw?(options))
|
||||
end
|
||||
rescue MemCache::MemCacheError => e
|
||||
logger.error("MemCacheError (#{e}): #{e.message}")
|
||||
logger.error("MemCacheError (#{e}): #{e.message}") if logger
|
||||
nil
|
||||
end
|
||||
|
||||
@@ -85,7 +85,7 @@ module ActiveSupport
|
||||
response == Response::STORED
|
||||
end
|
||||
rescue MemCache::MemCacheError => e
|
||||
logger.error("MemCacheError (#{e}): #{e.message}")
|
||||
logger.error("MemCacheError (#{e}): #{e.message}") if logger
|
||||
false
|
||||
end
|
||||
|
||||
@@ -95,7 +95,7 @@ module ActiveSupport
|
||||
response == Response::DELETED
|
||||
end
|
||||
rescue MemCache::MemCacheError => e
|
||||
logger.error("MemCacheError (#{e}): #{e.message}")
|
||||
logger.error("MemCacheError (#{e}): #{e.message}") if logger
|
||||
false
|
||||
end
|
||||
|
||||
|
||||
@@ -79,6 +79,10 @@ module Rails
|
||||
@_env ||= ActiveSupport::StringInquirer.new(ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development")
|
||||
end
|
||||
|
||||
def env=(environment)
|
||||
@_env = ActiveSupport::StringInquirer.new(environment)
|
||||
end
|
||||
|
||||
def cache
|
||||
RAILS_CACHE
|
||||
end
|
||||
@@ -88,11 +92,12 @@ module Rails
|
||||
end
|
||||
|
||||
def public_path
|
||||
@@public_path ||= self.root ? File.join(self.root, "public") : "public"
|
||||
application && application.paths.public.to_a.first
|
||||
end
|
||||
|
||||
def public_path=(path)
|
||||
@@public_path = path
|
||||
ActiveSupport::Deprecation.warn "Setting Rails.public_path= is deprecated. " <<
|
||||
"Please set paths.public = in config/application.rb instead.", caller
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -137,7 +137,7 @@ module Rails
|
||||
|
||||
def default_middleware_stack
|
||||
ActionDispatch::MiddlewareStack.new.tap do |middleware|
|
||||
middleware.use('::ActionDispatch::Static', lambda { Rails.public_path }, :if => lambda { serve_static_assets })
|
||||
middleware.use('::ActionDispatch::Static', lambda { paths.public.to_a.first }, :if => lambda { serve_static_assets })
|
||||
middleware.use('::Rack::Lock', :if => lambda { !allow_concurrency })
|
||||
middleware.use('::Rack::Runtime')
|
||||
middleware.use('::Rails::Rack::Logger')
|
||||
|
||||
@@ -1,15 +1,8 @@
|
||||
document.observe("dom:loaded", function() {
|
||||
var authToken = $$('meta[name=csrf-token]').first().readAttribute('content'),
|
||||
authParam = $$('meta[name=csrf-param]').first().readAttribute('content'),
|
||||
formTemplate = '<form method="#{method}" action="#{action}">\
|
||||
#{realmethod}<input name="#{param}" value="#{token}" type="hidden">\
|
||||
</form>',
|
||||
realmethodTemplate = '<input name="_method" value="#{method}" type="hidden">';
|
||||
|
||||
function handleRemote(element) {
|
||||
var method, url, params;
|
||||
|
||||
if (element.tagName.toLowerCase() == 'form') {
|
||||
if (element.tagName.toLowerCase() === 'form') {
|
||||
method = element.readAttribute('method') || 'post';
|
||||
url = element.readAttribute('action');
|
||||
params = element.serialize(true);
|
||||
@@ -39,65 +32,81 @@ document.observe("dom:loaded", function() {
|
||||
element.fire("ajax:after");
|
||||
}
|
||||
|
||||
function handleMethod(element) {
|
||||
var method, url, token_name, token;
|
||||
|
||||
method = element.readAttribute('data-method');
|
||||
url = element.readAttribute('href');
|
||||
csrf_param = $$('meta[name=csrf-param]').first();
|
||||
csrf_token = $$('meta[name=csrf-token]').first();
|
||||
|
||||
var form = new Element('form', { method: "POST", action: url, style: "display: none;" });
|
||||
element.parentNode.appendChild(form);
|
||||
|
||||
if (method != 'post') {
|
||||
var field = new Element('input', { type: 'hidden', name: '_method', value: method });
|
||||
form.appendChild(field);
|
||||
}
|
||||
|
||||
if (csrf_param) {
|
||||
var param = csrf_param.readAttribute('content');
|
||||
var token = csrf_token.readAttribute('content');
|
||||
var field = new Element('input', { type: 'hidden', name: param, value: token });
|
||||
form.appendChild(field);
|
||||
}
|
||||
|
||||
form.submit();
|
||||
}
|
||||
|
||||
$(document.body).observe("click", function(event) {
|
||||
var message = event.element().readAttribute('data-confirm');
|
||||
var message = event.findElement().readAttribute('data-confirm');
|
||||
if (message && !confirm(message)) {
|
||||
event.stop();
|
||||
return false;
|
||||
}
|
||||
|
||||
var element = event.findElement("a[data-remote=true]");
|
||||
var element = event.findElement("a[data-remote]");
|
||||
if (element) {
|
||||
handleRemote(element);
|
||||
event.stop();
|
||||
return true;
|
||||
}
|
||||
|
||||
var element = event.findElement("a[data-method]");
|
||||
if (element && element.readAttribute('data-remote') != 'true') {
|
||||
var method = element.readAttribute('data-method'),
|
||||
piggyback = method.toLowerCase() != 'post',
|
||||
formHTML = formTemplate.interpolate({
|
||||
method: 'POST',
|
||||
realmethod: piggyback ? realmethodTemplate.interpolate({ method: method }) : '',
|
||||
action: element.readAttribute('href'),
|
||||
token: authToken,
|
||||
param: authParam
|
||||
});
|
||||
|
||||
var form = new Element('div').update(formHTML).down().hide();
|
||||
this.insert({ bottom: form });
|
||||
|
||||
form.submit();
|
||||
if (element) {
|
||||
handleMethod(element);
|
||||
event.stop();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
// TODO: I don't think submit bubbles in IE
|
||||
$(document.body).observe("submit", function(event) {
|
||||
var message = event.element().readAttribute('data-confirm');
|
||||
var element = event.findElement(),
|
||||
message = element.readAttribute('data-confirm');
|
||||
if (message && !confirm(message)) {
|
||||
event.stop();
|
||||
return false;
|
||||
}
|
||||
|
||||
var inputs = event.element().select("input[type=submit][data-disable-with]");
|
||||
var inputs = element.select("input[type=submit][data-disable-with]");
|
||||
inputs.each(function(input) {
|
||||
input.disabled = true;
|
||||
input.writeAttribute('data-original-value', input.value);
|
||||
input.value = input.readAttribute('data-disable-with');
|
||||
});
|
||||
|
||||
var element = event.findElement("form[data-remote=true]");
|
||||
var element = event.findElement("form[data-remote]");
|
||||
if (element) {
|
||||
handleRemote(element);
|
||||
event.stop();
|
||||
}
|
||||
});
|
||||
|
||||
$(document.body).observe("ajax:complete", function(event) {
|
||||
var element = event.element();
|
||||
$(document.body).observe("ajax:after", function(event) {
|
||||
var element = event.findElement();
|
||||
|
||||
if (element.tagName.toLowerCase() == 'form') {
|
||||
if (element.tagName.toLowerCase() === 'form') {
|
||||
var inputs = element.select("input[type=submit][disabled=true][data-disable-with]");
|
||||
inputs.each(function(input) {
|
||||
input.value = input.readAttribute('data-original-value');
|
||||
@@ -106,4 +115,4 @@ document.observe("dom:loaded", function() {
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -184,6 +184,15 @@ module ApplicationTests
|
||||
end
|
||||
end
|
||||
|
||||
test "config.paths.public sets Rails.public_path" do
|
||||
add_to_config <<-RUBY
|
||||
config.paths.public = "somewhere"
|
||||
RUBY
|
||||
|
||||
require "#{app_path}/config/application"
|
||||
assert_equal File.join(app_path, "somewhere"), Rails.public_path
|
||||
end
|
||||
|
||||
def make_basic_app
|
||||
require "rails"
|
||||
require "action_controller/railtie"
|
||||
|
||||
@@ -125,5 +125,16 @@ module RailtiesTest
|
||||
require "#{app_path}/config/environment"
|
||||
assert $ran_block
|
||||
end
|
||||
|
||||
test "we can change our environment if we want to" do
|
||||
begin
|
||||
original_env = Rails.env
|
||||
Rails.env = 'foo'
|
||||
assert_equal('foo', Rails.env)
|
||||
ensure
|
||||
Rails.env = original_env
|
||||
assert_equal(original_env, Rails.env)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user