Click to install this script

IP Board: Post Saver

  • Added: October 27, 2007
  • Last Updated: October 27, 2007

File Name: ipboard_postsaver.user.js

Click to hide sectionDescription

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.

Screenshot of functionality added by script

Click to hide sectionScript Source

// IP.Board: Post Saver // Copyright (c) 2006-2009 Orbona // Version 1.1 // Release Date: 2009-04-23 // // See also: // // 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: // // //----------------------------------------------------------------------------- // DESCRIPTION // // This script was created for use on Invision Power Boards (IP.Board, see // // // 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 // @include* // @include* // ==/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: // see also: // see also: script = document.createElement('script'); script.type = 'text/javascript'; script.innerHTML = 'function copyPostToClipboard() {var copytext=document.REPLIER.Post.value; var clipboard, transferable,clipboardID, str; try{"UniversalXPConnect"); } catch(e){ alert(e); } try{ clipboard=Components.classes[";1"].createInstance(Components.interfaces.nsIClipboard); }catch(e){ alert(e); } try{ transferable=Components.classes[";1"].createInstance(Components.interfaces.nsITransferable); }catch(e){ alert(e); } transferable.addDataFlavor("text/unicode"); str=Components.classes[";1"].createInstance(Components.interfaces.nsISupportsString);; transferable.setTransferData("text/unicode",str,*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;