1
0
Fork 0
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:
siong1987 2010-09-11 14:09:16 -05:00 committed by Santiago Pastorino
parent cecccf1156
commit 708e09448b
8 changed files with 6309 additions and 57 deletions

View file

@ -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 -------------------------------------------------------------------------

View file

@ -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

View file

@ -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 -%>

File diff suppressed because it is too large Load diff

View 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'));
});
});
});

View file

@ -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();
});
});
})();

View file

@ -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"

View file

@ -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