? .DS_Store ? .patch ? head.db ? incremental_filter_access_control-229193-53.patch ? incremental_filter_access_control-229193-55.patch ? incremental_filter_access_control-229193-56.patch ? incremental_filter_access_control-229193-60.patch ? modules/.DS_Store ? sites/.DS_Store ? sites/all/.DS_Store ? sites/all/modules/.DS_Store ? sites/all/modules/permission_test ? sites/all/modules/permission_test 2.zip ? sites/all/modules/permission_test.zip ? sites/default/files ? sites/default/settings.php Index: modules/user/user.admin.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/user/user.admin.inc,v retrieving revision 1.37 diff -u -p -r1.37 user.admin.inc --- modules/user/user.admin.inc 3 Feb 2009 18:55:32 -0000 1.37 +++ modules/user/user.admin.inc 17 Feb 2009 04:30:18 -0000 @@ -480,7 +480,7 @@ function user_admin_settings() { '#prefix' => '
', '#suffix' => '
', ); - 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 @@ -593,6 +596,15 @@ function user_admin_perm($form_state, $r } /** + * Add the JavaScript to the page necessary to make the user permission page work. + */ +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. * * @see user_admin_perm @@ -633,6 +645,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 +656,7 @@ function theme_user_admin_perm($form) { $rows[] = $row; } } - $header[] = (t('Permission')); + $header[] = array('data' => t('Permission'), '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 17 Feb 2009 04:30:18 -0000 @@ -0,0 +1,212 @@ +// $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]](); + }); + } +}; + +/** + * Incrementally filter user permissions. + */ +Drupal.behaviors.userPermissions = { + attach: function(context) { + // Process the date and time, to make sure that there is a 100ms delay + // between iterations of the filter, or otherwise fast typers would make + // the filter unbearably slow. + var time = (new Date()).getTime(), newTime = time; + $('.permission-header:not(.userPermissions-processed)', context).addClass('.userPermissions-processed').text(Drupal.t('Filter: ')).append( + $('').bind('keyup', function() { + Drupal.userPermissionSearch($(this).val()); + }) + ); + } +}; + +/** + * Search callback - search for user permissions. + */ +Drupal.userPermissionSearch = function(term) { + if (!term) { + $('#permissions > tbody > tr.user-permissions-empty').remove(); + $('#user-admin-perm > div > input#edit-submit').show(); + $('#permissions > tbody > tr').show().find('.highlight').removeClass('highlight').end(); + } + else { + var previousModule = false; + 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(); + isEmpty = false; + previousModule = false; + td.html(foundTerm); + } + else { + // Text not found. Hide the row. + $(this).hide(); + } + } + else { + // If this isn't a permission, we've already interated through all + // permissions of the previous module, and we're on to the next module, + // then hide the previous module. + 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 { + var zebra = false; + $("table tbody tr:visible[td.permission]").each(function() { + zebra = !zebra; $(this).removeClass('even').removeClass('odd').addClass(zebra == false? 'odd' : 'even'); + }); + $('#permissions > tbody > tr .user-permissions-empty').remove(); + $('#user-admin-perm > div > input#edit-submit').show(); + } + } +} + +/** + * Highlight the search term as found in the user permission. + */ +Drupal.theme.userPermissionHighlight = function(prefix, highlight, postfix) { + return prefix + '' + highlight + '' + postfix; +}; + +/** + * Highlight the instance of a term in a user permisison. + */ +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 17 Feb 2009 04:30:18 -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 17 Feb 2009 04:30:18 -0000 @@ -158,16 +158,3 @@ Drupal.evaluatePasswordStrength = functi msg = translate.hasWeaknesses + ""; 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]](); - }); - } -};