Jump to content

User:PleaseStand/userScriptSandbox.js

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by PleaseStand (talk | contribs) at 00:54, 31 January 2012 (post script). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
(diff) ← Previous revision | Latest revision (diff) | Newer revision → (diff)
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
/*!
 * User script sandbox
 * http://en.wikipedia.org/wiki/Wikipedia:User_script_sandbox
 *
 * Copyright 2012 Wikipedia user PleaseStand 
 *
 * Licensed under the Creative Commons Attribution-Share-Alike 3.0 Unported License,
 * the GNU Free Documentation License (unversioned), and the GNU General Public License
 * (version 2 or any later version); pick the license(s) of your choice.
 *
 * http://creativecommons.org/licenses/by-sa/3.0/
 * http://www.gnu.org/copyleft/fdl.html
 * http://www.gnu.org/copyleft/gpl.html
 */

(function( $, undefined ) {

"use strict";

/**
 * Configuration for this script.
 */
var settings = {
	sandboxNamespaceNumber: 4,
	sandboxPageTitle: "User script sandbox",
	storagePrefix: "userScriptSandbox"
};

/**
 * A thin wrapper around localStorage.
 */
var storage = {

	/**
	 * Retrieves a string value from localStorage.
	 * @param selection {String} String key to get the value for.
	 * @param fallback {String} Value to use in case key does not exist (optional).
	 * @return A string value or null.
	 */
	get: function( selection, fallback ) {
		var value = localStorage.getItem( settings.storagePrefix + selection );
		return value != null ? value : (fallback != null ? fallback : null);
	},
	
	/**
	 * Sets a key/value pair in localStorage.
	 * @param selection {String} String key to set the value for.
	 * @param value {mixed} String value to set (null or undefined to remove).
	 */
	set: function( key, value ) {
		if ( value == null ) {
			localStorage.removeItem( settings.storagePrefix + key );
		} else {
			localStorage.setItem( settings.storagePrefix + key, value );
		}
	}
	
};

/**
 * The sandbox editor interface code.
 */
var editor = {

	dependencies: ["mediawiki.util", "jquery.ui.tabs"],
	
	/**
	 * Shows the user interface for the sandbox editor.
	 */
	show: function() {

		var textareaProps = {
			cols: mw.user.options.get("cols"),
			rows: mw.user.options.get("rows")
		};
		
		// CSS to add
		mw.util.addCSS( "#sandbox-tabs { font-size: 1em; } " +
		                "#sandbox-wrapper textarea { font-family: monospace, sans-serif; }" );
		
		// Elements to add
		editor.$wrapper = $("#sandbox-wrapper");
		editor.$enabled = $("<input id='sandbox-enabled' type='checkbox'>");
		editor.$dependencies = $("<input id='sandbox-dependencies' type='text' style='width: 80%;'>");
		editor.$jsArea = $("<textarea id='sandbox-js-area'></textarea>").prop( textareaProps );
		editor.$cssArea = $("<textarea id='sandbox-css-area'></textarea>").prop( textareaProps );
		editor.$saveLocal = $("<button id='sandbox-save-local'></button>");
		
		// Modifications to wiki page
		$("#sandbox-enabled-placeholder").replaceWith( editor.$enabled );
		$("#sandbox-enabled-label").wrap("<label for='sandbox-enabled'></label>");
		$("#sandbox-dependencies-label").wrap("<label for='sandbox-dependencies'></label>");
		$("#sandbox-dependencies-placeholder").replaceWith( editor.$dependencies );
		$("#sandbox-tabs").tabs();
		$("#sandbox-js-area-placeholder").replaceWith( editor.$jsArea );
		$("#sandbox-css-area-placeholder").replaceWith( editor.$cssArea );
		$("#sandbox-save-local-text").wrap( editor.$saveLocal );
		
		// Event handling functions
		editor.loadSandbox();
		editor.$saveLocal.click( editor.saveSandbox );
		editor.$wrapper.delegate( ":input", "change", editor.handleChange);
		
		$("#sandbox-loading").hide();
		editor.$wrapper.show();
		
	},

	/**
	 * Called when a form field's value changes.
	 */
	handleChange: function() {
		editor.$saveLocal.prop( "disabled", false );
	},

	/**
	 * Loads the contents of the sandbox editor from localStorage.
	 */
	loadSandbox: function() {
		editor.$saveLocal.prop( "disabled", true );
		editor.$enabled.prop( "checked", +storage.get( "enabled" ) );
		editor.$dependencies.val( storage.get( "dependencies" ) );
		editor.$jsArea.val( storage.get( "js" ) );
		editor.$cssArea.val( storage.get( "css" ) );
	},

	/**
	 * Saves the contents of the sandbox editor to localStorage.
	 */
	saveSandbox: function() {
		editor.$saveLocal.prop( "disabled", true );
		storage.set( "enabled", editor.$enabled.prop("checked") ? "1" : "0" );
		storage.set( "dependencies", editor.$dependencies.val() );
		storage.set( "js", editor.$jsArea.val() );
		storage.set( "css", editor.$cssArea.val() );
	}
	
};

/**
 * Runs any CSS and JS code from localStorage once dependencies have been satisfied.
 */
function runSandbox() {

	var enabled, css, js, dependencies;
	
	enabled = +storage.get( "enabled", "0" );
	if ( !enabled ) {
		return;
	}
	
	css = storage.get( "css", "" );
	js = storage.get( "js", "" );
	dependencies = $.trim( storage.get("dependencies", "") ).split( /\s*,\s*/ );
	
	mw.loader.using( "mediawiki.util", function() {
		mw.util.addCSS( css );
	});
	
	mw.loader.using( dependencies, function() {
		$.globalEval( js + "\n//@ sourceURL=localSandbox.js" );
	});
	
}

/**
 * Initialization code
 */
function main() {

	// localStorage is required for any of this to work.
	if ( !localStorage ) {
		return;
	}

	// On the sandbox page, run the editor instead of the code in the sandbox.
	if ( mw.config.get("wgAction") === "view" &&
		 mw.config.get("wgNamespaceNumber") === settings.sandboxNamespaceNumber &&
		 mw.config.get("wgPageName") === settings.sandboxPageTitle )
	{
		mw.loader.using( editor.dependencies, function() {
			$( editor.show );
		});
	}
	else
	{
		runSandbox();
	}
	
}

main();

})( jQuery );