includes/clientside/static/rank-manager.js
changeset 1227 bdac73ed481e
parent 823 4596c40aaa94
equal deleted inserted replaced
1226:de56132c008d 1227:bdac73ed481e
     2  * Creates a control that can be used to edit a rank.
     2  * Creates a control that can be used to edit a rank.
     3  */
     3  */
     4 
     4 
     5 var RankEditorControl = function(rankdata)
     5 var RankEditorControl = function(rankdata)
     6 {
     6 {
     7   this.rankdata = ( typeof(rankdata) == 'object' ) ? rankdata : {};
     7 	this.rankdata = ( typeof(rankdata) == 'object' ) ? rankdata : {};
     8   if ( !this.rankdata.rank_style )
     8 	if ( !this.rankdata.rank_style )
     9   {
     9 	{
    10     this.rankdata.rank_style = '';
    10 		this.rankdata.rank_style = '';
    11   }
    11 	}
    12   
    12 	
    13   // have the browser parse CSS for us and use an anchor to be as close
    13 	// have the browser parse CSS for us and use an anchor to be as close
    14   // as possible in calculating CSS
    14 	// as possible in calculating CSS
    15   
    15 	
    16   // this is kind of a hack as it relies on setAttribute/getAttribute in
    16 	// this is kind of a hack as it relies on setAttribute/getAttribute in
    17   // order to obtain stringified versions of CSS data
    17 	// order to obtain stringified versions of CSS data
    18   var cssobj = document.createElement('a');
    18 	var cssobj = document.createElement('a');
    19   cssobj.setAttribute('style', this.rankdata.rank_style);
    19 	cssobj.setAttribute('style', this.rankdata.rank_style);
    20   
    20 	
    21   this.style_sim_obj = cssobj;
    21 	this.style_sim_obj = cssobj;
    22   
    22 	
    23   // figure out if we're editing or creating
    23 	// figure out if we're editing or creating
    24   this.editing = ( typeof(this.rankdata.rank_id) == 'number' );
    24 	this.editing = ( typeof(this.rankdata.rank_id) == 'number' );
    25   
    25 	
    26   this.render = function()
    26 	this.render = function()
    27   {
    27 	{
    28     var editor = document.createElement('div');
    28 		var editor = document.createElement('div');
    29     editor.className = 'tblholder';
    29 		editor.className = 'tblholder';
    30     // stash this editor instance in the parent div for later function calls
    30 		// stash this editor instance in the parent div for later function calls
    31     editor.editor = this;
    31 		editor.editor = this;
    32     this.wrapperdiv = editor;
    32 		this.wrapperdiv = editor;
    33     editor.style.width = '100%';
    33 		editor.style.width = '100%';
    34     
    34 		
    35     // tables suck.
    35 		// tables suck.
    36     var table = document.createElement('table');
    36 		var table = document.createElement('table');
    37     table.setAttribute('cellspacing', '1');
    37 		table.setAttribute('cellspacing', '1');
    38     table.setAttribute('cellpadding', '4');
    38 		table.setAttribute('cellpadding', '4');
    39     table.setAttribute('width', '100%');
    39 		table.setAttribute('width', '100%');
    40     
    40 		
    41     // heading: "Edit rank: foo" or "Create a new rank"
    41 		// heading: "Edit rank: foo" or "Create a new rank"
    42     var tr_head = document.createElement('tr');
    42 		var tr_head = document.createElement('tr');
    43     var th_head = document.createElement('th');
    43 		var th_head = document.createElement('th');
    44     th_head.setAttribute('colspan', '2');
    44 		th_head.setAttribute('colspan', '2');
    45     if ( this.editing )
    45 		if ( this.editing )
    46     {
    46 		{
    47       var th_head_string = 'acpur_th_edit_rank';
    47 			var th_head_string = 'acpur_th_edit_rank';
    48       var th_head_data = { rank_title: $lang.get(this.rankdata.rank_title) };
    48 			var th_head_data = { rank_title: $lang.get(this.rankdata.rank_title) };
    49     }
    49 		}
    50     else
    50 		else
    51     {
    51 		{
    52       var th_head_string = 'acpur_th_create_rank';
    52 			var th_head_string = 'acpur_th_create_rank';
    53       var th_head_data = { };
    53 			var th_head_data = { };
    54     }
    54 		}
    55     th_head.appendChild(document.createTextNode($lang.get(th_head_string, th_head_data)));
    55 		th_head.appendChild(document.createTextNode($lang.get(th_head_string, th_head_data)));
    56     tr_head.appendChild(th_head);
    56 		tr_head.appendChild(th_head);
    57     this.th_head = th_head;
    57 		this.th_head = th_head;
    58     table.appendChild(tr_head);
    58 		table.appendChild(tr_head);
    59     
    59 		
    60     // row: rank title
    60 		// row: rank title
    61     var tr_title = document.createElement('tr');
    61 		var tr_title = document.createElement('tr');
    62     var td_title_l = document.createElement('td');
    62 		var td_title_l = document.createElement('td');
    63     var td_title_f = document.createElement('td');
    63 		var td_title_f = document.createElement('td');
    64     
    64 		
    65     td_title_l.className = td_title_f.className = 'row1';
    65 		td_title_l.className = td_title_f.className = 'row1';
    66     
    66 		
    67     td_title_l.appendChild(document.createTextNode($lang.get('acpur_field_rank_title')));
    67 		td_title_l.appendChild(document.createTextNode($lang.get('acpur_field_rank_title')));
    68     
    68 		
    69     // field: rank title
    69 		// field: rank title
    70     var f_rank_title = document.createElement('input');
    70 		var f_rank_title = document.createElement('input');
    71     f_rank_title.type = 'text';
    71 		f_rank_title.type = 'text';
    72     f_rank_title.size = '30';
    72 		f_rank_title.size = '30';
    73     f_rank_title.value = ( this.editing ) ? this.rankdata.rank_title : '';
    73 		f_rank_title.value = ( this.editing ) ? this.rankdata.rank_title : '';
    74     f_rank_title.editor = this;
    74 		f_rank_title.editor = this;
    75     f_rank_title.onkeyup = function()
    75 		f_rank_title.onkeyup = function()
    76     {
    76 		{
    77       this.editor.renderPreview();
    77 			this.editor.renderPreview();
    78     }
    78 		}
    79     this.f_rank_title = f_rank_title;
    79 		this.f_rank_title = f_rank_title;
    80     td_title_f.appendChild(f_rank_title);
    80 		td_title_f.appendChild(f_rank_title);
    81     
    81 		
    82     tr_title.appendChild(td_title_l);
    82 		tr_title.appendChild(td_title_l);
    83     tr_title.appendChild(td_title_f);
    83 		tr_title.appendChild(td_title_f);
    84     table.appendChild(tr_title);
    84 		table.appendChild(tr_title);
    85     
    85 		
    86     // row: basic style options
    86 		// row: basic style options
    87     var tr_basic = document.createElement('tr');
    87 		var tr_basic = document.createElement('tr');
    88     var td_basic_l = document.createElement('td');
    88 		var td_basic_l = document.createElement('td');
    89     var td_basic_f = document.createElement('td');
    89 		var td_basic_f = document.createElement('td');
    90     
    90 		
    91     td_basic_l.className = td_basic_f.className = 'row2';
    91 		td_basic_l.className = td_basic_f.className = 'row2';
    92     
    92 		
    93     td_basic_l.appendChild(document.createTextNode($lang.get('acpur_field_style_basic')));
    93 		td_basic_l.appendChild(document.createTextNode($lang.get('acpur_field_style_basic')));
    94     
    94 		
    95     // fieldset: basic style options
    95 		// fieldset: basic style options
    96     // field: bold
    96 		// field: bold
    97     var l_basic_bold = document.createElement('label');
    97 		var l_basic_bold = document.createElement('label');
    98     var f_basic_bold = document.createElement('input');
    98 		var f_basic_bold = document.createElement('input');
    99     f_basic_bold.type = 'checkbox';
    99 		f_basic_bold.type = 'checkbox';
   100     f_basic_bold.checked = ( this.style_sim_obj.style.fontWeight == 'bold' ) ? true : false;
   100 		f_basic_bold.checked = ( this.style_sim_obj.style.fontWeight == 'bold' ) ? true : false;
   101     f_basic_bold.editor = this;
   101 		f_basic_bold.editor = this;
   102     f_basic_bold.onclick = function()
   102 		f_basic_bold.onclick = function()
   103     {
   103 		{
   104       this.editor.style_sim_obj.style.fontWeight = ( this.checked ) ? 'bold' : null;
   104 			this.editor.style_sim_obj.style.fontWeight = ( this.checked ) ? 'bold' : null;
   105       this.editor.renderPreview();
   105 			this.editor.renderPreview();
   106     }
   106 		}
   107     l_basic_bold.style.fontWeight = 'bold';
   107 		l_basic_bold.style.fontWeight = 'bold';
   108     l_basic_bold.appendChild(f_basic_bold);
   108 		l_basic_bold.appendChild(f_basic_bold);
   109     l_basic_bold.appendChild(document.createTextNode(' '));
   109 		l_basic_bold.appendChild(document.createTextNode(' '));
   110     l_basic_bold.appendChild(document.createTextNode($lang.get('acpur_field_style_basic_bold')));
   110 		l_basic_bold.appendChild(document.createTextNode($lang.get('acpur_field_style_basic_bold')));
   111     
   111 		
   112     // field: italic
   112 		// field: italic
   113     var l_basic_italic = document.createElement('label');
   113 		var l_basic_italic = document.createElement('label');
   114     var f_basic_italic = document.createElement('input');
   114 		var f_basic_italic = document.createElement('input');
   115     f_basic_italic.type = 'checkbox';
   115 		f_basic_italic.type = 'checkbox';
   116     f_basic_italic.checked = ( this.style_sim_obj.style.fontStyle == 'italic' ) ? true : false;
   116 		f_basic_italic.checked = ( this.style_sim_obj.style.fontStyle == 'italic' ) ? true : false;
   117     f_basic_italic.editor = this;
   117 		f_basic_italic.editor = this;
   118     f_basic_italic.onclick = function()
   118 		f_basic_italic.onclick = function()
   119     {
   119 		{
   120       this.editor.style_sim_obj.style.fontStyle = ( this.checked ) ? 'italic' : null;
   120 			this.editor.style_sim_obj.style.fontStyle = ( this.checked ) ? 'italic' : null;
   121       this.editor.renderPreview();
   121 			this.editor.renderPreview();
   122     }
   122 		}
   123     l_basic_italic.style.fontStyle = 'italic';
   123 		l_basic_italic.style.fontStyle = 'italic';
   124     l_basic_italic.appendChild(f_basic_italic);
   124 		l_basic_italic.appendChild(f_basic_italic);
   125     l_basic_italic.appendChild(document.createTextNode(' '));
   125 		l_basic_italic.appendChild(document.createTextNode(' '));
   126     l_basic_italic.appendChild(document.createTextNode($lang.get('acpur_field_style_basic_italic')));
   126 		l_basic_italic.appendChild(document.createTextNode($lang.get('acpur_field_style_basic_italic')));
   127     
   127 		
   128     // field: underline
   128 		// field: underline
   129     var l_basic_underline = document.createElement('label');
   129 		var l_basic_underline = document.createElement('label');
   130     var f_basic_underline = document.createElement('input');
   130 		var f_basic_underline = document.createElement('input');
   131     f_basic_underline.type = 'checkbox';
   131 		f_basic_underline.type = 'checkbox';
   132     f_basic_underline.checked = ( this.style_sim_obj.style.textDecoration == 'underline' ) ? true : false;
   132 		f_basic_underline.checked = ( this.style_sim_obj.style.textDecoration == 'underline' ) ? true : false;
   133     f_basic_underline.editor = this;
   133 		f_basic_underline.editor = this;
   134     f_basic_underline.onclick = function()
   134 		f_basic_underline.onclick = function()
   135     {
   135 		{
   136       this.editor.style_sim_obj.style.textDecoration = ( this.checked ) ? 'underline' : null;
   136 			this.editor.style_sim_obj.style.textDecoration = ( this.checked ) ? 'underline' : null;
   137       this.editor.renderPreview();
   137 			this.editor.renderPreview();
   138     }
   138 		}
   139     l_basic_underline.style.textDecoration = 'underline';
   139 		l_basic_underline.style.textDecoration = 'underline';
   140     l_basic_underline.appendChild(f_basic_underline);
   140 		l_basic_underline.appendChild(f_basic_underline);
   141     l_basic_underline.appendChild(document.createTextNode(' '));
   141 		l_basic_underline.appendChild(document.createTextNode(' '));
   142     l_basic_underline.appendChild(document.createTextNode($lang.get('acpur_field_style_basic_underline')));
   142 		l_basic_underline.appendChild(document.createTextNode($lang.get('acpur_field_style_basic_underline')));
   143     
   143 		
   144     // finish up formatting row#1
   144 		// finish up formatting row#1
   145     td_basic_f.appendChild(l_basic_bold);
   145 		td_basic_f.appendChild(l_basic_bold);
   146     td_basic_f.appendChild(document.createTextNode(' '));
   146 		td_basic_f.appendChild(document.createTextNode(' '));
   147     td_basic_f.appendChild(l_basic_italic);
   147 		td_basic_f.appendChild(l_basic_italic);
   148     td_basic_f.appendChild(document.createTextNode(' '));
   148 		td_basic_f.appendChild(document.createTextNode(' '));
   149     td_basic_f.appendChild(l_basic_underline);
   149 		td_basic_f.appendChild(l_basic_underline);
   150     
   150 		
   151     tr_basic.appendChild(td_basic_l);
   151 		tr_basic.appendChild(td_basic_l);
   152     tr_basic.appendChild(td_basic_f);
   152 		tr_basic.appendChild(td_basic_f);
   153     table.appendChild(tr_basic);
   153 		table.appendChild(tr_basic);
   154     
   154 		
   155     // row: rank color
   155 		// row: rank color
   156     var tr_color = document.createElement('tr');
   156 		var tr_color = document.createElement('tr');
   157     var td_color_l = document.createElement('td');
   157 		var td_color_l = document.createElement('td');
   158     var td_color_f = document.createElement('td');
   158 		var td_color_f = document.createElement('td');
   159     
   159 		
   160     td_color_l.className = td_color_f.className = 'row1';
   160 		td_color_l.className = td_color_f.className = 'row1';
   161     
   161 		
   162     td_color_l.appendChild(document.createTextNode($lang.get('acpur_field_style_color')));
   162 		td_color_l.appendChild(document.createTextNode($lang.get('acpur_field_style_color')));
   163     
   163 		
   164     // field: rank color
   164 		// field: rank color
   165     var f_rank_color = document.createElement('input');
   165 		var f_rank_color = document.createElement('input');
   166     f_rank_color.type = 'text';
   166 		f_rank_color.type = 'text';
   167     f_rank_color.size = '7';
   167 		f_rank_color.size = '7';
   168     f_rank_color.value = ( this.editing ) ? this.rgb2hex(this.style_sim_obj.style.color) : '';
   168 		f_rank_color.value = ( this.editing ) ? this.rgb2hex(this.style_sim_obj.style.color) : '';
   169     f_rank_color.style.backgroundColor = this.style_sim_obj.style.color;
   169 		f_rank_color.style.backgroundColor = this.style_sim_obj.style.color;
   170     f_rank_color.editor = this;
   170 		f_rank_color.editor = this;
   171     this.f_rank_color = f_rank_color;
   171 		this.f_rank_color = f_rank_color;
   172     f_rank_color.onkeyup = function(e)
   172 		f_rank_color.onkeyup = function(e)
   173     {
   173 		{
   174       if ( !e.keyCode )
   174 			if ( !e.keyCode )
   175         e = window.event;
   175 				e = window.event;
   176       if ( !e )
   176 			if ( !e )
   177         return false;
   177 				return false;
   178       var chr = (String.fromCharCode(e.keyCode)).toLowerCase();
   178 			var chr = (String.fromCharCode(e.keyCode)).toLowerCase();
   179       this.value = this.value.replace(/[^a-fA-F0-9]/g, '');
   179 			this.value = this.value.replace(/[^a-fA-F0-9]/g, '');
   180       if ( this.value.length > 6 )
   180 			if ( this.value.length > 6 )
   181       {
   181 			{
   182         this.value = this.value.substr(0, 6);
   182 				this.value = this.value.substr(0, 6);
   183       }
   183 			}
   184       if ( this.value.length == 6 || this.value.length == 3 )
   184 			if ( this.value.length == 6 || this.value.length == 3 )
   185       {
   185 			{
   186         this.style.backgroundColor = '#' + this.value;
   186 				this.style.backgroundColor = '#' + this.value;
   187         this.editor.style_sim_obj.style.color = '#' + this.value;
   187 				this.editor.style_sim_obj.style.color = '#' + this.value;
   188         this.style.color = '#' + this.editor.determineLightness(this.value);
   188 				this.style.color = '#' + this.editor.determineLightness(this.value);
   189         this.editor.renderPreview();
   189 				this.editor.renderPreview();
   190       }
   190 			}
   191       else if ( this.value.length == 0 )
   191 			else if ( this.value.length == 0 )
   192       {
   192 			{
   193         this.style.backgroundColor = null;
   193 				this.style.backgroundColor = null;
   194         this.editor.style_sim_obj.style.color = null;
   194 				this.editor.style_sim_obj.style.color = null;
   195         this.editor.renderPreview();
   195 				this.editor.renderPreview();
   196       }
   196 			}
   197     }
   197 		}
   198     td_color_f.appendChild(f_rank_color);
   198 		td_color_f.appendChild(f_rank_color);
   199     
   199 		
   200     tr_color.appendChild(td_color_l);
   200 		tr_color.appendChild(td_color_l);
   201     tr_color.appendChild(td_color_f);
   201 		tr_color.appendChild(td_color_f);
   202     table.appendChild(tr_color);
   202 		table.appendChild(tr_color);
   203     
   203 		
   204     // field: additional CSS
   204 		// field: additional CSS
   205     var tr_css = document.createElement('tr');
   205 		var tr_css = document.createElement('tr');
   206     
   206 		
   207     var td_css_l = document.createElement('td');
   207 		var td_css_l = document.createElement('td');
   208     td_css_l.className = 'row2';
   208 		td_css_l.className = 'row2';
   209     td_css_l.appendChild(document.createTextNode($lang.get('acpur_field_style_css')));
   209 		td_css_l.appendChild(document.createTextNode($lang.get('acpur_field_style_css')));
   210     tr_css.appendChild(td_css_l);
   210 		tr_css.appendChild(td_css_l);
   211     
   211 		
   212     var td_css_f = document.createElement('td');
   212 		var td_css_f = document.createElement('td');
   213     td_css_f.className = 'row2';
   213 		td_css_f.className = 'row2';
   214     var f_css = document.createElement('input');
   214 		var f_css = document.createElement('input');
   215     f_css.type = 'text';
   215 		f_css.type = 'text';
   216     f_css.value = this.stripBasicCSSAttributes(this.rankdata.rank_style);
   216 		f_css.value = this.stripBasicCSSAttributes(this.rankdata.rank_style);
   217     f_css.style.width = '98%';
   217 		f_css.style.width = '98%';
   218     f_css.editor = this;
   218 		f_css.editor = this;
   219     f_css.onkeyup = function()
   219 		f_css.onkeyup = function()
   220     {
   220 		{
   221       if ( !(trim(this.value)).match(/^((([a-z-]+):(.+?);)+)?$/) )
   221 			if ( !(trim(this.value)).match(/^((([a-z-]+):(.+?);)+)?$/) )
   222         return;
   222 				return;
   223       var newcss = this.editor.stripExtendedCSSAttributes(String(this.editor.style_sim_obj.getAttribute('style'))) + ' ' + this.value;
   223 			var newcss = this.editor.stripExtendedCSSAttributes(String(this.editor.style_sim_obj.getAttribute('style'))) + ' ' + this.value;
   224       this.editor.preview_div.setAttribute('style', 'font-size: x-large; ' + newcss);
   224 			this.editor.preview_div.setAttribute('style', 'font-size: x-large; ' + newcss);
   225       this.editor.style_sim_obj.setAttribute('style', newcss);
   225 			this.editor.style_sim_obj.setAttribute('style', newcss);
   226     }
   226 		}
   227     this.f_css = f_css;
   227 		this.f_css = f_css;
   228     td_css_f.appendChild(f_css);
   228 		td_css_f.appendChild(f_css);
   229     tr_css.appendChild(td_css_f);
   229 		tr_css.appendChild(td_css_f);
   230     table.appendChild(tr_css);
   230 		table.appendChild(tr_css);
   231     
   231 		
   232     // "field": preview
   232 		// "field": preview
   233     var tr_preview = document.createElement('tr');
   233 		var tr_preview = document.createElement('tr');
   234     var td_preview_l = document.createElement('td');
   234 		var td_preview_l = document.createElement('td');
   235     td_preview_l.className = 'row1';
   235 		td_preview_l.className = 'row1';
   236     td_preview_l.appendChild(document.createTextNode($lang.get('acpur_field_preview')));
   236 		td_preview_l.appendChild(document.createTextNode($lang.get('acpur_field_preview')));
   237     tr_preview.appendChild(td_preview_l);
   237 		tr_preview.appendChild(td_preview_l);
   238     
   238 		
   239     var td_preview_f = document.createElement('td');
   239 		var td_preview_f = document.createElement('td');
   240     td_preview_f.className = 'row1';
   240 		td_preview_f.className = 'row1';
   241     var div_preview = document.createElement('a');
   241 		var div_preview = document.createElement('a');
   242     this.preview_div = div_preview;
   242 		this.preview_div = div_preview;
   243     div_preview.style.fontSize = 'x-large';
   243 		div_preview.style.fontSize = 'x-large';
   244     div_preview.appendChild(document.createTextNode(''));
   244 		div_preview.appendChild(document.createTextNode(''));
   245     div_preview.firstChild.nodeValue = ( this.editing ) ? this.rankdata.rank_title : '';
   245 		div_preview.firstChild.nodeValue = ( this.editing ) ? this.rankdata.rank_title : '';
   246     td_preview_f.appendChild(div_preview);
   246 		td_preview_f.appendChild(div_preview);
   247     tr_preview.appendChild(td_preview_f);
   247 		tr_preview.appendChild(td_preview_f);
   248     
   248 		
   249     table.appendChild(tr_preview);
   249 		table.appendChild(tr_preview);
   250     
   250 		
   251     // submit button
   251 		// submit button
   252     var tr_submit = document.createElement('tr');
   252 		var tr_submit = document.createElement('tr');
   253     var th_submit = document.createElement('th');
   253 		var th_submit = document.createElement('th');
   254     th_submit.className = 'subhead';
   254 		th_submit.className = 'subhead';
   255     th_submit.setAttribute('colspan', '2');
   255 		th_submit.setAttribute('colspan', '2');
   256     var btn_submit = document.createElement('input');
   256 		var btn_submit = document.createElement('input');
   257     btn_submit.type = 'submit';
   257 		btn_submit.type = 'submit';
   258     btn_submit.value = ( this.editing ) ? $lang.get('acpur_btn_save') : $lang.get('acpur_btn_create_submit');
   258 		btn_submit.value = ( this.editing ) ? $lang.get('acpur_btn_save') : $lang.get('acpur_btn_create_submit');
   259     btn_submit.editor = this;
   259 		btn_submit.editor = this;
   260     btn_submit.style.fontWeight = 'bold';
   260 		btn_submit.style.fontWeight = 'bold';
   261     btn_submit.onclick = function(e)
   261 		btn_submit.onclick = function(e)
   262     {
   262 		{
   263       this.editor.submitEvent(e);
   263 			this.editor.submitEvent(e);
   264     }
   264 		}
   265     this.btn_submit = btn_submit;
   265 		this.btn_submit = btn_submit;
   266     th_submit.appendChild(btn_submit);
   266 		th_submit.appendChild(btn_submit);
   267     
   267 		
   268     // delete button
   268 		// delete button
   269     if ( this.editing )
   269 		if ( this.editing )
   270     {
   270 		{
   271       var btn_delete = document.createElement('input');
   271 			var btn_delete = document.createElement('input');
   272       btn_delete.type = 'button';
   272 			btn_delete.type = 'button';
   273       btn_delete.value = $lang.get('acpur_btn_delete');
   273 			btn_delete.value = $lang.get('acpur_btn_delete');
   274       btn_delete.editor = this;
   274 			btn_delete.editor = this;
   275       btn_delete.onclick = function(e)
   275 			btn_delete.onclick = function(e)
   276       {
   276 			{
   277         this.editor.deleteEvent(e);
   277 				this.editor.deleteEvent(e);
   278       }
   278 			}
   279       th_submit.appendChild(document.createTextNode(' '));
   279 			th_submit.appendChild(document.createTextNode(' '));
   280       th_submit.appendChild(btn_delete);
   280 			th_submit.appendChild(btn_delete);
   281     }
   281 		}
   282     
   282 		
   283     tr_submit.appendChild(th_submit);
   283 		tr_submit.appendChild(th_submit);
   284     
   284 		
   285     table.appendChild(tr_submit);
   285 		table.appendChild(tr_submit);
   286     
   286 		
   287     // render preview
   287 		// render preview
   288     this.renderPreview();
   288 		this.renderPreview();
   289     
   289 		
   290     // finalize the editor table
   290 		// finalize the editor table
   291     editor.appendChild(table);
   291 		editor.appendChild(table);
   292     
   292 		
   293     // stash rendered editor
   293 		// stash rendered editor
   294     this.editordiv = editor;
   294 		this.editordiv = editor;
   295     
   295 		
   296     // send output
   296 		// send output
   297     return editor;
   297 		return editor;
   298   }
   298 	}
   299   
   299 	
   300   /**
   300 	/**
   301    * Takes the existing editor div and transforms the necessary elements so that it goes from "create" mode to "edit" mode
   301  	* Takes the existing editor div and transforms the necessary elements so that it goes from "create" mode to "edit" mode
   302    * @param object Edit data - same format as the rankdata parameter to the constructor, but we should only need rank_id
   302  	* @param object Edit data - same format as the rankdata parameter to the constructor, but we should only need rank_id
   303    */
   303  	*/
   304   
   304 	
   305   this.transformToEditor = function(rankdata)
   305 	this.transformToEditor = function(rankdata)
   306   {
   306 	{
   307     // we need a rank ID
   307 		// we need a rank ID
   308     if ( typeof(rankdata.rank_id) != 'number' )
   308 		if ( typeof(rankdata.rank_id) != 'number' )
   309       return false;
   309 			return false;
   310     
   310 		
   311     if ( this.editing )
   311 		if ( this.editing )
   312       return false;
   312 			return false;
   313     
   313 		
   314     this.editing = true;
   314 		this.editing = true;
   315     
   315 		
   316     this.rankdata = rankdata;
   316 		this.rankdata = rankdata;
   317     this.rankdata.rank_title = this.f_rank_title.value;
   317 		this.rankdata.rank_title = this.f_rank_title.value;
   318     this.rankdata.rank_style = this.getCSS();
   318 		this.rankdata.rank_style = this.getCSS();
   319     
   319 		
   320     // transform various controls
   320 		// transform various controls
   321     this.th_head.firstChild.nodeValue = $lang.get('acpur_th_edit_rank', {
   321 		this.th_head.firstChild.nodeValue = $lang.get('acpur_th_edit_rank', {
   322         rank_title: $lang.get(this.rankdata.rank_title)
   322 				rank_title: $lang.get(this.rankdata.rank_title)
   323       });
   323 			});
   324     this.btn_submit.value = $lang.get('acpur_btn_save');
   324 		this.btn_submit.value = $lang.get('acpur_btn_save');
   325     
   325 		
   326     // add the delete button
   326 		// add the delete button
   327     var th_submit = this.btn_submit.parentNode;
   327 		var th_submit = this.btn_submit.parentNode;
   328     
   328 		
   329     var btn_delete = document.createElement('input');
   329 		var btn_delete = document.createElement('input');
   330     btn_delete.type = 'button';
   330 		btn_delete.type = 'button';
   331     btn_delete.value = $lang.get('acpur_btn_delete');
   331 		btn_delete.value = $lang.get('acpur_btn_delete');
   332     btn_delete.editor = this;
   332 		btn_delete.editor = this;
   333     btn_delete.onclick = function(e)
   333 		btn_delete.onclick = function(e)
   334     {
   334 		{
   335       this.editor.deleteEvent(e);
   335 			this.editor.deleteEvent(e);
   336     }
   336 		}
   337     th_submit.appendChild(document.createTextNode(' '));
   337 		th_submit.appendChild(document.createTextNode(' '));
   338     th_submit.appendChild(btn_delete);
   338 		th_submit.appendChild(btn_delete);
   339     
   339 		
   340     return true;
   340 		return true;
   341   }
   341 	}
   342   
   342 	
   343   /**
   343 	/**
   344    * Takes a hex color, averages the three channels, and returns either 'ffffff' or '000000' depending on the luminosity of the color.
   344  	* Takes a hex color, averages the three channels, and returns either 'ffffff' or '000000' depending on the luminosity of the color.
   345    * @param string
   345  	* @param string
   346    * @return string
   346  	* @return string
   347    */
   347  	*/
   348   
   348 	
   349   this.determineLightness = function(hexval)
   349 	this.determineLightness = function(hexval)
   350   {
   350 	{
   351     var rgb = this.hex2rgb(hexval);
   351 		var rgb = this.hex2rgb(hexval);
   352     var lumin = ( rgb[0] + rgb[1] + rgb[2] ) / 3;
   352 		var lumin = ( rgb[0] + rgb[1] + rgb[2] ) / 3;
   353     return ( lumin > 60 ) ? '000000' : 'ffffff';
   353 		return ( lumin > 60 ) ? '000000' : 'ffffff';
   354   }
   354 	}
   355   
   355 	
   356   /**
   356 	/**
   357    * Strips out basic CSS attributes (color, font-weight, font-style, text-decoration) from a snippet of CSS.
   357  	* Strips out basic CSS attributes (color, font-weight, font-style, text-decoration) from a snippet of CSS.
   358    * @param string
   358  	* @param string
   359    * @return string
   359  	* @return string
   360    */
   360  	*/
   361   
   361 	
   362   this.stripBasicCSSAttributes = function(css)
   362 	this.stripBasicCSSAttributes = function(css)
   363   {
   363 	{
   364     return trim(css.replace(/(color|font-weight|font-style|text-decoration): ?([A-z0-9# ,\(\)]+);/g, ''));
   364 		return trim(css.replace(/(color|font-weight|font-style|text-decoration): ?([A-z0-9# ,\(\)]+);/g, ''));
   365   }
   365 	}
   366   
   366 	
   367   /**
   367 	/**
   368    * Strips out all but basic CSS attributes.
   368  	* Strips out all but basic CSS attributes.
   369    * @param string
   369  	* @param string
   370    * @return string
   370  	* @return string
   371    */
   371  	*/
   372   
   372 	
   373   this.stripExtendedCSSAttributes = function(css)
   373 	this.stripExtendedCSSAttributes = function(css)
   374   {
   374 	{
   375     var match;
   375 		var match;
   376     var final_css = '';
   376 		var final_css = '';
   377     var basics = ['color', 'font-weight', 'font-style', 'text-decoration'];
   377 		var basics = ['color', 'font-weight', 'font-style', 'text-decoration'];
   378     while ( match = css.match(/([a-z-]+):(.+?);/) )
   378 		while ( match = css.match(/([a-z-]+):(.+?);/) )
   379     {
   379 		{
   380       if ( in_array(match[1], basics) )
   380 			if ( in_array(match[1], basics) )
   381       {
   381 			{
   382         final_css += ' ' + match[0] + ' ';
   382 				final_css += ' ' + match[0] + ' ';
   383       }
   383 			}
   384       css = css.replace(match[0], '');
   384 			css = css.replace(match[0], '');
   385     }
   385 		}
   386     final_css = trim(final_css);
   386 		final_css = trim(final_css);
   387     return final_css;
   387 		return final_css;
   388   }
   388 	}
   389   
   389 	
   390   this.getCSS = function()
   390 	this.getCSS = function()
   391   {
   391 	{
   392     return this.style_sim_obj.getAttribute('style');
   392 		return this.style_sim_obj.getAttribute('style');
   393   }
   393 	}
   394   
   394 	
   395   this.renderPreview = function()
   395 	this.renderPreview = function()
   396   {
   396 	{
   397     if ( !this.preview_div )
   397 		if ( !this.preview_div )
   398       return false;
   398 			return false;
   399     var color = ( this.style_sim_obj.style.color ) ? '#' + this.rgb2hex(this.style_sim_obj.style.color) : null;
   399 		var color = ( this.style_sim_obj.style.color ) ? '#' + this.rgb2hex(this.style_sim_obj.style.color) : null;
   400     this.preview_div.style.color = color;
   400 		this.preview_div.style.color = color;
   401     this.preview_div.style.fontWeight = this.style_sim_obj.style.fontWeight;
   401 		this.preview_div.style.fontWeight = this.style_sim_obj.style.fontWeight;
   402     this.preview_div.style.fontStyle = this.style_sim_obj.style.fontStyle;
   402 		this.preview_div.style.fontStyle = this.style_sim_obj.style.fontStyle;
   403     this.preview_div.style.textDecoration = this.style_sim_obj.style.textDecoration;
   403 		this.preview_div.style.textDecoration = this.style_sim_obj.style.textDecoration;
   404     this.preview_div.firstChild.nodeValue = $lang.get(this.f_rank_title.value);
   404 		this.preview_div.firstChild.nodeValue = $lang.get(this.f_rank_title.value);
   405   }
   405 	}
   406   
   406 	
   407   this.submitEvent = function(e)
   407 	this.submitEvent = function(e)
   408   {
   408 	{
   409     if ( this.onsubmit )
   409 		if ( this.onsubmit )
   410     {
   410 		{
   411       this.onsubmit(e);
   411 			this.onsubmit(e);
   412     }
   412 		}
   413     else
   413 		else
   414     {
   414 		{
   415       window.console.error('RankEditorControl: no onsubmit event specified');
   415 			window.console.error('RankEditorControl: no onsubmit event specified');
   416     }
   416 		}
   417   }
   417 	}
   418   
   418 	
   419   this.deleteEvent = function(e)
   419 	this.deleteEvent = function(e)
   420   {
   420 	{
   421     if ( this.ondelete )
   421 		if ( this.ondelete )
   422     {
   422 		{
   423       this.ondelete(e);
   423 			this.ondelete(e);
   424     }
   424 		}
   425     else
   425 		else
   426     {
   426 		{
   427       window.console.error('RankEditorControl: no ondelete event specified');
   427 			window.console.error('RankEditorControl: no ondelete event specified');
   428     }
   428 		}
   429   }
   429 	}
   430   
   430 	
   431   /**
   431 	/**
   432    * Converts a parenthetical color specification (rgb(x, y, z)) to hex form (xxyyzz)
   432  	* Converts a parenthetical color specification (rgb(x, y, z)) to hex form (xxyyzz)
   433    * @param string
   433  	* @param string
   434    * @return string
   434  	* @return string
   435    */
   435  	*/
   436   
   436 	
   437   this.rgb2hex = function(rgb)
   437 	this.rgb2hex = function(rgb)
   438   {
   438 	{
   439     var p = rgb.match(/^rgb\(([0-9]+), ([0-9]+), ([0-9]+)\)$/);
   439 		var p = rgb.match(/^rgb\(([0-9]+), ([0-9]+), ([0-9]+)\)$/);
   440     if ( !p )
   440 		if ( !p )
   441       return rgb.replace(/^#/, '');
   441 			return rgb.replace(/^#/, '');
   442     
   442 		
   443     var r = parseInt(p[1]).toString(16), g = parseInt(p[2]).toString(16), b = parseInt(p[3]).toString(16);
   443 		var r = parseInt(p[1]).toString(16), g = parseInt(p[2]).toString(16), b = parseInt(p[3]).toString(16);
   444     if ( r.length < 2 )
   444 		if ( r.length < 2 )
   445       r = '0' + r;
   445 			r = '0' + r;
   446     if ( g.length < 2 )
   446 		if ( g.length < 2 )
   447       g = '0' + g;
   447 			g = '0' + g;
   448     if ( b.length < 2 )
   448 		if ( b.length < 2 )
   449       b = '0' + b;
   449 			b = '0' + b;
   450     
   450 		
   451     return r + g + b;
   451 		return r + g + b;
   452   }
   452 	}
   453   
   453 	
   454   /**
   454 	/**
   455    * Get red, green, and blue values for the given hex color
   455  	* Get red, green, and blue values for the given hex color
   456    * @param string
   456  	* @param string
   457    * @return array (numbered, e.g. not an object
   457  	* @return array (numbered, e.g. not an object
   458    */
   458  	*/
   459   
   459 	
   460   this.hex2rgb = function(hex)
   460 	this.hex2rgb = function(hex)
   461   {
   461 	{
   462     hex = hex.replace(/^#/, '');
   462 		hex = hex.replace(/^#/, '');
   463     if ( hex.length != 3 && hex.length != 6 )
   463 		if ( hex.length != 3 && hex.length != 6 )
   464     {
   464 		{
   465       return hex;
   465 			return hex;
   466     }
   466 		}
   467     if ( hex.length == 3 )
   467 		if ( hex.length == 3 )
   468     {
   468 		{
   469       // is there a better way to do this?
   469 			// is there a better way to do this?
   470       hex = hex.charAt(0) + hex.charAt(0) + hex.charAt(1) + hex.charAt(1) + hex.charAt(2) + hex.charAt(2);
   470 			hex = hex.charAt(0) + hex.charAt(0) + hex.charAt(1) + hex.charAt(1) + hex.charAt(2) + hex.charAt(2);
   471     }
   471 		}
   472     hex = [ hex.substr(0, 2), hex.substr(2, 2), hex.substr(4, 2) ];
   472 		hex = [ hex.substr(0, 2), hex.substr(2, 2), hex.substr(4, 2) ];
   473     var red = parseInt(hex[0], 16);
   473 		var red = parseInt(hex[0], 16);
   474     var green = parseInt(hex[1], 16);
   474 		var green = parseInt(hex[1], 16);
   475     var blue = parseInt(hex[2], 16);
   475 		var blue = parseInt(hex[2], 16);
   476     return [red, green, blue];
   476 		return [red, green, blue];
   477   }
   477 	}
   478 }
   478 }
   479 
   479 
   480 /**
   480 /**
   481  * Perform request for editable rank data and draw editor
   481  * Perform request for editable rank data and draw editor
   482  */
   482  */
   483 
   483 
   484 function ajaxInitRankEdit(rank_id)
   484 function ajaxInitRankEdit(rank_id)
   485 {
   485 {
   486   load_component('messagebox');
   486 	load_component('messagebox');
   487   var json_packet = {
   487 	var json_packet = {
   488     mode: 'get_rank',
   488 		mode: 'get_rank',
   489     rank_id: rank_id
   489 		rank_id: rank_id
   490   };
   490 	};
   491   json_packet = ajaxEscape(toJSONString(json_packet));
   491 	json_packet = ajaxEscape(toJSONString(json_packet));
   492   ajaxPost(makeUrlNS('Admin', 'UserRanks/action.json'), 'r=' + json_packet, function(ajax)
   492 	ajaxPost(makeUrlNS('Admin', 'UserRanks/action.json'), 'r=' + json_packet, function(ajax)
   493     {
   493 		{
   494       if ( ajax.readyState == 4 && ajax.status == 200 )
   494 			if ( ajax.readyState == 4 && ajax.status == 200 )
   495       {
   495 			{
   496         var response = String(ajax.responseText + '');
   496 				var response = String(ajax.responseText + '');
   497         if ( !check_json_response(response) )
   497 				if ( !check_json_response(response) )
   498         {
   498 				{
   499           handle_invalid_json(ajax.responseText);
   499 					handle_invalid_json(ajax.responseText);
   500           return false;
   500 					return false;
   501         }
   501 				}
   502         try
   502 				try
   503         {
   503 				{
   504           var response = parseJSON(ajax.responseText);
   504 					var response = parseJSON(ajax.responseText);
   505         }
   505 				}
   506         catch(e)
   506 				catch(e)
   507         {
   507 				{
   508           handle_invalid_json(ajax.responseText);
   508 					handle_invalid_json(ajax.responseText);
   509         }
   509 				}
   510         if ( response.error )
   510 				if ( response.error )
   511         {
   511 				{
   512           if ( response.error == 'need_auth_to_admin' )
   512 					if ( response.error == 'need_auth_to_admin' )
   513           {
   513 					{
   514             load_component('login');
   514 						load_component('login');
   515             var rid = rank_id;
   515 						var rid = rank_id;
   516             ajaxDynamicReauth(function()
   516 						ajaxDynamicReauth(function()
   517               {
   517 							{
   518                 ajaxInitRankEdit(rid);
   518 								ajaxInitRankEdit(rid);
   519               });
   519 							});
   520           }
   520 					}
   521           else
   521 					else
   522           {
   522 					{
   523             alert(response.error);
   523 						alert(response.error);
   524           }
   524 					}
   525           return false;
   525 					return false;
   526         }
   526 				}
   527         var editor = new RankEditorControl(response);
   527 				var editor = new RankEditorControl(response);
   528         editor.onsubmit = ajaxRankEditHandleSaveExisting;
   528 				editor.onsubmit = ajaxRankEditHandleSaveExisting;
   529         editor.ondelete = ajaxRankEditHandleDelete;
   529 				editor.ondelete = ajaxRankEditHandleDelete;
   530         var container = document.getElementById('admin_ranks_container_right');
   530 				var container = document.getElementById('admin_ranks_container_right');
   531         container.innerHTML = '';
   531 				container.innerHTML = '';
   532         container.appendChild(editor.render());
   532 				container.appendChild(editor.render());
   533       }
   533 			}
   534     }, true);
   534 		}, true);
   535 }
   535 }
   536 
   536 
   537 function ajaxInitRankCreate()
   537 function ajaxInitRankCreate()
   538 {
   538 {
   539   load_component('messagebox');
   539 	load_component('messagebox');
   540   var editor = new RankEditorControl();
   540 	var editor = new RankEditorControl();
   541   editor.onsubmit = ajaxRankEditHandleSaveNew;
   541 	editor.onsubmit = ajaxRankEditHandleSaveNew;
   542   var container = document.getElementById('admin_ranks_container_right');
   542 	var container = document.getElementById('admin_ranks_container_right');
   543   container.innerHTML = '';
   543 	container.innerHTML = '';
   544   container.appendChild(editor.render());
   544 	container.appendChild(editor.render());
   545 }
   545 }
   546 
   546 
   547 function ajaxRankEditHandleSave(editor, switch_new)
   547 function ajaxRankEditHandleSave(editor, switch_new)
   548 {
   548 {
   549   var whitey = whiteOutElement(editor.wrapperdiv);
   549 	var whitey = whiteOutElement(editor.wrapperdiv);
   550   
   550 	
   551   // pack it up, ...
   551 	// pack it up, ...
   552   var json_packet = {
   552 	var json_packet = {
   553     mode: ( switch_new ) ? 'create_rank' : 'save_rank',
   553 		mode: ( switch_new ) ? 'create_rank' : 'save_rank',
   554     rank_title: editor.f_rank_title.value,
   554 		rank_title: editor.f_rank_title.value,
   555     rank_style: editor.getCSS()
   555 		rank_style: editor.getCSS()
   556   }
   556 	}
   557   if ( !switch_new )
   557 	if ( !switch_new )
   558   {
   558 	{
   559     json_packet.rank_id = editor.rankdata.rank_id;
   559 		json_packet.rank_id = editor.rankdata.rank_id;
   560   }
   560 	}
   561   /// ... pack it in
   561 	/// ... pack it in
   562   var json_packet = ajaxEscape(toJSONString(json_packet));
   562 	var json_packet = ajaxEscape(toJSONString(json_packet));
   563   
   563 	
   564   ajaxPost(makeUrlNS('Admin', 'UserRanks/action.json'), 'r=' + json_packet, function(ajax)
   564 	ajaxPost(makeUrlNS('Admin', 'UserRanks/action.json'), 'r=' + json_packet, function(ajax)
   565     {
   565 		{
   566       if ( ajax.readyState == 4 && ajax.status == 200 )
   566 			if ( ajax.readyState == 4 && ajax.status == 200 )
   567       {
   567 			{
   568         var response = String(ajax.responseText + '');
   568 				var response = String(ajax.responseText + '');
   569         if ( !check_json_response(response) )
   569 				if ( !check_json_response(response) )
   570         {
   570 				{
   571           handle_invalid_json(ajax.responseText);
   571 					handle_invalid_json(ajax.responseText);
   572           return false;
   572 					return false;
   573         }
   573 				}
   574         try
   574 				try
   575         {
   575 				{
   576           var response = parseJSON(ajax.responseText);
   576 					var response = parseJSON(ajax.responseText);
   577         }
   577 				}
   578         catch(e)
   578 				catch(e)
   579         {
   579 				{
   580           handle_invalid_json(ajax.responseText);
   580 					handle_invalid_json(ajax.responseText);
   581         }
   581 				}
   582         if ( response.mode == 'success' )
   582 				if ( response.mode == 'success' )
   583         {
   583 				{
   584           whiteOutReportSuccess(whitey);
   584 					whiteOutReportSuccess(whitey);
   585           if ( switch_new )
   585 					if ( switch_new )
   586           {
   586 					{
   587             //
   587 						//
   588             // we have a few more things to do with a newly created rank.
   588 						// we have a few more things to do with a newly created rank.
   589             //
   589 						//
   590             
   590 						
   591             // 1. transform editor
   591 						// 1. transform editor
   592             editor.transformToEditor(response);
   592 						editor.transformToEditor(response);
   593             editor.onsubmit = ajaxRankEditHandleSaveExisting;
   593 						editor.onsubmit = ajaxRankEditHandleSaveExisting;
   594             editor.ondelete = ajaxRankEditHandleDelete;
   594 						editor.ondelete = ajaxRankEditHandleDelete;
   595             
   595 						
   596             // 2. append the new rank to the list
   596 						// 2. append the new rank to the list
   597             var create_link = document.getElementById('rankadmin_createlink');
   597 						var create_link = document.getElementById('rankadmin_createlink');
   598             if ( create_link )
   598 						if ( create_link )
   599             {
   599 						{
   600               var parent = create_link.parentNode;
   600 							var parent = create_link.parentNode;
   601               var edit_link = document.createElement('a');
   601 							var edit_link = document.createElement('a');
   602               edit_link.href = '#rank_edit:' + response.rank_id;
   602 							edit_link.href = '#rank_edit:' + response.rank_id;
   603               edit_link.className = 'rankadmin-editlink';
   603 							edit_link.className = 'rankadmin-editlink';
   604               edit_link.setAttribute('style', editor.getCSS());
   604 							edit_link.setAttribute('style', editor.getCSS());
   605               edit_link.id = 'rankadmin_editlink_' + response.rank_id;
   605 							edit_link.id = 'rankadmin_editlink_' + response.rank_id;
   606               edit_link.rank_id = response.rank_id;
   606 							edit_link.rank_id = response.rank_id;
   607               edit_link.appendChild(document.createTextNode($lang.get(editor.f_rank_title.value)));
   607 							edit_link.appendChild(document.createTextNode($lang.get(editor.f_rank_title.value)));
   608               parent.insertBefore(edit_link, create_link);
   608 							parent.insertBefore(edit_link, create_link);
   609               edit_link.onclick = function()
   609 							edit_link.onclick = function()
   610               {
   610 							{
   611                 ajaxInitRankEdit(this.rank_id);
   611 								ajaxInitRankEdit(this.rank_id);
   612               }
   612 							}
   613             }
   613 						}
   614           }
   614 					}
   615           else
   615 					else
   616           {
   616 					{
   617             // update the rank title on the left
   617 						// update the rank title on the left
   618             var edit_link = document.getElementById('rankadmin_editlink_' + editor.rankdata.rank_id);
   618 						var edit_link = document.getElementById('rankadmin_editlink_' + editor.rankdata.rank_id);
   619             if ( edit_link )
   619 						if ( edit_link )
   620             {
   620 						{
   621               edit_link.firstChild.nodeValue = $lang.get(editor.f_rank_title.value);
   621 							edit_link.firstChild.nodeValue = $lang.get(editor.f_rank_title.value);
   622               edit_link.setAttribute('style', editor.getCSS());
   622 							edit_link.setAttribute('style', editor.getCSS());
   623             }
   623 						}
   624           }
   624 					}
   625         }
   625 				}
   626         else
   626 				else
   627         {
   627 				{
   628           whitey.parentNode.removeChild(whitey);
   628 					whitey.parentNode.removeChild(whitey);
   629           if ( response.error == 'need_auth_to_admin' )
   629 					if ( response.error == 'need_auth_to_admin' )
   630           {
   630 					{
   631             load_component('login');
   631 						load_component('login');
   632             ajaxDynamicReauth(function()
   632 						ajaxDynamicReauth(function()
   633               {
   633 							{
   634                 ajaxRankEditHandleSave(editor, switch_new);
   634 								ajaxRankEditHandleSave(editor, switch_new);
   635               });
   635 							});
   636           }
   636 					}
   637           else
   637 					else
   638           {
   638 					{
   639             miniPromptMessage({
   639 						miniPromptMessage({
   640                 title: $lang.get('acpur_err_save_failed_title'),
   640 								title: $lang.get('acpur_err_save_failed_title'),
   641                 message: response.error,
   641 								message: response.error,
   642                 buttons: [
   642 								buttons: [
   643                   {
   643 									{
   644                     text: $lang.get('etc_ok'),
   644 										text: $lang.get('etc_ok'),
   645                     color: 'red',
   645 										color: 'red',
   646                     style: {
   646 										style: {
   647                       fontWeight: 'bold'
   647 											fontWeight: 'bold'
   648                     },
   648 										},
   649                     onclick: function()
   649 										onclick: function()
   650                     {
   650 										{
   651                       miniPromptDestroy(this);
   651 											miniPromptDestroy(this);
   652                     }
   652 										}
   653                   }
   653 									}
   654                 ]
   654 								]
   655             });
   655 						});
   656           }
   656 					}
   657         }
   657 				}
   658       }
   658 			}
   659     }, true);
   659 		}, true);
   660 }
   660 }
   661 
   661 
   662 var ajaxRankEditHandleSaveExisting = function()
   662 var ajaxRankEditHandleSaveExisting = function()
   663 {
   663 {
   664   ajaxRankEditHandleSave(this, false);
   664 	ajaxRankEditHandleSave(this, false);
   665 }
   665 }
   666 
   666 
   667 var ajaxRankEditHandleSaveNew = function()
   667 var ajaxRankEditHandleSaveNew = function()
   668 {
   668 {
   669   ajaxRankEditHandleSave(this, true);
   669 	ajaxRankEditHandleSave(this, true);
   670 }
   670 }
   671 
   671 
   672 var ajaxRankEditHandleDelete = function()
   672 var ajaxRankEditHandleDelete = function()
   673 {
   673 {
   674   var mp = miniPromptMessage({
   674 	var mp = miniPromptMessage({
   675       title: $lang.get('acpur_msg_rank_delete_confirm_title'),
   675 			title: $lang.get('acpur_msg_rank_delete_confirm_title'),
   676       message: $lang.get('acpur_msg_rank_delete_confirm_body'),
   676 			message: $lang.get('acpur_msg_rank_delete_confirm_body'),
   677       buttons: [
   677 			buttons: [
   678         {
   678 				{
   679           text: $lang.get('acpur_btn_delete'),
   679 					text: $lang.get('acpur_btn_delete'),
   680           color: 'red',
   680 					color: 'red',
   681           style: {
   681 					style: {
   682             fontWeight: 'bold'
   682 						fontWeight: 'bold'
   683           },
   683 					},
   684           onclick: function()
   684 					onclick: function()
   685           {
   685 					{
   686             var parent = miniPromptGetParent(this);
   686 						var parent = miniPromptGetParent(this);
   687             var editor = parent.editor;
   687 						var editor = parent.editor;
   688             setTimeout(function()
   688 						setTimeout(function()
   689               {
   689 							{
   690                 ajaxRankEditDeleteConfirmed(editor);
   690 								ajaxRankEditDeleteConfirmed(editor);
   691               }, 1000);
   691 							}, 1000);
   692             miniPromptDestroy(parent);
   692 						miniPromptDestroy(parent);
   693           }
   693 					}
   694         },
   694 				},
   695         {
   695 				{
   696           text: $lang.get('etc_cancel'),
   696 					text: $lang.get('etc_cancel'),
   697           onclick: function()
   697 					onclick: function()
   698           {
   698 					{
   699             miniPromptDestroy(this);
   699 						miniPromptDestroy(this);
   700           }
   700 					}
   701         }
   701 				}
   702       ]
   702 			]
   703     });
   703 		});
   704   console.debug(mp);
   704 	console.debug(mp);
   705   mp.editor = this;
   705 	mp.editor = this;
   706 }
   706 }
   707 
   707 
   708 function ajaxRankEditDeleteConfirmed(editor)
   708 function ajaxRankEditDeleteConfirmed(editor)
   709 {
   709 {
   710   var whitey = whiteOutElement(editor.wrapperdiv);
   710 	var whitey = whiteOutElement(editor.wrapperdiv);
   711   
   711 	
   712   load_component(['jquery', 'jquery-ui']);
   712 	load_component(['jquery', 'jquery-ui']);
   713   
   713 	
   714   var json_packet = {
   714 	var json_packet = {
   715     mode: 'delete_rank',
   715 		mode: 'delete_rank',
   716     rank_id: editor.rankdata.rank_id
   716 		rank_id: editor.rankdata.rank_id
   717   };
   717 	};
   718   var rank_id = editor.rankdata.rank_id;
   718 	var rank_id = editor.rankdata.rank_id;
   719   
   719 	
   720   json_packet = ajaxEscape(toJSONString(json_packet));
   720 	json_packet = ajaxEscape(toJSONString(json_packet));
   721   ajaxPost(makeUrlNS('Admin', 'UserRanks/action.json'), 'r=' + json_packet, function(ajax)
   721 	ajaxPost(makeUrlNS('Admin', 'UserRanks/action.json'), 'r=' + json_packet, function(ajax)
   722     {
   722 		{
   723       if ( ajax.readyState == 4 && ajax.status == 200 )
   723 			if ( ajax.readyState == 4 && ajax.status == 200 )
   724       {
   724 			{
   725         var response = String(ajax.responseText + '');
   725 				var response = String(ajax.responseText + '');
   726         if ( !check_json_response(response) )
   726 				if ( !check_json_response(response) )
   727         {
   727 				{
   728           handle_invalid_json(ajax.responseText);
   728 					handle_invalid_json(ajax.responseText);
   729           return false;
   729 					return false;
   730         }
   730 				}
   731         try
   731 				try
   732         {
   732 				{
   733           var response = parseJSON(ajax.responseText);
   733 					var response = parseJSON(ajax.responseText);
   734         }
   734 				}
   735         catch(e)
   735 				catch(e)
   736         {
   736 				{
   737           handle_invalid_json(ajax.responseText);
   737 					handle_invalid_json(ajax.responseText);
   738         }
   738 				}
   739         if ( response.mode == 'success' )
   739 				if ( response.mode == 'success' )
   740         {
   740 				{
   741           // the deletion was successful, report success and kill off the editor
   741 					// the deletion was successful, report success and kill off the editor
   742           whiteOutReportSuccess(whitey);
   742 					whiteOutReportSuccess(whitey);
   743           setTimeout(function()
   743 					setTimeout(function()
   744             {
   744 						{
   745               // nuke the rank title on the left
   745 							// nuke the rank title on the left
   746               var edit_link = document.getElementById('rankadmin_editlink_' + editor.rankdata.rank_id);
   746 							var edit_link = document.getElementById('rankadmin_editlink_' + editor.rankdata.rank_id);
   747               if ( edit_link )
   747 							if ( edit_link )
   748               {
   748 							{
   749                 edit_link.parentNode.removeChild(edit_link);
   749 								edit_link.parentNode.removeChild(edit_link);
   750               }
   750 							}
   751               // collapse and destroy the editor
   751 							// collapse and destroy the editor
   752               $(editor.wrapperdiv).hide("blind", {}, 500, function()
   752 							$(editor.wrapperdiv).hide("blind", {}, 500, function()
   753                   {
   753 									{
   754                     // when the animation finishes, nuke the whole thing
   754 										// when the animation finishes, nuke the whole thing
   755                     var container = document.getElementById('admin_ranks_container_right');
   755 										var container = document.getElementById('admin_ranks_container_right');
   756                     container.innerHTML = $lang.get('acpur_msg_select_rank');
   756 										container.innerHTML = $lang.get('acpur_msg_select_rank');
   757                   }
   757 									}
   758                 );
   758 								);
   759             }, 1500);
   759 						}, 1500);
   760         }
   760 				}
   761         else
   761 				else
   762         {
   762 				{
   763           whitey.parentNode.removeChild(whitey);
   763 					whitey.parentNode.removeChild(whitey);
   764           if ( response.error == 'need_auth_to_admin' )
   764 					if ( response.error == 'need_auth_to_admin' )
   765           {
   765 					{
   766             load_component('login');
   766 						load_component('login');
   767             ajaxDynamicReauth(function()
   767 						ajaxDynamicReauth(function()
   768               {
   768 							{
   769                 ajaxRankEditDeleteConfirmed(editor);
   769 								ajaxRankEditDeleteConfirmed(editor);
   770               });
   770 							});
   771           }
   771 					}
   772           else
   772 					else
   773           {
   773 					{
   774             miniPromptMessage({
   774 						miniPromptMessage({
   775                 title: $lang.get('acpur_err_delete_failed_title'),
   775 								title: $lang.get('acpur_err_delete_failed_title'),
   776                 message: response.error,
   776 								message: response.error,
   777                 buttons: [
   777 								buttons: [
   778                   {
   778 									{
   779                     text: $lang.get('etc_ok'),
   779 										text: $lang.get('etc_ok'),
   780                     color: 'red',
   780 										color: 'red',
   781                     style: {
   781 										style: {
   782                       fontWeight: 'bold'
   782 											fontWeight: 'bold'
   783                     },
   783 										},
   784                     onclick: function()
   784 										onclick: function()
   785                     {
   785 										{
   786                       miniPromptDestroy(this);
   786 											miniPromptDestroy(this);
   787                     }
   787 										}
   788                   }
   788 									}
   789                 ]
   789 								]
   790             });
   790 						});
   791           }
   791 					}
   792         }
   792 				}
   793       }
   793 			}
   794     }, true);
   794 		}, true);
   795 }
   795 }