User:Constraque/common.js
Note: After publishing, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
// Adapted from https://en.wiktionary.org/w/index.php?title=User:Erutuon/scripts/ScriptInstaller.js&oldid=54132174
// 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 = "//www.wikidata.org/w/index.php?title=User:So9q/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: "[[User:So9q/ScriptInstaller.js|Script Installer]]: Removed [[" + scriptPath + "]]",
};
});
}
var $installerWrapper = $("<div></div>").attr("id", "script-installer-wrapper").prop('hidden', true);
// 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:So9q/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('<div id="' + pageName + '" class="scriptInstallerLink jsPage"></div>');
$('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 {{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 (($('div.scriptInstallerLink').length > 0 && action != 'submit' && action != 'edit') ||
pageName == 'User:So9q/ScriptInstaller.js') {
//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:So9q/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 <a href="' + getPath('Special:MyPage/common.js') + '">common.js</a>. <div class="titleBadge"><a href="https://www.wikidata.org/wiki/User:So9q/ScriptInstaller.js' + '">Script Installer</a></div>';
var installerMessage = 'Only scripts installed using <span class="nx">importScript</span> 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('<div class="scriptInstaller" hidden="hidden"></div>');
var getInstallerStyles = $.get(installerStylesUrl).then(function(r) {
mw.util.addCSS(r);
//this is a SO version
//$('<link>', {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('<div id="scriptinstallerTog" style="display: inline-block;"><a style="font-weight:bold;font-size:10px" class="scriptinstallerTog" href="#bbx">' + toggleMessage + '</a></div>');
// 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 = '<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)
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 + '<li>' +
'<a class="installedScriptName" href="' + getPath(value) + '">' + decodeURIComponent(value) + '</a> ' +
'(<a href="#installerLink" class="unInstallerLink">' + unInstallerLink + '</a>)' +
'</li>';
});
// Cap off the list of installed scripts
installedList = installedList + '</ul>';
if (isInstalled) {
$('.scriptInstallerLink').first()
.after('<div id="uninstallThis" style="display: inline-block;"><a href="#installerLink" class="uninstallThisScript">' + unInstallerLink + '</a></div>');
$(".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;"></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>');
uninstallScript(path).then(function(postResponse) {
$('.arcProg').append('<div><span style="color:#00008C">Done!</span> Reloading...</div>');
}, 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('<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.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;"></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>');
uninstallScript(path).then(function(postResponse) {
$('.arcProg').append('<div><span style="color:#00008C">Done!</span> Reloading...</div>');
location.reload();
}, function(errorText){
mw.notify(errorText);
}).always(function(){
setTimeout(function(){location.reload();}, 500);
});
});
});
});
// Iterate through each templated (via {{userscript}}) 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;"></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:" + userName + "/common.js",
appendtext: "\nimportScript('" + decodeURIComponent(path) + "'); //Linkback: [[" + decodeURIComponent(path) + "]] Added by Script installer",
summary: "[[User:So9q/ScriptInstaller.js|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('<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>');
}
});
}
});
mw.loader.load( '//www.wikidata.org/w/index.php?title=User%3AJoern%2FaltLabels.js&action=raw&ctype=text%2Fjavascript' ); // [[User:Joern/altLabels.js]]