F
Francesco S. Carta
Hi there,
well, javascript is definitely a lot of fun
Here below I'm pasting a script I've created these days, after having
studied some Greasemonkey scripts a bit (Gmail Bottom Posting v.3 and
ggNoSpam 0.4.0 in particular)
I tested the script only on Firefox 3.5.3, works fine so far.
I'll welcome any fix, suggestion and improvement, but moreover any
critic about the coding style - I've hacked it altogether without any
deep insight, I've just fiddled with it till I've got it working as I
intended.
I'm having some trouble registering on userscripts.org, I'll post it
there and I'll add a link here afterwards, for easy installation -
assuming I'll ever be able to overcome the problems with my proxy.
Here is a screenshot:
http://fscode.altervista.org/ggp_utils.png
For what is worth, I hope you'll find it useful.
Cheers,
Francesco
-------
// ==UserScript==
// @name GG Posting Utils
// @version 2009/10/16
// @namespace http://fscode.altervista.org
// @description (see script for additional settings and details)
// @include http://groups.google.tld/group/*/thread*
// @include http://groups.google.tld/group/*/post*
// ==/UserScript==
/*
Google Groups Posting Utilities, v. 2009/10/16
Copyright 2009 by Francesco S. Carta
e-mail: entuland at gmail.com
Website: http://fscode.altervista.org
This script is inspired by:
Gmail Bottom Posting v3, http://userscripts.org/scripts/show/35866
ggNoSpam v. 0.4.0, http://userscripts.org/scripts/show/59377
Disclaimer: by running this script you take all responsibilities
about the effects of the script, no warranty given nor implied.
Permission is granted to copy, modify and distribute this script
as long as it is shipped with this comment, kept entirely unchanged.
*/
/*
FEATURES:
a) strip signature from quoted post
t, f) strip date from quoted post
t, f) insert snippets at the bottom of the active posting form
t, f) insert signatures at the bottom of the active posting form
f) settings panel in the bottom-right corner of the viewport
f) signature replacement warning
(a = always, t = toggle in the panel, f = flag in the script
settings)
Adding snippets and sigs works also when posting new topics
(the links appear as soon as you enter the textarea)
Improvement notice: I'm no javascript expert and this code
can be greatly improved by adding support for other browsers
(currently tested only on Firefox 3.5.3)
Feel free to improve and share it.
*/
// ========
// SETTINGS
// ========
/*
- add signatures and snippets to the arrays below
- insert \n into the signature text to split different lines
*/
var signatures = [
//["link text", "signature text"], // omit comma in the last sig
["Happy", "Poster\nHappy GG user"],
["Unhappy", "Poster\nUnhappy GG user"],
["Don't care", "Don't\nCare\nAbout\nSignatures"] // no comma here
];
var snippets = [
//["link text", "snippet text"], // omit comma in the last snippet
["c.l.js FAQ", "comp.lang.javascript FAQ:\nhttp://jibbering.com/faq
\n"],
["Don't care", "Don't\nCare\nAbout\nSnippets"] // no comma here
];
// set this to false to display the date of the quoted post
var strip_date_from_quote = true;
// set this to false to hide links for adding snippets
var show_snippets = true;
// set this to false to hide links for adding signatures
var show_signatures = true;
// set this to false to hide the safety reminder
// (makes no difference if signatures are turned off)
var show_reminder = true;
// set this to false to hide the bottom-right "GGP Utils" panel
var show_panel = true;
// ===============
// END OF SETTINGS
// ===============
// these are the class names used for the added elements
// change them if they conflict with some other script
var sigclassname = 'GGP_add_link_';
var snipclassname = 'GGP_add_snip_';
var toggledateclassname = 'GGP_toggle_date';
var togglesnipsclassname = 'GGP_toggle_snips';
var togglesigsclassname = 'GGP_toggle_sigs';
/*
GGP utils bar, this will be appended
after the currently active posting form
*/
var utilsbar = document.createElement('DIV');
var pseudolink = document.createElement('SPAN');
utilsbar.style.padding = '0.4em';
utilsbar.style.lineHeight = '200%';
pseudolink.style.color = '#00F';
pseudolink.style.cursor = 'pointer';
pseudolink.style.textDecoration = 'underline';
function updateutilsbar() {
utilsbar.innerHTML = '';
if(show_snippets) {
utilsbar.innerHTML = "Snippet: ";
for(var i = 0; i < snippets.length; ++i) {
var curlink = pseudolink.cloneNode(true);
// insert snippet link text
curlink.innerHTML = snippets[0];
// insert snippet into tooltip for preview
curlink.title = snippets[1];
// set snippet class name appending snippet index
curlink.className = snipclassname + i;
// add whitespace and separator, append link to utils bar
utilsbar.innerHTML += ' ';
utilsbar.appendChild(curlink);
if(i < snippets.length - 1) {
utilsbar.innerHTML += ' -';
}
}
// insert a break between snippets' and the sigs' links
utilsbar.innerHTML += '\n<br />\n';
}; // end if(show_snippets);
if(show_signatures) {
utilsbar.innerHTML += "Signature: ";
for(var i = 0; i < signatures.length; ++i) {
var curlink = pseudolink.cloneNode(true);
// insert signature link text
curlink.innerHTML = signatures[0];
// insert signature into tooltip for preview
curlink.title = signatures[1];
// set sig class name appending sig index
curlink.className = sigclassname + i;
// add whitespace and separator, append link to utils bar
utilsbar.innerHTML += ' ';
utilsbar.appendChild(curlink);
if(i < signatures.length - 1) {
utilsbar.innerHTML += '\n-';
}
}
if(show_reminder) {
utilsbar.innerHTML += '<br /><span '
+ 'style="color: #F00; '
+ 'font-style: italic; ">'
+ 'Everything after the "-- " '
+ 'line will be erased! (but \'Undo\' or '
+ '\'Ctrl+Z\' could eventually recover)</
span>';
}
}; // end if(show_signatures);
} // end of function updateutilsbar()
// call it for the first time
updateutilsbar();
// end of GGP utils bar construction
/*
update all the interface
*/
function update() {
updateutilsbar();
updatepanel();
}
/*
textarea formatting function
*/
function format(textarea) {
// work on a copy to avoid text flickering
var text = textarea.value;
if(strip_date_from_quote) {
text = text.replace(/^.*,.*, /, '');
}
// strip quoted signature
text = text.replace(/\> \-\- ?\n(> .*\n)+(>\n)?/, '');
// store back the copy into the textarea and scroll to its bottom
textarea.value = text;
textarea.scrollTop = textarea.scrollHeight;
// move the caret to the end of the post
setTimeout(
function(){textarea.setSelectionRange(text.length, text.length);}
,1);
// append the utils bar after the current textarea
textarea.parentNode.appendChild(utilsbar);
}
/*
functions for adding signatures and snippets
*/
function addsignature(link) {
// get the current posting textarea
var text = link.parentNode.previousSibling.previousSibling;
// work on a copy to avoid text flickering
var temp = text.value;
// strip out previously inserted signature (if any)
temp = temp.replace(/\n-- ?\n.*(\n.*)*/, '');
// save the current post length
var size = temp.length;
// extract the signature index from the class name
var i = +link.className.slice(sigclassname.length);
// add currently selected signature
temp += '\n-- \n' + signatures[1];
// store back the copy into the textarea
text.value = temp;
// focus the textarea
text.focus();
// place the caret between the text and the signature
setTimeout(
function(){
text.setSelectionRange(size,size);
}
,1);
}
function addsnippet(link) {
// get the current posting textarea
var text = link.parentNode.previousSibling.previousSibling;
// work on a copy to avoid text flickering
var temp = text.value;
// extract the snippet index from the class name
var i = +link.className.slice(snipclassname.length);
// add currently selected snippet
temp += snippets[1];
// store back the copy into the textarea
text.value = temp;
// place the caret at the end of text
text.focus();
}
/*
listener functions
*/
// dispatch the click events to add snippet & sig and to switch
toggles
document.addEventListener(
'click',
function(event) {
var classname = event.target.className
var sigfilter = new RegExp(sigclassname, '');
var snipfilter = new RegExp(snipclassname, '');
if(sigfilter.test(classname)) {
addsignature(event.target);
} else if (snipfilter.test(classname)) {
addsnippet(event.target);
} else if (classname == toggledateclassname) {
strip_date_from_quote = !strip_date_from_quote;
update();
} else if (classname == togglesnipsclassname) {
show_snippets = !show_snippets;
update();
} else if (classname == togglesigsclassname) {
show_signatures = !show_signatures;
update();
}
},
true
);
// when focusing the textarea of a posting form,
// call format() to strip date and signature from quoted post
// and to move the utils bar beneath the current textarea
document.addEventListener(
'focus',
function(event) {
if (event.target.id
&& event.target.name == 'body') {
format(event.target);
}
},
true
);
/*
code to display the panel in the
bottom-right corner of the viewport
*/
var utilspanel = document.createElement('DIV');
utilspanel.title = 'GoogleGroups Posting Utilities, '
+ 'http://fscode.altervista.org'
function updatepanel() {
if(show_panel) {
utilspanel.innerHTML = '';
var s = utilspanel.style;
s.fontSize = '80%'
s.position = 'fixed';
s.border = '1px solid #000';
s.padding = '0.4em 1em 0.4em 1em';
s.bottom = '0';
s.right = '0';
s.background = '#C3D9FF';
utilspanel.innerHTML = '<span style="font-weight: bolder">'
+ 'GGP Utils Settings</span>';
var curlink = pseudolink.cloneNode(true);
curlink.style.fontWeight = 'bolder';
curlink.title = 'Click to toggle ON/OFF';
var datetoggler = curlink.cloneNode(true);
var snipstoggler = curlink.cloneNode(true);
var sigstoggler = curlink.cloneNode(true);
datetoggler.className = toggledateclassname;
snipstoggler.className = togglesnipsclassname;
sigstoggler.className = togglesigsclassname;
function formattoggle(toggle, active) {
toggle.style.color = active ? '#00F' : '#F00';
toggle.innerHTML = active ? 'ON' : 'OFF';
}
formattoggle(datetoggler, strip_date_from_quote);
formattoggle(snipstoggler, show_snippets);
formattoggle(sigstoggler, show_signatures);
utilspanel.innerHTML += '<br />Strip Date: ';
utilspanel.appendChild(datetoggler);
utilspanel.innerHTML += '<br />Show Snips: ';
utilspanel.appendChild(snipstoggler);
utilspanel.innerHTML += '<br />Show Sigs: ';
utilspanel.appendChild(sigstoggler);
}
} // end of function updatepanel()
// call it for the first time
updatepanel();
// append it once
document.body.appendChild(utilspanel);
// end of script
well, javascript is definitely a lot of fun
Here below I'm pasting a script I've created these days, after having
studied some Greasemonkey scripts a bit (Gmail Bottom Posting v.3 and
ggNoSpam 0.4.0 in particular)
I tested the script only on Firefox 3.5.3, works fine so far.
I'll welcome any fix, suggestion and improvement, but moreover any
critic about the coding style - I've hacked it altogether without any
deep insight, I've just fiddled with it till I've got it working as I
intended.
I'm having some trouble registering on userscripts.org, I'll post it
there and I'll add a link here afterwards, for easy installation -
assuming I'll ever be able to overcome the problems with my proxy.
Here is a screenshot:
http://fscode.altervista.org/ggp_utils.png
For what is worth, I hope you'll find it useful.
Cheers,
Francesco
-------
// ==UserScript==
// @name GG Posting Utils
// @version 2009/10/16
// @namespace http://fscode.altervista.org
// @description (see script for additional settings and details)
// @include http://groups.google.tld/group/*/thread*
// @include http://groups.google.tld/group/*/post*
// ==/UserScript==
/*
Google Groups Posting Utilities, v. 2009/10/16
Copyright 2009 by Francesco S. Carta
e-mail: entuland at gmail.com
Website: http://fscode.altervista.org
This script is inspired by:
Gmail Bottom Posting v3, http://userscripts.org/scripts/show/35866
ggNoSpam v. 0.4.0, http://userscripts.org/scripts/show/59377
Disclaimer: by running this script you take all responsibilities
about the effects of the script, no warranty given nor implied.
Permission is granted to copy, modify and distribute this script
as long as it is shipped with this comment, kept entirely unchanged.
*/
/*
FEATURES:
a) strip signature from quoted post
t, f) strip date from quoted post
t, f) insert snippets at the bottom of the active posting form
t, f) insert signatures at the bottom of the active posting form
f) settings panel in the bottom-right corner of the viewport
f) signature replacement warning
(a = always, t = toggle in the panel, f = flag in the script
settings)
Adding snippets and sigs works also when posting new topics
(the links appear as soon as you enter the textarea)
Improvement notice: I'm no javascript expert and this code
can be greatly improved by adding support for other browsers
(currently tested only on Firefox 3.5.3)
Feel free to improve and share it.
*/
// ========
// SETTINGS
// ========
/*
- add signatures and snippets to the arrays below
- insert \n into the signature text to split different lines
*/
var signatures = [
//["link text", "signature text"], // omit comma in the last sig
["Happy", "Poster\nHappy GG user"],
["Unhappy", "Poster\nUnhappy GG user"],
["Don't care", "Don't\nCare\nAbout\nSignatures"] // no comma here
];
var snippets = [
//["link text", "snippet text"], // omit comma in the last snippet
["c.l.js FAQ", "comp.lang.javascript FAQ:\nhttp://jibbering.com/faq
\n"],
["Don't care", "Don't\nCare\nAbout\nSnippets"] // no comma here
];
// set this to false to display the date of the quoted post
var strip_date_from_quote = true;
// set this to false to hide links for adding snippets
var show_snippets = true;
// set this to false to hide links for adding signatures
var show_signatures = true;
// set this to false to hide the safety reminder
// (makes no difference if signatures are turned off)
var show_reminder = true;
// set this to false to hide the bottom-right "GGP Utils" panel
var show_panel = true;
// ===============
// END OF SETTINGS
// ===============
// these are the class names used for the added elements
// change them if they conflict with some other script
var sigclassname = 'GGP_add_link_';
var snipclassname = 'GGP_add_snip_';
var toggledateclassname = 'GGP_toggle_date';
var togglesnipsclassname = 'GGP_toggle_snips';
var togglesigsclassname = 'GGP_toggle_sigs';
/*
GGP utils bar, this will be appended
after the currently active posting form
*/
var utilsbar = document.createElement('DIV');
var pseudolink = document.createElement('SPAN');
utilsbar.style.padding = '0.4em';
utilsbar.style.lineHeight = '200%';
pseudolink.style.color = '#00F';
pseudolink.style.cursor = 'pointer';
pseudolink.style.textDecoration = 'underline';
function updateutilsbar() {
utilsbar.innerHTML = '';
if(show_snippets) {
utilsbar.innerHTML = "Snippet: ";
for(var i = 0; i < snippets.length; ++i) {
var curlink = pseudolink.cloneNode(true);
// insert snippet link text
curlink.innerHTML = snippets[0];
// insert snippet into tooltip for preview
curlink.title = snippets[1];
// set snippet class name appending snippet index
curlink.className = snipclassname + i;
// add whitespace and separator, append link to utils bar
utilsbar.innerHTML += ' ';
utilsbar.appendChild(curlink);
if(i < snippets.length - 1) {
utilsbar.innerHTML += ' -';
}
}
// insert a break between snippets' and the sigs' links
utilsbar.innerHTML += '\n<br />\n';
}; // end if(show_snippets);
if(show_signatures) {
utilsbar.innerHTML += "Signature: ";
for(var i = 0; i < signatures.length; ++i) {
var curlink = pseudolink.cloneNode(true);
// insert signature link text
curlink.innerHTML = signatures[0];
// insert signature into tooltip for preview
curlink.title = signatures[1];
// set sig class name appending sig index
curlink.className = sigclassname + i;
// add whitespace and separator, append link to utils bar
utilsbar.innerHTML += ' ';
utilsbar.appendChild(curlink);
if(i < signatures.length - 1) {
utilsbar.innerHTML += '\n-';
}
}
if(show_reminder) {
utilsbar.innerHTML += '<br /><span '
+ 'style="color: #F00; '
+ 'font-style: italic; ">'
+ 'Everything after the "-- " '
+ 'line will be erased! (but \'Undo\' or '
+ '\'Ctrl+Z\' could eventually recover)</
span>';
}
}; // end if(show_signatures);
} // end of function updateutilsbar()
// call it for the first time
updateutilsbar();
// end of GGP utils bar construction
/*
update all the interface
*/
function update() {
updateutilsbar();
updatepanel();
}
/*
textarea formatting function
*/
function format(textarea) {
// work on a copy to avoid text flickering
var text = textarea.value;
if(strip_date_from_quote) {
text = text.replace(/^.*,.*, /, '');
}
// strip quoted signature
text = text.replace(/\> \-\- ?\n(> .*\n)+(>\n)?/, '');
// store back the copy into the textarea and scroll to its bottom
textarea.value = text;
textarea.scrollTop = textarea.scrollHeight;
// move the caret to the end of the post
setTimeout(
function(){textarea.setSelectionRange(text.length, text.length);}
,1);
// append the utils bar after the current textarea
textarea.parentNode.appendChild(utilsbar);
}
/*
functions for adding signatures and snippets
*/
function addsignature(link) {
// get the current posting textarea
var text = link.parentNode.previousSibling.previousSibling;
// work on a copy to avoid text flickering
var temp = text.value;
// strip out previously inserted signature (if any)
temp = temp.replace(/\n-- ?\n.*(\n.*)*/, '');
// save the current post length
var size = temp.length;
// extract the signature index from the class name
var i = +link.className.slice(sigclassname.length);
// add currently selected signature
temp += '\n-- \n' + signatures[1];
// store back the copy into the textarea
text.value = temp;
// focus the textarea
text.focus();
// place the caret between the text and the signature
setTimeout(
function(){
text.setSelectionRange(size,size);
}
,1);
}
function addsnippet(link) {
// get the current posting textarea
var text = link.parentNode.previousSibling.previousSibling;
// work on a copy to avoid text flickering
var temp = text.value;
// extract the snippet index from the class name
var i = +link.className.slice(snipclassname.length);
// add currently selected snippet
temp += snippets[1];
// store back the copy into the textarea
text.value = temp;
// place the caret at the end of text
text.focus();
}
/*
listener functions
*/
// dispatch the click events to add snippet & sig and to switch
toggles
document.addEventListener(
'click',
function(event) {
var classname = event.target.className
var sigfilter = new RegExp(sigclassname, '');
var snipfilter = new RegExp(snipclassname, '');
if(sigfilter.test(classname)) {
addsignature(event.target);
} else if (snipfilter.test(classname)) {
addsnippet(event.target);
} else if (classname == toggledateclassname) {
strip_date_from_quote = !strip_date_from_quote;
update();
} else if (classname == togglesnipsclassname) {
show_snippets = !show_snippets;
update();
} else if (classname == togglesigsclassname) {
show_signatures = !show_signatures;
update();
}
},
true
);
// when focusing the textarea of a posting form,
// call format() to strip date and signature from quoted post
// and to move the utils bar beneath the current textarea
document.addEventListener(
'focus',
function(event) {
if (event.target.id
&& event.target.name == 'body') {
format(event.target);
}
},
true
);
/*
code to display the panel in the
bottom-right corner of the viewport
*/
var utilspanel = document.createElement('DIV');
utilspanel.title = 'GoogleGroups Posting Utilities, '
+ 'http://fscode.altervista.org'
function updatepanel() {
if(show_panel) {
utilspanel.innerHTML = '';
var s = utilspanel.style;
s.fontSize = '80%'
s.position = 'fixed';
s.border = '1px solid #000';
s.padding = '0.4em 1em 0.4em 1em';
s.bottom = '0';
s.right = '0';
s.background = '#C3D9FF';
utilspanel.innerHTML = '<span style="font-weight: bolder">'
+ 'GGP Utils Settings</span>';
var curlink = pseudolink.cloneNode(true);
curlink.style.fontWeight = 'bolder';
curlink.title = 'Click to toggle ON/OFF';
var datetoggler = curlink.cloneNode(true);
var snipstoggler = curlink.cloneNode(true);
var sigstoggler = curlink.cloneNode(true);
datetoggler.className = toggledateclassname;
snipstoggler.className = togglesnipsclassname;
sigstoggler.className = togglesigsclassname;
function formattoggle(toggle, active) {
toggle.style.color = active ? '#00F' : '#F00';
toggle.innerHTML = active ? 'ON' : 'OFF';
}
formattoggle(datetoggler, strip_date_from_quote);
formattoggle(snipstoggler, show_snippets);
formattoggle(sigstoggler, show_signatures);
utilspanel.innerHTML += '<br />Strip Date: ';
utilspanel.appendChild(datetoggler);
utilspanel.innerHTML += '<br />Show Snips: ';
utilspanel.appendChild(snipstoggler);
utilspanel.innerHTML += '<br />Show Sigs: ';
utilspanel.appendChild(sigstoggler);
}
} // end of function updatepanel()
// call it for the first time
updatepanel();
// append it once
document.body.appendChild(utilspanel);
// end of script