There are 23 previous versions of this script.
Add Syntax Highlighting (this will take a few seconds, probably freezing your browser while it works)
// ==UserScript==
// @name RS Advanced Forums
// @namespace http://www.xfire.com/profile/frostedfreeze/
// @description A script that greatly enhances the RuneScape forums by adding a variety of new features.
// @include http://services.runescape.com/m=forum/*
// @include http://services.runescape.com/m=forum_pt/*
// @include http://services.runescape.com/m=forum_fr/*
// @include http://services.runescape.com/m=forum_de/*
// @require http://sizzlemctwizzle.com/updater.php?id=13002&days=14
// ==/UserScript==
var rD = new Date(1318307623824);
var features = {
'Title Rename': ['Renames the title of the page to your location on the forums.', true],
'Direct Log In': ['Logging in will now send you to the last page you were on. The \'Terms and Conditions\' will no longer appear unless logging in from the main page.', true],
'Quick Log In': ['Allows logging in on the same page. Clicking Log In twice with no username entered will prompt the original log in screen.', true],
'QFC Links': ['Turns all quick find codes into links. If terms "Page" or "Pg" are present, promptly followed by a number, a link to that page will generate. This will also modify the quick find code at the bottom of a thread to a non-session link.', true],
'Quick Reply': ['Adds a reply box to the bottom of an open, non-maxed thread. The quick reply box is based off of the one present on the Stellar Dawn forums. If desired, one may press \'Preview post\' to preview the post in the default reply page.', true],
'Quick Edit': ['Allows the user to edit their post without leaving the page, by converting the HTML data. A box will appear within the post to edit it, and posts will recolor until the server registers the edit. Clicking edit twice or clicking \'Preview post\' will redirect the user to the default edit page.', true],
'Quotes': ['Allows users to use the Jagex Moderator quotes. Quotes will not be visible for users not using this script. BBCode format is [q]text[/q] without a name or [q-name]text[/q] with a name.', true],
'Quick Quotes': ['If \'Quick Reply\' is enabled with this, a link to quote posts will be displayed under a user\'s avatar. Clicking on \'Quote\' will convert the message into the BBCode and place it in the Quick Reply box.', true],
'Recolor Me': ['Recolors your posts to the values stored in the \'myRecolor\' persistent variable.', false],
'Recolor Hidden': ['Hidden posts are recolored red.', true],
'Thread Selecting': ['Threads are selected based on the URL. This occurs when returning to the forum from a thread.', true],
'Thread Recoloring': ['Threads are recolored based on their status and poster. Jagex Moderator threads are recolored yellow while Forum Moderator threads are recolored green. \'Recolor Hidden\' and \'Recolor Me\' will affect this feature.', false],
'Crowns': ['When on the thread list page, golden crowns will be added for Jagex Moderators. This includes Andrew, Paul, Ian, and Avalani. Green crowns will be added for forum moderators.', false],
'Forum Moderator Fix': ['Posts by forum moderators before promotion will render with the green theme. Ex-mods detected will retain their green theme, but the title "Ex-Forum Mod" will be added.', false],
'Search Posts by User': ['When on a user\'s profile, a search box will appear, allowing you to search that user\'s posts. Due to a limit of 100 posts per page, the accuracy of this is limited.', true],
'Bookmarks': ['Allows you to bookmark threads to view on the main page.', false],
'YouTube Links': ['Converts old style YouTube codes into links. Will convert censored text that contains a YouTube code into a link. Posting links is against forum rules; this is just meant to save time, not encourage it.', false],
'YouTube Embedding': ['If \'YouTube Links\' is enabled with this, clicking a YouTube link will load the video within the post. It should be noted that this triggers a warning in Google Chrome due to the nature of it. While highly unlikely, the script writer is not responsible for any harm using this feature.', false],
'Full Pictures': ['Forum avatars are swapped for full body pictures.', false]
};
var persist = {
'fModList': ['A weekly updated list of forum moderators. Viewing the forum moderator list updates this instantly, provided you have enabled a feature that requires it.', ''],
'myRecolor': ['If \'Recolor Me\' is enabled, the script will recolor your post using the settings here. \'Thread Recoloring\' relies on the last color.', '#1C5A45:#0F3F2E:#0A2C20:#071F17:#294D3F:#14392C'],
'signature': ['If a value exists, the following variable will be added at the end of your posts automatically.', ''],
'favorites': ['These are threads recorded by the \'Bookmarks\' feature.', '']
};
// GM_ quick fix
if(!this.GM_getValue || (this.GM_getValue.toString && this.GM_getValue.toString().indexOf('not supported') > -1)) {
this.GM_getValue = function(key, def) {
if(localStorage[key] == 'true') return true;
else if(localStorage[key] == 'false') return false;
else if(localStorage[key]) return localStorage[key];
else return def;
};
this.GM_setValue = function(key, value) { localStorage[key] = value; };
this.GM_deleteValue = function(key) { return delete localStorage[key]; };
}
// Global variables
var e = [document.getElementById('login'), document.getElementById('picker'), document.getElementById('accountName'), GM_getValue('signature', persist['signature'][1])]; // Verify elements / variables exist
var clip = (/(?!.*\/.*\.ws).+/).exec(window.location.href);
var loc = (/(?![^]*>)\s(.*)(?![^]*>)/).exec(document.getElementsByClassName('location')[0].textContent)[1]; // Language discrepancies
var lang = (/\/m=forum(_?.*?)\//).exec(window.location.href)[1];
var session = (/c=.*?\//).exec(window.location.href);
var login = e[0] ? e[0] : e[5];
var qualify = e[1] ? e[1].getElementsByTagName('a').length > 1 : false;
var sig = e[3] ? [e[3], new RegExp('\n{0,2}' + e[3].replace(/[\\\.\+\*\?\^\$\[\]\(\)\|\{\}\/\'\#]/g, '\\$&') + '(?![^]*[^\s])')] : e[3];
//var sig = '';
var jMod = /^(Mod\s.+|Andrew|Avalani|Ian|Paul)$/;
var fMods = GM_getValue('fModList', persist['fModList'][1]).split(':')[0];
var pending = [];
var lastUpdated = Math.floor(new Date().getTime() / 86400000 - rD.getTime() / 86400000);
var name = e[2] ? [e[2].textContent.replace(/\s/g, ' '), e[2].textContent.replace(/\s/g, '%A0')] : '';
// Miscellaneous
function checkFMod(n) { return (new RegExp('\\|' + n.replace(/\s/g, ' ') + '\\|', 'i').test(fMods)); }
function cE(tag, style, properties, text) {
var e = document.createElement(tag);
if(style) e.style.cssText = style;
if(properties) for(var i in properties) e.setAttribute(i, properties[i]);
if(text) e.textContent = text;
return e;
}
var uni = [];
for(var i = 0; i < 256; i ++) {
if(i < 128 || i > 159) uni.push(String.fromCharCode(i));
else uni.push(['\u20AC', '\u0020', '\u201A', '\u0192', '\u201E', '\u2026', '\u2020', '\u2021', '\u02C6', '\u2030', '\u0160', '\u2039', '\u0152', '\u0020', '\u017D', '\u0020', '\u0020', '\u2018', '\u2019', '\u201C', '\u201D', '\u2022', '\u2013', '\u2014', '\u02DC', '\u2122', '\u0161', '\u203A', '\u0153', '\u0020', '\u017E', '\u0178'][i - 128]);
}
function encode(s) { return s.replace(/./g, function(l) { for(var i = 0; i < 256; i ++) if(uni[i] == l) return '%' + (i < 16 ? '0' : '') + i.toString(16); return encodeURI(l); }); }
function encodeHTML(s) { var d = cE('div', '', '', s); return d.innerHTML; }
function getTextNodes(e) {
var textNodes = [];
for(var i = 0; i < e.childNodes.length; i ++) if(e.childNodes[i].nodeType == 3) textNodes.push(e.childNodes[i]);
e = e.getElementsByTagName('*');
for(var i = 0; i < e.length; i ++) for(var l = 0; l < e[i].childNodes.length; l ++) if(e[i].childNodes[l].nodeType == 3) textNodes.push(e[i].childNodes[l]);
return textNodes;
}
function maxText() { if(this.value.length > 2000) this.value = this.value.substring(0, 2000); }
function isQuoteElement(e) { if(e.style.marginTop == '14px' && e.nodeName == 'DIV' && e.childNodes[0].nodeName == 'P' && e.childNodes.length == 3) return true; return false; }
function pendMod(func) {
var outDated = lastUpdated > (parseInt(GM_getValue('fModList', persist['fModList'][1]).split(':')[1]) + 6);
var diffLang = GM_getValue('fModList', persist['fModList'][1]).split(':')[2] != lang;
var update = (outDated == true || diffLang == true);
if(fMods && !update == true) return func(); // No need to update, attempt with current list
if(login || !qualify == true) return func(); // User can't view forum mod list, attempt with current list
pending.push(func);
if(pending.length > 1) return;
GM_xmlhttpRequest({method: 'GET', url: 'forummods.ws', onload: function(response) {
var mods = [];
pR = response.responseText.replace(/[^]+Mods:/, '');
var reg = /[^]+?25%">\n+(.+?)\n+<\/td>/;
while(reg.test(pR) == true) {
mods.push(reg.exec(pR)[1]);
pR = pR.replace(reg, '');
}
GM_setValue('fModList', '|' + mods.toString().replace(/,/g, '|').replace(/\s/g, ' ') + '|:' + lastUpdated + ':' + lang);
fMods = GM_getValue('fModList', persist['fModList'][1]).split(':')[0].toString();
for(var i = 0; i < pending.length; i ++) pending[i]();
pending = [];
}});
}
function stripHTML(e, r) {
var p = [];
for(var i = 0; i < e.length; i ++) {
e[i].parentNode.insertBefore(document.createTextNode(r ? r : e[i].textContent), e[i]);
p.push(e[i]);
}
for(var i = 0; i < p.length; i ++) p[i].parentNode.removeChild(p[i]);
}
// Quick Log In
function logIn() {
var login_form = document.getElementById('login_form');
if(login_form) return login_form.submit();
var e = [cE('form', '', {'action': 'https://secure.runescape.com/m=weblogin/login.ws', 'autocomplete': 'off', 'id': 'login_form', 'method': 'post'})];
var s = ['background-image: url(http://www.runescape.com/img/main/layout/menu_buttons_bg.png); color: #E8D800; height: 19px; line-height: 19px; width: 106px;', 'border: 1px solid black; font-size: 12px; font-weight: bold; letter-spacing: 1px; margin-top: 0px; width: 212px;'];
for(var i = 0; i < 4; i ++) e.push(cE('li', '', {'class': 'top'}));
e[1].appendChild(cE('div', s[0], '', 'Username'));
e[2].appendChild(cE('input', s[1], {'id': 'username', 'name': 'username', 'type': 'text'}));
e[3].appendChild(cE('div', s[0], '', 'Password'));
e[4].appendChild(cE('input', s[1], {'id': 'password', 'maxlength': '20', 'name': 'password', 'type': 'Password'}));
for(var i = 1; i < 5; i ++) e[0].appendChild(e[i]);
for(var i = 0; i < 3; i ++) e[0].appendChild(cE('input', '', {'type': 'hidden', 'name': ['mod', 'ssl', 'dest'][i], 'value': ['forum', '0', login.href.replace(/.+&dest=/, '')][i]}));
e[0].appendChild(cE('input', 'position: absolute; visibility: hidden;', {'type': 'submit'}));
var ul = document.getElementById('menus');
while(ul.childNodes.length > 2) ul.removeChild(ul.firstChild);
ul.insertBefore(e[0], ul.firstChild);
e[2].firstChild.focus();
}
function quickLogIn() {
if(GM_getValue('Direct Log In', features['Direct Log In'][1]) == true && clip != 'forums.ws') login.href = 'https://secure.runescape.com/m=weblogin/loginform.ws?mod=forum&ssl=0&dest=' + clip;
if(GM_getValue('Quick Log In', features['Quick Log In'][1]) == true) login.addEventListener('click', function(event) { if(document.getElementById('username') ? !document.getElementById('username').value : false) return; logIn(); event.preventDefault(); }, false);
}
// Parse Post
function parsePosts() {
var e = document.getElementById('contrast_panel');
var pI = [
(/,(add|edit)/).test(clip), // Is the post on a preview page?
(/<img.+src=".+locked\.gif".+">/).test(e.innerHTML), // Is the thread locked?
(/<a href=".+?,edit,.+?">/).test(e.innerHTML), // Are any of the user's posts on this thread?
e.getElementsByClassName('inactive').length > 0, // Is the thread maxed?
(/,escalate,/).test(clip), // Is the post on a highlight page?
];
if(pI[4] == true) return; // Best to disable all effects when reporting a post for certain reasons
var posts = e.getElementsByClassName('message');
for(var i = 0; i < posts.length; i ++) modifyPost(posts[i], pI);
if(GM_getValue('YouTube Embedding', features['YouTube Embedding'][1]) == true) { // Have to implement afterward due to annoying bug
var youtube = document.getElementsByTagName('youtube');
for(var i = 0; i < youtube.length; i ++) youtube[i].childNodes[0].addEventListener('click', function(event) { var p = this.parentNode; p.removeChild(this); p.appendChild(cE('iframe', 'height: 315px; width: 420px', {'frameborder': '0px', 'src': 'http://www.youtube.com/embed/' + p.getAttribute('video')})); event.preventDefault(); }, false);
}
if(pI[0] == true && sig) addSignature(document.getElementById('charlimit_text_a'));
if(!pI[0] == true && GM_getValue('QFC Links', features['QFC Links'][1]) == true) qFCLink();
if(login || pI[0] == true || pI[1] == true || pI[3] == true || !qualify == true) return;
if(GM_getValue('Quick Reply', features['Quick Reply'][1]) == true) quickReply();
}
function modifyPost(e, pI) {
var uName = e.getElementsByClassName('msgcreator uname')[0].textContent.replace(/\n\s+|\n/g, '').replace(/\s/g, ' ');
var text = e.getElementsByClassName('msgcontents')[0];
if(!uName) {
if(GM_getValue('Recolor Hidden', features['Recolor Hidden'][1]) == true) recolorPost(e, ['#741E04', '#4C0E06', '#360D08', '#260603']);
return;
}
if(GM_getValue('Full Pictures', features['Full Pictures'][1]) == true) {
var i = e.getElementsByClassName('avatar')[0];
i.src = i.src.replace(/\/chat\.gif$/, '/full.gif');
}
if(GM_getValue('Recolor Me', features['Recolor Me'][1]) == true && uName == name[0]) recolorPost(e, GM_getValue('myRecolor', persist['myRecolor'][1]).split(':'));
if(GM_getValue('Forum Moderator Fix', features['Forum Moderator Fix'][1]) == true) pendMod(function() { if(!fMods) return; var modType = e.getElementsByClassName('modtype')[0]; var mMod = e.className.indexOf('fmod') > 0; var isMod = checkFMod(uName); if(!mMod == true) if(isMod == true) { if(!(GM_getValue('Recolor Me', features['Recolor Me'][1]) == true && uName == name[0])) { e.className = e.className + ' mod fmod' + (/(?:^message)(.*)/).exec(e.className)[1]; } if(modType) { modType.textContent = {'': 'Forum Mod', '_de': 'Forum-Mod', '_fr': 'Mod\u00E9rateur de forum', '_pt': 'Moderador do F\u00F3rum'}[lang]; } var n = e.getElementsByClassName('msgcreator uname')[0]; n.firstChild.nodeValue = '\u00a0\n\n'; n.insertBefore(cE('img', '', {'alt': '', 'src': 'http://www.runescape.com/img/forum/crown_green.gif'}), n.firstChild); n.insertBefore(document.createTextNode('\n'), n.firstChild) } if(mMod == true && !isMod == true) modType.textContent = 'Ex-' + modType.textContent; });
modifyText(text, uName);
if(login || pI[0] == true || pI[1] == true) return;
var commands = e.getElementsByClassName('msgcommands')[0];
if(!commands) {
commands = cE('div', '', {'class': 'msgcommands'});
e.getElementsByTagName('td')[0].appendChild(commands);
}
if(pI[2] == true && GM_getValue('Quick Edit', features['Quick Edit'][1]) == true) addQuickEdit(commands, e);
if(pI[3] == true || !qualify == true) return;
if(GM_getValue('Quick Reply', features['Quick Reply'][1]) == true && GM_getValue('Quick Quotes', features['Quick Quotes'][1]) == true) addQuote(commands);
}
function recolorPost(e, colors) {
if(!(/msghighlight$/).test(e.className) == true) e.style.borderColor = colors[0];
var t = e.getElementsByTagName('td');
t[0].style.borderColor = colors[1];
t[0].style.backgroundColor = colors[2];
t[0].getElementsByClassName('msgcreator uname')[0].style.backgroundColor = colors[2];
var m = [t[0].getElementsByClassName('modtype')[0], t[0].getElementsByClassName('msgcommands')[0], t[0].getElementsByClassName('avatar')[0]];
if(m[0]) m[0].style.backgroundColor = colors[2];
if(m[1]) m[1].style.borderTopColor = colors[1];
t[1].style.borderColor = colors[1];
t[1].style.backgroundColor = colors[3];
if(m[2]) m[2].style.borderColor = colors[4];
}
function decolorPost(element) {
var t = element.getElementsByTagName('td');
var e = [t[0].getElementsByClassName('msgcreator uname')[0], t[0].getElementsByClassName('modtype')[0], t[0].getElementsByClassName('msgcommands')[0], t[0].getElementsByClassName('avatar')[0]];
var c = [element.style.borderColor, e[2].style.borderTopColor, e[1].style.backgroundColor, t[1].style.backgroundColor, e[3].style.borderColor];
if(!(/msghighlight$/).test(element.className) == true) element.style.borderColor = '';
t[0].style.borderColor = '';
t[0].style.backgroundColor = '';
e[0].style.backgroundColor = '';
if(e[1]) e[1].style.backgroundColor = '';
if(e[2]) e[2].style.borderTopColor = '';
t[1].style.borderColor = '';
t[1].style.backgroundColor = '';
if(e[3]) e[3].style.borderColor = '';
return c;
}
var quote = /(\[q(?:uote)?(?:-([^\]]*?))?])(?![^]*\[q(?:-[^\]]*?)?][^]*\[\/q])[^]*?(\[\/q(?:uote)?])/i;
function modifyText(text, username) {
parseText(text);
if(username) if(jMod.test(username) == true) return;
if(!GM_getValue('Quotes', features['Quotes'][1]) == true) return;
text.innerHTML = text.innerHTML.replace(/(?:\*|\[)q(-.*?)?(?:\*|\])/g, '[q$1]'); // Censor fix [q] [q-name]
text.innerHTML = text.innerHTML.replace(/(?:\[|\*)\/q(?:\]|\*)/g, '[/q]'); // Censor fix [/q]
while(quote.test(text.innerHTML)) text.innerHTML = text.innerHTML.replace(quote, parseQuote);
styleQuote(text);
}
function parseText(text) {
if(!GM_getValue('QFC Links', features['QFC Links'][1]) == true && !GM_getValue('YouTube Links', features['YouTube Links'][1]) == true) return;
text.innerHTML = text.innerHTML.replace(/<br>/g, '\u2028');
var l = getTextNodes(text);
for(var i = 0; i < l.length; i ++) {
if(GM_getValue('QFC Links', features['QFC Links'][1]) == true) parseQFC(l[i]);
if(GM_getValue('YouTube Links', features['YouTube Links'][1]) == true) parseYTV(l[i]);
}
text.innerHTML = text.innerHTML.replace(/\u2028/g, '<br>');
}
function parseQFC(e) {
var qFC = /((?:\d{1,3}-){3}\d+)(?:[^]{0,100}?((?:Page(?: In Thread)?|Pg).{0,4}?(\d+)))?/i;
while(qFC.test(e.nodeValue) == true) {
var q = qFC.exec(e.nodeValue);
var h = q[1].replace(/-/g, ',');
var p = e.parentNode;
e.splitText(e.nodeValue.indexOf(q[0]));
var n = e.nextSibling;
n.nodeValue = n.nodeValue.substring(q[1].length);
p.insertBefore(cE('a', '', {'href': 'forums.ws?' + h}, q[1]), n);
if(q[2]) {
n.splitText(n.nodeValue.indexOf(q[2]));
n = n.nextSibling;
n.nodeValue = n.nodeValue.substring(q[2].length);
p.insertBefore(cE('a', '', {'href': 'forums.ws?' + h + ',goto,' + q[3]}, q[2]), n);
}
e = n;
}
}
function parseYTV(e) {
var yTV = /(?:(?:http:\/\/)?(?:(?:\*|w|v){3}\.)?(?:youtube.(?:\*|c|o|m){3}))?(?:\/)?(?:watch\?v=)([-a-zA-Z0-9_]+)/i;
while(yTV.test(e.nodeValue) == true) {
var y = yTV.exec(e.nodeValue);
e.splitText(e.nodeValue.indexOf(y[0]));
e = e.nextSibling;
e.nodeValue = e.nodeValue.substring(y[0].length);
var yT = cE('youtube', '', {'video': y[1]});
yT.appendChild(cE('a', 'border: 1px dashed red; border-width: 1px 0px 1px 0px; color: red; text-decoration: none;', {'href': 'http://www.youtube.com/watch?v=' + y[1]}, 'YouTube: /watch?v=' + y[1]));
e.parentNode.insertBefore(yT, e);
}
}
function parseQuote(text, open, name, close) {
var q = '<div style="border:1px solid #3F2E0F;margin: 14px 0 0"><p style="background:#2C200A;margin:0;padding:2px;font-style:normal">';
if(name) name = name.replace(/\s/g, '\u00a0');
var t = { // These took a while to find
'': '<strong>Quote</strong> ' + (name ? '(said by: ' + name + ')' : ''),
'_de': '<strong>Zitat</strong> ' + (name? '(von ' + name + ')' : ''),
'_fr': '<strong>Quote</strong> ' + (name ? '(said by: ' + name + ')' : ''), // The only quote I was able to find on the French forums uses the English conventions
'_pt': '<strong>Cita\u00E7\u00E3o ' + (name ? 'de ' + name : '') + '</strong>'
}[lang];
q += t + '</p><div style="position:relative;float:right;overflow:hidden;height:33px;top:-28px;left:10px"><span style="color:#3F2E0F;font-family:Engravers MT,Felix Titling,Perpetua Titling MT,Times New Roman;font-style:normal;font-size:120px;line-height:81px">"</span></div><div style="font-style:italic;margin:8px 6px">';
text = text.replace(open, q).replace(close, '</div></div>');
return text;
}
function styleQuote(e) {
var c = e;
while(c.nodeName != 'TD') c = c.parentNode;
c = c.previousSibling.previousSibling;
var s = [window.getComputedStyle(c).borderTopColor, window.getComputedStyle(c).backgroundColor];
var d = e.getElementsByTagName('div');
var q = [];
for(var i = 0; i < d.length; i ++) if((d[i].childNodes.length > 2 ? (isQuoteElement(d[i])) : false) == true) q.push(d[i]);
for(var i = 0; i < q.length; i ++) {
q[i].style.border = '1px solid ' + s[0];
q[i].childNodes[0].style.backgroundColor = s[1];
q[i].childNodes[1].childNodes[0].style.color = s[0];
}
}
function addQuickEdit(e, root) {
e = e.getElementsByTagName('a');
for(var i = 0; i < e.length; i ++) if((/,edit,/).test(e[i].href) == true) return e[i].addEventListener('click', function(event) { if(root.getElementsByTagName('form').length > 0) return; quickEdit(e[i].parentNode.parentNode.parentNode.parentNode.parentNode, e[i]); event.preventDefault(); }, false);
}
function quickEdit(element, a) {
if(element.className == 'message moved') return;
var timeStamp = element.getElementsByClassName('msgtime')[0];
timeStamp.style.display = 'none';
var text = element.getElementsByClassName('msgcontents')[0];
text.parentNode.style.padding = '0px';
text.style.cssText = 'padding: 0px; padding-right: 6px; width: 558px;';
var textHTML = [text.innerHTML, wipePost(text.cloneNode(true))];
var reg = [/(?:.+?(?:(?=,)|$)){4}/, /\d+,\d+$/];
var e = [cE('form', 'text-align: right; width: 564px', {'action': reg[0].exec(clip) + ',edit,' + reg[1].exec(a.href), 'method': 'post'}), cE('textarea', 'height: 153px; width: 558px; margin: 0px;', {'maxlength': '2000', 'name': 'contents'})];
for(var i = 0; i < 3; i ++) e.push(cE('input', '', {'class': 'buttonmedium', 'name': ['edit', 'preview', 'cancel'][i], 'type': 'submit', 'value': ['Update message', 'Preview post', 'Cancel'][i]}));
for(var i = 0; i < 2; i ++) e[1].addEventListener(['keyup', 'blur'][i], maxText, false);
e[1].value = textHTML[1];
if(sig) addSignature(e[1]);
var clean = function() { text.removeChild(e[0]); timeStamp.style.display = ''; text.parentNode.style.padding = ''; text.style.cssText = ''; };
e[2].addEventListener('click', function(event) { if(!e[1].value) return event.preventDefault(); clean(); text.innerHTML = encodeHTML(e[1].value).replace(/\n/g, '<br> '); edit(e[1].value, e[0].action, [element, text, timeStamp]); event.preventDefault(); }, false);
e[4].addEventListener('click', function(event) { clean(); text.innerHTML = textHTML[0]; event.preventDefault(); }, false);
for(var i = 1; i < 5; i ++) e[0].appendChild(e[i]);
text.textContent = '';
text.appendChild(e[0]);
e[1].focus();
}
function wipePost(text) {
var p = [];
var e = text.getElementsByTagName('img');
for(var i = 0; i < e.length; i ++) {
if(!(/^sm/).test(e[i].className) == true) continue;
e[i].parentNode.insertBefore(document.createTextNode(e[i].getAttribute('title')), e[i]);
p.push(e[i]);
}
for(var i = 0; i < p.length; i ++) p[i].parentNode.removeChild(p[i]);
if(GM_getValue('YouTube Links', features['YouTube Links'][1]) == true) {
var y = text.getElementsByTagName('youtube');
for(var i = 0; i < y.length; i ++) y[i].textContent = 'watch?v=' + y[i].getAttribute('video');
}
stripHTML(text.getElementsByTagName('a'));
for(var i = 0; i < 3; i ++) stripHTML(text.getElementsByTagName(['style', 'script', 'br'][i]), '\n');
if(GM_getValue('Quotes', features['Quotes'][1]) == true) convertQuotes(text);
stripHTML(text.getElementsByTagName('*'));
text.textContent = text.textContent.replace(/(^\n+|\n+?$)/g, '').replace(/\s\n/g, '\n');
return text.textContent;
}
function convertQuotes(e) {
var d = e.getElementsByTagName('div');
var q = [];
for(var i = 0; i < d.length; i ++) if(isQuoteElement(d[i]) == true && d[i].parentNode == e) q.push(d[i]);
for(var i = 0; i < q.length; i ++) {
q[i].parentNode.insertBefore(stripQuote(q[i]), q[i]);
q[i].parentNode.removeChild(q[i]);
}
}
function stripQuote(e) {
if(e.nodeType == 3) return e;
var qReg = {'': /^Quote \(said by: (.+?)\)/, '_de': /Zitat \(von (.+?)\)/, '_fr': /^Quote \(said by: (.+?)\)/, '_pt': /Cita\u00E7\u00E3o de (.+)/}[lang];
var n = qReg.exec((e.firstChild.textContent).replace(/\s/g, ' '));
var t = e.childNodes[2].childNodes;
var f = document.createTextNode('');
for(var i = 0; i < t.length; i ++) f.nodeValue += stripQuote(t[i]).nodeValue
return document.createTextNode('[q' + (n ? '-' + n[1] : '') + ']' + f.nodeValue + '[/q]');
}
function addSignature(e) {
if(e.value.search(sig[1]) > -1) return;
e.value += '\r\r' + sig[0];
}
function edit(newText, action, e) {
var orig = e[0].className;
var c = decolorPost(e[0]);
e[0].className = 'message moved';
modifyText(e[1]);
if(e[2].childNodes.length > 1) e[2].lastChild.nodeValue = (/(.+?)\n/).exec(e[2].lastChild.nodeValue)[1];
e[2].appendChild(cE('br'));
e[2].appendChild(document.createTextNode('Editing post...'));
GM_xmlhttpRequest({method: 'POST', url: action, data: 'contents=' + encode(newText) + '&edit=true', headers: { "Content-Type": "application/x-www-form-urlencoded" }, onload: function(response) {
var r = (/[^]+?<table class="[\w\s]+?msghighlight"[^]+?<div class="msgtime">([^]+?)<\/div>[^]+?<div class="msgcontents">([^]+?)<\/div>\n<\/td>\n<\/tr><\/table>\n(?:<a class="msgplace"|<\/div>\n<div class="actions" id="bottom">)/i).exec(response.responseText);
e[1].innerHTML = r[2];
e[2].innerHTML = r[1];
e[0].className = orig;
recolorPost(e[0], c);
modifyText(e[1]);
}});
}
function addQuote(element) {
var e = [cE('br'), cE('a', '', {'href': clip}, 'Quote')];
e[1].addEventListener('click', function(event) {
var qRB = document.getElementById('quickReplyBox');
var root = this.parentNode.parentNode.parentNode.parentNode.parentNode;
var uName = root.getElementsByClassName('msgcreator uname')[0].textContent.replace(/\n\s+|\n/g, '').replace(/\s/g, ' ');
var text = root.getElementsByClassName('msgcontents')[0];
if(text.getElementsByTagName('form').length > 0) text = text.getElementsByTagName('textarea')[0].value;
else text = wipePost(text.cloneNode(true));
text = '[q-' + uName + ']' + text.replace(/^\n+|\n+$/g, '') + '[/q]';
if(sig) {
qRB.value = qRB.value.replace(sig[1], '');
qRB.value += (qRB.value.length > 0 ? '\r' : '') + text + '\r' + (sig ? '\r\r' + sig[0] : '');
} else qRB.value += (qRB.value.length > 0 ? '\r' : '') + text + '\r';
event.preventDefault();
}, false);
for(var i = 0; i < 2; i ++) element.appendChild(e[i]);
}
function qFCLink() {
var e = document.getElementById('uid');
if(!e) return;
parseQFC(e.childNodes[0]);
e.childNodes[1].href = e.childNodes[1].href.replace(session, '');
}
function quickReply() {
var e = [cE('div', 'margin-bottom: 5px; padding: 7px;', {'class': 'brown_box_forum'}), cE('div', 'border: 1px solid #5A451C'), cE('div', 'background: #2d200A; border: 4px solid #3F2E0F; border-right-width: 3px; width: 135px; display: table-cell; text-align: center; padding-top: 3px; vertical-align: top;'), cE('a', '', {'href': '/m=adventurers-log/' + session + 'display_player_profile.ws?searchName=' + name[1]}), cE('div', 'background: #1F1707; border: 4px solid #3F2E0F; border-left-width: 0px; width: 564px; display: table-cell; text-align: right;'), cE('form', 'width: 564px', {'action': (/(?:.+?(?:(?=,)|$)){4}/).exec(clip) + ',add', 'method': 'post'}), cE('textarea', 'height: 153px; width: 558px; margin: 0px;', {'id': 'quickReplyBox', 'maxlength': '2000', 'name': 'contents'})];
e[0].appendChild(cE('div', 'color: #D6C6AC; background: transparent url(http://www.runescape.com/img/forum/headerbg.png) repeat-x scroll 0% 50%; font-family: Arial, Helvetica, FreeSans, sans-serif; font-size: 14px; font-weight: bold; height: 20px; margin-bottom: 4px; padding: 0px 0px 4px 5px; text-align: left;', {'class': 'subsectionHeader'}, 'Add Quick Reply'));
e[2].appendChild(cE('a', 'color: #A07F3B; font-family: Verdana,Helvetica,FreeSans,sans-serif; font-size: 12px; font-weight: bold;', {'href': 'users.ws?searchname=' + name[1] + '&lookup=view'}, name[0]))
e[3].appendChild(cE('img', 'border: 1px solid #4D3F29; margin: 4px;', {'src': '/m=avatar-rs/' + name[1] + (GM_getValue('Full Pictures', features['Full Pictures']) == true ? '/full.gif' : '/chat.gif')}));
e[2].appendChild(e[3]);
e[1].appendChild(e[2]);
e[6].addEventListener('keyup', maxText, false);
e[6].addEventListener('blur', maxText, false);
if(sig) e[6].value = '\r\r' + sig[0];
e[5].appendChild(e[6]);
e[5].appendChild(cE('input', 'height: 25px;', {'class': 'buttonmedium', 'name': 'add', 'type': 'submit', 'value': 'Add message'}));
e[5].appendChild(cE('input', 'height: 25px;', {'class': 'buttonmedium', 'name': 'preview', 'type': 'submit', 'value': 'Preview post'}));
e[4].appendChild(e[5]);
e[1].appendChild(e[4]);
e[0].appendChild(e[1]);
var ins = document.getElementById('contentmsg').nextSibling.nextSibling;
ins.parentNode.insertBefore(cE('a', '', {'name': 'quickReply'}), ins);
ins.parentNode.insertBefore(e[0], ins);
}
// Parse Threads
function parseThreads() {
var e = document.getElementsByClassName('thdnrml');
for(var i = 0; i < e.length; i ++) modifyThread(e[i]);
}
function modifyThread(e) {
if(GM_getValue('Thread Recoloring', features['Thread Recoloring'][1]) == true) recolorThread(e);
if(e.getElementsByTagName('a').length < 1) return;
if(GM_getValue('Crowns', features['Crowns'][1]) == true) addCrowns(e);
if(!GM_getValue('Thread Selecting', features['Thread Selecting'][1]) == true) return;
var t = /thd,(.+)/;
if(!t.test(clip) == true) return;
if(isSelectedThread(e, t.exec(clip)[1]) == true) threadSelect(e);
}
function isSelectedThread(e, t) {
if(e.getElementsByTagName('a').length < 1) return false; // Update to check if it's the only hidden thread and none other are selected, but thd still matches?
if((/\d+,\d+$/).exec(e.getElementsByTagName('a')[0].href) == t) return true;
return false;
}
function recolorThread(e) {
var e = [e.getElementsByTagName('td'), e.getElementsByTagName('img'), e.getElementsByTagName('a'), e.getElementsByTagName('span')[1]];
if(GM_getValue('Recolor Hidden', features['Recolor Hidden'][1]) == true) if((e[1].length > 0 ? (/locked\.gif$/).test(e[1][0].src) : e[2].length < 1) == true) for(var i = 0; i < e[0].length; i ++) e[0][i].style.backgroundColor = '#421715';
if((e[1].length > 0 ? (/sticky\.gif$/).test(e[1][0].src) : false) == true) for(var i = 0; i < e[0].length; i ++) e[0][i].style.backgroundColor = '#003F3F';
if(!e[3]) return;
var uName = e[3].textContent.replace(/\s/g, ' ');
if(jMod.test(uName) == true) for(var i = 0; i < e[0].length; i ++) e[0][i].style.backgroundColor = '#3F3F00';
pendMod(function() { if(checkFMod(uName) == true) if(!(GM_getValue('Recolor Me', features['Recolor Me'][1]) == true && uName == name)) for(var i = 0; i < e[0].length; i ++) e[0][i].style.backgroundColor = '#154217'; });
if(GM_getValue('Recolor Me', features['Recolor Me'][1]) == true && uName == name[0]) for(var i = 0; i < e[0].length; i ++) e[0][i].style.backgroundColor = GM_getValue('myRecolor', persist['myRecolor'][1]).split(':')[5];
var mL = {'': 'moved', '_de': 'verschoben', '_fr': 'transf\u00E9r\u00E9', '_pt': 'transferida'}[lang];
moved = new RegExp('\\s?\\(' + mL + '\\)$');
if(moved.test(e[2][0].textContent) == true && (e[1].length > 0 ? (/locked\.gif$/).test(e[1][0].src) : false) == true && e[0][1].textContent == '\n1\n') {
e[2][0].textContent = e[2][0].textContent.replace(moved, '');
e[0][0].insertBefore(document.createTextNode(' (' + mL + ')'), e[2][0].nextSibling);
for(var i = 0; i < e[0].length; i ++) e[0][i].style.backgroundColor = '#171542';
}
}
function addCrowns(element) {
var creator = element.getElementsByTagName('span')[1];
var uName = creator.textContent.replace(/\s/g, ' ');
var crown = [];
for(var i = 0; i < 2; i ++) crown.push(cE('img', 'margin-bottom: 3px;', {'src': 'http://www.runescape.com/img/forum/crown_' + ['gold', 'green', 'silver'][i] + '.gif'})); // i < 3 for the silver crown, disabled until future use
pendMod(function() { var creator = element.getElementsByTagName('span')[1]; if(checkFMod(uName) == true) creator.insertBefore(crown[1], creator.firstChild); });
if(jMod.test(uName) == true) creator.insertBefore(crown[0], creator.firstChild);
var last = element.childNodes[5].childNodes[2];
var lastPoster = (/([^]+?\s)(.+)/).exec(last.textContent);
if(jMod.test(lastPoster[2]) == true) {
last.splitText(last.textContent.indexOf(lastPoster[2]));
last.parentNode.insertBefore(crown[0].cloneNode(true), last.nextSibling);
}
pendMod(function() { if(checkFMod(lastPoster[2].replace(/\s/g, ' ')) != true) return; last.splitText(last.textContent.indexOf(lastPoster[2])); last.parentNode.insertBefore(crown[1].cloneNode(true), last.nextSibling); });
}
function threadSelect(thread) {
var t = thread.getElementsByTagName('td');
var i = t[0].getElementsByTagName('img');
var e = [cE('div', 'border: 1px solid yellow; border-right-width: 0px; height: 32px; margin: -1px 0px -1px -5px; padding: 3px 0px 0px 4px;'), cE('div', 'border: 1px solid yellow; border-width: 1px 0px 1px 0px; height: 25px; margin: -1px 0px -1px -2px; padding: 10px 0px 0px 2px;'), cE('div', 'border: 1px solid yellow; border-width: 1px 1px 1px 0px; height: 30px; margin: -1px -1px -1px -2px; padding: 3px 0px 2px 2px;')];
if((i.length > 0 ? !(/crown_.+?\.gif$/).test(i[0].src) : false) == true) e[0].style.padding = '2px 0px 1px 4px'; // Stupid picture messing up padding
for(var i = 0; i < t.length; i ++) {
while(t[i].childNodes.length > 0) e[i].appendChild(t[i].firstChild);
t[i].appendChild(e[i]);
}
}
// Parse Profile
function parseProfile() {
if(GM_getValue('Search Posts by User', features['Search Posts by User'][1]) == true) addSearch();
}
function addSearch() {
var history = document.getElementById('history');
if(!history) return;
var e = [cE('form', 'margin-top: 16px; margin-bottom: 16px;'), cE('input', '', {'id': 'query', 'type': 'text'}), cE('input', '', {'class': 'buttonNew finduser_button buttonmedium', 'type': 'submit', 'value': 'Find'})];
e[0].appendChild(document.createTextNode('Search posts: '));
for(var i = 1; i < 3; i ++) e[0].appendChild(e[i]);
e[0].addEventListener('submit', function(event) { search(); event.preventDefault(); }, false);
history.parentNode.insertBefore(e[0], history);
}
function search() {
var t = document.getElementById('query').value;
if(!t) return;
t = t.replace(/\\/g, '\\');
var e = document.getElementsByClassName('show_posts_by');
for(var i = 0; i < e.length; i ++) gm_search(t, e[i]);
}
function gm_search(t, e) { // Need to remove HTML from JMods
e.parentNode.parentNode.style.backgroundColor = '#2E2617'
GM_xmlhttpRequest({method: 'GET', url: e.href, onload: function(response) {
e.parentNode.parentNode.style.backgroundColor = 'inherit';
var pR = response.responseText.replace(/(\r\n|\n|\r)/gm, '');
var reg = /(<div class="msgcontents">).+?(?=<\/div>)/;
var pT = '';
while(reg.test(pR)) {
pT += reg.exec(pR)[0].replace(/<br>/g, '') + '\n';
pR = pR.replace(reg, '');
}
if(new RegExp(t.replace(/[\\\.\+\*\?\^\$\[\]\(\)\|\{\}\/\'\#]/g, '\$&'), 'i').test(pT) == true) e.parentNode.parentNode.style.backgroundColor = '#8a0a0a';
}});
}
// Parse Mods
function parseMods() {
if(!GM_getValue('Crowns', features['Crowns'][1]) == true && !GM_getValue('Thread Recoloring', features['Thread Recoloring'][1]) == true) return;
var td = document.getElementById('info').getElementsByTagName('td');
var mods = [];
for(var i = 0; i < td.length; i ++) mods.push(td[i].textContent.replace(/\n/g, ''));
GM_setValue('fModList', '|' + mods.toString().replace(/,/g, '|').replace(/\s/g, ' ') + '|:' + lastUpdated + ':' + lang);
fMods = GM_getValue('fModList', persist['fModList'][1]).split(':')[0].toString();
}
// Parse Forums
function parseForums() {
if(!GM_getValue('Bookmarks', features['Bookmarks'][1]) == true) return; // cleanup e[] and lang
var e = [cE('div', '', {'class': 'cont'}), cE('table', '', {'class': 'forumview'}), cE('tbody'), cE('tr'), cE('td', '', {'class': 'title1 first-child'}), cE('td', 'padding-left: 5px; text-align: left', {'class': 'title1'}, 'Bookmarks'), cE('td', '', {'class': 'title1'}, {'': 'Page'}[lang]), cE('td', '', {'class': 'center title', 'id': 'header_posts'}, {'': 'Posts'}[lang]), cE('td', '', {'class': 'title1', 'id': 'header_lastpost'}, '\n' + {'': 'Last Post'}[lang] + '\n')];
for(var i = 4; i < 9; i ++) e[3].appendChild(e[i]);
for(var i = 0; i < 3; i ++) e[i].appendChild(e[i + 1]);
var favorites = GM_getValue('favorites', persist['favorites'][1]).split(':');
for(var i = 0; i < favorites.length; i ++) {
var t = cE('tr', 'background-color: #392C14; border-top: 3px solid #1D1506; height: 40px', {'class': 'threadtitle'});
var q = [cE('td', 'margin-right: -2px', {'class': 'i'}), cE('td', '', {'class': 'threadtitle'}, 'forums.ws?' + favorites[i].replace(/.+?,.+?,/, '$&thd,')), cE('td', '', {'class': 'n posts'}), cE('td', '', {'class': 'n posts'}), cE('td', '', {'class': 'updated'}, 'Loading!')];
for(var h = 0; h < q.length; h ++) t.appendChild(q[h]);
e[2].appendChild(t);
getThread(t);
}
var c = document.getElementById('contentfrm');
c.appendChild(cE('h3', 'text-align: center', '', 'Bookmarked Threads'));
document.getElementById('contentfrm').appendChild(e[0]);
}
function getThread(p) { // CHECK IF THREAD EXISTS AT ALL, MAKE SURE SAME LANGUAGE
GM_xmlhttpRequest({method: 'GET', url: p.childNodes[1].textContent, onload: function(response) {
var html = cE('html');
var iHTML = response.responseText.replace(/[^]+<html>/, '').replace(/<\/html>[^]+/, '');
html.innerHTML = iHTML;
var d = html.getElementsByClassName('thdnrml');
var thread = (/.+?,thd,(.+)/).exec(p.childNodes[1].textContent)[1];
for(var i = 0; i < d.length; i ++) if(isSelectedThread(d[i], thread) == true) break;
modifyThread(d[i]);
var s = d[i].getElementsByTagName('td');
var e = cE('td', 'background-color: ' + s[0].style.backgroundColor, {'class': 'i'});
e.appendChild(cE('a', '', {'href': p.childNodes[1].textContent}));
e.childNodes[0].appendChild(html.getElementsByClassName('title')[0].getElementsByTagName('img')[0].cloneNode(true));
e.childNodes[0].childNodes[0].style.margin = '0px -2px 0px 3px';
while(p.childNodes.length > 0) p.removeChild(p.firstChild);
p.appendChild(e);
for(var t = 0; t < s.length; t ++) p.appendChild(s[t].cloneNode(true));
p.insertBefore(cE('td', 'background-color: ' + s[0].style.backgroundColor, {'class': 'n posts'}, html.getElementsByClassName('actions')[0].getElementsByTagName('input')[0].value), p.childNodes[2]);
}});
}
// RSAF Control Panel
function rSAFLink() {
var fLink = document.getElementById('community').parentNode.getElementsByTagName('ul')[0].childNodes[1];
rSAFL = fLink.cloneNode(true);
rSAFL.childNodes[0].childNodes[0].textContent = 'RS Advanced Forums';
rSAFL.childNodes[0].href = 'forums.ws?rsaf';
fLink.parentNode.insertBefore(rSAFL, fLink.nextSibling);
}
function rSAFCP() {
var p = document.getElementById('infopane');
if(!p) return;
var purge = function() {
window.localStorage.clear();
for(var i in features) {
GM_deleteValue(i);
var a = document.getElementById('f_' + i);
var n = GM_getValue(i, features[i][1]) ? 1 : 0;
a.style.color = ['red', 'green'][n];
a.textContent = ['FALSE', 'TRUE'][n];
} for(var i in persist) {
GM_deleteValue(i);
document.getElementById('t_' + i).value = GM_getValue(i, persist[i][1]);
}
};
loc = 'RuneScape Advanced Forums Script';
document.getElementById('article').getElementsByTagName('h1')[0].textContent = loc;
var e = document.getElementsByClassName('location');
for(var i = 0; i < e.length; i ++) {
var c = e[i].childNodes[5].childNodes[0];
var a = cE('a', '', {'href': 'forums.ws'});
a.appendChild(cE('span', '', '', c.textContent));
c.parentNode.insertBefore(a, c);
c.parentNode.insertBefore(document.createTextNode(' >\n'), c);
c.textContent = 'RuneScape Advanced Forums Script';
}
p.childNodes[1].textContent = 'RuneScape Advanced Forums';
p.insertBefore(cE('span', '', {'class': 'count'}, 'Last Updated: ' + rD.toLocaleDateString()), p.childNodes[2]);
p.insertBefore(cE('br'), p.childNodes[2]);
e = p.getElementsByTagName('ul')[0].getElementsByTagName('li');
while(e.length < 3) e[0].parentNode.appendChild(cE('li'));
for(var i = 0; i < 3; i ++) {
e[i].textContent = '';
e[i].appendChild(cE('img', '', {'src': ['http://userscripts.org/images/script_icon.png', 'http://www.runescape.com/img/forum/cmdicons/refresh.gif', 'http://www.runescape.com/img/forum/cmdicons/search_threads.gif'][i]}));
e[i].appendChild(cE('a', '', {'href': ['http://userscripts.org/scripts/show/13002', 'http://userscripts.org/scripts/discuss/13002', window.location.href][i]}, ['Visit Userscript Page', 'Suggest a Feature', 'Purge Variables'][i]));
}
e[0].childNodes[0].style.cssText = 'height: 15px; width: 15px;';
e[2].childNodes[1].addEventListener('click', function(event) { purge(); event.preventDefault(); }, false);
p = document.getElementById('contentfrm');
p.textContent = '';
for(var i = 0; i < 4; i ++) {
e = cE('div', 'margin-bottom: 5px;', {'class': 'brown_box'});
e.appendChild(cE('div', 'font-size: 12px;', {'class': 'subsectionHeader'}, ['Welcome', 'Features', 'Persistent Variables', 'A Note to Google Chrome Users'][i]));
e.appendChild(cE('div', '', {'class': 'inner_brown_box'}, ['This is the RuneScape Advanced Forums control panel. Here you may toggle features of the script. \'Purge Variables\' will restore settings to their default state and erase all persistent data. It is recommended you do this after each update.', 'Click to toggle a feature. Note that some features are dependent on others, and may not function until certain features are enabled.', 'This is a list of variables used by the features above. By default, any feature that requires a persistent variable is disabled. The default values of these variables do not store persistent data. You may edit persistent variables at your own discretion by editing the textbox and pressing modify. Doing so may affect the features which rely on it.', 'Google Chrome does not fully utilize Greasemonkey\'s features. Therefore, variables are stored in HTML5\'s localStorage. To clear these and remove all traces of the script, press \'Purge Variables\' BEFORE uninstalling. Default settings do not store variables, and persistent data will only be stored if settings are toggled.'][i]));
p.appendChild(e);
}
e = p.childNodes[1].childNodes[1];
e.appendChild(cE('table', 'margin-bottom: -8px; margin-top: 8px;'));
e.lastChild.appendChild(cE('tbody'));
t = e.lastChild.lastChild;
for(var f in features) {
var c = cE('tr', 'border-top: 1px solid #261C09;');
c.appendChild(cE('td', 'height: 50px; width: 10%;'));
var b = GM_getValue(f, features[f][1]);
var n = b ? 1 : 0;
var a = cE('a', 'text-decoration: none; color: ' + ['red', 'green'][n] + ';', {'href': window.location.href, 'id': 'f_' + f}, ['FALSE', 'TRUE'][n]);
a.addEventListener('click', function(event) {
var f = this.id.substring(2);
var b = GM_getValue(f, features[f][1]);
if(!b == features[f][1]) GM_deleteValue(f);
else GM_setValue(f, !b);
b = GM_getValue(f, features[f][1]);
var n = b ? 1 : 0;
this.style.color = ['red', 'green'][n];
this.textContent = ['FALSE', 'TRUE'][n];
event.preventDefault();
}, false);
c.lastChild.appendChild(a);
c.appendChild(cE('td', 'width: 20%', '', f));
var l = cE('td', 'width: 70%');
var s = features[f][0].split('.');
for(var n = 0; n < s.length - 1; n ++) {
if(n > 0) l.appendChild(cE('br'));
l.appendChild(document.createTextNode(s[n] + '.'));
}
for(var i = 0; i < 2; i ++) [c, t][i].appendChild([l, c][i]);
}
e = p.childNodes[2].childNodes[1];
e.appendChild(cE('table', 'margin-bottom: -8px; margin-top: 8px;'));
e.lastChild.appendChild(cE('tbody'));
t = e.lastChild.lastChild;
for(var v in persist) {
var c = cE('tr', 'border-top: 1px solid #261C09;');
c.appendChild(cE('td', 'height: 75px; width: 10%;', '', v));
var l = cE('td', 'width: 40%');
var s = persist[v][0].split('.');
for(var n = 0; n < s.length - 1; n ++) {
if(n > 0) l.appendChild(cE('br'));
l.appendChild(document.createTextNode(s[n] + '.'));
}
c.appendChild(l);
l = cE('td', 'width: 44%');
l.appendChild(cE('textarea', 'height: 65px; width: 295px', {'id': 't_' + v}));
l.firstChild.value = GM_getValue(v, persist[v][1]);
c.appendChild(l);
l = cE('td', 'text-align: right; width: 6%');
var a = cE('a', 'color: orange; text-decoration: none;', {'href': window.location.href, 'id': 'p_' + v}, 'MODIFY');
a.addEventListener('click', function(event) {
var f = this.id.substring(2);
var v = document.getElementById('t_' + f).value;
var p = GM_getValue(f, persist[f][1]);
if(v == p) GM_deleteValue(f);
else GM_setValue(f, v);
event.preventDefault();
}, false);
for(var i = 0; i < 3; i ++) [l, c, t][i].appendChild([a, l, c][i]);
}
}
// Determine Components
function determineComponent() {
// Globals
rSAFLink();
if(login) quickLogIn();
// Page Specific
var rSAF = /forums\.ws\?rsaf/;
var postView = /forums\.ws\?(\d{1,3},){3}.+/;
var threadView = /forums\.ws\?\d+,\d+(,thd,.+|,goto,.+|$)/;
var profileView = /users\.ws/;
var modsView = /forummods\.ws/;
var forumsView = /forums\.ws$/;
var v = [rSAF.test(clip), postView.test(clip), threadView.test(clip), profileView.test(clip), modsView.test(clip) && !login, forumsView.test(clip)];
var f = [rSAFCP, parsePosts, parseThreads, parseProfile, parseMods, parseForums];
for(var i = 0; i < v.length; i ++) if(v[i] == true) f[i]();
if(GM_getValue('Title Rename', features['Title Rename'][1]) == true) document.title = loc;
}
determineComponent();