User:Luístro/CSSInstaller.js
Appearance
Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump. This code will be executed when previewing this page. |
Documentation for this user script can be added at User:Luístro/CSSInstaller. |
(function($, mw){
'use strict';
var wgPageName = mw.config.get('wgPageName');
var wgUserName = mw.config.get('wgUserName');
var wgNamespaceNumber = mw.config.get('wgNamespaceNumber');
var cssPage = false;
// Never do anything in article space
if (wgNamespaceNumber === 0){
return;
}
// Handle .css pages
if ((wgPageName.lastIndexOf('.css') == wgPageName.length - 4) && (mw.config.get('wgAction') == 'view') && (wgNamespaceNumber > -1)) {
// Exclude users' own common.css and skin.css pages
var fixedUn = wgUserName.replace(/ /g,'_');
if ((wgPageName != 'User:' + fixedUn + '/common.css') &&
(wgPageName != 'User:' + fixedUn + '/monobook.css') &&
(wgPageName != 'User:' + fixedUn + '/minerva.css') &&
(wgPageName != 'User:' + fixedUn + '/vector.css') &&
(wgPageName != 'User:' + fixedUn + '/modern.css') &&
(wgPageName != 'User:' + fixedUn + '/cologneblue.css') &&
(wgPageName != 'User:' + fixedUn + '/timeless.css') &&
(wgPageName != 'User:Equazcion/ScriptInstaller.css')){
importStylesheet('User:Equazcion/ScriptInstaller.css');
// Thanks to Equazcion for the stylesheet
// Set a flag so the rest of the script knows we're on a .css page
cssPage = true;
// Append the install link to the header, along with a "cssInstallerLink" class for use by the rest of the script
$('h1#firstHeading').append('<span style="font-size:0.8em;font-weight:bold;" id="' + wgPageName + '" class="cssInstallerLink cssPage"></span>');
}
}
// The function to set the toggle link to
function setCSSsInstallerToggle(){
$('.CSSinstallerTog').click(function(){
if ($('.CSSinstallerTog').html() == "Show installed stylesheet list"){
$('.CSSInstaller').fadeIn(500);
$('.CSSinstallerTog').html('Hide installed stylesheet list');
} else {
$('.CSSInstaller').fadeOut(200);
$('.CSSinstallerTog').html('Show installed stylesheet list');
}
});
}
// If stylesheet links are found on the page, start the music. Detection is based on span tags with "cssInstallerLink" class.
// Also run if we're on User:Luístro/CSSInstaller, where we'll simply provide access to the installed stylesheet list and uninstall links
if ((($('span.cssInstallerLink').length > 0) && (mw.config.get('wgAction') != 'submit') && (mw.config.get('wgAction') != 'edit')) || (wgPageName == 'User:Luístro/CSSInstaller') || (wgPageName == 'User:Luístro/ScriptLibrary')){
if (cssPage !== true) {
importStylesheet('User:Equazcion/ScriptInstaller.css'); // Stylesheet already fetched above on .css pages
}
if (wgPageName == 'User:Luístro/CSSInstaller' || (wgPageName == 'User:Luístro/ScriptLibrary')) {
var homePage = true; // Set a flag if we're running the limited User:Luístro/CSSInstaller 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 stylesheets installed <div class="titleBadge"><a href="' + pre + 'User:Luístro/CSSInstaller' + '">CSS Installer</a></div>';
var installerMessage = 'Only stylesheets installed using <span style="font-weight:bold">CSSInstaller</span> are shown here. To uninstall a stylesheet, 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( 'importStylesheet\\(\'(.*)\'\\); \\/\\/Linkback: \\[\\[.*?\\]\\] Added by CSSInstaller' , ["i"]);
// Create array for installed stylesheet paths
var installedCSSs = [];
// Append the box of installed stylesheets. Hide unless we're on a designated installation page
$('div#contentSub').after('<div hidden="hidden" class="CSSInstaller"></div>');
// Set parameters for common.css ajax request
var request4 = {
action:"query",
titles: "User:" + mw.config.get("wgUserName") + "/common.css",
prop: "revisions|info",
intoken: "edit",
rvprop: "content",
indexpageids: 1,
format: "xml"
};
// ok
// Do common.css ajax request -- verify later
$.get(mw.config.get("wgScriptPath")+"/api.php", request4, function(response4){
// Grab common.css 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 CSSInstaller 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){
installedCSSs.push(match[1]);
}
});
// If none were found, remove the installed stylesheet list box. Otherwise fade-in the box and set up the toggle link
if (installedCSSs.length < 1){
$('div.CSSInstaller').remove();
} else if ((wgPageName == 'Wikipedia:WikiProject_User_scripts/Scripts') || (wgPageName == 'Wikipedia:WikiProject_User_scripts') ||
(wgPageName == 'Wikipedia:User_scripts') || (cssPage === true) || (homePage === true)){
// Insert script list toggle link
var toggleMessage = ((cssPage === true) || (homePage === true)) ? 'Show installed stylesheet list' : 'Hide installed stylesheet list';
$('.firstHeading').append(' <a style="font-weight:bold;font-size:10px" class="CSSinstallerTog" href="#bbx">' + toggleMessage + '</a>');
// Set the toggle link function. Also fade the box in initially, if we're at the script listing page.
if ((cssPage !== true) && (homePage !== true)){
setTimeout(function(){
$('.CSSInstaller').fadeIn(800, function(){ setCSSsInstallerToggle(); });
}, 500);
} else {
setCSSsInstallerToggle();
}
}
// Start building the code for display of the installed list. Iterate through each installed script in the array
var installedCssList = '<ul style="list-style-type:none;">';
$.each(installedCSSs, function(index, value){
// For each script already installed, change the install links (into "installed" messages) that are on the current page (if any)
$('span.CSSInstallerLink[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 (cssPage === true)
$('span.CSSInstallerLink[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
installedCssList = installedCssList + '<li>' +
'<a href="#installerLink" class="unInstallerLink">' + unInstallerLink + '</a>: ' +
'<a href="' + pre + value + '">' + decodeURIComponent(value) + '</a>' +
'</li>';
});
// Cap off the list of installed scripts
installedCssList = installedCssList + '</ul>';
// Build and append the rest if the list box code, and insert our constructed list of installed scripts
$('.CSSInstaller').html('<div class="CssinstallerTitle">' + installerTitle + '</div>' +
'<div class="container1">' +
'<div class="CssinstallerMessage">' + installerMessage + '</div>' +
'<div class="CssuninstallList">' + installedList + '</div>' +
'</div>');
// Iterate through each line in the installed list and set the click function for their uninstall links
$('.CSSInstaller 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.css",
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" + "importStylesheet('" + path + "'); //Linkback: [[" + path + "]] Added by CSSinstaller", "");
// 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.css",
text : newText,
summary : "[[User:Luístro/CSSInstaller|CSSInstaller]]: 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.CSSinstallerLink').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('.css') == path.length - 4)){
//var pipe = (jsPage == true) ? '' : ' | ';
$(this).html('<a href="#installerLink" class="CSSinstallerLink">' + CSSinstallerLink + '</a>')
.before(pipe);
// Set the click function for the install link
$(this).find('a.CSSinstallerLink').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.css",
appendtext: "\nimportStylesheet('" + decodeURIComponent(path) + "'); //Linkback: [[" + decodeURIComponent(path) + "]] Added by CSSinstaller",
summary: "[[User:Luístro/CSSInstaller|CSSInstaller]]: 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);