From 2ec99192d59e3f901b301d5735cee9a0b9ee091a Mon Sep 17 00:00:00 2001 From: "Erik St. Martin" Date: Wed, 27 Jan 2010 22:32:10 -0500 Subject: renaming javascript drivers to *.rails.js for better naming convention --- .../templates/public/javascripts/jquery.driver.js | 239 --------------- .../templates/public/javascripts/jquery.rails.js | 239 +++++++++++++++ .../public/javascripts/prototype.driver.js | 324 --------------------- .../public/javascripts/prototype.rails.js | 324 +++++++++++++++++++++ 4 files changed, 563 insertions(+), 563 deletions(-) delete mode 100644 railties/lib/generators/rails/app/templates/public/javascripts/jquery.driver.js create mode 100644 railties/lib/generators/rails/app/templates/public/javascripts/jquery.rails.js delete mode 100644 railties/lib/generators/rails/app/templates/public/javascripts/prototype.driver.js create mode 100644 railties/lib/generators/rails/app/templates/public/javascripts/prototype.rails.js (limited to 'railties/lib/generators/rails/app/templates/public') diff --git a/railties/lib/generators/rails/app/templates/public/javascripts/jquery.driver.js b/railties/lib/generators/rails/app/templates/public/javascripts/jquery.driver.js deleted file mode 100644 index 887da514e2..0000000000 --- a/railties/lib/generators/rails/app/templates/public/javascripts/jquery.driver.js +++ /dev/null @@ -1,239 +0,0 @@ -jQuery(function ($) { - var rails = { - update: function (selector, content, position) { - var element = $('#' + selector); - if (position) { - switch (position) { - case "before": - element.before(content); - break; - case "after": - element.after(content); - break; - case "top": - element.prepend(content); - break; - case "bottom": - element.append(content); - break; - default: - element.append(content); - break; - } - } else { - element.html(content); - } - }, - remote: function (e) { - var el = $(this), - data = [], - condition = el.attr('data-condition') ? eval(el.attr('data-condition')) : true, - method = el.attr('method') || el.attr('data-method') || 'GET', - url = el.attr('action') || el.attr('data-url') || '#', - async = el.attr('data-remote-type') === 'synchronous' ? false : true; - - if (el.attr('data-submit')) { - data = $('#' + el.attr('data-submit')).serializeArray(); - } else if (el.attr('data-with')) { - - if (e && e.target.tagName.toUpperCase() == 'SCRIPT' && el.attr('data-observed') !== null) { - var observed = $('#' + el.attr('data-observed')); - if(observed[0].tagName.toUpperCase() === 'FORM'){ - data = el.attr('data-with') + '=' + observed.serialize(); - } else if(observed[0].tagName.toUpperCase() === 'INPUT' && observed.attr('type').toUpperCase() !== "BUTTON" && observed.attr('type').toUpperCase() !== "SUBMIT") { - data = el.attr('data-with') + '=' + observed.val(); - } - } else { - // TODO: remove eval when deprecated - data = eval(el.attr('data-with')); - } - } else if (e && e.target.tagName.toUpperCase() == 'FORM') { - data = el.serializeArray(); - } else if (e && e.target.tagName.toUpperCase() == 'INPUT') { - data = el.closest('form').serializeArray(); - } - - if (condition) { - el.trigger('rails:before'); - - $.ajax({ - async: async, - url: url, - data: data, - type: method.toUpperCase(), - beforeSend: function (xhr) { - xhr.setRequestHeader("Accept", "text/javascript") - el.trigger('rails:after', xhr); - el.trigger('rails:loading', xhr); - }, - success: function (data, status, xhr) { - el.trigger('rails:success', [data, status, xhr]); - if (el.attr('data-update-success')) { - rails.update(el.attr('data-update-success'), data, el.attr('data-update-position')); - } - }, - complete: function (xhr) { - // enable disabled_with buttons - if (el[0].tagName.toUpperCase() == 'FORM') { - el.children('input[type="button"][data-enable-with],input[type="submit"][data-enable-with]').each(function(i, button){ - button = $(button); - button.attr('value', button.attr('data-enable-with')); - button.removeAttr('data-enable-with'); - button.removeAttr('disabled'); - - }); - } else { - el.attr('value', el.attr('data-enable-with')); - el.removeAttr('data-enable-with'); - el.removeAttr('disabled'); - } - - el.trigger('rails:complete', xhr); - el.trigger('rails:loaded', xhr); - }, - error: function (xhr, status, error) { - el.trigger('rails:failure', [xhr, status, error]); - if (el.attr('data-update-failure')) { - rails.update(el.attr('data-update-failure'), xhr.responseText, el.attr('data-update-position')); - } - } - }); - } - e.preventDefault(); - } - } - - /** - * observe_form, and observe_field - */ - $('script[data-observe="true"]').each(function (index, e) { - var el = $(e), - observed = $('#' + $(e).attr('data-observed')); - frequency = el.attr('data-frequency') ? el.attr('data-frequency') : 10, - value = observed[0].tagName.toUpperCase() === 'FORM' ? observed.serialize() : observed.val(); - - var observe = function (observed, frequency, value, e) { - return function () { - var event = new jQuery.Event('periodical'), - newValue = observed[0].tagName.toUpperCase() === 'FORM' ? observed.serialize() : observed.val(); - event.target = e; - - if(value !== newValue) { - value = newValue; - $(e).trigger('rails:observe'); - rails.remote.call(el, event); - } - } - }(observed, frequency, value, e); - - setInterval(observe, frequency * 1000); - }); - - /** - * confirm - * make sure this event is first! - */ - $('a[data-confirm],input[type="submit"][data-confirm],input[type="button"][data-confirm]').live('click', function(e){ - var el = $(this); - - if(!confirm(el.attr('data-confirm'))){ - return false; - } - }); - - /** - * periodically_call_remote - */ - $('script[data-periodical="true"]').each(function (index, e) { - var el = $(e), - frequency = el.attr('data-frequency') ? el.attr('data-frequency') : 10; - - setInterval(function () { - return function () { - var event = new jQuery.Event('periodical'); - event.target = e; - - rails.remote.call(el, event); - } - }(e, el), frequency * 1000); - }); - - /** - * disable_with - */ - $('input[type="button"][data-disable-with],input[type="submit"][data-disable-with]').live('click', function(e){ - var el = $(this); - - el.attr('data-enable-with', el.attr('value')); - el.attr('disabled', 'disabled'); - el.attr('value', el.attr('data-disable-with')); - }); - - /** - * remote_form_tag, and remote_form_for - */ - $('form[data-remote="true"]').live('submit', rails.remote); - - /** - * link_to_remote, button_to_remote, and submit_to_remote - */ - $('a[data-remote="true"],input[data-remote="true"],input[data-remote-submit="true"]').live('click', rails.remote); - - /* - * popup - */ - $('a[data-popup],input[type="button"][data-popup]').live('click', function(e){ - var el = $(this), - url = el.attr('data-url') || el.attr('href'); - - e.preventDefault(); - - if(el.attr('data-popup') === "true"){ - window.open(url); - } else { - window.open(url, el.attr('data-popup')); - } - }); - - /** - * - * Rails 2.x Helper / Event Handlers - * By default we listen to all callbacks, and status code callbacks and - * check the element for data- attribute and eval it. - * - */ - rails.compat = { - evalAttribute: function (element, attribute) { - var el = $(element), - attr = el.attr('data-' + attribute); - return (attr) ? eval(attr) : true; - } - }; - - $('form[data-remote="true"],a[data-remote="true"],input[data-remote="true"],script[data-observe="true"]') - .live('rails:before', function (e) { - rails.compat.evalAttribute(this, 'onbefore'); - }) - .live('rails:after', function (e, xhr) { - rails.compat.evalAttribute(this, 'onafter'); - }) - .live('rails:loading', function (e, xhr) { - rails.compat.evalAttribute(this, 'onloading'); - }) - .live('rails:loaded', function (e, xhr) { - rails.compat.evalAttribute(this, 'onloaded'); - }) - .live('rails:complete', function (e, xhr) { - rails.compat.evalAttribute(this, 'oncomplete'); - rails.compat.evalAttribute(this, 'on' + xhr.status); - }) - .live('rails:success', function (e, data, status, xhr) { - rails.compat.evalAttribute(this, 'onsuccess'); - }) - .live('rails:failure', function (e, xhr, status, error) { - rails.compat.evalAttribute(this, 'onfailure'); - }) - .live('rails:observe', function (e) { - rails.compat.evalAttribute(this, 'onobserve'); - }); -}); diff --git a/railties/lib/generators/rails/app/templates/public/javascripts/jquery.rails.js b/railties/lib/generators/rails/app/templates/public/javascripts/jquery.rails.js new file mode 100644 index 0000000000..887da514e2 --- /dev/null +++ b/railties/lib/generators/rails/app/templates/public/javascripts/jquery.rails.js @@ -0,0 +1,239 @@ +jQuery(function ($) { + var rails = { + update: function (selector, content, position) { + var element = $('#' + selector); + if (position) { + switch (position) { + case "before": + element.before(content); + break; + case "after": + element.after(content); + break; + case "top": + element.prepend(content); + break; + case "bottom": + element.append(content); + break; + default: + element.append(content); + break; + } + } else { + element.html(content); + } + }, + remote: function (e) { + var el = $(this), + data = [], + condition = el.attr('data-condition') ? eval(el.attr('data-condition')) : true, + method = el.attr('method') || el.attr('data-method') || 'GET', + url = el.attr('action') || el.attr('data-url') || '#', + async = el.attr('data-remote-type') === 'synchronous' ? false : true; + + if (el.attr('data-submit')) { + data = $('#' + el.attr('data-submit')).serializeArray(); + } else if (el.attr('data-with')) { + + if (e && e.target.tagName.toUpperCase() == 'SCRIPT' && el.attr('data-observed') !== null) { + var observed = $('#' + el.attr('data-observed')); + if(observed[0].tagName.toUpperCase() === 'FORM'){ + data = el.attr('data-with') + '=' + observed.serialize(); + } else if(observed[0].tagName.toUpperCase() === 'INPUT' && observed.attr('type').toUpperCase() !== "BUTTON" && observed.attr('type').toUpperCase() !== "SUBMIT") { + data = el.attr('data-with') + '=' + observed.val(); + } + } else { + // TODO: remove eval when deprecated + data = eval(el.attr('data-with')); + } + } else if (e && e.target.tagName.toUpperCase() == 'FORM') { + data = el.serializeArray(); + } else if (e && e.target.tagName.toUpperCase() == 'INPUT') { + data = el.closest('form').serializeArray(); + } + + if (condition) { + el.trigger('rails:before'); + + $.ajax({ + async: async, + url: url, + data: data, + type: method.toUpperCase(), + beforeSend: function (xhr) { + xhr.setRequestHeader("Accept", "text/javascript") + el.trigger('rails:after', xhr); + el.trigger('rails:loading', xhr); + }, + success: function (data, status, xhr) { + el.trigger('rails:success', [data, status, xhr]); + if (el.attr('data-update-success')) { + rails.update(el.attr('data-update-success'), data, el.attr('data-update-position')); + } + }, + complete: function (xhr) { + // enable disabled_with buttons + if (el[0].tagName.toUpperCase() == 'FORM') { + el.children('input[type="button"][data-enable-with],input[type="submit"][data-enable-with]').each(function(i, button){ + button = $(button); + button.attr('value', button.attr('data-enable-with')); + button.removeAttr('data-enable-with'); + button.removeAttr('disabled'); + + }); + } else { + el.attr('value', el.attr('data-enable-with')); + el.removeAttr('data-enable-with'); + el.removeAttr('disabled'); + } + + el.trigger('rails:complete', xhr); + el.trigger('rails:loaded', xhr); + }, + error: function (xhr, status, error) { + el.trigger('rails:failure', [xhr, status, error]); + if (el.attr('data-update-failure')) { + rails.update(el.attr('data-update-failure'), xhr.responseText, el.attr('data-update-position')); + } + } + }); + } + e.preventDefault(); + } + } + + /** + * observe_form, and observe_field + */ + $('script[data-observe="true"]').each(function (index, e) { + var el = $(e), + observed = $('#' + $(e).attr('data-observed')); + frequency = el.attr('data-frequency') ? el.attr('data-frequency') : 10, + value = observed[0].tagName.toUpperCase() === 'FORM' ? observed.serialize() : observed.val(); + + var observe = function (observed, frequency, value, e) { + return function () { + var event = new jQuery.Event('periodical'), + newValue = observed[0].tagName.toUpperCase() === 'FORM' ? observed.serialize() : observed.val(); + event.target = e; + + if(value !== newValue) { + value = newValue; + $(e).trigger('rails:observe'); + rails.remote.call(el, event); + } + } + }(observed, frequency, value, e); + + setInterval(observe, frequency * 1000); + }); + + /** + * confirm + * make sure this event is first! + */ + $('a[data-confirm],input[type="submit"][data-confirm],input[type="button"][data-confirm]').live('click', function(e){ + var el = $(this); + + if(!confirm(el.attr('data-confirm'))){ + return false; + } + }); + + /** + * periodically_call_remote + */ + $('script[data-periodical="true"]').each(function (index, e) { + var el = $(e), + frequency = el.attr('data-frequency') ? el.attr('data-frequency') : 10; + + setInterval(function () { + return function () { + var event = new jQuery.Event('periodical'); + event.target = e; + + rails.remote.call(el, event); + } + }(e, el), frequency * 1000); + }); + + /** + * disable_with + */ + $('input[type="button"][data-disable-with],input[type="submit"][data-disable-with]').live('click', function(e){ + var el = $(this); + + el.attr('data-enable-with', el.attr('value')); + el.attr('disabled', 'disabled'); + el.attr('value', el.attr('data-disable-with')); + }); + + /** + * remote_form_tag, and remote_form_for + */ + $('form[data-remote="true"]').live('submit', rails.remote); + + /** + * link_to_remote, button_to_remote, and submit_to_remote + */ + $('a[data-remote="true"],input[data-remote="true"],input[data-remote-submit="true"]').live('click', rails.remote); + + /* + * popup + */ + $('a[data-popup],input[type="button"][data-popup]').live('click', function(e){ + var el = $(this), + url = el.attr('data-url') || el.attr('href'); + + e.preventDefault(); + + if(el.attr('data-popup') === "true"){ + window.open(url); + } else { + window.open(url, el.attr('data-popup')); + } + }); + + /** + * + * Rails 2.x Helper / Event Handlers + * By default we listen to all callbacks, and status code callbacks and + * check the element for data- attribute and eval it. + * + */ + rails.compat = { + evalAttribute: function (element, attribute) { + var el = $(element), + attr = el.attr('data-' + attribute); + return (attr) ? eval(attr) : true; + } + }; + + $('form[data-remote="true"],a[data-remote="true"],input[data-remote="true"],script[data-observe="true"]') + .live('rails:before', function (e) { + rails.compat.evalAttribute(this, 'onbefore'); + }) + .live('rails:after', function (e, xhr) { + rails.compat.evalAttribute(this, 'onafter'); + }) + .live('rails:loading', function (e, xhr) { + rails.compat.evalAttribute(this, 'onloading'); + }) + .live('rails:loaded', function (e, xhr) { + rails.compat.evalAttribute(this, 'onloaded'); + }) + .live('rails:complete', function (e, xhr) { + rails.compat.evalAttribute(this, 'oncomplete'); + rails.compat.evalAttribute(this, 'on' + xhr.status); + }) + .live('rails:success', function (e, data, status, xhr) { + rails.compat.evalAttribute(this, 'onsuccess'); + }) + .live('rails:failure', function (e, xhr, status, error) { + rails.compat.evalAttribute(this, 'onfailure'); + }) + .live('rails:observe', function (e) { + rails.compat.evalAttribute(this, 'onobserve'); + }); +}); diff --git a/railties/lib/generators/rails/app/templates/public/javascripts/prototype.driver.js b/railties/lib/generators/rails/app/templates/public/javascripts/prototype.driver.js deleted file mode 100644 index aaed677fda..0000000000 --- a/railties/lib/generators/rails/app/templates/public/javascripts/prototype.driver.js +++ /dev/null @@ -1,324 +0,0 @@ -Event.observe(document, 'dom:loaded', function() { - function handle_remote(el, e){ - var data = null, - method = el.readAttribute('method') || el.readAttribute('data-method') || 'GET', - url = el.readAttribute('action') || el.readAttribute('data-url') || '#', - async = el.readAttribute('data-remote-type') === 'synchronous' ? false : true, - update = el.readAttribute('data-update-success'), - position = el.readAttribute('data-update-position'); - - if (el.readAttribute('data-submit')) { - var submit_el = $(el.readAttribute('data-submit')); - if(submit_el !== undefined && submit_el.tagName.toUpperCase() == 'FORM'){ - data = submit_el.serialize(); - } - } else if (el.readAttribute('data-with')) { - // It seems there is a big inconsistency between what :with means depending on the element type - // so this is going to look a bit crazy - if(el.tagName.toUpperCase() === 'SCRIPT' && el.readAttribute('data-observed') !== null){ - // Handle observe_field and observe_form - var observed_element = $(el.readAttribute('data-observed')); - - if(observed_element.tagName.toUpperCase() === 'FORM'){ - data = el.readAttribute('data-with') + '=' + observed_element.serialize(); - } else if(observed_element.tagName.toUpperCase() === 'INPUT' && observed_element.readAttribute('type').toUpperCase() !== "BUTTON" && observed_element.readAttribute('type').toUpperCase() !== "SUBMIT") { - data = el.readAttribute('data-with') + '=' + observed_element.getValue(); - } - } else { - // Handle link_to and button_to - data = evalAttribute(el, 'data-with'); - } - } else if(el.tagName.toUpperCase() === 'FORM') { - data = el.serialize(); - } - - document.fire('rails:before'); - - var request = new Ajax.Request(url, { - method: method, - asynchronous: async, - parameters: data, - evalJS: true, - evalJSON: true, - onComplete: function(xhr){ - document.fire('rails:complete', {xhr: xhr, element: el, submitted_button: getEventProperty(e, 'submitted_button')}); - }, - onLoading: function(xhr){ - document.fire('rails:after', {xhr: xhr, element: el}); - document.fire('rails:loading', {xhr: xhr, element: el}); - }, - onLoaded: function(xhr){ - document.fire('rails:loaded', {xhr: xhr, element: el}); - }, - onSuccess: function(xhr){ - document.fire('rails:success', {xhr: xhr, element: el}); - }, - onFailure: function(xhr){ - document.fire('rails:failure', {xhr: xhr, element: el}); - } - }); - - } - - function setEventProperty(e, property, value){ - if(e.memo === undefined){ - e.memo = {}; - } - - e.memo[property] = value; - } - - function getEventProperty(e, property){ - if(e !== null && e.memo !== undefined && e.memo[property] !== undefined){ - return e.memo[property]; - } - } - - function confirmed(e, el){ - if(getEventProperty(e,'confirm_checked') !== true){ - setEventProperty(e, 'confirm_checked', true); - - el = Event.findElement(e, 'form') || el; - var confirm_msg = el.readAttribute('data-confirm'); - - if(confirm_msg !== null){ - var result = el.fire('rails:confirm', {confirm_msg: confirm_msg}); - if(result.memo.stop_event === true){ - Event.stop(e); - return false; - } - } - } - return true; - } - - function disable_button(el){ - var disable_with = el.readAttribute('data-disable-with'); - if(disable_with !== null){ - el.writeAttribute('data-enable-with', el.readAttribute('value')); - el.writeAttribute('value', disable_with); - el.writeAttribute('disabled', true); - } - } - - function enable_button(el){ - var enable_with = el.readAttribute('data-enable-with'); - if(enable_with !== null){ - el.writeAttribute('value', enable_with); - } - el.writeAttribute('disabled', false); - } - - function updateHTML(el, content, result){ - var element_id = null; - - if(result === 'success'){ - element_id = el.readAttribute('data-update-success'); - } else if(result === 'failure'){ - element_id = el.readAttribute('data-update-failure'); - } - - var element_to_update = $(element_id); - if(element_to_update !== null){ - var position = el.readAttribute('data-update-position'); - if(position !== null){ - var options = {}; - options[position] = content; - element_to_update.insert(options); - } else { - element_to_update.update(content); - } - } - } - - $$("script[data-periodical=true]").each(function(el){ - var executor = new PeriodicalExecuter(function() { handle_remote(el);}, el.readAttribute('data-frequency')); - }); - - $$("script[data-observe=true]").each(function(el){ - var observed_element = $(el.readAttribute('data-observed')); - var original_value = observed_element.tagName.toUpperCase() === 'FORM' ? observed_element.serialize() : observed_element.getValue(); - var callback = el.readAttribute('data-onobserve'); - var executor = new PeriodicalExecuter(function() { - var value = observed_element.tagName.toUpperCase() === 'FORM' ? observed_element.serialize() : observed_element.getValue(); - - if(original_value !== value){ - original_value = value; - - if(callback !== null){ - evalAttribute(el, 'onobserve'); - } else if(el.readAttribute('data-url') !== null){ - handle_remote(el); - } - } - }, el.readAttribute('data-frequency')); - - }); - - /** - * - * Event Listeners - * - * the original element is contained inside the event, - * for some reason prototype wont let me listen for custom events on document - * if the event wasn't fired on document - * - */ - - Event.observe(document, 'submit', function (e) { - var form = Event.findElement(e, 'form'); - // Make sure conditions and confirm have not already run - if(form !== undefined && conditions_met(e, form) && confirmed(e, form)){ - - var button = form.down('input[data-submitted=true]'); - button.writeAttribute('data-submitted', null); - setEventProperty(e, 'submitted_button', button); - disable_button(button); - - if(form.readAttribute('data-remote') === 'true'){ - Event.stop(e); - handle_remote(form, e); - } - } - }); - - Event.observe(document, 'click', function (e) { - var el = Event.findElement(e, 'a') || Event.findElement(e, 'input'); - - if(el !== undefined && el.tagName.toUpperCase() === 'INPUT' && el.readAttribute('type').toUpperCase() === 'SUBMIT'){ - el.writeAttribute('data-submitted', 'true'); - - // Submit is handled by submit event, don't continue on this path - el = undefined; - } else if(el !== undefined && el.tagName.toUpperCase() === 'INPUT' && el.readAttribute('type').toUpperCase() !== 'BUTTON'){ - // Make sure other inputs do not send this event - el = undefined; - } - - if(el !== undefined && conditions_met(e, el) && confirmed(e, el)){ - if(el.tagName.toUpperCase() === 'INPUT' && el.readAttribute('type').toUpperCase() === 'BUTTON'){ - disable_button(el); - } - - if(el.readAttribute('data-remote') === 'true'){ - Event.stop(e); - handle_remote(el, e); - } else if(el.readAttribute('data-popup') !== null){ - Event.stop(e); - document.fire('rails:popup', {element: el}); - } - } - }); - - /** - * - * Default Event Handlers - * - */ - Event.observe(document, 'rails:confirm', function(e){ - setEventProperty(e, 'stop_event', !confirm(getEventProperty(e,'confirm_msg'))); - }); - - Event.observe(document, 'rails:popup', function(e){ - var el = getEventProperty(e, 'element'); - var url = el.readAttribute('href') || el.readAttribute('data-url'); - - if(el.readAttribute('data-popup') === true){ - window.open(url); - } else { - window.open(url, el.readAttribute('data-popup')); - } - }); - - Event.observe(document, 'rails:complete', function(e){ - var el = getEventProperty(e, 'element'); - - if(el.tagName.toUpperCase() === 'FORM'){ - var button = getEventProperty(e, 'submitted_button') ; - enable_button(button); - } - }); - - Event.observe(document, 'rails:success', function(e){ - var el = getEventProperty(e, 'element'), - xhr = getEventProperty(e, 'xhr'); - - if(xhr.responseText !== null){ - updateHTML(el, xhr.responseText, 'success'); - } - }); - - Event.observe(document, 'rails:failure', function(e){ - var el = getEventProperty(e, 'element'), - xhr = getEventProperty(e, 'xhr'); - - if(xhr.responseText !== null){ - updateHTML(el, xhr.responseText, 'failure'); - } - }); - - /** - * - * Rails 2.x Helpers / Event Handlers - * - */ - function evalAttribute(el, attribute){ - var js = el.readAttribute('data-' + attribute); - - if(js){ - eval(js); - } - } - - function conditions_met(e, el){ - if(getEventProperty(e,'condition_checked') !== true){ - setEventProperty(e, 'condition_checked', true); - - el = Event.findElement(e, 'form') || el; - var conditions = el.readAttribute('data-condition'); - - if(conditions !== null){ - if(eval(conditions) === false){ - Event.stop(e); - return false; - } - } - } - return true; - } - - Event.observe(document, 'rails:success', function(e){ - evalAttribute(el, 'onsuccess'); - }); - - Event.observe(document, 'rails:failure', function(e){ - evalAttribute(el, 'onfailure'); - }); - - Event.observe(document, 'rails:complete', function(e){ - var el = getEventProperty(e, 'element'); - - evalAttribute(el, 'oncomplete'); - evalAttribute(el, 'on' + getEventProperty('xhr', xhr.status)); - - if(el.readAttribute('data-periodical') === 'true'){ - evalAttribute(el, 'onobserve'); - } - }); - - Event.observe(document, 'rails:loading', function(e){ - evalAttribute(el, 'onloading'); - }); - - Event.observe(document, 'rails:loaded', function(e){ - evalAttribute(el, 'onloaded'); - }); - - Event.observe(document, 'rails:before', function(e){ - evalAttribute(el, 'onbefore'); - }); - - Event.observe(document, 'rails:after', function(e){ - evalAttribute(el, 'onafter'); - }); -}); diff --git a/railties/lib/generators/rails/app/templates/public/javascripts/prototype.rails.js b/railties/lib/generators/rails/app/templates/public/javascripts/prototype.rails.js new file mode 100644 index 0000000000..aaed677fda --- /dev/null +++ b/railties/lib/generators/rails/app/templates/public/javascripts/prototype.rails.js @@ -0,0 +1,324 @@ +Event.observe(document, 'dom:loaded', function() { + function handle_remote(el, e){ + var data = null, + method = el.readAttribute('method') || el.readAttribute('data-method') || 'GET', + url = el.readAttribute('action') || el.readAttribute('data-url') || '#', + async = el.readAttribute('data-remote-type') === 'synchronous' ? false : true, + update = el.readAttribute('data-update-success'), + position = el.readAttribute('data-update-position'); + + if (el.readAttribute('data-submit')) { + var submit_el = $(el.readAttribute('data-submit')); + if(submit_el !== undefined && submit_el.tagName.toUpperCase() == 'FORM'){ + data = submit_el.serialize(); + } + } else if (el.readAttribute('data-with')) { + // It seems there is a big inconsistency between what :with means depending on the element type + // so this is going to look a bit crazy + if(el.tagName.toUpperCase() === 'SCRIPT' && el.readAttribute('data-observed') !== null){ + // Handle observe_field and observe_form + var observed_element = $(el.readAttribute('data-observed')); + + if(observed_element.tagName.toUpperCase() === 'FORM'){ + data = el.readAttribute('data-with') + '=' + observed_element.serialize(); + } else if(observed_element.tagName.toUpperCase() === 'INPUT' && observed_element.readAttribute('type').toUpperCase() !== "BUTTON" && observed_element.readAttribute('type').toUpperCase() !== "SUBMIT") { + data = el.readAttribute('data-with') + '=' + observed_element.getValue(); + } + } else { + // Handle link_to and button_to + data = evalAttribute(el, 'data-with'); + } + } else if(el.tagName.toUpperCase() === 'FORM') { + data = el.serialize(); + } + + document.fire('rails:before'); + + var request = new Ajax.Request(url, { + method: method, + asynchronous: async, + parameters: data, + evalJS: true, + evalJSON: true, + onComplete: function(xhr){ + document.fire('rails:complete', {xhr: xhr, element: el, submitted_button: getEventProperty(e, 'submitted_button')}); + }, + onLoading: function(xhr){ + document.fire('rails:after', {xhr: xhr, element: el}); + document.fire('rails:loading', {xhr: xhr, element: el}); + }, + onLoaded: function(xhr){ + document.fire('rails:loaded', {xhr: xhr, element: el}); + }, + onSuccess: function(xhr){ + document.fire('rails:success', {xhr: xhr, element: el}); + }, + onFailure: function(xhr){ + document.fire('rails:failure', {xhr: xhr, element: el}); + } + }); + + } + + function setEventProperty(e, property, value){ + if(e.memo === undefined){ + e.memo = {}; + } + + e.memo[property] = value; + } + + function getEventProperty(e, property){ + if(e !== null && e.memo !== undefined && e.memo[property] !== undefined){ + return e.memo[property]; + } + } + + function confirmed(e, el){ + if(getEventProperty(e,'confirm_checked') !== true){ + setEventProperty(e, 'confirm_checked', true); + + el = Event.findElement(e, 'form') || el; + var confirm_msg = el.readAttribute('data-confirm'); + + if(confirm_msg !== null){ + var result = el.fire('rails:confirm', {confirm_msg: confirm_msg}); + if(result.memo.stop_event === true){ + Event.stop(e); + return false; + } + } + } + return true; + } + + function disable_button(el){ + var disable_with = el.readAttribute('data-disable-with'); + if(disable_with !== null){ + el.writeAttribute('data-enable-with', el.readAttribute('value')); + el.writeAttribute('value', disable_with); + el.writeAttribute('disabled', true); + } + } + + function enable_button(el){ + var enable_with = el.readAttribute('data-enable-with'); + if(enable_with !== null){ + el.writeAttribute('value', enable_with); + } + el.writeAttribute('disabled', false); + } + + function updateHTML(el, content, result){ + var element_id = null; + + if(result === 'success'){ + element_id = el.readAttribute('data-update-success'); + } else if(result === 'failure'){ + element_id = el.readAttribute('data-update-failure'); + } + + var element_to_update = $(element_id); + if(element_to_update !== null){ + var position = el.readAttribute('data-update-position'); + if(position !== null){ + var options = {}; + options[position] = content; + element_to_update.insert(options); + } else { + element_to_update.update(content); + } + } + } + + $$("script[data-periodical=true]").each(function(el){ + var executor = new PeriodicalExecuter(function() { handle_remote(el);}, el.readAttribute('data-frequency')); + }); + + $$("script[data-observe=true]").each(function(el){ + var observed_element = $(el.readAttribute('data-observed')); + var original_value = observed_element.tagName.toUpperCase() === 'FORM' ? observed_element.serialize() : observed_element.getValue(); + var callback = el.readAttribute('data-onobserve'); + var executor = new PeriodicalExecuter(function() { + var value = observed_element.tagName.toUpperCase() === 'FORM' ? observed_element.serialize() : observed_element.getValue(); + + if(original_value !== value){ + original_value = value; + + if(callback !== null){ + evalAttribute(el, 'onobserve'); + } else if(el.readAttribute('data-url') !== null){ + handle_remote(el); + } + } + }, el.readAttribute('data-frequency')); + + }); + + /** + * + * Event Listeners + * + * the original element is contained inside the event, + * for some reason prototype wont let me listen for custom events on document + * if the event wasn't fired on document + * + */ + + Event.observe(document, 'submit', function (e) { + var form = Event.findElement(e, 'form'); + // Make sure conditions and confirm have not already run + if(form !== undefined && conditions_met(e, form) && confirmed(e, form)){ + + var button = form.down('input[data-submitted=true]'); + button.writeAttribute('data-submitted', null); + setEventProperty(e, 'submitted_button', button); + disable_button(button); + + if(form.readAttribute('data-remote') === 'true'){ + Event.stop(e); + handle_remote(form, e); + } + } + }); + + Event.observe(document, 'click', function (e) { + var el = Event.findElement(e, 'a') || Event.findElement(e, 'input'); + + if(el !== undefined && el.tagName.toUpperCase() === 'INPUT' && el.readAttribute('type').toUpperCase() === 'SUBMIT'){ + el.writeAttribute('data-submitted', 'true'); + + // Submit is handled by submit event, don't continue on this path + el = undefined; + } else if(el !== undefined && el.tagName.toUpperCase() === 'INPUT' && el.readAttribute('type').toUpperCase() !== 'BUTTON'){ + // Make sure other inputs do not send this event + el = undefined; + } + + if(el !== undefined && conditions_met(e, el) && confirmed(e, el)){ + if(el.tagName.toUpperCase() === 'INPUT' && el.readAttribute('type').toUpperCase() === 'BUTTON'){ + disable_button(el); + } + + if(el.readAttribute('data-remote') === 'true'){ + Event.stop(e); + handle_remote(el, e); + } else if(el.readAttribute('data-popup') !== null){ + Event.stop(e); + document.fire('rails:popup', {element: el}); + } + } + }); + + /** + * + * Default Event Handlers + * + */ + Event.observe(document, 'rails:confirm', function(e){ + setEventProperty(e, 'stop_event', !confirm(getEventProperty(e,'confirm_msg'))); + }); + + Event.observe(document, 'rails:popup', function(e){ + var el = getEventProperty(e, 'element'); + var url = el.readAttribute('href') || el.readAttribute('data-url'); + + if(el.readAttribute('data-popup') === true){ + window.open(url); + } else { + window.open(url, el.readAttribute('data-popup')); + } + }); + + Event.observe(document, 'rails:complete', function(e){ + var el = getEventProperty(e, 'element'); + + if(el.tagName.toUpperCase() === 'FORM'){ + var button = getEventProperty(e, 'submitted_button') ; + enable_button(button); + } + }); + + Event.observe(document, 'rails:success', function(e){ + var el = getEventProperty(e, 'element'), + xhr = getEventProperty(e, 'xhr'); + + if(xhr.responseText !== null){ + updateHTML(el, xhr.responseText, 'success'); + } + }); + + Event.observe(document, 'rails:failure', function(e){ + var el = getEventProperty(e, 'element'), + xhr = getEventProperty(e, 'xhr'); + + if(xhr.responseText !== null){ + updateHTML(el, xhr.responseText, 'failure'); + } + }); + + /** + * + * Rails 2.x Helpers / Event Handlers + * + */ + function evalAttribute(el, attribute){ + var js = el.readAttribute('data-' + attribute); + + if(js){ + eval(js); + } + } + + function conditions_met(e, el){ + if(getEventProperty(e,'condition_checked') !== true){ + setEventProperty(e, 'condition_checked', true); + + el = Event.findElement(e, 'form') || el; + var conditions = el.readAttribute('data-condition'); + + if(conditions !== null){ + if(eval(conditions) === false){ + Event.stop(e); + return false; + } + } + } + return true; + } + + Event.observe(document, 'rails:success', function(e){ + evalAttribute(el, 'onsuccess'); + }); + + Event.observe(document, 'rails:failure', function(e){ + evalAttribute(el, 'onfailure'); + }); + + Event.observe(document, 'rails:complete', function(e){ + var el = getEventProperty(e, 'element'); + + evalAttribute(el, 'oncomplete'); + evalAttribute(el, 'on' + getEventProperty('xhr', xhr.status)); + + if(el.readAttribute('data-periodical') === 'true'){ + evalAttribute(el, 'onobserve'); + } + }); + + Event.observe(document, 'rails:loading', function(e){ + evalAttribute(el, 'onloading'); + }); + + Event.observe(document, 'rails:loaded', function(e){ + evalAttribute(el, 'onloaded'); + }); + + Event.observe(document, 'rails:before', function(e){ + evalAttribute(el, 'onbefore'); + }); + + Event.observe(document, 'rails:after', function(e){ + evalAttribute(el, 'onafter'); + }); +}); -- cgit v1.2.3