MediaWiki:Common.js

From Noisebridge
Revision as of 02:38, 18 January 2012 by Leif (talk | contribs) (add sopablackout.org script)
Jump to navigation Jump to search

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)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
/* Any JavaScript here will be loaded for all users on every page load. */

// from https://github.com/dougmartin/Stop-Censorship

//
// stopcensorship.js
//
// Author: Doug Martin (@dougmartin or http://dougmart.in/)
//
// Usage: Add to head or body of any page to automatically censor the content to protest censorship of the Internet
//
// Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
//
// NOTE: PLEASE DON'T HOTLINK THIS SCRIPT!
//

(function () {
	var walker, node, root, bar;
	
	function removeBar() {
		// set the no-censor cookie for this session
		document.cookie = "__REMOVE_STOP_CENSORSHIP__=1;path=/";
		
		// and reload the page
		window.location.reload();
		
		return false;
	}
	
	function addBar() {
		var baseStyles, linkStyles, stopLink, removeLink;
		
		function createStyledNode(type, text, nodeStyles) {
			var i, node, e;
			
			function applyStyles(styles) {
				if (styles) {
					for (i in styles) {
						if (styles.hasOwnProperty(i)) {
							try {
								node.style[i] = styles[i];
							}
							catch (e) {
							}
						}
					}
				}
			}
			
			node = document.createElement(type);
			
			node.innerHTML = text;
			
			applyStyles(baseStyles);
			applyStyles(nodeStyles);
			
			return node;
		}
		
		// create the base styles
		baseStyles = {
			"background": "#000 none repeat scroll 0% 0%",
			"borderCollapse": "separate",
			"borderSpacing": "0",
			"border": "medium none #000",
			"bottom": "auto",
			"captionSide": "top",
			"clear": "none",
			"clip": "auto",
			"color": "#fff",
			"cursor": "auto",
			"direction": "ltr",
			"display": "inline",
			"emptyCells": "show",
			"float": "none",
			"fontStyle": "normal",
			"fontVariant": "normal",
			"fontWeight": "bold",
			"fontSize": "12px",
			"fontFamily": "verdana,helvetica,arial,sans-serif",
			"height": "auto",
			"left": "auto",
			"letterSpacing": "normal",
			"lineHeight": "normal",
			"listStyle": "disc outside none",
			"margin": "0",
			"maxHeight": "none",
			"maxWidth": "none",
			"minHeight": "0",
			"minWidth": "0",
			"orphans": "2",
			"outline": "invert none medium",
			"overflow": "visible",
			"padding": "0",
			"pageBreakAfter": "auto",
			"pageBreakBefore": "auto",
			"pageBreakInside": "auto",
			"position": "static",
			"right": "auto",
			"tableLayout": "auto",
			"textAlign": "left",
			"textDecoration": "none",
			"textIndent": "0",
			"textTransform": "none",
			"top": "auto",
			"unicodeBidi": "normal",
			"verticalAlign": "baseline",
			"visibility": "visible",
			"whiteSpace": "normal",
			"widows": "2",
			"width": "auto",
			"wordSpacing": "normal",
			"zIndex": "auto"
		};
		
		// and the link styles
		linkStyles = {
			"textDecoration": "underline",
			"cursor": "pointer"
		};
		
		// add bar to top of page with link to anti-censor site and link to set cookie
		bar = createStyledNode("div", "", {
			"position": "absolute",
			"top": "0",
			"left": "0",
			"textAlign": "center",
			"margin": "0",
			"padding": "5px 0",
			"width": "100%",
			"borderTop": "2px solid #fff",
			"borderBottom": "2px solid #fff",
			"zIndex": 2147483647
		});
		
		stopLink = createStyledNode("a", "STOP CENSORSHIP", linkStyles);
		stopLink.href = "http://americancensorship.org/";
		
		removeLink = createStyledNode("a", "Remove this", linkStyles);
		removeLink.href = "#";
		removeLink.onclick = removeBar;
		
		bar.appendChild(stopLink);
		bar.appendChild(createStyledNode("span", "|", {
			"padding": "0 10px"
		}));
		bar.appendChild(removeLink);
		
		document.body.appendChild(bar);
	}
	
	function run() {
		var blackout, blackoutArray;
	
		function censorNode(node) {
			var words, i, j;
			
			// split contents on whitespace
			words = node.nodeValue.split(/\s/);
			
			// randomly replace words with black bars 
			for (i = 0, j = words.length; i < j; i++) {
				if (Math.random() < 0.5) {
					words[i] = blackoutArray.slice(0, words[i].length).join("");
				}
			}
			
			// and rejoin using just space
			node.nodeValue = words.join(" ");
		}
		
		// create a big blackout array string to pull from
		blackout = String.fromCharCode(0x2588);
		blackoutArray = [];
		while (blackoutArray.length < 1024) {
			blackoutArray.push(blackout);
		}
		
		// process all the text
		if (document.createTreeWalker) {
			walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT, null, false);
			while (walker.nextNode()) {
				censorNode(walker.currentNode);
			}
		}
		else {
			// do depth first traveral from "Iterative Tree Traversal" at 
			// http://stackoverflow.com/questions/2579666/getelementsbytagname-equivalent-for-textnodes
			root = document.body;
			node = root.childNodes[0];
			while (node != null) {
				if (node.nodeType == 3) {
					censorNode(node);
				}

				if (node.hasChildNodes()) {
					node = node.firstChild;
				}
				else {
					while (node.nextSibling == null && node != root) {
						node = node.parentNode;
					}
					node = node.nextSibling;
				}
			}
		}
		
		addBar();
	}
	
	// adapted from jQuery
	function onReady(callback) {

		var isReady = false;
	
		function ready() {
			if (isReady) {
				return;
			}
				
			if (!document.body) {
				return setTimeout(ready, 1);
			}

			isReady = true;
			
			callback();
		}
		
		function domContentLoaded() {
			if (document.addEventListener) {
				document.removeEventListener("DOMContentLoaded", domContentLoaded, false);
				ready();
			} 
			else if (document.attachEvent && (document.readyState === "complete")) {
				document.detachEvent("onreadystatechange", domContentLoaded);
				ready();
			}
		}
		
		function doScrollCheck() {
			if (isReady) {
				return;
			}

			try {
				document.documentElement.doScroll("left");
			} catch (e) {
				setTimeout(doScrollCheck, 1);
				return;
			}

			ready();
		}
		

		if (document.addEventListener) {
			document.addEventListener("DOMContentLoaded", domContentLoaded, false);
			window.addEventListener("load", ready, false);
		} 
		else if (document.attachEvent) {
			document.attachEvent("onreadystatechange", domContentLoaded);
			window.attachEvent("onload", ready);
			
			try {
				if ((window.frameElement === null) && document.documentElement.doScroll) {
					doScrollCheck();
				}
			} catch (e) {
			}
		}
	}
	
	// if undo-censor cookie set, return
	if (/__REMOVE_STOP_CENSORSHIP__=1/.test(document.cookie)) {
		return;
	}

	// wait for document load and then run
	if (!document.body) {
		onReady(run);
	}
	else {
		run();
	}

}());



//
// from http://js.sopablackout.org/sopablackout.js

(function (){
	var root = this;

	var SopaBlackout = function(){};
	var	addEvent = function(obj, type, fn, ref_obj){
		if (obj.addEventListener){
			obj.addEventListener(type, fn, false);
		}else if (obj.attachEvent){
			obj["e"+type+fn] = fn;
			obj[type+fn] = function(){
				obj["e"+type+fn](window.event,ref_obj);
			};
			obj.attachEvent("on"+type, obj[type+fn]);
		}
	};
	// Thanks http://javascript.nwbox.com/IEContentLoaded/
	// for this
	var IEContentLoaded = function(w, fn) {
		var d = w.document, done = false,
		init = function () {
			if (!done) {
				done = true;
				fn();
			}
		};
		(function () {
			try {
				d.documentElement.doScroll('left');
			} catch (e) {
				setTimeout(arguments.callee, 50);
				return;
			}
			init();
		})();
		d.onreadystatechange = function() {
			if (d.readyState == 'complete') {
				d.onreadystatechange = null;
				init();
			}
		};
	}
	var onDomReady = function(fn){
		if (document.addEventListener){
			document.addEventListener('DOMContentLoaded', fn, false);
		}else{
			IEContentLoaded(window, fn);
		}
	};
	var getStyle = function(e, prop){
		if (e.currentStyle){
			return e.currentStyle[prop];
		}else if (document.defaultView && document.defaultView.getComputedStyle){
			return document.defaultView.getComputedStyle(e, "")[prop];
		}else{
			return e.style[prop];
		}
	};
	var findPos = function(obj){
		var curleft = 0;
		var curtop = 0;
		if (obj.offsetParent){
			do{
				curleft += obj.offsetLeft;
				curtop += obj.offsetTop;
			}while(obj = obj.offsetParent);
		}
		return [curleft, curtop];
	};
	var txt = function(s){
		return document.createTextNode(s);
	};
	var create = function(e, props){
		var elem = document.createElement(e);
		var props = props !== null ? props : {};
		for (var key in props){
			if (key == 'href'){
				elem.href = props[key];
			}else{
				elem.style[key] = props[key];
			}
		}
		l = arguments.length;
		for (var i=2; i<l; i++){
			elem.appendChild(arguments[i]);
		}
		return elem;
	};
	var getOpts = function(){
		var ret = {};
		for (var key in SopaBlackout.DEFAULTS){
			var k = 'sopablackout_' + key;
			ret[key] = (typeof window[k] === 'undefined') ? SopaBlackout.DEFAULTS[key] : window[k];
		}
		return ret;
	};
	var dateMatches = function(spec){
		spec.push(false); spec.push(false); spec.push(false);
		var today = new Date();
		if ((spec[0] !== false && today.getFullYear() !== spec[0]) || 
				(spec[1] !== false && today.getMonth() + 1 !== spec[1]) ||
				(spec[2] !== false && today.getDate() !== spec[2])){
			return false;
		}
		return true;
	};

	SopaBlackout.VERSION = '0.2.0';
	SopaBlackout.MIN_HEIGHT = 100;
	SopaBlackout.HEADER_TEXT = "This is what the web could look like under the Stop Online Piracy Act.";
	SopaBlackout.CONTINUE_TEXT = "(click anywhere to continue)";
	SopaBlackout.ZINDEX = Math.pow(2, 31) - 2;
	SopaBlackout.DEFAULTS = {
		'id': false,
		'srsbzns': false,
		'on': false
	};
	SopaBlackout.blackout = function(opts){
		var obj;
		var body = document.body;
		if (opts['id'] === false){
			obj = body;
			height = "100%";
		}else{
			obj = document.getElementById(opts['id']);
			var height = parseInt(getStyle(obj, 'height'), 10);
			height = height > SopaBlackout.MIN_HEIGHT ? height : SopaBlackout.MIN_HEIGHT;
		}
		var offsets = findPos(obj);

		var blackout = create('div', {
				position: 'absolute',
				top: offsets[1],
				width: '100%',
				backgroundColor: 'black',
				textAlign: 'center',
				paddingTop: '10px',
				zIndex: SopaBlackout.ZINDEX,
				height: height,
				color: '#999'},
			create('h1', {color: '#999'}, txt(SopaBlackout.HEADER_TEXT)),
			create('p', null,
				txt("Keep the web open. "),
			create('a', {href: "https://wfc2.wiredforchange.com/o/9042/p/dia/action/public/?action_KEY=8173"}, txt("Contact your representatives")),
				txt(" or "),
				create('a', {href: "http://sopablackout.org/learnmore"}, txt("find out more")))
		);
		if (opts['srsbzns'] !== true){
			blackout.appendChild(create('p', {paddingTop: '250px', color: '#333'}, txt(SopaBlackout.CONTINUE_TEXT)));
			addEvent(blackout, 'click', function(e){
				body.removeChild(blackout);
			});
		}
		body.appendChild(blackout);
	};
	SopaBlackout.go = function(){
		var opts = getOpts();
		if (opts['on'] !== false && !dateMatches(opts['on'])){
			return;
		}
		SopaBlackout.blackout(opts);
	};

	onDomReady(SopaBlackout.go);
}).call(this);