Script Details
File Name: ipboard_fastreply.user.js
Description
Invision Power (IP) Boards have a "Fast Reply", "Add Reply", and "New Topic" buttons at the bottom of the page. However, at the top of the page, they only have "Add Reply" and "New Topic" buttons. I like symmetry, and sometimes I want to Fast Reply when I'm at the top of the page. Also, I thought some improvements could be made to the "Fast Reply" functionality.
This script:- Adds a "Fast Reply" button to the top of the page
- Transfers focus to the text area after pressing "Fast Reply" so that I can begin typing immediately
- Adds shortcut formatting keys (CTRL-B=bold, CTRL-I = italic, CTRL-Q=quote) to the fast reply text area
- Adds short-cut keys for inserting text
- CTRL-SHIFT-G Appends an italicized "Edited for grammar" message to the post.
- CTRL-SHIFT-C Appends an italicized "Edited for clarification" message to the post.
- CTRL-SHIFT-I Inserts an "In my opinion, ".
- CTRL-SHIFT-T Appends a "Thanks in advance." to the post.
Script Source
// IP.Board: 'Fast Reply' Improvements
// Copyright (c) 2006-2007 Orbona
// Version 1.0
// Release Date: 2007-10-22
//
// See also: http://www.orbona.com/greasemonkey/
//
// Original file name: ipboard_fastreply.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).
//
// (1) Adds a Fast Reply button at the top of the page which behaves just
// like the Fast Reply button at the bottom of the page.
//
// (2) When any action is taken that opens the "Fast Reply" form, the focus
// is automatically moved to the "fast reply" text area so that typing
// can begin immediately.
//
// (3) Adds shortcuts for formatting text to the reply text area. CTRL-B
// will add bold tags, CTRL-I will add italic tags, and CTRL-Q will add
// "Quote" tags to the selected text.Not all IP.Boards support all
// formatting options.
//
// (4) Adds shortcuts for inserting (my) commonly used phrases. CTRL-SHIFT-G
// appends an italicized 'Edited for grammar' to the post. CTRL-SHIFT-C
// appends an italicized 'Edited for clarification' to the post.
// CTRL-SHIFT-I inserts an "In my opinion,". CTRL-SHIFT-T appends a
// "Thanks in advance." to the post,
// --------------------------------------------------------------------------
// ==UserScript==
// @name IP.Board: 'Fast Reply' Improvements
// @description Adds a 'Fast Reply' button to the top of the page, moves focus to the fast reply text area when it is opened, and adds shortcuts (CTRL-B, CTRL-I, CTRL-Q) for formatting selected text and inserting commonly used phrases
// @namespace http://www.orbona.com/greasemonkey/
// @include http://forums.televisionwithoutpity.com/index.php?showtopic*
// @include http://www2.konfabulator.com/forums/index.php?showtopic*
// ==/UserScript==
//-----------------------------------------------------------------------------
// Stops the default event action from occuring.
//-----------------------------------------------------------------------------
function stopDefault(event) {
event.preventDefault();
event.stopPropogation();
}
//-----------------------------------------------------------------------------
// Shows or hides the fast reply area, and sets the focus to the fast reply
// area if it is showing
//-----------------------------------------------------------------------------
function focusFastReply(event) {
//unsafeWindow.ShowHide('qr_open','qr_closed');
//to avoid using unsafeWindow
toggleView ('qr_open');
toggleView('qr_closed');
var fastReplyArea = document.getElementById('fastreplyarea');
if (fastReplyArea.style.display != 'none') fastReplyArea.focus();
//stopDefault(event);
}
//-----------------------------------------------------------------------------
// Show/hide element specified by id
//-----------------------------------------------------------------------------
function toggleView(id) {
if ( !id ) return;
var itm = document.getElementById(id);
if ( itm )
itm.style.display = itm.style.display=="none" ? "" : "none";
}
//-----------------------------------------------------------------------------
// Surrounds the selected text with the appropriate UBB tags, or inserts the
// appropriate text.
//-----------------------------------------------------------------------------
function handleKey(event) {
var target = event ? event.target : this;
var key, selStart, selEnd, stringKey, tag;
if (event.shiftKey && event.ctrlKey) {
key = event.which || event.charCode || event.keyCode;
switch (key) {
case 67: //C
target.value = target.value + '\n\n' + '[i]Edited for clarification.[/i]';
stopDefault(event);
break;
case 71: //G
target.value = target.value + '\n\n' + '[i]Edited for grammar.[/i]';
stopDefault(event);
break;
case 73: //I
selStart = target.selectionStart;
selEnd = target.selectionEnd;
target.value = target.value.substring(0, selStart) + 'In my opinion, ' + target.value.substring(selEnd, target.value.length);
stopDefault(event);
break;
case 84: //T
selStart = target.selectionStart;
selEnd = target.selectionEnd;
target.value = target.value + 'Thanks in advance.';
stopDefault(event);
}
}
else if (event.ctrlKey) {
key = event.which || event.charCode || event.keyCode;
stringKey = String.fromCharCode(key).toUpperCase();
if (stringKey=="B" || stringKey=="I" || stringKey=="Q") {
tag= stringKey!="Q" ? stringKey : "QUOTE";
selStart = target.selectionStart;
selEnd = target.selectionEnd;
target.value = target.value.substring(0, selStart)+ '[' + tag + ']' + target.value.substring(selStart, selEnd) + '[/' + tag + ']'+ target.value.substring(selEnd, target.value.length);
stopDefault(event);
}
}
}
// ----------------------------------------------------------------------------
// Changes the id attribute of a node to include a "-clone" at the end. If the
// node doesn't have an id attribute, it is not added. Currently used to
// ensure cloned nodes have unique ids when added to the document.
// ----------------------------------------------------------------------------
function changeId(node) {
var children, i;
if(node.nodeType == 1 && node.id)
node.id += '-clone';
children = node.childNodes;
for(i = 0;i < children.length;i++)
changeId(children.item(i));
}
// ----------------------------------------------------------------------------
// Main function that does everything described in the description area above.
// ----------------------------------------------------------------------------
function doIt() {
var fastReplyArea = document.getElementById('fastreplyarea');
var links, currentLink, clonedFastReply;
if (fastReplyArea) {
//Adds shortcut keys for text formatting
fastReplyArea.addEventListener('keypress', handleKey, true);
// Modifies any "Fast Reply" buttons to transfer focus to the fast reply area text box.
links=document.evaluate("//A[contains(@href,'qr_open')]", document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
for (var i = 0; i < links.snapshotLength; i++) {
currentLink = links.snapshotItem(i);
currentLink .addEventListener('click', focusFastReply, true);
currentLink.addEventListener('click', function(event) {stopDefault(event);}, false);
clonedNode = currentLink.cloneNode(true);
clonedNode.addEventListener('click', focusFastReply, true);
clonedNode.addEventListener('click', function(event) {stopDefault(event);}, false);
changeId(clonedNode);
}
//Add "Fast Reply" button at top, in front of non-fast "Reply"
links=document.evaluate("//A[contains(@href,'reply_post')]", document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
if (links.snapshotLength > 0 && clonedNode)
links.snapshotItem(0).parentNode.insertBefore(clonedNode, links.snapshotItem(0));
}
}
// ------------------END OF FUNCTIONS -----------------------------
window.addEventListener("load", function() { doIt(); }, false);