Last active
December 20, 2016 20:23
-
-
Save josefandersson/87bb047bea31124ec7f6b4af2064bf71 to your computer and use it in GitHub Desktop.
A userscript for counting characters in a post! (In the same way the server counts characters in a post.)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name HF Character Counter | |
// @description Counts the number of characters in a post or PM on Hackforums.net! | |
// @author Josef A. (DrDoof) | |
// @namespace https://github.com/josefandersson | |
// @require https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js | |
// @include *://hackforums.net/* | |
// @grant GM_addStyle | |
// @grant GM_setValue | |
// @grant GM_getValue | |
// @version 1.2.6 | |
// @run-at document-end | |
// ==/UserScript== | |
/* HELLO USER - CHANGE THESE SETTINGS AS YOU WILL - ALL SHOULD BE SET TO TRUE FOR THE REAL CHARACTER COUNT (THE ONE USED FOR LUCKY AWARD) */ | |
ignore = { | |
quotes: true, // Ignore quotes | |
images: true, // Ignore images | |
urls: true, // Ignore urls | |
emails: true, // Ignore emails | |
fonts: true, // Ignore fonts | |
colors: true, // Ignore colors | |
aligns: true, // Ignore aligns | |
sizes: true, // Ignore sizes | |
lists: true, // Ignore lists | |
italics: true, // Ignore italics | |
bolds: true, // Ignore bolds | |
underlines: true, // Ignore underlines | |
strikes: true, // Ignore strikes | |
spoilers: true, // Ignore spoilers | |
smilies: true, // Ignore smilies | |
codes: true, // Ignore codes | |
phps: true, // Ignore phps | |
videos: true, // Ignore videos | |
newlines: true, // Ignore newlines | |
}; | |
/* END OF SETTINGS*/ | |
// To get the real length of a textarea we have to think like the HF server! | |
sr = /^([ ]|\n|\t|\r)+/g; | |
er = /([ ]|\n|\t|\r)+$/g; | |
// The user may also toggle the counting of various things. | |
qr = /\[quote.*?\](.|\n)*?\[\/quote\]/g; // quotes | |
ir = /\[img\](http|https):\/\/.+\[\/img\]/g; // images | |
ur1 = /\[url\].+\[\/url\]/g; // 1st url variant | |
ur2 = /\[url=.+\]((?:.|\n)*?)\[\/url\]/g; // 2nd url variant | |
mr1 = /\[email\].+\[\/email\]/g; // 1st email variant | |
mr2 = /\[email=.+\]((?:.|\n)*?)\[\/email\]/g; // 2nd email variant | |
fr = /\[font=.+\]((?:.|\n)*?)\[\/font\]/g; // font | |
cr = /\[color=#[a-fA-F0-9]{6}\]((?:.|\n)*?)\[\/color\]/g; // color | |
ar = /\[align=(?:left|right|center|justify)\]((?:.|\n)*?)\[\/align\]/g; // align | |
sir = /\[size=(?:xx-small|x-small|small|medium|large|x-large|xx-large)\]((?:.|\n)*?)\[\/size\]/g; // size | |
lr = /\[list(?:=1|=a)?\]((?:.|\n)*?)\[\/list\]/g; // list | |
br = /\[b\]((?:.|\n)*?)\[\/b\]/g; // bold | |
itr = /\[i\]((?:.|\n)*?)\[\/i\]/g; // italic | |
ur = /\[u\]((?:.|\n)*?)\[\/u\]/g; // underline | |
str = /\[s\]((?:.|\n)*?)\[\/s\]/g; // strikethrough | |
cor = /\[code\]((?:.|\n)*?)\[\/code\]/g; // code | |
pr = /\[php\]((?:.|\n)*?)\[\/php\]/g; // php | |
vr = /\[video=(?:youtube|vimeo|yahoo)\]((?:.|\n)*?)\[\/video\]/g; // video (I believe only three of them works) | |
sr1 = /\[sp.*?\]((?:.|\n)*?)\[\/sp\]/g; // 1st spoiler variant | |
sr2 = /\[spoiler.*?\]((?:.|\n)*?)\[\/spoiler\]/g; // 2nd spoiler variant | |
smr = /:(pinch|victoire|hehe|oui|bebe-pleure|ohmy|blink|superman|nono|biggrin|sad|unsure|glare|roflmao|devlish|rolleyes|cool|gratte|confused|blackhat|ninja|blush|lipssealed|yeye|non|smile|whistle|sleep|evilgrin|omg|tongue|mad|huh|thumbsup|wacko|pirate):/g; // smilies | |
nr = /\n*/g; // newline | |
// Our textarea variable will just default to null. | |
ta = null; | |
// Whether or not we should ignore to filter ignore settings. | |
// If you are using longer posts this should probably be toggled to true to prevent lag. | |
// This gets toggled by clicking on the character counter text. | |
f = GM_getValue('f') === 'true'; | |
/* Find the textarea for this page, add the counter | |
** element to it and add the eventlistener. */ | |
(() => { | |
// Add the styling for the display text. | |
GM_addStyle([ | |
'p#char_count {', | |
'margin-top: -20px;', | |
'float: right;', | |
'margin-right: 13px;', | |
'color: red;', | |
'opacity: 0.999', // This one has to be here but it makes absolutely no sense why... Stupid CSS. | |
'}' | |
].join('')); | |
// Determine the textarea from current path. | |
paths = {'/showthread.php': [25, 100], '/newreply.php': [25, 100], '/newthread.php': [25, false]}; | |
if (paths[location.pathname]) { | |
ta = $('#message_new'); | |
if (!ta.length) ta = $('#message'); | |
low = paths[location.pathname][0]; | |
high = paths[location.pathname][1]; | |
} | |
// Whoops! No text areas on this page! | |
if (!ta) return; | |
// Add the element that displays the character count text after the text area. | |
(cc = $('<p>', { id: 'char_count', text: `${ta.text().length} characters`, onselectstart: 'return false;' })).insertAfter(ta); | |
// Update the character counter elements text and color. | |
u = () => { | |
if (high === false) { | |
cc.text(`${rl} characters`); | |
if (low <= rl) cc.css('color', 'green'); else cc.css('color', 'red'); | |
} else { | |
if (f) { | |
cc.text(`${rl} characters (click to toggle lucky filtering)`); | |
if (low <= rl) cc.css('color', 'green'); else cc.css('color', 'red'); | |
} else { | |
if (l == rl) cc.text(`${rl} characters`); | |
else cc.text(`${rl} characters (${l} lucky characters)`); | |
if (high <= l) cc.css('color', 'green'); else if (low <= rl) cc.css('color', '#008ae6'); else cc.css('color', 'red'); | |
} | |
} | |
}; | |
// Count the characters in the text right now. | |
lf = () => { | |
t = ta.val(), t = t.slice((t.match(sr) || [''])[0].length, -(t.match(er) || [''])[0].length || undefined); // Remove spaces at start and end of string and replace newlines with two underscores. | |
// This will be the character count before user filtering has been applied. | |
rl = t.split("\n").join('__').length; | |
// Don't filter ignore settings when f is true. | |
if (!f && high !== false) { | |
// Depending on the user settings we'll remove some things from the text. | |
if (ignore.newlines) t = t.replace(nr, ''); | |
if (ignore.quotes) t = t.replace(qr, ''); | |
if (ignore.images) t = t.replace(ir, ''); | |
if (ignore.urls) { t = t.replace(ur1, ''); while (ur2.test(t)) t = t.replace(ur2, '$1'); } | |
if (ignore.emails) { t = t.replace(mr1, ''); while (mr2.test(t)) t = t.replace(mr2, '$1'); } | |
if (ignore.fonts) while (fr.test(t)) t = t.replace(fr, '$1'); | |
if (ignore.colors) while (cr.test(t)) t = t.replace(cr, '$1'); | |
if (ignore.aligns) while (ar.test(t)) t = t.replace(ar, '$1'); | |
if (ignore.sizes) while (sir.test(t)) t = t.replace(sir, '$1'); | |
if (ignore.lists) while (lr.test(t)) t = t.replace(lr, '$1'); | |
if (ignore.italics) while (itr.test(t)) t = t.replace(itr, '$1'); | |
if (ignore.bolds) while (br.test(t)) t = t.replace(br, '$1'); | |
if (ignore.underlines) while (ur.test(t)) t = t.replace(ur, '$1'); | |
if (ignore.strikes) while (str.test(t)) t = t.replace(str, '$1'); | |
if (ignore.spoilers) { while (sr1.test(t)) t = t.replace(sr1, '$1'); while (sr2.test(t)) t = t.replace(sr2, '$1'); } | |
if (ignore.smilies) t = t.replace(smr, ''); | |
if (ignore.codes) t = t.replace(cor, ''); | |
if (ignore.phps) t = t.replace(pr, ''); | |
if (ignore.videos) t = t.replace(vr, ''); | |
// The length after filtering ignore settings. | |
l = t.length; | |
} | |
} | |
// Listen to every click event on the character counter element. | |
cc.click((e) => { | |
f = !f; | |
GM_setValue('f', `${f}`); // Save the state between pages. | |
lf(); | |
u(); | |
}); | |
// Listen to every input event in the textarea and update the character counter element. | |
ta.on('input', (e) => { | |
// Count the characters in the text. | |
lf(); | |
// Update the character counter elements text and color. | |
u(); | |
}); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment