mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
-j parameter added to rails new command.
Now you can start your apps with jquery with rails new myapp -j jquery, the default is still prototype [#5613 state:committed] Signed-off-by: Santiago Pastorino <santiago@wyeworks.com>
This commit is contained in:
parent
cecccf1156
commit
708e09448b
8 changed files with 6309 additions and 57 deletions
|
@ -45,8 +45,9 @@ task :generate_guides do
|
|||
ruby "guides/rails_guides.rb"
|
||||
end
|
||||
|
||||
task :update_prototype_ujs do
|
||||
system "curl http://github.com/rails/prototype-ujs/raw/master/src/rails.js > lib/rails/generators/rails/app/templates/public/javascripts/rails.js"
|
||||
task :update_ujs do
|
||||
system "curl http://github.com/rails/prototype-ujs/raw/master/src/rails.js > lib/rails/generators/rails/app/templates/public/javascripts/prototype_ujs.js"
|
||||
system "curl http://github.com/rails/jquery-ujs/raw/master/src/rails.js > lib/rails/generators/rails/app/templates/public/javascripts/jquery_ujs.js"
|
||||
end
|
||||
|
||||
# Validate guides -------------------------------------------------------------------------
|
||||
|
|
|
@ -108,14 +108,22 @@ module Rails
|
|||
end
|
||||
|
||||
def javascripts
|
||||
unless options[:skip_prototype]
|
||||
directory "public/javascripts"
|
||||
else
|
||||
empty_directory_with_gitkeep "public/javascripts"
|
||||
create_file "public/javascripts/application.js"
|
||||
empty_directory "public/javascripts"
|
||||
|
||||
unless options[:skip_javascript]
|
||||
copy_file "public/javascripts/#{@options[:javascript]}.js"
|
||||
copy_file "public/javascripts/#{@options[:javascript]}_ujs.js", "public/javascripts/rails.js"
|
||||
|
||||
if options[:prototype]
|
||||
copy_file "public/javascripts/controls.js"
|
||||
copy_file "public/javascripts/dragdrop.js"
|
||||
copy_file "public/javascripts/effects.js"
|
||||
end
|
||||
end
|
||||
|
||||
copy_file "public/javascripts/application.js"
|
||||
end
|
||||
|
||||
def script
|
||||
directory "script" do |content|
|
||||
"#{shebang}\n" + content
|
||||
|
@ -152,6 +160,7 @@ module Rails
|
|||
|
||||
class AppGenerator < Base
|
||||
DATABASES = %w( mysql oracle postgresql sqlite3 frontbase ibm_db )
|
||||
JAVASCRIPTS = %w( prototype jquery )
|
||||
|
||||
attr_accessor :rails_template
|
||||
add_shebang_option!
|
||||
|
@ -161,6 +170,9 @@ module Rails
|
|||
class_option :database, :type => :string, :aliases => "-d", :default => "sqlite3",
|
||||
:desc => "Preconfigure for selected database (options: #{DATABASES.join('/')})"
|
||||
|
||||
class_option :javascript, :type => :string, :aliases => "-j", :default => "prototype",
|
||||
:desc => "Preconfigure for selected javascript library (options: #{JAVASCRIPTS.join('/')})"
|
||||
|
||||
class_option :builder, :type => :string, :aliases => "-b",
|
||||
:desc => "Path to an application builder (can be a filesystem path or URL)"
|
||||
|
||||
|
@ -182,8 +194,8 @@ module Rails
|
|||
class_option :skip_test_unit, :type => :boolean, :aliases => "-T", :default => false,
|
||||
:desc => "Skip Test::Unit files"
|
||||
|
||||
class_option :skip_prototype, :type => :boolean, :aliases => "-J", :default => false,
|
||||
:desc => "Skip Prototype files"
|
||||
class_option :skip_javascript, :type => :boolean, :aliases => "-J", :default => false,
|
||||
:desc => "Skip javascript files"
|
||||
|
||||
class_option :skip_git, :type => :boolean, :aliases => "-G", :default => false,
|
||||
:desc => "Skip Git ignores and keeps"
|
||||
|
@ -205,6 +217,10 @@ module Rails
|
|||
if !options[:skip_active_record] && !DATABASES.include?(options[:database])
|
||||
raise Error, "Invalid value for --database option. Supported for preconfiguration are: #{DATABASES.join(", ")}."
|
||||
end
|
||||
|
||||
if !options[:skip_javascript] && !JAVASCRIPTS.include?(options[:javascript])
|
||||
raise Error, "Invalid value for --javascript option. Supported for preconfiguration are: #{JAVASCRIPTS.join(", ")}."
|
||||
end
|
||||
end
|
||||
|
||||
def create_root
|
||||
|
@ -269,7 +285,7 @@ module Rails
|
|||
build(:stylesheets)
|
||||
end
|
||||
|
||||
def create_prototype_files
|
||||
def create_javascript_files
|
||||
build(:javascripts)
|
||||
end
|
||||
|
||||
|
|
|
@ -40,8 +40,10 @@ module <%= app_const_base %>
|
|||
# config.i18n.default_locale = :de
|
||||
|
||||
# JavaScript files you want as :defaults (application.js is always included).
|
||||
<% if options[:skip_prototype] -%>
|
||||
<% if options[:skip_javascript] -%>
|
||||
config.action_view.javascript_expansions[:defaults] = %w()
|
||||
<% elsif options[:javascript] == 'jquery' -%>
|
||||
config.action_view.javascript_expansions[:defaults] = %w(jquery rails)
|
||||
<% else -%>
|
||||
# config.action_view.javascript_expansions[:defaults] = %w(jquery rails)
|
||||
<% end -%>
|
||||
|
|
6078
railties/lib/rails/generators/rails/app/templates/public/javascripts/jquery.js
vendored
Normal file
6078
railties/lib/rails/generators/rails/app/templates/public/javascripts/jquery.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
132
railties/lib/rails/generators/rails/app/templates/public/javascripts/jquery_ujs.js
vendored
Normal file
132
railties/lib/rails/generators/rails/app/templates/public/javascripts/jquery_ujs.js
vendored
Normal file
|
@ -0,0 +1,132 @@
|
|||
jQuery(function ($) {
|
||||
var csrf_token = $('meta[name=csrf-token]').attr('content'),
|
||||
csrf_param = $('meta[name=csrf-param]').attr('content');
|
||||
|
||||
$.fn.extend({
|
||||
/**
|
||||
* Triggers a custom event on an element and returns the event result
|
||||
* this is used to get around not being able to ensure callbacks are placed
|
||||
* at the end of the chain.
|
||||
*
|
||||
* TODO: deprecate with jQuery 1.4.2 release, in favor of subscribing to our
|
||||
* own events and placing ourselves at the end of the chain.
|
||||
*/
|
||||
triggerAndReturn: function (name, data) {
|
||||
var event = new $.Event(name);
|
||||
this.trigger(event, data);
|
||||
|
||||
return event.result !== false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Handles execution of remote calls firing overridable events along the way
|
||||
*/
|
||||
callRemote: function () {
|
||||
var el = this,
|
||||
method = el.attr('method') || el.attr('data-method') || 'GET',
|
||||
url = el.attr('action') || el.attr('href'),
|
||||
dataType = el.attr('data-type') || 'script';
|
||||
|
||||
if (url === undefined) {
|
||||
throw "No URL specified for remote call (action or href must be present).";
|
||||
} else {
|
||||
if (el.triggerAndReturn('ajax:before')) {
|
||||
var data = el.is('form') ? el.serializeArray() : [];
|
||||
$.ajax({
|
||||
url: url,
|
||||
data: data,
|
||||
dataType: dataType,
|
||||
type: method.toUpperCase(),
|
||||
beforeSend: function (xhr) {
|
||||
el.trigger('ajax:loading', xhr);
|
||||
},
|
||||
success: function (data, status, xhr) {
|
||||
el.trigger('ajax:success', [data, status, xhr]);
|
||||
},
|
||||
complete: function (xhr) {
|
||||
el.trigger('ajax:complete', xhr);
|
||||
},
|
||||
error: function (xhr, status, error) {
|
||||
el.trigger('ajax:failure', [xhr, status, error]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
el.trigger('ajax:after');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* confirmation handler
|
||||
*/
|
||||
$('a[data-confirm],input[data-confirm]').live('click', function () {
|
||||
var el = $(this);
|
||||
if (el.triggerAndReturn('confirm')) {
|
||||
if (!confirm(el.attr('data-confirm'))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* remote handlers
|
||||
*/
|
||||
$('form[data-remote]').live('submit', function (e) {
|
||||
$(this).callRemote();
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
$('a[data-remote],input[data-remote]').live('click', function (e) {
|
||||
$(this).callRemote();
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
$('a[data-method]:not([data-remote])').live('click', function (e){
|
||||
var link = $(this),
|
||||
href = link.attr('href'),
|
||||
method = link.attr('data-method'),
|
||||
form = $('<form method="post" action="'+href+'"></form>'),
|
||||
metadata_input = '<input name="_method" value="'+method+'" type="hidden" />';
|
||||
|
||||
if (csrf_param != null && csrf_token != null) {
|
||||
metadata_input += '<input name="'+csrf_param+'" value="'+csrf_token+'" type="hidden" />';
|
||||
}
|
||||
|
||||
form.hide()
|
||||
.append(metadata_input)
|
||||
.appendTo('body');
|
||||
|
||||
e.preventDefault();
|
||||
form.submit();
|
||||
});
|
||||
|
||||
/**
|
||||
* disable-with handlers
|
||||
*/
|
||||
var disable_with_input_selector = 'input[data-disable-with]';
|
||||
var disable_with_form_remote_selector = 'form[data-remote]:has(' + disable_with_input_selector + ')';
|
||||
var disable_with_form_not_remote_selector = 'form:not([data-remote]):has(' + disable_with_input_selector + ')';
|
||||
|
||||
var disable_with_input_function = function () {
|
||||
$(this).find(disable_with_input_selector).each(function () {
|
||||
var input = $(this);
|
||||
input.data('enable-with', input.val())
|
||||
.attr('value', input.attr('data-disable-with'))
|
||||
.attr('disabled', 'disabled');
|
||||
});
|
||||
};
|
||||
|
||||
$(disable_with_form_remote_selector).live('ajax:before', disable_with_input_function);
|
||||
$(disable_with_form_not_remote_selector).live('submit', disable_with_input_function);
|
||||
|
||||
$(disable_with_form_remote_selector).live('ajax:complete', function () {
|
||||
$(this).find(disable_with_input_selector).each(function () {
|
||||
var input = $(this);
|
||||
input.removeAttr('disabled')
|
||||
.val(input.data('enable-with'));
|
||||
});
|
||||
});
|
||||
|
||||
});
|
|
@ -14,33 +14,33 @@
|
|||
}
|
||||
|
||||
function isForm(element) {
|
||||
return Object.isElement(element) && element.nodeName.toUpperCase() == 'FORM'
|
||||
return Object.isElement(element) && element.nodeName.toUpperCase() == 'FORM';
|
||||
}
|
||||
|
||||
function isInput(element) {
|
||||
if (Object.isElement(element)) {
|
||||
var name = element.nodeName.toUpperCase()
|
||||
return name == 'INPUT' || name == 'SELECT' || name == 'TEXTAREA'
|
||||
var name = element.nodeName.toUpperCase();
|
||||
return name == 'INPUT' || name == 'SELECT' || name == 'TEXTAREA';
|
||||
}
|
||||
else return false
|
||||
else return false;
|
||||
}
|
||||
|
||||
var submitBubbles = isEventSupported('submit'),
|
||||
changeBubbles = isEventSupported('change')
|
||||
changeBubbles = isEventSupported('change');
|
||||
|
||||
if (!submitBubbles || !changeBubbles) {
|
||||
// augment the Event.Handler class to observe custom events when needed
|
||||
Event.Handler.prototype.initialize = Event.Handler.prototype.initialize.wrap(
|
||||
function(init, element, eventName, selector, callback) {
|
||||
init(element, eventName, selector, callback)
|
||||
init(element, eventName, selector, callback);
|
||||
// is the handler being attached to an element that doesn't support this event?
|
||||
if ( (!submitBubbles && this.eventName == 'submit' && !isForm(this.element)) ||
|
||||
(!changeBubbles && this.eventName == 'change' && !isInput(this.element)) ) {
|
||||
// "submit" => "emulated:submit"
|
||||
this.eventName = 'emulated:' + this.eventName
|
||||
this.eventName = 'emulated:' + this.eventName;
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (!submitBubbles) {
|
||||
|
@ -49,26 +49,26 @@
|
|||
// special handler for the real "submit" event (one-time operation)
|
||||
if (!form.retrieve('emulated:submit')) {
|
||||
form.on('submit', function(submitEvent) {
|
||||
var emulated = form.fire('emulated:submit', submitEvent, true)
|
||||
var emulated = form.fire('emulated:submit', submitEvent, true);
|
||||
// if custom event received preventDefault, cancel the real one too
|
||||
if (emulated.returnValue === false) submitEvent.preventDefault()
|
||||
})
|
||||
form.store('emulated:submit', true)
|
||||
if (emulated.returnValue === false) submitEvent.preventDefault();
|
||||
});
|
||||
form.store('emulated:submit', true);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
if (!changeBubbles) {
|
||||
// discover form inputs on the page
|
||||
document.on('focusin', 'input, select, texarea', function(focusEvent, input) {
|
||||
document.on('focusin', 'input, select, textarea', function(focusEvent, input) {
|
||||
// special handler for real "change" events
|
||||
if (!input.retrieve('emulated:change')) {
|
||||
input.on('change', function(changeEvent) {
|
||||
input.fire('emulated:change', changeEvent, true)
|
||||
})
|
||||
input.store('emulated:change', true)
|
||||
input.fire('emulated:change', changeEvent, true);
|
||||
});
|
||||
input.store('emulated:change', true);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
function handleRemote(element) {
|
||||
|
@ -80,7 +80,10 @@
|
|||
if (element.tagName.toLowerCase() === 'form') {
|
||||
method = element.readAttribute('method') || 'post';
|
||||
url = element.readAttribute('action');
|
||||
params = element.serialize();
|
||||
// serialize the form with respect to the submit button that was pressed
|
||||
params = element.serialize({ submit: element.retrieve('rails:submit-button') });
|
||||
// clear the pressed submit button information
|
||||
element.store('rails:submit-button', null);
|
||||
} else {
|
||||
method = element.readAttribute('data-method') || 'get';
|
||||
url = element.readAttribute('href');
|
||||
|
@ -100,6 +103,10 @@
|
|||
element.fire("ajax:after");
|
||||
}
|
||||
|
||||
function insertHiddenField(form, name, value) {
|
||||
form.insert(new Element('input', { type: 'hidden', name: name, value: value }));
|
||||
}
|
||||
|
||||
function handleMethod(element) {
|
||||
var method = element.readAttribute('data-method'),
|
||||
url = element.readAttribute('href'),
|
||||
|
@ -110,15 +117,11 @@
|
|||
element.parentNode.insert(form);
|
||||
|
||||
if (method !== 'post') {
|
||||
var field = new Element('input', { type: 'hidden', name: '_method', value: method });
|
||||
form.insert(field);
|
||||
insertHiddenField(form, '_method', method);
|
||||
}
|
||||
|
||||
if (csrf_param) {
|
||||
var param = csrf_param.readAttribute('content'),
|
||||
token = csrf_token.readAttribute('content'),
|
||||
field = new Element('input', { type: 'hidden', name: param, value: token });
|
||||
form.insert(field);
|
||||
insertHiddenField(form, csrf_param.readAttribute('content'), csrf_token.readAttribute('content'));
|
||||
}
|
||||
|
||||
form.submit();
|
||||
|
@ -142,34 +145,34 @@
|
|||
event.stop();
|
||||
});
|
||||
|
||||
document.on("click", "form input[type=submit]", function(event, button) {
|
||||
// register the pressed submit button
|
||||
event.findElement('form').store('rails:submit-button', button.name || false);
|
||||
});
|
||||
|
||||
document.on("submit", function(event) {
|
||||
var element = event.findElement(),
|
||||
message = element.readAttribute('data-confirm');
|
||||
var form = event.findElement(),
|
||||
message = form.readAttribute('data-confirm');
|
||||
|
||||
if (message && !confirm(message)) {
|
||||
event.stop();
|
||||
return false;
|
||||
}
|
||||
|
||||
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');
|
||||
form.select('input[type=submit][data-disable-with]').each(function(input) {
|
||||
input.store('rails:original-value', input.getValue());
|
||||
input.disable().setValue(input.readAttribute('data-disable-with'));
|
||||
});
|
||||
|
||||
var element = event.findElement("form[data-remote]");
|
||||
if (element) {
|
||||
handleRemote(element);
|
||||
if (form.readAttribute('data-remote')) {
|
||||
handleRemote(form);
|
||||
event.stop();
|
||||
}
|
||||
});
|
||||
|
||||
document.on("ajax:after", "form", function(event, element) {
|
||||
var inputs = element.select("input[type=submit][disabled=true][data-disable-with]");
|
||||
inputs.each(function(input) {
|
||||
input.value = input.readAttribute('data-original-value');
|
||||
input.removeAttribute('data-original-value');
|
||||
input.disabled = false;
|
||||
document.on("ajax:after", "form", function(event, form) {
|
||||
form.select('input[type=submit][data-disable-with]').each(function(input) {
|
||||
input.setValue(input.retrieve('rails:original-value')).enable();
|
||||
});
|
||||
});
|
||||
})();
|
|
@ -60,7 +60,7 @@ namespace :rails do
|
|||
|
||||
# desc "Update Prototype javascripts from your current rails install"
|
||||
task :javascripts do
|
||||
invoke_from_app_generator :create_prototype_files
|
||||
invoke_from_app_generator :create_javascript_files
|
||||
end
|
||||
|
||||
# desc "Adds new scripts to the application script/ directory"
|
||||
|
|
|
@ -188,13 +188,33 @@ class AppGeneratorTest < Rails::Generators::TestCase
|
|||
assert_file "test"
|
||||
end
|
||||
|
||||
def test_prototype_and_test_unit_are_skipped_if_required
|
||||
run_generator [destination_root, "--skip-prototype", "--skip-test-unit"]
|
||||
def test_test_unit_is_skipped_if_required
|
||||
run_generator [destination_root, "--skip-test-unit"]
|
||||
assert_no_file "test"
|
||||
end
|
||||
|
||||
def test_javascript_is_skipped_if_required
|
||||
run_generator [destination_root, "--skip-javascript"]
|
||||
assert_file "config/application.rb", /^\s+config\.action_view\.javascript_expansions\[:defaults\]\s+=\s+%w\(\)/
|
||||
assert_file "public/javascripts/application.js"
|
||||
assert_no_file "public/javascripts/prototype.js"
|
||||
assert_no_file "public/javascripts/rails.js"
|
||||
assert_no_file "test"
|
||||
end
|
||||
|
||||
def test_config_prototype_javascript_library
|
||||
run_generator [destination_root, "-j", "prototype"]
|
||||
assert_file "config/application.rb", /#\s+config\.action_view\.javascript_expansions\[:defaults\]\s+=\s+%w\(jquery rails\)/
|
||||
assert_file "public/javascripts/application.js"
|
||||
assert_file "public/javascripts/prototype.js"
|
||||
assert_file "public/javascripts/rails.js", /prototype/
|
||||
end
|
||||
|
||||
def test_config_jquery_javascript_library
|
||||
run_generator [destination_root, "-j", "jquery"]
|
||||
assert_file "config/application.rb", /^\s+config\.action_view\.javascript_expansions\[:defaults\]\s+=\s+%w\(jquery rails\)/
|
||||
assert_file "public/javascripts/application.js"
|
||||
assert_file "public/javascripts/jquery.js"
|
||||
assert_file "public/javascripts/rails.js", /jQuery/
|
||||
end
|
||||
|
||||
def test_shebang_is_added_to_rails_file
|
||||
|
|
Loading…
Reference in a new issue