From Wikipedia, the free encyclopedia
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.

(function($, mw){

	'use strict';



	var wgPageName = mw.config.get('wgPageName');

	var wgUserName = mw.config.get('wgUserName');

	var wgNamespaceNumber = mw.config.get('wgNamespaceNumber');

	var jsPage = false;

	

	// Never do anything in article space

	if (wgNamespaceNumber === 0){

		return;

	}



	// Handle .js pages

	if ((wgPageName.lastIndexOf('.js') == wgPageName.length - 3) && (mw.config.get('wgAction') == 'view') && (wgNamespaceNumber > -1)) {

		

		// Exclude users' own common.js and skin.js pages

		var fixedUn = wgUserName.replace(/ /g,'_');

		if ((wgPageName != 'User:' + fixedUn + '/common.js') && 

			(wgPageName != 'User:' + fixedUn + '/monobook.js') &&

			(wgPageName != 'User:' + fixedUn + '/minerva.js') &&

			(wgPageName != 'User:' + fixedUn + '/vector.js') &&

			(wgPageName != 'User:' + fixedUn + '/modern.js') &&

			(wgPageName != 'User:' + fixedUn + '/cologneblue.js') &&

			(wgPageName != 'User:' + fixedUn + '/timeless.js') &&

			(wgPageName != 'User:Equazcion/ScriptInstaller.js')){

				importStylesheet('User:Equazcion/ScriptInstaller.css');

				

				// Set a flag so the rest of the script knows we're on a .js page

				jsPage = true;

				

				// Append the install link to the header, along with a "scriptInstallerLink" class for use by the rest of the script

				$('h1#firstHeading').append('<span style="font-size:0.8em;font-weight:bold;" id="' + wgPageName + '" class="scriptInstallerLink jsPage"></span>');

		}

	}

	

	// If script links are found on the page, start the music. Detection is based on span tags with "scriptInstallerLink" class, which are added by {{userscript}}.

	// Also run if we're on User:Equazcion/scriptInstaller, where we'll simply provide access to the installed script list and uninstall links

	if ((($('span.scriptInstallerLink').length > 0) && (mw.config.get('wgAction') != 'submit') && (mw.config.get('wgAction') != 'edit')) || (wgPageName == 'User:Equazcion/ScriptInstaller')){

		

		if (jsPage !== true) {

			importStylesheet('User:Equazcion/ScriptInstaller.css'); // Stylesheet already fetched above on .js pages

		}

		if (wgPageName == 'User:Equazcion/ScriptInstaller') {

			var homePage = true; // Set a flag if we're running the limited User:Equazcion/ScriptInstaller functions

		}

		

		// Set URL prefix

		var pre = location.protocol + '//' + mw.config.get('wgPageContentLanguage') + '.' + mw.config.get('wgNoticeProject') + '.org' + '/?title=';

		

		// Set interface text

		var installerTitle = 'You currently have the following scripts installed <div class="titleBadge"><a href="' + pre + 'User:Equazcion/ScriptInstaller' + '">Script Installer</a></div>';

		var installerMessage = 'Only scripts installed using <span style="font-weight:bold">Script Installer</span> are shown here. To uninstall a script, click "Uninstall".'; 

		var pipe = '<span style="font-size:1.1em;"> | </span>';

		var installerLink = 'Install';

		var installed = 'Installed';

		var unInstallerLink = 'Uninstall';

		var noauto = 'Must be installed manually';

	

		// Set up the regex pattern for later

		var regexObject = new RegExp( 'importScript\\(\'(.*)\'\\); \\/\\/Linkback: \\[\\[.*?\\]\\] Added by Script installer' , "i"]);

		

		// Create array for installed script paths

		var installedScripts = [];

		

		// Append the box of installed scripts. Hide unless we're on a designated installation page

		$('div#contentSub').after('<div hidden="hidden" class="scriptInstaller"></div>');

		

		// Set parameters for common.js ajax request	

		var request4 = {

			action:"query", 

			titles: "User:" + mw.config.get("wgUserName") + "/common.js", 

			prop: "revisions|info", 

			intoken: "edit", 

			rvprop: "content",

			indexpageids: 1,

			format: "xml"

		};

		

		// Do common.js ajax request

		$.get(mw.config.get("wgScriptPath")+"/api.php", request4, function(response4){

			

			// Grab common.js content and split by lines 

			var lines = $(response4).find('rev').text().split('\n');

			

			// Use the regex to iterate through the lines, looking for the ones that ScriptInstaller added

			$.each(lines, function(index, value){

				var match = regexObject.exec(value);

				

				// Put the paths of the matches into the array of installed scripts

				if (match !== null){

					installedScripts.push(match1]);

				}

			});

			

			// If none were found, remove the installed script list box. Otherwise fade-in the box and set up the toggle link

			if (installedScripts.length < 1){

				$('div.scriptInstaller').remove();

			} else if ((wgPageName == 'Wikipedia:WikiProject_User_scripts/Scripts') || (wgPageName == 'Wikipedia:WikiProject_User_scripts') || 

				(wgPageName == 'Wikipedia:User_scripts') || (jsPage === true) || (homePage === true)){

				

				// Insert script list toggle link

				var toggleMessage = ((jsPage === true) || (homePage === true)) ? 'Show installed script list' : 'Hide installed script list';

				$('.firstHeading').append(' <a style="font-weight:bold;font-size:10px" class="scriptinstallerTog" href="#bbx">' + toggleMessage + '</a>');

				

				// The function to set the toggle link to

				function setScriptInstallerToggle(){

					$('.scriptinstallerTog').click(function(){

						if ($('.scriptinstallerTog').html() == "Show installed script list"){

							$('.scriptInstaller').fadeIn(500);

							$('.scriptinstallerTog').html('Hide installed script list');

						} else {

							$('.scriptInstaller').fadeOut(200);

							$('.scriptinstallerTog').html('Show installed script list');

						}

					});

				}

				

				// Set the toggle link function. Also fade the box in initially, if we're at the script listing page.

				if ((jsPage !== true) && (homePage !== true)){ 

					setTimeout(function(){

						$('.scriptInstaller').fadeIn(800, function(){ setScriptInstallerToggle(); });

					}, 500);

				} else {

					setScriptInstallerToggle();

				}					

			}

			

			// Start building the code for display of the installed list. Iterate through each installed script in the array

			var installedList = '<ul style="list-style-type:none;">';

			$.each(installedScripts, function(index, value){

				

				// For each script already installed, change the install links (into "installed" messages) that are on the current page (if any)

				$('span.scriptInstallerLink[id="' + encodeURIComponent(value).replace('%3A',':').replace(/\//g,'.2F').replace(/ /g,'_').replace(/%/g,'.').replace(/\.20/g,'_') + '"]')

					.attr('id','installed' + index)

					.addClass('installed')

					.html(installed)

					.css('font-weight','bold');

				if (jsPage === true)

					$('span.scriptInstallerLink[id="' + value.replace(/ /g,'_') + '"]')

						.attr('id','installed' + index)

						.addClass('installed')

						.html(installed)

						.css('font-weight','bold');

				

				// Add an HTML list element for each installed script, containing .js and uninstall links

				installedList = installedList + '<li>' + 

					'<a href="#installerLink" class="unInstallerLink">' + unInstallerLink + '</a>: ' +

					'<a href="' + pre + value + '">' + decodeURIComponent(value) + '</a>' + 

				'</li>'; 

			});

			

			// Cap off the list of installed scripts

			installedList = installedList + '</ul>';

			

			// Build and append the rest if the list box code, and insert our constructed list of installed scripts

			$('.scriptInstaller').html('<div class="installerTitle">' + installerTitle + '</div>' +	

			'<div class="container1">' + 

					'<div class="installerMessage">' + installerMessage + '</div>' + 

					'<div class="uninstallList">' + installedList + '</div>' + 

			'</div>');

			

			// Iterate through each line in the installed list and set the click function for their uninstall links

			$('.scriptInstaller li').each(function(){

				var path = $(this).find('a:last').html();

				$(this).find('a:first').click(function(){

					

					$('body').append('<div class="overlay" style="background-color:#000;opacity:.4;position:fixed;' + 

						'top:0;left:0;width:100%;height:100%;z-index:500;"></div>');					

						

					$('body').prepend('<div class="arcProg" style="font-weight:bold;box-shadow: 7px 7px 5px #000;font-size:0.9em;line-height:1.5em;' + 

						'z-index:501;opacity:1;position:fixed;width:50%;left:25%;top:30%;background:#F7F7F7;border:#222 ridge 1px;padding:20px;"></div>');

						

					$('.arcProg').append('<div>Uninstalling <span style="font-weight:normal;color:#003366;">' + path + '</span>...</div>');

					

					// Set parameters for the first uninstall ajax request that occurs when the uninstall link is clicked

					var request5 = {

						action:"query", 

						titles: "User:" + mw.config.get("wgUserName") + "/common.js", 

						prop: "revisions|info", 

						intoken: "edit", 

						rvprop: "content",

						indexpageids: 1,

						dataType: "xml",

						format: "xml"

					};

					

					// Send the request

					$.get(mw.config.get("wgScriptPath")+"/api.php", request5, function(response5){

						

						//Grab common.js content and find/replace our line with nothing, thereby removing the script

						var content = $(response5).find('rev').text();

						var newText = content.replace("\n" + "importScript('" + path + "'); //Linkback: [[" + path + "]] Added by Script installer", "");

						

						// Set paraemeters for the ajax post that replaces common.js with our edited version

						var request6 = {

							action : "edit",

							title : "User:" + mw.config.get("wgUserName") + "/common.js", 

							text : newText,

							summary : "[[User:Equazcion/ScriptInstaller|Script Installer]]: Removed [[" + path + "]]",

							token: mw.user.tokens.get("csrfToken")

						};

						

						// Send the ajax post to save the new common.js, then reload the current page

						$.post(mw.config.get("wgScriptPath")+"/api.php", request6, function(response6){

							$('.arcProg').append('<div><span style="color:#00008C">Done!</span> Reloading...</div>');

							location.reload();

						});

					});

				});

			});

		});

		

		// Iterate through each templated (via {{userscript}}) script on the page

		$('span.scriptInstallerLink').each(function(){

			

			// Get the script path, which the template places in the span's ID

			var path = $(this).attr('id');

			path = path.replace(/.2F/g,'/').replace(/\_/g,' ');

			

			// If there's more than one dot left in the path, assume percent encoding was converted to dots. Leave the last dot for ".js"

			if ((path.split(".").length - 1) > 1){

				var parts = path.split('.');

	    		path = parts.slice(0,-1).join('%') + '.' + parts.slice(-1);

			}

			

			// If this path leads to a valid en-wiki .js script in userspace or wikipedia space, add an install link

			if (((path.toLowerCase().substring(0, 5) == "user:") || (path.toLowerCase().substring(0,10) == 'wikipedia:')) && (path.lastIndexOf('.js') == path.length - 3)){

				//var pipe = (jsPage == true) ? '' : ' | ';

				$(this).html('<a href="#installerLink" class="installerLink">' + installerLink + '</a>')

					.before(pipe);

				

				// Set the click function for the install link

				$(this).find('a.installerLink').click(function(){

					

					$('body').append('<div class="overlay" style="background-color:#000;opacity:.4;position:fixed;' + 

						'top:0;left:0;width:100%;height:100%;z-index:500;"></div>');					

						

					$('body').prepend('<div class="arcProg" style="font-weight:bold;box-shadow: 7px 7px 5px #000;font-size:0.9em;line-height:1.5em;' + 

						'z-index:501;opacity:1;position:fixed;width:50%;left:25%;top:30%;background:#F7F7F7;border:#222 ridge 1px;padding:20px;"></div>');

						

					$('.arcProg').append('<div>Installing <span style="font-weight:normal;color:#003366;">' + path + '</span>...</div>');

					

					// Set ajax parameters for the ajax post that occurs when the install link is clicked 

					var request1 = {

						action:"edit", 

						title: "User:" + mw.config.get("wgUserName") + "/common.js", 

						appendtext: "\nimportScript('" + decodeURIComponent(path) + "'); //Linkback: [[" + decodeURIComponent(path) + "]] Added by Script installer", 

						summary: "[[User:Equazcion/ScriptInstaller|Script Installer]]: Added [[" + path + "]]", 

						token: mw.user.tokens.get("csrfToken")

					};

					

					// Send the ajax post, which appends our new importScript line to common.js, then reload the current page

					$.post(mw.config.get("wgScriptPath")+"/api.php", request1, function(response1){

						$('.arcProg').append('<div><span style="color:#00008C">Done!</span> Reloading...</div>');

					    location.reload();

					});

				});	

			} else {

				// If this is not a valid path to an en-wiki .js script in user or wikipedia space, add a "must install manually" message

				$(this).html(' | <span class="noauto">' + noauto + '</span>');

			}

		});

	}

})(jQuery, mediaWiki);