_ _    _ _____  ___   __                       
 __      _(_) | _(_)___ / ( _ ) / /_   ___ ___  _ __ ___  
 \ \ /\ / / | |/ / | |_ \ / _ \| '_ \ / __/ _ \| '_ ` _ \ 
  \ V  V /| |   <| |___) | (_) | (_) | (_| (_) | | | | | |
   \_/\_/ |_|_|\_\_|____/ \___/ \___(_)___\___/|_| |_| |_|

User:Naypta/ScriptInstaller.js

In this article, we will delve into the fascinating world of User:Naypta/ScriptInstaller.js, exploring its origins, meaning and relevance today. User:Naypta/ScriptInstaller.js has aroused the interest and curiosity of many people over time, and in this article we will try to shed light on all the aspects that make it so special. From its impact on society to its influence in different areas, User:Naypta/ScriptInstaller.js has left an indelible mark that deserves to be analyzed and understood in depth. Join us on this journey of discovery and knowledge about User:Naypta/ScriptInstaller.js, an experience that promises to be enriching and revealing.
//
// ScriptInstaller
// Forked from User:Equazcion/ScriptInstaller.js
// Updated to work for the new APIs by Naypta
//
(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') &&
			(wgPageName != 'User:Naypta/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' || wgPageName == 'User:Naypta/ScriptInstaller')){
		
		if (jsPage !== true) {
			importStylesheet('User:Equazcion/ScriptInstaller.css'); // Stylesheet already fetched above on .js pages
		}
		if (wgPageName == 'User:Equazcion/ScriptInstaller' || wgPageName == 'User:Naypta/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' + '/w/index.php?title=';
		
		// Set interface text
		var installerTitle = 'You currently have the following scripts installed <div class="titleBadge"><a href="' + pre + 'User:Naypta/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' , );
		
		// 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(match);
				}
			});
			
			// 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')
					.attr('id','installed' + index)
					.addClass('installed')
					.html(installed)
					.css('font-weight','bold');
				if (jsPage === true)
					$('span.scriptInstallerLink')
						.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: ] 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 : "]: Removed ]",
							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: ] Added by Script installer", 
						summary: "]: Added ]", 
						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);