',
);
- drupal_add_js(drupal_get_path('module', 'user') . '/user.js');
+ drupal_add_js(drupal_get_path('module', 'user') . '/user.admin.js');
// If JS is enabled, and the radio is defaulting to off, hide all
// the settings on page load via .css using the js-hide class so
// that there's no flicker.
@@ -542,7 +542,7 @@ function user_admin_settings() {
* @see theme_user_admin_perm()
*/
function user_admin_perm($form_state, $rid = NULL) {
-
+ drupal_add_js(drupal_get_path('module', 'user') .'/user.admin.js');
// Retrieve role names for columns.
$role_names = user_roles();
if (is_numeric($rid)) {
@@ -559,6 +559,7 @@ function user_admin_perm($form_state, $r
// Render role/permission overview:
$options = array();
$hide_descriptions = !system_admin_compact_mode();
+ $index = 0;
foreach (module_implements('perm') as $module) {
if ($permissions = module_invoke($module, 'perm')) {
$info = drupal_parse_info_file(drupal_get_path('module', $module) . "/$module.info");
@@ -571,6 +572,8 @@ function user_admin_perm($form_state, $r
'#type' => 'item',
'#markup' => $perm_item['title'],
'#description' => $hide_descriptions ? $perm_item['description'] : NULL,
+ '#post_render' => array('user_admin_perm_post_render'),
+ '#index' => $index++,
);
foreach ($role_names as $rid => $name) {
// Builds arrays for checked boxes for each role
@@ -592,6 +595,12 @@ function user_admin_perm($form_state, $r
return $form;
}
+function user_admin_perm_post_render($html, $form) {
+ $clean = trim(preg_replace('/\s+/', ' ', $html));
+ drupal_add_js(array('userPerm' => array($form['#index'] => array('stripped' => strtolower(strip_tags((string)$clean)), 'pieces' => preg_split('/(<[^>]+>)/', (string)$clean, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_OFFSET_CAPTURE)))), 'setting');
+ return $html;
+}
+
/**
* Save permissions selected on the administer permissions page.
*
@@ -633,6 +642,7 @@ function theme_user_admin_perm($form) {
$row[] = array(
'data' => drupal_render($form['permission'][$key]),
'class' => 'permission',
+ 'id' => 'permission-' . $form['permission'][$key]['#index'],
);
foreach (element_children($form['checkboxes']) as $rid) {
if (is_array($form['checkboxes'][$rid])) {
@@ -643,7 +653,7 @@ function theme_user_admin_perm($form) {
$rows[] = $row;
}
}
- $header[] = (t('Permission'));
+ $header[] = array('data' => t('Filter: '), 'class' => 'permission-header');
foreach (element_children($form['role_names']) as $rid) {
if (is_array($form['role_names'][$rid])) {
$header[] = array('data' => drupal_render($form['role_names'][$rid]), 'class' => 'checkbox');
Index: modules/user/user.admin.js
===================================================================
RCS file: modules/user/user.admin.js
diff -N modules/user/user.admin.js
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/user/user.admin.js 14 Feb 2009 18:41:03 -0000
@@ -0,0 +1,206 @@
+// $Id$
+
+/**
+ * On the admin/user/settings page, conditionally show all of the
+ * picture-related form elements depending on the current value of the
+ * "Picture support" radio buttons.
+ */
+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]]();
+ });
+ }
+};
+
+Drupal.behaviors.userPermissions = {
+ attach: function(context) {
+ var time = (new Date()).getTime(), newTime = (new Date()).getTime();
+ $('.permission-header:not(.userPermissions-processed)', context).addClass('.userPermissions-processed').append(' ').append(
+ $('').bind('keyup mouseup', function() {
+ $('.permission-header > input.form-text').val($(this).val());
+ newTime = (new Date()).getTime();
+ if (time + 100 < newTime) {
+ Drupal.userPermissionSearch($(this).val());
+ }
+ time = newTime;
+ })
+ );
+ }
+};
+
+Drupal.userPermissionSearch = function(term) {
+ if (term) {
+ var previousModule = false;
+ var zebra = true;
+ var isEmpty = true;
+ $('#permissions > tbody > tr').each(function() {
+ td = $(this).find('td:first');
+ if (td.is('.permission')) {
+ var index = td.attr('id').replace('permission-', '');
+ // If we have found the text in the stripped string, get the first character position
+ // of the found string.
+ var found_begin = Drupal.settings.userPerm[index].stripped.indexOf(term);
+ // If it was found, begin highlighting
+ if (found_begin !== -1) {
+ var foundTerm = Drupal.termInstance(term, Drupal.settings.userPerm[index], found_begin, Drupal.theme.userPermissionHighlight);
+ $(this).show().removeClass('even').removeClass('odd').addClass(zebra == false? 'odd' : 'even');
+ isEmpty = false;
+ previousModule = false;
+ zebra = !zebra;
+ td.html(foundTerm);
+ }
+ else {
+ // Text not found. Hide the row.
+ $(this).hide();
+ }
+ }
+ else {
+ if (previousModule != false) {
+ previousModule.hide();
+ }
+ previousModule = $(this).show();
+ }
+ });
+ if (previousModule != false) {
+ previousModule.hide();
+ }
+ if (isEmpty) {
+ $('#permissions > tbody > tr').hide().parent().append('
No permissions were found.
');
+ $('#user-admin-perm > div > input#edit-submit').hide();
+ }
+ else {
+ $('#permissions > tbody > tr .user-permissions-empty').remove();
+ $('#user-admin-perm > div > input#edit-submit').show();
+ }
+ }
+ else {
+ $('#permissions > tbody > tr.user-permissions-empty').remove();
+ $('#user-admin-perm > div > input#edit-submit').show();
+ var zebra = false;
+ $('#permissions > tbody > tr').each(function() {
+ if (zebra) {
+ $(this).addClass('even').removeClass('odd');
+ }
+ else {
+ $(this).addClass('odd').removeClass('even');
+ }
+ zebra = !zebra;
+ }).show().find('.highlight').removeClass('highlight').end()
+ }
+}
+
+Drupal.theme.userPermissionHighlight = function(prefix, highlight, postfix) {
+ return prefix + '' + highlight + '' + postfix;
+};
+
+Drupal.termInstance = function(term, instance, found_begin, found) {
+ // Length of the search string.
+ var search_length = term.length,
+ // The last character position of the search string in the stripped string.
+ found_end = found_begin + search_length,
+ // The final, assembled string.
+ output = '',
+ // Whether the device is currently highlighting.
+ highlight = false,
+ // Whether the device has encountered the first chunk that contains the search string.
+ first_chunk = false,
+ // Whether the loop is about to encounter a tag.
+ tag = false,
+ // The offset, so far, between the string with HTML and string without HTML. Each
+ // time another chunk gets processed, if the chunk is a tag, this value is incremented
+ // by the length of the chunk.
+ tag_length = 0;
+ // Iterate through the chunks.
+ for (var i = 0; i < instance.pieces.length; i++) {
+ // Get the current chunk.
+ var chunk = instance.pieces[i][0],
+ // Chunk length.
+ length_of_chunk = chunk.length;
+ // If we're in a tag, add the tag to the tag_length variable, and do nothing else.
+ if (tag) {
+ tag_length += length_of_chunk;
+ }
+ // This is where the magic begins.
+ else {
+ // Get the starting offset of the chunk.
+ var start_of_chunk = instance.pieces[i][1],
+ // Get the end offset of the chunk.
+ end_of_chunk = start_of_chunk + length_of_chunk,
+ // Starting offset, but in the stripped string.
+ start_of_chunk_in_stripped = start_of_chunk - tag_length,
+ // Ending offset, but in the stripped string.
+ end_of_chunk_in_stripped = end_of_chunk - tag_length;
+ // If the first character of the found string is within the chunk's offsets in the
+ // stripped string, then we have found the first chunk.
+ if (start_of_chunk_in_stripped <= found_begin && found_begin < end_of_chunk_in_stripped) {
+ highlight = true;
+ first_chunk = true;
+ }
+ if (highlight) {
+ // If it's the last chunk, that means that the end of the search string is before
+ // the end of the chunk.
+ var last_chunk = found_end <= end_of_chunk_in_stripped;
+ if (last_chunk) {
+ // If that's true, then stop highlighting after this.
+ highlight = false;
+ }
+ // The prefix before the chunk if it's the first chunk.
+ var prefix = '',
+ // The postfix, after the chunk, if it's the last chunk.
+ postfix = '',
+ // The offset at which to start the highlighting.
+ start = 0,
+ // The length to highlight.
+ length = length_of_chunk,
+ // Whether we need to run a substring or not.
+ substr = false;
+ // If we're in the first chunk...
+ if (first_chunk) {
+ // We need to run substring to generate a prefix.
+ // Where to end the prefix, and start the highlight.
+ start = found_begin - start_of_chunk_in_stripped;
+ // Generate the prefix.
+ prefix = chunk.substr(0, start);
+ // We might as well set substring length to the full length of the search string -
+ // in the worst case, it will go to a longer length than needed, and there's no breakage
+ // that will happen.
+ length = search_length;
+ // Yes, we need a substring.
+ substr = true;
+ }
+ // If we're in the last chunk, we need to find the postfix.
+ if (last_chunk) {
+ // If we're not in the first chunk, the length is not the length of the
+ // search string, so calculate it.
+ if (!first_chunk) {
+ length = found_end - start_of_chunk_in_stripped;
+ }
+ // Get the postfix.
+ postfix = chunk.substr(start + length, length_of_chunk);
+ // And we need to substring.
+ substr = true;
+ }
+ // The text to highlight.
+ var chunk_to_highlight;
+ // If we need a substring, get it.
+ if (substr) {
+ chunk_to_highlight = chunk.substr(start, length);
+ }
+ // Otherwise, just get the chunk.
+ else {
+ chunk_to_highlight = chunk;
+ }
+ // Slap it all together.
+ chunk = found(prefix, chunk_to_highlight, postfix);
+ // We're not in the first chunk.
+ first_chunk = false;
+ }
+ }
+ // Add the chunk to the general output.
+ output += chunk;
+ // If we weren't in the tag, we are now, and vise-versa.
+ tag = !tag;
+ }
+ return output;
+}
\ No newline at end of file
Index: modules/user/user.css
===================================================================
RCS file: /cvs/drupal/drupal/modules/user/user.css,v
retrieving revision 1.10
diff -u -p -r1.10 user.css
--- modules/user/user.css 9 Oct 2008 04:19:44 -0000 1.10
+++ modules/user/user.css 14 Feb 2009 18:41:03 -0000
@@ -9,6 +9,9 @@
#permissions tr.odd .form-item, #permissions tr.even .form-item {
white-space: normal;
}
+#permissions td span.highlight {
+ background-color: #ff6;
+}
#user-login-form {
text-align: center;
}
Index: modules/user/user.js
===================================================================
RCS file: /cvs/drupal/drupal/modules/user/user.js,v
retrieving revision 1.9
diff -u -p -r1.9 user.js
--- modules/user/user.js 20 Nov 2008 06:56:17 -0000 1.9
+++ modules/user/user.js 14 Feb 2009 18:41:03 -0000
@@ -158,16 +158,3 @@ Drupal.evaluatePasswordStrength = functi
msg = translate.hasWeaknesses + "
" + msg.join("
") + "
";
return { strength: strength, message: msg };
};
-
-/**
- * On the admin/user/settings page, conditionally show all of the
- * picture-related form elements depending on the current value of the
- * "Picture support" radio buttons.
- */
-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]]();
- });
- }
-};