提交 b2aacc34 编写于 作者: X Xavier Noria

Prototype and Scriptaculous are no longer vendored, but provided by...

Prototype and Scriptaculous are no longer vendored, but provided by prototype-rails from now on, also the -j option of the application generator is removed
上级 7ee5f2ee
......@@ -99,10 +99,9 @@ def javascript_path(source)
#
# When passing paths, the ".js" extension is optional.
#
# To include the default JavaScript expansion pass <tt>:defaults</tt> as source.
# By default, <tt>:defaults</tt> loads jQuery. If the application was generated
# with "-j prototype" the libraries Prototype and Scriptaculous are loaded instead.
# In any case, the defaults can be overridden in <tt>config/application.rb</tt>:
# If the application is not using the asset pipeline, to include the default JavaScript
# expansion pass <tt>:defaults</tt> as source. By default, <tt>:defaults</tt> loads jQuery,
# and that can be overridden in <tt>config/application.rb</tt>:
#
# config.action_view.javascript_expansions[:defaults] = %w(foo.js bar.js)
#
......
*Rails 3.1.0 (unreleased)*
* Application generation no longer supports the -j option. [fxn]
* Prototype and Scriptaculous are no longer vendored, they are provided from now on
by the prototype-rails gem. [fxn]
* The scaffold controller will now produce SCSS file if Sass is available [Prem Sichanugrist]
* The controller and resource generators will now automatically produce asset stubs (this can be turned off with --skip-assets). These stubs will use Coffee and Sass, if those libraries are available. [DHH]
......
......@@ -46,7 +46,6 @@ task :generate_guides do
end
task :update_ujs do
system "curl https://github.com/rails/prototype-ujs/raw/master/src/rails.js > lib/rails/generators/rails/app/templates/vendor/assets/javascripts/prototype_ujs.js"
system "curl https://github.com/rails/jquery-ujs/raw/master/src/rails.js > lib/rails/generators/rails/app/templates/vendor/assets/javascripts/jquery_ujs.js"
end
......
......@@ -526,7 +526,7 @@ javascript_include_tag "common" # =>
<script type="text/javascript" src="/javascripts/common.js"></script>
</ruby>
To include the Prototype and Scriptaculous JavaScript libraries in your application, pass +:defaults+ as the source. When using +:defaults+, if an +application.js+ file exists in your +public/javascripts+ directory, it will be included as well.
If the application does not use the asset pipeline, to include the jQuery JavaScript library in your application, pass +:defaults+ as the source. When using +:defaults+, if an +application.js+ file exists in your +public/javascripts+ directory, it will be included as well.
<ruby>
javascript_include_tag :defaults
......@@ -1301,7 +1301,7 @@ h4. JavaScriptHelper
Provides functionality for working with JavaScript in your views.
Rails includes the Prototype JavaScript framework and the Scriptaculous JavaScript controls and visual effects library. If you wish to use these libraries and their helpers, make sure +&lt;%= javascript_include_tag :defaults, :cache => true %&gt;+ is in the HEAD section of your page. This function will include the necessary JavaScript files Rails generated in the +public/javascripts+ directory.
Rails includes by default the jQuery JavaScript library. If you wish to use these libraries and they are in your asset pipeline, or otherwise make sure +&lt;%= javascript_include_tag :defaults, :cache => true %&gt;+ is in the HEAD section of your page. This function will include the necessary JavaScript files Rails generated in the +public/javascripts+ directory.
h5. button_to_function
......@@ -1402,16 +1402,6 @@ number_with_precision(111.2345) # => 111.235
number_with_precision(111.2345, 2) # => 111.23
</ruby>
h4. PrototypeHelper
Prototype is a JavaScript library that provides DOM manipulation, Ajax functionality, and more traditional object-oriented facilities for JavaScript. This module provides a set of helpers to make it more convenient to call functions from Prototype using Rails, including functionality to call remote Rails methods (that is, making a background request to a Rails action) using Ajax.
To be able to use these helpers, you must first include the Prototype JavaScript framework in the HEAD of the pages with Prototype functions.
<ruby>
javascript_include_tag 'prototype'
</ruby>
h5. evaluate_remote_response
Returns +eval(request.responseText)+ which is the JavaScript function that form_remote_tag can call in +:complete+ to evaluate a multiple update return document using +update_element_function+ calls.
......@@ -1508,171 +1498,6 @@ would generate:
return false;" type="button" value="Create" />
</html>
h5. update_page
Yields a JavaScriptGenerator and returns the generated JavaScript code. Use this to update multiple elements on a page in an Ajax response.
<ruby>
update_page do |page|
page.hide 'spinner'
end
</ruby>
h5. update_page_tag
Works like update_page but wraps the generated JavaScript in a +script+ tag. Use this to include generated JavaScript in an ERB template.
h4. PrototypeHelper::JavaScriptGenerator::GeneratorMethods
JavaScriptGenerator generates blocks of JavaScript code that allow you to change the content and presentation of multiple DOM elements. Use this in your Ajax response bodies, either in a +script+ tag or as plain JavaScript sent with a Content-type of "text/javascript".
h5(#push). <<
Writes raw JavaScript to the page.
<ruby>
page << "alert('JavaScript with Prototype.');"
</ruby>
h5(#at). []
Returns a element reference by finding it through it's id in the DOM.
<ruby>
page['blank_slate'].show # => $('blank_slate').show();
</ruby>
h5. alert
Displays an alert dialog with the given message.
<ruby>
page.alert('This message is from Rails!')
</ruby>
h5. assign
Assigns the JavaScript variable the given value.
<ruby>
page.assign 'tabulated_total', @total_from_cart
</ruby>
h5. call
Calls the JavaScript function, optionally with the given arguments.
<ruby>
page.call 'Element.replace', 'my_element', "My content to replace with."
</ruby>
h5. delay
Executes the content of the block after a delay of the number of seconds provided.
<ruby>
page.delay(20) do
page.visual_effect :fade, 'notice'
end
</ruby>
h5. draggable
Creates a script.aculo.us draggable element. See ActionView::Helpers::ScriptaculousHelper for more information.
h5. drop_receiving
Creates a script.aculo.us drop receiving element. See ActionView::Helpers::ScriptaculousHelper for more information.
h5. hide
Hides the visible DOM elements with the given ids.
<ruby>
page.hide 'person_29', 'person_9', 'person_0'
</ruby>
h5. insert_html
Inserts HTML at the specified position relative to the DOM element identified by the given id.
<ruby>
page.insert_html :bottom, 'my_list', '<li>Last item</li>'
</ruby>
h5. literal
Returns an object whose to_json evaluates to the code provided. Use this to pass a literal JavaScript expression as an argument to another JavaScriptGenerator method.
h5. redirect_to
Redirects the browser to the given location using JavaScript, in the same form as +url_for+.
<ruby>
page.redirect_to(:controller => 'accounts', :action => 'new')
</ruby>
h5. remove
Removes the DOM elements with the given ids from the page.
<ruby>
page.remove 'person_23', 'person_9', 'person_2'
</ruby>
h5. replace
Replaces the "outer HTML" (i.e., the entire element, not just its contents) of the DOM element with the given id.
<ruby>
page.replace 'person-45', :partial => 'person', :object => @person
</ruby>
h5. replace_html
Replaces the inner HTML of the DOM element with the given id.
<ruby>
page.replace_html 'person-45', :partial => 'person', :object => @person
</ruby>
h5(#prototype-select). select
Returns a collection reference by finding it through a CSS pattern in the DOM.
<ruby>
page.select('p.welcome b').first.hide # => $$('p.welcome b').first().hide();
</ruby>
h5. show
Shows hidden DOM elements with the given ids.
<ruby>
page.show 'person_6', 'person_13', 'person_223'
</ruby>
h5. sortable
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.
h5. toggle
Toggles the visibility of the DOM elements with the given ids. Example:
<ruby>
page.toggle 'person_14', 'person_12', 'person_23' # Hides the elements
page.toggle 'person_14', 'person_12', 'person_23' # Shows the previously hidden elements
</ruby>
h5. visual_effect
Starts a script.aculo.us visual effect. See ActionView::Helpers::ScriptaculousHelper for more information.
TODO start from RecordIdentificationHelper
h3. Localized Views
Action View has the ability render different templates depending on the current locale.
......
......@@ -695,13 +695,13 @@ To include +http://example.com/main.js+:
<%= javascript_include_tag "http://example.com/main.js" %>
</erb>
The +:defaults+ option loads jQuery by default:
If the application does not use the asset pipeline, the +:defaults+ option loads jQuery by default:
<erb>
<%= javascript_include_tag :defaults %>
</erb>
If the application was generated with "-j prototype" <tt>:defaults</tt> loads Prototype and Scriptaculous. And you can in any case override the expansion in <tt>config/application.rb</tt>:
And you can in any case override the expansion in <tt>config/application.rb</tt>:
<ruby>
config.action_view.javascript_expansions[:defaults] = %w(foo.js bar.js)
......@@ -709,7 +709,7 @@ config.action_view.javascript_expansions[:defaults] = %w(foo.js bar.js)
When using <tt>:defaults</tt>, if an <tt>application.js</tt> file exists in <tt>public/javascripts</tt> it will be included as well at then end.
The +:all+ option loads every JavaScript file in +public/javascripts+:
Also, the +:all+ option loads every JavaScript file in +public/javascripts+:
<erb>
<%= javascript_include_tag :all %>
......
......@@ -38,9 +38,6 @@ def self.add_shared_options_for(name)
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 => "jquery",
:desc => "Preconfigure for selected JavaScript library (options: #{JAVASCRIPTS.join('/')})"
class_option :skip_javascript, :type => :boolean, :aliases => "-J", :default => false,
:desc => "Skip JavaScript files"
......
......@@ -120,14 +120,8 @@ def vendor_javascripts
if options[:skip_javascript]
empty_directory_with_gitkeep "vendor/assets/javascripts"
else
copy_file "vendor/assets/javascripts/#{options[:javascript]}.js"
copy_file "vendor/assets/javascripts/#{options[:javascript]}_ujs.js"
if options[:javascript] == "prototype"
copy_file "vendor/assets/javascripts/controls.js"
copy_file "vendor/assets/javascripts/dragdrop.js"
copy_file "vendor/assets/javascripts/effects.js"
end
copy_file "vendor/assets/javascripts/jquery.js"
copy_file "vendor/assets/javascripts/jquery_ujs.js"
end
end
......@@ -162,10 +156,6 @@ def initialize(*args)
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
public_task :create_root
......
......@@ -10,6 +10,9 @@ gem 'sass'
gem 'coffee-script'
gem 'uglifier'
# Prototype, Scriptaculous, and RJS.
# gem 'prototype-rails'
# Use unicorn as the web server
# gem 'unicorn'
......
// FIXME: Tell people that this is a manifest file, real code should go into discrete files
// FIXME: Tell people how Sprockets and CoffeeScript works
//
//= require <%= options[:javascript] %>
//= require <%= options[:javascript] %>_ujs
<% if options[:javascript] == "prototype" %>
//= require controls
//= require dragdrop
//= require effects
<% unless options[:skip_javascript] -%>
//= require jquery
//= require jquery_ujs
<% end -%>
//= require_tree .
......@@ -45,9 +45,7 @@ class Application < Rails::Application
#
# JavaScript files you want as :defaults (application.js is always included).
<% if options[:skip_javascript] -%>
config.action_view.javascript_expansions[:defaults] = %w()
<% elsif options[:javascript] == 'prototype' -%>
config.action_view.javascript_expansions[:defaults] = %w(prototype effects dragdrop controls rails)
# config.action_view.javascript_expansions[:defaults] = %w()
<% else -%>
# config.action_view.javascript_expansions[:defaults] = %w(prototype effects dragdrop controls rails)
<% end -%>
......
(function() {
Ajax.Responders.register({
onCreate: function(request) {
var token = $$('meta[name=csrf-token]')[0];
if (token) {
if (!request.options.requestHeaders) request.options.requestHeaders = {};
request.options.requestHeaders['X-CSRF-Token'] = token.readAttribute('content');
}
}
});
// Technique from Juriy Zaytsev
// http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
function isEventSupported(eventName) {
var el = document.createElement('div');
eventName = 'on' + eventName;
var isSupported = (eventName in el);
if (!isSupported) {
el.setAttribute(eventName, 'return;');
isSupported = typeof el[eventName] == 'function';
}
el = null;
return isSupported;
}
function isForm(element) {
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';
}
else return false;
}
var submitBubbles = isEventSupported('submit'),
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);
// 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;
}
}
);
}
if (!submitBubbles) {
// discover forms on the page by observing focus events which always bubble
document.on('focusin', 'form', function(focusEvent, form) {
// 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);
// if custom event received preventDefault, cancel the real one too
if (emulated.returnValue === false) submitEvent.preventDefault();
});
form.store('emulated:submit', true);
}
});
}
if (!changeBubbles) {
// discover form inputs on the page
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);
}
});
}
function handleRemote(element) {
var method, url, params;
var event = element.fire("ajax:before");
if (event.stopped) return false;
if (element.tagName.toLowerCase() === 'form') {
method = element.readAttribute('method') || 'post';
url = element.readAttribute('action');
// 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');
params = {};
}
new Ajax.Request(url, {
method: method,
parameters: params,
evalScripts: true,
onCreate: function(response) { element.fire("ajax:create", response); },
onComplete: function(response) { element.fire("ajax:complete", response); },
onSuccess: function(response) { element.fire("ajax:success", response); },
onFailure: function(response) { element.fire("ajax:failure", response); }
});
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'),
csrf_param = $$('meta[name=csrf-param]')[0],
csrf_token = $$('meta[name=csrf-token]')[0];
var form = new Element('form', { method: "POST", action: url, style: "display: none;" });
$(element.parentNode).insert(form);
if (method !== 'post') {
insertHiddenField(form, '_method', method);
}
if (csrf_param) {
insertHiddenField(form, csrf_param.readAttribute('content'), csrf_token.readAttribute('content'));
}
form.submit();
}
function disableFormElements(form) {
form.select('input[type=submit][data-disable-with]').each(function(input) {
input.store('rails:original-value', input.getValue());
input.setValue(input.readAttribute('data-disable-with')).disable();
});
}
function enableFormElements(form) {
form.select('input[type=submit][data-disable-with]').each(function(input) {
input.setValue(input.retrieve('rails:original-value')).enable();
});
}
function allowAction(element) {
var message = element.readAttribute('data-confirm');
return !message || confirm(message);
}
document.on('click', 'a[data-confirm], a[data-remote], a[data-method]', function(event, link) {
if (!allowAction(link)) {
event.stop();
return false;
}
if (link.readAttribute('data-remote')) {
handleRemote(link);
event.stop();
} else if (link.readAttribute('data-method')) {
handleMethod(link);
event.stop();
}
});
document.on("click", "form input[type=submit], form button[type=submit], form button:not([type])", function(event, button) {
// register the pressed submit button
event.findElement('form').store('rails:submit-button', button.name || false);
});
document.on("submit", function(event) {
var form = event.findElement();
if (!allowAction(form)) {
event.stop();
return false;
}
if (form.readAttribute('data-remote')) {
handleRemote(form);
event.stop();
} else {
disableFormElements(form);
}
});
document.on('ajax:create', 'form', function(event, form) {
if (form == event.findElement()) disableFormElements(form);
});
document.on('ajax:complete', 'form', function(event, form) {
if (form == event.findElement()) enableFormElements(form);
});
})();
......@@ -119,19 +119,10 @@ def javascripts
if mountable?
copy_file "#{app_templates_dir}/app/assets/javascripts/application.js.tt",
"app/assets/javascripts/application.js"
copy_file "#{app_templates_dir}/vendor/assets/javascripts/#{options[:javascript]}.js",
"vendor/assets/javascripts/#{options[:javascript]}.js"
copy_file "#{app_templates_dir}/vendor/assets/javascripts/#{options[:javascript]}_ujs.js",
"vendor/assets/javascripts/#{options[:javascript]}_ujs.js"
if options[:javascript] == "prototype"
copy_file "#{app_templates_dir}/vendor/assets/javascripts/controls.js",
"vendor/assets/javascripts/controls.js"
copy_file "#{app_templates_dir}/vendor/assets/javascripts/dragdrop.js",
"vendor/assets/javascripts/dragdrop.js"
copy_file "#{app_templates_dir}/vendor/assets/javascripts/effects.js",
"vendor/assets/javascripts/effects.js"
end
copy_file "#{app_templates_dir}/vendor/assets/javascripts/jquery.js",
"vendor/assets/javascripts/jquery.js"
copy_file "#{app_templates_dir}/vendor/assets/javascripts/jquery_ujs.js",
"vendor/assets/javascripts/jquery_ujs.js"
elsif full?
empty_directory_with_gitkeep "app/assets/javascripts"
end
......
......@@ -174,31 +174,12 @@ def test_jquery_and_test_unit_are_added_by_default
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 "config/application.rb", /^\s+# config\.action_view\.javascript_expansions\[:defaults\]\s+=\s+%w\(\)/
assert_file "app/assets/javascripts/application.js"
assert_no_file "vendor/assets/javascripts/jquery.js"
assert_no_file "vendor/assets/javascripts/jquery_ujs.js"
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\(prototype effects dragdrop controls rails\)/
assert_file "app/assets/javascripts/application.js"
assert_file "vendor/assets/javascripts/prototype.js"
assert_file "vendor/assets/javascripts/effects.js"
assert_file "vendor/assets/javascripts/dragdrop.js"
assert_file "vendor/assets/javascripts/controls.js"
assert_file "vendor/assets/javascripts/prototype_ujs.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\(prototype effects dragdrop controls rails\)/
assert_file "app/assets/javascripts/application.js"
assert_file "vendor/assets/javascripts/jquery.js"
assert_file "vendor/assets/javascripts/jquery_ujs.js", /jQuery/
end
def test_template_from_dir_pwd
FileUtils.cd(Rails.root)
assert_match /It works from file!/, run_generator([destination_root, "-m", "lib/template.rb"])
......
......@@ -114,16 +114,6 @@ def test_skip_javascripts
assert_no_file "vendor/assets/javascripts/jquery_ujs.js"
end
def test_config_prototype_javascript_library
run_generator [destination_root, "-j", "prototype", "--mountable"]
assert_file "app/assets/javascripts/application.js"
assert_file "vendor/assets/javascripts/prototype.js"
assert_file "vendor/assets/javascripts/effects.js"
assert_file "vendor/assets/javascripts/dragdrop.js"
assert_file "vendor/assets/javascripts/controls.js"
assert_file "vendor/assets/javascripts/prototype_ujs.js", /prototype/
end
def test_template_from_dir_pwd
FileUtils.cd(Rails.root)
assert_match(/It works from file!/, run_generator([destination_root, "-m", "lib/template.rb"]))
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册