ID:1346680
 
This'll create a 'Save Draft' and 'Load Draft' button after the 'Preview' button on the reply box. Not sure about thems other browsers, maybe I'll look into it if demand is high enough.

Note: Doesn't work on quote replies or editing your posts. The quotes and edits are gonna be tricky since they load using AJAX -- might not be worth the effort. Also, the buttons go away after saving your post, I'm gonna investigate catching the AJAX calls so I can dump some buttons into the results.

Current version: 5

// ==UserScript==
// @name BYOND_Drafts
// @namespace Drafts
// @description Saves and loads post drafts. (By Nadrew)
// @include http://www.byond.com/forum/?post=*
// @include http://www.byond.com/forum/?forum=*&command=add_post
// @version 5
// @grant none
// ==/UserScript==

function CreateElements() {
// Create a save button, a load button, and a span to display some text in.

var draft_save = document.createElement('input');
var draft_load = document.createElement('input');
var draft_info = document.createElement('span');

// Set all the attributes of our new elements here...
with(draft_save) {
setAttribute('value','Save Draft');
setAttribute('type','button');
addEventListener('click',function () {SaveDraft(false);},true);
}

with(draft_load) {
setAttribute('value','Load Draft');
setAttribute('type','button');
addEventListener('click',LoadDraft,true);
}

with(draft_info) {
setAttribute('id','draft_info');
}

// Make sure everything exists like it should and append/insert the elements into the document as needed.
if(draft_save && draft_load && draft_info) {
var inputs = document.getElementsByTagName('input');

// Since the inputs (or their parent div) don't have id fields we need to loop over the document's inputs and find the 'Preview' value.
// Using that we'll stick our elements in after it, and the info span at the end of the div.
for(input in inputs) {
var input_element = inputs[input];
if(input_element.value == 'Preview') {
input_element.parentNode.insertBefore(draft_load,input_element.nextSibling);
input_element.parentNode.insertBefore(draft_save,input_element.nextSibling);
input_element.parentNode.appendChild(draft_info);
break;
}
}
}
}

function SaveDraft(confirmed=false) {
// Saves the post text to the window's localStorage, which requires Firefox 2+ and Chrome 4+
var input_box = document.getElementById('message');
var info = document.getElementById('draft_info');
info.innerHTML = '';
if(!input_box) input_box = document.getElementById('message_1'); // New posts.
if(!input_box) return;
if(!input_box.value || input_box.value == '') {
if(!confirmed) {
info.innerHTML = '<b><font color="red">Warning:</font></b> This will delete your saved draft. ';
var delete_link = document.createElement('a');
delete_link.style = 'cursor: pointer;';
delete_link.innerHTML = '[Click here to confirm]';
delete_link.addEventListener('click',function() { SaveDraft(true); },true);
info.appendChild(delete_link);
return;
}
}
var draft_text = escape(input_box.value);
if(!localStorage) {
info.innerHTML = 'Your browser does not support this function.';
return;
}
localStorage.setItem('byond_draft',draft_text);
if(info) {
var save_text = 'saved!';
if(confirmed) {
save_text = 'cleared!';
localStorage.removeItem('byond_draft');
}
info.innerHTML = 'Draft successfully ' + save_text
}
}

function LoadDraft() {
// And loads it back up as needed.
var input_box = document.getElementById('message');
var info = document.getElementById('draft_info');
if(!input_box) input_box = document.getElementById('message_1');
if(!input_box) return;
info.innerHTML = '';
var draft_value;
if(!localStorage) {
info.innerHTML = 'Your browser does not support this function.';
return;
}
if(localStorage.byond_draft) {
draft_value = unescape(localStorage.getItem('byond_draft'));
input_box.value = draft_value;
info.innerHTML = 'Draft successfully loaded!';
}

else {
info.innerHTML = 'No draft data to load.';
}
}

CreateElements();


[Version 2]

Updated to work with new topics.

[Version 3]

Updated the method of clearing your draft, instead of using javascript's confirm() it now uses a confirmation link in the same place as the information text.

[Versions 4-5]

Updated to use localStorage, which is supported by Firefox 2.5+ and Chrome 4+, a loooot easier to manage data, and generally around 5MB to work with as opposed to 4KB for cookies.
I'm also finding there are limitations to the length you can set for cookies, so this probably won't work on longer posts. Researching other methods of storing the data, but as far as I'm aware javascript is really limited in that regard. Things like file storage aren't really possible in enough cases to be reliable.

I don't think there's a reliable method of going clipboard manipulation in javascript anymore either, was too much of a security issue. Aside from storing them server-side and using AJAX to send a request to my own server I'm not sure what kind of options I have. Will post more information as I learn it, learning is a slow process on the ol' dial-up.


... could always make an actual Firefox/Chrome plugin for it, but that might be overkill. Would be a good learning adventure though.

[Problem solved]
Could you pipe the text to a cached file corresponding with the post ID and just check the cache for the file when loading a post?

Chrome extensions are pretty fun and easy!
I'm actually gonna use the WebStorage standard that was introduced for HTML5 but expanded on its own. It won't support all browsers, but it'll support the ones listed below:

"Web storage is being standardized by the World Wide Web Consortium (W3C). It was originally part of the HTML 5 specification, but is now in a separate specification. It is supported by Internet Explorer 8, Mozilla-based browsers (e.g., Firefox 2+, officially from 3.5), Safari 4, Google Chrome 4 (sessionStorage is from 5), and Opera 10.50. As of 14 March 2011 Opera and IE9 supports the storage events."

So Chrome and Firefox are covered pretty well, so Greasemonkey is handled. It'll also make it easier to support multiple drafts across multiple posts.
Updated to use localStorage. (also split this into its own topic)
Very neat, Nadrew. Good job.