Commit 5371104a authored by Dries's avatar Dries

- Patch #316225 by sun et al: allow behaviors to detach from AHAH/AJAX.

parent 068febde
......@@ -15,7 +15,8 @@
/**
* Attaches the ahah behavior to each ahah form element.
*/
Drupal.behaviors.ahah = function(context) {
Drupal.behaviors.ahah = {
attach: function(context) {
for (var base in Drupal.settings.ahah) {
if (!$('#'+ base + '.ahah-processed').size()) {
var element_settings = Drupal.settings.ahah[base];
......@@ -28,6 +29,7 @@ Drupal.behaviors.ahah = function(context) {
$('#'+ base).addClass('ahah-processed');
}
}
}
};
/**
......
......@@ -3,7 +3,8 @@
/**
* Attaches the autocomplete behavior to all required fields.
*/
Drupal.behaviors.autocomplete = function (context) {
Drupal.behaviors.autocomplete = {
attach: function(context) {
var acdb = [];
$('input.autocomplete:not(.autocomplete-processed)', context).each(function () {
var uri = this.value;
......@@ -16,6 +17,7 @@ Drupal.behaviors.autocomplete = function (context) {
new Drupal.jsAC(input, acdb[uri]);
$(this).addClass('autocomplete-processed');
});
}
};
/**
......
......@@ -3,7 +3,8 @@
/**
* Attaches the batch behavior to progress bars.
*/
Drupal.behaviors.batch = function (context) {
Drupal.behaviors.batch = {
attach: function(context) {
// This behavior attaches by ID, so is only valid once on a page.
if ($('#progress.batch-processed').size()) {
return;
......@@ -35,4 +36,5 @@ Drupal.behaviors.batch = function (context) {
$(holder).append(progress.element);
progress.startMonitoring(uri+'&op=do', 10);
});
}
};
......@@ -50,7 +50,8 @@ Drupal.collapseScrollIntoView = function (node) {
}
};
Drupal.behaviors.collapse = function (context) {
Drupal.behaviors.collapse = {
attach: function(context) {
$('fieldset.collapsible > legend:not(.collapse-processed)', context).each(function() {
var fieldset = $(this.parentNode);
// Expand if there are errors inside
......@@ -74,4 +75,5 @@ Drupal.behaviors.collapse = function (context) {
.append(fieldset.children(':not(legend):not(.action)')))
.addClass('collapse-processed');
});
}
};
......@@ -12,10 +12,15 @@ Drupal.jsEnabled = document.getElementsByTagName && document.createElement && do
*
* Behaviors are event-triggered actions that attach to page elements, enhancing
* default non-Javascript UIs. Behaviors are registered in the Drupal.behaviors
* object as follows:
* object using the method 'attach' and optionally also 'detach' as follows:
* @code
* Drupal.behaviors.behaviorName = function () {
* Drupal.behaviors.behaviorName = {
* attach: function(context) {
* ...
* },
* detach: function(context) {
* ...
* }
* };
* @endcode
*
......@@ -38,7 +43,38 @@ Drupal.attachBehaviors = function(context) {
context = context || document;
// Execute all of them.
jQuery.each(Drupal.behaviors, function() {
this(context);
if (jQuery.isFunction(this.attach)) {
this.attach(context);
}
});
};
/**
* Detach registered behaviors from a page element.
*
* Developers implementing AHAH/AJAX in their solutions should call this
* function before page content is about to be removed, feeding in an element
* to be processed, in order to allow special behaviors to detach from the
* content.
*
* Such implementations should look for the class name that was added in their
* corresponding Drupal.behaviors.behaviorName.attach implementation, i.e.
* behaviorName-processed, to ensure the behavior is detached only from
* previously processed elements.
*
* @param context
* An element to detach behaviors from. If none is given, the document element
* is used.
*
* @see Drupal.attachBehaviors
*/
Drupal.detachBehaviors = function(context) {
context = context || document;
// Execute all of them.
jQuery.each(Drupal.behaviors, function() {
if (jQuery.isFunction(this.detach)) {
this.detach(context);
}
});
};
......
// $Id$
Drupal.behaviors.multiselectSelector = function() {
Drupal.behaviors.multiselectSelector = {
attach: function(context) {
// Automatically selects the right radio button in a multiselect control.
$('.multiselect select:not(.multiselectSelector-processed)')
$('.multiselect select:not(.multiselectSelector-processed)', context)
.addClass('multiselectSelector-processed').change(function() {
$('.multiselect input:radio[value="'+ this.id.substr(5) +'"]')
.attr('checked', true);
});
}
};
......@@ -11,7 +11,8 @@
* overriding the .onDrag, .onDrop, .row.onSwap, and .row.onIndent methods.
* See blocks.js for an example of adding additional functionality to tableDrag.
*/
Drupal.behaviors.tableDrag = function(context) {
Drupal.behaviors.tableDrag = {
attach: function(context) {
for (var base in Drupal.settings.tableDrag) {
if (!$('#' + base + '.tabledrag-processed', context).size()) {
var tableSettings = Drupal.settings.tableDrag[base];
......@@ -25,6 +26,7 @@ Drupal.behaviors.tableDrag = function(context) {
$('#' + base).addClass('tabledrag-processed');
}
}
}
};
/**
......
......@@ -6,7 +6,8 @@ Drupal.tableHeaderDoScroll = function() {
}
};
Drupal.behaviors.tableHeader = function (context) {
Drupal.behaviors.tableHeader = {
attach: function(context) {
// This breaks in anything less than IE 7. Prevent it from running.
if (jQuery.browser.msie && parseInt(jQuery.browser.version, 10) < 7) {
return;
......@@ -110,4 +111,5 @@ Drupal.behaviors.tableHeader = function (context) {
}, 250);
};
$(window).resize(resize);
}
};
// $Id$
Drupal.behaviors.tableSelect = function (context) {
Drupal.behaviors.tableSelect = {
attach: function(context) {
$('form table:has(th.select-all):not(.tableSelect-processed)', context).each(Drupal.tableSelect);
}
};
Drupal.tableSelect = function() {
......
......@@ -5,7 +5,8 @@
*
* Note: depends on resizable textareas.
*/
Drupal.behaviors.teaser = function(context) {
Drupal.behaviors.teaser = {
attach: function(context) {
// This breaks in Konqueror. Prevent it from running.
if (/KDE/.test(navigator.vendor)) {
return;
......@@ -85,7 +86,7 @@ Drupal.behaviors.teaser = function(context) {
// Make sure that textarea.js has done its magic to ensure proper visibility state.
if (Drupal.behaviors.textarea && teaser.is(('.form-textarea:not(.textarea-processed)'))) {
Drupal.behaviors.textarea(teaser.parentNode);
Drupal.behaviors.textarea.attach(teaser.parentNode);
}
// Set initial visibility.
if ($(teaser).is('[@disabled]')) {
......@@ -93,4 +94,5 @@ Drupal.behaviors.teaser = function(context) {
}
});
}
};
// $Id$
Drupal.behaviors.textarea = function(context) {
Drupal.behaviors.textarea = {
attach: function(context) {
$('textarea.resizable:not(.textarea-processed)', context).each(function() {
// Avoid non-processed teasers.
if ($(this).is(('textarea.teaser:not(.teaser-processed)'))) {
......@@ -33,4 +34,5 @@ Drupal.behaviors.textarea = function(context) {
textarea.css('opacity', 1);
}
});
}
};
......@@ -6,7 +6,8 @@
* This behavior is dependent on the tableDrag behavior, since it uses the
* objects initialized in that behavior to update the row.
*/
Drupal.behaviors.blockDrag = function(context) {
Drupal.behaviors.blockDrag = {
attach: function(context) {
var table = $('table#blocks');
var tableDrag = Drupal.tableDrag.blocks; // Get the blocks tableDrag object.
......@@ -92,4 +93,5 @@ Drupal.behaviors.blockDrag = function(context) {
}
});
};
}
};
// $Id$
Drupal.behaviors.color = function (context) {
Drupal.behaviors.color = {
attach: function(context) {
// This behavior attaches by ID, so is only valid once on a page.
if ($('#color_scheme_form .color-form.color-processed').size()) {
return;
......@@ -248,4 +249,5 @@ Drupal.behaviors.color = function (context) {
// Render preview.
preview();
}
};
// $Id$
Drupal.behaviors.comment = function(context) {
Drupal.behaviors.comment = {
attach: function(context) {
var parts = new Array("name", "homepage", "mail");
var cookie = '';
for (i=0;i<3;i++) {
......@@ -11,6 +12,7 @@ Drupal.behaviors.comment = function(context) {
.addClass('comment-processed');
}
}
}
};
Drupal.comment = {};
......
// $Id$
Drupal.behaviors.openid = function (context) {
Drupal.behaviors.openid = {
attach: function(context) {
var $loginElements = $("#edit-name-wrapper, #edit-pass-wrapper, li.openid-link");
var $openidElements = $("#edit-openid-identifier-wrapper, li.user-link");
......@@ -35,4 +36,5 @@ Drupal.behaviors.openid = function (context) {
$("#edit-name")[0].focus();
return false;
});
}
};
......@@ -7,7 +7,8 @@
* objects initialized in that behavior to update the row. It shows and hides
* a warning message when removing the last field from a profile category.
*/
Drupal.behaviors.profileDrag = function(context) {
Drupal.behaviors.profileDrag = {
attach: function(context) {
var table = $('#profile-fields');
var tableDrag = Drupal.tableDrag['profile-fields']; // Get the profile tableDrag object.
......@@ -51,4 +52,5 @@ Drupal.behaviors.profileDrag = function(context) {
}
}
};
}
};
......@@ -3,7 +3,8 @@
/**
* Add the cool table collapsing on the testing overview page.
*/
Drupal.behaviors.simpleTestMenuCollapse = function() {
Drupal.behaviors.simpleTestMenuCollapse = {
attach: function() {
// Adds expand-collapse functionality.
$('div.simpletest-image').each(function() {
direction = Drupal.settings.simpleTest[$(this).attr('id')].imageDirection;
......@@ -33,13 +34,15 @@ Drupal.behaviors.simpleTestMenuCollapse = function() {
$(this).html(Drupal.settings.simpleTest.images[(direction? 0 : 1)]);
}
});
}
}
};
/**
* Select/deselect all the inner checkboxes when the outer checkboxes are
* selected/deselected.
*/
Drupal.behaviors.simpleTestSelectAll = function() {
Drupal.behaviors.simpleTestSelectAll = {
attach: function() {
$('td.simpletest-select-all').each(function() {
var checkboxes = Drupal.settings.simpleTest['simpletest-test-group-'+ $(this).attr('id')].testNames, totalCheckboxes = 0,
checkbox = $('<input type="checkbox" class="form-checkbox" id="'+ $(this).attr('id') +'-select-all" />').change(function() {
......@@ -72,4 +75,5 @@ Drupal.behaviors.simpleTestSelectAll = function() {
}
$(this).append(checkbox);
});
}
};
......@@ -7,7 +7,8 @@
* This function is not used to verify whether or not clean URLs
* are currently enabled.
*/
Drupal.behaviors.cleanURLsSettingsCheck = function(context) {
Drupal.behaviors.cleanURLsSettingsCheck = {
attach: function(context) {
// This behavior attaches by ID, so is only valid once on a page.
// Also skip if we are on an install page, as Drupal.cleanURLsInstallCheck will handle
// the processing.
......@@ -33,6 +34,7 @@ Drupal.behaviors.cleanURLsSettingsCheck = function(context) {
}
});
$("#clean-url").addClass('clean-url-processed');
}
};
/**
......@@ -70,7 +72,8 @@ Drupal.cleanURLsInstallCheck = function() {
* use the same value. In the installer this is used to populate the
* administrator e-mail address with the same value as the site e-mail address.
*/
Drupal.behaviors.copyFieldValue = function (context) {
Drupal.behaviors.copyFieldValue = {
attach: function(context) {
for (var sourceId in Drupal.settings.copyFieldValue) {
// Get the list of target fields.
targetIds = Drupal.settings.copyFieldValue[sourceId];
......@@ -88,12 +91,14 @@ Drupal.behaviors.copyFieldValue = function (context) {
sourceField.addClass('copy-field-values-processed');
}
}
}
};
/**
* Show/hide custom format sections on the date-time settings page.
*/
Drupal.behaviors.dateTime = function(context) {
Drupal.behaviors.dateTime = {
attach: function(context) {
// Show/hide custom format depending on the select's value.
$('select.date-format:not(.date-time-processed)', context).change(function() {
$(this).addClass('date-time-processed').parents("div.date-container").children("div.custom-container")[$(this).val() == "custom" ? "show" : "hide"]();
......@@ -110,4 +115,5 @@ Drupal.behaviors.dateTime = function(context) {
// Trigger the event handler to show the form input if necessary.
$('select.date-format', context).trigger('change');
}
};
......@@ -6,7 +6,8 @@
* This behavior is dependent on the tableDrag behavior, since it uses the
* objects initialized in that behavior to update the row.
*/
Drupal.behaviors.termDrag = function(context) {
Drupal.behaviors.termDrag = {
attach: function(context) {
var table = $('#taxonomy', context);
var tableDrag = Drupal.tableDrag.taxonomy; // Get the blocks tableDrag object.
var rows = $('tr', table).size();
......@@ -33,4 +34,5 @@ Drupal.behaviors.termDrag = function(context) {
$(table[0].tBodies[0].rows[rows - Drupal.settings.taxonomy.forwardPeddle - 1]).addClass('taxonomy-term-divider-bottom');
}
};
}
};
......@@ -4,8 +4,8 @@
* Attach handlers to evaluate the strength of any password fields and to check
* that its confirmation is correct.
*/
Drupal.behaviors.password = function(context) {
Drupal.behaviors.password = {
attach: function(context) {
var translate = Drupal.settings.password;
$("input.password-field:not(.password-processed)", context).each(function() {
var passwordInput = $(this).addClass('password-processed');
......@@ -83,6 +83,7 @@ Drupal.behaviors.password = function(context) {
passwordInput.keyup(passwordCheck).focus(passwordCheck).blur(passwordCheck);
confirmInput.keyup(passwordCheckMatch).blur(passwordCheckMatch);
});
}
};
/**
......@@ -171,9 +172,10 @@ Drupal.setDefaultTimezone = function() {
* picture-related form elements depending on the current value of the
* "Picture support" radio buttons.
*/
Drupal.behaviors.userSettings = function (context) {
Drupal.behaviors.userSettings = {
attach: function(context) {
$('div.user-admin-picture-radios input[type=radio]:not(.userSettings-processed)', context).addClass('userSettings-processed').click(function () {
$('div.user-admin-picture-settings', context)[['hide', 'show'][this.value]]();
});
}
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment