diff --git a/modules/user/user.admin.inc b/modules/user/user.admin.inc
index afaddeb..53ade47 100644
--- a/modules/user/user.admin.inc
+++ b/modules/user/user.admin.inc
@@ -712,7 +712,12 @@ function user_admin_permissions($form, $form_state, $rid = NULL) {
// Have to build checkboxes here after checkbox arrays are built
foreach ($role_names as $rid => $name) {
- $form['checkboxes'][$rid] = array('#type' => 'checkboxes', '#options' => $options, '#default_value' => isset($status[$rid]) ? $status[$rid] : array());
+ $form['checkboxes'][$rid] = array(
+ '#type' => 'checkboxes',
+ '#options' => $options,
+ '#default_value' => isset($status[$rid]) ? $status[$rid] : array(),
+ '#attributes' => array('class' => array('rid-' . $rid)),
+ );
$form['role_names'][$rid] = array('#markup' => check_plain($name), '#tree' => TRUE);
}
diff --git a/modules/user/user.permissions.js b/modules/user/user.permissions.js
index 4ef576c..ee36fd9 100644
--- a/modules/user/user.permissions.js
+++ b/modules/user/user.permissions.js
@@ -5,34 +5,47 @@
*/
Drupal.behaviors.permissions = {
attach: function (context) {
- $('table#permissions:not(.permissions-processed)').each(function () {
+ var self = this;
+ $('table#permissions').once('permissions', function () {
// Create dummy checkboxes. We use dummy checkboxes instead of reusing
// the existing checkboxes here because new checkboxes don't alter the
// submitted form. If we'd automatically check existing checkboxes, the
// permission table would be polluted with redundant entries. This
// is deliberate, but desirable when we automatically check them.
- $(':checkbox', this).not('[name^="2["]').not('[name^="1["]').each(function () {
- $(this).addClass('real-checkbox');
- $('')
- .attr('title', Drupal.t("This permission is inherited from the authenticated user role."))
- .insertAfter(this)
- .hide();
- });
+ var $dummy = $('')
+ .attr('title', Drupal.t("This permission is inherited from the authenticated user role."))
+ .hide();
- // Helper function toggles all dummy checkboxes based on the checkboxes'
- // state. If the "authenticated user" checkbox is checked, the checked
- // and disabled checkboxes are shown, the real checkboxes otherwise.
- var toggle = function () {
- $(this).closest('tr')
- .find('.real-checkbox')[this.checked ? 'hide' : 'show']().end()
- .find('.dummy-checkbox')[this.checked ? 'show' : 'hide']();
- };
+ $(':checkbox:not(.rid-2,.rid-1)', this).addClass('real-checkbox').each(function () {
+ $dummy.clone().insertAfter(this);
+ });
// Initialize the authenticated user checkbox.
- $(':checkbox[name^="2["]', this)
- .click(toggle)
- .each(function () { toggle.call(this); });
- }).addClass('permissions-processed');
+ $(':checkbox.rid-2', this)
+ .bind('click.permissions', self.toggle)
+ // .triggerHandler() cannot be used here, as it only affects the first
+ // element.
+ .each(self.toggle);
+ });
+ },
+
+ /**
+ * Toggles all dummy checkboxes based on the checkboxes' state.
+ *
+ * If the "authenticated user" checkbox is checked, the checked and disabled
+ * checkboxes are shown, the real checkboxes otherwise.
+ */
+ toggle: function () {
+ var authCheckbox = this, $row = $(this).closest('tr');
+ // jQuery performs too many layout calculations for .hide() and .show(),
+ // leading to a major page rendering lag on sites with many roles and
+ // permissions. Therefore, we toggle visibility directly.
+ $row.find('.real-checkbox').each(function () {
+ this.style.display = (authCheckbox.checked ? 'none' : '');
+ });
+ $row.find('.dummy-checkbox').each(function () {
+ this.style.display = (authCheckbox.checked ? '' : 'none');
+ });
}
};