// ==UserScript==
// @name Hide objects until double click (Flash block)
// @author TarquinWJ 
// @namespace http://www.howtocreate.co.uk/ 
// @version 2.1
// @description  Hides all embedded objects until you double click on
//			the page.
// @ujs:category general: enhancements
// @ujs:published 2005-10-29 20:00
// @ujs:modified 2005-10-29 23:01
// @ujs:documentation http://userjs.org/scripts/general/enhancements/hide-objects 
// @ujs:download http://userjs.org/scripts/download/general/enhancements/hide-objects.js
// ==/UserScript==


/* 
 * Please see
 * http://www.howtocreate.co.uk/operaStuff/userJavaScript.html#terms
 * for License and Terms of Use
 */

(function () {

//specify elements to hide
var typesToHide = ['object','embed','applet','iframe'];

//timeout to hide notification (in milliseconds) - 0 for no notification
var hideNoticeIn = 5000;

//should it show a placeholder for each hidden element - can be clicked to re-show
var showPlaceholder = true;

//should it show the address of the blocked object when you hold your mouse over the placeholders
var showTooltip = true;

// ***stop editing***

var hiddenAlready = [], hasDoneOneReshow, hasHiddenSomething = 0, hasAllowedSomething = [], foo, fooInt, oProtectNum = -1, oProtectType = /^(image\/|text\/|application\/.*xml$)/;

for( var i = 0; typesToHide[i]; i++ ) {
	//dynamic objects - Opera will keep these updated
	if( typesToHide[i] == 'object' ) { oProtectNum = i; }
	typesToHide[i] = document.getElementsByTagName(typesToHide[i]);
	hiddenAlready[i] = 0;
	hasAllowedSomething[i] = 0;
}

function titleCas(oWord) {
	return oWord.charAt(0).toUpperCase()+oWord.substr(1).toLowerCase();
}

function checkForMoreHide() {
	//check if any more have been added since we last checked
	for( var x = 0, y; y = typesToHide[x]; x++ ) {
		for( var z = hiddenAlready[x] + hasAllowedSomething[x], oEl, oAt; oEl = y[z]; z++ ) {
			//do not hide objects if they are being viewed on their own
			if( !z && ( document.body.firstChild == document.body.lastChild ) && ( oEl == document.body.firstChild ) ) { return; }
			if( ( x == oProtectNum ) && ( oAt = oEl.getAttribute('type') ) && oAt.match(oProtectType) ) {
				//allow certain data types of objects
				hasAllowedSomething[x]++;
				continue;
			}
			if( showPlaceholder ) {
				//make a clickable placeholder
				var oPH = document.createElement('hidobplhld');
				oPH.appendChild(document.createTextNode(titleCas(oEl.tagName)+' hidden. Click here to show.'));
				oPH.onclick = function () {
					//show this, and if it is an object, show child embeds as well
					if( this.actobj.tagName.toLowerCase() == 'object' ) {
						//objects fall back. so do other elements, but objects are special imho, so fallback children will be shown
						for( var n = 0, m = ['embed','object'], l; l = m[n]; n++ ) {
							for( var i = 0, j = this.actobj.getElementsByTagName(l), k; k = j[i]; i++ ) {
								if( k.style.wasDsspMod ) { k.style.noticelm.onclick(); }
							}
						}
					}
					this.actobj.style.display = this.actobj.style.olddisplay;
					this.actobj.style.wasDsspMod = false;
					if(showTooltip) { document.body.removeChild(this.fauxtitle); }
					this.parentNode.removeChild(this);
				};
				//try to find appropriate size - offsetFoo reports 0 if falling back or if parent is set to display:none;
				var oTmpSty = oEl.getAttribute('height');
				oTmpSty = 'height:' + ( ( oTmpSty ? parseInt( oTmpSty ) : ( oEl.offsetHeight ? oEl.offsetHeight : 50 ) ) - 2 ) + 'px;';
				var oTmpSty2 = oEl.getAttribute('width');
				oTmpSty2 = 'width:' + ( ( oTmpSty2 ? parseInt( oTmpSty2 ) : ( oEl.offsetWidth ? oEl.offsetWidth : 150 ) ) - 2 ) + 'px;';
				oPH.setAttribute('style','display:inline-block;cursor:crosshair;overflow:hidden;border:1px solid #000;background-color:#ddd;color:#000;'+oTmpSty+oTmpSty2);
				if( showTooltip ) {
					//try to get the address of the blocked item
					var oTitle = oEl.getAttribute('src') ? oEl.getAttribute('src') : ( oEl.getAttribute('data') ? oEl.getAttribute('data') : oEl.getAttribute('movie') );
					if( !oTitle && oEl.tagName.toLowerCase() == 'object' ) {
						for( var i = 0, j; j = oEl.childNodes[i]; i++ ) {
							if( !j.tagName || j.tagName.toLowerCase() != 'param' ) { continue; }
							var pName = j.getAttribute('name').toLowerCase();
							if( ( pName == 'data' ) || ( pName == 'movie' ) || ( pName == 'src' ) ) {
								oTitle = j.getAttribute('value');
								if( oTitle ) { break; }
							}
						}
					}
					if( !oTitle && ( oEl.codebase || oEl.code ) ) {
						oTitle = ( oEl.codebase ? oEl.codebase : '' ) + ( oEl.code ? oEl.code : '' );
					}
					if( oTitle ) {
						if( oTitle.length > 70 ) {
							oTitle = oTitle.substr(0,45) + ' ... ' + oTitle.substr(oTitle.length - 25);
						}
						//title attribute ignored on custom elements, so using DHTML
						oPH.fauxtitle = document.createElement('hidobplhldtoolt');
						oPH.fauxtitle.setAttribute('style','position: absolute;top: 0px;left: 0px;visibility: hidden;border: 1px solid #000;font-size: smaller;color: #000;background-color: #ffffe1;padding: 1px;white-space: nowrap;');
						oPH.fauxtitle.appendChild(document.createTextNode(oTitle));
						oPH.addEventListener('mousemove',function (e) {
							var tY = e.pageY + 22, tX = e.pageX + 10;
							if( tX + this.fauxtitle.offsetWidth + 20 > window.innerWidth + window.pageXOffset ) { tX = window.innerWidth + window.pageXOffset - ( this.fauxtitle.offsetWidth + 20 ); }
							if( tY + this.fauxtitle.offsetHeight + 20 > window.innerHeight + window.pageYOffset ) { tY = e.pageY - ( this.fauxtitle.offsetHeight + 20 ); }
							this.fauxtitle.style.top = tY + 'px';
							this.fauxtitle.style.left = tX + 'px';
							if( !this.isO ) {
								this.fauxtitle.style.visibility = 'visible';
								this.isO = true;
							}
						},false);
						oPH.addEventListener('mouseout',function () {
							this.fauxtitle.style.visibility = 'hidden';
							this.fauxtitle.style.top = '0px';
							this.fauxtitle.style.left = '0px';
							this.isO = false;
						},false);
						document.body.appendChild(oPH.fauxtitle);
					}
				}
				oEl.parentNode.insertBefore(oPH,oEl);
				//preserve pointers between elements so that download-embeds script does not conflict
				oPH.actobj = oEl;
				oEl.style.noticelm = oPH;
			}
			//hide the element
			oEl.style.wasDsspMod = true;
			oEl.style.olddisplay = oEl.style.display ? oEl.style.display : '';
			oEl.style.display = 'none';
			hasHiddenSomething++;
		}
		hiddenAlready[x] = z;
	}
}
var oIntR = setInterval(checkForMoreHide,200);

document.addEventListener('load',function () {
	clearInterval(oIntR); //stop checking
	checkForMoreHide(); //one last time
	if( !hasHiddenSomething ) { return; }
	document.documentElement.addEventListener('dblclick',function () {
		//add a double click listener to make all elements reappear
		if( hasDoneOneReshow ) { return; }
		hasDoneOneReshow = true;
		for( var x = 0, y; y = typesToHide[x]; x++ ) {
			for( var z = 0, oEl; z < hiddenAlready[x] && ( oEl = y[z]) ; z++ ) {
				if( oEl.style.wasDsspMod ) {
					oEl.style.display = oEl.style.olddisplay;
					if( showPlaceholder ) { if(showTooltip) { document.body.removeChild(oEl.style.noticelm.fauxtitle); } oEl.parentNode.removeChild(oEl.style.noticelm); }
				}
			}
		}
	},false);
	if( hideNoticeIn ) {
		//show a notice if required
		foo = document.createElement('sayaboutembeds');
		foo.appendChild(document.createTextNode((hasHiddenSomething--)+' item'+(hasHiddenSomething?'s':'')+' blocked. Double click the page to show '+(hasHiddenSomething?'them':'it')+'.'));
		foo.setAttribute('style','position:absolute;top:0px;right:0px;padding:2px;border:2px dotted red;background-color:#fff;color:red;cursor:crosshair;');
		foo.onclick = function () { clearTimeout(fooInt); this.parentNode.removeChild(this); };
		document.body.appendChild(foo);
		fooInt = setTimeout(function () { foo.parentNode.removeChild(foo); },hideNoticeIn);
	}
},false);

})();
