Script Details
File Name: ipboard_postsaver.user.js
Description
Nothing is worse than typing a long post, and then losing it because "the connection with the server was reset" or some other random technical error occurred. And I'm not a fan of typing in third party-apps, and then pasting my text elsewhere, so I wrote this script to auto-save the post text to the system clipboard, where it can be retrieved with a Paste, or to Greasemonkey storage, where it can be retrieved via Tools >> Greasemonkey >> User Script Commands, before the post is submitted. As you might have guessed by the script name, this works on IP Boards only.

Script Source
// IP.Board: Post Saver
// Copyright (c) 2006-2009 Orbona
// Version 1.1
// Release Date: 2009-04-23
//
// See also: http://www.orbona.com/greasemonkey/
//
// Original file name: ipboard_postsaver.user.js
// Please reference the original file name when contacting me regarding this
// script.
// .
//
// This software is licensed under the CC-GNU GPL:
// http://creativecommons.org/license/cc-gpl
//
//-----------------------------------------------------------------------------
// DESCRIPTION
//
// This script was created for use on Invision Power Boards (IP.Board, see
// http://www.invisionpower.com).
//
// This script modifies the page so that posts are automatically copied to
// the system clipboard or to Greasemonkey storage when a post is submitted.
// Since the "copy" is performed before the page unloads, posts will never
// be lost again (well, unless changes to the site or to Greasemonkey break
// this script). This is quite handy, because on TWoP, returning to the
// "add/edit post form" doesn't always show you a cached version of what was
// typed. When this script is used, if a "submit" doesn't complete properly,
// a "Paste" or Tools >> Greasemonkey >> User Script Commands will give you
// back your post.
//
// WARNING: (1) When you submit a post, any text already on the system
// clipboard will be overwritten.
//
// (2) Obviously, a subsequent "cut" or "copy" will overwrite the
// post data on the system clipboard, so it's a good idea to
// see if your post got "eaten" before doing any more text
// editing in any application.
//-----------------------------------------------------------------------------
// ==UserScript==
// @name IP.Board: Post Saver
// @description Automatically copies posts when submitting
// @namespace http://www.orbona.com/greasemonkey/
// @include http://forums.televisionwithoutpity.com/index.php*
// @include http://www2.konfabulator.com/forums/index.php*
// ==/UserScript==
var postContentIDName = 'ed-0_textarea';
var gotEditor = true;
//-----------------------------------------------------------------------------
// A wrapper for the main "copyPostToClipboard" method added to the main
// document. Exists so we can use it in "addEventListener" and method
// redefinitions
//-----------------------------------------------------------------------------
function copyPostToClipboardWrapper (event) {
if (GM_getValue('useclip', "2")=="1")
unsafeWindow.copyPostToClipboard();
else {
var postContentElem = document.getElementById(postContentIDName);
if (postContentElem) GM_setValue('posttext', postContentElem.value);
}
this._submit(); // call real submit function
}
//-----------------------------------------------------------------------------
// Retrieves the post from Greasmonkey storage. If the user is currently
// saving to the system clipboard, then the most recently edited post won't
// be here. Selecting 'ok' on the prompt window will paste the last post
// contents into the post body text box.
//-----------------------------------------------------------------------------
function retrievePost(e) {
var lastPost=GM_getValue('posttext', "");
var ans = prompt('Here is your last saved post:', lastPost.replace(/\n/g,'\\n'));
if (ans) {
var postContentElem = document.getElementById(postContentIDName);
if (postContentElem) {
postContentElem.value += lastPost;
if (gotEditor) {
unsafeWindow.IPS_editor['ed-0'].editor_set_content( postContentElem.value );
unsafeWindow.IPS_editor['ed-0'].focus();
}
else
postContentElem.focus();
}
}
}
//-----------------------------------------------------------------------------
// Prompts for save location for the post text and sets the post to be saved
// to the clipboard or a Greasemonkey configuration variable.
//-----------------------------------------------------------------------------
function enterSaveLocation (e) {
var saveToClipboard = GM_getValue('useclip', "2")=="1";
var msg = "Your posts are currently saved to ";
msg += saveToClipboard ? "the system clipboard.\n\n" : "Greasemonkey storage.\n\n";
msg += "To save to the system clipboard, which requires special configuration, enter a \"1\".\nTo save to Greasemonkey storage, enter a \"2\".";
var reply = prompt(msg, saveToClipboard ? "1" : "2");
if (!reply) return;
if (reply != "2" && reply !="1")
alert ("You have entered an invalid choice. Save location has not been changed.");
else
GM_setValue('useclip', reply);
}
// ----------------------------------------------------------------------------
// Main function that does everything described in the description area above.
// ----------------------------------------------------------------------------
function doIt() {
GM_registerMenuCommand('IP Board: Set post save location ...', enterSaveLocation, "l", "shift alt", "l");
GM_registerMenuCommand('IP Board: Retrieve post data from Greasemonkey storage', retrievePost, "r", "shift alt", "r");
var script;
var postContentElem = document.getElementById(postContentIDName);
if (!postContentElem) {
gotEditor = false;
postContentIDName = 'postcontent';
postContentElem = document.getElementById(postContentIDName);
}
if (postContentElem) {
// Greasemonkey doesn't recognize the "netscape" (used below) and GM
// doesn't currently provide access to the system clipboard. So, I'm
// forced to add this javascript to the main document and call it
// via my wrapper see below). Will modify in the future if a better
// way presents itself.
// see also: http://www.febooti.com/support/website-help/website-javascript-copy-clipboard.html
// see also: http://developer.mozilla.org/en/docs/Using_the_Clipboard
// see also: http://www.xulplanet.com/tutorials/mozsdk/clipboard.php
script = document.createElement('script');
script.type = 'text/javascript';
script.innerHTML = 'function copyPostToClipboard() {var copytext=document.REPLIER.Post.value; var clipboard, transferable,clipboardID, str; try{ netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); } catch(e){ alert(e); } try{ clipboard=Components.classes["@mozilla.org/widget/clipboard;1"].createInstance(Components.interfaces.nsIClipboard); }catch(e){ alert(e); } try{ transferable=Components.classes["@mozilla.org/widget/transferable;1"].createInstance(Components.interfaces.nsITransferable); }catch(e){ alert(e); } transferable.addDataFlavor("text/unicode"); str=Components.classes["@mozilla.org/supports-string;1"].createInstance(Components.interfaces.nsISupportsString); str.data=copytext; transferable.setTransferData("text/unicode",str,str.data.length*2); try{ clipboardID=Components.interfaces.nsIClipboard; } catch(e){ alert(e); } clipboard.setData(transferable,null,clipboardID.kGlobalClipboard); }';
document.body.appendChild(script);
var submitForm = document.getElementById('postingform');
submitForm.addEventListener('submit', copyPostToClipboardWrapper, true);
}
}
// ------------------END OF FUNCTIONS -----------------------------
window.addEventListener("load", function() { doIt(); }, false);
//capture any post text for any submitted forms, because I really hate losing
//what I typed
window.addEventListener('submit', copyPostToClipboardWrapper, true);
// If a script calls someForm.submit(), the onsubmit event does not fire,
// so we need to redefine the submit method of the HTMLFormElement class
// and we want to copy that post no matter how it is submitted
HTMLFormElement.prototype._submit = HTMLFormElement.prototype.submit;
HTMLFormElement.prototype.submit = copyPostToClipboardWrapper;