fpa.js 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. (function ($) {
  2. var fpa = {
  3. selector : {
  4. form: '#user-admin-permissions',
  5. table : '#permissions',
  6. row : 'tbody tr',
  7. filter : 'td.permission',
  8. grouping : 'td.module'
  9. },
  10. dom : {
  11. table : '', // jquery object for entire permissions table
  12. rows : '', // jquery object containing just the rows
  13. perm_style : '', // jquery object containing permissions style
  14. role_style : '', // jquery object containing roles style
  15. section_left: '',
  16. section_right: ''
  17. },
  18. search:''
  19. };
  20. /**
  21. * Kick a function to the Back Of The Line.
  22. *
  23. * Anything that is botl'd will run after other attach events, like sticky table headers.
  24. */
  25. fpa.botl = function (func) {
  26. setTimeout(function () {
  27. func();
  28. }, 0);
  29. };
  30. /**
  31. * Changes a string into a safe single css class.
  32. */
  33. fpa.classify = function (str) {
  34. return str.toLowerCase().replace(/ /ig, '-');
  35. };
  36. /**
  37. * Callback for click events on module list.
  38. */
  39. fpa.filter_module = function () {
  40. var $this = $(this);
  41. $('div.fpa-left-section ul li').removeClass('active');
  42. $this.parent().addClass('active');
  43. var current_perm = fpa.dom.filter.val().split('@');
  44. current_perm[1] = $this.attr('title');
  45. fpa.dom.filter.val(current_perm.join('@').replace(/@$/ig, '')); // remove trailing @ as that means no module; clean 'All' filter value
  46. fpa.filter('=');
  47. };
  48. fpa.filter = function (module_match) {
  49. module_match = module_match || '*=';
  50. perm = fpa.dom.filter.val();
  51. fpa.botl(function () {
  52. if (typeof perm != 'undefined' && ['', '@'].indexOf(perm) == -1) {
  53. var perm_copy = fpa.classify(perm).split('@');
  54. var selector = fpa.selector.table + ' ' + fpa.selector.row;
  55. var perm_style_code = selector + '[fpa-module]{display:none;}';
  56. if (perm_copy[0]) selector += '[fpa-permission*="' + perm_copy[0] + '"]';
  57. if (perm_copy[1]) selector += '[fpa-module' + module_match + '"' + perm_copy[1] + '"]';
  58. perm_style_code += selector + '{display: table-row;}';
  59. fpa.dom.perm_style[0].innerHTML = perm_style_code;
  60. }
  61. else {
  62. fpa.dom.perm_style[0].innerHTML = '';
  63. }
  64. });
  65. };
  66. fpa.prepare = function (context) {
  67. fpa.dom.form = $(fpa.selector.form, context);
  68. if (fpa.dom.form.length == 0) {
  69. return;
  70. }
  71. fpa.dom.table = fpa.dom.form.find(fpa.selector.table);
  72. fpa.dom.section_right = fpa.dom.table.wrap('<div class="fpa-right-section" />').parent();
  73. fpa.dom.module_list = $('<ul />').insertBefore(fpa.dom.section_right).wrap('<div class="fpa-left-section" />');
  74. // create module list
  75. fpa.dom.all_modules = $('<div />')
  76. .appendTo(fpa.dom.module_list)
  77. .wrap('<li class="active" />')
  78. .text('All modules')
  79. .attr('title', '')
  80. .click(fpa.filter_module);
  81. fpa.dom.table.find(fpa.selector.grouping).each(function () {
  82. var module_id = $(this).text();
  83. // Add new item to module list.
  84. $('<div />')
  85. .appendTo(fpa.dom.module_list)
  86. .wrap('<li />')
  87. .text(module_id.replace(/ module$/ig, ''))
  88. .attr('title', module_id)
  89. .attr('fpa-module', fpa.classify(module_id))
  90. .click(fpa.filter_module);
  91. });
  92. // tag rows with required classes
  93. fpa.botl(function () {
  94. fpa.dom.filter_form = $('<div class="fpa-filter-form" />').prependTo(fpa.dom.section_right);
  95. fpa.dom.perm_style = $('<style type="text/css" />').prependTo(fpa.dom.section_right);
  96. fpa.dom.role_style = $('<style type="text/css" />').prependTo(fpa.dom.section_right);
  97. // Put the "Save Permissions" button at the top and bottom.
  98. fpa.dom.form.find('input[type="submit"][name="op"]').remove()
  99. .clone().insertAfter(fpa.dom.module_list)
  100. .clone().insertAfter(fpa.dom.table);
  101. fpa.dom.filter = $('<input id="fpa_filter" type="text" class="form-text" placeholder="permission@module" />')
  102. .appendTo(fpa.dom.filter_form)
  103. .keypress(function (e) {
  104. //prevent enter key from submitting form
  105. if (e.which == 13) {
  106. return false;
  107. }
  108. })
  109. .keyup(function (e) {
  110. fpa.filter();
  111. })
  112. .wrap('<div id="fpa-filter-perm" class="form-item" />')
  113. .before('<label for="fpa_filter">Filter:</label>')
  114. .after('<div class="description">Enter in the format of permission@module;<br /> E.g. admin@system will show only permissions with<br />the text "admin" in modules with the text "system".</div>')
  115. .val(Drupal.settings.fpa.perm);
  116. $('<button class="clear-search">Clear Filter</button>')
  117. .insertAfter(fpa.dom.filter)
  118. .click(function (e) {
  119. e.preventDefault();
  120. fpa.dom.filter.val('');
  121. fpa.filter();
  122. fpa.dom.all_modules.click();
  123. });
  124. var roles_select = $('<select multiple="multiple" size=5 />')
  125. .appendTo(fpa.dom.filter_form)
  126. .wrap('<div id="fpa-filter-role" class="form-item" />')
  127. .before('<label for="fpa_filter">Roles:</label>')
  128. .after('<div class="description">Select which roles to display.<br />Ctrl+click to select multiple.</div>')
  129. .change(function () {
  130. var values = $(this).val();
  131. var selector_array = [];
  132. var role_style_code = fpa.selector.table + ' .checkbox{display:none;}';
  133. for (i in values) {
  134. selector_array.push(fpa.selector.table + ' .checkbox[title^="' + values[i] + '"]');
  135. }
  136. role_style_code += selector_array.join(',') + '{display: table-cell;}';
  137. fpa.dom.role_style[0].innerHTML = role_style_code;
  138. });
  139. fpa.dom.rows = fpa.dom.table.find(fpa.selector.row);
  140. var roles = fpa.dom.table.find('thead th.checkbox').each(function () {
  141. $this = $(this);
  142. var role_text = $this.text();
  143. var index = $this.attr('title', role_text).index() + 1;
  144. fpa.dom.rows.find('td:nth-child(' + index + ')').attr('title', role_text);
  145. $('<option />')
  146. .appendTo(roles_select)
  147. .attr('value', $this.text())
  148. .attr('selected', 'selected')
  149. .text($this.text());
  150. });
  151. var module_id = '';
  152. var $module_row;
  153. // iterate over the rows
  154. fpa.dom.rows.each(function () {
  155. var $this = $(this);
  156. // Is this a module row?
  157. var new_module_id = $this.find(fpa.selector.grouping).text();
  158. if (new_module_id != '') {
  159. $module_row = $this.addClass('module');
  160. module_id = fpa.classify(new_module_id);
  161. }
  162. var perm = $this.find(fpa.selector.filter).clone();
  163. perm.find('div.description').remove();
  164. var permission = fpa.classify($.trim(perm.text()));
  165. $this.attr('fpa-module', module_id).attr('fpa-permission', permission);
  166. $module_row.attr('fpa-permission', $module_row.attr('fpa-permission') + ' ' + permission);
  167. });
  168. if (Drupal.settings.fpa.perm == '' && window.location.hash.indexOf('module-') > -1) {
  169. fpa.dom.filter.val('@' + window.location.hash.substring(8));
  170. fpa.filter('=');
  171. }
  172. fpa.filter();
  173. fpa.dom.form.addClass('show');
  174. fpa.dom.filter.focus();
  175. });
  176. };
  177. fpa.modalframe = function (context) {
  178. $('a.fpa_modalframe', context).click(function (e) {
  179. e.preventDefault();
  180. e.stopPropagation();
  181. Drupal.modalFrame.open({
  182. url: $(this).attr('href'),
  183. draggable: false
  184. });
  185. });
  186. };
  187. Drupal.behaviors.fpa = {attach: function (context) {
  188. fpa.prepare(context);
  189. fpa.modalframe(context);
  190. }};
  191. })(jQuery);