MediaWiki:Install.js

From Wikimedia Commons, the free media repository
Jump to navigation Jump to search
Note: After saving, you have to bypass your browser's cache to see the changes. Internet Explorer: press Ctrl-F5, Mozilla: hold down Shift while clicking Reload (or press Ctrl-Shift-R), Opera/Konqueror: press F5, Safari: hold down Shift + Alt while clicking Reload, Chrome: hold down Shift while clicking Reload.
/**
 * Helper script for the installation of JavaScript files into
 * the user script page of a user.
 * @author Dschwen, 2013
 */
/* jshint laxcomma: true, smarttabs: true */
/* global mw,$ */

mw.loader.using([
	'jquery.ui'
], function() {
	var installJS = mw.config.get('wgPageName')
	  , userScript = 'User:' + mw.config.get('wgUserName') + '/common.js'
	  , beginMarker = '// BEGIN: ' + installJS + ' (Install.js marker)'
	  , endMarker = '// END: ' + installJS + ' (Install.js marker)'
	  , editToken = mw.user.tokens.get( 'csrfToken' );
	
	function getPage(page,callback) {
		$.ajax({
			url: mw.util.wikiScript( 'index' ),
			data: { action: 'raw', title: page },
			type: 'POST',
			success: function(data) {
				callback(data||'');
			},
			error: function() { callback(''); }
		});
	}
	
	function savePage(page,text,summary,success,error) {
		function reportError(data) {
			var message = data ? ('Error ' + data.error.code + '": ' + data.error.info + ' writing page ' + page + '.') : ('Error writing page ' + page + '.');
			$('<div title="Error">'+message+'</div>').dialog({ buttons: [ {
				text: "Ok",
				click: function() { $( this ).dialog( "close" ); }
			} ] });
			error();
		}
			
		$.ajax({
			url: mw.util.wikiScript( 'api' ),
			data: {
				format: 'json',
				action: 'edit',
				title: page,
				summary: summary,
				text: text,
				token: editToken
			},
			dataType: 'json',
			type: 'POST',
			success: function( data ) {
				if ( data && data.edit && data.edit.result == 'Success' ) {
					success(data);
				} else if ( data && data.error ) {
					reportError(data);
				} else {
					reportError();
				}
			},
			error: reportError
		});
	}
 
	// Disallow some characters in file name and only allow installing scripts from the Mediawiki: namespace
	if (!installJS.match(/^MediaWiki:[^&<>=%#]*\.js$/)) {
		$('<div title="Error">This script cannot be installed due to security reasons</div>').dialog({ buttons: [ {
			text: "Ok",
			click: function() { $( this ).dialog( "close" ); }
		} ] });
		return;
	}
 
	// fetch user's script page
	getPage( userScript, function(text) { 
		// parse the page text to see if the script is already installed
		var lines = text.split('\n'), i, line
		  , installed = false, removing = false
		  , newText = '';
		 
		// perform the install/uninstall
		function updateUserScript() {
			if(installed) {
				savePage(userScript,newText,'Uninstalling '+installJS,function(){
					// successfully uninstalled
					$('<div title="Success">Successfully uninstalled.</div>').dialog({ buttons: [ {
						text: "Ok",
						click: function() { $( this ).dialog( "close" ); }
					} ] });
				},function(){});
			} else {
				// first get the script that is to be installed
				getPage(installJS,function(script){
					// now wrap it in the markers and append it to the user scripts page
					newText += beginMarker +'\n' + script + '\n' + endMarker;
					// and save the user scripts page
					savePage(userScript,newText,'Installing '+installJS,function(){
						// successfully installed
						$('<div title="Success">Successfully installed.</div>').dialog({ buttons: [ {
							text: "Ok",
							click: function() { $( this ).dialog( "close" ); }
						} ] });
					},function(){});
				});
			}
		}
		 
		for (i=0; i<lines.length; ++i) {
			line=lines[i];
			if (line==beginMarker) {
				installed=true;
				removing=true;
			}
			if (!removing) { newText += line+'\n'; }
			if (line==endMarker) { removing=true; }
		}
		 
		// if installed==true && removing==true -> no endMarker found!
		 
		var message = installed ? 'Uninstall' : 'Install';
		$('<div title="'+message+'">'+message+' '+installJS+' on your user script page?</div>').dialog({ 
			buttons: [ 
				{ text: "Yes", click: function() { $( this ).dialog( "close" ); updateUserScript(); }	},
				{ text: "No", click: function() { $( this ).dialog( "close" ); }	},
			] });
	});
});