Click to install this script

IP Board: Fast Reply Improvements

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

File Name: ipboard_fastreply.user.js

Click to hide sectionDescription

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.

Click to hide sectionScript 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);