NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript==
// @name SDMB Editor shortcuts
// @namespace http://tampermonkey.net/
// @version 0.95
// @description Adds better keyboard shortcuts for the post editor, even on Chrome
// @author BigT@SDMB
// @match *://boards.straightdope.com/sdmb/showthread.php*
// @match *://boards.straightdope.com/sdmb/newreply.php*
// @match *://boards.straightdope.com/sdmb/private.php*
// @grant none
// @license MIT
// ==/UserScript==
var keytest = false;
if (keytest) { window.alert('keytest active'); }
var vB_Editor = window.vB_Editor || window.wrappedJSObject.vB_Editor;
var editorID = Object.keys(vB_Editor)[0];
var textbox = document.getElementById(editorID + '_textarea');
var buttonList = {
undo: ['undo', 'Shift-Z', 'Shift-Z) (works on formatting'],
redo: ['redo', 'Shift-Y', 'Shift-Y) (works on formatting'],
bold: ['Bold', 'B'],
italic: ['Italic', 'I'],
underline: ['Underline', 'U'],
createlink: ['Insert link', 'K'],
wrap0_quote: ['Wrap [QUOTE] tags around selected text', 'Q'],
removeformat: ['Remove text formatting', ' ', 'Space'],
resize_0_: ['Decrease size' + ((editorID == 'vB_Editor_001') ? '100' : '99'), 'ARROWUP', 'Up'],
resize_1_: ['Increase size' + ((editorID == 'vB_Editor_001') ? '100' : '99'), 'ARROWDOWN', 'Down'],
justifyleft: ['justifyleft', 'L'],
justifyright: ['justifyright', 'R'],
justifycenter: ['justifycenter', 'E'],
insertorderedlist: ['insertorderedlist', '1'],
insertunorderedlist: ['insertunorderedlist', 'Shift-L'],
indent: ['indent', 'M'],
unlink: ['unlink', 'Shift-K'],
outdent: ['outdent', 'Shift-M'],
wrap0_code: ['wrap0_code','3','#', 'Shift-#'],
wrap0_php: ['wrap0_php','H'],
wrap0_del: ['wrap0_del', 'S'],
switchmode: ['switchmode', 'Shift-S']
};
applyTooltips(buttonList, editorID);
textbox.addEventListener('keydown', function(key) { keyCheck(key, editorID);} );
/* Doesn't work
applyEditButton();
function applyEditButton() {
var editButton = document.querySelector('[alt="Edit/Delete Message"]');
if (editButton) {
var postEditorID = editButton.parentNode.name.split('::')[2];
var postEditor = document.getElementById('post_message_' + postEditorID);
editButton.addEventListener('click', function() {
console.warn('Edit button clicked');
var observer = new MutationObserver(function() {
applyEditbox(postEditor);
observer.disconnect();
});
observer.observe(postEditor, { childList: true });
}/*, { once: true }*//*);
}
var submitButton = document.getElementById('qr_submit');
if (submitButton) {
submitButton.addEventListener('click', function() {
console.warn('"Post Quick Reply" pressed');
var observer = new MutationObserver( function() {
applyEditButton();
observer.disconnect();
});
observer.observe(postEditor, { childList: true });
});
}
}
END doesn't work */
function applyTooltips(buttonList, editorID) {
//window.fakeConsole = '';
for (let command in buttonList) {
let buttonID = buttonList[command];
let element = document.getElementById(editorID + '_cmd_' + command);
//fakeConsole += command + '\n';
if (element) {
if (!element.firstChild.title) { element.firstChild.title = buttonID[0]; } //[0] = tooltip
if (element.firstChild.title.search('Ctrl-') === -1) {
element.firstChild.title += ' (Ctrl-' + (buttonID[2] ? buttonID[2] : buttonID[1]) + ')';
}
}
}
//alert(fakeConsole);
}
function keyCheck(event, editorID){
var finished;
if (event.ctrlKey) {
var keypress = (event.shiftKey ? 'Shift-' : '') + event.key.toUpperCase();
for (let button in buttonList) {
let key = buttonList[button];
if (keypress === key[1] || keypress === key[2] || keypress === key[3]) {
vB_Editor[editorID].format(new Event('click'), button);
event.preventDefault();
event.stopPropagation();
finished = true;
break;
}
}
} else if (event.altKey && !event.ShiftKey && !event.CtrlKey && event.key.toUpperCase() === 'S') {
var submitButton = document.getElementById('qr_submit');
if (submitButton) {
submitButton.dispatchEvent('click');
event.preventDefault();
event.stopPropagation();
finished = true;
}
}
if (keytest && !finished && event.key !== 'Control' && event.key !== 'Shift' && event.key !== 'Alt') {
let Ctrl = event.ctrlKey ? 'Ctrl-' : '',
Alt = event.altKey ? 'Alt-' : '',
Shift = event.shiftKey ? 'Shift-' : '',
Key = event.key.search(/^[a-z]$/) !== -1 ? event.key.toUpperCase() + ' (lowercase)' : event.key;
if (Ctrl || Alt || event.key.search(/^[\w `\-=[\]\\;',./!@#$%^&*()+{}:"<>?]$/) === -1) {
console.warn(Ctrl + Alt + Shift + Key);
if (Key !== 'Backspace' && Key !== 'Enter') {
event.preventDefault();
event.stopPropagation();
}
}
}
}
function applyEditbox(postEditor) {
var editorID;
var editbox = postEditor.getElementsByTagName('textarea')[0];
if (editbox) { editorID = editbox.id.split('_textarea')[0]; }
applyTooltips(buttonList, editorID);
editbox.addEventListener('keydown', function (key) {
keyCheck(key, editorID);
});
var observer2 = new MutationObserver(function () {
applyWysiwyg(editorID);
observer2.disconnect();
});
observer2.observe(editbox.parentNode, { childList: true });
}
// ---Apply to WYSIWYG editor, too.---
function applyWysiwyg(editorID) {
//alert('applyWysiwyg() fired');
var wysiwyg = document.getElementById(editorID + '_iframe');
if (wysiwyg) {
wysiwyg.contentWindow.document.body.addEventListener('keydown', function(event) { keyCheck(event, editorID); });
}
return !!wysiwyg; //true if function worked, false otherwise
}
if (!applyWysiwyg() && window.MutationObserver) { //don't create observer unnecessarily
var observer = new MutationObserver(function () {
applyWysiwyg(editorID);
observer.disconnect();
} );
observer.observe(textbox.parentNode, { childList: true });
}
/**/