User:PassionFruitMaster/global.js

/** * This file loads for myself. * For skin specific variants see User:StrawberryMaster/monobook.js and User:StrawberryMaster/wikia.js * for monobook and oasis respectively * * Please test any changes made to this file. * Jshint  can catch syntax errors to help testing. * Alternatively, Wikia's code editor has jshint embedded to make life extra simple. * * The scripts here follow Wikia JS guidelines or MediaWiki coding standards where the Wikia * guidelines do not specify: * -  * -  * * The scripts have extremely high usage across Wikia, please do not deploy without * extensive testing. Be aware that these scripts must be ES3 compliant due to the * minifier used by ResourceLoader. * * The majority of the scripts here are for personal use as they modify parts of the Oasis/Monobook skin violating Wikia's Terms of Use. * * Some of the scripts here were taken from: Iynque, Dorumin, Slyst and Cqm, alongside GitHub and the Dev Wiki. * * Note: Update global.js version at the end of the page. As of June 29, 2016, it is version 52. */ /* global mw, wgServer, wgScriptPath, wgPageName, wgArticleId, wgAction, importArticles:true, href:true, link:true, specialpage /* jshint bitwise:true, browser:true, camelcase:true, curly:false, devel:true, eqeqeq:true, es5:true, forin:true, immed:true, jquery:true, latedef:true, newcap:true, noarg:true, noempty:true, nonew:true, onevar:false, plusplus:true, quotmark:single, undef:true, unused:false, strict:true, trailing:true asi:true, boss:true, debug:true, eqnull:true, evil:true, expr:true, lastsemic:true, loopfunc:true, moz:true, proto:true, scripturl:true /* -- */ /* ================================ Settings ================================ */ /* ======== Header slightly modified from Iynque.  ========= */ /* -- */ /* Some settings and tweaks. * Something I found on Ozuzanna's global.js.  */ (function ($, mw) { var c = mw.config.get ([ 'wgAction', 'wgArticlePath', 'wgCanonicalNamespace', 'wgCanonicalSpecialPageName', 'wgNamespaceNumber', 'wgPageName', 'wgUserGroups', 'wgSiteName', 'skin', 'wgTitle' ]), articlePath = c.wgArticlePath.slice (0, -2), escapedPage = encodeURIComponent (c.wgPageName), str, array = []; switch (c.wgCanonicalSpecialPageName) {	/* Add IP range calculator and lookup link to Special:Block for IPs */	case "Block":		if ($('.mw-ipb-conveniencelinks a').text.indexOf('Contributions for') === -1) {			str = c.wgPageName.match(/((?:\d{1,3}\.){3}\d{1,3})/)[0];			$('.visualClear').before(' (lookup | range calc)');		}		$('#mw-input-wpHardBlock').attr('checked','checked');	break;	/* Compile list of videos listed on Special:UnusedVideos and Special:UnusedFiles */	case "UnusedVideos":	case "Unusedimages":			$('.mw-spcontent p:first').after('Compile');		$('#btn-compile').click(function { array = []; $('.gallerytext').each(function {				if (!/File missing/gi.test($(this).text))					array.push($(this).find('a').attr('title'));			}); alert(array.sort.join('\n').trim); });	break;	/* Add IP lookup on anon contribs */	case "Contributions":		if (c.wgTitle.split('.').length == 4)			$('.masthead-info h2').html('(lookup)');	break;	/* Create an edit link on Special:MovePage */		case "Movepage":		$('#mw-movepage-table').find('a').first.after(' (edit)');	break;	/* Add edit link to Special:WhatLinksHere listings */	case "Whatlinkshere":		$('#mw-whatlinkshere-list li').find('a:first').each(function { $(this).parent.find('a:last').before('edit</a> | '); });	 	break;	/* Special:SearchDigest better functionality */	case "SearchDigest":		$('#mw-content-text ul li').each(function { if ($(this).find('a').attr('title').indexOf('(page does not exist)') === -1) $(this).remove; });	break;	/* Dupe file list markup */	case "Blankpage":		if ($.getUrlVar('blankspecial') === 'listdupefiles') {			document.title = 'Duplicate Files';			$('#mw-content-text').html(' ');			importScriptPage('MediaWiki:DupImageList/code.js', 'dev');		}	break;	/* Make sure when using CheckUser on IPs, it always has users selected by default rather than edits */	case "CheckUser":		if ($.getUrlVar('user').split('.').length == 4)			$('#subipusers').attr('checked','checked');	break;	/* Add links for chatconnect log and CU on CheckUser Log user entries; replace MultiLookup with local contribs */	case "CheckUserLog":		$('#mw-content-text ul li').each(function { if (!$(this).children('.mw-usertoollinks').length) { $(this).children('a:last').attr('href', articlePath + 'Special:Contributions/' + $(this).children('a:last').attr('href').split('?target=')[1]); $(this).children('a:last').after(' (check</a>)'); }		});		$('#mw-content-text ul li .mw-usertoollinks').each(function { $(this).children('a:last').after(' | connect</a> | check</a>'); });	break;	/* Add confirmation window when making users bureaucrats due to unable to undo */	case "Userrights":		var bcratBefore = $('#wpGroup-bureaucrat:checked').length;		$('input[name="saveusergroups"]').click(function(e) { if (!bcratBefore && $('#wpGroup-bureaucrat:checked').length) { e.preventDefault; $.showCustomModal('Confirm', 'You are making this user a bureaucrat. Please ensure this is what you intended before confirming, as it cannot be undone.', {					id: 'bureaucrat-confirm',					width: 660,					buttons: [{						message: 'Confirm',						defaultButton: true,						handler: function {							$('#mw-userrights-form2').submit;							$('#bureaucrat-confirm').closeModal;						}					},{		 						message: 'Cancel',						handler: function {							$('#bureaucrat-confirm').closeModal;						}					}]				}); }		});	break; } /* Unchecks redirects when moving files */ if (c.wgPageName.indexOf("Special:MovePage/File:") !== -1)	$('#wpLeaveRedirect').removeAttr('checked'); /* Show abuse log entries in Special:Log/newusers */ if ("Special:Log/newusers".indexOf(c.wgPageName) !== -1) {	$('.mw-logline-newusers').each(function { $(this).find('.mw-usertoollinks').find('a:last').after(' | abuse</a>'); }); } /* Revision delete */ if (c.wgAction == 'revisiondelete' || c.wgCanonicalSpecialPageName == 'Revisiondelete') {	$('#wpHidePrimary,#wpHideComment,#wpHideUser').attr('checked','checked');	$('#wpReason').val('spam'); } /* Thread history return to thread */ if (c.wgCanonicalNamespace == "Thread" && c.wgAction == "history")	$('.SortingBar').after('Back to thread</a>'); /* Make Visual Editor links load the regular editor instead */ /* if ($.getUrlVar('veaction') == 'edit')	location.replace(document.URL.replace('veaction','action')); /* Special:WhatLinksHere on redirect page */ if ($('#WikiaPageHeader h2').text.indexOf('Redirected from') != -1)	$('#WikiaPageHeader h2').append(' (links)</a> (history)</a>'); /* Add link to chatconnect per banned user for MLP chat ban log */ if ("Special:Log/chatban".indexOf(c.wgPageName) !== -1 && c.wgSiteName == "Floyd's Testing Wikia") { $('.mw-logline-chatban').each(function {		$(this).find('.mw-usertoollinks:last').find('a:last').after(' | connect</a>');	}); } /* Always go to IP contributions, not userpage */ if (c.wgNamespaceNumber == 2 && c.wgTitle.split('.').length == 4) location.replace(articlePath + 'Special:Contributions/' + c.wgTitle); /* Remove Help:Contents from dropdown thing */ if ($('#globalNavigation').length) $('.user-menu.subnav li:nth-child(3),.hubs-entry-point').remove; /* Auto-submit bugged pages for deletion */ if (c.wgAction == "delete" && $('#ca-edit').text.trim == "Create") $('#mw-img-deleteconfirm,#deleteconfirm').submit; /* Create dupe file list button */ if (c.skin === 'monobook') { mw.util.addPortletLink('p-tb', '/index.php?title=Special:BlankPage&blankspecial=listdupefiles', 'List dupe files', 't-ld'); } else { $('#my-tools-menu').prepend(' List dupe files</a></li>'); } /* Untick minor edit box after 10 seconds when editing */ if (c.wgAction === 'edit' || c.wgAction === 'submit') { setTimeout(function {		if ($('#wpMinoredit').attr('Checked')) 			$('#wpMinoredit').removeAttr('checked');	}, 10000); } /* Add "show most recent" notice to message notifications when not on the same wiki */ if ($('#WikiaNotifications li div[data-type="1"]').length && $('#WikiaNotifications li div[data-type="1"] a:last').attr('href').slice(0,6) != "/wiki/") $('#WikiaNotifications li div[data-type="1"]').append(' (show most recent</a>)'); }) (this.jQuery, this.mediaWiki); /* Adds an 'AJAX UNDO' link next into the undo link on page histories/diff pages. * Something I found on Dorumin's global.js. <c:User:Dorumin/global.js> * See w:c:dev:AjaxUndo (stable?) for info & attribution. */ jQuery(document).ready(function($) { 'use strict'; function createUndoLink(diffUndoUrl) { var $ajaxUndoLink = $('').text('AJAX Undo').attr('href', '#').click(function {           var $ajaxUndoLinkob = $(this),                undoIdRegex = /&undo=([^&]*)/,                undoId = undoIdRegex.exec(diffUndoUrl)[1],                editToken,                etUrl = wgServer + wgScriptPath + '/api.php?action=query&prop=info|revisions&intoken=edit&titles=' + encodeURIComponent(wgPageName) + '&format=json',                usrUnd = $('#mw-diff-ntitle2 .mw-userlink').html,                smry = prompt('Undo summary', 'Undo revision ' + undoId + ' by ' + usrUnd + ' (talk)');                if (smry === null) return;                else if (!smry) smry = 'Undo revision ' + undoId + ' by ' + usrUnd + ' (talk)';            $ajaxUndoLinkob.html(' <img src="http://images2.wikia.nocookie.net/dev/images/8/82/Facebook_throbber.gif" style="vertical-align: baseline;" border="0" alt="Undoing..." />');           $.getJSON(etUrl, function(data) { editToken = data.query.pages[wgArticleId].edittoken; $.ajax({                   url: wgScriptPath + '/api.php?',                    data: 'action=edit&format=json&title=' + encodeURIComponent(wgPageName) + '&undo=' + encodeURIComponent(undoId) + '&bot=1&summary=' + encodeURIComponent(smry) + '&token=' + encodeURIComponent(editToken),                    dataType: 'json',                    type: 'POST',                    success: function(data) {                        if (data.edit && data.edit.result === 'Success') {                            $ajaxUndoLinkob.text('(undone)');                        } else if (data.error && data.error.code === 'undofailure') {                            $ajaxUndoLinkob.text('(error)');                            alert(data.error.info);                        } else {                            $ajaxUndoLinkob.text('(error)');                            alert('Error: Unknown result from API.'); }                   },                    error: function { $ajaxUndoLinkob.text('(error)'); }               });            });        });        return $ajaxUndoLink;    }    if ($('.mw-history-undo > a').length && wgAction === 'history') {        $('.mw-history-undo > a').each(function { var diffUndoUrl = $(this).attr('href'), $ajaxUndoLink = createUndoLink(diffUndoUrl); $(this).replaceWith($ajaxUndoLink); });   } else if ($('table.diff').length && typeof $.getUrlVar('diff') !== 'undefined') {        var $diffUndoLink = $('table.diff').find('.diff-ntitle > #mw-diff-ntitle1 a:last'),            diffUndoUrl = $diffUndoLink.attr('href'),            $ajaxDiffUndoLink = createUndoLink(diffUndoUrl);        $diffUndoLink.replaceWith($ajaxDiffUndoLink);    } }); /* -- */ /* Script settings. */ /* Header slightly modified from Iynque. <w:c:User:Iynque> - */ /* -- */ /* Auto updating recent changes opt-in. * Something I found on Dorumin's global.js. <c:User:Dorumin/global.js> * See w:c:dev:AjaxRC for info & attribution. */ window.ajaxPages = ['Blog:Recent_posts', 'Special:RecentChanges', 'Special:WikiActivity', 'Special:Chat', 'Special:Watchlist', 'Special:Log', 'Special:Log/upload', 'Special:Contributions']; window.ajaxIndicator = 'http://vignette2.wikia.nocookie.net/dev/images/8/82/Facebook_throbber.gif'; window.ajaxRefresh = 30000; window.AjaxRCRefreshText = 'Auto-refresh'; window.AjaxRCRefreshHoverText = 'Automatically refresh the page'; /* Vector skin configuration. * See w:c:dev:Pseudo-Vector JS for info & attribution. */ window.pseudoVector = { loadCss: true, addReadTab: true, addContributionsTab: true, disableWatchIcon: false, newDiffStyle: true }; /* Removes backlinks from pages. * See w:c:dev:Linksweeper for info & attirbution. */ window.linkSweepConfirmation = true; window.LinkSweeperDelay = 1000; /* Places "QuickToolsv2" button on the "My Tools" section. * Something I found on Zmario's global.js. <c:User:Zmario/global.js> * See w:c:dev:QuickToolsv2 for info & attribution. */ window.QuickToolsAdvancedtop = true; /** * Import JavaScript and Stylesheet articles from any wiki. * @author Kyle Florence <kflorence@wikia-inc.com> * * >> Examples: * * // Importing a single Stylesheet from the local wiki * importArticle({ *    type: "style", *     article: "Mediawiki:MyCustomStyles.css" * }); * * // Importing multiple JavaScript files from an external wiki * importArticles({ *    type: "script", *     articles: [ *         "Mediawiki:MyCustomJavaScript.js", *         "w:starwars:Mediawiki:External.js" *     ] * }); * * @param {...Object} Any number of modules to load. * @returns {Array} An array of DOM nodes used for injection. */ importArticles({	type: 'script',	articles: [           // ...            'u:dev:MediaWiki:AjaxRC/code.js', // Special:RecentChanges live update            'u:dev:MediaWiki:AjaxBatchDelete/code.2.js', // Batch delete            'u:dev:MediaWiki:AjaxBatchUndelete.js',            // 'u:dev:MediaWiki:AjaxBlock/code.js', // Blocks users quickily              // -- ↳ temporarily disabled while modified code is here (above) --                // - ↳↳ enabled again, for now -            'u:dev:MediaWiki:AjaxPatrol/code.js',            'u:dev:MediaWiki:ArchiveTool/code.js',            'u:dev:MediaWiki:DisplayClock/code.js', // Show UTC clock            // 'u:dev:MediaWiki:FastDelete/beta.js',               // ↳ disabled while another code is here (below)            'u:dev:MediaWiki:Linksweeper/code.js',            'u:dev:MediaWiki:MassBlock/code.js',            // 'u:dev:MediaWiki:MassCategorization/code.js', // ↳ testing new beta 'u:dev:MediaWiki:MassProtect/code.js', 'u:dev:MediaWiki:MassRename/code.js', 'u:dev:MediaWiki:MassUserRights/code.js', 'u:dev:MediaWiki:Pseudo-Vector.js', 'u:dev:MediaWiki:QuickCreateUserPage/code.js', 'u:dev:Mediawiki:QuickToolsv2/code.js', // Quick tools // ↳ Not used very often; Wikimarks handles a lot of this anyway 'u:dev:MediaWiki:ThreadIndicator/code.js', // Indicates thread stats // 'u:dev:MediaWiki:WHAM/code.2.js' // Quick tools 'u:dev:User:Dorumin/wikia.js' // betas here // ...	] });

// these have to be defined here for reasons I don't understand // Monch tells me IFFE's can mess with the run order of js but neither of us know why or how // #confused function importScriptPage( p, w ) { var s = document.createElement( 'script' ); s.type = 'text/javascript'; s.src = 'http://' + w + '.wikia.com/index.php?title=' + p.replace( / /g, '_' ) + '&action=raw&ctype=text/javascript&maxage=0&smaxage=0'; document.getElementsByTagName( 'body' )[0].appendChild( s ); } function importScript( p ) { var s = document.createElement( 'script' ); s.type = 'text/javascript'; s.src = '/index.php?title=' + p.replace( / /g, '_' ) + '&action=raw&ctype=text/javascript&maxage=0&smaxage=0'; document.getElementsByTagName( 'body' )[0].appendChild( s ); }

/* loading chat plugins globally */ ChatEntryPoint.onClickChatButton = function { var welp = window.open('/wiki/Special:Chat', 'wikiachat', mw.config.get('wgWikiaChatWindowFeatures')); welp.onload = function { var s = document.createElement('script'); s.type = 'text/javascript'; s.src = 'http://hypotheticalhurricanes.wikia.com/wiki/User:PassionFruitMaster/chat.js?action=raw&ctype=text/javascript&cb=' + new Date.getTime; welp.document.head.appendChild(s); }; } ( function ( $, mw, importArticles ) {   'use strict';    var self = {        /**         * @desc Loads functions conditionally         */        init: function  {            var config = mw.config.get( [ 'wgCanonicalSpecialPageName', 'wgNamespaceNumber', 'wgTitle' ] );           self.imports;            if ( $( '#UserProfileMasthead' ).length ) {                self.mastheadEditcount;            }            if ( config.wgCanonicalSpecialPageName === 'Movepage' && ( /File/ ).test( config.wgTitle ) ) {               self.uncheckFileRedirects;            }            if ( config.wgNamespaceNumber === 6 && !$( '#file > a' ).length ) {                self.removeAutoplay;            }            if ( $( '[src*="youtube.com"]' ).length ) {                self.switchAutoplay;            }        },        /**         * @desc Defines variables for imported scripts and import said scripts         *         * @author Cqm         */        imports: function  {            var fdButtons = [],                scripts = [],                config = mw.config.get( [ 'wgAction', 'wgCityId', 'wgCanonicalSpecialPageName', 'wgNamespaceNumber' ] );            /**             * Setup globals vars here             */            // fastdelete buttons            fdButtons[ fdButtons.length ] = { summary: 'Housekeeping', label: 'HK' };            // for rswiki only // if ( config.wgCityId === '304' ) { //   fdButtons[ fdButtons.length ] = { summary: 'Successful RfD', label: 'RfD' }; // }           // add as global window.fdButtons = fdButtons; /**            * Create an array of scripts to be imported conditionally * See imported pages for documentation * @todo Find a way to turn these on/off from console or something */           // always load these scripts.push(               // CSS testing input                'u:dev:PortableCSSPad/code.js',                // Customisable On The Wiki tab                // 'u:dev:MediaWiki:Wikimarks/code.js',                // Nuke script.                'u:dev:MediaWiki:Nuke/code.js',                // Fix search for Special pages                'u:rs:User:Cqm/specialsearchfix.js'            ); if ( config.wgAction === 'view' ) { scripts.push(                   // Icon to link to header tags                    'u:dev:HeaderLinks/code.js'                ); if ( $( '#ca-delete' ).length ) { // Fast Delete buttons // scripts.push( 'u:dev:FastDelete/code.js' ); scripts.push( 'u:dev:FastDelete/beta.js' ); }               if ( config.wgNamespaceNumber === 6 ) { scripts.push(                       // Changes file pages back to original styling                        // @todo fix this up at some point                        'u:rs:User:Cqm/oldfilepages.js'                    ); }               if ( [ 'Allpages', 'Prefixindex' ].indexOf( config.wgCanonicalSpecialPageName ) > 1 ) { scripts.push(                       // Adds a hide redirect button to AllPages & PrefixIndex                        'u:dev:AllPagesHideRedirect/code.js'                    ); }               if ( config.wgAction === 'history' || $( '#mw-history-searchform' ).length ) { scripts.push(                       // Add an undo link to page diffs and histories                        'u:dev:AjaxUndo/code.js'                    ); }           }            /**             * Import the filled arrays */           importArticles( { type: 'script', articles: scripts } ); },       /**         * @desc Adds a link to Special:Editcount on the user profile masthead *        * @author Matthew2602 <http://c.wikia.com/User:Matthew2602> * @author Cqm */       mastheadEditcount: function  { var config = mw.config.get( [                   'wgCanonicalNamespace',                    'wgTitle'                ] ), user = config.wgTitle, link; if ( config.wgCanonicalNamespace === 'Special' ) { user = user.split( '/' )[1]; }           link = $( '' ) .attr( {                   href: '/wiki/Special:Editcount/' + user,                    title: 'Special:Editcount'                } ) .text(                   $( '#UserProfileMasthead .tally em' ).text                ); $( '#UserProfileMasthead .tally em' ).html( link ); },        /**         * @desc Uncheck file redirects on Special:MovePage *        * File redirects are normally bad because they will create false positives on Special:WantedFiles * In very rare cases it's reasonable to have them, but those are so rare it's better to have this as        * the default behaviour. *        * @author Cqm */       uncheckFileRedirects: function  { $( '#wpLeaveRedirect' ).removeAttr( 'checked' ); },       /**         * @desc Set the type attribute of input elements to type="text" (which it defaults to anyway) *      Used to undo styling in touchScreen.scss which indiscriminately makes every input *      element larger than I need. */       setInputType: function  { $( 'input' ).each( function {                if ( !this.type ) {                    this.type = 'text';                }            } ); },       /**         * @desc For preventing autoplay for embedded youtube videos on file pages *        * @author Cqm */       removeAutoplay: function  { var loading; // used in setInterval function iframeLoad { if ( $( '#file iframe[src*="youtube.com"]' ).length ) { self.switchAutoplay; window.clearInterval( loading ); }           }            // @todo use mutation observers for this instead loading = window.setInterval( iframeLoad, 500 ); }   };    $( self.init ); }( this.jQuery, this.mediaWiki, this.importArticles ) );