User:Erutuon/scripts/ScriptInstaller.js

// Modified from w:User:Equazcion/ScriptInstaller.js /*jshint maxerr:1048576, strict:true, undef:true, latedef:true, es5:true */ /*global mw, $ */ $.when(mw.loader.using(["mediawiki.util", "mediawiki.api"]), $.ready).then(function {	var installerStylesUrl = "//en.wiktionary.org/w/index.php?title=User:Erutuon/ScriptInstaller.css&action=raw&ctype=text/css";	var namespaceNumber = mw.config.values.wgNamespaceNumber;	var pageName = mw.config.values.wgPageName;	var userName = mw.config.values.wgUserName;	var action = mw.config.values.wgAction;	var contentLanguage = mw.config.values.wgPageContentLanguage;	var noticeProject = mw.config.values.wgNoticeProject;	var contentModel = mw.config.values.wgPageContentModel;	var jsPage, homePage;	var isInstalled = false; // This will be changed, if the current script is found to be installed.

// If current revision id is 0, page has not been created. var articleExists = (mw.config.values.wgCurRevisionId > 0);

// Never do anything in article space, or on a page that hasn't been created. if (namespaceNumber === 0 || !articleExists) return;

function getPath(p) { return mw.config.get("wgArticlePath").replace("$1", p); }

function getCommonJs { return new mw.Api.get({			action: "query",			titles: "User:" + userName + "/common.js",			prop: "revisions",			rvprop: "content",			indexpageids: 1		}).then(function(r) {			var pageid = r.query.pageids[0];			return r.query.pages[pageid].revisions[0]["*"];		}); }

function uninstallScript(scriptPath) { return new mw.Api.edit("User:" + userName + "/common.js", function(response) {			var wikitext = response.content;			//find/replace our line with nothing, thereby removing the script			var toBeReplaced1 = "importScript('" + scriptPath + "')";			var toBeReplaced2 = 'importScript("' + scriptPath + '")';			var regex1 = new RegExp("\\n" + mw.util.escapeRegExp(toBeReplaced1) + "[^\\n]*[^\\n]*");			var regex2 = new RegExp("\\n" + mw.util.escapeRegExp(toBeReplaced2) + "[^\\n]*[^\\n]*");			var newText = wikitext.replace(regex1, "").replace(regex2, "");			if (wikitext === newText){				//throw new Error("");				return $.Deferred.reject("ScriptInstaller.js failed to make any changes in your common.js.").promise;			}			return {				text: newText,				summary: "Script Installer: Removed " + scriptPath + "",			}; 		}); }	var $installerWrapper = $(" ").attr("id", "script-installer-wrapper").attr("hidden", "hidden"); // Handle .js pages if (contentModel === "javascript" &&		action == 'view' &&		namespaceNumber > -1) { // Exclude users' own common.js and skin.js pages var fixedUn = mw.util.escapeRegExp(userName.replace(/ /g, '_')); var defaultJSPagesRegex = new RegExp('User:' + fixedUn + '/(?:common|monobook|vector|modern|cologneblue).js'); if (!defaultJSPagesRegex.test(pageName) &&			pageName != 'User:Erutuon/scripts/ScriptInstaller.js') { // 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 $installerWrapper.append(' '); $('h1#firstHeading').after($installerWrapper); }	}

// If script links are found on the page, start the music. Detection is based on span tags with "scriptInstallerLink" class, which are added by. // Also run if we're on User:Equazcion/scriptInstaller, where we'll simply provide access to the installed script list and uninstall links if (($('div.scriptInstallerLink').length > 0 && action != 'submit' && action != 'edit') ||		pageName == 'User:Erutuon/ScriptInstaller') { //if ( !jsPage ) importStylesheetURI("//en.wiktionary.org/w/index.php?title=User:Erutuon/ScriptInstaller.css&action=raw&ctype=text/css"); // Stylesheet already fetched above on .js pages if (pageName == 'User:Erutuon/ScriptInstaller') homePage = true; // Set a flag if we're running the limited User:Erutuon/ScriptInstaller functions

// Set interface text var installerTitle = 'You currently have the following scripts installed in your common.js. Script Installer '; var installerMessage = 'Only scripts installed using importScript are shown here. To uninstall a script, click "uninstall".'; var installerLink = 'Install'; var installedBadge = 'Installed'; var unInstallerLink = 'uninstall'; var noauto = 'Must be installed manually';

// Append the box of installed scripts. Hide unless we're on a designated installation page $('div#contentSub').after(' ');

var getInstallerStyles = $.get(installerStylesUrl).then(function(r) {			mw.util.addCSS(r);			//this is a SO version			//$(' ', {rel:'stylesheet', type:'text/css', 'href':installerStylesUrl}).appendTo('head');		});

// Create array for installed script paths var installedScripts = []; $.when(getCommonJs, getInstallerStyles).then(function(wikitext) {			$installerWrapper.prop("hidden", false);			var lines = wikitext.split('\n');

// Use the regex to iterate through the lines, looking for the ones that ScriptInstaller added $.each(lines, function(index, value) {				var match = new RegExp('importScript\\(\'(.*)\'\\)', "i").exec(value);

// Put the paths of the matches into the array of installed scripts if (match) { installedScripts.push(match[1]); }			});

// If none were found, remove the installed script list box. Otherwise fade-in the box and set up the toggle link if (installedScripts.length === 0) $('div.scriptInstaller').remove; else if (pageName == 'Wikipedia:WikiProject_User_scripts/Scripts' ||				/:WikiProject_User_scripts$/.test(pageName) ||				/:User_scripts$/.test(pageName) ||				jsPage ||				homePage) { // Insert script list toggle link. var toggleMessage = (jsPage || homePage) ? 'Show installed script list' : 'Hide installed script list'; $('.scriptInstallerLink').first .after(' ' + toggleMessage + ' ');

// The function to set the toggle link to				var setScriptInstallerToggle = function { $('.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 && !homePage) { 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 = ''; $.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) var scriptNameId = value.replace(/ /g, '_').replace(/[\.%]20/g, '_'); var scriptNameElement = $('div.scriptInstallerLink[id="' + scriptNameId + '"]'); if (scriptNameElement.length) { isInstalled = true; scriptNameElement .attr('id', 'installed' + index) .addClass('installed') .html(installedBadge); }				if (jsPage) $('div.scriptInstallerLink[id="' + value.replace(/ /g, '_') + '"]') .attr('id', 'installed' + index) .addClass('installed') .html(installedBadge) .css('font-weight', 'bold');

// Add an HTML list element for each installed script, containing .js and uninstall links installedList = installedList + '' + '' + decodeURIComponent(value) + ' ' + '(' + unInstallerLink + ')' + ''; });

// Cap off the list of installed scripts installedList = installedList + '';

if (isInstalled) { $('.scriptInstallerLink').first .after(' ' + unInstallerLink + '</a> ');

$(".uninstallThisScript").each(function {					var path = mw.config.get("wgCanonicalNamespace") + ":" + mw.config.get("wgTitle");					$(this).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;"> ');

$('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;"> ');

$('.arcProg').append(' Uninstalling ' + path + ' ... ');

uninstallScript(path).then(function(postResponse) {								$('.arcProg').append(' Done! Reloading... ');							}, function(errorText){								mw.notify(errorText);							}).always(function{								setTimeout(function{location.reload;}, 500);							}); }					);				});			}

// Build and append the rest if the list box code, and insert our constructed list of installed scripts $('.scriptInstaller').html(' ' + installerTitle + ' ' +				' ' +				' ' + installerMessage + ' ' +				' ' + installedList + ' ' +				' ');

// 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.installedScriptName').html;				$(this).find('.unInstallerLink').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;"> ');

$('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;"> ');

$('.arcProg').append(' Uninstalling ' + path + ' ... ');

uninstallScript(path).then(function(postResponse) {						$('.arcProg').append(' Done! Reloading... ');						location.reload;					}, function(errorText){						mw.notify(errorText);					}).always(function{						setTimeout(function{location.reload;}, 500);					}); });			});		});

// Iterate through each templated (via ) script on the page $('div.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)) { $(this).html('<a href="#installerLink" class="installerLink">' + installerLink + '</a>');

// 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;"> ');

$('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;"> ');

$('.arcProg').append(' Installing ' + path + ' ... ');

// Set ajax parameters for the ajax post that occurs when the install link is clicked var request1 = { action: "edit", title: "User:" + userName + "/common.js", appendtext: "\nimportScript('" + decodeURIComponent(path) + "'); //Linkback: " + decodeURIComponent(path) + " Added by Script installer", summary: "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.values.wgScriptPath + "/api.php", request1, function(response1) {						$('.arcProg').append(' Done! Reloading... ');						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(' | ' + noauto + ' ');			}		}); } });