includes/clientside/static/theme-manager.js
author Dan
Tue, 20 Apr 2010 11:38:59 -0400
changeset 1245 62763b17be2d
parent 1227 bdac73ed481e
permissions -rw-r--r--
Reordered wiki render stages so images happen before external links. Fixes a parser bug seen, among other places, on the Donation page.

function ajaxToggleSystemThemes()
{
	var theme_list = document.getElementById('theme_list_edit');
	var mode = ( theme_list.sys_shown ) ? 'hide' : 'show';
	for ( var i = 0; i < theme_list.childNodes.length; i++ )
	{
		var child = theme_list.childNodes[i];
		if ( child.tagName == 'DIV' )
		{
			if ( $dynano(child).hasClass('themebutton_theme_system') )
			{
				if ( $dynano(child).hasClass('themebutton_theme_disabled') )
				{
					$dynano(child).rmClass('themebutton_theme_disabled')
				}
				if ( mode == 'show' )
				{
					domObjChangeOpac(0, child);
					child.style.display = 'block';
					domOpacity(child, 0, 100, 1000);
				}
				else
				{
					domOpacity(child, 100, 0, 1000);
					setTimeout("document.getElementById('" + child.id + "').style.display = 'none';", 1050);
				}
			}
		}
	}
	theme_list.sys_shown = ( mode == 'show' );
	document.getElementById('systheme_toggler').innerHTML = ( mode == 'hide' ) ? $lang.get('acptm_btn_system_themes_show') : $lang.get('acptm_btn_system_themes_hide');
}

function ajaxInstallTheme(theme_id)
{
	var thediv = document.getElementById('themebtn_install_' + theme_id);
	if ( !thediv )
		return false;
	thediv.removeChild(thediv.getElementsByTagName('a')[0]);
	var status = document.createElement('div');
	status.className = 'status';
	thediv.appendChild(status);
	
	var req = toJSONString({
			mode: 'install',
			theme_id: theme_id
		});
	// we've finished nukeing the existing interface, request editor data
	ajaxPost(makeUrlNS('Admin', 'ThemeManager/action.json'), 'r=' + ajaxEscape(req), function(ajax)
		{
			if ( ajax.readyState == 4 && ajax.status == 200 )
			{
				var response = String(ajax.responseText + '');
				if ( response.substr(0, 1) == '{' )
				{
					response = parseJSON(response);
					if ( response.mode == 'error' )
					{
						alert(response.error);
						return false;
					}
				}
				
				var theme_list = document.getElementById('theme_list_edit');
	
				var btn = document.createElement('div');
				btn.className = 'themebutton';
				btn.style.backgroundImage = thediv.style.backgroundImage;
				btn.id = 'themebtn_edit_' + theme_id;
				
				var a = document.createElement('a');
				a.className = 'tb-inner';
				a.appendChild(document.createTextNode($lang.get('acptm_btn_theme_edit')));
				a.appendChild(document.createTextNode("\n"));
				a.theme_id = theme_id;
				a.onclick = function()
				{
					ajaxEditTheme(this.theme_id);
					return false;
				}
				a.href = '#';
				var span = document.createElement('span');
				span.className = 'themename';
				span.appendChild(document.createTextNode(thediv.getAttribute('enano:themename')));
				a.appendChild(span);
				btn.appendChild(a);
				btn.setAttribute('enano:themename', thediv.getAttribute('enano:themename'));
				theme_list.appendChild(btn);
				
				thediv.parentNode.removeChild(thediv);
			}
		});
}

function ajaxEditTheme(theme_id)
{
	// Fade out and subsequently destroy the entire list, then make an
	// ajax request to the theme manager for the theme info via JSON
	var theme_list = document.getElementById('theme_list_edit').parentNode;
	var backgroundImage = document.getElementById('themebtn_edit_' + theme_id).style.backgroundImage;
	/*
	for ( var i = 0; i < theme_list.childNodes.length; i++ )
	{
		var el = theme_list.childNodes[i];
		if ( el.tagName )
			domOpacity(el, 100, 0, 1000);
	}
	*/
	var thediv = document.getElementById('themebtn_edit_' + theme_id);
	if ( !thediv )
		return false;
	thediv.removeChild(thediv.getElementsByTagName('a')[0]);
	var status = document.createElement('div');
	status.className = 'status';
	thediv.appendChild(status);
	
	setTimeout(function()
		{
			var req = toJSONString({
					mode: 'fetch_theme',
					theme_id: theme_id
				});
			// we've finished nukeing the existing interface, request editor data
			ajaxPost(makeUrlNS('Admin', 'ThemeManager/action.json'), 'r=' + ajaxEscape(req), function(ajax)
				{
					if ( ajax.readyState == 4 && ajax.status == 200 )
					{
						theme_list.innerHTML = '';
						var response = String(ajax.responseText + '');
						if ( !check_json_response(response) )
						{
							alert(response);
							return false;
						}
						response = parseJSON(response);
						if ( response.mode == 'error' )
						{
							alert(response.error);
							return false;
						}
						response.background_image = backgroundImage;
						ajaxBuildThemeEditor(response, theme_list);
					}
				});
		}, 200);
}

function ajaxBuildThemeEditor(data, target)
{
	// Build the theme editor interface
	// Init opacity
	domObjChangeOpac(0, target);
	
	// Theme preview
	var preview = document.createElement('div');
	preview.style.border = '1px solid #F0F0F0';
	preview.style.padding = '5px';
	preview.style.width = '216px';
	preview.style.height = '150px';
	preview.style.backgroundImage = data.background_image;
	preview.style.backgroundRepeat = 'no-repeat';
	preview.style.backgroundPosition = 'center center';
	preview.style.cssFloat = 'right';
	preview.style.styleFloat = 'right';
	
	target.appendChild(preview);
	
	// Heading
	var h3 = document.createElement('h3');
	h3.appendChild(document.createTextNode($lang.get('acptm_heading_theme_edit', { theme_name: data.theme_name })));
	target.appendChild(h3);
	
	// Field: Theme name
	var l_name = document.createElement('label');
	l_name.appendChild(document.createTextNode($lang.get('acptm_field_theme_name') + ' '));
	var f_name = document.createElement('input');
	f_name.type = 'text';
	f_name.id = 'themeed_field_name';
	f_name.value = data.theme_name;
	f_name.size = '40';
	l_name.appendChild(f_name);
	target.appendChild(l_name);
	
	target.appendChild(document.createElement('br'));
	target.appendChild(document.createElement('br'));
	
	// Field: default style
	var l_style = document.createElement('label');
	l_style.appendChild(document.createTextNode($lang.get('acptm_field_default_style') + ' '));
	var f_style = document.createElement('select');
	f_style.id = 'themeed_field_style';
	var opts = [];
	for ( var i = 0; i < data.css.length; i++ )
	{
		if ( data.css[i] == '_printable' )
			continue;
		
		opts[i] = document.createElement('option');
		opts[i].value = data.css[i];
		opts[i].appendChild(document.createTextNode(data.css[i]));
		if ( data.default_style == data.css[i] )
		{
			opts[i].selected = true;
		}
		f_style.appendChild(opts[i]);
	}
	l_style.appendChild(f_style);
	target.appendChild(l_style);
	
	target.appendChild(document.createElement('br'));
	target.appendChild(document.createElement('br'));
	
	// Default theme
	target.appendChild(document.createTextNode($lang.get('acptm_field_default_theme') + ' '));
	if ( data.is_default )
	{
		var l_default = document.createElement('b');
		l_default.appendChild(document.createTextNode($lang.get('acptm_field_default_msg_current')));
	}
	else
	{
		var l_default = document.createElement('label');
		var f_default = document.createElement('input');
		f_default.type = 'checkbox';
		f_default.id = 'themeed_field_default';
		l_default.appendChild(f_default);
		l_default.appendChild(document.createTextNode($lang.get('acptm_field_default_btn_make_default')));
	}
	target.appendChild(l_default);
	
	target.appendChild(document.createElement('br'));
	target.appendChild(document.createElement('br'));
	
	// Disable theme
	var disable_span = document.createElement('span');
	disable_span.appendChild(document.createTextNode($lang.get('acptm_field_disable_title') + ' '));
	target.appendChild(disable_span);
	var l_disable = document.createElement('label');
	var f_disable = document.createElement('input');
	f_disable.type = 'checkbox';
	f_disable.id = 'themeed_field_disable';
	if ( !data.enabled )
		f_disable.setAttribute('checked', 'checked');
	l_disable.style.fontWeight = 'bold';
	l_disable.appendChild(f_disable);
	l_disable.appendChild(document.createTextNode($lang.get('acptm_field_disable')));
	target.appendChild(l_disable);
	
	// Availability policy
	var h3 = document.createElement('h3');
	h3.appendChild(document.createTextNode($lang.get('acptm_heading_theme_groups')));
	target.appendChild(h3);
	
	// Label for the whole field
	var p_d_policy = document.createElement('p');
	p_d_policy.style.fontWeight = 'bold';
	p_d_policy.appendChild(document.createTextNode($lang.get('acptm_field_policy')));
	target.appendChild(p_d_policy);
	
	// Wrapper for options
	var p_f_policy = document.createElement('p');
	
	// Option: allow all
	var l_policy_allow_all = document.createElement('label');
	var f_policy_allow_all = document.createElement('input');
	f_policy_allow_all.type = 'radio';
	f_policy_allow_all.id = 'themeed_field_policy_allow_all';
	f_policy_allow_all.name = 'themeed_field_policy';
	f_policy_allow_all.value = 'allow_all';
	l_policy_allow_all.appendChild(f_policy_allow_all);
	l_policy_allow_all.appendChild(document.createTextNode(' ' + $lang.get('acptm_field_policy_allow_all')));
	if ( data.group_policy == 'allow_all' )
	{
		f_policy_allow_all.setAttribute('checked', 'checked');
	}
	
	// Option: whitelist
	var l_policy_whitelist = document.createElement('label');
	var f_policy_whitelist = document.createElement('input');
	f_policy_whitelist.type = 'radio';
	f_policy_whitelist.id = 'themeed_field_policy_whitelist';
	f_policy_whitelist.name = 'themeed_field_policy';
	f_policy_whitelist.value = 'whitelist';
	l_policy_whitelist.appendChild(f_policy_whitelist);
	l_policy_whitelist.appendChild(document.createTextNode(' ' + $lang.get('acptm_field_policy_whitelist')));
	if ( data.group_policy == 'whitelist' )
	{
		f_policy_whitelist.setAttribute('checked', 'checked');
	}
	
	// Option: blacklist
	var l_policy_blacklist = document.createElement('label');
	var f_policy_blacklist = document.createElement('input');
	f_policy_blacklist.type = 'radio';
	f_policy_blacklist.id = 'themeed_field_policy_blacklist';
	f_policy_blacklist.name = 'themeed_field_policy';
	f_policy_blacklist.value = 'blacklist';
	l_policy_blacklist.appendChild(f_policy_blacklist);
	l_policy_blacklist.appendChild(document.createTextNode(' ' + $lang.get('acptm_field_policy_blacklist')));
	if ( data.group_policy == 'blacklist' )
	{
		f_policy_blacklist.setAttribute('checked', 'checked');
	}
	f_policy_allow_all.onclick = ajaxThemeManagerHandlePolicyClick;
	f_policy_whitelist.onclick = ajaxThemeManagerHandlePolicyClick;
	f_policy_blacklist.onclick = ajaxThemeManagerHandlePolicyClick;
	
	p_f_policy.appendChild(l_policy_allow_all);
	p_f_policy.appendChild(document.createElement('br'));
	p_f_policy.appendChild(l_policy_whitelist);
	p_f_policy.appendChild(document.createElement('br'));
	p_f_policy.appendChild(l_policy_blacklist);
	
	target.appendChild(p_d_policy);
	target.appendChild(p_f_policy);
	
	var div_acl = document.createElement('div');
	div_acl.id = 'themeed_acl_box';
	div_acl.style.margin = '0 0 10px 30px';
	
	var h3_g = document.createElement('h3');
	h3_g.appendChild(document.createTextNode($lang.get('acptm_field_acl_heading_groups')));
	div_acl.appendChild(h3_g);
	
	var div_groups = document.createElement('div');
	div_groups.style.border = '1px solid #E8E8E8';
	div_groups.id = 'themeed_group_list';
	
	// Group list
	for ( var i in data.group_names )
	{
		var g_name = data.group_names[i];
		var check = document.createElement('input');
		check.type = 'checkbox';
		if ( in_array("g:" + i, data.group_list) )
		{
			check.setAttribute('checked', 'checked');
		}
		check.group_id = parseInt(i);
		var lbl_g_acl = document.createElement('label');
		lbl_g_acl.appendChild(check);
		var str = 'groupcp_grp_' + g_name.toLowerCase();
		var g_name_l10n = ( $lang.get(str) != str ) ? $lang.get(str) : g_name;
		lbl_g_acl.appendChild(document.createTextNode(g_name_l10n));
		div_groups.appendChild(lbl_g_acl);
		div_groups.appendChild(document.createElement('br'));
	}
	div_acl.appendChild(div_groups);
	
	var h3_u = document.createElement('h3');
	h3_u.appendChild(document.createTextNode($lang.get('acptm_field_acl_heading_users')));
	div_acl.appendChild(h3_u);
	
	// User addition field
	var frm = document.createElement('form');
	frm.action = 'javascript:ajaxThemeManagerHandleUserAdd();';
	frm.appendChild(document.createTextNode($lang.get('acptm_field_acl_add_user')));
	var f_useradd = document.createElement('input');
	f_useradd.type = 'text';
	f_useradd.id = 'themeed_field_adduser';
	f_useradd.onkeyup = function(e)
	{
		new AutofillUsername(this, e, false);
	}
	
	frm.appendChild(f_useradd);
	div_acl.appendChild(frm);
	
	div_acl.appendChild(document.createElement('br'));
	
	// User list
	var div_users = document.createElement('div');
	div_users.style.border = '1px solid #E8E8E8';
	div_users.style.padding = '4px';
	div_users.id = 'themeed_user_list';
	for ( var i = 0; i < data.group_list.length; i++ )
	{
		var id = data.group_list[i];
		if ( id.substr(0, 2) != 'u:' )
			continue;
		var uid = id.substr(2);
		var username = data.usernames[uid];
		
		var useritem = document.createElement('span');
		useritem.appendChild(document.createTextNode(username + ' '));
		useritem.userid = parseInt(uid);
		var deleter = document.createElement('a');
		deleter.href = '#';
		deleter.onclick = function()
		{
			ajaxThemeManagerHandleUserRemoval(this);
			return false;
		}
		deleter.appendChild(document.createTextNode('[X]'));
		useritem.appendChild(deleter);
		div_users.appendChild(useritem);
		div_users.appendChild(document.createElement('br'));
	}
	div_acl.appendChild(div_users);
	
	target.appendChild(div_acl);
	
	ajaxThemeManagerHandlePolicyClick();
	
	var clearer = document.createElement('span');
	clearer.className = 'menuclear';
	target.appendChild(clearer);
	
	// Theme ID
	var tid = document.createElement('input');
	tid.type = 'hidden';
	tid.id = 'themeed_theme_id';
	tid.value = data.theme_id;
	target.appendChild(tid);
	
	// Save button
	var raquo = unescape('%BB');
	var savebtn = document.createElement('input');
	savebtn.type = 'button';
	savebtn.style.fontWeight = 'bold';
	savebtn.value = $lang.get('etc_save_changes') + ' ' + raquo;
	savebtn.onclick = function()
	{
		ajaxThemeManagerHandleSaveRequest();
	}
	target.appendChild(savebtn);
	
	target.appendChild(document.createTextNode(' '));
	
	// Cancel button
	var savebtn = document.createElement('input');
	savebtn.type = 'button';
	savebtn.value = $lang.get('etc_cancel');
	savebtn.onclick = function()
	{
		ajaxPage(namespace_list['Admin'] + 'ThemeManager');
	}
	target.appendChild(savebtn);
	
	target.appendChild(document.createTextNode(' '));
	
	// Uninstall button
	var savebtn = document.createElement('input');
	savebtn.type = 'button';
	savebtn.value = $lang.get('acptm_btn_uninstall_theme');
	savebtn.style.color = '#D84308';
	savebtn.onclick = function()
	{
		if ( !confirm($lang.get('acptm_msg_uninstall_confirm')) )
			return false;
		ajaxThemeManagerHandleUninstallClick();
	}
	target.appendChild(savebtn);
	
	// Fade it all in
	domOpacity(target, 0, 100, 500);
	f_name.focus();
}

function ajaxThemeManagerHandlePolicyClick()
{
	if ( document.getElementById('themeed_field_policy_allow_all').checked )
	{
		document.getElementById('themeed_acl_box').style.display = 'none';
	}
	else if ( document.getElementById('themeed_field_policy_whitelist').checked || document.getElementById('themeed_field_policy_blacklist').checked )
	{
		document.getElementById('themeed_acl_box').style.display = 'block';
	}
}

function ajaxThemeManagerHandleUserAdd()
{
	var f_useradd = document.getElementById('themeed_field_adduser');
	f_useradd.setAttribute('disabled', 'disabled');
	var parent = f_useradd.parentNode;
	var img = document.createElement('img');
	img.src = ajax_load_icon;
	img.id = 'themeed_useradd_status';
	img.style.marginLeft = '10px';
	insertAfter(parent, img, f_useradd);
	
	var req = toJSONString({
			mode: 'uid_lookup',
			username: f_useradd.value
		});
	ajaxPost(makeUrlNS('Admin', 'ThemeManager/action.json'), 'r=' + ajaxEscape(req), function(ajax)
		{
			if ( ajax.readyState == 4 && ajax.status == 200 )
			{
				var img = document.getElementById('themeed_useradd_status');
				var f_useradd = document.getElementById('themeed_field_adduser');
				
				f_useradd.disabled = null;
				img.parentNode.removeChild(img);
				
				// process response
				var response = String(ajax.responseText + '');
				if ( !check_json_response(response) )
				{
					alert(response);
					return false;
				}
				response = parseJSON(response);
				if ( response.mode == 'error' )
				{
					alert(response.error);
					return false;
				}
						
				var uid = parseInt(response.uid);
				var username = response.username;
				
				// Loop through the list of users and remove any existing ones with the same uid
				var div_users = document.getElementById('themeed_user_list');
				var children = div_users.getElementsByTagName('span');
				for ( var i = 0; i < children.length; i++ )
				{
					var child = children[i];
					if ( child.userid == uid )
					{
						// the sister is the br element next to the span with the checkbox/text
						var sister = child.nextSibling;
						div_users.removeChild(child);
						div_users.removeChild(sister);
						break;
					}
				}
				
				var useritem = document.createElement('span');
				useritem.appendChild(document.createTextNode(username + ' '));
				useritem.userid = parseInt(uid);
				var deleter = document.createElement('a');
				deleter.href = '#';
				deleter.onclick = function()
				{
					ajaxThemeManagerHandleUserRemoval(this);
					return false;
				}
				deleter.appendChild(document.createTextNode('[X]'));
				useritem.appendChild(deleter);
				div_users.appendChild(useritem);
				div_users.appendChild(document.createElement('br'));
			}
		});
}

function ajaxThemeManagerHandleUserRemoval(el)
{
	var parent = el.parentNode;
	var uid = parent.userid;
	
	var grandparent = parent.parentNode;
	var sister = parent.nextSibling;
	grandparent.removeChild(parent);
	grandparent.removeChild(sister);
}

function ajaxThemeManagerHandleSaveRequest()
{
	// Build a JSON condensed request
	var md = false;
	if ( document.getElementById('themeed_field_default') )
	{
		if ( document.getElementById('themeed_field_default').checked )
		{
			md = true;
		}
	}
	var policy = 'allow_all';
	if ( document.getElementById('themeed_field_policy_whitelist').checked )
		policy = 'whitelist';
	else if ( document.getElementById('themeed_field_policy_blacklist').checked )
		policy = 'blacklist';
	var json_packet = {
		theme_id: document.getElementById('themeed_theme_id').value,
		theme_name: document.getElementById('themeed_field_name').value,
		default_style: document.getElementById('themeed_field_style').value,
		make_default: md,
		group_policy: policy,
		enabled: ( document.getElementById('themeed_field_disable').checked ? false : true )
	};
	var acl_list = [];
	var checks = document.getElementById('themeed_group_list').getElementsByTagName('input');
	for ( var i = 0; i < checks.length; i++ )
	{
		if ( checks[i].checked )
			acl_list.push('g:' + checks[i].group_id);
	}
	var spans = document.getElementById('themeed_user_list').getElementsByTagName('span');
	for ( var i = 0; i < spans.length; i++ )
	{
		if ( spans[i].userid )
			acl_list.push('u:' + spans[i].userid);
	}
	json_packet.group_list = acl_list;
	
	var json_send = {
		mode: 'save_theme',
		theme_data: json_packet
	};
	
	json_send = ajaxEscape(toJSONString(json_send));
	
	// Request the save
	var parent = document.getElementById('ajaxPageContainer');
	ajaxPost(makeUrlNS('Admin', 'ThemeManager/action.json'), 'r=' + json_send, function(ajax)
		{
			if ( ajax.readyState == 4 && ajax.status == 200 )
			{
				// process response
				var response = String(ajax.responseText + '');
				if ( !check_json_response(response) )
				{
					// For this we actually *expect* an HTML response.
					parent.innerHTML = response;
					return false;
				}
				response = parseJSON(response);
				if ( response.mode == 'error' )
				{
					alert(response.error);
					return false;
				}
			}
		});
}

function ajaxThemeManagerHandleUninstallClick()
{
	var theme_id = document.getElementById('themeed_theme_id').value;
	var json_send = {
		mode: 'uninstall',
		theme_id: theme_id
	};
	
	json_send = ajaxEscape(toJSONString(json_send));
	
	// Request the action
	var parent = document.getElementById('ajaxPageContainer');
	ajaxPost(makeUrlNS('Admin', 'ThemeManager/action.json'), 'r=' + json_send, function(ajax)
		{
			if ( ajax.readyState == 4 && ajax.status == 200 )
			{
				// process response
				var response = String(ajax.responseText + '');
				if ( !check_json_response(response) )
				{
					// For this we actually *expect* an HTML response.
					parent.innerHTML = response;
					return false;
				}
				response = parseJSON(response);
				if ( response.mode == 'error' )
				{
					alert(response.error);
					return false;
				}
			}
		});
}