User:Equazcion/ScriptInstaller.js

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

}

}

// 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' + '/w/index.php?title=';

// Set interface text

var installerTitle = 'You currently have the following scripts installed

';

var installerMessage = 'Only scripts installed using Script Installer are shown here. To uninstall a script, click "Uninstall".';

var pipe = ' | ';

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('

');

// 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[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 < 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(' ' + toggleMessage + '');

// 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 = '

    ';

    $.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 + '

  • ' +

    '' + unInstallerLink + ': ' +

    '' + decodeURIComponent(value) + '' +

    '

  • ';

    });

    // Cap off the list of installed scripts

    installedList = installedList + '

';

// 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:last').html();

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

$('body').append('

');

$('body').prepend('

');

$('.arcProg').append('

Uninstalling ' + path + '...
');

// 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 : "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('

Done! Reloading...
');

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('' + installerLink + '')

.before(pipe);

// Set the click function for the install link

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

$('body').append('

');

$('body').prepend('

');

$('.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:" + mw.config.get("wgUserName") + "/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.get("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 + '');

}

});

}

})(jQuery, mediaWiki);