includes/clientside/static/acl.js
changeset 1 fe660c52c48f
child 40 723bb7acf914
equal deleted inserted replaced
0:902822492a68 1:fe660c52c48f
       
     1 // Javascript routines for the ACL editor
       
     2 
       
     3 var aclManagerID = 'enano_aclmanager_' + Math.floor(Math.random() * 1000000);
       
     4 var aclPermList = false;
       
     5 var aclDataCache = false;
       
     6 
       
     7 function ajaxOpenACLManager(page_id, namespace)
       
     8 {
       
     9   if(IE)
       
    10     return true;
       
    11   if(!page_id || !namespace)
       
    12   {
       
    13     var data = strToPageID(title);
       
    14     var page_id = data[0];
       
    15     var namespace = data[1];
       
    16   }
       
    17   var params = {
       
    18       'mode' : 'listgroups',
       
    19       'page_id' : page_id,
       
    20       'namespace' : namespace
       
    21     };
       
    22   params = toJSONString(params);
       
    23   params = ajaxEscape(params);
       
    24   ajaxPost(stdAjaxPrefix+'&_mode=acljson', 'acl_params='+params, function() {
       
    25       if(ajax.readyState == 4)
       
    26       {
       
    27         __aclBuildWizardWindow();
       
    28         groups = parseJSON(ajax.responseText);
       
    29         aclDataCache = groups;
       
    30         __aclBuildSelector(groups);
       
    31       }
       
    32     });
       
    33   return false;
       
    34 }
       
    35 
       
    36 function ajaxACLSwitchToSelector()
       
    37 {
       
    38   params = {
       
    39       'mode' : 'listgroups'
       
    40     };
       
    41   if ( aclDataCache.page_id && aclDataCache.namespace )
       
    42   {
       
    43     params.page_id   = aclDataCache.page_id;
       
    44     params.namespace = aclDataCache.namespace;
       
    45   }
       
    46   params = toJSONString(params);
       
    47   params = ajaxEscape(params);
       
    48   ajaxPost(stdAjaxPrefix+'&_mode=acljson', 'acl_params='+params, function() {
       
    49       if(ajax.readyState == 4)
       
    50       {
       
    51         document.getElementById(aclManagerID+'_main').innerHTML = '';
       
    52         document.getElementById(aclManagerID + '_back').style.display = 'none';
       
    53         document.getElementById(aclManagerID + '_next').value = 'Next >';
       
    54         groups = parseJSON(ajax.responseText);
       
    55         aclDataCache = groups;
       
    56         thispage = strToPageID(title);
       
    57         groups.page_id = thispage[0];
       
    58         groups.namespace = thispage[1];
       
    59         __aclBuildSelector(groups);
       
    60       }
       
    61     });
       
    62 }
       
    63 
       
    64 function __aclBuildSelector(groups)
       
    65 {
       
    66   thispage = strToPageID(title);
       
    67   do_scopesel = ( thispage[0] == groups.page_id && thispage[1] == groups.namespace );
       
    68   
       
    69   seed = Math.floor(Math.random() * 1000000);
       
    70         
       
    71   main = document.getElementById(aclManagerID + '_main');
       
    72   main.style.padding = '10px';
       
    73   
       
    74   selector = document.createElement('div');
       
    75   
       
    76   grpsel = __aclBuildGroupsHTML(groups);
       
    77   grpsel.name = 'group_id';
       
    78   
       
    79   span = document.createElement('div');
       
    80   span.id = "enACL_grpbox_"+seed+"";
       
    81   
       
    82   // Build the selector
       
    83   grpb = document.createElement('input');
       
    84   grpb.type = 'radio';
       
    85   grpb.name  = 'target_type';
       
    86   grpb.value = 1; // ACL_TYPE_GROUP
       
    87   grpb.checked = 'checked';
       
    88   grpb.className = seed;
       
    89   grpb.onclick = function() { seed = this.className; document.getElementById('enACL_grpbox_'+seed).style.display = 'block'; document.getElementById('enACL_usrbox_'+seed).style.display = 'none'; };
       
    90   lbl = document.createElement('label');
       
    91   lbl.appendChild(grpb);
       
    92   lbl.appendChild(document.createTextNode('A usergroup'));
       
    93   lbl.style.display = 'block';
       
    94   span.appendChild(grpsel);
       
    95   
       
    96   usrb = document.createElement('input');
       
    97   usrb.type = 'radio';
       
    98   usrb.name  = 'target_type';
       
    99   usrb.value = 2; // ACL_TYPE_USER
       
   100   usrb.className = seed;
       
   101   usrb.onclick = function() { seed = this.className; document.getElementById('enACL_grpbox_'+seed).style.display = 'none'; document.getElementById('enACL_usrbox_'+seed).style.display = 'block'; };
       
   102   lbl2 = document.createElement('label');
       
   103   lbl2.appendChild(usrb);
       
   104   lbl2.appendChild(document.createTextNode('A specific user'));
       
   105   lbl2.style.display = 'block';
       
   106   
       
   107   usrsel = document.createElement('input');
       
   108   usrsel.type = 'text';
       
   109   usrsel.name = 'username';
       
   110   usrsel.onkeyup = function() { ajaxUserNameComplete(this); };
       
   111   usrsel.id = 'userfield_' + aclManagerID;
       
   112   try {
       
   113     usrsel.setAttribute("autocomplete","off");
       
   114   } catch(e) {};
       
   115   
       
   116   span2 = document.createElement('div');
       
   117   span2.id = "enACL_usrbox_"+seed+"";
       
   118   span2.style.display = 'none';
       
   119   span2.appendChild(usrsel);
       
   120   
       
   121   // Scope selector
       
   122   if(do_scopesel)
       
   123   {
       
   124     scopediv1 = document.createElement('div');
       
   125     scopediv2 = document.createElement('div');
       
   126     scopeRadioPage = document.createElement('input');
       
   127       scopeRadioPage.type = 'radio';
       
   128       scopeRadioPage.name = 'scope';
       
   129       scopeRadioPage.value = 'page';
       
   130       scopeRadioPage.checked = 'checked';
       
   131     scopeRadioGlobal = document.createElement('input');
       
   132       scopeRadioGlobal.type = 'radio';
       
   133       scopeRadioGlobal.name = 'scope';
       
   134       scopeRadioGlobal.value = 'global';
       
   135     lblPage = document.createElement('label');
       
   136       lblPage.style.display = 'block';
       
   137       lblPage.appendChild(scopeRadioPage);
       
   138       lblPage.appendChild(document.createTextNode('Only this page'));
       
   139     lblGlobal = document.createElement('label');
       
   140       lblGlobal.style.display = 'block';
       
   141       lblGlobal.appendChild(scopeRadioGlobal);
       
   142       lblGlobal.appendChild(document.createTextNode('The entire website'));
       
   143     scopediv1.appendChild(lblPage);
       
   144     scopediv2.appendChild(lblGlobal);
       
   145     
       
   146     scopedesc = document.createElement('p');
       
   147     scopedesc.appendChild(document.createTextNode('What should this access rule control?'));
       
   148   }
       
   149   
       
   150   // Styles
       
   151   span.style.marginLeft = '13px';
       
   152   span.style.padding = '5px 0';
       
   153   span2.style.marginLeft = '13px';
       
   154   span2.style.padding = '5px 0';
       
   155   
       
   156   selector.appendChild(lbl);
       
   157   selector.appendChild(span);
       
   158   
       
   159   selector.appendChild(lbl2);
       
   160   selector.appendChild(span2);
       
   161   
       
   162   container = document.createElement('div');
       
   163   container.style.margin = 'auto';
       
   164   container.style.width = '360px';
       
   165   container.style.paddingTop = '70px';
       
   166   
       
   167   head = document.createElement('h2');
       
   168   head.appendChild(document.createTextNode('Manage page access'));
       
   169   
       
   170   desc = document.createElement('p');
       
   171   desc.appendChild(document.createTextNode('Please select who should be affected by this access rule.'));
       
   172   
       
   173   container.appendChild(head);
       
   174   container.appendChild(desc);
       
   175   container.appendChild(selector);
       
   176   
       
   177   if(do_scopesel)
       
   178   {
       
   179     container.appendChild(scopedesc);
       
   180     container.appendChild(scopediv1);
       
   181     container.appendChild(scopediv2);
       
   182   }
       
   183   
       
   184   main.appendChild(container);
       
   185   
       
   186   var mode = document.createElement('input');
       
   187   mode.name = 'mode';
       
   188   mode.type = 'hidden';
       
   189   mode.id = aclManagerID + '_mode';
       
   190   mode.value = 'seltarget';
       
   191   
       
   192   var theform = document.getElementById(aclManagerID + '_formobj_id');
       
   193   if ( !theform.mode )
       
   194   {
       
   195     theform.appendChild(mode);
       
   196   }
       
   197   else
       
   198   {
       
   199     theform.removeChild(theform.mode);
       
   200     theform.appendChild(mode);
       
   201   }
       
   202 }
       
   203 
       
   204 var aclDebugWin = false;
       
   205 
       
   206 function aclDebug(text)
       
   207 {
       
   208   if(!aclDebugWin)
       
   209     aclDebugWin = pseudoWindowOpen("data:text/html;plain,<html><head><title>debug win</title></head><body><h1>Debug window</h1></body></html>", "aclDebugWin");
       
   210     setTimeout(function() {
       
   211   aclDebugWin.pre = aclDebugWin.document.createElement('pre');
       
   212   aclDebugWin.pre.appendChild(aclDebugWin.document.createTextNode(text));
       
   213   aclDebugWin.b = aclDebugWin.document.getElementsByTagName('body')[0];
       
   214     aclDebugWin.b.appendChild(aclDebugWin.pre);}, 1000);
       
   215 }
       
   216 
       
   217 var pseudoWindows = new Object();
       
   218 
       
   219 function pseudoWindowOpen(url, id)
       
   220 {
       
   221   if(pseudoWindows[id])
       
   222   {
       
   223     document.getElementById('pseudowin_ifr_'+id).src = url;
       
   224   }
       
   225   else
       
   226   {
       
   227     win = document.createElement('iframe');
       
   228     win.style.position='fixed';
       
   229     win.style.width = '640px';
       
   230     win.style.height = '480px';
       
   231     win.style.top = '0px';
       
   232     win.style.left = '0px';
       
   233     win.style.zIndex = getHighestZ() + 1;
       
   234     win.style.backgroundColor = '#FFFFFF';
       
   235     win.name = 'pseudo_ifr_'+id;
       
   236     win.id = 'pseudowindow_ifr_'+id;
       
   237     win.src = url;
       
   238     body = document.getElementsByTagName('body')[0];
       
   239     body.appendChild(win);
       
   240   }
       
   241   win_obj = eval("( pseudo_ifr_"+id+" )");
       
   242   return win_obj;
       
   243 }
       
   244 
       
   245 function __aclJSONSubmitAjaxHandler(params)
       
   246 {
       
   247   params = toJSONString(params);
       
   248   params = ajaxEscape(params);
       
   249   ajaxPost(stdAjaxPrefix+'&_mode=acljson', 'acl_params='+params, function() {
       
   250       if(ajax.readyState == 4)
       
   251       {
       
   252         try {
       
   253           data = parseJSON(ajax.responseText);
       
   254         } catch(e) {
       
   255           aclDebug(e+"\n\nResponse:\n"+ajax.responseText);
       
   256         }
       
   257         aclDataCache = data;
       
   258         switch(data.mode)
       
   259         {
       
   260           case 'seltarget':
       
   261             
       
   262             // Build the ACL edit form
       
   263             // try {
       
   264               act_desc = ( data.type == 'new' ) ? 'Create access rule' : 'Editing permissions';
       
   265               target_type_t = ( data.target_type == 1 ) ? 'group' : 'user';
       
   266               target_name_t = data.target_name;
       
   267               var scope_type = ( data.page_id == false && data.namespace == false ) ? 'this entire site' : 'this page';
       
   268               html = '<h2>'+act_desc+'</h2><p>This panel allows you to edit what the '+target_type_t+' "<b>'+target_name_t+'</b>" can do on <b>' + scope_type + '</b>. Unless you set a permission to "Deny", these permissions may be overridden by other rules.</p>';
       
   269               parser = new templateParser(data.template.acl_field_begin);
       
   270               html += parser.run();
       
   271               
       
   272               cls = 'row2';
       
   273               for(var i in data.acl_types)
       
   274               {
       
   275                 if(typeof(data.acl_types[i]) == 'number')
       
   276                 {
       
   277                   cls = ( cls == 'row1' ) ? 'row2' : 'row1';
       
   278                   p = new templateParser(data.template.acl_field_item);
       
   279                   vars = new Object();
       
   280                   vars['FIELD_DESC'] = data.acl_descs[i];
       
   281                   vars['FIELD_DENY_CHECKED'] = '';
       
   282                   vars['FIELD_DISALLOW_CHECKED'] = '';
       
   283                   vars['FIELD_WIKIMODE_CHECKED'] = '';
       
   284                   vars['FIELD_ALLOW_CHECKED'] = '';
       
   285                   vars['FIELD_NAME'] = i;
       
   286                   switch(data.current_perms[i])
       
   287                   {
       
   288                     case 1:
       
   289                       vars['FIELD_DENY_CHECKED'] = 'checked="checked"';
       
   290                       break;
       
   291                     case 2:
       
   292                     default:
       
   293                       vars['FIELD_DISALLOW_CHECKED'] = 'checked="checked"';
       
   294                       break;
       
   295                     case 3:
       
   296                       vars['FIELD_WIKIMODE_CHECKED'] = 'checked="checked"';
       
   297                       break;
       
   298                     case 4:
       
   299                       vars['FIELD_ALLOW_CHECKED'] = 'checked="checked"';
       
   300                       break;
       
   301                   }
       
   302                   vars['ROW_CLASS'] = cls;
       
   303                   p.assign_vars(vars);
       
   304                   html += p.run();
       
   305                 }
       
   306               }
       
   307               
       
   308               var parser = new templateParser(data.template.acl_field_end);
       
   309               html += parser.run();
       
   310               
       
   311               if(data.type == 'edit')
       
   312                 html += '<p id="'+aclManagerID+'_deletelnk" style="text-align: right;"><a href="#delete_acl_rule" onclick="if(confirm(\'Do you really want to delete this rule?\')) __aclDeleteRule(); return false;" style="color: red;">Delete this rule</a></p>';
       
   313               
       
   314               var main = document.getElementById(aclManagerID + '_main');
       
   315               main.innerHTML = html;
       
   316               
       
   317               var form = document.getElementById(aclManagerID + '_formobj_id');
       
   318               
       
   319               var modeobj = form_fetch_field(form, 'mode');
       
   320               if ( modeobj )
       
   321                 modeobj.value = 'save_' + data.type;
       
   322               else
       
   323                 alert('modeobj is invalid: '+modeobj);
       
   324               
       
   325               aclPermList = array_keys(data.acl_types);
       
   326               
       
   327               document.getElementById(aclManagerID + '_back').style.display = 'inline';
       
   328               document.getElementById(aclManagerID + '_next').value = 'Save Changes';
       
   329               
       
   330             // } catch(e) { alert(e); aclDebug(ajax.responseText); }
       
   331             
       
   332             break;
       
   333           case 'success':
       
   334             var note = document.createElement('div');
       
   335             note.className = 'info-box';
       
   336             note.style.marginLeft = '0';
       
   337             var b = document.createElement('b');
       
   338             b.appendChild(document.createTextNode('Permissions updated'));
       
   339             note.appendChild(b);
       
   340             note.appendChild(document.createElement('br'));
       
   341             note.appendChild(document.createTextNode('The permissions for '+data.target_name+' on this page have been updated successfully.'));
       
   342             note.appendChild(document.createElement('br'));
       
   343             var a = document.createElement('a');
       
   344             a.href = 'javascript:void(0);';
       
   345             a.onclick = function() { this.parentNode.parentNode.removeChild(this.parentNode); return false; };
       
   346             a.appendChild(document.createTextNode('[ dismiss :'));
       
   347             note.appendChild(a);
       
   348             var a2 = document.createElement('a');
       
   349             a2.href = 'javascript:void(0);';
       
   350             a2.onclick = function() { killACLManager(); return false; };
       
   351             a2.appendChild(document.createTextNode(': close manager ]'));
       
   352             note.appendChild(a2);
       
   353             document.getElementById(aclManagerID + '_main').insertBefore(note, document.getElementById(aclManagerID + '_main').firstChild);
       
   354             if(!document.getElementById(aclManagerID+'_deletelnk'))
       
   355               document.getElementById(aclManagerID + '_main').innerHTML += '<p id="'+aclManagerID+'_deletelnk" style="text-align: right;"><a href="#delete_acl_rule" onclick="if(confirm(\'Do you really want to delete this rule?\')) __aclDeleteRule(); return false;" style="color: red;">Delete this rule</a></p>';
       
   356             //fadeInfoBoxes();
       
   357             break;
       
   358           case 'delete':
       
   359             
       
   360             params = {
       
   361               'mode' : 'listgroups'
       
   362             };
       
   363           params = toJSONString(params);
       
   364           params = ajaxEscape(params);
       
   365           ajaxPost(stdAjaxPrefix+'&_mode=acljson', 'acl_params='+params, function() {
       
   366               if(ajax.readyState == 4)
       
   367               {
       
   368                 document.getElementById(aclManagerID+'_main').innerHTML = '';
       
   369                 document.getElementById(aclManagerID + '_back').style.display = 'none';
       
   370                 document.getElementById(aclManagerID + '_next').value = 'Next >';
       
   371                 var thispage = strToPageID(title);
       
   372                 groups.page_id = thispage[0];
       
   373                 groups.namespace = thispage[1];
       
   374                 __aclBuildSelector(groups);
       
   375                 
       
   376                 note = document.createElement('div');
       
   377                 note.className = 'info-box';
       
   378                 note.style.marginLeft = '0';
       
   379                 b = document.createElement('b');
       
   380                 b.appendChild(document.createTextNode('Entry deleted'));
       
   381                 note.appendChild(b);
       
   382                 note.appendChild(document.createElement('br'));
       
   383                 note.appendChild(document.createTextNode('The access rules for '+aclDataCache.target_name+' on this page have been deleted.'));
       
   384                 note.appendChild(document.createElement('br'));
       
   385                 a = document.createElement('a');
       
   386                 a.href = '#';
       
   387                 a.onclick = function() { this.parentNode.parentNode.removeChild(this.parentNode); return false; };
       
   388                 a.appendChild(document.createTextNode('[ dismiss :'));
       
   389                 note.appendChild(a);
       
   390                 a = document.createElement('a');
       
   391                 a.href = '#';
       
   392                 a.onclick = function() { killACLManager(); return false; };
       
   393                 a.appendChild(document.createTextNode(': close manager ]'));
       
   394                 note.appendChild(a);
       
   395                 document.getElementById(aclManagerID + '_main').insertBefore(note, document.getElementById(aclManagerID + '_main').firstChild);
       
   396                 //fadeInfoBoxes();
       
   397                 
       
   398               }
       
   399             });
       
   400             
       
   401             break;
       
   402           case 'error':
       
   403             alert("Server side processing error:\n"+data.error);
       
   404             break;
       
   405           case 'debug':
       
   406             aclDebug(data.text);
       
   407             break;
       
   408           default:
       
   409             alert("Invalid JSON response from server\nMode: "+data.mode+"\nJSON string: "+ajax.responseText);
       
   410             break;
       
   411         }
       
   412       }
       
   413     });
       
   414 }
       
   415 
       
   416 function __aclBuildGroupsHTML(groups)
       
   417 {
       
   418   groups = groups.groups;
       
   419   select = document.createElement('select');
       
   420   for(var i in groups)
       
   421   {
       
   422     if(typeof(groups[i]['name']) == 'string' && i != 'toJSONString')
       
   423     {
       
   424       o = document.createElement('option');
       
   425       o.value = groups[i]['id'];
       
   426       t = document.createTextNode(groups[i]['name']);
       
   427       o.appendChild(t);
       
   428       select.appendChild(o);
       
   429     }
       
   430   }
       
   431   return select;
       
   432 }
       
   433 
       
   434 function __aclBuildWizardWindow()
       
   435 {
       
   436   darken();
       
   437   box = document.createElement('div');
       
   438   box.style.width = '640px'
       
   439   box.style.height = '440px';
       
   440   box.style.position = 'fixed';
       
   441   width = getWidth();
       
   442   height = getHeight();
       
   443   box.style.left = ( width / 2 - 320 ) + 'px';
       
   444   box.style.top = ( height / 2 - 250 ) + 'px';
       
   445   box.style.backgroundColor = 'white';
       
   446   box.style.zIndex = getHighestZ() + 1;
       
   447   box.id = aclManagerID;
       
   448   box.style.opacity = '0';
       
   449   box.style.filter = 'alpha(opacity=0)';
       
   450   box.style.display = 'none';
       
   451   
       
   452   mainwin = document.createElement('div');
       
   453   mainwin.id = aclManagerID + '_main';
       
   454   mainwin.style.clip = 'rect(0px,640px,440px,0px)';
       
   455   mainwin.style.overflow = 'auto';
       
   456   mainwin.style.width = '620px';
       
   457   mainwin.style.height = '420px';
       
   458   
       
   459   panel = document.createElement('div');
       
   460   panel.style.width = '620px';
       
   461   panel.style.padding = '10px';
       
   462   panel.style.lineHeight = '40px';
       
   463   panel.style.textAlign = 'right';
       
   464   panel.style.position = 'fixed';
       
   465   panel.style.left = ( width / 2 - 320 ) + 'px';
       
   466   panel.style.top = ( height / 2 + 190 ) + 'px';
       
   467   panel.style.backgroundColor = '#D0D0D0';
       
   468   panel.style.opacity = '0';
       
   469   panel.style.filter = 'alpha(opacity=0)';
       
   470   panel.id = aclManagerID + '_panel';
       
   471   
       
   472   form = document.createElement('form');
       
   473   form.method = 'post';
       
   474   form.action = 'javascript:void(0)';
       
   475   form.onsubmit = function() { if(this.username && !submitAuthorized) return false; __aclSubmitManager(this); return false; };
       
   476   form.name = aclManagerID + '_formobj';
       
   477   form.id   = aclManagerID + '_formobj_id';
       
   478   
       
   479   back = document.createElement('input');
       
   480   back.type = 'button';
       
   481   back.value = '< Back';
       
   482   back.style.fontWeight = 'normal';
       
   483   back.onclick = function() { ajaxACLSwitchToSelector(); return false; };
       
   484   back.style.display = 'none';
       
   485   back.id = aclManagerID + '_back';
       
   486   
       
   487   saver = document.createElement('input');
       
   488   saver.type = 'submit';
       
   489   saver.value = 'Next >';
       
   490   saver.style.fontWeight = 'bold';
       
   491   saver.id = aclManagerID + '_next';
       
   492   
       
   493   closer = document.createElement('input');
       
   494   closer.type = 'button';
       
   495   closer.value = 'Cancel Changes';
       
   496   closer.onclick = function() { if(!confirm('Do you really want to close the ACL manager?')) return false; killACLManager(); return false; }
       
   497   
       
   498   spacer1 = document.createTextNode('  ');
       
   499   spacer2 = document.createTextNode('  ');
       
   500   
       
   501   panel.appendChild(back);
       
   502   panel.appendChild(spacer1);
       
   503   panel.appendChild(saver);
       
   504   panel.appendChild(spacer2);
       
   505   panel.appendChild(closer);
       
   506   form.appendChild(mainwin);
       
   507   form.appendChild(panel);
       
   508   box.appendChild(form);
       
   509   
       
   510   body = document.getElementsByTagName('body')[0];
       
   511   body.appendChild(box);
       
   512   setTimeout("document.getElementById('"+aclManagerID+"').style.display = 'block'; opacity('"+aclManagerID+"', 0, 100, 500); opacity('"+aclManagerID + '_panel'+"', 0, 100, 500);", 1000);
       
   513 }
       
   514 
       
   515 function killACLManager()
       
   516 {
       
   517   el = document.getElementById(aclManagerID);
       
   518   if(el)
       
   519   {
       
   520     el.parentNode.removeChild(el);
       
   521     enlighten();
       
   522   }
       
   523 }
       
   524 
       
   525 function __aclSubmitManager(form)
       
   526 {
       
   527   var thefrm = document.forms[form.name];
       
   528   var modeobj = form_fetch_field(thefrm, 'mode');
       
   529   if ( typeof(modeobj) == 'object' )
       
   530   {
       
   531     var mode = (thefrm.mode.value) ? thefrm.mode.value : 'cant_get';
       
   532   }
       
   533   else
       
   534   {
       
   535     var mode = '';
       
   536   }
       
   537   switch(mode)
       
   538   {
       
   539     case 'cant_get':
       
   540       alert('BUG: can\'t get the state value from the form field.');
       
   541       break;
       
   542     case 'seltarget':
       
   543       var target_type = parseInt(getRadioState(thefrm, 'target_type'));
       
   544       if(isNaN(target_type))
       
   545       {
       
   546         alert('Please select a target type.');
       
   547         return false;
       
   548       }
       
   549       target_id = ( target_type == 1 ) ? parseInt(thefrm.group_id.value) : thefrm.username.value;
       
   550       
       
   551       obj = { 'mode' : mode, 'target_type' : target_type, 'target_id' : target_id };
       
   552       
       
   553       thispage = strToPageID(title);
       
   554       do_scopesel = ( thispage[0] == aclDataCache.page_id && thispage[1] == aclDataCache.namespace );
       
   555       
       
   556       if(do_scopesel)
       
   557       {
       
   558         scope = getRadioState(thefrm, 'scope');
       
   559         if(scope == 'page')
       
   560         {
       
   561           pageid = strToPageID(title);
       
   562           obj['page_id'] = pageid[0];
       
   563           obj['namespace'] = pageid[1];
       
   564         }
       
   565         else if(scope == 'global')
       
   566         {
       
   567           obj['page_id'] = false;
       
   568           obj['namespace'] = false;
       
   569         }
       
   570         else
       
   571         {
       
   572           alert('Invalid scope');
       
   573           return false;
       
   574         }
       
   575       }
       
   576       else
       
   577       {
       
   578         obj['page_id'] = aclDataCache.page_id;
       
   579         obj['namespace'] = aclDataCache.namespace;
       
   580       }
       
   581       if(target_id == '')
       
   582       {
       
   583         alert('Please enter a username.');
       
   584         return false;
       
   585       }
       
   586       __aclJSONSubmitAjaxHandler(obj);
       
   587       break;
       
   588     case 'save_edit':
       
   589     case 'save_new':
       
   590       var form = document.forms[aclManagerID + '_formobj'];
       
   591       selections = new Object();
       
   592       for(var i in aclPermList)
       
   593       {
       
   594         if(i != 'toJSONString' && i != aclPermList.length-1)
       
   595         {
       
   596           selections[aclPermList[i]] = getRadioState(form, aclPermList[i]);
       
   597           if(!selections[aclPermList[i]])
       
   598           {
       
   599             alert("Invalid return from getRadioState: "+i+": "+selections[i]+" ("+typeof(selections[i])+")");
       
   600             return false;
       
   601           }
       
   602         }
       
   603       }
       
   604       obj = new Object();
       
   605       obj['perms'] = selections;
       
   606       obj['mode'] = mode;
       
   607       obj['target_type'] = aclDataCache.target_type;
       
   608       obj['target_id'] = aclDataCache.target_id;
       
   609       obj['target_name'] = aclDataCache.target_name;
       
   610       obj['page_id'] = aclDataCache.page_id;
       
   611       obj['namespace'] = aclDataCache.namespace;
       
   612       __aclJSONSubmitAjaxHandler(obj);
       
   613       break;
       
   614     default:
       
   615       alert("JSON form submit: invalid mode string "+mode+", stopping execution");
       
   616       return false;
       
   617       break;
       
   618   }
       
   619 }
       
   620 
       
   621 function getRadioState(form, name)
       
   622 {
       
   623   inputs = form.getElementsByTagName('input');
       
   624   radios = new Array();
       
   625   for(var i in inputs)
       
   626   {
       
   627     if(inputs[i]) if(inputs[i].type == 'radio')
       
   628       radios.push(inputs[i]);
       
   629   }
       
   630   for(var i in radios)
       
   631   {
       
   632     if(radios[i].checked && radios[i].name == name)
       
   633       return radios[i].value;
       
   634   }
       
   635   return false;
       
   636 }
       
   637 
       
   638 function __aclSetAllRadios(val)
       
   639 {
       
   640   val = val+'';
       
   641   form = document.forms[aclManagerID + '_formobj'];
       
   642   if (!form)
       
   643     return false;
       
   644   inputs = form.getElementsByTagName('input');
       
   645   radios = new Array();
       
   646   for(var i in inputs)
       
   647   {
       
   648     if(inputs[i].type == 'radio')
       
   649       radios.push(inputs[i]);
       
   650   }
       
   651   for(var i in radios)
       
   652   {
       
   653     if(radios[i].value == val)
       
   654       radios[i].checked = true;
       
   655     else
       
   656       radios[i].checked = false;
       
   657   }
       
   658 }
       
   659 
       
   660 function __aclDeleteRule()
       
   661 {
       
   662   if(!aclDataCache) return false;
       
   663   if(aclDataCache.mode != 'seltarget') return false;
       
   664   parms = {
       
   665     'target_type' : aclDataCache.target_type,
       
   666     'target_id' : aclDataCache.target_id,
       
   667     'target_name' : aclDataCache.target_name,
       
   668     'page_id' : aclDataCache.page_id,
       
   669     'namespace' : aclDataCache.namespace,
       
   670     'mode' : 'delete'
       
   671   };
       
   672   __aclJSONSubmitAjaxHandler(parms);
       
   673 }
       
   674 
       
   675 function array_keys(obj)
       
   676 {
       
   677   keys = new Array();
       
   678   for(var i in obj)
       
   679     keys.push(i);
       
   680   return keys;
       
   681 }
       
   682 
       
   683 function form_fetch_field(form, name)
       
   684 {
       
   685   var fields = form.getElementsByTagName('input');
       
   686   if ( fields.length < 1 )
       
   687     return false;
       
   688   for ( var i = 0; i < fields.length; i++ )
       
   689   {
       
   690     var field = fields[i];
       
   691     if ( field.name == name )
       
   692       return field;
       
   693   }
       
   694   return false;
       
   695 }
       
   696