All pastes #123589 Raw Edit

WhiteAcid

public javascript v1 · immutable
·published 2006-08-09 12:27 UTC
rendered paste body
// ==UserScript==// @name          IPB Thread Preview 1.2// @description	  Previews the first post of a thread in IPB letting you quickly read those threads with vague titles where you're not sure actually loading the page is worth your time.// @include       http://www.criticalsecurity.net/*// @include       http://forums.invisionpower.com/*// ==/UserScript==/*	Thanks to henke37 for the idea and for pointers throughout	Thanks to OutThere for how to make the regexes non-greedy	Thanks to IceShaman for the idea of using the lo-fi version	Thanks to all the CriticalSecurity members who have told me about the many bugs as well as what features they want.*///Variables the user can easily edit://These refer to the box with the preview inside itwidth = 250 //default 250height = 80 //default 80background_colour = '#bcd0ed' //default #bcd0edborder_width = 1 //default 1border_colour = '#2f5d89' //default #2f5d89//These refer to what you want various things replaced by, for instance if you want images replaced by the text [image] or if you just want them removed//Set the variable to false (boolean, not string) if you do not want to remove the element at all.smiley = "" //default <blank string>image = "[image]" //default [image]quote = "[quote]" //default [quote]code = "[code]" //default [code]//End of user controlled variables//Given an array of lines (of XHTML), find the first line containing a postfunction findPost(lines){	for (i=0; i<lines.length; i++)		if (lines[i].search("<div class='postcontent'>") > -1)			return i	return false //error}//Given the XHTML of a post, remove stuff you don't want in the preview boxfunction stripTags(post){	if (!isNaN(smiley.length))		post = post.replace(/<img src=".+?\/style_emoticons\/.+?" border="\d+" alt=".+?" \/>/g,smiley)	if (!isNaN(image.length))		post = post.replace(/<img src=".+?" [^emoid] border="\d+" alt=".+?" \/>/g,image)	if (!isNaN(quote.length))	{		post = post.replace(/<!--QuoteBegin-?(.*?)-->.+?<!--QuoteEnd-->/g,quote)		post = post.replace(/<!--quoteo-?(.*?)-->.+?<!--QuoteEEnd-->/g,quote)	}	if (!isNaN(code.length))	{		post = post.replace(/<!--c1--><div class='codetop'>CODE<\/div><div class='codemain'><!--ec1-->.+?<!--c2--><\/div><!--ec2-->/gi,code)		post = post.replace(/<!--html--><div class='htmltop'>HTML<\/div><div class='htmlmain'><!--html1-->.+?<!--html2--><\/div><!--html3-->/gi,code)		post = post.replace(/<!--sql--><div class='sqltop'>SQL<\/div><div class='sqlmain'><!--sql1-->.+?<!--sql2--><\/div><!--sql3-->/gi,code)		post = post.replace(/<div class='codetop'>CODE<\/div><div class='codemain' style='height\:200px;white\-space\:pre;overflow\:auto'>.+?<\/div>/gi,code)	}	return post}//Given the HTML of a thread, return the first and last post after removing all unneeded tags like imagesfunction parseThread(html){	lines = html.split("\n")		/*The thread may contain more than 1 page, lofi has 50 posts per page. We cannot use the HTTP HEAD command to see if the pages exist because they are dynamic	so instead we simply parse out the number of pages, multiply by 50 and get the page that way.*/	for (i=0; i<lines.length; i++)	{		//If the Pages: line was found		if (lines[i].substring(0,7) == "Pages: " && lines[i-1] == "  <div class='ipbpagespan'>")		{			document.getElementById('preview_div').innerHTML = "multiple pages found, loading newest"			line = lines[i].split(".html'>")			max_page = parseInt(line[line.length-1]) -1 //count from 0, not 1			max_page *= 50			link2 = "lofiversion/index.php/t"+topic+"-"+max_page+".html" //link to latest page						var xhReq = new XMLHttpRequest();			xhReq.open("GET", link2, false); //false signifies a synchronous request, so it's done straight away.			xhReq.send(null);			html += xhReq.responseText //append html of last page		}	}	lines		= html.split("\n") // re-split because new stuff may have been added	post1_html	= lines[findPost(lines)+1]	lines.reverse()	post2_html	= lines[findPost(lines)-1]		//get rid of all tags	post1_html	= stripTags(post1_html)	post2_html	= stripTags(post2_html)	posts		= {post1:post1_html,post2:post2_html}	return posts}//the main functionfunction show_preview(obj,flag_first){	link = obj.alt		//Get the url of the thread from the lofi version of the board	topic_start	= link.search(/\d+/) //Find where the number start	temp		= link.substring(topic_start,link.length).search(/\D/) //Find what's after the numbers	topic_end	= (temp>0)?temp:link.length-topic_start //since maybe nothing after numbers account for that	topic		= link.substr(topic_start,topic_end) //get the total thread number	domain		= location.href.substr(0,location.href.substring(8,location.href.length).indexOf("/")+8) //get the domain name	link		= domain+"/lofiversion/index.php/t"+topic+".html" //get the final link		box = document.getElementById('preview_div')	box.innerHTML = "loading..."	//Build the object I'll send via GM_xmlhttpRequest()	obj_thread =	{		method:"GET",		url:link,		headers:{"User-Agent":navigator.userAgent},		onload:function(details)		{			posts = parseThread(details.responseText)			if (flag_first == true) //if we want to show the first post				box.innerHTML = posts.post1			else //if we want to show the last post				box.innerHTML = posts.post2			//Store into post_cache			thread = {url:link,html:posts}			post_cache[post_cache.length] = thread		}	}		//Check if this page has already been requested	found = -1	for (i=0; i<post_cache.length; i++)	{		if (post_cache[i].url == link)		{			found = i			break		}	}		if (found == -1) //if not found request the page		GM_xmlhttpRequest(obj_thread)	else //else get the page from the cache	{		if (flag_first == true) //if we want to show the first post			box.innerHTML = post_cache[i].html.post1		else //if we want to show the last post			box.innerHTML = post_cache[i].html.post2	}		//position and display the box	box.style.display = 'block'	coords = findPos(obj)	if (flag_first == true)		box.style.left = coords.left-(125)+'px'	else		box.style.left = coords.left-(200)+'px'	box.style.left	= (parseInt(box.style.left) < 0)? '2px':box.style.left    box.style.top	= coords.top+(obj.offsetHeight)+'px'}//Create hover boxobj = document.getElementById('logostrip')obj.innerHTML += "<div id='preview_div' onmouseover='clearTimeout(timer2)' onmouseout='_this=this;timer2=setTimeout(\"hideMe(_this)\",200)'><p>loading...</p></div>"//copy the functions into the document so event handlers can call it (thanks to http://blog.monstuff.com/archives/000274.html)unsafeWindow.eval("post_cache = new Array()")unsafeWindow.eval(show_preview.toString())unsafeWindow.eval(findPos.toString())unsafeWindow.eval(hide_preview.toString())unsafeWindow.eval(hideMe.toString())//Add some CSSGM_addStyle('#preview_div {display: none; position: absolute; width:'+width+'px; height:'+height+'px; overflow-y:scroll; background-color:'+background_colour+'; border: '+border_width+'px solid '+border_colour+';}')GM_addStyle('#preview_div * {margin-top:-2px;margin-left:1px;background:transparent;}')thread_links = document.getElementsByTagName('a') //returns an array of all link tags)//Create the eye image objectseye_first = document.createElement("img")eye_first.setAttribute("src","http://blog.whiteacid.org/wp-content/uploads/2006/04/eye.gif")eye_first.setAttribute("onmouseout","_this=this;timer2=setTimeout('hide_preview(this)',200);clearTimeout(timer)")		eye_first.setAttribute("onmouseover","_this=this;timer=setTimeout('show_preview(_this,true)',300)")eye_last = document.createElement("img")eye_last.setAttribute("src","http://blog.whiteacid.org/wp-content/uploads/2006/04/eye.gif")eye_last.setAttribute("onmouseout","_this=this;timer2=setTimeout('hide_preview(this)',200);clearTimeout(timer)")		eye_last.setAttribute("onmouseover","_this=this;timer=setTimeout('show_preview(_this,false)',300)")for (i=0; i<thread_links.length; i++) //for each link{	link = thread_links[i].href	//Here I want to insert the eye right after the link. there is no insertAfter method	//so instead I'll have to hack a solution using a couple of insertBefores	if (link.search(/\?showtopic=\d+$/) > -1) //If the link goes to a thread	{		eval("eye_f"+i+"=eye_first.cloneNode(false)")		eval("eye_f"+i+".setAttribute('alt','"+link+"')")		eval("thread_links[i].parentNode.insertBefore(eye_f"+i+",thread_links[i])")		eval("thread_links[i].parentNode.insertBefore(thread_links[i],eye_f"+i+")")	}	if (link.search(/\?showtopic=\d+.+?view=getlastpost$/) > -1) //If the link goes to the last post of a thread	{		eval("eye_l"+i+"=eye_last.cloneNode(false)")		eval("eye_l"+i+".setAttribute('alt','"+link+"')")		eval("thread_links[i].parentNode.insertBefore(eye_l"+i+",thread_links[i])")		eval("thread_links[i].parentNode.insertBefore(thread_links[i],eye_l"+i+")")	}}//Functions I won't ever really change://function to hide the preview boxfunction hide_preview(obj){	document.getElementById('preview_div').style.display = 'none'	document.getElementById('preview_div').innerHTML = ""}//Function to find the X and Y co-ordinates of where the box should go. Returns both within a struct, of sortsfunction findPos(obj){	var curtop = 0;	var curleft = 0;    if (obj.offsetParent)    {        while (obj.offsetParent)        {            curtop += obj.offsetTop			curleft += obj.offsetLeft            obj = obj.offsetParent;	        }    }    return {left:curleft,top:curtop}}//general function to hide an object, used on the box's onmouseout eventfunction hideMe(obj){	obj.style.display='none'}