Index: includes/ajax.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/ajax.inc,v retrieving revision 1.40 diff -u -p -r1.40 ajax.inc --- includes/ajax.inc 17 Dec 2010 01:03:58 -0000 1.40 +++ includes/ajax.inc 22 Dec 2010 14:32:19 -0000 @@ -572,10 +572,7 @@ function ajax_pre_render_element($elemen case 'submit': case 'button': case 'image_button': - // Use the mousedown instead of the click event because form - // submission via pressing the enter key triggers a click event on - // submit inputs, inappropriately triggering AJAX behaviors. - $element['#ajax']['event'] = 'mousedown'; + $element['#ajax']['event'] = 'click'; // Attach an additional event handler so that AJAX behaviors // can be triggered still via keyboard input. $element['#ajax']['keypress'] = TRUE; Index: misc/ajax.js =================================================================== RCS file: /cvs/drupal/drupal/misc/ajax.js,v retrieving revision 1.34 diff -u -p -r1.34 ajax.js --- misc/ajax.js 21 Dec 2010 04:21:16 -0000 1.34 +++ misc/ajax.js 22 Dec 2010 15:36:25 -0000 @@ -149,11 +149,9 @@ Drupal.ajax = function (base, element, e return ajax.beforeSerialize(element_settings, options); }, beforeSubmit: function (form_values, element_settings, options) { - ajax.ajaxing = true; return ajax.beforeSubmit(form_values, element_settings, options); }, beforeSend: function (xmlhttprequest) { - ajax.ajaxing = true; return ajax.beforeSend(xmlhttprequest, ajax.options); }, success: function (response, status) { @@ -176,6 +174,31 @@ Drupal.ajax = function (base, element, e // Bind the ajaxSubmit function to the element event. $(ajax.element).bind(element_settings.event, function (event) { + // Do not perform another ajax command if one is already in progress. + if (ajax.ajaxing) { + return false; + } + // Retrieve the actual element, on which the event was triggered. Normally, + // browsers provide the actual source element that triggered the event in + // event.target, resp., event.currentElement. But if a 'click' event is + // bound to a form button and enter is pressed in a text input, a browser + // will submit the form and therefore trigger the click event of the form + // button. Therefore, we need to figure out the original source element. + // Clicking a button does not provide an originalEvent. + event.ajaxSrcElement = null; + if (event.originalEvent) { + event.ajaxSrcElement = event.originalEvent.explicitOriginalTarget || event.originalEvent.relatedTarget; + } + // Also try the browser-specific (but also HTML5) activeElement property, + // denoting the focused form element. + event.ajaxSrcElement = event.ajaxSrcElement || document.activeElement; + // Some browsers may return text nodes; use the parentNode instead. + event.ajaxSrcElement = (event.ajaxSrcElement.nodeType == 1 ? event.ajaxSrcElement : event.ajaxSrcElement.parentNode); + // If we found the source and it is not the bound element, cancel. + if (event.ajaxSrcElement && event.ajaxSrcElement != ajax.element) { + return; + } + ajax.ajaxing = true; return ajax.eventResponse(this, event); }); @@ -183,7 +206,7 @@ Drupal.ajax = function (base, element, e // can be triggered through keyboard input as well as e.g. a mousedown // action. if (element_settings.keypress) { - $(element_settings.element).keypress(function (event) { + $(ajax.element).keypress(function (event) { return ajax.keypressResponse(this, event); }); } @@ -208,7 +231,7 @@ Drupal.ajax.prototype.keypressResponse = // spacebar activation causes inappropriate activation if #ajax['keypress'] is // TRUE. On a text-type widget a space should always be a space. if (event.which == 13 || (event.which == 32 && element.type != 'text' && element.type != 'textarea')) { - $(ajax.element_settings.element).trigger(ajax.element_settings.event); + $(ajax.element).trigger(ajax.element_settings.event); return false; } }; @@ -225,11 +248,6 @@ Drupal.ajax.prototype.eventResponse = fu // Create a synonym for this to reduce code confusion. var ajax = this; - // Do not perform another ajax command if one is already in progress. - if (ajax.ajaxing) { - return false; - } - try { if (ajax.form) { // If setClick is set, we must set this to ensure that the button's