User:Ale jrb/Scripts/catMan.js

/* ============================================== *\ \* ============================================== */	function catManMain { // =======	// 		Initialisation object. This object handles the creation of the rest of the script. // =======		var me = this; me.settings = new Object ; this.init = function { // init - check namespace // SETUP: this section contains the namespaces the catMan will operate in. var runInNamespaces = new Array ( 0, 2, 4, 6, 8, 10, 12, 14 ); // ENDSETUP if ( ! runInNamespaces.contains ( mw.config.get('wgNamespaceNumber') ) ) return false; if ( mw.config.get('wgTitle').indexOf ( '.js' ) > -1 ) return false; // allow removal // init - objects me.memory = new catManMemory ; me.memory.fillMemoryObjects; wa_window.prototype = new wa_document; wa_element.prototype = new wa_document; // init - check cookies, memory me.memory.storem ( 'success', 'cookietest', 0.04 ); if ( me.memory.loadm ( 'cookietest' ) != 'success' ) { alert ( 'catMan could not access memory - load stopped' ); return false; } me.doSettings ; me.defendSelf ; // init - main me.interface = new catManInterface ; me.interface.init ; me.actions = new catManActions ; me.actions.init ; me.interaction = new catManInteraction ; me.interaction.init ; me.cats = new catManCats ; me.cats.init ; // init - first run if ( ( me.firstRun == true ) && ( me.settings['allow-url-manipulation'] == 'true' ) ) { window.location = me.settings['url-server'] + me.settings['url-path'] + me.settings['url-install-good']; }		}		this.doSettings = function ( action ) { if ( action == 'store' ) { var settingString = ''; for ( i in me.settings ) { settingString += i + '<<<' + me.settings[i] + '|||'; }				me.memory.storem ( settingString, 'set' ) } else { if ( ! me.memory.loadm ( 'set' ) ) { // SETUP: this section contains the settings that will be given to users by default. // actions // permissions me.settings['allow-url-manipulation'] = 'true'; 								// catMan can automatically browse to new pages me.settings['allow-state-defence'] = 'true';									// catMan can defend its editing state by preventing browsing me.settings['allow-javascript-defence'] = 'true';								// catMan can defend its compatibility by attacking other scripts // urls me.settings['url-server'] = mw.config.get('wgServer'); me.settings['url-path'] = mw.config.get('wgArticlePath').replace ( '$1', '' ); me.settings['url-install-good'] = 'User:Ale_jrb/Scripts/catMan/Welcome';		// the location to redirect to on first run me.settings['url-blacklist'] = 'User:Ale_jrb/Scripts/catMat/Blacklist';			// the location of the category blacklist // data me.settings['cache-blacklist'] = 'true';										// whether catMan should cache the blacklist to the hard drive // config me.settings['config-show-int-after'] = 0.15;									// how long you must hover over the category area to show catMan me.settings['config-remove-int-after'] = 1.2;									// how long you must leave the category area before catMan will disappear me.settings['config-use-intellicat'] = 'true';									// whether catMan should attempt to provide intelligent category suggestions me.settings['config-start-intellicat'] = 1;										// how quickly catMan should degeneralise its suggestions (lower = faster) me.settings['config-use-blacklist'] = 'true';									// whether catMan should enforce the category blacklist, preventing addition of those cats me.settings['config-notify-general-cat'] = 'true';								// whether catMan should scan for overly-general categories me.settings['config-general-cat-limit'] = 20;									// how many sub-cats a category can have before it is considered overly general me.settings['config-notify-nonexist-cat'] = 'true';							// whether catMan should scan for non-existant categories // ENDSETUP me.doSettings ( 'store' ); } else { var settings = me.memory.loadm ( 'set' ); settings = settings.split ( '|||' ); for ( i in settings ) { if ( typeof settings[i] !== 'string' ) continue; var key = settings[i].substr ( 0, settings[i].indexOf ( '<<<' ) ); var content = settings[i].substr ( settings[i].indexOf ( '<<<' ) + 3 ); me.settings[key] = content; }				}			}		}		this.defendSelf = function { if ( me.settings['allow-javascript-defence'] != 'true' ) return false; // hotCat var t = document.getElementById ( 'catlinks' ); if ( t ) { var d = t.innerHTML, r = []; r[0] = //ig; r[1] = //ig; r[2] = /(?:\| *?)?/ig; for ( var i = 0, l = r.length; i < l; i ++ ) { d = d.replace ( r[i], '' ); }				t.innerHTML = d;			} }		this.firstRun = function { var test = me.memory.loadm ( 'run' ); if ( ! test ) { me.memory.storem( '1', 'run' ); return true; } else { return false; } }	}	function catManInteraction { // =======	// 		Interaction object. This object handles attaching other actions to global events. // =======		var me = this; me.active = 0; this.init = function { // connect to the catlinks space me.interfaceHide = false; me.interfaceShow = false; var catlinks = document.getElementById ( 'catlinks' ); var mainint = document.getElementById ( 'catman_container' ); wa_attach ( catlinks, 'mouseenter', function ( e ) { 														 	if ( me.interfaceHide ) { 														  		clearTimeout ( me.interfaceHide ); 																me.interfaceHide = false;															} else { 																me.interfaceShow = setTimeout ( function  { catMan.interface.show ( e, true ); }, ( catMan.settings['config-show-int-after'] * 1000 ) ); 															} 														 } ); wa_attach ( catlinks, 'mouseleave', function { 														  	if ( me.interfaceShow ) { 																clearTimeout ( me.interfaceShow ); 																me.interfaceShow = false; 															} else { 																me.interfaceHide = setTimeout ( catMan.interface.hide, ( catMan.settings['config-remove-int-after'] * 1000 ) ); 															} 														} ); wa_attach ( mainint, 'mouseenter', function { clearTimeout ( me.interfaceHide ); } ); wa_attach ( mainint, 'mouseleave', function { me.interfaceHide = setTimeout ( catMan.interface.hide, ( catMan.settings['config-remove-int-after'] * 1000 ) ); } ); }		this.registerActive = function ( activeid ) { // by registering an active category, the interaction manager will be aware what should be checked to determine what the // user currently intends to do. if ( me.active !== activeid ) { me.active = activeid; // set active // clear existing content, so users don't get confused: document.getElementById ( 'catman_col2' ).innerHTML = ' intellicat is building a data set - wait...
 * catMan - JavaScript Category Editor
 * for MediaWiki v1.16 and above
 * Copyright (c) Alex Barley User:Ale_jrb
 * Some rights reserved.
 * revision: 0031 (ALPHA)
 * TRACKER: User:Ale_jrb/Scripts
 * revision: 0031 (ALPHA)
 * TRACKER: User:Ale_jrb/Scripts
 * TRACKER: User:Ale_jrb/Scripts
 * TRACKER: User:Ale_jrb/Scripts

so what\'s going on? intellicat is currently building a list of categories that you may be referring to. For more info on intellicat, check out the manual. ';				me.performIntellicat ; // call intellicat }		}		this.manageActivity = function { if ( ! catMan.cats.intellicatRunning ) { var cattext = document.getElementById ( 'catMan_cat_' + me.active + '_txt' ).value; catMan.cats.intellicat ( 0, cattext, function ( d ) { catMan.interface.displayintellicat ( d ); } ); }		}		this.performIntellicat = function { // this method calls the intellicat system with the content of the currently active category input field var cattext = document.getElementById ( 'catMan_cat_' + me.active + '_txt' ).value; catMan.cats.intellicat ( 0, cattext, function ( d ) { catMan.interface.displayintellicat ( d ); } ); }	}	function catManCats { var me = this; me.os = []; me.ms = []; me.sc = []; me.results = {}; me.limit = 0; me.intellicatRunning = false; this.init = function { // nothing much to do here }		this.getcats = function ( pagename, doparse ) { // get the categories that a page is in			switch ( doparse ) { default: case 0: wa ( ':api' ).command ( 'getcats', 'format=xml&action=query&prop=categories&clshow=!hidden&cllimit=500&titles=' + wa(':func').encodewiki ( pagename ) ).get( 'getcats2', pagename, 1 ).wait ( function { catMan.cats.getcats ( 0, 1 ); } ).run ; break; case 1: me.results ['pageincats'] = []; if ( wa ( ':api' ).results['getcats']['query']['pages']['page-attr']['missing'] !== undefined ) return false; if ( wa ( ':api' ).results['getcats']['query']['pages']['page'] !== null ) { var cats = wa ( ':api' ).results['getcats']['query']['pages']['page']['categories']['cl-attr']; } else { catMan.interface.displaymaincats ; return false; } var catstext = wa ( ':api' ).results['getcats2']['query']['pages']['page']['revisions']['rev']['#text']; // get from text var cats2 = catMan.actions.extractCategories ( catstext ); // add those to the list if ( cats2 !== false ) { for ( var i = 0, l = cats2.length; i < l; i ++ ) { var t = []; t[0] = cats2[i][0]; t[1] = 1; // canedit t[2] = 0; // status: all is well me.results ['pageincats'].push ( t ); }				}				// reduce the api list to those we haven't already added if ( cats.length !== undefined ) { for ( var i = 0, l = cats.length; i < l; i ++ ) { if ( ! me.results ['pageincats'].contains ( cats[i]['title'].substr ( 9 ), true ) ) { var t = []; t[0] = cats[i]['title'].substr ( 9 ); t[1] = 2; // cannotedit t[2] = 0; // status: all is well me.results ['pageincats'].push ( t ); }					}				} else { if ( ! me.results ['pageincats'].contains ( cats['title'].substr ( 9 ), true ) ) { var t = []; t[0] = cats['title'].substr ( 9 ); t[1] = 2; // cannotedit t[2] = 0; // status: all is well me.results ['pageincats'].push ( t ); }				}				if ( ( catMan.settings['config-notify-nonexist-cat'] == 'true' ) && ( catMan.settings['config-notify-general-cat'] == 'true' ) ) { var useid = 'catscheck_', t = ''; for ( var i = 0, l = me.results['pageincats'].length; i < l; i ++ ) { t += 'Category:' + me.results['pageincats'][i][0] + '|'; }					t = t.substr ( 0, t.length - 1 ); t = wa ( ':func' ).encodewiki ( t ); wa ( ':api' ).command ( useid + 'end', 'format=xml&action=query&prop=revisions&rvprop=ids&titles=' + t ).run ( 'checkFullQueue' ); for ( var i = 0, l = me.results['pageincats'].length; i < l; i ++ ) { wa ( ':api' ).command ( useid + i, 'format=xml&action=query&list=categorymembers&cmlimit=500&cmnamespace=14&cmtitle=' + wa(':func').encodewiki ( 'Category:' + me.results['pageincats'][i][0] ) ).run( 'checkFullQueue' ); }					wa ( ':api' ).wait ( function { catMan.cats.getcats ( 'catManInternal_checkGeneral', 2 ); } ).run ( 'checkFullQueue' ); } else if ( catMan.settings['config-notify-nonexist-cat'] == 'true' ) { var useid = 'catscheck_', t = ''; for ( var i = 0, l = me.results['pageincats'].length; i < l; i ++ ) { t += 'Category:' + me.results['pageincats'][i][0] + '|'; }					t = t.substr ( 0, t.length - 1 ); t = wa ( ':func' ).encodewiki ( t ); wa ( ':api' ).command ( useid + 'end', 'format=xml&action=query&prop=revisions&rvprop=ids&titles=' + t ).wait ( function { catMan.cats.getcats ( 0, 2 ); } ).run ; } else if ( catMan.settings['config-notify-general-cat'] == 'true' ) { var useid = 'catscheck_', t = ''; for ( var i = 0, l = me.results['pageincats'].length; i < l; i ++ ) { wa ( ':api' ).command ( useid + i, 'format=xml&action=query&list=categorymembers&cmlimit=500&cmnamespace=14&cmtitle=' + wa(':func').encodewiki ( 'Category:' + me.results['pageincats'][i][0] ) ).run( 'checkGeneralQueue' ); }					wa ( ':api' ).wait ( function { catMan.cats.getcats ( 'catManInternal_checkGeneral', '2b' ); } ).run ( 'checkGeneralQueue' ); } else { // both false; do nothing }				break; case 2: var t;				for ( var i = 0, l = me.results ['pageincats'].length; i < l; i ++ ) { if ( wa (':api').results['catscheck_end']['query']['pages']['page-attr'] === null ) { throw 'catMan: unexpected return from API, page attributes missing when checking page existance'; return false; } else if ( wa (':api').results['catscheck_end']['query']['pages']['page-attr'].length === undefined ) { t = wa (':api').results['catscheck_end']['query']['pages']; if ( 'Category:' + me.results ['pageincats'][i][0] == t['page-attr']['title'] ) { if ( t['page-attr']['missing'] !== undefined ) me.results ['pageincats'][i][2] = 1; // cat doesn't exist }					} else { for ( var j = 0, m = wa (':api').results['catscheck_end']['query']['pages']['page-attr'].length; j < m; j ++ ) { t = wa (':api').results['catscheck_end']['query']['pages']; if ( 'Category:' + me.results ['pageincats'][i][0] == t['page-attr'][j]['title'] ) { if ( t['page-attr'][j]['missing'] !== undefined ) me.results ['pageincats'][i][2] = 1; // cat doesn't exist }						}					}				}			case '2b': if ( pagename === 'catManInternal_checkGeneral' ) { var useid = 'catscheck_', tid; for ( var i = 0, l = me.results['pageincats'].length; i < l; i ++ ) { tid = useid + i;						if ( wa ( ':api' ).results [tid]['query']['categorymembers'] !== null ) { if ( wa ( ':api' ).results [tid]['query']['categorymembers']['cm-attr'].length !== undefined ) { if ( ( wa ( ':api' ).results [tid]['query']['categorymembers']['cm-attr'].length >= catMan.settings['config-general-cat-limit'] ) && ( me.results ['pageincats'][i][2] !== 1 ) ) me.results ['pageincats'][i][2] = 2; // too general }						}					}				}				catMan.cats.getcats ( 0, 3 ); break; case 3: catMan.interface.displaymaincats ; break; }			return true; }		this.getsubcats = function ( pagename, doparse ) { // get the categories that a category contains if ( ! doparse ) { wa ( ':api' ).command ( 'getsubcats', 'format=xml&action=query&list=categorymembers&cmlimit=500&cmnamespace=14&cmtitle=' + wa(':func').encodewiki ( pagename ) ).wait ( function { catMan.cats.getsubcats ( 0, true ); } ).run ; } else { var cats = wa ( ':api' ).results['getsubcats']['query']['categorymembers']['cm-attr']; me.results ['catsincat'] = []; for ( var i in cats ) { me.results [i] = cats[i]['title']; }			}			return true; }		this.intellicat = function ( stage, text, runondone ) { if ( runondone ) me.runondone = runondone; if ( text ) { me.text = text; me.components = me.text.split ( ' ' ); }			switch ( stage ) { case 0: default: // start if ( ! me.text ) { throw 'catMan: unexpected intellicat input, missing check string'; return false; } me.intellicatRunning = true; wa ( ':api' ).kill ( 'cat' ); me.limit = 0; // reset if ( ( me.components[me.components.length - 1].length <= catMan.settings['config-start-intellicat'] ) || ( catMan.settings['config-use-intellicat'] !== 'true' ) ) { wa ( ':api' ).command ( 'suggestions', 'format=xml&action=opensearch&namespace=14&search=' + me.text ).wait ( function { catMan.cats.intellicat ( 101 ); } ).run ( 'cat' ); } else { wa ( ':api' ).get ( 'suggestions', 'Category:' + text, 1 ).wait ( function { catMan.cats.intellicat ( 1 ); } ).run ( 'cat' ); }					break; case 1: // check for exact page match if ( wa ( ':api' ).results['suggestions']['query']['pages']['page-attr']['missing'] === undefined ) { // fullsearch whole phrase --> 10 me.intellicat ( 10 ); } else { // opensearch whole phrase --> 3 wa ( ':api' ).command ( 'suggestions', 'format=xml&action=opensearch&namespace=14&search=' + me.text ).wait ( function { catMan.cats.intellicat ( 3 ); } ).run ( 'cat' ); }					break; case 3: // determine phrase to fullsearch var r = wa ( ':api' ).results['suggestions']['Section'], compc = ( me.components.length - me.limit ); if ( r === null ) { // no matches if ( ++ me.limit >= me.components.length ) { // just fullsearch! me.intellicat ( 10 ); } else { // continue with this process var t = ''; for ( var i = 0, l = ( me.components.length - me.limit ); i < l; i ++ ) { t += me.components [i] + ' '; }							t = t.substr ( 0, t.length - 1 ); wa ( ':api' ).command ( 'suggestions', 'format=xml&action=opensearch&namespace=14&search=' + t ).wait ( function { catMan.cats.intellicat ( 3 ); } ).run ( 'cat' ); }						break; }					r = r['Item']; if ( r[0] !== undefined ) { // multiple matches var compm = 0, compt, compw = {}; for ( var i = 0, l = r.length; i < l; i ++ ) { compt = r[i]['Text']['#text'].substr ( 9 ).split ( ' ' ); if ( compt [ compc - 1 ] !== undefined ) { if ( compw [ compt [ compc - 1 ] ] !== undefined ) { compw [ compt [ compc - 1 ] ] ++; } else { compw [ compt [ compc - 1 ] ] = 1; }							}						}						for ( var i in compw ) { if ( compw [i] > compm ) { me.compg = i;								compm = compw [i]; }						}						// fullsearch phrase match --> 11 me.intellicat ( 12 ); } else { // exactly one match var compt = r['Text']['#text'].substr ( 9 ).split ( ' ' ); if ( compt [ compc - 1 ] !== undefined ) { me.compg = compt [ compc - 1 ]; }						me.intellicat ( 12 ); }					break; case 10: // fullsearch whole phrase var t = ''; for ( var i = 0, l = me.components.length; i < l; i ++ ) { t += me.components [i] + ' '; }					t = t.substr ( 0, t.length - 1 ); wa ( ':api' ).command ( 'suggestions', 'format=xml&action=query&list=search&srnamespace=14&srprop=size&srsearch=' + t ).wait ( function { catMan.cats.intellicat ( 11 ); } ).run ( 'cat' ); break; case 11: // check fullsearch for suggestions var s = '', d = wa ( ':api' ).results['suggestions']['query']['searchinfo-attr']; if ( d['totalhits'] == 0 ) { if ( d['suggestion'] !== undefined ) { wa ( ':api' ).command ( 'suggestions', 'format=xml&action=query&list=search&srnamespace=14&srprop=size&srsearch=' + d['suggestion'] ).wait ( function { catMan.cats.intellicat ( 11 ); } ).run ( 'cat' ); } else { // total failure - end //alert ('faiiiiled'); me.intellicatRunning = false; document.getElementById ( 'catman_col2' ).innerHTML = ' intellicat failed to find related data - consider revising input...

what\s going on? intellicat couldn\'t find any categories that are related to the input of the active field. intellicat is very thorough, so this often means there is no such category on this wiki. Consider revising your input. ';						}					} else { me.intellicat ( 100 ); }					break; case 12: // fullsearch phrase match var t = ''; for ( var i = 0, l = ( me.components.length - me.limit ); i < ( l - 1 ); i ++ ) { t += me.components [i] + ' '; }					t += me.compg; wa ( ':api' ).command ( 'suggestions', 'format=xml&action=query&list=search&srnamespace=14&srprop=size&srsearch=' + t ).wait ( function { catMan.cats.intellicat ( 100 ); } ).run ( 'cat' ); break; case 100: // display fullsearch var s = ''; tout = wa ( ':api' ).results['suggestions']['query']['search']['p-attr']; me.output = []; if ( tout [0] === undefined ) { me.output [0] = tout['title']; s += tout['title'] + ''; } else { for ( var i = 0, l = tout.length; i < l; i ++ ) { me.output [i] = tout [i]['title']; s += tout [i]['title'] + ', '; }					}					me.intellicat ( 200 ); //alert ( s ); break; case 101: // display opensearch var s = ''; tout = wa ( ':api' ).results['suggestions']['Section']['Item']; me.output = []; if ( tout [0] === undefined ) { me.output [0] = tout['Text']['#text']; s += tout['Text']['#text'] + ''; } else { for ( var i = 0, l = tout.length; i < l; i ++ ) { me.output [i] = tout [i]['Text']['#text']; s += tout[i]['Text']['#text'] + ', '; }					}					me.intellicat ( 200 ); //alert ( s ); break; case 200: // finish me.intellicatRunning = false; if ( me.runondone ) me.runondone ( me.output ); break; }		}		this.display = function { }	}	function catManInterface { // =======	// 		Interface management object. This object allows the creation and destruction of any and all interface elements related to that script. // =======		var me = this; me.activecat = false; // main program interface methods // I define the main program for the purpose of these functions as the window that is displayed when a user // is editing categories in some way. In this, it is distinguished from any information tooltips. this.init = function { // column setup var col1default = '    to edit a category, just click and type below...  searching for categories... ';			var col2default = ' catMan\'s intellicat system automatically provides suggestions for possible categories. To begin, select a category from the left and start typing. ';			var col3default = ' MENU manage favourites (0) manage recent cats (0)

run script manage scripts

settings hide '; me.main = new wa_window ; me.main.win_width = 730; me.main.win_height = 200; me.main.win_padding = 0; me.main.win_left = 0; me.main.win_top = 0; me.main.win_content = ''; me.main.win_content += ''+col1default+' '; me.main.win_content += ''+col2default+' '; me.main.win_content += ''+col3default+' '; me.main.win_content += ' '; me.main.applyAll ; me.main.hide ; }		this.show = function ( e, move ) { // show moves the interface to the right place, and unhides it. //alert('t3'); var x = mousex ( e ); var y = mousey ( e ); // the category div var catlinks = document.getElementById ( 'catlinks' ); var catpos = wa_getObjPos ( catlinks ); // move and show the interface. I move the interface to the mouse x and the cat top y, then shift it based on dimensions. var mtx = ( x - ( me.main.win_width / 3.5 ) ); var mty = ( ( catpos [1] ) - me.main.win_height ); if ( move === true ) me.main.setLocation ( mtx, mty, true ); catMan.interaction.interfaceShow = false; me.main.show ; // begin searching for data catMan.cats.getcats ( mw.config.get('wgPageName') ); }		this.hide = function { // hide removes the interfave from the view, and deactives any active controls. catMan.interaction.interfaceHide = false; me.main.hide ; }		this.displayintellicat = function ( data ) { // stop if there is no response for some reason if ( ! data ) return false; if ( data.length === undefined ) return false; o = ''; for ( var i = 0, l = Math.min ( data.length, 12 ); i < l; i ++ ) { o += '- ' + data [i] + ' ';			}			document.getElementById ( 'catman_col2' ).innerHTML = ' the following categories may be relevant: ' + o + ' '; return true; }		this.displaymaincats = function { var cats = catMan.cats.results ['pageincats']; var output = ''; if ( cats.length === 0 ) { output = 'There are no categories on this page.'; document.getElementById ( 'catman_currentcats' ).innerHTML = output; return output; }			var col, disabled = , disabled2 = , info = ''; output += ' '; // create new output += ''; output += '  '; output += ' '; // existing for ( var i = 0, l = cats.length; i < l; i ++ ) { // interface if ( cats[i][1] === 1 ) { //canedit? if ( cats[i][2] === 0 ) { col = '#99ee99'; info = ''; } else if ( cats[i][2] === 1 ) { col = '#ee9999'; info = ' ? '; } else if ( cats[i][2] === 2 ) { col = '#9999ee'; info = ' ? '; }				} else { col = '#aaaaaa'; disabled = ' disabled '; disabled2 = 'cursor: default;'; info = ' ? ';				}				// output output += ''; output += '' + info + ' '; output += '  '; output += ' '; }			output += ' '; document.getElementById ( 'catman_currentcats' ).innerHTML = output; // events for ( var i = 0, l = cats.length; i < l; i ++ ) { var d = document.getElementById ( 'catMan_cat_' + i ); if ( cats[i][1] === 1 ) { //canedit? wa_attach ( d, 'mouseup', function { var myid = this.id.substr ( 11 ); var txt = document.getElementById ( 'catMan_cat_' + myid + '_txt' ); catMan.interaction.registerActive ( myid ); if ( catMan.interface.activecat === myid ) { return false; } else { catMan.interface.activecat = myid; txt.select ; txt.focus ;  }  } ); wa_attach ( d, 'keyup', function ( e ) { var myid = this.id.substr ( 11 ); catMan.interaction.manageActivity ( myid ); } ); } else { }			}			return output; }		// tooltip methods // I define tooltips for the purpose of these functins as simple windows or information popups that do not // require any complex functionality. In this, they are distinguished from the main window and its components. this.tooltip = function ( id, action, var1, var2, var3, var4 ) { // manage tooltip with the selected id if ( ! id ) return false; switch ( action ) { case 'create': // var1 = x pos, var2 = ypos, var3 = content, var4 = height override if ( ! var4 ) var4 = 200; // this uses the library funcs. Needs watching for when I change the library... var tooltip = new wa_window ; tooltip.win_left = var1; tooltip.win_top = var2; tooltip.win_pos = 'static'; tooltip.win_id = 'catman_tooltip_' + id; tooltip.win_bg = '#99cccc'; tooltip.win_bd = '#003366'; tooltip.win_bd_wd = 1; tooltip.win_width = 300; tooltip.win_height = var4; var content = ' catMan X   '; tooltip.win_content = content; tooltip.applyAll ; return true; break; case 'destroy': // vars irrelevant var tooltip = document.getElementById ( 'catMan_tooltip_' + id ); tooltip.parentNode.removeChild ( tooltip ); return true; break; case 'update': // var1 = content var tooltip = document.getElementById ( 'catMan_tooltip_' + id + '_content' ); tooltip.innerHTML = var1; return true; break; }			return false; }	}	function catManActions { // =======	// 		Action management object. These functions handle loading data, editing pages and searching the API. //				NB. waLib API functions can be a little messy. I should clean them up, but I can't really be bothered, so //					some of these functions only really serve as neat redirect calls. (fixed in waLib2) // =======		var me = this; this.init = function { return true; }		this.executeActionBuffer = function { // this function reads off the action buffer, edits the page text to add remove the relevant cats, etc.		} // lower functions this.extractCategories = function ( string ) { // this function extracts categories and category templates, and returns an array of the categories and types. var categories = new Array ; var regTest = /(\[\[|{{)category:([^\[\{]+?)(?:\]\]|}}|\|)/gi; var regResult; while ( regResult = regTest.exec ( string ) ) { if ( regResult[1] == '[[' ) {					categories.push ( [ regResult[2], 'c' ] );				} else {					categories.push ( [ regResult[2], 't' ] );				}			}			if ( categories.length > 0 ) {				return categories;			} else {				return false;			}		}		this.getPageData = function ( id, page, runOnGet ) {			wa ( ':api' ).get( id, page, 1 ).wait( runOnGet ).run;			return true;		}	}	function catManMemory {	// =======	// 		Buffer management object. These functions manage the internal program memory features, such as storing the actions that will need to be performed.	// =======		var me = this;		me.actionBuffer = new Array ;		me.favouriteCategories = new Array ;		me.recentCategories = new Array ;		// upper management - int array		this.addCategoryAction = function ( action, details ) {			// the addCategoryAction function adds a category removal or addition to the program buffer		}		this.manageFavouriteCategories = function ( action, details ) {			// the manageFavouriteCategories function allows you to add or remove favourite categories		}		this.addRecentCategory = function ( details ) {			// the addRecentCategory function adds a category to the top of the recent cats buffer, and removes the oldest one. It also prevents				// recent categories from being duplicated in the buffer		}		// lower management - helpers		this.fillMemoryObjects = function  {			// the fillMemoryObjects function resets the program internal memory arrays, and refills them from the cookies			me.favouriteCategories = null; me.favouriteCategories = new Array ;			me.recentCategories = null; me.recentCategories = new Array ;			var favourites = me.loadm ( 'fav' );			if ( favourites ) {				var favourites = favourites.split ( ',,' );				for ( i in favourites ) {					me.favouriteCategories.push ( favourites [i] );				}			}			var recent = me.loadm ( 'rec' );			if ( recent ) {				var recent = recent.split ( ',,' );				for ( i in recent ) {					me.recentCategories.push ( recent [i] );				}			}			return true;		}		// lower manegement - cookies		this.storem = function ( storeWhat, memId, expiresTime ) {			var cookieString = ;			if ( ! expiresTime ) expiresTime = 10000;			if ( ( memId.indexOf ( 'catMan_' ) !== 0 ) && ( memId.indexOf ( 'catMan_' ) !== 1 ) ) memId = 'catMan_' + memId;			storeWhat = storeWhat.replace ( ';', '::' );			cookieString += memId + '=' + storeWhat;			var date = new Date ;			date.setTime ( date.getTime  + expiresTime * 24 * 60 * 60 * 1000 );			cookieString += '; expires=' + date.toGMTString ;			cookieString += '; path=/';			document.cookie = cookieString;			return document.cookie;		}		this.loadm = function ( loadWhat ) {			var data = document.cookie;			data = data.split ( ';' );			if ( loadWhat.indexOf ( 'catMan_' ) !== 0 ) loadWhat = 'catMan_' + loadWhat;			for ( i in data ) {				if ( typeof data[i] !== 'string' ) continue;				if ( data[i].substr ( 0, 1 ) == ' ' ) data[i] = data[i].substr ( 1 );				if ( data[i].indexOf ( loadWhat + '=' )  === 0 ) {					var r = data[i].substr ( loadWhat.length + 1 );					r = r.replace ( '::', ';' );					return r;				}			}			return false;		}		this.readmids = function  {			var data = document.cookie;			var data2 = new Array ;			data = data.split ( ';' );			var j = 0;			for ( i in data ) {				if ( typeof data[i] !== 'string' ) continue;				if ( data[i].substr ( 0, 1 ) == ' ' ) data[i] = data[i].substr ( 1 );				if ( data[i].indexOf ( 'catMan_' )  === 0 ) {					data2[j] = data[i].substr ( 7, data[i].indexOf ( '=' ) );					j ++;				}			}			return data2;		}		this.renewm = function ( memId ) {			var data = me.loadm ( memId );			if ( data ) {				me.storem ( data, memId );			} else { return false; }		}		this.destroym = function ( memId ) {			return me.storem ( , memId, -1 );		}		this.clearm = function  {			var data = document.cookie;			data = data.split ( ';' );			for ( i in data ) {				if ( typeof data[i] !== 'string' ) continue;				if ( data[i].substr ( 0, 1 ) == ' ' ) data[i] = data[i].substr ( 1 );				if ( data[i].indexOf ( 'catMan_' ) === 0 ) {					me.destroym ( data[i].substr ( 0, data[i].indexOf ( '=' ) ) );				}			}			return true;		}	}	importScript ( 'User:Ale_jrb/Scripts/waLib.js' );	importScript ( 'User:Ale_jrb/Scripts/waLib2.js' );	var catMan = new catManMain ;	hookEvent ( 'load', catMan.init );