// Yuku: Post Saver
// Copyright (c) 2006-2007 Orbona
// Version 1.0
// Release Date: 2007-10-22
//
// See also: http://www.orbona.com/greasemonkey/
//
// Original file name: yuku_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 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 some message boards,
// 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            Yuku: Post Saver
// @description     Automatically copies posts when submitting
// @namespace       http://www.orbona.com/greasemonkey/
// @include         http://*.yuku.com/forum/*
// @include         http://*.yuku.com/topic/*
// ==/UserScript==
//-----------------------------------------------------------------------------
// 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('body');
      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 NOT paste the last post
// contents into the post body text box since Yuku uses a fancy HTML editor
// and I haven't had time to figure out a fool-proof way to set the inner
// HTML for the editor.  Thus, you'll need to grab the text out of the
// response prompt.
//-----------------------------------------------------------------------------
function retrievePost(e) {
   var lastPost=GM_getValue('posttext', "");
   var ans = prompt('Here is your last saved post:', lastPost.replace(/\n/g,'\\n'));
}

//-----------------------------------------------------------------------------
// 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('Yuku: Set post save location ...',  enterSaveLocation, "l", "shift alt", "l");
   GM_registerMenuCommand('Yuku: Retrieve post data from Greasemonkey storage',  retrievePost, "r", "shift alt", "r");

   var submitForm = document.getElementById('post-form');

   if (!submitForm) submitForm = document.getElementById('quick-reply');

   if (submitForm) {

      // 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
      var script = document.createElement('script');
      script.type = 'text/javascript';
      script.innerHTML = 'function copyPostToClipboard() { var copytext=document.getElementById(\'body\').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);

      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;
