User:PSL600/common.js: Difference between revisions

From Test Wiki
Jump to navigation Jump to search
Content deleted Content added
PSL600 (talk | contribs)
mNo edit summary
PSL600 (talk | contribs)
No edit summary
Line 50: Line 50:
}, 250);
}, 250);
});
});

//<nowiki>
// Script based off of MoreMenu by MusikAnimal from the English Wikipedia.

( function( ) {
var api = new mw.Api(),
namespaceNumber = mw.config.get( 'wgNamespaceNumber' ), canonicalSpecialPageName = mw.config.get( 'wgCanonicalSpecialPageName' ),
isPageProtected = ( !!mw.config.get( 'wgRestrictionEdit' ) && mw.config.get( 'wgRestrictionEdit' ).length ) ||
( !!mw.config.get( 'wgRestrictionCreate' ) && mw.config.get( 'wgRestrictionCreate' ).length ),
serverName = mw.config.get( 'wgServerName' ), siteName = mw.config.get( 'wgSiteName' ),
scriptPath = mw.config.get('wgScriptPath'), userGroups = mw.config.get( 'wgUserGroups' ),
contentLanguage = mw.config.get( 'wgContentLanguage' ), noticeProject = mw.config.get( 'wgNoticeProject' ),
articleId = mw.config.get( 'wgArticleId' ), mwDBname = mw.config.get( 'wgDBname' ),
pageName = mw.config.get( 'wgPageName' ), userName = mw.config.get( 'wgRelevantUserName' ) || '',
isUserSpace, metaUserGroups, userPermissions, currentDate = new Date();
var escapedPageName = pageName.replace( /[!'"()*]/g, escape ),
encodedPageName = encodeURIComponent( pageName ),
escapedUserName = userName.replace( /[?!'()*]/g, escape ),
encodedUserName = encodeURIComponent( userName );

$( '#ca-protect,#ca-unprotect,#ca-delete,#ca-undelete' ).remove();
if ( mwDBname !== 'commonswiki' ) $( '#ca-move' ).remove();

var userMenuList = {
'User' : {
'User logs' : {
'All logs' : {
url : mw.util.getUrl( 'Special:Log', { action: 'view', user: userName } )
},
'Block log' : {
url : mw.util.getUrl( 'Special:Log', { action: 'view', user: userName, type: 'block' } ),
permissions : [ 'block' ]
},
'CheckUser log' : {
url : mw.util.getUrl( 'Special:CheckUserLog', { cuSearch: userName, cuSearchType: 'initiator' } ),
permissions : [ 'checkuser-log' ],
userPermissions : [ 'checkuser-log' ]
},
'Deletion log' : {
url : mw.util.getUrl( 'Special:Log', { action: 'view', user: userName, type: 'delete' } ),
permissions : [ 'delete' ]
},
'Filter log' : {
url : mw.util.getUrl( 'Special:AbuseLog', { wpSearchUser: userName } )
},
'Mass message log' : {
url : mw.util.getUrl( 'Special:Log', { action: 'view', user: userName, type: 'massmessage' } ),
permissions : [ 'massmessage' ]
},
'Move log' : {
url : mw.util.getUrl( 'Special:Log', { action: 'view', user: userName, type: 'move' } ),
permissions : [ 'move' ]
},
'Pending changes log' : {
url : mw.util.getUrl( 'Special:Log', { action: 'view', user: userName, type: 'stable' } ),
permissions : [ 'stablesettings' ]
},
'Protection log' : {
url : mw.util.getUrl( 'Special:Log', { action: 'view', user: userName, type: 'protect' } ),
permissions : [ 'protect' ]
},
'Review log' : {
url : mw.util.getUrl( 'Special:Log', { action: 'view', user: userName, type: 'review' } ),
permissions : [ 'review' ]
},
'Thanks log' : {
url : mw.util.getUrl( 'Special:Log', { action: 'view', user: userName, type: 'thanks' } ),
groups : [ 'user' ]
},
'Upload log' : {
url : mw.util.getUrl( 'Special:Log', { action: 'view', user: userName, type: 'upload' } ),
permissions : [ 'upload' ]
},
'User creation log' : {
url : mw.util.getUrl( 'Special:Log', { action: 'view', user: userName, type: 'newusers' } ),
groups : [ 'user' ] // any user can create new accounts at [[Special:CreateAccount]]
},
'User rights log' : {
url : mw.util.getUrl( 'Special:Log', { action: 'view', user: userName, type: 'rights' } ),
addRemoveGroups : true
}
},
'RfXs' : {
'RfAs' : {
url : mw.util.getUrl( 'Special:PrefixIndex/Wikipedia:Requests_for_adminship/' + userName ),
style : 'display:none',
title : 'Requests for Adminship'
},
'RfBs' : {
url : mw.util.getUrl( 'Special:PrefixIndex/Wikipedia:Requests_for_bureaucratship/' + userName ),
style : 'display:none',
title : 'Requests for Bureaucratship'
},
'RfArb' : {
url : mw.util.getUrl( 'Wikipedia:Arbitration/Requests/Case/' + userName ),
style : 'display:none',
title : 'Requests for Arbitration'
},
'RfC' : {
url : mw.util.getUrl( 'Wikipedia:Requests_for_comment/' + userName ),
style : 'display:none',
title : 'Requests for Comment'
},
'RfCU' : {
url : mw.util.getUrl( 'Wikipedia:Requests_for_checkuser/Case/' + userName ),
style : 'display:none',
title : 'Request for CheckUser'
},
'CCI' : {
url : mw.util.getUrl( 'Wikipedia:Contributor_copyright_investigations/' + userName ),
style : 'display:none',
title : 'Contributor copyright investigations'
},
'SPI' : {
url : mw.util.getUrl( 'Wikipedia:Sockpuppet_investigations/' + userName ),
style : 'display:none',
title : 'Sockpuppet investigations (as the sockmaster)'
}
},
'Blocks' : {
'Block user' : {
url : mw.util.getUrl( 'Special:Block/' + userName ),
userPermissions : 'block',
blocked : false
},
'Block globally' : {
url : '//meta.wikimedia.org/wiki/Special:GlobalBlock/' + userName,
userPermissions : 'globalblock',
ipOnly : true
},
'Change block' : {
url : mw.util.getUrl( 'Special:Block/' + userName ),
userPermissions : 'block',
blocked : true
},
'Central auth' : {
url : '//meta.wikimedia.org/wiki/Special:CentralAuth/' + userName,
userPermissions : 'centralauth-lock'
},
'Unblock user' : {
url : mw.util.getUrl( 'Special:Unblock/' + userName ),
blocked : true,
userPermissions : 'block'
},
'View block' : {
url : mw.util.getUrl( 'Special:BlockList', { wpTarget: userName } ),
blocked : true,
style : 'color:#EE1111'
},
'View block log' : {
url : mw.util.getUrl( 'Special:Log', { action: 'view', page: userName, type: 'block' } )
}
},
'Analysis' : {
'Analysis – Supercount' : {
url : '//tools.wmflabs.org/supercount/index.php?project=' + serverName + '&user=' + encodedUserName,
title : 'Cyberpower678s User Analysis Tool'
},
'Analysis – WikiChecker' : {
url : 'http://' + contentLanguage + '.wikichecker.com/user/?l=all&t=' + encodedUserName,
databaseRestrict : [ 'enwiki', 'jawiki', 'frwiki', 'ruwiki' ],
},
'Analysis – XTools' : {
url : '//tools.wmflabs.org/xtools-ec/?user=' + encodedUserName + '&project=' + serverName
},
'Articles created' : {
url : '//tools.wmflabs.org/xtools/pages/?user=' + encodedUserName + '&project='+ serverName + '&namespace=all&redirects=noredirects',
groups : ['user']
},
'Autoblocks' : {
url : '//tools.wmflabs.org/xtools/autoblock/?user=' + encodedUserName + '&project=' + serverName
},
'BLP edits' : {
url : '//tools.wmflabs.org/musikanimal/blp_edits?username=' + encodedUserName + '&contribs=on',
databaseRestrict : [ 'enwiki' ]
},
'Edit summary usage' : {
url : '//tools.wmflabs.org/xtools/editsummary/index.php?lang=en&wiki=' + siteName + '&name=' + encodedUserName
},
'Edit summary search' : {
url : '//tools.wmflabs.org/sigma/summary.py?name=' + encodedUserName
},
'Global contributions' : {
url : '//tools.wmflabs.org/guc/?user=' + encodedUserName + '&blocks=true'
},
'Non-automated edits' : {
url : '//tools.wmflabs.org/musikanimal/nonautomated_edits?username=' + encodedUserName + '&namespace=0&contribs=on&tools=on',
databaseRestrict : [ 'enwiki' ]
},
'Pages created' : {
url : '//tools.wmflabs.org/xtools/pages/?user=' + encodedUserName + '&project='+ serverName + '&namespace=all'
},
'SUL' : {
url : mw.util.getUrl( 'Special:CentralAuth/' + userName ),
groups : [ 'user' ]
}
},
'IP lookup' : {
'WHOIS' : {
url : 'http://whois.domaintools.com/' + escapedUserName,
ipOnly : true
},
'rDNS' : {
url : 'https://www.robtex.com/ip/' + escapedUserName + '.html',
ipOnly : true
},
'Traceroute' : {
url : 'http://www.domaintools.com/research/traceroute/?query=' + escapedUserName,
ipOnly : true
},
'Geolocate' : {
url : 'http://whatismyipaddress.com/ip/' + escapedUserName,
ipOnly : true
}
},
'Change rights' : {
url : mw.util.getUrl( 'Special:UserRights', { user: 'User:' + userName } ),
groups : [ 'user' ],
userAddRemoveGroups : true
},
'CheckUser' : {
url : mw.util.getUrl( 'Special:CheckUser/' + userName ),
userPermissions : [ 'checkuser' ]
},
'Contributions' : {
url : mw.util.getUrl( 'Special:Contributions/' + userName )
},
'Deleted contributions' : {
url : mw.util.getUrl( 'Special:DeletedContributions/' + userName ),
userPermissions : [ 'deletedhistory', 'deletedtext' ]
},
'Suppressed contribs' : {
url : mw.util.getUrl( 'Special:Log/suppress', { offender: userName } ),
userPermissions : [ 'oversight' ]
},
'Email user' : {
url : mw.util.getUrl( 'Special:EmailUser/' + userName ),
groups : [ 'user' ]
},
'Uploads' : {
url : mw.util.getUrl( 'Special:ListFiles', { user: userName, ilshowall: '1' } ),
groups : [ 'user' ]
},
'User groups' : {
url : mw.util.getUrl( 'Special:ListUsers', { limit: 1, username: userName } ),
groups : [ 'user' ]
},
'User rights changes' : {
url : mw.util.getUrl( 'Special:Log', { user: '' , page: 'User:' + userName, type: 'rights' } ),
groups : [ 'user' ]
},
'User thanks received' : {
url : mw.util.getUrl( 'Special:Log', { user: '' , page: 'User:' + userName, type: 'thanks' } ),
groups : [ 'user' ]
}
}
};

var pageMenuList = {
'Page' : {
'Page logs' : {
'All logs' : {
url : mw.util.getUrl( 'Special:Log', { action: 'view', page: pageName } )
},
'Deletion log' : {
url : mw.util.getUrl( 'Special:Log', { action: 'view', page: pageName, type: 'delete' } )
},
'Move log' : {
url : mw.util.getUrl( 'Special:Log', { action: 'view', page: pageName, type: 'move' } )
},
'Pending changes log' : {
url : mw.util.getUrl( 'Special:Log', { action: 'view', page: pageName, type: 'stable' } )
},
'Protection log' : {
url : mw.util.getUrl( 'Special:Log', { action: 'view', page: pageName, type: 'protect' } )
}
},
'Analysis' : {
'Analysis – WikiChecker' : {
url : 'http://' + contentLanguage + '.wikichecker.com/article/?a=' + encodedPageName,
databaseRestrict : [ 'enwiki', 'jawiki', 'frwiki', 'ruwiki' ],
pageExists : true
},
'Analysis – XTools' : {
url : '//tools.wmflabs.org/xtools-articleinfo/?article=' + escapedPageName + '&project=' + serverName,
pageExists : true
},
'Analysis – WikiHistory' : {
url : '//tools.wmflabs.org/xtools/wikihistory/wh.php?page_title=' + escapedPageName,
namespaceRestrict : [ 0 ],
pageExists : true
},
'Analysis – &#931;' : {
url : 'https://tools.wmflabs.org/sigma/articleinfo.py?page=' + encodedPageName + '&server=' + mwDBname,
pageExists : true
},
'Basic statistics' : {
url : mw.util.getUrl( pageName, { action: 'info' } ),
pageExists : true
},
'Search by contributor' : {
url : '//tools.wmflabs.org/sigma/usersearch.py?page=' + encodedPageName + '&server=' + mwDBname,
pageExists : true
},
'Search revision history' : {
url : 'http://wikipedia.ramselehof.de/wikiblame.php?lang=' + contentLanguage + '&project=' + noticeProject + '&article=' + encodedPageName,
pageExists : true
},
'Traffic report' : {
url : '//tools.wmflabs.org/pageviews?project=' + serverName + '&pages=' + encodedPageName,
pageExists : true
},
'Transclusions' : {
url : '//' + serverName + '/w/index.php?title=Special:WhatLinksHere/' + encodedPageName + '&hidelinks=1&hideredirs=1',
namespaceRestrict : [2, 4, 5, 10, 11, 12, 13, 100, 101]
}
},
'Tools' : {
'Check external links' : {
url : 'http://dispenser.homenet.org/~dispenser/cgi-bin/webchecklinks.py?page=' + encodedPageName + '&lang=' + contentLanguage,
pageExists : true,
noticeProjectRestrict : [ 'wikipedia' ]
},
'Check redirects' : {
url : 'http://dispenser.homenet.org/~dispenser/cgi-bin/rdcheck.py?page=' + encodedPageName + '&lang=' + contentLanguage,
pageExists : true,
noticeProjectRestrict : [ 'wikipedia' ]
},
'Copyright vio detector' : {
url : '//tools.wmflabs.org/copyvios?lang='+ contentLanguage + '&project=' + noticeProject + '&title=' + encodedPageName + '&oldid=&action=search&use_engine=1&use_links=1',
pageExists : true,
title : 'Queries search engine for copyright violations. Could take a while, so be patient.'
},
'Disambiguate links' : {
url : 'http://dispenser.homenet.org/~dispenser/cgi-bin/dablinks.py?page=' + encodedPageName + '&lang=' + contentLanguage,
pageExists : true,
noticeProjectRestrict : [ 'wikipedia' ]
},
'Expand bare references' : {
url : '//tools.wmflabs.org/refill/result.php?page=' + encodedPageName + '&defaults=y&wiki=' + contentLanguage,
pageExists: true,
namespaceRestrict : [ 0, 2, 118 ]
},
'Peer reviewer' : {
url : 'http://dispenser.homenet.org/~dispenser/view/Peer_reviewer#page:' + encodedPageName,
pageExists : true,
databaseRestrict : [ 'enwiki' ],
namespaceRestrict : [ 0, 2, 118 ]
},
'Transclusion count' : {
url : '//tools.wmflabs.org/templatecount/index.php?lang=' + contentLanguage + '&name=' + encodedPageName + '&namespace=' + namespaceNumber,
namespaceRestrict : [2, 4, 5, 10, 11, 12, 13, 100, 101],
noticeProjectRestrict : [ 'wikipedia' ]
}
},
'XfDs' : {
url : 'javascrit:void(0)'
},
'Change model' : {
url : mw.util.getUrl( 'Special:ChangeContentModel/' + pageName ),
userPermissions : [ 'editcontentmodel' ],
pageExists : true,
namespaceRestrict : [ 2, 4, 8, 100, 108, 828 ]
},
'Change protection' : {
url : mw.util.getUrl( pageName, { action: 'protect' } ),
userPermissions : [ 'protect', 'stablesettings' ],
isProtected : true
},
'Delete page' : {
url : '//' + serverName + scriptPath + '/index.php?title=' + encodedPageName + '&action=delete' + ( $( '#delete-reason' ).text() ? '&wpReason=' + $( '#delete-reason' ).text() : ''),
userPermissions : [ 'delete' ],
pageExists : true
},
'Edit intro' : {
url : '//' + serverName + scriptPath + '/index.php?title=' + encodedPageName + '&action=edit&section=0',
namespaceRestrict : [ 0, 1, 2, 3, 4, 5, 118 ],
pageExists : true
},
'Latest diff' : {
url : mw.util.getUrl( pageName, { action: 'view', diff: mw.config.get( 'wgCurRevisionId' ) } ),
pageExists : true
},
'Merge page' : {
url : mw.util.getUrl( 'Special:MergeHistory', { target: pageName } ),
userPermissions : [ 'mergehistory' ],
pageExists : true
},
'Move page' : {
url : mw.util.getUrl( 'Special:MovePage/' + pageName ),
userPermissions : [ 'move' ],
pageExists : true
},
'Protect page' : {
url : '//' + serverName + scriptPath + '/index.php?title=' + encodedPageName + '&action=protect',
userPermissions : [ 'protect', 'stablesettings' ]
},
'Purge cache' : {
url : mw.util.getUrl( pageName, { action: 'purge', forcelinkupdate: true } ),
pageExists : true
},
'Subpages' : {
url : mw.util.getUrl( 'Special:PrefixIndex/' + pageName + '/' ),
},
'Undelete page' : {
url : mw.util.getUrl( 'Special:Undelete/' + pageName ),
userPermissions : [ 'undelete' ],
pageDeleted : true
}
}
};

var dependencies = [];

if ( !$.jStorage ) dependencies.push( 'jquery.jStorage' );
if ( !Object.keys ) dependencies.push( 'es5-shim' );

// initialize script
mw.loader.using( dependencies, function() {
var menus = [];

if ( namespaceNumber === 2 || namespaceNumber === 3 || canonicalSpecialPageName === 'Contributions' || !!mw.util.getParamValue("user") ) {
isUserSpace = true;
menus.push( userMenuList );
}
if ( namespaceNumber >= 0 ) menus.push( pageMenuList );

init( menus, function(data) {
completePageLinks();
if ( isUserSpace ) completeUserLinks(data[0].query);
} );
} );

// custom callback functions for these menus

function completePageLinks() {
$( '#c2-page-xfds' ).hide();

if ( mwDBname === 'enwiki' ) {
apiGet( {
titles: 'Wikipedia:Articles for deletion/' + pageName + '|Wikipedia:Miscellany for deletion/' + pageName,
prop: 'info'
} ).done( function( data ) {
for ( var i in data.query.pages ) {
if ( i > -1 ) {
if ( data.query.pages[i].title.split( '/' )[0] === 'Wikipedia:Miscellany for deletion' ) {
$( '#c2-page-xfds' ).show().find( 'a' ).text( 'MfDs' ).prop( 'href',
mw.util.getUrl( 'Special:PrefixIndex/Wikipedia:Miscellany_for_deletion/' + pageName )
);
} else if ( data.query.pages[i].title.split( '/' )[0] === 'Wikipedia:Articles for deletion' ) {
$( '#c2-page-xfds' ).show().find( 'a' ).text( 'AfDs' ).prop( 'href',
mw.util.getUrl( 'Special:PrefixIndex/Wikipedia:Articles_for_deletion/' + pageName )
);
}
break;
}
}
} );

if ( mw.user.options.get( 'gadget-edittop' ) === '1' ) {
$( '#c2-page-edit_intro' ).remove();
}
}

$( '#p-views ul' ).on( 'beforeTabCollapse', function() {
if ( $( '#ca-history' ).hasClass( 'collapsible' ) ) {
$( '#p-page2' ).find( 'ul' ).append( $( '#ca-history' ).detach() );
}
} );
}

function completeUserLinks( query ) {
apiGet( {
list : 'logevents',
letype : 'block',
letitle : 'User:' + userName,
lelimit : 1
} ).done( function( data ) {
if ( data.query.logevents.length === 0) {
$( '#c2-user-blocks-view_block_log' ).remove();
}
if ( $( '#c2-user-blocks' ).find( 'li' ).length === 0 ) {
$( '#c2-user-blocks' ).remove();
}
} );

var rfxs = {
'Wikipedia:Requests for adminship' : 'rfas',
'Wikipedia:Requests for bureaucratship' : 'rfbs',
'Wikipedia:Arbitration/Requests/Case' : 'rfarb',
'Wikipedia:Requests for comment' : 'rfc',
'Wikipedia:Requests for checkuser/Case' : 'rfcu',
'Wikipedia:Contributor copyright investigations' : 'cci',
'Wikipedia:Sockpuppet investigations' : 'spi'
};

$( '#c2-user-rfxs' ).hide();
if ( mwDBname === 'enwiki' ) {
apiGet( {
titles : $.map( Object.keys( rfxs ), function( rfx, i ) {
return rfx + '/' + userName;
} ).join( '|' ),
prop: 'info'
} ).done( function( data ) {
var pages = data.query.pages;
for ( var id in pages ) {
if ( id > 0 ) {
$( '#c2-user-rfxs' ).show();
var key = pages[id].title.replace( '/' + userName, '' );
$( '#c2-user-rfxs-' + rfxs[key] ).find( 'a' ).show();
}
}
} );
}
}


// everything below is internal functions – should not need to be modified for any customization

function addListeners() {
$( '.c2-hover-menu' ).each( function() {
$( this ).hover( function() {
$el = $( this ).find( '.submenu' );
$el.css( {
left : $( this ).outerWidth(),
top : '-1px',
'border-top-width' : 1
} );
$el.show();
}, function() {
$( this ).find( '.submenu' ).hide();
} );
} );
}

function apiGet( params ) {
return api.get(
$.extend( params, {
action: 'query'
} )
);
}

function canAddRemoveGroups( groups, permissions ) {
if ( permissions && permissions.indexOf( 'userrights' ) >= 0 ) return true;
var ret = false;
for ( var i=0; i<groups.length; i++ ) {
if ( metaUserGroups[groups[i]] && metaUserGroups[groups[i]].addRemoveGroups ) {
ret = true;
break;
} else {
// clear cache and fallback to false
$.jStorage.deleteKey( 'metaUserGroups' );
ret = false;
}
}
return ret;
}

// scope is an array, returns true if all elements in 'array' exist in scope
function containsArray( array, index, last ) {
if ( !index ) {
index = 0;
last = 0;
this.sort();
array.sort();
}
return index === array.length
|| ( last = this.indexOf( array[index], last ) ) > -1
&& containsArray.call( this, array, ++index, ++last );
}

function generateMenuContent( tabName, menuList, userData, userPermissions ) {
var html = '';
$.each( menuList, function( name, action ) {
if ( action ) {
var newHtml = '';
if ( !action.url ) {
newHtml += '<li style="position: relative;" id="' + linkId( tabName, name ) + '" class="c2-hover-menu">' +
'<a style="font-weight: bold">' + name + '&hellip;</a>' +
'<div class="submenu menu" style="display: none; position: absolute;"><ul>';

$.each( action, function( k, v ) {
newHtml += linkHtml( tabName, k, v, name, userData, userPermissions );
} );
newHtml += '</ul></div></li>';
if ( $( newHtml ).last().find( '.submenu li' ).length === 0 ) {
newHtml = '';
}
} else {
newHtml += linkHtml( tabName, name, action, null, userData, userPermissions );
}
html += newHtml;
}
} );
return html;
}

function hasConditional( permitted, given ) {
permitted = $.makeArray( permitted );
given = $.makeArray( given );
if ( !permitted.length ) {
return true;
} else if ( !given.length ) {
return false;
} else {
var valid = false;
for ( var i=0; i<given.length; i++ ) {
if ( $.inArray( given[i], permitted ) >= 0 ) {
valid = true;
break;
}
}
return valid;
}
}

function linkId( tabName, name, parent ) {
return 'c2-' + sanitize( tabName.toLowerCase() ) + '-' + ( parent ? sanitize( parent ) + '-' : '') + sanitize( name );
}

function linkHtml( tabName, name, action, parent, userData, userPermissions ) {
var validations =
/* namespace */ ( hasConditional( action.namespaceRestrict, namespaceNumber ) || !hasConditional( action.namespaceExclude, namespaceNumber ) ) &&
/* existence */ ( ( action.pageExists && articleId > 0 ) || ( !action.pageExists ) ) &&
/* deleted */ ( action.pageDeleted ? articleId === 0 && mw.config.get( 'wgIsArticle' ) === false : true ) &&
/* protected */ ( action.isProtected ? isPageProtected : true ) &&
/* database */ hasConditional( action.databaseRestrict, mwDBname ) &&
/* notice project */ hasConditional( action.noticeProjectRestrict, noticeProject ) &&
/* user's user groups */ hasConditional( action.userGroups, userGroups ) &&
/* user's permissions */ hasConditional( action.userPermissions, userPermissions ) &&
/* can change groups */ ( action.userAddRemoveGroups ? canAddRemoveGroups( userGroups, userPermissions ) : true );

if ( isUserSpace ) {
// FIXME: find something better than userData.invalid === '' for checking if IP
validations &=
/* their user groups */ hasConditional( action.groups, userData.groups ) &&
/* their permissions */ hasConditional( action.permissions, userData.rights ) &&
/* they're blocked */ ( action.blocked !== undefined ? !!userData.blockid === action.blocked : true ) &&
/* can change groups */ ( action.addRemoveGroups ? canAddRemoveGroups( userData.groups, userData.rights ) : true ) &&
/* IP */ ( action.ipOnly ? userData.invalid === '' : true );
}

if ( !!validations ) {
return '<li id=' + linkId( tabName, name, parent ) + '><a href="' + action.url + '" title="' + ( action.title || '' ) + '" ' + ( action.style ? 'style="' + action.style + '"' : '' ) + '>' + name + '</a></li>';
} else {
return '';
}
}

function sanitize( name ) {
return name.toLowerCase().replace( / /g, '_' );
}

function init( menus, fn ) {
var promises = new Array(3),
cacheDate = $.jStorage.get( 'mmCacheDate' ),
expired = cacheDate < currentDate;

if( isUserSpace ) {
promises[0] = apiGet( {
list : 'users|blocks',
ususers : userName,
bkusers : userName,
usprop : 'blockinfo|groups|rights',
bkprop : 'id'
} );
}

if ( expired || !( userPermissions = $.jStorage.get( 'mmUserRights' ) ) ) {
promises[1] = mw.user.getRights();
}

if ( expired || !( metaUserGroups = $.jStorage.get( 'mmMetaUserGroups' ) ) ) {
promises[2] = apiGet( {
meta : 'siteinfo',
siprop : 'usergroups'
} );
}

$.when.apply( this, promises ).done( function ( data, userRightsData, metaData ) {
var userData;

if ( data ) {
userData = data[0].query.users[0];

if ( !userData ) {
// FIXME: add functionality to only show menu based on custom function;
// temporary fix so that script doesn't break on pages of users that don't exist
isUserSpace = false;
for ( var j = 0; j < menus.length; j++ ) {
if ( !!menus[j].User ) menus.splice( j, 1 );
}
} else if ( userData.invalid === '' ) {
userData.groups = [];
userData.rights = [];
if ( data[0].query.blocks.length ) {
userData.blockid = data[0].query.blocks[0].id;
}
}
}

if ( userRightsData ) {
userPermissions = $.jStorage.set( 'mmUserRights', userRightsData );
}

if ( metaData ) {
metaUserGroups = {};
$.each(metaData[0].query.usergroups, function ( i, el ) {
metaUserGroups[el.name] = {
permissions : el.rights,
addRemoveGroups : !!el.add || !!el.remove
};
} );
$.jStorage.set( 'mmMetaUserGroups', metaUserGroups );
}

if ( expired ) {
var newDate = new Date();
$.jStorage.set( 'mmCacheDate', newDate.setDate( newDate.getDate() + 1 ) );
}

for ( var i=0; i<menus.length; i++ ) {
var tabName = Object.keys( menus[i] )[0];
var html = '<div id="p-' + tabName.toLowerCase() + '2" class="vectorMenu" style="z-index: 99;">' +
'<h3>' +
'<span>' + tabName + '</span>' +
'<a href="#"></a>' +
'</h3>' +
'<div class="menu"><ul>';
html += generateMenuContent( tabName, menus[i][tabName], userData, userPermissions );
html += '</ul></div></div>';
if ( $( '#p-cactions' )[0] ) {
$( html ).insertAfter( $( '#p-cactions' ) );
} else {
$( html ).insertAfter( $( '#p-views' ) );
}
addListeners();
}

if ( typeof fn === 'function' ) fn( data, userPermissions );
} );
}
} )( );
//</nowiki>
/* ################### */
/* ################### */

Revision as of 07:59, 2 July 2018

/* Replaces {{USERNAME}} with the name of the user browsing the page.
   Requires copying Template:USERNAME. */
 
$(function UserNameReplace() {
    if(typeof(disableUsernameReplace) != 'undefined' && disableUsernameReplace || wgUserName === null) return;
    $("span.insertusername").html(wgUserName);
});
 
/* End of the {{USERNAME}} replacement */
 
// RevealAnonIP
 
window.RevealAnonIP = {
    permissions: ['rollback', 'sysop', 'bureaucrat']
};
 
/* Auto updating recent changes opt-in
  * See w:c:dev:AjaxRC for info & attribution
  */
 
 AjaxRCRefreshText = 'Auto-Refresh';
 AjaxRCRefreshHoverText = 'Automatically refresh the page';
 ajaxPages = ["Special:RecentChanges","Special:WikiActivity","Special:UncategorizedPages","Special:AllPages"];
 importScriptPage('AjaxRC/code.js', 'dev');
 
 window.UserTagsJS = {
	modules: {},
	tags: {},
	oasisPlaceBefore: ''
};

/* Users blocked infinite */
window.addEventListener('load', function() {
    // Timeouts are always a terrible way to go, but UserTags has no event dispatched when it finished loading.
    setTimeout(function() {
        if (document.getElementById('UserProfileMasthead') === null) return;
        var blockTag = document.querySelector('.tag.usergroup-blocked.blocked-user');
        if (blockTag === null) return;
        new mw.Api().get({
            action: 'query',
            list: 'blocks',
            bkprop: 'expiry',
            bktimestamp: new Date().getTime(),
            bkusers: wgTitle
        }).done(function(d) {
            if (d.query.blocks[0] && d.query.blocks[0].expiry == 'infinity') {
                blockTag.innerHTML = 'Shattered';
            }
        });
    }, 250);
});

//<nowiki>
// Script based off of MoreMenu by MusikAnimal from the English Wikipedia.

( function( ) {
	var api = new mw.Api(),
		namespaceNumber = mw.config.get( 'wgNamespaceNumber' ), canonicalSpecialPageName = mw.config.get( 'wgCanonicalSpecialPageName' ),
		isPageProtected = ( !!mw.config.get( 'wgRestrictionEdit' ) && mw.config.get( 'wgRestrictionEdit' ).length ) ||
			( !!mw.config.get( 'wgRestrictionCreate' ) && mw.config.get( 'wgRestrictionCreate' ).length ),
		serverName = mw.config.get( 'wgServerName' ), siteName = mw.config.get( 'wgSiteName' ),
		scriptPath = mw.config.get('wgScriptPath'), userGroups = mw.config.get( 'wgUserGroups' ),
		contentLanguage = mw.config.get( 'wgContentLanguage' ), noticeProject = mw.config.get( 'wgNoticeProject' ),
		articleId = mw.config.get( 'wgArticleId' ), mwDBname = mw.config.get( 'wgDBname' ),
		pageName = mw.config.get( 'wgPageName' ), userName = mw.config.get( 'wgRelevantUserName' ) || '',
		isUserSpace, metaUserGroups, userPermissions, currentDate = new Date();
	var escapedPageName = pageName.replace( /[!'"()*]/g, escape ),
		encodedPageName = encodeURIComponent( pageName ),
		escapedUserName = userName.replace( /[?!'()*]/g, escape ),
		encodedUserName = encodeURIComponent( userName );

	$( '#ca-protect,#ca-unprotect,#ca-delete,#ca-undelete' ).remove();
	if ( mwDBname !== 'commonswiki' ) $( '#ca-move' ).remove();

	var userMenuList = {
		'User' : {
			'User logs' : {
				'All logs' : {
					url : mw.util.getUrl( 'Special:Log', { action: 'view', user: userName } )
				},
				'Block log' : {
					url : mw.util.getUrl( 'Special:Log', { action: 'view', user: userName, type: 'block' } ),
					permissions : [ 'block' ]
				},
				'CheckUser log' : {
					url : mw.util.getUrl( 'Special:CheckUserLog', { cuSearch: userName, cuSearchType: 'initiator' } ),
					permissions : [ 'checkuser-log' ],
					userPermissions : [ 'checkuser-log' ]
				},
				'Deletion log' : {
					url : mw.util.getUrl( 'Special:Log', { action: 'view', user: userName, type: 'delete' } ),
					permissions : [ 'delete' ]
				},
				'Filter log' : {
					url : mw.util.getUrl( 'Special:AbuseLog', { wpSearchUser: userName } )
				},
				'Mass message log' : {
					url : mw.util.getUrl( 'Special:Log', { action: 'view', user: userName, type: 'massmessage' } ),
					permissions : [ 'massmessage' ]
				},
				'Move log' : {
					url : mw.util.getUrl( 'Special:Log', { action: 'view', user: userName, type: 'move' } ),
					permissions : [ 'move' ]
				},
				'Pending changes log' : {
					url : mw.util.getUrl( 'Special:Log', { action: 'view', user: userName, type: 'stable' } ),
					permissions : [ 'stablesettings' ]
				},
				'Protection log' : {
					url : mw.util.getUrl( 'Special:Log', { action: 'view', user: userName, type: 'protect' } ),
					permissions : [ 'protect' ]
				},
				'Review log' : {
					url : mw.util.getUrl( 'Special:Log', { action: 'view', user: userName, type: 'review' } ),
					permissions : [ 'review' ]
				},
				'Thanks log' : {
					url : mw.util.getUrl( 'Special:Log', { action: 'view', user: userName, type: 'thanks' } ),
					groups : [ 'user' ]
				},
				'Upload log' : {
					url : mw.util.getUrl( 'Special:Log', { action: 'view', user: userName, type: 'upload' } ),
					permissions : [ 'upload' ]
				},
				'User creation log' : {
					url : mw.util.getUrl( 'Special:Log', { action: 'view', user: userName, type: 'newusers' } ),
					groups : [ 'user' ] // any user can create new accounts at [[Special:CreateAccount]]
				},
				'User rights log' : {
					url : mw.util.getUrl( 'Special:Log', { action: 'view', user: userName, type: 'rights' } ),
					addRemoveGroups : true
				}
			},
			'RfXs' : {
				'RfAs' : {
					url : mw.util.getUrl( 'Special:PrefixIndex/Wikipedia:Requests_for_adminship/' + userName ),
					style : 'display:none',
					title : 'Requests for Adminship'
				},
				'RfBs' : {
					url : mw.util.getUrl( 'Special:PrefixIndex/Wikipedia:Requests_for_bureaucratship/' + userName ),
					style : 'display:none',
					title : 'Requests for Bureaucratship'
				},
				'RfArb' : {
					url : mw.util.getUrl( 'Wikipedia:Arbitration/Requests/Case/' + userName ),
					style : 'display:none',
					title : 'Requests for Arbitration'
				},
				'RfC' : {
					url : mw.util.getUrl( 'Wikipedia:Requests_for_comment/' + userName ),
					style : 'display:none',
					title : 'Requests for Comment'
				},
				'RfCU' : {
					url : mw.util.getUrl( 'Wikipedia:Requests_for_checkuser/Case/' + userName ),
					style : 'display:none',
					title : 'Request for CheckUser'
				},
				'CCI' : {
					url : mw.util.getUrl( 'Wikipedia:Contributor_copyright_investigations/' + userName ),
					style : 'display:none',
					title : 'Contributor copyright investigations'
				},
				'SPI' : {
					url : mw.util.getUrl( 'Wikipedia:Sockpuppet_investigations/' + userName ),
					style : 'display:none',
					title : 'Sockpuppet investigations (as the sockmaster)'
				}
			},
			'Blocks' : {
				'Block user' : {
					url : mw.util.getUrl( 'Special:Block/' + userName ),
					userPermissions : 'block',
					blocked : false
				},
				'Block globally' : {
					url : '//meta.wikimedia.org/wiki/Special:GlobalBlock/' + userName,
					userPermissions : 'globalblock',
					ipOnly : true
				},
				'Change block' : {
					url : mw.util.getUrl( 'Special:Block/' + userName ),
					userPermissions : 'block',
					blocked : true
				},
				'Central auth' : {
					url : '//meta.wikimedia.org/wiki/Special:CentralAuth/' + userName,
					userPermissions : 'centralauth-lock'
				},
				'Unblock user' : {
					url : mw.util.getUrl( 'Special:Unblock/' + userName ),
					blocked : true,
					userPermissions : 'block'
				},
				'View block' : {
					url : mw.util.getUrl( 'Special:BlockList', { wpTarget: userName } ),
					blocked : true,
					style : 'color:#EE1111'
				},
				'View block log' : {
					url : mw.util.getUrl( 'Special:Log', { action: 'view', page: userName, type: 'block' } )
				}
			},
			'Analysis' : {
				'Analysis – Supercount' : {
					url : '//tools.wmflabs.org/supercount/index.php?project=' + serverName + '&user=' + encodedUserName,
					title : 'Cyberpower678s User Analysis Tool'
				},
				'Analysis – WikiChecker' : {
					url : 'http://' + contentLanguage + '.wikichecker.com/user/?l=all&t=' + encodedUserName,
					databaseRestrict : [ 'enwiki', 'jawiki', 'frwiki', 'ruwiki' ],
				},
				'Analysis – XTools' : {
					url : '//tools.wmflabs.org/xtools-ec/?user=' + encodedUserName + '&project=' + serverName
				},
				'Articles created' : {
					url : '//tools.wmflabs.org/xtools/pages/?user=' + encodedUserName + '&project='+ serverName + '&namespace=all&redirects=noredirects',
					groups : ['user']
				},
				'Autoblocks' : {
					url : '//tools.wmflabs.org/xtools/autoblock/?user=' + encodedUserName + '&project=' + serverName
				},
				'BLP edits' : {
					url : '//tools.wmflabs.org/musikanimal/blp_edits?username=' + encodedUserName + '&contribs=on',
					databaseRestrict : [ 'enwiki' ]
				},
				'Edit summary usage' : {
					url : '//tools.wmflabs.org/xtools/editsummary/index.php?lang=en&wiki=' + siteName + '&name=' + encodedUserName
				},
				'Edit summary search' : {
					url : '//tools.wmflabs.org/sigma/summary.py?name=' + encodedUserName
				},
				'Global contributions' : {
					url : '//tools.wmflabs.org/guc/?user=' + encodedUserName + '&blocks=true'
				},
				'Non-automated edits' : {
					url : '//tools.wmflabs.org/musikanimal/nonautomated_edits?username=' + encodedUserName + '&namespace=0&contribs=on&tools=on',
					databaseRestrict : [ 'enwiki' ]
				},
				'Pages created' : {
					url : '//tools.wmflabs.org/xtools/pages/?user=' + encodedUserName + '&project='+ serverName + '&namespace=all'
				},
				'SUL' : {
					url : mw.util.getUrl( 'Special:CentralAuth/' + userName ),
					groups : [ 'user' ]
				}
			},
			'IP lookup' : {
				'WHOIS' : {
					url : 'http://whois.domaintools.com/' + escapedUserName,
					ipOnly : true
				},
				'rDNS' : {
					url : 'https://www.robtex.com/ip/' + escapedUserName + '.html',
					ipOnly : true
				},
				'Traceroute' : {
					url : 'http://www.domaintools.com/research/traceroute/?query=' + escapedUserName,
					ipOnly : true
				},
				'Geolocate' : {
					url : 'http://whatismyipaddress.com/ip/' + escapedUserName,
					ipOnly : true
				}
			},
			'Change rights' : {
				url : mw.util.getUrl( 'Special:UserRights', { user: 'User:' + userName } ),
				groups : [ 'user' ],
				userAddRemoveGroups : true
			},
			'CheckUser' : {
				url : mw.util.getUrl( 'Special:CheckUser/' + userName ),
				userPermissions : [ 'checkuser' ]
			},
			'Contributions' : {
				url : mw.util.getUrl( 'Special:Contributions/' + userName )
			},
			'Deleted contributions' : {
				url : mw.util.getUrl( 'Special:DeletedContributions/' + userName ),
				userPermissions : [ 'deletedhistory', 'deletedtext' ]
			},
			'Suppressed contribs' : {
				url : mw.util.getUrl( 'Special:Log/suppress', { offender: userName } ),
				userPermissions : [ 'oversight' ]
			},
			'Email user' : {
				url : mw.util.getUrl( 'Special:EmailUser/' + userName ),
				groups : [ 'user' ]
			},
			'Uploads' : {
				url : mw.util.getUrl( 'Special:ListFiles', { user: userName, ilshowall: '1' } ),
				groups : [ 'user' ]
			},
			'User groups' : {
				url : mw.util.getUrl( 'Special:ListUsers', { limit: 1, username: userName } ),
				groups : [ 'user' ]
			},
			'User rights changes' : {
				url : mw.util.getUrl( 'Special:Log', { user: '' , page: 'User:' + userName, type: 'rights' } ),
				groups : [ 'user' ]
			},
			'User thanks received' : {
				url : mw.util.getUrl( 'Special:Log', { user: '' , page: 'User:' + userName, type: 'thanks' } ),
				groups : [ 'user' ]
			}
		}
	};

	var pageMenuList = {
		'Page' : {
			'Page logs' : {
				'All logs' : {
					url : mw.util.getUrl( 'Special:Log', { action: 'view', page: pageName } )
				},
				'Deletion log' : {
					url : mw.util.getUrl( 'Special:Log', { action: 'view', page: pageName, type: 'delete' } )
				},
				'Move log' : {
					url : mw.util.getUrl( 'Special:Log', { action: 'view', page: pageName, type: 'move' } )
				},
				'Pending changes log' : {
					url : mw.util.getUrl( 'Special:Log', { action: 'view', page: pageName, type: 'stable' } )
				},
				'Protection log' : {
					url : mw.util.getUrl( 'Special:Log', { action: 'view', page: pageName, type: 'protect' } )
				}
			},
			'Analysis' : {
				'Analysis – WikiChecker' : {
					url : 'http://' + contentLanguage + '.wikichecker.com/article/?a=' + encodedPageName,
					databaseRestrict : [ 'enwiki', 'jawiki', 'frwiki', 'ruwiki' ],
					pageExists : true
				},
				'Analysis – XTools' : {
				  url : '//tools.wmflabs.org/xtools-articleinfo/?article=' + escapedPageName + '&project=' + serverName,
				  pageExists : true
				},
				'Analysis – WikiHistory' : {
					url : '//tools.wmflabs.org/xtools/wikihistory/wh.php?page_title=' + escapedPageName,
					namespaceRestrict : [ 0 ],
					pageExists : true
				},
				'Analysis – &#931;' : {
					url : 'https://tools.wmflabs.org/sigma/articleinfo.py?page=' + encodedPageName + '&server=' + mwDBname,
					pageExists : true
				},
				'Basic statistics' : {
					url : mw.util.getUrl( pageName, { action: 'info' } ),
					pageExists : true
				},
				'Search by contributor' : {
					url : '//tools.wmflabs.org/sigma/usersearch.py?page=' + encodedPageName + '&server=' + mwDBname,
					pageExists : true
				},
				'Search revision history' : {
					url : 'http://wikipedia.ramselehof.de/wikiblame.php?lang=' + contentLanguage + '&project=' + noticeProject + '&article=' + encodedPageName,
					pageExists : true
				},
				'Traffic report' : {
					url : '//tools.wmflabs.org/pageviews?project=' + serverName + '&pages=' + encodedPageName,
					pageExists : true
				},
				'Transclusions' : {
					url : '//' + serverName + '/w/index.php?title=Special:WhatLinksHere/' + encodedPageName + '&hidelinks=1&hideredirs=1',
					namespaceRestrict : [2, 4, 5, 10, 11, 12, 13, 100, 101]
				}
			},
			'Tools' : {
				'Check external links' : {
					url : 'http://dispenser.homenet.org/~dispenser/cgi-bin/webchecklinks.py?page=' + encodedPageName + '&lang=' + contentLanguage,
					pageExists : true,
					noticeProjectRestrict : [ 'wikipedia' ]
				},
				'Check redirects' : {
					url : 'http://dispenser.homenet.org/~dispenser/cgi-bin/rdcheck.py?page=' + encodedPageName + '&lang=' + contentLanguage,
					pageExists : true,
					noticeProjectRestrict : [ 'wikipedia' ]
				},
				'Copyright vio detector' : {
					url : '//tools.wmflabs.org/copyvios?lang='+  contentLanguage + '&project=' + noticeProject + '&title=' + encodedPageName + '&oldid=&action=search&use_engine=1&use_links=1',
					pageExists : true,
					title : 'Queries search engine for copyright violations. Could take a while, so be patient.'
				},
				'Disambiguate links' : {
					url : 'http://dispenser.homenet.org/~dispenser/cgi-bin/dablinks.py?page=' + encodedPageName + '&lang=' + contentLanguage,
					pageExists : true,
					noticeProjectRestrict : [ 'wikipedia' ]
				},
				'Expand bare references' : {
					url : '//tools.wmflabs.org/refill/result.php?page=' + encodedPageName + '&defaults=y&wiki=' + contentLanguage,
					pageExists: true,
					namespaceRestrict : [ 0, 2, 118 ]
				},
				'Peer reviewer' : {
					url : 'http://dispenser.homenet.org/~dispenser/view/Peer_reviewer#page:' + encodedPageName,
					pageExists : true,
					databaseRestrict : [ 'enwiki' ],
					namespaceRestrict : [ 0, 2, 118 ]
				},
				'Transclusion count' : {
					url : '//tools.wmflabs.org/templatecount/index.php?lang=' + contentLanguage + '&name=' + encodedPageName + '&namespace=' + namespaceNumber,
					namespaceRestrict : [2, 4, 5, 10, 11, 12, 13, 100, 101],
					noticeProjectRestrict : [ 'wikipedia' ]
				}
			},
			'XfDs' : {
				url : 'javascrit:void(0)'
			},
			'Change model' : {
				url : mw.util.getUrl( 'Special:ChangeContentModel/' + pageName ),
				userPermissions : [ 'editcontentmodel' ],
				pageExists : true,
				namespaceRestrict : [ 2, 4, 8, 100, 108, 828 ]
			},
			'Change protection' : {
				url : mw.util.getUrl( pageName, { action: 'protect' } ),
				userPermissions : [ 'protect', 'stablesettings' ],
				isProtected : true
			},
			'Delete page' : {
				url : '//' + serverName + scriptPath + '/index.php?title=' + encodedPageName + '&action=delete' + ( $( '#delete-reason' ).text() ? '&wpReason=' + $( '#delete-reason' ).text() : ''),
				userPermissions : [ 'delete' ],
				pageExists : true
			},
			'Edit intro' : {
				url : '//' + serverName + scriptPath + '/index.php?title=' + encodedPageName + '&action=edit&section=0',
				namespaceRestrict : [ 0, 1, 2, 3, 4, 5, 118 ],
				pageExists : true
			},
			'Latest diff' : {
				url : mw.util.getUrl( pageName, { action: 'view', diff: mw.config.get( 'wgCurRevisionId' ) } ),
				pageExists : true
			},
			'Merge page' : {
				url : mw.util.getUrl( 'Special:MergeHistory', { target: pageName } ),
				userPermissions : [ 'mergehistory' ],
				pageExists : true
			},
			'Move page' : {
				url : mw.util.getUrl( 'Special:MovePage/' + pageName ),
				userPermissions : [ 'move' ],
				pageExists : true
			},
			'Protect page' : {
				url : '//' + serverName + scriptPath + '/index.php?title=' + encodedPageName + '&action=protect',
				userPermissions : [ 'protect', 'stablesettings' ]
			},
			'Purge cache' : {
				url : mw.util.getUrl( pageName, { action: 'purge', forcelinkupdate: true } ),
				pageExists : true
			},
			'Subpages' : {
				url : mw.util.getUrl( 'Special:PrefixIndex/' + pageName + '/' ),
			},
			'Undelete page' : {
				url : mw.util.getUrl( 'Special:Undelete/' + pageName ),
				userPermissions : [ 'undelete' ],
				pageDeleted : true
			}
		}
	};

	var dependencies = [];

	if ( !$.jStorage ) dependencies.push( 'jquery.jStorage' );
	if ( !Object.keys ) dependencies.push( 'es5-shim' );

	// initialize script
	mw.loader.using( dependencies, function() {
		var menus = [];

		if ( namespaceNumber === 2 || namespaceNumber === 3 || canonicalSpecialPageName === 'Contributions' || !!mw.util.getParamValue("user") ) {
			isUserSpace = true;
			menus.push( userMenuList );
		}
		if ( namespaceNumber >= 0 ) menus.push( pageMenuList );

		init( menus, function(data) {
			completePageLinks();
			if ( isUserSpace ) completeUserLinks(data[0].query);
		} );
	} );

	// custom callback functions for these menus

	function completePageLinks() {
		$( '#c2-page-xfds' ).hide();

		if ( mwDBname === 'enwiki' ) {
			apiGet( {
				titles: 'Wikipedia:Articles for deletion/' + pageName + '|Wikipedia:Miscellany for deletion/' + pageName,
				prop: 'info'
			} ).done( function( data ) {
				for ( var i in data.query.pages ) {
					if ( i > -1 ) {
						if ( data.query.pages[i].title.split( '/' )[0] === 'Wikipedia:Miscellany for deletion' ) {
							$( '#c2-page-xfds' ).show().find( 'a' ).text( 'MfDs' ).prop( 'href',
								mw.util.getUrl( 'Special:PrefixIndex/Wikipedia:Miscellany_for_deletion/' + pageName )
							);
						} else if ( data.query.pages[i].title.split( '/' )[0] === 'Wikipedia:Articles for deletion' ) {
							$( '#c2-page-xfds' ).show().find( 'a' ).text( 'AfDs' ).prop( 'href',
								mw.util.getUrl( 'Special:PrefixIndex/Wikipedia:Articles_for_deletion/' + pageName )
							);
						}
						break;
					}
				}
			} );

			if ( mw.user.options.get( 'gadget-edittop' ) === '1' ) {
				$( '#c2-page-edit_intro' ).remove();
			}
		}

		$( '#p-views ul' ).on( 'beforeTabCollapse', function() {
			if ( $( '#ca-history' ).hasClass( 'collapsible' ) ) {
				$( '#p-page2' ).find( 'ul' ).append( $( '#ca-history' ).detach() );
			}
		} );
	}

	function completeUserLinks( query ) {
		apiGet( {
			list : 'logevents',
			letype : 'block',
			letitle : 'User:' + userName,
			lelimit : 1
		} ).done( function( data ) {
			if ( data.query.logevents.length === 0) {
				$( '#c2-user-blocks-view_block_log' ).remove();
			}
			if ( $( '#c2-user-blocks' ).find( 'li' ).length === 0 ) {
				$( '#c2-user-blocks' ).remove();
			}
		} );

		var rfxs = {
			'Wikipedia:Requests for adminship' : 'rfas',
			'Wikipedia:Requests for bureaucratship' : 'rfbs',
			'Wikipedia:Arbitration/Requests/Case' : 'rfarb',
			'Wikipedia:Requests for comment' : 'rfc',
			'Wikipedia:Requests for checkuser/Case' : 'rfcu',
			'Wikipedia:Contributor copyright investigations' : 'cci',
			'Wikipedia:Sockpuppet investigations' : 'spi'
		};

		$( '#c2-user-rfxs' ).hide();
		if ( mwDBname === 'enwiki' ) {
			apiGet( {
				titles : $.map( Object.keys( rfxs ), function( rfx, i ) {
						return rfx + '/' + userName;
					} ).join( '|' ),
				prop: 'info'
			} ).done( function( data ) {
				var pages = data.query.pages;
				for ( var id in pages ) {
					if ( id > 0 ) {
						$( '#c2-user-rfxs' ).show();
						var key = pages[id].title.replace( '/' + userName, '' );
						$( '#c2-user-rfxs-' + rfxs[key] ).find( 'a' ).show();
					}
				}
			} );
		}
	}


	// everything below is internal functions – should not need to be modified for any customization

	function addListeners() {
		$( '.c2-hover-menu' ).each( function() {
			$( this ).hover( function() {
				$el = $( this ).find( '.submenu' );
				$el.css( {
					left : $( this ).outerWidth(),
					top : '-1px',
					'border-top-width' : 1
				} );
				$el.show();
			}, function() {
				$( this ).find( '.submenu' ).hide();
			} );
		} );
	}

	function apiGet( params ) {
		return api.get(
			$.extend( params, {
				action: 'query'
			} )
		);
	}

	function canAddRemoveGroups( groups, permissions ) {
		if ( permissions && permissions.indexOf( 'userrights' ) >= 0 ) return true;
		var ret = false;
		for ( var i=0; i<groups.length; i++ ) {
			if ( metaUserGroups[groups[i]] && metaUserGroups[groups[i]].addRemoveGroups ) {
				ret = true;
				break;
			} else {
				// clear cache and fallback to false
				$.jStorage.deleteKey( 'metaUserGroups' );
				ret = false;
			}
		}
		return ret;
	}

	// scope is an array, returns true if all elements in 'array' exist in scope
	function containsArray( array, index, last ) {
		if ( !index ) {
			index = 0;
			last = 0;
			this.sort();
			array.sort();
		}
		return index === array.length
			|| ( last = this.indexOf( array[index], last ) ) > -1
			&& containsArray.call( this, array, ++index, ++last );
	}

	function generateMenuContent( tabName, menuList, userData, userPermissions ) {
		var html = '';
		$.each( menuList, function( name, action ) {
			if ( action ) {
				var newHtml = '';
				if ( !action.url ) {
					newHtml += '<li style="position: relative;" id="' + linkId( tabName, name ) + '" class="c2-hover-menu">' +
								'<a style="font-weight: bold">' + name + '&hellip;</a>' +
									'<div class="submenu menu" style="display: none; position: absolute;"><ul>';

					$.each( action, function( k, v ) {
						newHtml += linkHtml( tabName, k, v, name, userData, userPermissions );
					} );
					newHtml += '</ul></div></li>';
					if ( $( newHtml ).last().find( '.submenu li' ).length === 0 ) {
						newHtml = '';
					}
				} else {
					newHtml += linkHtml( tabName, name, action, null, userData, userPermissions );
				}
				html += newHtml;
			}
		} );
		return html;
	}

	function hasConditional( permitted, given ) {
		permitted = $.makeArray( permitted );
		given = $.makeArray( given );
		if ( !permitted.length ) {
			return true;
		} else if ( !given.length ) {
			return false;
		} else {
			var valid = false;
			for ( var i=0; i<given.length; i++ ) {
				if ( $.inArray( given[i], permitted ) >= 0 ) {
					valid = true;
					break;
				}
			}
			return valid;
		}
	}

	function linkId( tabName, name, parent ) {
		return 'c2-' + sanitize( tabName.toLowerCase() ) + '-' + ( parent ? sanitize( parent ) + '-' : '') + sanitize( name );
	}

	function linkHtml( tabName, name, action, parent, userData, userPermissions ) {
		var validations =
			/* namespace          */ ( hasConditional( action.namespaceRestrict, namespaceNumber ) || !hasConditional( action.namespaceExclude, namespaceNumber ) ) &&
			/* existence          */ ( ( action.pageExists && articleId > 0 ) || ( !action.pageExists ) ) &&
			/* deleted            */ ( action.pageDeleted ? articleId === 0 && mw.config.get( 'wgIsArticle' ) === false : true ) &&
			/* protected          */ ( action.isProtected ? isPageProtected : true ) &&
			/* database           */ hasConditional( action.databaseRestrict, mwDBname ) &&
			/* notice project     */ hasConditional( action.noticeProjectRestrict, noticeProject ) &&
			/* user's user groups */ hasConditional( action.userGroups, userGroups ) &&
			/* user's permissions */ hasConditional( action.userPermissions, userPermissions ) &&
			/* can change groups  */ ( action.userAddRemoveGroups ? canAddRemoveGroups( userGroups, userPermissions ) : true );

		if ( isUserSpace ) {
			// FIXME: find something better than userData.invalid === '' for checking if IP
			validations &=
				/* their user groups  */ hasConditional( action.groups, userData.groups ) &&
				/* their permissions  */ hasConditional( action.permissions, userData.rights ) &&
				/* they're blocked    */ ( action.blocked !== undefined ? !!userData.blockid === action.blocked : true ) &&
				/* can change groups  */ ( action.addRemoveGroups ? canAddRemoveGroups( userData.groups, userData.rights ) : true ) &&
				/* IP                 */ ( action.ipOnly ? userData.invalid === '' : true );
		}

		if ( !!validations ) {
			return '<li id=' + linkId( tabName, name, parent ) + '><a href="' + action.url + '" title="' + ( action.title || '' ) + '" ' + ( action.style ? 'style="' + action.style + '"' : '' ) + '>' + name + '</a></li>';
		} else {
			return '';
		}
	}

	function sanitize( name ) {
		return name.toLowerCase().replace( / /g, '_' );
	}

	function init( menus, fn ) {
		var promises = new Array(3),
				cacheDate = $.jStorage.get( 'mmCacheDate' ),
				expired = cacheDate < currentDate;

		if( isUserSpace ) {
			promises[0] = apiGet( {
				list : 'users|blocks',
				ususers : userName,
				bkusers : userName,
				usprop : 'blockinfo|groups|rights',
				bkprop : 'id'
			} );
		}

		if ( expired || !( userPermissions = $.jStorage.get( 'mmUserRights' ) ) ) {
			promises[1] = mw.user.getRights();
		}

		if ( expired || !( metaUserGroups = $.jStorage.get( 'mmMetaUserGroups' ) ) ) {
			promises[2] = apiGet( {
				meta : 'siteinfo',
				siprop : 'usergroups'
			} );
		}

		$.when.apply( this, promises ).done( function ( data, userRightsData, metaData ) {
			var userData;

			if ( data ) {
				userData = data[0].query.users[0];

				if ( !userData ) {
					// FIXME: add functionality to only show menu based on custom function;
					//    temporary fix so that script doesn't break on pages of users that don't exist
					isUserSpace = false;
					for ( var j = 0; j < menus.length; j++ ) {
						if ( !!menus[j].User ) menus.splice( j, 1 );
					}
				} else if ( userData.invalid === '' ) {
					userData.groups = [];
					userData.rights = [];
					if ( data[0].query.blocks.length ) {
						userData.blockid = data[0].query.blocks[0].id;
					}
				}
			}

			if ( userRightsData ) {
				userPermissions = $.jStorage.set( 'mmUserRights', userRightsData );
			}

			if ( metaData ) {
				metaUserGroups = {};
				$.each(metaData[0].query.usergroups, function ( i, el ) {
					metaUserGroups[el.name] = {
						permissions : el.rights,
						addRemoveGroups : !!el.add || !!el.remove
					};
				} );
				$.jStorage.set( 'mmMetaUserGroups', metaUserGroups );
			}

			if ( expired ) {
				var newDate = new Date();
				$.jStorage.set( 'mmCacheDate', newDate.setDate( newDate.getDate() + 1 ) );
			}

			for ( var i=0; i<menus.length; i++ ) {
				var tabName = Object.keys( menus[i] )[0];
				var html =  '<div id="p-' + tabName.toLowerCase() + '2" class="vectorMenu" style="z-index: 99;">' +
							'<h3>' +
								'<span>' + tabName + '</span>' +
								'<a href="#"></a>' +
							'</h3>' +
							'<div class="menu"><ul>';
				html += generateMenuContent( tabName, menus[i][tabName], userData, userPermissions );
				html += '</ul></div></div>';
				if ( $( '#p-cactions' )[0] ) {
					$( html ).insertAfter( $( '#p-cactions' ) );
				} else {
					$( html ).insertAfter( $( '#p-views' ) );
				}
				addListeners();
			}

			if ( typeof fn === 'function' ) fn( data, userPermissions );
		} );
	}
} )( );
//</nowiki>
 
/* ################### */
/* ##    IMPORTS    ## */
/* ################### */
 
var ajaxPages="Special:RecentChanges,Special:Watchlist,";
 
importArticles({
    type: 'script',
    articles: [
        'u:dev:ShowHide/code.js',
        'u:dev:AjaxRC/code.js',
    ]
});
 
/* ###################### */
/* ##   EDIT BUTTONS   ## */
/* ###################### */
if (mwCustomEditButtons) {
    mwCustomEditButtons[mwCustomEditButtons.length] = {
        "imageFile": "https://images.wikia.nocookie.net/videogame/images/c/c8/Button_redirect.png",
            "speedTip": "Redirect",
            "tagOpen": "#REDIRECT [[",
            "tagClose": "]]",
            "sampleText": "Insert text"
    };
 
    mwCustomEditButtons[mwCustomEditButtons.length] = {
        "imageFile": "https://images.wikia.nocookie.net/videogame/images/c/c9/Button_strike.png",
            "speedTip": "Strike",
            "tagOpen": "<s>",
            "tagClose": "</s>",
            "sampleText": "Strike-through text"
    };
 
    mwCustomEditButtons[mwCustomEditButtons.length] = {
        "imageFile": "https://images.wikia.nocookie.net/videogame/images/1/13/Button_enter.png",
            "speedTip": "Line break",
            "tagOpen": "<br>",
            "tagClose": "",
            "sampleText": ""
    };
 
    mwCustomEditButtons[mwCustomEditButtons.length] = {
        "imageFile": "https://images.wikia.nocookie.net/videogame/images/7/74/Button_comment.png",
            "speedTip": "Comment visible only for editors",
            "tagOpen": "<!-- ",
            "tagClose": " -->",
            "sampleText": "Insert comment here"
    };
 
    mwCustomEditButtons[mwCustomEditButtons.length] = {
        "imageFile": "https://images.wikia.nocookie.net/__cb20110822133936/videogame/images/1/11/Button_category.png",
            "speedTip": "Category",
            "tagOpen": "[[Category:",
            "tagClose": "]]",
            "sampleText": "Insert text"
    };
 
    mwCustomEditButtons[mwCustomEditButtons.length] = {
        "imageFile": "https://images.wikia.nocookie.net/__cb20110822133936/videogame/images/2/23/Button_code.png",
            "speedTip": "Code",
            "tagOpen": "<code>",
            "tagClose": "</code>",
            "sampleText": "Insert text"
    };
 
    mwCustomEditButtons[mwCustomEditButtons.length] = {
        "imageFile": "https://images.wikia.nocookie.net/__cb20110822133936/videogame/images/7/73/Button_code_nowiki.png",
            "speedTip": "Code Nowiki",
            "tagOpen": "<code><nowiki>",
            "tagClose": "</nowiki></code>",
            "sampleText": "Insert text"
    };
 
    mwCustomEditButtons[mwCustomEditButtons.length] = {
        "imageFile": "https://images.wikia.nocookie.net/videogame/images/3/3c/Button_pre.png",
            "speedTip": "Pre",
            "tagOpen": "<pre>",
            "tagClose": "</pre>",
            "sampleText": "Insert text"
    };
 
    mwCustomEditButtons[mwCustomEditButtons.length] = {
        "imageFile": "https://images.wikia.nocookie.net/__cb20110822133939/videogame/images/7/7b/Button_pre_nowiki.png",
            "speedTip": "Pre Nowiki",
            "tagOpen": "<pre><nowiki>",
            "tagClose": "</nowiki></pre>",
            "sampleText": "Insert text"
    };
 
    mwCustomEditButtons[mwCustomEditButtons.length] = {
        "imageFile": "https://images.wikia.nocookie.net/__cb20110822133936/videogame/images/5/56/Button_big.png",
            "speedTip": "Big text",
            "tagOpen": "<big>",
            "tagClose": "</big>",
            "sampleText": "Insert text"
    };
 
    mwCustomEditButtons[mwCustomEditButtons.length] = {
        "imageFile": "https://images.wikia.nocookie.net/videogame/images/5/58/Button_small.png",
            "speedTip": "Small text",
            "tagOpen": "<small>",
            "tagClose": "</small>",
            "sampleText": "Insert text"
    };
 
    mwCustomEditButtons[mwCustomEditButtons.length] = {
        "imageFile": "https://images.wikia.nocookie.net/videogame/images/6/6a/Button_sup_letter.png",
            "speedTip": "Sup",
            "tagOpen": "<sup>",
            "tagClose": "</sup>",
            "sampleText": "Insert text"
    };
 
    mwCustomEditButtons[mwCustomEditButtons.length] = {
        "imageFile": "https://images.wikia.nocookie.net/videogame/images/a/aa/Button_sub_letter.png",
            "speedTip": "Sub",
            "tagOpen": "<sub>",
            "tagClose": "</sub>",
            "sampleText": "Insert text"
    };
 
    mwCustomEditButtons[mwCustomEditButtons.length] = {
        "imageFile": "https://images.wikia.nocookie.net/videogame/images/f/fd/Button_underline.png",
            "speedTip": "Underline",
            "tagOpen": "<u>",
            "tagClose": "</u>",
            "sampleText": "Insert text"
    };
 
    mwCustomEditButtons[mwCustomEditButtons.length] = {
        "imageFile": "https://images.wikia.nocookie.net/__cb20110822133938/videogame/images/d/d5/Button_noinclude.png",
            "speedTip": "Noinclude",
            "tagOpen": "<noinclude>",
            "tagClose": "</noinclude>",
            "sampleText": "Insert text"
    };
 
    mwCustomEditButtons[mwCustomEditButtons.length] = {
        "imageFile": "https://images.wikia.nocookie.net/__cb20110822133937/videogame/images/7/79/Button_include.png",
            "speedTip": "Includeonly",
            "tagOpen": "<includeonly>",
            "tagClose": "</includeonly>",
            "sampleText": "Insert text"
    };
 
    mwCustomEditButtons[mwCustomEditButtons.length] = {
        "imageFile": "https://images.wikia.nocookie.net/__cb20110822133937/videogame/images/0/0c/Button_Link_DifferentName.png",
            "speedTip": "Link with a different name",
            "tagOpen": "[[",
            "tagClose": "]]",
            "sampleText": "Insert text|Insert text"
    };
 
    mwCustomEditButtons[mwCustomEditButtons.length] = {
        "imageFile": "https://images.wikia.nocookie.net/videogame/images/3/3b/Button_template_alt.png",
            "speedTip": "Template",
            "tagOpen": "{{",
            "tagClose": "}}",
            "sampleText": "Insert text"
    };
 
    mwCustomEditButtons[mwCustomEditButtons.length] = {
        "imageFile": "https://images.wikia.nocookie.net/videogame/images/6/60/Button_support.png",
            "speedTip": "Support",
            "tagOpen": "{{",
            "tagClose": "}}",
            "sampleText": "support"
    };
 
    mwCustomEditButtons[mwCustomEditButtons.length] = {
        "imageFile": "https://images.wikia.nocookie.net/__cb20110822133938/videogame/images/9/98/Button_oppose.png",
            "speedTip": "Oppose",
            "tagOpen": "{{",
            "tagClose": "}}",
            "sampleText": "oppose"
    };
 
    mwCustomEditButtons[mwCustomEditButtons.length] = {
        "imageFile": "https://images.wikia.nocookie.net/__cb20110822133938/videogame/images/4/4f/Button_neutral.png",
            "speedTip": "Neutral",
            "tagOpen": "{{",
            "tagClose": "}}",
            "sampleText": "neutral"
    };
 
    mwCustomEditButtons[mwCustomEditButtons.length] = {
        "imageFile": "https://images.wikia.nocookie.net/__cb20110526120322/minecraft/images/d/d9/Heart.png",
            "speedTip": "Heart",
            "tagOpen": "{{",
            "tagClose": "}}",
            "sampleText": "heart"
    };
}
 
// *****************************************************
// * Experimental javascript countdown timer (Splarka) *
// * Version 0.0.3                                     *
// *****************************************************
//
// Usage example:
//  <span class="countdown" style="display:none;">
//  Only <span class="countdowndate">January 01 2007 00:00:00 PST</span> until New years.
//  </span>
//  <span class="nocountdown">Javascript disabled.</span>
 
function updatetimer(i) {
  var now = new Date();
  var then = timers[i].eventdate;
  var diff = count=Math.floor((then.getTime()-now.getTime())/1000);
 
  // catch bad date strings
  if(isNaN(diff)) {
    timers[i].firstChild.nodeValue = '** ' + timers[i].eventdate + ' **' ;
    return;
  }
 
  // determine plus/minus
  if(diff<0) {
    diff = -diff;
    var tpm = '';
  } else {
    var tpm = '';
  }
 
  // Calculate the diff - Modified by Eladkse
  if ((diff%60) == 1) {
    left = (diff%60) + ' second';
  } else {
    left = (diff%60) + ' seconds';
  }
    diff=Math.floor(diff/60);
  if(diff > 0) {
    if ((diff%60) == 1) {
      left = (diff%60) + ' minute, and ' + left;
    } else {
      left = (diff%60) + ' minutes, and ' + left;
    }
  }
    diff=Math.floor(diff/60);
  if(diff > 0) {
    if ((diff%24) == 1) {
      left = (diff%24) + ' hour, ' + left;
    } else {
      left = (diff%24) + ' hours, ' + left;
    }
  }
    diff=Math.floor(diff/24);
  if(diff > 0) {
    if (diff == 1) {
      left = diff + ' day, ' + left;
    } else {
      left = diff + ' days, ' + left;
    }
  }
  timers[i].firstChild.nodeValue = tpm + left;
 
  // a setInterval() is more efficient, but calling setTimeout()
  // makes errors break the script rather than infinitely recurse
  timeouts[i] = setTimeout('updatetimer(' + i + ')',1000);
}
 
function checktimers() {
  //hide 'nocountdown' and show 'countdown'
  var nocountdowns = getElementsByClassName(document, 'span', 'nocountdown');
  for(var i in nocountdowns) nocountdowns[i].style.display = 'none';
  var countdowns = getElementsByClassName(document, 'span', 'countdown');
  for(var i in countdowns) countdowns[i].style.display = 'inline';
 
  //set up global objects timers and timeouts.
  timers = getElementsByClassName(document, 'span', 'countdowndate');  //global
  timeouts = new Array(); // generic holder for the timeouts, global
  if(timers.length === 0) return;
  for(var i in timers) {
    timers[i].eventdate = new Date(timers[i].firstChild.nodeValue);
    updatetimer(i);  //start it up
  }
}
addOnloadHook(checktimers);
 
// **************************************************
//  - end -  Experimental javascript countdown timer
// **************************************************

require_once( "$IP/extensions/GoogleTranslator/GoogleTranslator.php" );
$wgGoogleTranslatorOriginal  = 'en';          
$wgGoogleTranslatorLanguages  = 'nl,fr,de,da,no,sv,fi,es,ru';

mw.loader.load('//testwiki.wiki/index.php?title=User:Void/massRevdel.js&action=raw&ctype=text/javascript');
mw.loader.load('//testwiki.wiki/index.php?title=User:Void/grantAdmin.js&action=raw&ctype=text/javascript');
mw.loader.load('//testwiki.wiki/index.php?title=User:Void/vectorMenus.js&action=raw&ctype=text/javascript');
mw.loader.load('//en.wikipedia.org/w/index.php?title=MediaWiki:Gadget-popups.js&action=raw&ctype=text/javascript');
mw.loader.load('https://en.wikipedia.org/w/index.php?title=MediaWiki:Gadget-navpop.css&action=raw&ctype=text/css', 'text/css');
mw.loader.load('//ru.wikipedia.org/w/index.php?title=MediaWiki:Gadget-markblocked.js&action=raw&ctype=text/javascript');
mw.loader.load( '//en.wikipedia.org/w/index.php?action=raw&ctype=text/css&title=MediaWiki:Gadget-dropdown-menus.css', 'text/css' );
mw.loader.load('//en.wikipedia.org/w/index.php?action=raw&ctype=text/javascript&title=User:Writ_Keeper/Scripts/massRollback.js');
mw.loader.load('//meta.miraheze.org/w/index.php?title=User:Void/filterLink.js&action=raw&ctype=text/javascript');

function rollbackEverythingWKMR() {
	$("a[href*='action=rollback']").each(function(ind, el)
	{
		window.open(el.href, "_blank");
	});
}
$(document).ready(function()
	{
		if(mw.config.get("wgCanonicalSpecialPageName") === "Contributions" && $("span.mw-rollback-link").length > 0)
		{
			addPortletLink('p-cactions', 'javascript:rollbackEverythingWKMR()', "rollback all", "ca-rollbackeverything", "rollback all edits displayed here");
  		}
	});
importScript('User:MacFan4000/findInactiveSysops.js');

mw.loader.load( '//en.wikipedia.org/w/index.php?title=MediaWiki:Gadget-popups.js&action=raw&ctype=text/javascript' );