User:Poke/GuildWarsWikiTools.js

From Guild Wars Wiki
Jump to navigationJump to search

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
 /*<nowiki>*/
  /** Fetch mediawiki variables **/
  var conf = mw.config.get([
   'wgServer',
   'wgPageName',
   'wgTitle',
   'wgNamespaceNumber',
   'wgCanonicalNamespace',
   'wgCanonicalSpecialPageName',
   'wgCurRevisionId'
  ]);

 /**** class PortletArea.js
  * (c) 2007 by Patrick Westerhoff [poke]
  */
 
 function PortletArea ( id, title, nextNode )
 {
   var areaNode;
   var bodyNode;
   
   if ( document.getElementById( id ) == null )
     addArea( id, title, nextNode );
   else
   {
     areaNode = document.getElementById( id );
     bodyNode = getLastElement( areaNode, 'className', 'pBody' );
   }
   
   /** private getLastElement ( parentNode [, attrName, attrValue ] ) :: gets last element node **/
   function getLastElement ( parentNode, attrName, attrValue )
   {
     if ( !parentNode.hasChildNodes() )
       return false;
     
     var node = parentNode.lastChild;
     
     do
     {
       if ( node.nodeType == 1 && ( attrName == null || node[attrName] == attrValue ) )
         return node;
     }
     while ( ( node = node.previousSibling ) );
     
     return false;
   }
   
   /** private addArea ( id, title, before ) :: adds new portlet area (constructor) **/
   function addArea ( id, title, nextNode )
   {
     areaNode           = document.createElement( 'div' );
     areaNode.id        = id;
     areaNode.className = 'portlet';
     
     bodyNode           = document.createElement( 'div' );
     bodyNode.className = 'pBody';
     
     areaNode.appendChild( document.createElement( 'h3' ) );
     areaNode.appendChild( bodyNode );
     areaNode.firstChild.appendChild( document.createTextNode( title ) );
     
     var rootNode = document.getElementById( 'column-one' );
     
     if ( nextNode && nextNode.parentNode == rootNode )
       rootNode.insertBefore( areaNode, nextNode );
     else
       rootNode.appendChild( areaNode );
   }
   
   /** public getArea () :: get PortletArea reference **/
   this.getArea = function ()
   {
     return areaNode;
   }
   
   /** public addText ( text ) :: adds new text element **/
   this.addText = function ( text )
   {
     bodyNode.appendChild( document.createElement( 'p' ) );
     bodyNode.lastChild.appendChild( document.createTextNode( text ) );
     
     return bodyNode.lastChild;
   }
   
   /** public addList () :: adds new list element **/
   this.addList = function ()
   {
     bodyNode.appendChild( document.createElement( 'ul' ) );
     
     return bodyNode.lastChild;
   }
   
   /** public addItem ( [ id ], title [, href, tooltip, listNode, nextNode ] ) :: adds new list item **/
   this.addItem = function ( id, title, href, tooltip, listNode, nextNode )
   {
     var parNode;
     var itemNode;
     
     if ( listNode && listNode.parentNode == bodyNode )
       parNode = listNode;
     else if ( nextNode && nextNode.parentNode.parentNode == bodyNode )
       parNode = nextNode.parentNode;
     else if ( ( parNode = getLastElement( bodyNode ) ) && parNode.nodeName.toLowerCase() == 'ul' )
     { }
     else
       parNode = this.addList();
     
     itemNode    = document.createElement( 'li' );
     
     if ( id )
       itemNode.id = id;
     
     if ( href )
     {
       itemNode.appendChild( document.createElement( 'a' ) );
       itemNode.lastChild.href  = href;
       itemNode.lastChild.title = ( tooltip ) ? tooltip : title;
       itemNode.lastChild.appendChild( document.createTextNode( title ) );
     }
     else
     {
       itemNode.appendChild( document.createTextNode( title ) );
     }
     
     if ( nextNode && nextNode.parentNode == parNode )
       parNode.insertBefore( itemNode, nextNode );
     else
       parNode.appendChild( itemNode );
     
     return itemNode;
   }
 }
 
 /**** class GuildWarsWikiTools.js
  * (c) 2007-2008 by Patrick Westerhoff [poke]
  */
 
 function GuildWarsWikiTools ( thisObjectName )
 {
   var gwwtVers   = '1.1.5a';
   var gwwtHome   = 'User:Poke/GuildWarsWikiTools';
   var portletPos = ( typeof( gwwtPortletPos ) == 'string' ) ? document.getElementById( gwwtPortletPos ) : document.getElementById( 'p-search' ).nextSibling;
   var portlet    = new PortletArea( 'p-gwwt', 'Guild Wars Wiki Tools', portletPos );
   var portTop    = new PortletArea( 'p-cactions' );
   var portTool   = new PortletArea( 'p-tb' );
   var actions    = new Array();
   
   // configuration
   var nsSortTbl  = new Object( {
     'Main':            0, 'Main talk':            1,
     'Guild Wars Wiki': 2, 'Guild Wars Wiki talk': 3,
     'User':            4, 'User talk':            5,
     'Feedback':        6, 'Feedback talk':        7,
     'Guild':           8, 'Guild talk':           9,
     'ArenaNet':       10, 'ArenaNet talk':       11,
     'Help':           12, 'Help talk':           13,
     'File':           14, 'File talk':           15,
     'Template':       16, 'Template talk':       17,
     'Category':       18, 'Category talk':       19,
     'Game link':      20, 'Game link talk':      21,
     'MediaWiki':      22, 'MediaWiki talk':      23,
     'Special':        24 } );
  
   /* create Guild Wars Wiki Tools info box */
   var gwwtInfoBox     = document.createElement( 'div' );
   var gwwtInfoDiv     = document.createElement( 'div' );
   var gwwtInfoContent = document.createElement( 'div' );
   
   gwwtInfoBox.id            = 'gwwtInfoBox';
   gwwtInfoBox.style.display = 'none';
   gwwtInfoBox.appendChild( gwwtInfoDiv );
   
   gwwtInfoDiv.id = 'gwwtInfo';
   gwwtInfoDiv.appendChild( document.createElement( 'h1' ) );
   gwwtInfoDiv.lastChild.appendChild( document.createTextNode( 'Guild Wars Wiki Tools' ) );
   gwwtInfoDiv.appendChild( gwwtInfoContent );
   
   /* gwwtButton */
   gwwtInfoDiv.appendChild( document.createElement( 'div' ) );
   gwwtInfoDiv.lastChild.id = 'gwwtButton';
   gwwtInfoDiv.lastChild.appendChild( document.createTextNode( 'tag & save' ) );
   gwwtInfoDiv.lastChild.onclick = performActions;
   
   /* gwwtFoot */
   gwwtInfoDiv.appendChild( document.createElement( 'div' ) );
   gwwtInfoDiv.lastChild.id = 'gwwtFoot';
   gwwtInfoDiv.lastChild.appendChild( document.createElement( 'span' ) );
   gwwtInfoDiv.lastChild.lastChild.appendChild( document.createTextNode( 'v' + gwwtVers + ' © 2007 by ' ) );
   gwwtInfoDiv.lastChild.lastChild.appendChild( document.createElement( 'a' ) );
   gwwtInfoDiv.lastChild.lastChild.lastChild.href = 'http://wiki.guildwars.com/wiki/' + gwwtHome;
   gwwtInfoDiv.lastChild.lastChild.lastChild.appendChild( document.createTextNode( 'poke' ) );
   gwwtInfoDiv.lastChild.appendChild( document.createElement( 'a' ) );
   gwwtInfoDiv.lastChild.lastChild.href = 'javascript:' + thisObjectName + '.resetActions()';
   gwwtInfoDiv.lastChild.lastChild.appendChild( document.createTextNode( 'abort' ) );
   
   document.getElementsByTagName( 'body' )[0].appendChild( gwwtInfoBox );
   
   /** private namespaceSorting ( a, b ) :: compares namespaces **/
   function namespaceSorting ( a, b )
   {
     if ( nsSortTbl[a] == null && nsSortTbl[b] == null )
       return 0;
     
     if ( nsSortTbl[a] == null )
       return +1;
     
     if ( nsSortTbl[b] == null )
       return -1;
     
     return nsSortTbl[a] - nsSortTbl[b];
   }
   
   /** private radioListInitialize ( node, values, name, value, actionObject ) :: inserts a new radio button list **/
   function radioListInitialize ( node, values, name, value, actionObject )
   { 
     node.appendChild( document.createElement( 'ul' ) );
     
     for ( var each in values )
     {
       var input     = document.createElement( 'input' );
       input.type    = 'radio';
       input.name    = name;
       input.value   = each;
       input.onclick = function ()
       {
         var inputs = document.getElementsByTagName( 'input' );
         
         for ( var i = 0; i < inputs.length; i++ )
         {
           if ( inputs[i].type == 'radio' && inputs[i].name == this.name )
           {
             inputs[i].checked = ( inputs[i] == this ) ? true : false;
             inputs[i].parentNode.className = inputs[i].checked ? 'checked' : '';
           }
         }
       }
       
       node.lastChild.appendChild( document.createElement( 'li' ) );
       node.lastChild.lastChild.appendChild( input );
       node.lastChild.lastChild.appendChild( document.createTextNode( values[each] ) );
       node.lastChild.lastChild.onclick = function ()
       {
         this.firstChild.onclick();
       }
       
       if ( value != null && each == value )
       {
         node.lastChild.lastChild.firstChild.checked = true;
         node.lastChild.lastChild.className          = 'checked';
         actionObject.activated                      = node.lastChild.lastChild.firstChild;
       }
     }
   }
   
   /** private jsFunc ( param1, param2 ) :: creates javascript: function call **/
   function jsFunc ( param1, param2 )
   {
     return "javascript:" + thisObjectName + ".addAction('" + param1 + ( param2 == null ? '' : "', '" + param2 ) + "')";
   }
   
   /** private performActions () :: gets all actions and redirects to edit page **/
   function performActions ()
   {
     if ( actions.length < 1 )
       return;
     
     var errors  = false;
     var query   = new Array();
     var editUrl = conf.wgServer + '/index.php?title=' + conf.wgPageName.replace( /\+/, '%2B' ).replace( /&/, '%26' ) + '&action=edit&gwwt=';
     
     for ( var i = 0; i < actions.length; i++ )
     {
       if ( actions[i] == null )
         continue;
       
       if ( actions[i].setOpt() == false )
       {
         actions[i].div.style.borderColor           = '#CC3300';
         actions[i].div.previousSibling.style.color = '#CC3300';
         
         errors = true;
       }
       else
       {
         actions[i].div.style.borderColor           = '';
         actions[i].div.previousSibling.style.color = '';
       }
       
       if ( errors == true )
         continue;
       
       for ( var j = 0; j < actions[i].opt.length; j++ )
       {
         if ( actions[i].opt[j] == null )
           break;
         
         query.push( actions[i].opt[j] + '~' );
       }
       query.push( '~' );
     }
     
     if ( errors == true )
       return;
     
     editUrl += encodeURIComponent( query.join( '' ) );
     
     while ( editUrl.lastIndexOf( '~' ) == editUrl.length -1 )
     {
       editUrl = editUrl.slice( 0, -1 );
     }
     
     window.location = editUrl;
   }
   
   /** private handlePageEdit () : handles edit page **/
   function handlePageEdit ()
   {
     if ( window.location.href.indexOf( 'action=edit' ) < 0 || window.location.href.indexOf( 'gwwt=' ) < 0 )
       return;
     
     var txtTextbox  = document.getElementById( 'wpTextbox1' );
     var txtSummary  = document.getElementById( 'wpSummary' );
     var minorEdit   = true;
     var gwwtOptions = window.location.href;
     var option;
     
     // evil back button
     if ( txtSummary.value.indexOf( '|GWWT]]' ) > -1 )
     	return;
     
     gwwtOptions = decodeURIComponent( gwwtOptions.match( /gwwt=(.+)&?/ )[1] );
     gwwtOptions = gwwtOptions.split( '~~' );
     
     while ( ( option = gwwtOptions.pop() ) )
     {
       option = option.split( '~' );
       
       switch ( option[0].toLowerCase() )
       {
         case 'del':
           if ( option[1] == null || option[1] == '' )
           {
             txtTextbox.value = '<noinclude>{{delete}}</noinclude>\n' + txtTextbox.value;
             txtSummary.value = '+delete' + ( txtSummary.value != '' ? ' | ' + txtSummary.value : '' );
           }
           else
           {
             txtTextbox.value = '<noinclude>{{delete|' + option[1] + '}}</noinclude>\n' + txtTextbox.value;
             txtSummary.value = '+delete (' + ( option[2] != null ? option[2] : option[1] ) + ')' + ( txtSummary.value != '' ? ' | ' + txtSummary.value : '' );
           }
           minorEdit = false;
         break;
         
         case 'del.copyvio':
           if ( option[1] == null || option[1] == '' )
             continue;
           
           txtTextbox.value = '<noinclude>{{copyvio|' + option[1] + '}}</noinclude>\n' + txtTextbox.value;
           txtSummary.value = '+delete (copyviolation)' + ( txtSummary.value != '' ? ' | ' + txtSummary.value : '' );
           minorEdit        = false;
         break;
         
         case 'del.speedy':
           var values   = new Object();
           values['G1'] = '[[GWW:DP#Speedy deletion|speedy deletion]] G1: Purely Vandalism';
           values['G2'] = '[[GWW:DP#Speedy deletion|speedy deletion]] G2: Test page';
           values['G3'] = '[[GWW:DP#Speedy deletion|speedy deletion]] G3: Editor\'s request';
           values['G4'] = '[[GWW:DP#Speedy deletion|speedy deletion]] G4: Housekeeping';
           values['G5'] = '[[GWW:DP#Speedy deletion|speedy deletion]] G5: Attack page';
           values['G6'] = '[[GWW:DP#Speedy deletion|speedy deletion]] G6: Recreation of deleted page';
           values['G7'] = '[[GWW:DP#Speedy deletion|speedy deletion]] G7: Decision or conditional enforcement by arbitration committee';
           values['A1'] = '[[GWW:DP#Speedy deletion|speedy deletion]] A1: No appropriate information';
           values['A2'] = '[[GWW:DP#Speedy deletion|speedy deletion]] A2: Missing of verifiable source for the information';
           values['R1'] = '[[GWW:DP#Speedy deletion|speedy deletion]] R1: Redirect to User/Guild/Talk namespace'
           values['R2'] = '[[GWW:DP#Speedy deletion|speedy deletion]] R2: Unnecessary redirect';
           values['R3'] = '[[GWW:DP#Speedy deletion|speedy deletion]] R3: Misleading redirect';
           values['R4'] = '[[GWW:DP#Speedy deletion|speedy deletion]] R4: Broken redirect';
           values['R5'] = '[[GWW:DP#Speedy deletion|speedy deletion]] R5: Redirect at move destination';
           values['I1'] = '[[GWW:DP#Speedy deletion|speedy deletion]] I1: Redundant image';
           values['I2'] = '[[GWW:DP#Speedy deletion|speedy deletion]] I2: Corrupt or unviewable image';
           values['C1'] = '[[GWW:DP#Speedy deletion|speedy deletion]] C1: Empty or unused category';
           values['U1'] = '[[GWW:DP#Speedy deletion|speedy deletion]] U1: User request';
           values['U2'] = '[[GWW:DP#Speedy deletion|speedy deletion]] U2: Unregistered user';
           values['U3'] = '[[GWW:DP#Speedy deletion|speedy deletion]] U3: Image that violates userspace policy';
           
           if ( option[1] == null || values[ option[1].toUpperCase() ] == null )
             continue;
           
           option[1] = option[1].toUpperCase();
           
           txtTextbox.value = '<noinclude>{{delete|' + values[ option[1] ] + '|speedy}}</noinclude>\n' + txtTextbox.value;
           txtSummary.value = '+delete (speedy ' + option[1] + ')' + ( txtSummary.value != '' ? ' | ' + txtSummary.value : '' );
           minorEdit        = false;
         break;
         
         case 'move':
           if ( option[1] == null || option[1] == '' )
             continue;
           
           if ( option[2] == null || option[2] == '' )
           {
             txtTextbox.value = '<noinclude>{{move|' + option[1] + '}}</noinclude>\n' + txtTextbox.value;
             txtSummary.value = '+move' + ( txtSummary.value != '' ? ' | ' + txtSummary.value : '' );
           }
           else
           {
             txtTextbox.value = '<noinclude>{{move|' + option[1] + '|' + option[2] + '}}</noinclude>\n' + txtTextbox.value;
             txtSummary.value = '+move (' + ( option[3] != null ? option[3] : option[2] ) + ')' + ( txtSummary.value != '' ? ' | ' + txtSummary.value : '' );
           }
           minorEdit = false;
         break;
         
         case 'stub':
           var values                   = new Object();
           values['-']                  = 'Stub';
           values['armor']              = 'Armor-stub';
           values['bounty']             = 'Bounty-stub';
           values['guild']              = 'Guild-stub';
           values['interactive-object'] = 'Interactive-object-stub';
           values['item']               = 'Item-stub';
           values['location']           = 'Location-stub';
           values['mission']            = 'Mission-stub';
           values['npc']                = 'Npc-stub';
           values['profession']         = 'Profession-stub';
           values['pve']                = 'Pve-stub';
           values['pvp']                = 'Pvp-stub';
           values['quest']              = 'Quest-stub';
           values['region']             = 'Region-stub';
           //values['section']          = 'Section-stub'; // disabled
           values['skill']              = 'Skill-stub';
           values['term']               = 'Term-stub';
           values['title']              = 'Title-stub';
           values['weapon']             = 'Weapon-stub';
           
           if ( option[1] == null || values[ option[1].toLowerCase() ] == null )
             continue;
           
           option[1] = option[1].toLowerCase();
           
           txtTextbox.value = '{{' + values[ option[1] ] + '}}\n' + txtTextbox.value;
           txtSummary.value = '+' + values[ option[1] ].replace( /-/g, ' ' ).toLowerCase() + ( txtSummary.value != '' ? ' | ' + txtSummary.value : '' );
         break;
         
         case 'cleanup':
           txtTextbox.value = '{{cleanup}}\n' + txtTextbox.value;
           txtSummary.value = '+cleanup' + ( txtSummary.value != '' ? ' | ' + txtSummary.value : '' );
         break;
         
         case 'guild.cleanup':
           if ( option[1] == null || option[1] == '' )
           {
             txtTextbox.value = '{{guild cleanup|~~~~~}}<!-- remove this line, if the guild cleanup is done -->\n' + txtTextbox.value;
             txtSummary.value = '+guild cleanup' + ( txtSummary.value != '' ? ' | ' + txtSummary.value : '' );
           }
           else
           {
             txtTextbox.value = '{{guild cleanup|~~~~~|' + option[1] + '}}\n' + txtTextbox.value;
             txtSummary.value = '+guild cleanup (' + ( option[2] != null ? option[2] : option[1] ) + ')' + ( txtSummary.value != '' ? ' | ' + txtSummary.value : '' );
           }
         break;
         
         case 'guild.inactive':
           txtTextbox.value = '{{inactive guild|~~~~~}}<!-- remove this line, if the guild is still active -->\n' + txtTextbox.value;
           txtSummary.value = '+inactive guild' + ( txtSummary.value != '' ? ' | ' + txtSummary.value : '' );
           minorEdit        = false;
         break;
         
         case 'del.img':
           if ( option[1] == null || option[1] == '' )
             continue;
           
           switch ( option[1].toLowerCase() )
           {
             case 'orphaned':
               txtTextbox.value = '{{delete|orphaned (unused) image.}}\n' + txtTextbox.value;
               txtSummary.value = '+delete (orphaned image)' + ( txtSummary.value != '' ? ' | ' + txtSummary.value : '' );
             break;
             
             case 'usernaming':
               txtTextbox.value = '{{delete|user image naming, see [[Guild Wars Wiki:Image use#User page images|image use policy]]}}\n' + txtTextbox.value;
               txtSummary.value = '+delete (user image naming)' + ( txtSummary.value != '' ? ' | ' + txtSummary.value : '' );
             break;
             
             case 'guildnaming':
               txtTextbox.value = '{{delete|guild image naming, see [[Guild Wars Wiki:Image use#Guild images|image use policy]].}}\n' + txtTextbox.value;
               txtSummary.value = '+delete (guild image naming)' + ( txtSummary.value != '' ? ' | ' + txtSummary.value : '' );
             break;
             
             default:
               continue;
           }
           minorEdit = false;
         break;
         
         case 'tag':
           if ( option[1] == null || option[1] == '')
             continue;
           
           switch ( option[1].toLowerCase() )
           {
             case 'guild':
               txtTextbox.value = '{{Guild}}\n' + txtTextbox.value;
               txtSummary.value = '+guild' + ( txtSummary.value != '' ? ' | ' + txtSummary.value : '' );
             break;
             
             case 'imguser':
               txtTextbox.value = '{{User image}}\n' + txtTextbox.value;
               txtSummary.value = '+user image' + ( txtSummary.value != '' ? ' | ' + txtSummary.value : '' );
             break;
             
             case 'imgguild':
               txtTextbox.value = '{{Guild image}}\n' + txtTextbox.value;
               txtSummary.value = '+guild image' + ( txtSummary.value != '' ? ' | ' + txtSummary.value : '' );
             break;
             
             case 'imganet':
               txtTextbox.value = '{{ArenaNet image}}\n' + txtTextbox.value;
               txtSummary.value = '+arenanet image' + ( txtSummary.value != '' ? ' | ' + txtSummary.value : '' );
             break;
             
             case 'imgscreen':
               txtTextbox.value = '{{Screenshot}}\n' + txtTextbox.value;
               txtSummary.value = '+screenshot' + ( txtSummary.value != '' ? ' | ' + txtSummary.value : '' );
             break;
             
             case 'imgfsk':
               txtTextbox.value = '{{Fansite kit image}}\n' + txtTextbox.value;
               txtSummary.value = '+fansite kit image' + ( txtSummary.value != '' ? ' | ' + txtSummary.value : '' );
             break;
             
             case 'needimg':
               txtTextbox.value = '{{image needed}}\n' + txtTextbox.value;
               txtSummary.value = '+image needed' + ( txtSummary.value != '' ? ' | ' + txtSummary.value : '' );
             break;
             
             case 'needmap':
               txtTextbox.value = '{{image needed|map}}\n' + txtTextbox.value;
               txtSummary.value = '+map needed' + ( txtSummary.value != '' ? ' | ' + txtSummary.value : '' );
             break;
             
             default:
               continue;
           }
         break;
         
         default:
           return;
       }
     }
     
     if ( minorEdit == true )
       document.getElementById( 'wpMinoredit' ).checked = true;
     
     txtSummary.value += ' | [[' + gwwtHome + '|GWWT]]';
     
     // send
     document.getElementById( 'editform' ).submit();
   }
   
   /** public removeAction ( id ) :: removes specific action **/
   this.removeAction = function ( id )
   {
     gwwtInfoContent.removeChild( actions[ id ].div.previousSibling );
     gwwtInfoContent.removeChild( actions[ id ].div );
     
     actions[ id ] = null;
   }
   
   /** pubic resetActions () :: resets all actions and clears info box **/
   this.resetActions = function ()
   {
     gwwtInfoBox.style.display = 'none';
     actions                   = new Array();
     
     while ( gwwtInfoContent.hasChildNodes() )
     {
       gwwtInfoContent.removeChild( gwwtInfoContent.firstChild );
     }
   }
   
   /** public addAction ( id, value ) :: adds new action **/
   this.addAction = function ( id, value )
   {
     gwwtInfoBox.style.display = 'block';
     
     var checked;
     var action   = new Object();
     action.id    = actions.length;
     action.opt   = new Array();
     action.opts  = '';
     action.title = '';
     action.div   = document.createElement( 'div' );
     action.div.className = 'action';
     
     switch ( id )
     {
       case 'del':
         action.title  = 'Deletion';
         action.opt[0] = 'del';
         action.opt[1] = ''; // reason: null, empty
         action.opt[2] = ''; // summary: null, empty
         
         // layout
         action.div.appendChild( document.createTextNode( 'Add deletion request because...' ) );
         action.div.appendChild( document.createElement( 'span' ) );
         action.div.lastChild.style.color = '#AAAAAA';
         action.div.lastChild.appendChild( document.createTextNode( ' (optional)' ) );
         action.div.appendChild( document.createElement( 'input' ) );
         action.div.lastChild.type = 'text';
         action.div.appendChild( document.createElement( 'br' ) );
         action.div.appendChild( document.createTextNode( 'Short reason for edition summary...' ) );
         action.div.appendChild( document.createElement( 'span' ) );
         action.div.lastChild.style.color = '#AAAAAA';
         action.div.lastChild.appendChild( document.createTextNode( ' (optional)' ) );
         action.div.appendChild( document.createElement( 'input' ) );
         action.div.lastChild.type = 'text';
         
         // setOpt
         action.setOpt   = function()
         {
           var inputs  = this.div.getElementsByTagName( 'input' );
           
           this.opt[1] = inputs[0].value != '' ? inputs[0].value : null;
           this.opt[2] = inputs[1].value != '' ? inputs[1].value : null;
           this.opt[2] = this.opt[1] != null   ? this.opt[2]     : null;
           
           return true;
         }
       break;
       
       case 'del.copyvio':
         action.title  = 'Deletion (copyviolation)';
         action.opt[0] = 'del.copyvio';
         action.opt[1] = ''; // url: not null, not empty
         
         // layout
         action.div.appendChild( document.createTextNode( 'Add deletion request because of a potential copyright violation. ' ) );
         action.div.appendChild( document.createTextNode( 'The original source can be found on...' ) );
         action.div.appendChild( document.createElement( 'span' ) );
         action.div.lastChild.style.color = '#AAAAAA';
         action.div.lastChild.appendChild( document.createTextNode( ' (url)' ) );
         action.div.appendChild( document.createElement( 'input' ) );
         action.div.lastChild.type = 'text';
         
         // setOpt
         action.setOpt   = function()
         {
           this.opt[1] = this.div.getElementsByTagName( 'input' )[0].value;
           
           if ( this.opt[1] != '' && this.opt[1].search( /http:\/\/(.+)/ ) != -1 )
             return true;
           else
             return false;
         }
       break;
       
       case 'del.speedy':
         action.title  = 'Speedy Deletion';
         action.opt[0] = 'del.speedy';
         action.opt[1] = ''; // reason: not null; list
         action.vals   = new Object();
         
         action.vals['G1'] = 'G1: Purely Vandalism.';
         action.vals['G2'] = 'G2: Test page';
         action.vals['G3'] = 'G3: Editor\'s request.';
         action.vals['G4'] = 'G4: Housekeeping.';
         action.vals['G5'] = 'G5: Attack page.';
         action.vals['G6'] = 'G6: Recreation of deleted page.';
         action.vals['G7'] = 'G7: Decision or conditional enforcement by arbitration committee. ';
         action.vals['A1'] = 'A1: No appropriate information.';
         action.vals['A2'] = 'A2: Missing of verifiable source for the information.';
         action.vals['R1'] = 'R1: Redirect to User/Guild/Talk namespace.'
         action.vals['R2'] = 'R2: Unnecessary redirect.';
         action.vals['R3'] = 'R3: Misleading redirect.';
         action.vals['R4'] = 'R4: Broken redirect.';
         action.vals['R5'] = 'R5: Redirect at move destination.';
         action.vals['I1'] = 'I1: Redundant image.';
         action.vals['I2'] = 'I2: Corrupt or unviewable image.';
         action.vals['C1'] = 'C1: Empty or unused category.';
         action.vals['U1'] = 'U1: User request.';
         action.vals['U2'] = 'U2: Unregistered user.';
         action.vals['U3'] = 'U3: Image that violates userspace policy.';
         
         // layout
         action.div.appendChild( document.createTextNode( 'Add speedy deletion request because...' ) );
         radioListInitialize( action.div, action.vals, 'gwwt-' + action.id, value, action );
         
         // setOpt
         action.setOpt   = function()
         {
           var inputs  = this.div.getElementsByTagName( 'input' );
           
           for ( var i = 0; i < inputs.length; i++ )
           {
             if ( inputs[i].name == 'gwwt-' + this.id && inputs[i].checked == true )
             {
               this.opt[1] = inputs[i].value;
               
               if ( this.vals[ this.opt[1] ] != null )
                 return true;
               else
                 return false;
             }
           }
           return false;
         }
       break;
       
       case 'move':
         action.title  = 'Move';
         action.opt[0] = 'move';
         action.opt[1] = ''; // target: not null, not empty
         action.opt[2] = ''; // reason: null, empty
         action.opt[3] = ''; // summary: null, empty
         
         // layout
         action.div.appendChild( document.createTextNode( 'Suggest moving this page to...' ) );
         action.div.appendChild( document.createElement( 'span' ) );
         action.div.lastChild.style.color = '#AAAAAA';
         action.div.lastChild.appendChild( document.createTextNode( ' (wiki path needed)' ) );
         action.div.appendChild( document.createElement( 'input' ) );
         action.div.lastChild.type = 'text';
         action.div.appendChild( document.createElement( 'br' ) );
         action.div.appendChild( document.createTextNode( 'Give reason for moving...' ) );
         action.div.appendChild( document.createElement( 'span' ) );
         action.div.lastChild.style.color = '#AAAAAA';
         action.div.lastChild.appendChild( document.createTextNode( ' (optional)' ) );
         action.div.appendChild( document.createElement( 'input' ) );
         action.div.lastChild.type = 'text';
         action.div.appendChild( document.createElement( 'br' ) );
         action.div.appendChild( document.createTextNode( 'Short reason for edition summary...' ) );
         action.div.appendChild( document.createElement( 'span' ) );
         action.div.lastChild.style.color = '#AAAAAA';
         action.div.lastChild.appendChild( document.createTextNode( ' (optional)' ) );
         action.div.appendChild( document.createElement( 'input' ) );
         action.div.lastChild.type = 'text';
         
         // setOpt
         action.setOpt   = function()
         {
           var inputs  = this.div.getElementsByTagName( 'input' );
           
           this.opt[1] = inputs[0].value != '' ? inputs[0].value : null;
           
           if ( this.opt[1] != null )
           {
             this.opt[2] = inputs[1].value != '' ? inputs[1].value : null;
             this.opt[3] = inputs[2].value != '' ? inputs[2].value : null;
             this.opt[3] = this.opt[2] != null   ? this.opt[3]     : null;
             
             return true;
           }
           
           return false;
         }
       break;
       
       case 'stub':
         action.title  = 'Stub';
         action.opt[0] = 'stub';
         action.opt[1] = ''; // type: not null; list
         action.vals   = new Object();
         
         action.vals['-']                  = 'Stub';
         action.vals['armor']              = 'Armor-stub';
         action.vals['bounty']             = 'Bounty-stub';
         action.vals['guild']              = 'Guild-stub';
         action.vals['interactive-object'] = 'Interactive-object-stub';
         action.vals['item']               = 'Item-stub';
         action.vals['location']           = 'Location-stub';
         action.vals['mission']            = 'Mission-stub';
         action.vals['npc']                = 'Npc-stub';
         action.vals['profession']         = 'Profession-stub';
         action.vals['pve']                = 'Pve-stub';
         action.vals['pvp']                = 'Pvp-stub';
         action.vals['quest']              = 'Quest-stub';
         action.vals['region']             = 'Region-stub';
         //action.vals['section']          = 'Section-stub'; // disabled
         action.vals['skill']              = 'Skill-stub';
         action.vals['term']               = 'Term-stub';
         action.vals['title']              = 'Title-stub';
         action.vals['weapon']             = 'Weapon-stub';
         
         // layout
         action.div.appendChild( document.createTextNode( 'Tag this page as a stub. Choose stub type...' ) );
         radioListInitialize( action.div, action.vals, 'gwwt-' + action.id, value, action );
         
         // setOpt
         action.setOpt   = function()
         {
           var inputs  = this.div.getElementsByTagName( 'input' );
           
           for ( var i = 0; i < inputs.length; i++ )
           {
             if ( inputs[i].name == 'gwwt-' + this.id && inputs[i].checked == true )
             {
               this.opt[1] = inputs[i].value;
               
               if ( this.vals[ this.opt[1] ] != null )
                 return true;
               else
                 return false;
             }
           }
           return false;
         }
       break;
       
       case 'cleanup':
         action.title  = 'Cleanup';
         action.opt[0] = 'cleanup';
         
         // layout
         action.div.appendChild( document.createTextNode( 'Tag this page for cleanup.' ) );
         
         // setOpt
         action.setOpt = function()
         {
           return true;
         }
       break;
       
       case 'guild.cleanup':
         action.title  = 'Guild Cleanup';
         action.opt[0] = 'guild.cleanup';
         action.opt[1] = ''; // reason: null, empty
         action.opt[2] = ''; // summary: null, empty
         
         // layout
         action.div.appendChild( document.createTextNode( 'Tag this guild page for cleanup because...' ) );
         action.div.appendChild( document.createElement( 'span' ) );
         action.div.lastChild.style.color = '#AAAAAA';
         action.div.lastChild.appendChild( document.createTextNode( ' (optional)' ) );
         action.div.appendChild( document.createElement( 'input' ) );
         action.div.lastChild.type = 'text';
         action.div.appendChild( document.createElement( 'br' ) );
         action.div.appendChild( document.createTextNode( 'Short reason for edition summary...' ) );
         action.div.appendChild( document.createElement( 'span' ) );
         action.div.lastChild.style.color = '#AAAAAA';
         action.div.lastChild.appendChild( document.createTextNode( ' (optional)' ) );
         action.div.appendChild( document.createElement( 'input' ) );
         action.div.lastChild.type = 'text';
         
         // setOpt
         action.setOpt   = function()
         {
           var inputs  = this.div.getElementsByTagName( 'input' );
           
           this.opt[1] = inputs[0].value != '' ? inputs[0].value : null;
           this.opt[2] = inputs[1].value != '' ? inputs[1].value : null;
           this.opt[2] = this.opt[1] != null   ? this.opt[2]     : null;
           
           return true;
         }
       break;
       
       case 'guild.inactive':
         action.title  = 'Inactive guild';
         action.opt[0] = 'guild.inactive';
         
         // layout
         action.div.appendChild( document.createTextNode( 'Tag this guild page as inactive (please check the activity status before)' ) );
         
         // setOpt
         action.setOpt   = function()
         {
           return true;
         }
       break;
       
       case 'del.img':
         action.title  = 'Image Deletion';
         action.opt[0] = 'del.img';
         action.opt[1] = ''; // reason type: not null, list
         action.vals   = new Object();
         
         action.vals['orphaned']    = 'Orphaned (unused) image';
         action.vals['usernaming']  = 'User Image Naming (User page policy)';
         action.vals['guildnaming'] = 'Guild Image Naming (Guild page policy)';
         
         // layout
         action.div.appendChild( document.createTextNode( 'Add a image deletion request because...' ) );
         radioListInitialize( action.div, action.vals, 'gwwt-' + action.id, value, action );
         
         // setOpt
         action.setOpt   = function()
         {
           var inputs  = this.div.getElementsByTagName( 'input' );
           
           for ( var i = 0; i < inputs.length; i++ )
           {
             if ( inputs[i].name == 'gwwt-' + this.id && inputs[i].checked == true )
             {
               this.opt[1] = inputs[i].value;
               
               if ( this.vals[ this.opt[1] ] != null )
                 return true;
               else
                 return false;
             }
           }
           return false;
         }
       break;
       
       case 'tag':
         action.title  = 'Tagging';
         action.opt[0] = 'tag';
         action.opt[1] = ''; // tag type: not null, list
         action.vals   = new Object();
         
         if ( conf.wgNamespaceNumber == 100 ) // namespace: Guild
           action.vals['guild']        = 'Guild Tag';
         
         if ( conf.wgNamespaceNumber == 6 ) // namespace: File
         {
           action.vals['imguser']      = 'User Image Tag';
           action.vals['imgguild']     = 'Guild Image Tag';
           action.vals['imganet']      = 'ArenaNet Image Tag';
           action.vals['imgscreen']    = 'Screenshot Image Tag';
           action.vals['imgfsk']       = 'Fansite Kit Image Tag';
         }
         
         action.vals['needimg']      = 'Image needed Tag';
         action.vals['needmap']      = 'Map needed Tag';
         
         // layout
         action.div.appendChild( document.createTextNode( 'Tag this page with...' ) );
         radioListInitialize( action.div, action.vals, 'gwwt-' + action.id, value, action );
         
         // setOpt
         action.setOpt   = function()
         {
           var inputs  = this.div.getElementsByTagName( 'input' );
           
           for ( var i = 0; i < inputs.length; i++ )
           {
             if ( inputs[i].name == 'gwwt-' + this.id && inputs[i].checked == true )
             {
               this.opt[1] = inputs[i].value;
               
               if ( this.vals[ this.opt[1] ] != null )
                 return true;
               else
                 return false;
             }
           }
           return false;
         }
       break;
       
       default:
         return;
     }
     
     actions[ action.id ] = action;
     
     gwwtInfoContent.appendChild( document.createElement( 'h2' ) );
     gwwtInfoContent.lastChild.appendChild( document.createElement( 'a' ) );
     gwwtInfoContent.lastChild.lastChild.href = 'javascript:' + thisObjectName + '.removeAction(' + action.id + ')';
     gwwtInfoContent.lastChild.lastChild.appendChild( document.createTextNode( '[x]' ) );
     gwwtInfoContent.lastChild.appendChild( document.createTextNode( action.title ) );
     
     gwwtInfoContent.appendChild( action.div );
     
     if ( action.activated != null )
       action.activated.checked = true;
   }
   
   /** public initialize () :: initializes Guild Wars Wiki Tools **/
   this.initialize = function()
   {
     var isTalk        = ( conf.wgCanonicalNamespace.match( /talk/i ) == null ) ? false : true;
     var pageRootName  = conf.wgTitle.substring( 0, ( ( conf.wgTitle.indexOf( '/' ) > 0 ) ? conf.wgTitle.indexOf( '/' ) : conf.wgTitle.length ) );
     
     if ( conf.wgNamespaceNumber == -1 ) // Special namespace
     {
       portlet.addText( 'unsupported' );
       
       switch ( conf.wgCanonicalSpecialPageName )
       {
         case 'Log':
           switch ( document.getElementsByTagName( 'h1' )[0].firstChild.nodeValue )
           {
             case 'Upload log':
               portTop.addItem( 'gwwt-special.recentchanges', 'Recent changes', '/wiki/Special:Recentchanges', 'Show recent changes' );
               portTop.addItem( 'gwwt-special.logdelete',     'Deletion log',   '/wiki/Special:Log/delete',    'Show deletion log' );
               portTop.addItem( 'gwwt-special.logmove',       'Move log',       '/wiki/Special:Log/move',      'Show move log' );
             break;
             
             case 'Deletion log':
               portTop.addItem( 'gwwt-special.recentchanges', 'Recent changes', '/wiki/Special:Recentchanges', 'Show recent changes' );
               portTop.addItem( 'gwwt-special.logupload',     'Upload log',     '/wiki/Special:Log/upload',    'Show upload log' );
               portTop.addItem( 'gwwt-special.logmove',       'Move log',       '/wiki/Special:Log/move',      'Show move log' );
             break;
             
             case 'Move log':
               portTop.addItem( 'gwwt-special.recentchanges', 'Recent changes', '/wiki/Special:Recentchanges', 'Show recent changes' );
               portTop.addItem( 'gwwt-special.logupload',     'Upload log',     '/wiki/Special:Log/upload',    'Show upload log' );
               portTop.addItem( 'gwwt-special.logdelete',     'Deletion log',   '/wiki/Special:Log/delete',    'Show deletion log' );
             break;
             
             default:
               portTop.addItem( 'gwwt-special.recentchanges', 'Recent changes', '/wiki/Special:Recentchanges', 'Show recent changes' );
               portTop.addItem( 'gwwt-special.logupload',     'Upload log',     '/wiki/Special:Log/upload',    'Show upload log' );
               portTop.addItem( 'gwwt-special.logdelete',     'Deletion log',   '/wiki/Special:Log/delete',    'Show deletion log' );
               portTop.addItem( 'gwwt-special.logmove',       'Move log',       '/wiki/Special:Log/move',      'Show move log' );
             break;
           }
         break;
         
         case 'Watchlist':
           if ( typeof( gwwtWatchlist ) == 'undefined' || gwwtWatchlist == false )
             break;
           
           var dayLists = document.getElementById( 'bodyContent' ).getElementsByTagName( 'h4' );
           var dayList;
           
           for ( var i = 0; i < dayLists.length; i++ )
           {
             dayList = dayLists[i].nextSibling;
             
             while ( dayList.nodeType != 1 || dayList.nodeName.toLowerCase() != 'ul' )
               dayList  = dayList.nextSibling;
             
             var dayItems = dayList.getElementsByTagName( 'li' );
             var dayDiv   = document.createElement( 'div' );
             var nsItems  = new Object();
             var nsNames  = new Array();
             var nsName;
             
             for ( var j = 0; j < dayItems.length; j++ )
             {
               nsName = dayItems[j].getElementsByTagName( 'a' )[0].title;
               nsName = nsName.match( /(([^:]+):)?(.+)/ )[2];
               nsName = ( nsName == undefined ) ? 'Main' : nsName;
               nsName = ( nsName == 'Talk' ) ? 'Main talk' : nsName;
               nsName = ( nsSortTbl[nsName] == undefined ) ? 'Main' : nsName; 
               
               if ( nsItems[ nsName ] == undefined )
               {
                 nsNames.push( nsName );
                 nsItems[ nsName ] = document.createElement( 'ul' );
                 nsItems[ nsName ].className = 'special';
               }
               
               nsItems[ nsName ].appendChild( dayItems[j].cloneNode( true ) );
             }
             
             nsNames.sort( namespaceSorting );
             
             for ( var j = 0; j < nsNames.length; j++ )
             {
               dayDiv.appendChild( document.createElement( 'h5' ) );
               dayDiv.lastChild.appendChild( document.createTextNode( nsNames[j] ) );
               dayDiv.appendChild( nsItems[ nsNames[j] ] );
             }
             
             dayDiv.style.marginLeft = '15px';
             dayList.parentNode.replaceChild( dayDiv, dayList );
           }
         break;
       }
       
       return;
     }
     
     /* primary :: handle page */
     if ( window.location.href.indexOf( 'gwwt=' ) > 0 )
     {
       var pageAction = window.location.href.match( /action=([^&=]+)/ );
       var pageGWWT   = window.location.href.match( /gwwt=([^&=]+)/ );
       
       switch ( pageAction[1] )
       {
         case 'edit':
           handlePageEdit();
         break;
       }
     }
     
     /* secondary :: show portlet */
     var caHistory = document.getElementById( 'ca-history' );
     if ( caHistory != undefined )
       portTop.addItem( 'gwwt-special.diff', 'diff last', '/index.php?title=' + conf.wgPageName + '&diff=' + conf.wgCurRevisionId,
         'Show differences between last and actual revision', null, caHistory.nextSibling );
     
     if ( conf.wgNamespaceNumber == 2 || conf.wgNamespaceNumber == 3 ) // namespace: User, User talk
     {
       var ca_watch = document.getElementById( 'ca-watch' );
       ca_watch     = ( ca_watch == null ) ? document.getElementById( 'ca-unwatch' ) : ca_watch;
       ca_watch.style.marginRight = '1.6em';
       
       portTop.addItem( 'gwwt-user.page',     'User page', '/wiki/User:' + pageRootName,                         'Show user page of User:' + pageRootName );
       portTop.addItem( 'gwwt-user.talk',     'User talk', '/wiki/User talk:' + pageRootName,                    'Show talk page of User:' + pageRootName );
       portTop.addItem( 'gwwt-user.contribs', 'Contribs',  '/wiki/Special:Contributions/' + pageRootName,        'View the contributions of User:' + pageRootName );
       portTop.addItem( 'gwwt-user.logs',     'Logs',      '/index.php?title=Special:Logs&user=' + pageRootName, 'View the logs of User:' + pageRootName );
       
       portTool.addText( '' );
       portTool.addItem( 'gwwt-user.subpages', 'User\'s pages',      '/index.php?title=Special:Prefixindex&namespace=2&prefix=' + pageRootName,      'Show user pages of User:' + pageRootName );
       portTool.addItem( 'gwwt-user.subtalks', 'User\'s talk pages', '/index.php?title=Special:Prefixindex&namespace=3&prefix=' + pageRootName,      'Show talk pages of User:' + pageRootName );
       portTool.addItem( 'gwwt-user.images',   'User\'s images',     '/index.php?title=Special:Prefixindex&namespace=6&prefix=User+' + pageRootName, 'Show user images of User:' + pageRootName );
     }
     if ( conf.wgNamespaceNumber == 100 || conf.wgNamespaceNumber == 101 ) // namespace: Guild, Guild talk
     {
       portTool.addText( '' );
       portTool.addItem( 'gwwt-guild.subpages', 'Guild\'s subpages',    '/index.php?title=Special:Prefixindex&namespace=100&prefix=' + pageRootName,     'Show user pages of Guild:' + pageRootName );
       portTool.addItem( 'gwwt-guild.subtalks', 'Guild\'s talk pages',  '/index.php?title=Special:Prefixindex&namespace=101&prefix=' + pageRootName,     'Show talk pages of Guild:' + pageRootName );
       portTool.addItem( 'gwwt-guild.images',   'Guild\'s images',      '/index.php?title=Special:Prefixindex&namespace=6&prefix=Guild+' + pageRootName, 'Show guild images of Guild:' + pageRootName );
     }
     if ( conf.wgNamespaceNumber == 100 ) // namespace: Guild
     {
       portTool.addItem( 'gwwt-guild.diffPrel', 'Guild preload changes', '/index.php?diff=' + conf.wgCurRevisionId + '&oldid=1331782', 'Show changes of the current guild page to the guild page preload' );
       portTool.addItem( 'gwwt-guild.diffEG',   'Guild example changes', '/index.php?diff=' + conf.wgCurRevisionId + '&oldid=1267726',  'Show changes of the current guild page to the example guild' );
     }
     
     // check protected status
     if ( document.getElementById( 'ca-viewsource' ) != null )
     {
       portlet.addText( 'protected page' );
       return;
     }
     
     // portlet
     portlet.addItem( 'gwwt-del',           'delete',             jsFunc('del'),           'delete this page' );
     portlet.addItem( 'gwwt-del.speedy',    'delete (speedy)',    jsFunc('del.speedy'),    'speedy delete this page' );
     portlet.addItem( 'gwwt-del.copyvio',   'delete (copyvio)',   jsFunc('del.copyvio'),   'delete this page because copyviolation' );
     portlet.addItem( 'gwwt-move',          'move',               jsFunc('move'),          'move this page' );
     
     portlet.addText( 'cleanup & stub' );
     portlet.addItem( 'gwwt-stub',          'stub',               jsFunc('stub'),          'tag as a stub' );
     portlet.addItem( 'gwwt-cleanup',       'cleanup',            jsFunc('cleanup'),       'tag as a cleanup needed page' );
     
     if ( conf.wgNamespaceNumber == 100 ) // namespace: Guild
     {
       portlet.addItem( 'gwwt-guild.inactive',      'inactive guild',       jsFunc('guild.inactive'),        'tag as a inactive guild' );
       portlet.addItem( 'gwwt-guild.cleanup',       'guild cleanup',        jsFunc('guild.cleanup'),         'tag as a cleanup needed guild page' );
     }
     
     if ( conf.wgNamespaceNumber == 6 ) // namespace: File
     {
       portlet.addText( 'image deletion' );
       portlet.addItem( 'gwwt-del.img-orphaned',    'orphaned',             jsFunc('del.img','orphaned'),    'delete image because it\'s orphaned' );
       portlet.addItem( 'gwwt-del.img-usernaming',  'user image naming',    jsFunc('del.img','usernaming'),  'delete image because of user image naming' );
       portlet.addItem( 'gwwt-del.img-guildnaming', 'guild image naming',   jsFunc('del.img','guildnaming'), 'delete image because of guild image naming' );
     }
     
     portlet.addText( 'tagging' );
     
     if ( conf.wgNamespaceNumber == 100 ) // namespace: Guild
       portlet.addItem( 'gwwt-tag-guild',           'guild tag',            jsFunc('tag','guild'),           'tag this page as a guild page' );
     
     if ( conf.wgNamespaceNumber == 6 ) // namespace: File
     {
       portlet.addItem( 'gwwt-tag-imguser',         'user image tag',       jsFunc('tag','imguser'),         'tag this image as a user image' );
       portlet.addItem( 'gwwt-tag-imgguild',        'guild image tag',      jsFunc('tag','imgguild'),        'tag this image as a guild image' );
       portlet.addItem( 'gwwt-tag-imganet',         'arenanet image tag',   jsFunc('tag','imganet'),         'tag this image as a arenanet image' );
       portlet.addItem( 'gwwt-tag-imgscreen',       'screenshot image tag', jsFunc('tag','imgscreen'),       'tag this image as a screenshot' );
     }
     
     portlet.addItem( 'gwwt-tag-needimg',   'image needed tag',   jsFunc('tag','needimg'), 'tag this page with image needed' );
     portlet.addItem( 'gwwt-tag',           'more...',            jsFunc('tag'),           'tag this page ... (more options)' );
   }
 }
 
 /** setup **/
 var gwwt;
 function initGWWT ()
 {
   mw.loader.load( '/index.php?title=User:Poke/GuildWarsWikiTools.css&action=raw&ctype=text/css', 'text/css' );
   gwwt = new GuildWarsWikiTools( 'gwwt' );
   gwwt.initialize();
   
   if ( typeof( gwwtLoadAfter ) != 'undefined' )
     gwwtLoadAfter();
 }
$(initGWWT);
 /*</nowiki>*/