From 85412da5f41038e365c77cd6d7ba4a165e76bc80 Mon Sep 17 00:00:00 2001 From: Neeraj Singh Date: Sat, 13 Nov 2010 14:01:53 -0500 Subject: [PATCH 001/364] add rubygems.org to Gemfile and Gemfile.lock --- Gemfile | 3 +++ Gemfile.lock | 1 + 2 files changed, 4 insertions(+) diff --git a/Gemfile b/Gemfile index a1767e96..d1793e4c 100644 --- a/Gemfile +++ b/Gemfile @@ -1,2 +1,5 @@ +source 'http://rubygems.org' + gem "json" + gem "sinatra", "= 1.0" diff --git a/Gemfile.lock b/Gemfile.lock index 6e7745e3..4d10d04d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,4 +1,5 @@ GEM + remote: http://rubygems.org/ specs: json (1.4.6) rack (1.2.1) From e1ae2de9a5adf6612ad3a2d7388d63e50893721e Mon Sep 17 00:00:00 2001 From: Neeraj Singh Date: Sat, 13 Nov 2010 22:39:04 -0500 Subject: [PATCH 002/364] remove lint warning by replacing != with !== --- src/rails.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rails.js b/src/rails.js index 223fe7ea..9588bfbe 100644 --- a/src/rails.js +++ b/src/rails.js @@ -108,7 +108,7 @@ jQuery(function ($) { form = $('
'), metadata_input = ''; - if (csrf_param != null && csrf_token != null) { + if (csrf_param !== undefined && csrf_token !== undefined) { metadata_input += ''; } From b1f0e58dc79e867ee68effb422205ed2459aca8b Mon Sep 17 00:00:00 2001 From: Neeraj Singh Date: Sat, 13 Nov 2010 22:41:54 -0500 Subject: [PATCH 003/364] add ; to fix lint warning --- src/rails.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rails.js b/src/rails.js index 9588bfbe..7abbb0ca 100644 --- a/src/rails.js +++ b/src/rails.js @@ -150,7 +150,7 @@ jQuery(function ($) { var jqueryVersion = $().jquery; if ( (jqueryVersion === '1.4') || (jqueryVersion === '1.4.1') || (jqueryVersion === '1.4.2') ){ - alert('This rails.js does not support the jQuery version you are using. Please read documentation.') + alert('This rails.js does not support the jQuery version you are using. Please read documentation.'); } }); From 512691e9cd3108788ee138216a23b16d05407f69 Mon Sep 17 00:00:00 2001 From: Neeraj Singh Date: Sat, 13 Nov 2010 22:50:36 -0500 Subject: [PATCH 004/364] fix indentation --- src/rails.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rails.js b/src/rails.js index 7abbb0ca..ba4b2b56 100644 --- a/src/rails.js +++ b/src/rails.js @@ -44,7 +44,7 @@ jQuery(function ($) { dataType = el.attr('data-type') || 'script'; if (url === undefined) { - throw "No URL specified for remote call (action or href must be present)."; + 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() : []; @@ -109,7 +109,7 @@ jQuery(function ($) { metadata_input = ''; if (csrf_param !== undefined && csrf_token !== undefined) { - metadata_input += ''; + metadata_input += ''; } form.hide() @@ -150,7 +150,7 @@ jQuery(function ($) { var jqueryVersion = $().jquery; if ( (jqueryVersion === '1.4') || (jqueryVersion === '1.4.1') || (jqueryVersion === '1.4.2') ){ - alert('This rails.js does not support the jQuery version you are using. Please read documentation.'); + alert('This rails.js does not support the jQuery version you are using. Please read documentation.'); } }); From 17dec3864174ffefadc012c23e470c303d95861f Mon Sep 17 00:00:00 2001 From: Steve Schwartz Date: Sun, 14 Nov 2010 23:41:33 -0500 Subject: [PATCH 005/364] Added 'rails' namespace to all live and delegate event bindings. Signed-off-by: Neeraj Singh --- src/rails.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/rails.js b/src/rails.js index ba4b2b56..595de557 100644 --- a/src/rails.js +++ b/src/rails.js @@ -77,7 +77,7 @@ jQuery(function ($) { * confirmation handler */ - $('body').delegate('a[data-confirm], button[data-confirm], input[data-confirm]', 'click', function () { + $('body').delegate('a[data-confirm], button[data-confirm], input[data-confirm]', 'click.rails', function () { var el = $(this); if (el.triggerAndReturn('confirm')) { if (!confirm(el.attr('data-confirm'))) { @@ -91,17 +91,17 @@ jQuery(function ($) { /** * remote handlers */ - $('form[data-remote]').live('submit', function (e) { + $('form[data-remote]').live('submit.rails', function (e) { $(this).callRemote(); e.preventDefault(); }); - $('a[data-remote],input[data-remote]').live('click', function (e) { + $('a[data-remote],input[data-remote]').live('click.rails', function (e) { $(this).callRemote(); e.preventDefault(); }); - $('a[data-method]:not([data-remote])').live('click', function (e){ + $('a[data-method]:not([data-remote])').live('click.rails', function (e){ var link = $(this), href = link.attr('href'), method = link.attr('data-method'), @@ -136,10 +136,10 @@ jQuery(function ($) { }); }; - $(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:before.rails', disable_with_input_function); + $(disable_with_form_not_remote_selector).live('submit.rails', disable_with_input_function); - $(disable_with_form_remote_selector).live('ajax:complete', function () { + $(disable_with_form_remote_selector).live('ajax:complete.rails', function () { $(this).find(disable_with_input_selector).each(function () { var input = $(this); input.removeAttr('disabled') From 4ece456c505b6929cde996100770a67b1a805cfc Mon Sep 17 00:00:00 2001 From: Neeraj Singh Date: Mon, 15 Nov 2010 12:39:40 -0500 Subject: [PATCH 006/364] respect global ajaxSettings declared via $.ajaxSetup --- src/rails.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rails.js b/src/rails.js index 595de557..427e0c2f 100644 --- a/src/rails.js +++ b/src/rails.js @@ -41,7 +41,7 @@ jQuery(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'; + dataType = el.attr('data-type') || ($.ajaxSettings && $.ajaxSettings.dataType) || 'script'; if (url === undefined) { throw "No URL specified for remote call (action or href must be present)."; From ff185db3198d4891ea5606e9dd9ef950a897f349 Mon Sep 17 00:00:00 2001 From: Neeraj Singh Date: Thu, 18 Nov 2010 14:54:51 -0500 Subject: [PATCH 007/364] get closer to jQuery. Do not set data-type as 'script' arbitrarily. Possibly might break a few apps. However passing data-type is always a good idea. Be in control. --- src/rails.js | 2 +- test/server.rb | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/rails.js b/src/rails.js index 427e0c2f..62f257d5 100644 --- a/src/rails.js +++ b/src/rails.js @@ -41,7 +41,7 @@ jQuery(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') || ($.ajaxSettings && $.ajaxSettings.dataType) || 'script'; + dataType = el.attr('data-type') || ($.ajaxSettings && $.ajaxSettings.dataType); if (url === undefined) { throw "No URL specified for remote call (action or href must be present)."; diff --git a/test/server.rb b/test/server.rb index fbc8b760..2816797e 100644 --- a/test/server.rb +++ b/test/server.rb @@ -9,8 +9,7 @@ FileUtils.cp(source_file, dest_file) after do - ctype = request.xhr? ? 'application/json' : 'text/html' - content_type ctype, :charset => 'utf-8' + content_type 'text/html', :charset => 'utf-8' end get '/' do From b6a3500bfb4b845d2c5e2f81b3c57a62fffd0845 Mon Sep 17 00:00:00 2001 From: Neeraj Singh Date: Tue, 23 Nov 2010 20:55:05 -0500 Subject: [PATCH 008/364] If an ajax request is being sent then HTTP_ACCEPT must have text/javascript. Fixes #52 --- src/rails.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/rails.js b/src/rails.js index 62f257d5..3db37270 100644 --- a/src/rails.js +++ b/src/rails.js @@ -54,6 +54,7 @@ jQuery(function ($) { dataType: dataType, type: method.toUpperCase(), beforeSend: function (xhr) { + xhr.setRequestHeader("Accept", "text/javascript"); el.trigger('ajax:loading', xhr); }, success: function (data, status, xhr) { From 866a1031c4049896fdae724059595dba85b4cc40 Mon Sep 17 00:00:00 2001 From: Neeraj Singh Date: Tue, 23 Nov 2010 21:14:22 -0500 Subject: [PATCH 009/364] fix module name in test file --- test/public/test/call-remote-callbacks.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/public/test/call-remote-callbacks.js b/test/public/test/call-remote-callbacks.js index aecd37dd..3265ecd0 100644 --- a/test/public/test/call-remote-callbacks.js +++ b/test/public/test/call-remote-callbacks.js @@ -18,7 +18,7 @@ App.build_form = function(opt) { })); }; -module('call-remote', { +module('call-remote-callbacks', { teardown: App.teardown, From f0d2e561d4a80e6933c83ff7fea91f690e2e4c15 Mon Sep 17 00:00:00 2001 From: Neeraj Singh Date: Fri, 26 Nov 2010 19:15:19 -0500 Subject: [PATCH 010/364] add comments to data-method --- src/rails.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/rails.js b/src/rails.js index 3db37270..e59a480e 100644 --- a/src/rails.js +++ b/src/rails.js @@ -102,6 +102,11 @@ jQuery(function ($) { e.preventDefault(); }); + /** + * <%= link_to "Delete", user_path(@user), :method => :delete, :confirm => "Are you sure?" %> + * + * Delete + */ $('a[data-method]:not([data-remote])').live('click.rails', function (e){ var link = $(this), href = link.attr('href'), From 3d4f74fc07d7c09dbbb2e37aa87300682b92ab00 Mon Sep 17 00:00:00 2001 From: Neeraj Singh Date: Fri, 26 Nov 2010 20:17:18 -0500 Subject: [PATCH 011/364] fix the wrong module name inside test --- test/public/test/data-method-iframe.js | 2 +- test/public/test/data-method.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/public/test/data-method-iframe.js b/test/public/test/data-method-iframe.js index 06dcd12d..5bedae97 100644 --- a/test/public/test/data-method-iframe.js +++ b/test/public/test/data-method-iframe.js @@ -1,4 +1,4 @@ -module('data-remote-iframe', { +module('data-method-iframe', { teardown: App.teardown, diff --git a/test/public/test/data-method.js b/test/public/test/data-method.js index e76a6f2a..9b41fa78 100644 --- a/test/public/test/data-method.js +++ b/test/public/test/data-method.js @@ -1,4 +1,4 @@ -module('data-remote'); +module('data-method'); test('clicking on a link with data-method attribute', function() { expect(1); From 1c2c0db532b2d2fd3c0c49e93818b77a948aefd1 Mon Sep 17 00:00:00 2001 From: Neeraj Singh Date: Fri, 26 Nov 2010 23:08:28 -0500 Subject: [PATCH 012/364] remove the unused @app_base_url --- test/views/index.erb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/views/index.erb b/test/views/index.erb index 0ad5ebba..dbbe662c 100644 --- a/test/views/index.erb +++ b/test/views/index.erb @@ -34,7 +34,7 @@
-
From c284be39c752cebfc9c0b12425a371660af4686d Mon Sep 17 00:00:00 2001 From: Neeraj Singh Date: Fri, 26 Nov 2010 23:12:30 -0500 Subject: [PATCH 014/364] remove unused markup from test file --- test/views/index.erb | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/views/index.erb b/test/views/index.erb index 5b966dd4..21d34bf9 100644 --- a/test/views/index.erb +++ b/test/views/index.erb @@ -40,9 +40,6 @@
From d4899b3bafad4b939d69e6da692779ea559a989a Mon Sep 17 00:00:00 2001 From: Neeraj Singh Date: Fri, 26 Nov 2010 23:34:57 -0500 Subject: [PATCH 015/364] Add comment to add where the assertion is actually taking place --- test/public/test/data-method-iframe.js | 6 ++++++ test/public/test/data-method.js | 4 ++-- test/views/iframe.erb | 4 ++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/test/public/test/data-method-iframe.js b/test/public/test/data-method-iframe.js index 5bedae97..7af34292 100644 --- a/test/public/test/data-method-iframe.js +++ b/test/public/test/data-method-iframe.js @@ -14,6 +14,12 @@ module('data-method-iframe', { }); test('clicking on a link with data-method attribute', function() { + + /* + * There is nothing to verify here. The trigger clicks the link + * which submits to /delete. The response given by /delete is asserted in + * data-method-iframe.js + */ expect(0); stop(); diff --git a/test/public/test/data-method.js b/test/public/test/data-method.js index 9b41fa78..a852f48b 100644 --- a/test/public/test/data-method.js +++ b/test/public/test/data-method.js @@ -13,7 +13,7 @@ test('clicking on a link with data-method attribute', function() { start(); }; - //Nothing to do. Just wait for iframe to load and do its thing. And then verify + //index.erb loads iframe.erb . Just wait for iframe to load and do its thing and then verify. if(iframe[0].loaded) { iframeCallback(); } else { @@ -36,7 +36,7 @@ test('clicking on a link with data-method attribute and csrf', function() { start(); }; - //Nothing to do. Just wait for iframe to load and do its thing. And then verify + //index.erb load iframe-csrf.eb . Just wait for iframe to load and do its thing and then verify . if(iframe[0].loaded) { iframeCallback(); } else { diff --git a/test/views/iframe.erb b/test/views/iframe.erb index e3f06abb..3c5536da 100644 --- a/test/views/iframe.erb +++ b/test/views/iframe.erb @@ -11,6 +11,10 @@ +
From 085d910a5ec07b69f31beabce286141aa26f3005 Mon Sep 17 00:00:00 2001 From: Neeraj Singh Date: Mon, 29 Nov 2010 11:37:19 -0500 Subject: [PATCH 016/364] Remove trailing spaces and check for right version closes #51 --- src/rails.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/rails.js b/src/rails.js index e59a480e..3e71bfda 100644 --- a/src/rails.js +++ b/src/rails.js @@ -5,7 +5,7 @@ * * This rails.js file supports jQuery 1.4.3 and 1.4.4 . * - */ + */ jQuery(function ($) { var csrf_token = $('meta[name=csrf-token]').attr('content'), @@ -35,7 +35,7 @@ jQuery(function ($) { * - ajax:success - is executed when status is success * - ajax:complete - is execute when status is complete * - ajax:failure - is execute in case of error - * - ajax:after - is execute every single time at the end of ajax call + * - ajax:after - is execute every single time at the end of ajax call */ callRemote: function () { var el = this, @@ -86,7 +86,7 @@ jQuery(function ($) { } } }); - + /** @@ -155,8 +155,9 @@ jQuery(function ($) { var jqueryVersion = $().jquery; - if ( (jqueryVersion === '1.4') || (jqueryVersion === '1.4.1') || (jqueryVersion === '1.4.2') ){ - alert('This rails.js does not support the jQuery version you are using. Please read documentation.'); - } + if (!( (jqueryVersion === '1.4.3') || (jqueryVersion === '1.4.4'))){ + alert('This rails.js does not support the jQuery version you are using. Please read documentation.'); + } + }); From eac77fcba67f53d808b5adfac70cdb8eac55e2be Mon Sep 17 00:00:00 2001 From: Neeraj Singh Date: Tue, 23 Nov 2010 21:09:34 -0500 Subject: [PATCH 017/364] Be consistent with the names of callbacks jQuery ajax call has callback named error. jquery-ujs has callback ajax:failure. Changing that to ajax:error --- src/rails.js | 6 +++--- test/public/test/call-remote-callbacks.js | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/rails.js b/src/rails.js index 3e71bfda..e9a42f27 100644 --- a/src/rails.js +++ b/src/rails.js @@ -34,8 +34,8 @@ jQuery(function ($) { * - ajax:loading - is executed before firing ajax call * - ajax:success - is executed when status is success * - ajax:complete - is execute when status is complete - * - ajax:failure - is execute in case of error - * - ajax:after - is execute every single time at the end of ajax call + * - ajax:error - is execute in case of error + * - ajax:after - is execute every single time at the end of ajax call */ callRemote: function () { var el = this, @@ -64,7 +64,7 @@ jQuery(function ($) { el.trigger('ajax:complete', xhr); }, error: function (xhr, status, error) { - el.trigger('ajax:failure', [xhr, status, error]); + el.trigger('ajax:error', [xhr, status, error]); } }); } diff --git a/test/public/test/call-remote-callbacks.js b/test/public/test/call-remote-callbacks.js index 3265ecd0..fcb51a08 100644 --- a/test/public/test/call-remote-callbacks.js +++ b/test/public/test/call-remote-callbacks.js @@ -66,8 +66,8 @@ test('before, loading, error, complete and after callbacks should be called in c $('form') .bind('ajax:before', function() { ok(true, 'ajax:before'); return true; }) .bind('ajax:loading', function(arg) { ok(true, 'ajax:loading'); }) - .bind('ajax:failure', function(e, xhr, status, error) { - ok(true, 'ajax:failure'); + .bind('ajax:error', function(e, xhr, status, error) { + ok(true, 'ajax:error'); equals(xhr.status, 403, 'status code should be 403'); }) .bind('ajax:complete', function(arg) { ok(true, 'ajax:complete'); start(); }) From eb8ad739df4916f1f2583ab1ca336cc9fdee97e8 Mon Sep 17 00:00:00 2001 From: Neeraj Singh Date: Tue, 23 Nov 2010 21:17:08 -0500 Subject: [PATCH 018/364] bring clarity to ajax:complete callback documentation --- src/rails.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rails.js b/src/rails.js index e9a42f27..e3420238 100644 --- a/src/rails.js +++ b/src/rails.js @@ -33,7 +33,7 @@ jQuery(function ($) { * - ajax:before - is execute before the whole thing begings * - ajax:loading - is executed before firing ajax call * - ajax:success - is executed when status is success - * - ajax:complete - is execute when status is complete + * - ajax:complete - is executed when the request finishes, whether in failure or success. * - ajax:error - is execute in case of error * - ajax:after - is execute every single time at the end of ajax call */ From 9446379704a65faa0c94b3803bc751740c43fdf1 Mon Sep 17 00:00:00 2001 From: Neeraj Singh Date: Tue, 23 Nov 2010 21:21:00 -0500 Subject: [PATCH 019/364] Since ajax:complete callback is fired when ajax request completes, whether the request ended in success or error. I do not see a need for another callback called ajax:after. --- src/rails.js | 3 --- test/public/test/call-remote-callbacks.js | 14 ++++++-------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/rails.js b/src/rails.js index e3420238..ec401dd7 100644 --- a/src/rails.js +++ b/src/rails.js @@ -35,7 +35,6 @@ jQuery(function ($) { * - ajax:success - is executed when status is success * - ajax:complete - is executed when the request finishes, whether in failure or success. * - ajax:error - is execute in case of error - * - ajax:after - is execute every single time at the end of ajax call */ callRemote: function () { var el = this, @@ -68,8 +67,6 @@ jQuery(function ($) { } }); } - - el.trigger('ajax:after'); } } }); diff --git a/test/public/test/call-remote-callbacks.js b/test/public/test/call-remote-callbacks.js index fcb51a08..26e80a05 100644 --- a/test/public/test/call-remote-callbacks.js +++ b/test/public/test/call-remote-callbacks.js @@ -44,22 +44,21 @@ test('if ajax:before callback returns false then do not proceed', function() { App.short_timeout(); }); -test('before, loading, success, complete and after callbacks should be called', function() { - expect(5); +test('before, loading, success and complete callbacks should be called', function() { + expect(4); stop(App.ajax_timeout); $('form') .bind('ajax:before', function() { ok(true, 'ajax:before'); return true; }) .bind('ajax:loading', function(arg) { ok(true, 'ajax:loading'); }) .bind('ajax:success', function(arg) { ok(true, 'ajax:success'); }) - .bind('ajax:complete', function(arg) { ok(true, 'ajax:complete'); start(); }) - .bind('ajax:after', function() { ok(true, 'ajax:after'); }); + .bind('ajax:complete', function(arg) { ok(true, 'ajax:complete'); start(); }); $('form[data-remote]').trigger('submit'); }); -test('before, loading, error, complete and after callbacks should be called in case of error', function() { - expect(6); +test('before, loading, error and complete callbacks should be called in case of error', function() { + expect(5); $('form').attr('action', App.url('error')); stop(App.ajax_timeout); @@ -70,8 +69,7 @@ test('before, loading, error, complete and after callbacks should be called in c ok(true, 'ajax:error'); equals(xhr.status, 403, 'status code should be 403'); }) - .bind('ajax:complete', function(arg) { ok(true, 'ajax:complete'); start(); }) - .bind('ajax:after', function() { ok(true, 'ajax:after'); }); + .bind('ajax:complete', function(arg) { ok(true, 'ajax:complete'); start(); }); $('form[data-remote]').trigger('submit'); }); From ac94b45fad0fe4b2658e3a0112b89aa65b79e95c Mon Sep 17 00:00:00 2001 From: Neeraj Singh Date: Tue, 23 Nov 2010 21:24:37 -0500 Subject: [PATCH 020/364] jQuery provides callback named beforeSend. jquery-ujs fires ajax:loading for beforeSend. A few times I have been confused if loading is fired after the request has already been made or after. I guess the best solution is to be as close to jQuery as possible. No need to invent new names. This patch changes callback named ajax:loading to ajax:beforeSend. --- src/rails.js | 4 ++-- test/public/test/call-remote-callbacks.js | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/rails.js b/src/rails.js index ec401dd7..3eb9ac97 100644 --- a/src/rails.js +++ b/src/rails.js @@ -31,7 +31,7 @@ jQuery(function ($) { * Handles execution of remote calls. Provides following callbacks: * * - ajax:before - is execute before the whole thing begings - * - ajax:loading - is executed before firing ajax call + * - ajax:beforeSend - is executed before firing ajax call * - ajax:success - is executed when status is success * - ajax:complete - is executed when the request finishes, whether in failure or success. * - ajax:error - is execute in case of error @@ -54,7 +54,7 @@ jQuery(function ($) { type: method.toUpperCase(), beforeSend: function (xhr) { xhr.setRequestHeader("Accept", "text/javascript"); - el.trigger('ajax:loading', xhr); + el.trigger('ajax:beforeSend', xhr); }, success: function (data, status, xhr) { el.trigger('ajax:success', [data, status, xhr]); diff --git a/test/public/test/call-remote-callbacks.js b/test/public/test/call-remote-callbacks.js index 26e80a05..619ed9c2 100644 --- a/test/public/test/call-remote-callbacks.js +++ b/test/public/test/call-remote-callbacks.js @@ -35,7 +35,7 @@ test('if ajax:before callback returns false then do not proceed', function() { $('form') .bind('ajax:before', function() { return false; }) - .bind('ajax:loading', function(){ + .bind('ajax:beforeSend', function(){ ok(false, 'ajax call should not have been made since ajax:before callback returns false'); }); @@ -44,27 +44,27 @@ test('if ajax:before callback returns false then do not proceed', function() { App.short_timeout(); }); -test('before, loading, success and complete callbacks should be called', function() { +test('before, beforeSend, success and complete callbacks should be called', function() { expect(4); stop(App.ajax_timeout); $('form') .bind('ajax:before', function() { ok(true, 'ajax:before'); return true; }) - .bind('ajax:loading', function(arg) { ok(true, 'ajax:loading'); }) + .bind('ajax:beforeSend', function(arg) { ok(true, 'ajax:beforeSend'); }) .bind('ajax:success', function(arg) { ok(true, 'ajax:success'); }) .bind('ajax:complete', function(arg) { ok(true, 'ajax:complete'); start(); }); $('form[data-remote]').trigger('submit'); }); -test('before, loading, error and complete callbacks should be called in case of error', function() { +test('before, beforeSend, error and complete callbacks should be called in case of error', function() { expect(5); $('form').attr('action', App.url('error')); stop(App.ajax_timeout); $('form') .bind('ajax:before', function() { ok(true, 'ajax:before'); return true; }) - .bind('ajax:loading', function(arg) { ok(true, 'ajax:loading'); }) + .bind('ajax:beforeSend', function(arg) { ok(true, 'ajax:loading'); }) .bind('ajax:error', function(e, xhr, status, error) { ok(true, 'ajax:error'); equals(xhr.status, 403, 'status code should be 403'); From 8b9863b285937c08e333e7ded3876732922fdda0 Mon Sep 17 00:00:00 2001 From: Neeraj Singh Date: Sat, 27 Nov 2010 00:01:36 -0500 Subject: [PATCH 021/364] Callback ajax:before is called before any ajax call. jQuery already provides beforeSend callback which jquery-ujs uses to provide ajax:beforeSend callback. Anything can be done in ajax:before can also be done in ajax:beforeSend callback. I have been attempting to get the callbacks in jquery-ujs close to jQuery and this was the last hurdle. --- src/rails.js | 9 +++++---- test/public/test/call-remote-callbacks.js | 20 +++++++++----------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/rails.js b/src/rails.js index 3eb9ac97..3f6bfadb 100644 --- a/src/rails.js +++ b/src/rails.js @@ -45,8 +45,8 @@ jQuery(function ($) { 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() : []; + var $this = $(this), data = el.is('form') ? el.serializeArray() : []; + $.ajax({ url: url, data: data, @@ -54,7 +54,9 @@ jQuery(function ($) { type: method.toUpperCase(), beforeSend: function (xhr) { xhr.setRequestHeader("Accept", "text/javascript"); - el.trigger('ajax:beforeSend', xhr); + if ($this.triggerHandler('ajax:beforeSend') === false) { + return false; + } }, success: function (data, status, xhr) { el.trigger('ajax:success', [data, status, xhr]); @@ -66,7 +68,6 @@ jQuery(function ($) { el.trigger('ajax:error', [xhr, status, error]); } }); - } } } }); diff --git a/test/public/test/call-remote-callbacks.js b/test/public/test/call-remote-callbacks.js index 619ed9c2..e7de5b6e 100644 --- a/test/public/test/call-remote-callbacks.js +++ b/test/public/test/call-remote-callbacks.js @@ -29,14 +29,14 @@ module('call-remote-callbacks', { } }); -test('if ajax:before callback returns false then do not proceed', function() { +test('ajax:beforeSend returns false do not proceed', function() { expect(0); stop(); $('form') - .bind('ajax:before', function() { return false; }) - .bind('ajax:beforeSend', function(){ - ok(false, 'ajax call should not have been made since ajax:before callback returns false'); + .bind('ajax:beforeSend', function() { return false; }) + .bind('ajax:complete', function(){ + ok(false, 'ajax call should not have been made since ajax:beforeSend callback returns false'); }); $('form[data-remote]').trigger('submit'); @@ -44,12 +44,11 @@ test('if ajax:before callback returns false then do not proceed', function() { App.short_timeout(); }); -test('before, beforeSend, success and complete callbacks should be called', function() { - expect(4); +test('beforeSend, success and complete callbacks should be called', function() { + expect(3); stop(App.ajax_timeout); $('form') - .bind('ajax:before', function() { ok(true, 'ajax:before'); return true; }) .bind('ajax:beforeSend', function(arg) { ok(true, 'ajax:beforeSend'); }) .bind('ajax:success', function(arg) { ok(true, 'ajax:success'); }) .bind('ajax:complete', function(arg) { ok(true, 'ajax:complete'); start(); }); @@ -57,14 +56,13 @@ test('before, beforeSend, success and complete callbacks should be called', func $('form[data-remote]').trigger('submit'); }); -test('before, beforeSend, error and complete callbacks should be called in case of error', function() { - expect(5); +test('beforeSend, error and complete callbacks should be called in case of error', function() { + expect(4); $('form').attr('action', App.url('error')); stop(App.ajax_timeout); $('form') - .bind('ajax:before', function() { ok(true, 'ajax:before'); return true; }) - .bind('ajax:beforeSend', function(arg) { ok(true, 'ajax:loading'); }) + .bind('ajax:beforeSend', function(arg) { ok(true, 'ajax:beforeSend'); }) .bind('ajax:error', function(e, xhr, status, error) { ok(true, 'ajax:error'); equals(xhr.status, 403, 'status code should be 403'); From 72d875a8d57c6bb466170980a5142c66ac74e8f0 Mon Sep 17 00:00:00 2001 From: Neeraj Singh Date: Sat, 27 Nov 2010 15:42:46 -0500 Subject: [PATCH 022/364] remove ajax:before from the documentation --- src/rails.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/rails.js b/src/rails.js index 3f6bfadb..4ed98998 100644 --- a/src/rails.js +++ b/src/rails.js @@ -30,7 +30,6 @@ jQuery(function ($) { /** * Handles execution of remote calls. Provides following callbacks: * - * - ajax:before - is execute before the whole thing begings * - ajax:beforeSend - is executed before firing ajax call * - ajax:success - is executed when status is success * - ajax:complete - is executed when the request finishes, whether in failure or success. From 96bd1328856b0a266c2f4cb2c9c3f99fbf2690a2 Mon Sep 17 00:00:00 2001 From: Neeraj Singh Date: Tue, 14 Dec 2010 22:59:13 -0500 Subject: [PATCH 023/364] too many issues regarding https. It is a solved problem. Use the latest version. --- README.rdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rdoc b/README.rdoc index 1ed16791..f4255b53 100644 --- a/README.rdoc +++ b/README.rdoc @@ -22,7 +22,7 @@ rails.js file from v1.4 branch can be accessed at https://github.com/rails/jquer Add this line to your Gemfile: - gem 'jquery-rails' + gem 'jquery-rails', '>= 0.2.6' === Step 2 From 5c5eac8b671c31720f4f29bb4a1a639c8d96ecb4 Mon Sep 17 00:00:00 2001 From: Justin Schier Date: Thu, 9 Dec 2010 13:07:38 +0800 Subject: [PATCH 024/364] Final README clarifications. --- README.rdoc | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/README.rdoc b/README.rdoc index f4255b53..b173c8bb 100644 --- a/README.rdoc +++ b/README.rdoc @@ -45,10 +45,20 @@ Copy rails.js from http://github.com/rails/jquery-ujs/raw/master/src/rails.js in === Step 3 (optional) -Switch the javascript_include_tag :defaults to use jquery instead of the default prototype helpers. Uncomment following line from file config/application.rb +Uncomment following line from file config/application.rb config.action_view.javascript_expansions[:defaults] = %w(jquery rails application) +To load jQuery from a CDN such as Google, just specify the full path. Change the above to + + config.action_view.javascript_expansions[:defaults] = %w(https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js rails application) + +Alternatively, you can specify the exact files to load in app/views/layouts/application.html.erb. Change javascript_include_tag :defaults to use jQuery + <%= javascript_include_tag 'jquery' %> + or + <%= javascript_include_tag 'https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js' %> +instead of the default prototype helpers. + = Testing == Installation From 02d0a7076976c100883c10d35034100c704fbd13 Mon Sep 17 00:00:00 2001 From: Neeraj Singh Date: Wed, 22 Dec 2010 14:56:47 -0500 Subject: [PATCH 025/364] remove TODO --- src/rails.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/rails.js b/src/rails.js index 4ed98998..10b72e1a 100644 --- a/src/rails.js +++ b/src/rails.js @@ -16,9 +16,6 @@ jQuery(function ($) { * 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); From 565ed5e54eada1523b060a2b041fea40671f5c38 Mon Sep 17 00:00:00 2001 From: Neeraj Singh Date: Wed, 22 Dec 2010 14:58:21 -0500 Subject: [PATCH 026/364] formatting --- src/rails.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/rails.js b/src/rails.js index 10b72e1a..3e6d21a8 100644 --- a/src/rails.js +++ b/src/rails.js @@ -27,10 +27,10 @@ jQuery(function ($) { /** * Handles execution of remote calls. Provides following callbacks: * - * - ajax:beforeSend - is executed before firing ajax call - * - ajax:success - is executed when status is success - * - ajax:complete - is executed when the request finishes, whether in failure or success. - * - ajax:error - is execute in case of error + * - ajax:beforeSend - is executed before firing ajax call + * - ajax:success - is executed when status is success + * - ajax:complete - is executed when the request finishes, whether in failure or success + * - ajax:error - is execute in case of error */ callRemote: function () { var el = this, @@ -69,9 +69,8 @@ jQuery(function ($) { }); /** - * confirmation handler + * confirmation handler */ - $('body').delegate('a[data-confirm], button[data-confirm], input[data-confirm]', 'click.rails', function () { var el = $(this); if (el.triggerAndReturn('confirm')) { @@ -153,5 +152,4 @@ jQuery(function ($) { alert('This rails.js does not support the jQuery version you are using. Please read documentation.'); } - }); From cff3fa97168cdac1f124395826bcdff967298f96 Mon Sep 17 00:00:00 2001 From: Neeraj Singh Date: Wed, 22 Dec 2010 14:59:35 -0500 Subject: [PATCH 027/364] do not set accept header. leave the value as is set by browser --- src/rails.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/rails.js b/src/rails.js index 3e6d21a8..6419fd44 100644 --- a/src/rails.js +++ b/src/rails.js @@ -49,7 +49,6 @@ jQuery(function ($) { dataType: dataType, type: method.toUpperCase(), beforeSend: function (xhr) { - xhr.setRequestHeader("Accept", "text/javascript"); if ($this.triggerHandler('ajax:beforeSend') === false) { return false; } From 3fbeaf64f6189fa7449b438a79d7588f71e7c8b4 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Sun, 26 Dec 2010 08:32:40 -0200 Subject: [PATCH 028/364] Remove ^M DOS characters --- src/rails.js | 308 +++++++++++++++++++++++++-------------------------- 1 file changed, 154 insertions(+), 154 deletions(-) diff --git a/src/rails.js b/src/rails.js index 6419fd44..668cffa7 100644 --- a/src/rails.js +++ b/src/rails.js @@ -1,154 +1,154 @@ -/* - * jquery-ujs - * - * http://github.com/rails/jquery-ujs/blob/master/src/rails.js - * - * This rails.js file supports jQuery 1.4.3 and 1.4.4 . - * - */ - -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. - */ - triggerAndReturn: function (name, data) { - var event = new $.Event(name); - this.trigger(event, data); - - return event.result !== false; - }, - - /** - * Handles execution of remote calls. Provides following callbacks: - * - * - ajax:beforeSend - is executed before firing ajax call - * - ajax:success - is executed when status is success - * - ajax:complete - is executed when the request finishes, whether in failure or success - * - ajax:error - is execute in case of error - */ - 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') || ($.ajaxSettings && $.ajaxSettings.dataType); - - if (url === undefined) { - throw "No URL specified for remote call (action or href must be present)."; - } else { - var $this = $(this), data = el.is('form') ? el.serializeArray() : []; - - $.ajax({ - url: url, - data: data, - dataType: dataType, - type: method.toUpperCase(), - beforeSend: function (xhr) { - if ($this.triggerHandler('ajax:beforeSend') === false) { - return false; - } - }, - 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:error', [xhr, status, error]); - } - }); - } - } - }); - - /** - * confirmation handler - */ - $('body').delegate('a[data-confirm], button[data-confirm], input[data-confirm]', 'click.rails', function () { - var el = $(this); - if (el.triggerAndReturn('confirm')) { - if (!confirm(el.attr('data-confirm'))) { - return false; - } - } - }); - - - - /** - * remote handlers - */ - $('form[data-remote]').live('submit.rails', function (e) { - $(this).callRemote(); - e.preventDefault(); - }); - - $('a[data-remote],input[data-remote]').live('click.rails', function (e) { - $(this).callRemote(); - e.preventDefault(); - }); - - /** - * <%= link_to "Delete", user_path(@user), :method => :delete, :confirm => "Are you sure?" %> - * - * Delete - */ - $('a[data-method]:not([data-remote])').live('click.rails', function (e){ - var link = $(this), - href = link.attr('href'), - method = link.attr('data-method'), - form = $('
'), - metadata_input = ''; - - if (csrf_param !== undefined && csrf_token !== undefined) { - metadata_input += ''; - } - - form.hide() - .append(metadata_input) - .appendTo('body'); - - e.preventDefault(); - form.submit(); - }); - - /** - * disable-with handlers - */ - var disable_with_input_selector = 'input[data-disable-with]', - disable_with_form_remote_selector = 'form[data-remote]:has(' + disable_with_input_selector + ')', - 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.rails', disable_with_input_function); - $(disable_with_form_not_remote_selector).live('submit.rails', disable_with_input_function); - - $(disable_with_form_remote_selector).live('ajax:complete.rails', function () { - $(this).find(disable_with_input_selector).each(function () { - var input = $(this); - input.removeAttr('disabled') - .val(input.data('enable-with')); - }); - }); - - var jqueryVersion = $().jquery; - - if (!( (jqueryVersion === '1.4.3') || (jqueryVersion === '1.4.4'))){ - alert('This rails.js does not support the jQuery version you are using. Please read documentation.'); - } - -}); +/* + * jquery-ujs + * + * http://github.com/rails/jquery-ujs/blob/master/src/rails.js + * + * This rails.js file supports jQuery 1.4.3 and 1.4.4 . + * + */ + +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. + */ + triggerAndReturn: function (name, data) { + var event = new $.Event(name); + this.trigger(event, data); + + return event.result !== false; + }, + + /** + * Handles execution of remote calls. Provides following callbacks: + * + * - ajax:beforeSend - is executed before firing ajax call + * - ajax:success - is executed when status is success + * - ajax:complete - is executed when the request finishes, whether in failure or success + * - ajax:error - is execute in case of error + */ + 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') || ($.ajaxSettings && $.ajaxSettings.dataType); + + if (url === undefined) { + throw "No URL specified for remote call (action or href must be present)."; + } else { + var $this = $(this), data = el.is('form') ? el.serializeArray() : []; + + $.ajax({ + url: url, + data: data, + dataType: dataType, + type: method.toUpperCase(), + beforeSend: function (xhr) { + if ($this.triggerHandler('ajax:beforeSend') === false) { + return false; + } + }, + 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:error', [xhr, status, error]); + } + }); + } + } + }); + + /** + * confirmation handler + */ + $('body').delegate('a[data-confirm], button[data-confirm], input[data-confirm]', 'click.rails', function () { + var el = $(this); + if (el.triggerAndReturn('confirm')) { + if (!confirm(el.attr('data-confirm'))) { + return false; + } + } + }); + + + + /** + * remote handlers + */ + $('form[data-remote]').live('submit.rails', function (e) { + $(this).callRemote(); + e.preventDefault(); + }); + + $('a[data-remote],input[data-remote]').live('click.rails', function (e) { + $(this).callRemote(); + e.preventDefault(); + }); + + /** + * <%= link_to "Delete", user_path(@user), :method => :delete, :confirm => "Are you sure?" %> + * + * Delete + */ + $('a[data-method]:not([data-remote])').live('click.rails', function (e){ + var link = $(this), + href = link.attr('href'), + method = link.attr('data-method'), + form = $('
'), + metadata_input = ''; + + if (csrf_param !== undefined && csrf_token !== undefined) { + metadata_input += ''; + } + + form.hide() + .append(metadata_input) + .appendTo('body'); + + e.preventDefault(); + form.submit(); + }); + + /** + * disable-with handlers + */ + var disable_with_input_selector = 'input[data-disable-with]', + disable_with_form_remote_selector = 'form[data-remote]:has(' + disable_with_input_selector + ')', + 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.rails', disable_with_input_function); + $(disable_with_form_not_remote_selector).live('submit.rails', disable_with_input_function); + + $(disable_with_form_remote_selector).live('ajax:complete.rails', function () { + $(this).find(disable_with_input_selector).each(function () { + var input = $(this); + input.removeAttr('disabled') + .val(input.data('enable-with')); + }); + }); + + var jqueryVersion = $().jquery; + + if (!( (jqueryVersion === '1.4.3') || (jqueryVersion === '1.4.4'))){ + alert('This rails.js does not support the jQuery version you are using. Please read documentation.'); + } + +}); From fbbefa0773d791d3a67b7a3bb971c10ca750131b Mon Sep 17 00:00:00 2001 From: Neeraj Singh Date: Tue, 28 Dec 2010 11:49:58 -0500 Subject: [PATCH 029/364] closes #52 The current code by default doest not set any HTTP ACCEPT header since I put in this commit https://github.com/rails/jquery-ujs/commit/cff3fa97168cdac1f124395826bcdff967298f96 Now I am going to assume that you have following code def destroy @user = User.find(params[:id]) @user.destroy respond_to do |format| format.html { redirect_to(users_url) } format.xml { head :ok } format.js { } end end Note that the index page has :remote => true <%= link_to 'Destroy', user, :confirm => 'Are you sure?', :method => :delete, :remote => true %> If you click on Destroy then browser will send
*/*
and format.html will be executed. Your goal is to execute format.js. Add following lines in your javascript right after jquery is loaded. jQuery.ajaxSetup({ beforeSend: function (xhr) { xhr.setRequestHeader("Accept", "text/javascript"); } }); Now format.js will be executed. --- src/rails.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/rails.js b/src/rails.js index 668cffa7..1089647d 100644 --- a/src/rails.js +++ b/src/rails.js @@ -52,6 +52,11 @@ jQuery(function ($) { if ($this.triggerHandler('ajax:beforeSend') === false) { return false; } + // if user has used jQuery.ajaxSetup then call beforeSend callback + var beforeSendGlobalCallback = $.ajaxSettings && $.ajaxSettings.beforeSend; + if (beforeSendGlobalCallback !== undefined) { + beforeSendGlobalCallback(xhr); + } }, success: function (data, status, xhr) { el.trigger('ajax:success', [data, status, xhr]); From 1008c33b3775d6ceb20a1c5d19086eda972d66fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mislav=20Marohni=C4=87?= Date: Thu, 6 Jan 2011 19:58:50 +0100 Subject: [PATCH 030/364] rake tasks for testing E.g. shotgun-powered reloadable server: $ rake test:reloadable If you don't want to use this, install the bundle without it: $ bundle install --without reloadable --- Gemfile | 7 ++++--- Gemfile.lock | 16 ++++++++++++++-- Rakefile | 47 +++++++++++++++++++++++++++++++++++++++++++++++ test/config.ru | 3 +++ 4 files changed, 68 insertions(+), 5 deletions(-) create mode 100644 Rakefile create mode 100644 test/config.ru diff --git a/Gemfile b/Gemfile index d1793e4c..e32e523b 100644 --- a/Gemfile +++ b/Gemfile @@ -1,5 +1,6 @@ source 'http://rubygems.org' -gem "json" - -gem "sinatra", "= 1.0" +gem 'sinatra', '~> 1.0' +gem 'shotgun', :group => :reloadable +gem 'thin', :group => :reloadable +gem 'json' diff --git a/Gemfile.lock b/Gemfile.lock index 4d10d04d..42460e58 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,14 +1,26 @@ GEM remote: http://rubygems.org/ specs: + daemons (1.1.0) + eventmachine (0.12.10) json (1.4.6) rack (1.2.1) - sinatra (1.0) + shotgun (0.8) rack (>= 1.0) + sinatra (1.1.2) + rack (~> 1.1) + tilt (~> 1.2) + thin (1.2.7) + daemons (>= 1.0.9) + eventmachine (>= 0.12.6) + rack (>= 1.0.0) + tilt (1.2.1) PLATFORMS ruby DEPENDENCIES json - sinatra (= 1.0) + shotgun + sinatra (~> 1.0) + thin diff --git a/Rakefile b/Rakefile new file mode 100644 index 00000000..e0e44e67 --- /dev/null +++ b/Rakefile @@ -0,0 +1,47 @@ +desc %(Starts the test server and opens it in a web browser) +multitask :default => ['test:server', 'test:open'] + +PORT = 4567 + +namespace :test do + desc %(Starts the test server) + task :server do + system 'bundle exec ruby test/server.rb' + end + + desc %(Starts the test server which reloads everything on each refresh) + task :reloadable do + exec "bundle exec shotgun test/config.ru -p #{PORT} --server thin" + end + + task :open do + url = "http://localhost:#{PORT}" + puts "Opening test app at #{url} ..." + sleep 3 + system( *browse_cmd(url) ) + end +end + +# Returns an array e.g.: ['open', 'http://example.com'] +def browse_cmd(url) + require 'rbconfig' + browser = ENV['BROWSER'] || + (RbConfig::CONFIG['host_os'].include?('darwin') && 'open') || + (RbConfig::CONFIG['host_os'] =~ /msdos|mswin|djgpp|mingw|windows/ && 'start') || + %w[xdg-open x-www-browser firefox opera mozilla netscape].find { |comm| which comm } + + abort('ERROR: no web browser detected') unless browser + Array(browser) << url +end + +# which('ruby') #=> /usr/bin/ruby +def which cmd + exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : [''] + ENV['PATH'].split(File::PATH_SEPARATOR).each do |path| + exts.each { |ext| + exe = "#{path}/#{cmd}#{ext}" + return exe if File.executable? exe + } + end + return nil +end diff --git a/test/config.ru b/test/config.ru new file mode 100644 index 00000000..44fb4f03 --- /dev/null +++ b/test/config.ru @@ -0,0 +1,3 @@ +$LOAD_PATH.unshift File.expand_path('..', __FILE__) +require 'server' +run Sinatra::Application From 74aad2687be8cdd97d1fa5442998ab0edebce490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mislav=20Marohni=C4=87?= Date: Thu, 6 Jan 2011 20:01:00 +0100 Subject: [PATCH 031/364] refactor the test server & HTML layout Changes: - configure the server to return application/json for JSON responses - remove jQuery version-specific routes - remove the super-ugly hack of copying "src/rails.js" under the "test" directory - fix test suite when running on port other than 4567 --- test/public/test/call-remote.js | 12 ++--- test/public/test/data-confirm.js | 4 +- test/public/test/data-remote.js | 6 +-- test/public/test/settings.js | 12 +---- test/public/{ => vendor}/qunit.css | 0 test/server.rb | 85 ++++++++++++++++-------------- test/views/iframe.erb | 27 +++------- test/views/iframe_csrf.erb | 16 ------ test/views/index.erb | 63 +++++++--------------- test/views/layout.erb | 23 ++++++++ 10 files changed, 107 insertions(+), 141 deletions(-) rename test/public/{ => vendor}/qunit.css (100%) delete mode 100644 test/views/iframe_csrf.erb create mode 100644 test/views/layout.erb diff --git a/test/public/test/call-remote.js b/test/public/test/call-remote.js index 3e707527..a5c9b058 100644 --- a/test/public/test/call-remote.js +++ b/test/public/test/call-remote.js @@ -35,7 +35,7 @@ test('method should be picked up from method attribute and not from data-method' $('form[data-remote]') .live('ajax:success', function(e, data, status, xhr) { App.assert_callback_invoked('ajax:success'); - var request_env = $.parseJSON(data)['request_env']; + var request_env = data.request_env; App.assert_post_request(request_env); start(); @@ -56,7 +56,7 @@ test('method should be picked up from data-method attribute if method is missing $('form[data-remote]') .live('ajax:success', function(e, data, status, xhr) { App.assert_callback_invoked('ajax:success'); - var request_env = $.parseJSON(data)['request_env']; + var request_env = data.request_env; App.assert_post_request(request_env); start(); @@ -76,7 +76,7 @@ test('default method GET should be picked up if no method or data-method is supp $('form[data-remote]') .live('ajax:success', function(e, data, status, xhr) { App.assert_callback_invoked('ajax:success'); - var request_env = $.parseJSON(data)['request_env']; + var request_env = data.request_env; App.assert_get_request(request_env); start(); @@ -96,7 +96,7 @@ test('url should be picked up from action', function() { $('form[data-remote]') .live('ajax:success', function(e, data, status, xhr) { App.assert_callback_invoked('ajax:success'); - var request_env = $.parseJSON(data)['request_env']; + var request_env = data.request_env; App.assert_request_path(request_env, '/show'); start(); @@ -116,7 +116,7 @@ test('url should be picked up from action if both action and href are mentioned $('form[data-remote]') .live('ajax:success', function(e, data, status, xhr) { App.assert_callback_invoked('ajax:success'); - var request_env = $.parseJSON(data)['request_env']; + var request_env = data.request_env; App.assert_request_path(request_env, '/show'); start(); @@ -136,7 +136,7 @@ test('url should be picked up from href if no action is provided', function() { $('form[data-remote]') .live('ajax:success', function(e, data, status, xhr) { App.assert_callback_invoked('ajax:success'); - var request_env = $.parseJSON(data)['request_env']; + var request_env = data.request_env; App.assert_request_path(request_env, '/show'); start(); diff --git a/test/public/test/data-confirm.js b/test/public/test/data-confirm.js index f6249ed5..21243aa5 100644 --- a/test/public/test/data-confirm.js +++ b/test/public/test/data-confirm.js @@ -46,7 +46,7 @@ test('clicking on a link with data-confirm attribute. Confirm yes.', function() $('a[data-confirm]') .live('ajax:success', function(e, data, status, xhr) { App.assert_callback_invoked('ajax:success'); - var request_env = $.parseJSON(data)['request_env']; + var request_env = data.request_env; App.assert_request_path(request_env, '/show'); App.assert_get_request(request_env); @@ -98,7 +98,7 @@ test('clicking on Submit input tag with data-confirm attribute. Confirm yes.', f $('input[data-confirm]') .live('ajax:success', function(e, data, status, xhr) { App.assert_callback_invoked('ajax:success'); - var request_env = $.parseJSON(data)['request_env']; + var request_env = data.request_env; App.assert_request_path(request_env, '/show'); App.assert_get_request(request_env); diff --git a/test/public/test/data-remote.js b/test/public/test/data-remote.js index cc64c8fa..b51affd8 100644 --- a/test/public/test/data-remote.js +++ b/test/public/test/data-remote.js @@ -43,7 +43,7 @@ test('clicking on a link with data-remote attribute', function() { $('a[data-remote]') .live('ajax:success', function(e, data, status, xhr) { App.assert_callback_invoked('ajax:success'); - var request_env = $.parseJSON(data)['request_env']; + var request_env = data.request_env; App.assert_request_path(request_env, '/show'); App.assert_get_request(request_env); @@ -60,7 +60,7 @@ test('clicking on Submit input tag with data-remote attribute', function() { .live('ajax:success', function(e, data, status, xhr) { App.assert_callback_invoked('ajax:success'); - var request_env = $.parseJSON(data)['request_env']; + var request_env = data.request_env; App.assert_request_path(request_env, '/show'); App.assert_get_request(request_env); @@ -78,7 +78,7 @@ test('Submitting form with data-remote attribute', function() { .live('ajax:success', function(e, data, status, xhr) { App.assert_callback_invoked('ajax:success'); - var request_env = $.parseJSON(data)['request_env'], + var request_env = data.request_env, params = request_env['rack.request.query_hash']; App.assert_request_path(request_env, '/update'); diff --git a/test/public/test/settings.js b/test/public/test/settings.js index ffccadbd..006da678 100644 --- a/test/public/test/settings.js +++ b/test/public/test/settings.js @@ -1,19 +1,11 @@ var App = App || {}; - -// ######## SETTINGS ################################### App.host = 'http://localhost'; App.port = 4567; -App.ajax_timeout = 5000; - - -// -// ######## helper methods ########################### -// -App.base_url = App.host + ':' + App.port; +App.ajax_timeout = 1000; App.url = function(url) { - return App.base_url + '/' + url; + return App.host + ':' + App.port + '/' + url; }; App.confirmation_message = 'Are you absolutely sure?'; diff --git a/test/public/qunit.css b/test/public/vendor/qunit.css similarity index 100% rename from test/public/qunit.css rename to test/public/vendor/qunit.css diff --git a/test/server.rb b/test/server.rb index 2816797e..bab4d74d 100644 --- a/test/server.rb +++ b/test/server.rb @@ -1,66 +1,69 @@ -require 'rubygems' require 'sinatra' require 'json' -require 'fileutils' -# copy rails.js file from src to vendor directory -source_file = File.join( File.dirname(__FILE__) , '..', 'src', 'rails.js') -dest_file = File.join(File.dirname(__FILE__), 'public', 'vendor', 'rails.js') -FileUtils.cp(source_file, dest_file) - -after do - content_type 'text/html', :charset => 'utf-8' -end - -get '/' do - FileUtils.cp(source_file, dest_file) - params[:version] ||= '1.4.4' - erb :index -end - -get '/jquery/:version' do - FileUtils.cp(source_file, dest_file) - erb :index -end +use Rack::Static, :urls => ["/src"], :root => File.expand_path('..', settings.root) helpers do def jquery_link version if params[:version] == version "[#{version}]" else - "#{version}" + "#{version}" end end -end - -get '/show' do - if request.xhr? - {:hello => :sexy, :request_env => request.env}.to_json - else - '/show requested without ajax' + + def jquery_src + "http://code.jquery.com/jquery-#{params[:version]}.js" + end + + def test *names + names = ["/vendor/qunit.js", "settings"] + names + names.map { |name| script_tag name }.join("\n") + end + + def script_tag src + src = "/test/#{src}.js" unless src.index('/') + %() + end + + def ajax_json_or_error + if request.xhr? + content_type 'application/json' + data = yield + String === data ? data : data.to_json + else + content_type 'text/plain' + status 400 + "#{request.path} requested without ajax" + end end end -get '/error' do - status 403 +get '/' do + params[:version] ||= '1.4.4' + erb :index end -post '/update' do - if request.xhr? - {:hello => :sexy, :request_env => request.env}.to_json - else - '/update requested without ajax' - end +get '/iframe' do + erb :iframe end -get '/iframe/:version' do - erb :iframe +get '/show' do + ajax_json_or_error do + { :hello => :sexy, :request_env => request.env } + end end -get '/iframe-csrf/:version' do - erb :iframe_csrf +post '/update' do + ajax_json_or_error do + { :hello => :sexy, :request_env => request.env } + end end delete '/delete' do "/delete was invoked with delete verb. params is #{params.inspect}" end + +get '/error' do + status 403 +end diff --git a/test/views/iframe.erb b/test/views/iframe.erb index 3c5536da..83b1d631 100644 --- a/test/views/iframe.erb +++ b/test/views/iframe.erb @@ -1,22 +1,9 @@ - - - - jquery-ujs iframe - - - - - - +<% @title = "jquery-ujs iframe" %> - +<%= test 'data-method-iframe' %> - -
- - - - + +
diff --git a/test/views/iframe_csrf.erb b/test/views/iframe_csrf.erb deleted file mode 100644 index 9c12b75d..00000000 --- a/test/views/iframe_csrf.erb +++ /dev/null @@ -1,16 +0,0 @@ - - - - jquery-ujs iframe - - - - - - - - - -
- - diff --git a/test/views/index.erb b/test/views/index.erb index 21d34bf9..ae604930 100644 --- a/test/views/index.erb +++ b/test/views/index.erb @@ -1,50 +1,27 @@ - - - - jquery-ujs test - - - - - +<% @title = "jquery-ujs test" %> - - - - - - - - +<%= test 'data-confirm', 'data-remote', 'data-disable', 'call-remote', 'call-remote-callbacks', 'data-method' %> - -

- jquery-ujs test - <%= jquery_link '1.4.3' %> - <%= jquery_link '1.4.4' %> -

-

-

- -
    +

    + jquery-ujs test + <%= jquery_link '1.4.3' %> + <%= jquery_link '1.4.4' %> +

    +

    +

    -
    +
      -
      - -
      +
      -
      - -
      +
      + +
      -
      +
      + +
      - - - +
      diff --git a/test/views/layout.erb b/test/views/layout.erb new file mode 100644 index 00000000..e727eb6e --- /dev/null +++ b/test/views/layout.erb @@ -0,0 +1,23 @@ + + + + <%= @title %> + + + + <% if params[:csrf] %> + + + <% end %> + + <%= script_tag jquery_src %> + <%= script_tag "/src/rails.js" %> + + + + <%= yield %> + + From 9d77cb79d46fe5f31d3d09654f93a0def8696247 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mislav=20Marohni=C4=87?= Date: Fri, 7 Jan 2011 12:14:53 +0100 Subject: [PATCH 032/364] whitespace: convert indentation to tabs --- src/rails.js | 284 +++++++++++++++++++++++++-------------------------- 1 file changed, 140 insertions(+), 144 deletions(-) diff --git a/src/rails.js b/src/rails.js index 1089647d..cdb92e34 100644 --- a/src/rails.js +++ b/src/rails.js @@ -7,150 +7,146 @@ * */ -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. - */ - triggerAndReturn: function (name, data) { - var event = new $.Event(name); - this.trigger(event, data); - - return event.result !== false; - }, - - /** - * Handles execution of remote calls. Provides following callbacks: - * - * - ajax:beforeSend - is executed before firing ajax call - * - ajax:success - is executed when status is success - * - ajax:complete - is executed when the request finishes, whether in failure or success - * - ajax:error - is execute in case of error - */ - 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') || ($.ajaxSettings && $.ajaxSettings.dataType); - - if (url === undefined) { - throw "No URL specified for remote call (action or href must be present)."; - } else { - var $this = $(this), data = el.is('form') ? el.serializeArray() : []; - - $.ajax({ - url: url, - data: data, - dataType: dataType, - type: method.toUpperCase(), - beforeSend: function (xhr) { - if ($this.triggerHandler('ajax:beforeSend') === false) { - return false; - } - // if user has used jQuery.ajaxSetup then call beforeSend callback - var beforeSendGlobalCallback = $.ajaxSettings && $.ajaxSettings.beforeSend; - if (beforeSendGlobalCallback !== undefined) { - beforeSendGlobalCallback(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:error', [xhr, status, error]); - } - }); - } - } - }); - - /** - * confirmation handler - */ - $('body').delegate('a[data-confirm], button[data-confirm], input[data-confirm]', 'click.rails', function () { - var el = $(this); - if (el.triggerAndReturn('confirm')) { - if (!confirm(el.attr('data-confirm'))) { - return false; - } - } - }); - - - - /** - * remote handlers - */ - $('form[data-remote]').live('submit.rails', function (e) { - $(this).callRemote(); - e.preventDefault(); - }); - - $('a[data-remote],input[data-remote]').live('click.rails', function (e) { - $(this).callRemote(); - e.preventDefault(); - }); - - /** - * <%= link_to "Delete", user_path(@user), :method => :delete, :confirm => "Are you sure?" %> - * - * Delete - */ - $('a[data-method]:not([data-remote])').live('click.rails', function (e){ - var link = $(this), - href = link.attr('href'), - method = link.attr('data-method'), - form = $('
      '), - metadata_input = ''; - - if (csrf_param !== undefined && csrf_token !== undefined) { - metadata_input += ''; - } - - form.hide() - .append(metadata_input) - .appendTo('body'); - - e.preventDefault(); - form.submit(); - }); - - /** - * disable-with handlers - */ - var disable_with_input_selector = 'input[data-disable-with]', - disable_with_form_remote_selector = 'form[data-remote]:has(' + disable_with_input_selector + ')', - 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.rails', disable_with_input_function); - $(disable_with_form_not_remote_selector).live('submit.rails', disable_with_input_function); - - $(disable_with_form_remote_selector).live('ajax:complete.rails', function () { - $(this).find(disable_with_input_selector).each(function () { - var input = $(this); - input.removeAttr('disabled') - .val(input.data('enable-with')); - }); - }); - - var jqueryVersion = $().jquery; +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. + */ + triggerAndReturn: function(name, data) { + var event = new $.Event(name); + this.trigger(event, data); + + return event.result !== false; + }, + + /** + * Handles execution of remote calls. Provides following callbacks: + * + * - ajax:beforeSend - is executed before firing ajax call + * - ajax:success - is executed when status is success + * - ajax:complete - is executed when the request finishes, whether in failure or success + * - ajax:error - is execute in case of error + */ + 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') || ($.ajaxSettings && $.ajaxSettings.dataType); + + if (url === undefined) { + throw "No URL specified for remote call (action or href must be present)."; + } else { + var $this = $(this), data = el.is('form') ? el.serializeArray() : []; + + $.ajax({ + url: url, + data: data, + dataType: dataType, + type: method.toUpperCase(), + beforeSend: function(xhr) { + if ($this.triggerHandler('ajax:beforeSend') === false) { + return false; + } + + // if user has used jQuery.ajaxSetup then call beforeSend callback + var beforeSendGlobalCallback = $.ajaxSettings && $.ajaxSettings.beforeSend; + if (beforeSendGlobalCallback !== undefined) { + beforeSendGlobalCallback(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:error', [xhr, status, error]); + } + }); + } + } + }); + + /** + * confirmation handler + */ + $('body').delegate('a[data-confirm], button[data-confirm], input[data-confirm]', 'click.rails', function() { + var el = $(this); + if (el.triggerAndReturn('confirm')) { + if (!confirm(el.attr('data-confirm'))) { + return false; + } + } + }); + + /** + * remote handlers + */ + $('form[data-remote]').live('submit.rails', function(e) { + $(this).callRemote(); + e.preventDefault(); + }); + + $('a[data-remote],input[data-remote]').live('click.rails', function(e) { + $(this).callRemote(); + e.preventDefault(); + }); + + /** + * <%= link_to "Delete", user_path(@user), :method => :delete, :confirm => "Are you sure?" %> + * + * Delete + */ + $('a[data-method]:not([data-remote])').live('click.rails', function(e) { + var link = $(this), + href = link.attr('href'), + method = link.attr('data-method'), + form = $('
      '), + metadata_input = ''; + + if (csrf_param !== undefined && csrf_token !== undefined) { + metadata_input += ''; + } + + form.hide().append(metadata_input).appendTo('body'); + + e.preventDefault(); + form.submit(); + }); + + /** + * disable-with handlers + */ + var disable_with_input_selector = 'input[data-disable-with]', + disable_with_form_remote_selector = 'form[data-remote]:has(' + disable_with_input_selector + ')', + 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.rails', disable_with_input_function); + $(disable_with_form_not_remote_selector).live('submit.rails', disable_with_input_function); + + $(disable_with_form_remote_selector).live('ajax:complete.rails', function() { + $(this).find(disable_with_input_selector).each(function() { + var input = $(this); + input.removeAttr('disabled').val(input.data('enable-with')); + }); + }); + + var jqueryVersion = $().jquery; if (!( (jqueryVersion === '1.4.3') || (jqueryVersion === '1.4.4'))){ alert('This rails.js does not support the jQuery version you are using. Please read documentation.'); From b4cd9c351cf7a873514669d4730d0a49f84c8218 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mislav=20Marohni=C4=87?= Date: Fri, 7 Jan 2011 12:27:59 +0100 Subject: [PATCH 033/364] remove jQuery version check It's silly. Users should read the docs. Also, the version check would fail for every new version of jQuery. --- src/rails.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/rails.js b/src/rails.js index cdb92e34..9f43d92f 100644 --- a/src/rails.js +++ b/src/rails.js @@ -145,11 +145,4 @@ jQuery(function($) { input.removeAttr('disabled').val(input.data('enable-with')); }); }); - - var jqueryVersion = $().jquery; - - if (!( (jqueryVersion === '1.4.3') || (jqueryVersion === '1.4.4'))){ - alert('This rails.js does not support the jQuery version you are using. Please read documentation.'); - } - }); From b95f1ed91033df3fd38ca558732004e526e8838c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mislav=20Marohni=C4=87?= Date: Fri, 7 Jan 2011 12:46:12 +0100 Subject: [PATCH 034/364] ability to test against an edge version of jQuery simply put jQuery in "test/public/test/jquery.js" and select "edge" in the header --- .gitignore | 2 +- test/server.rb | 4 +++- test/views/index.erb | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 50880aa7..3330f6be 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -test/public/vendor/rails.js +test/public/vendor/jquery.js *.swp *.swo .#* diff --git a/test/server.rb b/test/server.rb index bab4d74d..ea821e0f 100644 --- a/test/server.rb +++ b/test/server.rb @@ -13,7 +13,9 @@ def jquery_link version end def jquery_src - "http://code.jquery.com/jquery-#{params[:version]}.js" + if params[:version] == 'edge' then "/vendor/jquery.js" + else "http://code.jquery.com/jquery-#{params[:version]}.js" + end end def test *names diff --git a/test/views/index.erb b/test/views/index.erb index ae604930..90497bde 100644 --- a/test/views/index.erb +++ b/test/views/index.erb @@ -6,6 +6,7 @@ jquery-ujs test <%= jquery_link '1.4.3' %> <%= jquery_link '1.4.4' %> + <%= jquery_link 'edge' if File.exist?(settings.root + '/public/vendor/jquery.js') %>

      From 429866a6acd64d086dbec9ec3fcb49d96f4ad885 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mislav=20Marohni=C4=87?= Date: Fri, 7 Jan 2011 13:10:36 +0100 Subject: [PATCH 035/364] prettier jquery version links --- test/views/index.erb | 6 ++++-- test/views/layout.erb | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/test/views/index.erb b/test/views/index.erb index 90497bde..5f9d03bf 100644 --- a/test/views/index.erb +++ b/test/views/index.erb @@ -4,9 +4,11 @@

      jquery-ujs test - <%= jquery_link '1.4.3' %> - <%= jquery_link '1.4.4' %> + — + <%= jquery_link '1.4.3' %> • + <%= jquery_link '1.4.4' %> • <%= jquery_link 'edge' if File.exist?(settings.root + '/public/vendor/jquery.js') %> +

      diff --git a/test/views/layout.erb b/test/views/layout.erb index e727eb6e..4801e7c8 100644 --- a/test/views/layout.erb +++ b/test/views/layout.erb @@ -6,6 +6,7 @@ <% if params[:csrf] %> From adbd972dbc20085190d6718edf99d5280f6bdfeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mislav=20Marohni=C4=87?= Date: Fri, 7 Jan 2011 13:11:00 +0100 Subject: [PATCH 036/364] remove unused fixture settings --- test/views/index.erb | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/views/index.erb b/test/views/index.erb index 5f9d03bf..a7d08239 100644 --- a/test/views/index.erb +++ b/test/views/index.erb @@ -26,5 +26,3 @@ - -
      From 51272c68714748420d8c35984b3e2532ab14f748 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mislav=20Marohni=C4=87?= Date: Fri, 7 Jan 2011 14:19:00 +0100 Subject: [PATCH 037/364] rails.js doesn't have to wait until DOM ready --- src/rails.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/rails.js b/src/rails.js index 9f43d92f..9674415c 100644 --- a/src/rails.js +++ b/src/rails.js @@ -7,10 +7,7 @@ * */ -jQuery(function($) { - var csrf_token = $('meta[name=csrf-token]').attr('content'), - csrf_param = $('meta[name=csrf-param]').attr('content'); - +(function($) { $.fn.extend({ /** * Triggers a custom event on an element and returns the event result @@ -76,7 +73,7 @@ jQuery(function($) { /** * confirmation handler */ - $('body').delegate('a[data-confirm], button[data-confirm], input[data-confirm]', 'click.rails', function() { + $('a[data-confirm], button[data-confirm], input[data-confirm]').live('click.rails', function() { var el = $(this); if (el.triggerAndReturn('confirm')) { if (!confirm(el.attr('data-confirm'))) { @@ -107,6 +104,8 @@ jQuery(function($) { var link = $(this), href = link.attr('href'), method = link.attr('data-method'), + csrf_token = $('meta[name=csrf-token]').attr('content'), + csrf_param = $('meta[name=csrf-param]').attr('content'), form = $('
      '), metadata_input = ''; @@ -145,4 +144,4 @@ jQuery(function($) { input.removeAttr('disabled').val(input.data('enable-with')); }); }); -}); +})( jQuery ); From 498b35e24cdb14f2d94486e8a1f4a1f661091426 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mislav=20Marohni=C4=87?= Date: Fri, 7 Jan 2011 18:10:31 +0100 Subject: [PATCH 038/364] small test overhaul: "/echo" resource, remote forms Changes: - replace "/show", "/update" actions with "/echo" - changed some expectations about "remote" form method lookup - stop using unnecessary `App.url()` --- test/public/test/call-remote-callbacks.js | 101 +++++++--------- test/public/test/call-remote.js | 135 +++++---------------- test/public/test/data-confirm.js | 138 +++++++++++----------- test/public/test/data-disable.js | 98 +++++++-------- test/public/test/data-method-iframe.js | 2 +- test/public/test/data-method.js | 26 ++-- test/public/test/data-remote.js | 66 +++++------ test/public/test/settings.js | 11 -- test/server.rb | 20 ++-- 9 files changed, 246 insertions(+), 351 deletions(-) diff --git a/test/public/test/call-remote-callbacks.js b/test/public/test/call-remote-callbacks.js index e7de5b6e..b0935928 100644 --- a/test/public/test/call-remote-callbacks.js +++ b/test/public/test/call-remote-callbacks.js @@ -1,75 +1,56 @@ -var App = App || {}; - -App.build_form = function(opt) { - var defaults = { - 'data-remote': 'true' - }; - - var options = $.extend(defaults, opt); - - $('#fixtures').append($('
      ', options)); - - $('form').append($('', { - id: 'user_name', - type: 'text', - size: '30', - 'name': 'user_name', - 'value': 'john' - })); -}; +(function(){ module('call-remote-callbacks', { - - teardown: App.teardown, - - setup: function() { - App.build_form({ - 'action': App.url('show') - }); - } + setup: function() { + $('#fixtures').append($('', { + action: '/echo', method: 'get', 'data-remote': 'true' + })); + }, + teardown: App.teardown }); -test('ajax:beforeSend returns false do not proceed', function() { - expect(0); - stop(); - - $('form') - .bind('ajax:beforeSend', function() { return false; }) +function submit(fn) { + stop(App.ajax_timeout); + + var form = $('form') .bind('ajax:complete', function(){ - ok(false, 'ajax call should not have been made since ajax:beforeSend callback returns false'); + ok(true, 'ajax:complete'); + start(); }); + + if (fn) fn(form); + form.trigger('submit'); +} - $('form[data-remote]').trigger('submit'); - - App.short_timeout(); +test('stopping the "ajax:beforeSend" event aborts the request', function() { + expect(0); + submit(function(form) { + form.bind('ajax:beforeSend', function() { return false }); + form.unbind('ajax:complete').bind('ajax:complete', function() { + ok(false, 'ajax:complete should not run'); + }); + }); + setTimeout(function(){ start() }, 200); }); -test('beforeSend, success and complete callbacks should be called', function() { - expect(3); - stop(App.ajax_timeout); - - $('form') - .bind('ajax:beforeSend', function(arg) { ok(true, 'ajax:beforeSend'); }) - .bind('ajax:success', function(arg) { ok(true, 'ajax:success'); }) - .bind('ajax:complete', function(arg) { ok(true, 'ajax:complete'); start(); }); - - $('form[data-remote]').trigger('submit'); +test('"ajax:beforeSend", "ajax:success" and "ajax:complete" are triggered', function() { + expect(3); + submit(function(form) { + form.bind('ajax:beforeSend', function(arg) { ok(true, 'ajax:beforeSend') }); + form.bind('ajax:success', function(arg) { ok(true, 'ajax:success') }); + }); }); -test('beforeSend, error and complete callbacks should be called in case of error', function() { - expect(4); - $('form').attr('action', App.url('error')); - stop(App.ajax_timeout); - - $('form') - .bind('ajax:beforeSend', function(arg) { ok(true, 'ajax:beforeSend'); }) - .bind('ajax:error', function(e, xhr, status, error) { +test('"ajax:beforeSend", "ajax:error" and "ajax:complete" are triggered on error', function() { + expect(4); + submit(function(form) { + form.attr('action', '/error'); + form.bind('ajax:beforeSend', function(arg) { ok(true, 'ajax:beforeSend') }); + form.bind('ajax:error', function(e, xhr, status, error) { ok(true, 'ajax:error'); equals(xhr.status, 403, 'status code should be 403'); - }) - .bind('ajax:complete', function(arg) { ok(true, 'ajax:complete'); start(); }); - - $('form[data-remote]').trigger('submit'); + }); + }); }); - +})(); diff --git a/test/public/test/call-remote.js b/test/public/test/call-remote.js index a5c9b058..9b69d51b 100644 --- a/test/public/test/call-remote.js +++ b/test/public/test/call-remote.js @@ -1,181 +1,110 @@ -var App = App || {}; +(function(){ -App.build_form = function(opt) { +function build_form(attrs) { + attrs = $.extend({ action: '/echo', 'data-remote': 'true' }, attrs); - var defaults = { - 'data-remote': 'true' - }; + $('#fixtures').append($('', attrs)); - var options = $.extend(defaults, opt); - - $('#fixtures').append($('', options)); - - $('#fixtures form').append($('', { - id: 'user_name', - type: 'text', - size: '30', - 'name': 'user_name', - 'value': 'john' - })); + $('#fixtures form').append($('', { + id: 'user_name', + type: 'text', + size: '30', + 'name': 'user_name', + 'value': 'john' + })); }; module('call-remote', { teardown: App.teardown }); -test('method should be picked up from method attribute and not from data-method', function() { +test('form method is read from "method" and not from "data-method"', function() { expect(2); - App.build_form({ - 'method': 'post', - 'data-method': 'get', - 'action': App.url('update') - }); + build_form({ method: 'post', 'data-method': 'get' }); stop(App.ajax_timeout); $('form[data-remote]') .live('ajax:success', function(e, data, status, xhr) { App.assert_callback_invoked('ajax:success'); - var request_env = data.request_env; - App.assert_post_request(request_env); - - start(); - }) - .trigger('submit'); -}); - -test('method should be picked up from data-method attribute if method is missing', function() { - expect(2); - - App.build_form({ - 'data-method': 'post', - 'action': App.url('update') - }); - - stop(App.ajax_timeout); - - $('form[data-remote]') - .live('ajax:success', function(e, data, status, xhr) { - App.assert_callback_invoked('ajax:success'); - var request_env = data.request_env; - App.assert_post_request(request_env); - + App.assert_post_request(data.request_env); start(); }) .trigger('submit'); }); -test('default method GET should be picked up if no method or data-method is supplied', function() { +test('form method is not read from "data-method" attribute in case of missing "method"', function() { expect(2); - - App.build_form({ - action: App.url('show') - }); - + build_form({ 'data-method': 'put' }); stop(App.ajax_timeout); $('form[data-remote]') .live('ajax:success', function(e, data, status, xhr) { App.assert_callback_invoked('ajax:success'); - var request_env = data.request_env; - App.assert_get_request(request_env); + App.assert_post_request(data.request_env); start(); }) .trigger('submit'); }); -test('url should be picked up from action', function() { +test('form default method is POST', function() { expect(2); - - App.build_form({ - 'action': App.url('show') - }); - + build_form(); stop(App.ajax_timeout); $('form[data-remote]') .live('ajax:success', function(e, data, status, xhr) { App.assert_callback_invoked('ajax:success'); - var request_env = data.request_env; - App.assert_request_path(request_env, '/show'); - + App.assert_post_request(data.request_env); start(); }) .trigger('submit'); }); -test('url should be picked up from action if both action and href are mentioned ', function() { +test('form url is picked up from "action"', function() { expect(2); - - App.build_form({ - 'action': App.url('show'), - 'href': 'http://example.org' - }); + build_form(); stop(App.ajax_timeout); $('form[data-remote]') .live('ajax:success', function(e, data, status, xhr) { App.assert_callback_invoked('ajax:success'); - var request_env = data.request_env; - App.assert_request_path(request_env, '/show'); - + App.assert_request_path(data.request_env, '/echo'); start(); }) .trigger('submit'); }); -test('url should be picked up from href if no action is provided', function() { +test('form url is read from "action" not "href"', function() { expect(2); - - App.build_form({ - 'href': App.url('show') - }); + build_form({ href: '/echo2' }); stop(App.ajax_timeout); - $('form[data-remote]') .live('ajax:success', function(e, data, status, xhr) { App.assert_callback_invoked('ajax:success'); - var request_env = data.request_env; - App.assert_request_path(request_env, '/show'); - + App.assert_request_path(data.request_env, '/echo'); start(); }) .trigger('submit'); }); -test('exception should be thrown if both action and url are missing', function() { - expect(1); - var exception_was_raised = false; - - App.build_form({}); - - try { - $('form[data-remote]').trigger('submit'); - } catch(err) { - exception_was_raised = true; - } - - ok(exception_was_raised, 'exception should have been raised'); -}); - -test('data should be availabe in JSON format if datat-type is json', function() { +test('data should be availabe in JSON format if data-type is json', function() { expect(2); - App.build_form({ + build_form({ 'method': 'post', 'data-method': 'get', - 'data-type': 'json', - 'action': App.url('update') + 'data-type': 'json' }); stop(App.ajax_timeout); $('form[data-remote]') .live('ajax:success', function(e, data, status, xhr) { App.assert_callback_invoked('ajax:success'); - var request_env = data['request_env']; - App.assert_post_request(request_env); - + App.assert_post_request(data.request_env); start(); }) .trigger('submit'); }); + +})(); diff --git a/test/public/test/data-confirm.js b/test/public/test/data-confirm.js index 21243aa5..a1016933 100644 --- a/test/public/test/data-confirm.js +++ b/test/public/test/data-confirm.js @@ -2,52 +2,52 @@ module('data-confirm', { teardown: App.teardown, - setup: function() { - - $('#fixtures').append($('', { - href: App.url('show'), - 'data-remote': 'true', - 'data-confirm': 'Are you absolutely sure?', - text: 'my social security number' - })); - - $('#fixtures').append($('', { - 'data-confirm': App.confirmation_message, - 'data-remote': 'true', - href: App.url('show'), - name: 'submit', - type: 'submit', - value: 'Click me' - })); - - - $('#fixtures').append($('