diff -r 902822492a68 -r fe660c52c48f includes/clientside/static/acl.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/static/acl.js Wed Jun 13 16:07:17 2007 -0400 @@ -0,0 +1,696 @@ +// Javascript routines for the ACL editor + +var aclManagerID = 'enano_aclmanager_' + Math.floor(Math.random() * 1000000); +var aclPermList = false; +var aclDataCache = false; + +function ajaxOpenACLManager(page_id, namespace) +{ + if(IE) + return true; + if(!page_id || !namespace) + { + var data = strToPageID(title); + var page_id = data[0]; + var namespace = data[1]; + } + var params = { + 'mode' : 'listgroups', + 'page_id' : page_id, + 'namespace' : namespace + }; + params = toJSONString(params); + params = ajaxEscape(params); + ajaxPost(stdAjaxPrefix+'&_mode=acljson', 'acl_params='+params, function() { + if(ajax.readyState == 4) + { + __aclBuildWizardWindow(); + groups = parseJSON(ajax.responseText); + aclDataCache = groups; + __aclBuildSelector(groups); + } + }); + return false; +} + +function ajaxACLSwitchToSelector() +{ + params = { + 'mode' : 'listgroups' + }; + if ( aclDataCache.page_id && aclDataCache.namespace ) + { + params.page_id = aclDataCache.page_id; + params.namespace = aclDataCache.namespace; + } + params = toJSONString(params); + params = ajaxEscape(params); + ajaxPost(stdAjaxPrefix+'&_mode=acljson', 'acl_params='+params, function() { + if(ajax.readyState == 4) + { + document.getElementById(aclManagerID+'_main').innerHTML = ''; + document.getElementById(aclManagerID + '_back').style.display = 'none'; + document.getElementById(aclManagerID + '_next').value = 'Next >'; + groups = parseJSON(ajax.responseText); + aclDataCache = groups; + thispage = strToPageID(title); + groups.page_id = thispage[0]; + groups.namespace = thispage[1]; + __aclBuildSelector(groups); + } + }); +} + +function __aclBuildSelector(groups) +{ + thispage = strToPageID(title); + do_scopesel = ( thispage[0] == groups.page_id && thispage[1] == groups.namespace ); + + seed = Math.floor(Math.random() * 1000000); + + main = document.getElementById(aclManagerID + '_main'); + main.style.padding = '10px'; + + selector = document.createElement('div'); + + grpsel = __aclBuildGroupsHTML(groups); + grpsel.name = 'group_id'; + + span = document.createElement('div'); + span.id = "enACL_grpbox_"+seed+""; + + // Build the selector + grpb = document.createElement('input'); + grpb.type = 'radio'; + grpb.name = 'target_type'; + grpb.value = 1; // ACL_TYPE_GROUP + grpb.checked = 'checked'; + grpb.className = seed; + grpb.onclick = function() { seed = this.className; document.getElementById('enACL_grpbox_'+seed).style.display = 'block'; document.getElementById('enACL_usrbox_'+seed).style.display = 'none'; }; + lbl = document.createElement('label'); + lbl.appendChild(grpb); + lbl.appendChild(document.createTextNode('A usergroup')); + lbl.style.display = 'block'; + span.appendChild(grpsel); + + usrb = document.createElement('input'); + usrb.type = 'radio'; + usrb.name = 'target_type'; + usrb.value = 2; // ACL_TYPE_USER + usrb.className = seed; + usrb.onclick = function() { seed = this.className; document.getElementById('enACL_grpbox_'+seed).style.display = 'none'; document.getElementById('enACL_usrbox_'+seed).style.display = 'block'; }; + lbl2 = document.createElement('label'); + lbl2.appendChild(usrb); + lbl2.appendChild(document.createTextNode('A specific user')); + lbl2.style.display = 'block'; + + usrsel = document.createElement('input'); + usrsel.type = 'text'; + usrsel.name = 'username'; + usrsel.onkeyup = function() { ajaxUserNameComplete(this); }; + usrsel.id = 'userfield_' + aclManagerID; + try { + usrsel.setAttribute("autocomplete","off"); + } catch(e) {}; + + span2 = document.createElement('div'); + span2.id = "enACL_usrbox_"+seed+""; + span2.style.display = 'none'; + span2.appendChild(usrsel); + + // Scope selector + if(do_scopesel) + { + scopediv1 = document.createElement('div'); + scopediv2 = document.createElement('div'); + scopeRadioPage = document.createElement('input'); + scopeRadioPage.type = 'radio'; + scopeRadioPage.name = 'scope'; + scopeRadioPage.value = 'page'; + scopeRadioPage.checked = 'checked'; + scopeRadioGlobal = document.createElement('input'); + scopeRadioGlobal.type = 'radio'; + scopeRadioGlobal.name = 'scope'; + scopeRadioGlobal.value = 'global'; + lblPage = document.createElement('label'); + lblPage.style.display = 'block'; + lblPage.appendChild(scopeRadioPage); + lblPage.appendChild(document.createTextNode('Only this page')); + lblGlobal = document.createElement('label'); + lblGlobal.style.display = 'block'; + lblGlobal.appendChild(scopeRadioGlobal); + lblGlobal.appendChild(document.createTextNode('The entire website')); + scopediv1.appendChild(lblPage); + scopediv2.appendChild(lblGlobal); + + scopedesc = document.createElement('p'); + scopedesc.appendChild(document.createTextNode('What should this access rule control?')); + } + + // Styles + span.style.marginLeft = '13px'; + span.style.padding = '5px 0'; + span2.style.marginLeft = '13px'; + span2.style.padding = '5px 0'; + + selector.appendChild(lbl); + selector.appendChild(span); + + selector.appendChild(lbl2); + selector.appendChild(span2); + + container = document.createElement('div'); + container.style.margin = 'auto'; + container.style.width = '360px'; + container.style.paddingTop = '70px'; + + head = document.createElement('h2'); + head.appendChild(document.createTextNode('Manage page access')); + + desc = document.createElement('p'); + desc.appendChild(document.createTextNode('Please select who should be affected by this access rule.')); + + container.appendChild(head); + container.appendChild(desc); + container.appendChild(selector); + + if(do_scopesel) + { + container.appendChild(scopedesc); + container.appendChild(scopediv1); + container.appendChild(scopediv2); + } + + main.appendChild(container); + + var mode = document.createElement('input'); + mode.name = 'mode'; + mode.type = 'hidden'; + mode.id = aclManagerID + '_mode'; + mode.value = 'seltarget'; + + var theform = document.getElementById(aclManagerID + '_formobj_id'); + if ( !theform.mode ) + { + theform.appendChild(mode); + } + else + { + theform.removeChild(theform.mode); + theform.appendChild(mode); + } +} + +var aclDebugWin = false; + +function aclDebug(text) +{ + if(!aclDebugWin) + aclDebugWin = pseudoWindowOpen("data:text/html;plain,debug win

Debug window

", "aclDebugWin"); + setTimeout(function() { + aclDebugWin.pre = aclDebugWin.document.createElement('pre'); + aclDebugWin.pre.appendChild(aclDebugWin.document.createTextNode(text)); + aclDebugWin.b = aclDebugWin.document.getElementsByTagName('body')[0]; + aclDebugWin.b.appendChild(aclDebugWin.pre);}, 1000); +} + +var pseudoWindows = new Object(); + +function pseudoWindowOpen(url, id) +{ + if(pseudoWindows[id]) + { + document.getElementById('pseudowin_ifr_'+id).src = url; + } + else + { + win = document.createElement('iframe'); + win.style.position='fixed'; + win.style.width = '640px'; + win.style.height = '480px'; + win.style.top = '0px'; + win.style.left = '0px'; + win.style.zIndex = getHighestZ() + 1; + win.style.backgroundColor = '#FFFFFF'; + win.name = 'pseudo_ifr_'+id; + win.id = 'pseudowindow_ifr_'+id; + win.src = url; + body = document.getElementsByTagName('body')[0]; + body.appendChild(win); + } + win_obj = eval("( pseudo_ifr_"+id+" )"); + return win_obj; +} + +function __aclJSONSubmitAjaxHandler(params) +{ + params = toJSONString(params); + params = ajaxEscape(params); + ajaxPost(stdAjaxPrefix+'&_mode=acljson', 'acl_params='+params, function() { + if(ajax.readyState == 4) + { + try { + data = parseJSON(ajax.responseText); + } catch(e) { + aclDebug(e+"\n\nResponse:\n"+ajax.responseText); + } + aclDataCache = data; + switch(data.mode) + { + case 'seltarget': + + // Build the ACL edit form + // try { + act_desc = ( data.type == 'new' ) ? 'Create access rule' : 'Editing permissions'; + target_type_t = ( data.target_type == 1 ) ? 'group' : 'user'; + target_name_t = data.target_name; + var scope_type = ( data.page_id == false && data.namespace == false ) ? 'this entire site' : 'this page'; + html = '

'+act_desc+'

This panel allows you to edit what the '+target_type_t+' "'+target_name_t+'" can do on ' + scope_type + '. Unless you set a permission to "Deny", these permissions may be overridden by other rules.

'; + parser = new templateParser(data.template.acl_field_begin); + html += parser.run(); + + cls = 'row2'; + for(var i in data.acl_types) + { + if(typeof(data.acl_types[i]) == 'number') + { + cls = ( cls == 'row1' ) ? 'row2' : 'row1'; + p = new templateParser(data.template.acl_field_item); + vars = new Object(); + vars['FIELD_DESC'] = data.acl_descs[i]; + vars['FIELD_DENY_CHECKED'] = ''; + vars['FIELD_DISALLOW_CHECKED'] = ''; + vars['FIELD_WIKIMODE_CHECKED'] = ''; + vars['FIELD_ALLOW_CHECKED'] = ''; + vars['FIELD_NAME'] = i; + switch(data.current_perms[i]) + { + case 1: + vars['FIELD_DENY_CHECKED'] = 'checked="checked"'; + break; + case 2: + default: + vars['FIELD_DISALLOW_CHECKED'] = 'checked="checked"'; + break; + case 3: + vars['FIELD_WIKIMODE_CHECKED'] = 'checked="checked"'; + break; + case 4: + vars['FIELD_ALLOW_CHECKED'] = 'checked="checked"'; + break; + } + vars['ROW_CLASS'] = cls; + p.assign_vars(vars); + html += p.run(); + } + } + + var parser = new templateParser(data.template.acl_field_end); + html += parser.run(); + + if(data.type == 'edit') + html += '

Delete this rule

'; + + var main = document.getElementById(aclManagerID + '_main'); + main.innerHTML = html; + + var form = document.getElementById(aclManagerID + '_formobj_id'); + + var modeobj = form_fetch_field(form, 'mode'); + if ( modeobj ) + modeobj.value = 'save_' + data.type; + else + alert('modeobj is invalid: '+modeobj); + + aclPermList = array_keys(data.acl_types); + + document.getElementById(aclManagerID + '_back').style.display = 'inline'; + document.getElementById(aclManagerID + '_next').value = 'Save Changes'; + + // } catch(e) { alert(e); aclDebug(ajax.responseText); } + + break; + case 'success': + var note = document.createElement('div'); + note.className = 'info-box'; + note.style.marginLeft = '0'; + var b = document.createElement('b'); + b.appendChild(document.createTextNode('Permissions updated')); + note.appendChild(b); + note.appendChild(document.createElement('br')); + note.appendChild(document.createTextNode('The permissions for '+data.target_name+' on this page have been updated successfully.')); + note.appendChild(document.createElement('br')); + var a = document.createElement('a'); + a.href = 'javascript:void(0);'; + a.onclick = function() { this.parentNode.parentNode.removeChild(this.parentNode); return false; }; + a.appendChild(document.createTextNode('[ dismiss :')); + note.appendChild(a); + var a2 = document.createElement('a'); + a2.href = 'javascript:void(0);'; + a2.onclick = function() { killACLManager(); return false; }; + a2.appendChild(document.createTextNode(': close manager ]')); + note.appendChild(a2); + document.getElementById(aclManagerID + '_main').insertBefore(note, document.getElementById(aclManagerID + '_main').firstChild); + if(!document.getElementById(aclManagerID+'_deletelnk')) + document.getElementById(aclManagerID + '_main').innerHTML += '

Delete this rule

'; + //fadeInfoBoxes(); + break; + case 'delete': + + params = { + 'mode' : 'listgroups' + }; + params = toJSONString(params); + params = ajaxEscape(params); + ajaxPost(stdAjaxPrefix+'&_mode=acljson', 'acl_params='+params, function() { + if(ajax.readyState == 4) + { + document.getElementById(aclManagerID+'_main').innerHTML = ''; + document.getElementById(aclManagerID + '_back').style.display = 'none'; + document.getElementById(aclManagerID + '_next').value = 'Next >'; + var thispage = strToPageID(title); + groups.page_id = thispage[0]; + groups.namespace = thispage[1]; + __aclBuildSelector(groups); + + note = document.createElement('div'); + note.className = 'info-box'; + note.style.marginLeft = '0'; + b = document.createElement('b'); + b.appendChild(document.createTextNode('Entry deleted')); + note.appendChild(b); + note.appendChild(document.createElement('br')); + note.appendChild(document.createTextNode('The access rules for '+aclDataCache.target_name+' on this page have been deleted.')); + note.appendChild(document.createElement('br')); + a = document.createElement('a'); + a.href = '#'; + a.onclick = function() { this.parentNode.parentNode.removeChild(this.parentNode); return false; }; + a.appendChild(document.createTextNode('[ dismiss :')); + note.appendChild(a); + a = document.createElement('a'); + a.href = '#'; + a.onclick = function() { killACLManager(); return false; }; + a.appendChild(document.createTextNode(': close manager ]')); + note.appendChild(a); + document.getElementById(aclManagerID + '_main').insertBefore(note, document.getElementById(aclManagerID + '_main').firstChild); + //fadeInfoBoxes(); + + } + }); + + break; + case 'error': + alert("Server side processing error:\n"+data.error); + break; + case 'debug': + aclDebug(data.text); + break; + default: + alert("Invalid JSON response from server\nMode: "+data.mode+"\nJSON string: "+ajax.responseText); + break; + } + } + }); +} + +function __aclBuildGroupsHTML(groups) +{ + groups = groups.groups; + select = document.createElement('select'); + for(var i in groups) + { + if(typeof(groups[i]['name']) == 'string' && i != 'toJSONString') + { + o = document.createElement('option'); + o.value = groups[i]['id']; + t = document.createTextNode(groups[i]['name']); + o.appendChild(t); + select.appendChild(o); + } + } + return select; +} + +function __aclBuildWizardWindow() +{ + darken(); + box = document.createElement('div'); + box.style.width = '640px' + box.style.height = '440px'; + box.style.position = 'fixed'; + width = getWidth(); + height = getHeight(); + box.style.left = ( width / 2 - 320 ) + 'px'; + box.style.top = ( height / 2 - 250 ) + 'px'; + box.style.backgroundColor = 'white'; + box.style.zIndex = getHighestZ() + 1; + box.id = aclManagerID; + box.style.opacity = '0'; + box.style.filter = 'alpha(opacity=0)'; + box.style.display = 'none'; + + mainwin = document.createElement('div'); + mainwin.id = aclManagerID + '_main'; + mainwin.style.clip = 'rect(0px,640px,440px,0px)'; + mainwin.style.overflow = 'auto'; + mainwin.style.width = '620px'; + mainwin.style.height = '420px'; + + panel = document.createElement('div'); + panel.style.width = '620px'; + panel.style.padding = '10px'; + panel.style.lineHeight = '40px'; + panel.style.textAlign = 'right'; + panel.style.position = 'fixed'; + panel.style.left = ( width / 2 - 320 ) + 'px'; + panel.style.top = ( height / 2 + 190 ) + 'px'; + panel.style.backgroundColor = '#D0D0D0'; + panel.style.opacity = '0'; + panel.style.filter = 'alpha(opacity=0)'; + panel.id = aclManagerID + '_panel'; + + form = document.createElement('form'); + form.method = 'post'; + form.action = 'javascript:void(0)'; + form.onsubmit = function() { if(this.username && !submitAuthorized) return false; __aclSubmitManager(this); return false; }; + form.name = aclManagerID + '_formobj'; + form.id = aclManagerID + '_formobj_id'; + + back = document.createElement('input'); + back.type = 'button'; + back.value = '< Back'; + back.style.fontWeight = 'normal'; + back.onclick = function() { ajaxACLSwitchToSelector(); return false; }; + back.style.display = 'none'; + back.id = aclManagerID + '_back'; + + saver = document.createElement('input'); + saver.type = 'submit'; + saver.value = 'Next >'; + saver.style.fontWeight = 'bold'; + saver.id = aclManagerID + '_next'; + + closer = document.createElement('input'); + closer.type = 'button'; + closer.value = 'Cancel Changes'; + closer.onclick = function() { if(!confirm('Do you really want to close the ACL manager?')) return false; killACLManager(); return false; } + + spacer1 = document.createTextNode(' '); + spacer2 = document.createTextNode(' '); + + panel.appendChild(back); + panel.appendChild(spacer1); + panel.appendChild(saver); + panel.appendChild(spacer2); + panel.appendChild(closer); + form.appendChild(mainwin); + form.appendChild(panel); + box.appendChild(form); + + body = document.getElementsByTagName('body')[0]; + body.appendChild(box); + setTimeout("document.getElementById('"+aclManagerID+"').style.display = 'block'; opacity('"+aclManagerID+"', 0, 100, 500); opacity('"+aclManagerID + '_panel'+"', 0, 100, 500);", 1000); +} + +function killACLManager() +{ + el = document.getElementById(aclManagerID); + if(el) + { + el.parentNode.removeChild(el); + enlighten(); + } +} + +function __aclSubmitManager(form) +{ + var thefrm = document.forms[form.name]; + var modeobj = form_fetch_field(thefrm, 'mode'); + if ( typeof(modeobj) == 'object' ) + { + var mode = (thefrm.mode.value) ? thefrm.mode.value : 'cant_get'; + } + else + { + var mode = ''; + } + switch(mode) + { + case 'cant_get': + alert('BUG: can\'t get the state value from the form field.'); + break; + case 'seltarget': + var target_type = parseInt(getRadioState(thefrm, 'target_type')); + if(isNaN(target_type)) + { + alert('Please select a target type.'); + return false; + } + target_id = ( target_type == 1 ) ? parseInt(thefrm.group_id.value) : thefrm.username.value; + + obj = { 'mode' : mode, 'target_type' : target_type, 'target_id' : target_id }; + + thispage = strToPageID(title); + do_scopesel = ( thispage[0] == aclDataCache.page_id && thispage[1] == aclDataCache.namespace ); + + if(do_scopesel) + { + scope = getRadioState(thefrm, 'scope'); + if(scope == 'page') + { + pageid = strToPageID(title); + obj['page_id'] = pageid[0]; + obj['namespace'] = pageid[1]; + } + else if(scope == 'global') + { + obj['page_id'] = false; + obj['namespace'] = false; + } + else + { + alert('Invalid scope'); + return false; + } + } + else + { + obj['page_id'] = aclDataCache.page_id; + obj['namespace'] = aclDataCache.namespace; + } + if(target_id == '') + { + alert('Please enter a username.'); + return false; + } + __aclJSONSubmitAjaxHandler(obj); + break; + case 'save_edit': + case 'save_new': + var form = document.forms[aclManagerID + '_formobj']; + selections = new Object(); + for(var i in aclPermList) + { + if(i != 'toJSONString' && i != aclPermList.length-1) + { + selections[aclPermList[i]] = getRadioState(form, aclPermList[i]); + if(!selections[aclPermList[i]]) + { + alert("Invalid return from getRadioState: "+i+": "+selections[i]+" ("+typeof(selections[i])+")"); + return false; + } + } + } + obj = new Object(); + obj['perms'] = selections; + obj['mode'] = mode; + obj['target_type'] = aclDataCache.target_type; + obj['target_id'] = aclDataCache.target_id; + obj['target_name'] = aclDataCache.target_name; + obj['page_id'] = aclDataCache.page_id; + obj['namespace'] = aclDataCache.namespace; + __aclJSONSubmitAjaxHandler(obj); + break; + default: + alert("JSON form submit: invalid mode string "+mode+", stopping execution"); + return false; + break; + } +} + +function getRadioState(form, name) +{ + inputs = form.getElementsByTagName('input'); + radios = new Array(); + for(var i in inputs) + { + if(inputs[i]) if(inputs[i].type == 'radio') + radios.push(inputs[i]); + } + for(var i in radios) + { + if(radios[i].checked && radios[i].name == name) + return radios[i].value; + } + return false; +} + +function __aclSetAllRadios(val) +{ + val = val+''; + form = document.forms[aclManagerID + '_formobj']; + if (!form) + return false; + inputs = form.getElementsByTagName('input'); + radios = new Array(); + for(var i in inputs) + { + if(inputs[i].type == 'radio') + radios.push(inputs[i]); + } + for(var i in radios) + { + if(radios[i].value == val) + radios[i].checked = true; + else + radios[i].checked = false; + } +} + +function __aclDeleteRule() +{ + if(!aclDataCache) return false; + if(aclDataCache.mode != 'seltarget') return false; + parms = { + 'target_type' : aclDataCache.target_type, + 'target_id' : aclDataCache.target_id, + 'target_name' : aclDataCache.target_name, + 'page_id' : aclDataCache.page_id, + 'namespace' : aclDataCache.namespace, + 'mode' : 'delete' + }; + __aclJSONSubmitAjaxHandler(parms); +} + +function array_keys(obj) +{ + keys = new Array(); + for(var i in obj) + keys.push(i); + return keys; +} + +function form_fetch_field(form, name) +{ + var fields = form.getElementsByTagName('input'); + if ( fields.length < 1 ) + return false; + for ( var i = 0; i < fields.length; i++ ) + { + var field = fields[i]; + if ( field.name == name ) + return field; + } + return false; +} +