Userscripts.org Preview Posts

By JoeSimmons Last update Dec 21, 2012 — Installed 571 times.

There are 38 previous versions of this script.

// ==UserScript==
// @name           Userscripts.org Preview Posts
// @namespace      http://userscripts.org/users/23652
// @description    Allows previewing of userscripts.org posts and post edits with auto-update
// @include        http://userscripts.org/topics/*
// @include        https://userscripts.org/topics/*
// @require        http://userscripts.org/scripts/source/51532.user.js
// @require        http://usocheckup.redirectme.net/47771.js
// @grant GM_getValue
// @grant GM_log
// @grant GM_openInTab
// @grant GM_registerMenuCommand
// @grant GM_setValue
// @grant GM_xmlhttpRequest
// @copyright      JoeSimmons
// @version        1.2.0
// @license        Creative Commons Attribution-Noncommercial 3.0 United States License
// ==/UserScript==

function insertAfter(node, pnode) {try {pnode.parentNode.insertBefore(node, pnode.nextSibling);}catch(e){}}

// Don't run if in a frame or if page doesn't have reply/newtopic section
if(top.location!=location || !document.body || (!$g('#reply')&&!$g('#new_topic'))) return;

// Create by avg, modified by JoeSimmons
function create(a,b) {
	var ret=document.createElement(a);
	if(b) for(var prop in b) {
		if(prop.indexOf('on')==0) ret.addEventListener(prop.substring(2),b[prop],false);
		else if(prop=="kids" && (prop=b[prop])) {
			for(var i=0;i<prop.length;i++) ret.appendChild(prop[i]);
		}
		else if('style,accesskey,id,name,src,href,class'.indexOf(prop)!=-1) ret.setAttribute(prop, b[prop]);
		else ret[prop]=b[prop];
	}  return ret;
}

function preview() {
	var post = $g('#'+postid).value.replace(/\n/g,'<br>'),
		link_re = /(?![^"=><]+)(https?:\/\/)?([a-z0-9-]+\.)?[a-z0-9-]+\.(dk|com|net|org|se|no|nl|us|uk|de|it|nu|edu|info|co\.nr)\/?([^<>"=]+)?\s*\b/i;
	if(post.length<1) return;
	if(link_re.test(post)) post=post.replace(link_re, function(r){alert(r);return "<a href=\""+r+"\">"+r+"</a>";});
	$g('#uso_preview_frame').innerHTML = post;
	$g('#uso_preview_div').style.display = '';
}

// Kill script if not logged in
if($g(".//a[starts-with(@href,'/login') or starts-with(@href,'/signup')]",{type:3,node:$g('#homeBox')})) return;

// Determine what post area should be previewed when button is clicked
var postid = ((window.location.href.indexOf('/topics/new')!=-1)?'topic':'post') + '_body';

// Global variables
var node,
	width = window.innerWidth,
	height = window.innerHeight,
	url = window.location.href;

// Create preview button to go on reply and new post area
var preview = create('input', {
value:'Preview',type:'button',title:'Full Page Preview',id:'uso_preview_button',style:'margin:0 0 0 4px;',onclick:preview});

// Set up the previewing box
document.body.appendChild(create('div', {
id:'uso_preview_div',
ondblclick:function(e){this.style.display='none'},
style:'z-index:99; position:fixed; top:0; left:0; width:100%; height:100%; background:url(\'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAK3RFWHRDcmVhdGlvbiBUaW1lAFRodSA3IEp1biAyMDA3IDE5OjMzOjIyIC0wODAwwDv6agAAAAd0SU1FB9cGCAIiHDkslXkAAAAJcEhZcwAALiMAAC4jAXilP3YAAAAEZ0FNQQAAsY8L/GEFAAAAMElEQVR42u3OQREAAAjDsIF/T1jjUMEnNdBUkslj/TkHAAAAAAAAAAAAAAAAAAC4FhnWAP/rGcSaAAAAAElFTkSuQmCC\'); text-align:center; display:none;',
kids:new Array(
// Create the frame
create('div',{id:'preview_holder',style:'border:3px solid #2D96FF; width:75%; height:80%; max-height:80%; background:#fff; margin-left:auto; margin-right:auto; margin-top:4%; overflow:auto;',kids:new Array(create('table', {class:'posts',kids:new Array(create('tr',{class:'post hentry',kids:new Array(create('td',{id:'uso_preview_frame',class:'body'}))}))}))}),
// Create the line break
create('br'),
// Create the close frame link
create('input', {id:'close_preview',type:'button',value:'Close This Preview',onclick:function(){$g('#uso_preview_div').style.display='none';}})
)}));

// Attach a listener to the reply link so if they cancel an edit box, and start a new reply, the script will use the reply textarea not the edit textarea
var reply = $g("//a[.='Reply to topic']", {type:9});
if(reply) reply.addEventListener('click', function(){postid='post_body';}, false);

// Attach a listener to the edit links so it works on them as well
var edits = $g("//a[contains(@href, '/edit') and .='Edit post']"),
	i = edits.snapshotLength;
while(edit=edits.snapshotItem(--i)) {
	edit.addEventListener('click', function() {
		$g('#uso_preview_edit_button', {del:true});
		postid = 'edit_post_body'; // Change the target of the preview so it doesn't use the new reply's text
		// Create preview button for edit area
		var preview_edit = create('input', {
		value:'Preview',type:'button',title:'Full Page Preview',id:'uso_preview_edit_button',style:'margin:0 0 0 4px;',onclick:preview});
		$g('#edit').appendChild(create('div', {id:'test_exist_previewposts',style:'display:none;'}));
		var intv = setInterval(function() {
			if(!$g('#test_exist_previewposts')) {
				clearInterval(intv); // Stop checking if edit box is up yet
				node = $g(".//input[@name='commit']", {type:9, node:$g('#edit')}); // Save changes button
				if(node && node.parentNode) insertAfter(preview_edit, node); // Add preview button beside Save changes
					else alert('Error. Could not add preview button to edit reply area.');
			}
		}, 250);
	}, false);
}

// Determine where to add the preview button and add it
if(url.indexOf('topics/new?')!=-1) {
	node = $g(".//input[@name='commit']", {type:9, node:$g('#new_topic')});
	if(node && node.parentNode) insertAfter(preview, node); // Add preview button beside Post topic
		else alert('Error. Could not add preview button to new topic area.');
}
else if(/topics\/\d+/.test(url)) {
	node = $g(".//input[@name='commit']", {type:9, node:$g('#reply')});
	if(node && node.parentNode) insertAfter(preview, node); // Add preview button beside Post reply
		else alert('Error. Could not add preview button to new reply area.');
}