Year of the Dragon: Through May 28th, claim free Expansion Pack (excluding Vecna Unleashed) or a Greater Elixir of Discovery! Speak to Xatheral in the Hall of Heroes. edit
Game mechanics • Newbie guide • In development • DDO Store • Social Media
Challenges • Classes • Collectables • Crafting • Enhancements • Epic Destinies • Favor • Feats
Glossary • Items • Maps • Monsters • Places • Quests • Races • Reincarnation • Skills • Spells
Please create an account or log in to build a reputation and unlock more editing privileges, and then visit DDO wiki's IRC Chat/Discord if you need any help!
MediaWiki:Gadget-vectorMenu.js
Jump to navigation
Jump to search
Note: After saving, you may have to bypass your browser's cache to see the changes, you can click here or try one of the methods below..
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl+F5 or Ctrl+r (⌘ Command+r on a Mac)
- Google Chrome: Press Ctrl+⇧ Shift+R (⌘ Command+⇧ Shift+R on a Mac)
- Internet Explorer: Hold Ctrl while clicking Refresh, or press Ctrl+F5
- Konqueror: Click Reload or press F5
- Opera: Clear the cache in Tools ‣ Preferences
/**********************************************************************
** ***WARNING: GLOBAL GADGET FILE*** **
** any changes to this file will affect many users **
** please discuss changes on the talk page **
** (consider dropping the script author a note as well...) **
**********************************************************************
** SOURCED BY [[MediaWiki:Gadget-vectorMenu.js]] **
**********************************************************************/
//<nowiki>
// Version : 1.0
// Author : [[U:Technical 13]]
// Script : [[MW:Gadget-vectorMenu.js]]
// Description : [[MWt:Gadget-vectorMenu]]
// Documentation : [[MW:Gadget-vectorMenu]]
// GitHub :
// Prerequisites : MediaWiki version 1.8 or higher
// jStorage via ResourceLoader
// Any modern browser or IE8+
// Based on : https://github.com/MusikAnimal/MoreMenu v4.3.2
// ( http://enwp.org/User:MusikAnimal/MoreMenu docs )
//
// Text available under the Creative Commons Attribution-ShareAlike License (CC BY-SA 3.0)
//
( function( mw, $ ) {
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( 'wgServer' ),
siteName = mw.config.get( 'wgSiteName' ),
userGroups = mw.config.get( 'wgUserGroups' ),
contentLanguage = mw.config.get( 'wgContentLanguage' ),
articleId = mw.config.get( 'wgArticleId' ),
mwDBname = mw.config.get( 'wgDBname' ),
pageName = mw.config.get( 'wgPageName' ),
actionType = mw.config.get( 'wgAction' ),
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();// Admin stuff
$( '#ca-move' ).remove();// Everyone has a move link
if ( mw.user.options.get( 'gadget-wikEd' ) !== '1' ) {// wikEd bug workaround...
$( '#ca-purge,#p-cactions' ).remove();//Remove purge and empty menu if not using wiEd.
}
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' ]
},
'Deletion log' : {
url : mw.util.getUrl( 'Special:Log', { action: 'view', user: userName, type: 'delete' } ),
permissions : [ 'delete' ]
},
'Move log' : {
url : mw.util.getUrl( 'Special:Log', { action: 'view', user: userName, type: 'move' } ),
permissions : [ 'move' ]
},
'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' ]
},
'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'
},
},*/
'Blocks' : {
'Block user' : {
url : mw.util.getUrl( 'Special:Block/' + userName ),
userPermissions : 'block',
blocked : false
},
'Change block' : {
url : mw.util.getUrl( 'Special:Block/' + userName ),
userPermissions : 'block',
blocked : true
},
'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' } )
}
},
'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' ]
},
}
};
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' } )
},
'Protection log' : {
url : mw.util.getUrl( 'Special:Log', { action: 'view', page: pageName, type: 'protect' } )
}
},/*
'XfDs' : {
url : 'javascrit:void(0)'
},*/
'Protect page' : {
url : serverName + '/index.php?title=' + encodedPageName + '&action=protect',
userPermissions : [ 'protect', 'stablesettings' ]
},
'Change protection' : {
url : mw.util.getUrl( pageName, { action: 'protect' } ),
userPermissions : [ 'protect', 'stablesettings' ],
isProtected : true
},
'Delete page' : {
url : serverName + '/index.php?title=' + encodedPageName + '&action=delete' + ( $( '#delete-reason' ).text() ? '&wpReason=' + $( '#delete-reason' ).text() : ''),
userPermissions : [ 'delete' ],
pageExists : true
},
'Undelete page' : {
url : mw.util.getUrl( 'Special:Undelete/' + pageName ),
userPermissions : [ 'undelete' ],
pageDeleted : true
},
'Edit intro' : {
url : serverName + '/index.php?title=' + encodedPageName + '&action=edit§ion=0',
namespaceRestrict : [ 0, 1, 2, 3, 4, 5, 500, 501 ],
pageExists : true
},
'Latest diff' : {
url : mw.util.getUrl( pageName, { action: 'view', diff: mw.config.get( 'wgCurRevisionId' ) } ),
pageExists : true
},
'Move page' : {
url : mw.util.getUrl( 'Special:MovePage/' + pageName ),
userPermissions : [ 'move' ],
pageExists : true
},
'Purge cache' : {
url : mw.util.getUrl( pageName, { action: 'purge', forcelinkupdate: true } ),
pageExists : true
},
'Compare page' : {
url : mw.util.getUrl( 'Special:ComparePages', { page1: pageName, page2: ( pageName.substr( 0, pageName.indexOf( '/' ) ) || pageName ) } ),
pageExists : true
}/*,
'Subpages' : {
url : mw.util.getUrl( 'Special:PrefixIndex/' + pageName + '/' ),
},*/// Not yet available, but I want it to be.
}
};
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();
$( '#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 = {
'DDO:Requests for adminship' : 'rfas',
'DDO:Requests for bureaucratship' : 'rfbs',
};
$( '#c2-user-rfxs' ).hide();*/
}
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 + '…</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() + 7 ) );
}
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="#" title="' + tabName + '"></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 );
} );
}
} )( mediaWiki, jQuery );
//</nowiki> [[C:Gadgets]]