// ==UserScript== // @name Marforio Add-Ons // @description Add permalinks, SmartQuotes, extended editor to Marforio. // @namespace http://oblomov.myopenid.com // @include http://www.marforio.org/forum/* // @include http://www.marforio.org/forumstud/* // @author Giuseppe "Oblomov" Bilotta // @version 5.1.1 // ==/UserScript== if (typeof(unsafeWindow) == 'undefined') unsafeWindow = window ; if (unsafeWindow.location.pathname.match(/^\/forumstud\//)) { unsafeWindow.location = unsafeWindow.location.toString().replace(/forumstud/,'forum'); } unsafeWindow.load_ids = function(url) { var e = unsafeWindow.document.createElement('script'); e.type = 'text/javascript'; e.src = url; unsafeWindow.document.getElementsByTagName('head')[0].appendChild(e); }; unsafeWindow.load_ids('http://oblomov.dnsalias.org/marforio/marforio.ids'); unsafeWindow.load_ids('http://oblomov.dnsalias.org/marforio/chat/status/status.js'); unsafeWindow.editorToolbarString = '
'+unsafeWindow.chatStatus.users + ' utenti in chat, inclusi';
if ((num = unsafeWindow.chatStatus.ops) != '0') {
s += join +' '+num+' op';
join = ','
}
if ((num = unsafeWindow.chatStatus.hops) != '0') {
s += join+' '+num+' half-op';
join = ','
}
if ((num = unsafeWindow.chatStatus.voices) != '0')
s += join+' '+num+' voice';
info.innerHTML = s;
if (unsafeWindow.chatStatus.lastchange)
info.innerHTML += ' Ultimo evento: '+unsafeWindow.chatStatus.lastchange+'';
} else {
info.innerHTML = '(stato della chat non reperibile)';
}
div.addEventListener('mouseover',unsafeWindow.createChatLines,false);
div.addEventListener('mousemove',unsafeWindow.moveChatLines,true);
div.addEventListener('mouseout',unsafeWindow.hideChatLines,false);
div.appendChild(info);
return div;
}
unsafeWindow.createChatLines = function(e) {
var frame = unsafeWindow.document.getElementById('chatlines');
if (frame) {
frame.src = 'http://oblomov.dnsalias.org/marforio/chat/last/';
unsafeWindow.moveChatLines(e);
return true;
}
var style = unsafeWindow.document.createElement('style');
style.setAttribute('type', 'text/css');
style.innerHTML = "#chatlines {" +
"position: absolute;" +
"font-size:10px;" +
"overflow:hidden;" +
"border:none;" +
"z-index:5;"+
"}";
unsafeWindow.document.getElementsByTagName('head')[0].appendChild(style);
frame = unsafeWindow.document.createElement('iframe');
frame.setAttribute('id', 'chatlines');
var div = document.getElementById('chatdiv');
var cs = getComputedStyle(div, null);
/*
frame.style.top = cs.top;
// Firefox bug: cs.right has the wrong value!
frame.style.left = (div.offsetLeft+div.offsetWidth)+'px';
*/
// Firefox bug: cs.bottom has the wrong value!
frame.style.top = (div.offsetTop+div.offsetHeight)+'px';
frame.style.left = '1.5%';
frame.width = '100%';
frame.height = '100%';
unsafeWindow.document.body.appendChild(frame);
frame.src = 'http://oblomov.dnsalias.org/marforio/chat/last/';
return frame;
}
unsafeWindow.moveChatLines = function(e) {
var frame = unsafeWindow.document.getElementById('chatlines');
if (!frame) {
frame = unsafeWindow.createChatLines();
if (!frame)
return true;
}
/*
// Stupid Firefox needs the 'px' appended
var tp = e.pageY + 10;
var lf = e.pageX + 10;
frame.style.top = tp + 'px';
frame.style.left = lf + 'px';
frame.width = (document.body.clientWidth - lf - 10) + 'px';
frame.height = (document.body.clientHeight - tp - 10) + 'px';
*/
frame.style.visibility = 'visible';
}
unsafeWindow.hideChatLines = function() {
var frame = unsafeWindow.document.getElementById('chatlines');
if (!frame)
return true;
frame.style.visibility = 'hidden';
}
unsafeWindow.TocDivAdd = function(anch, txt) {
var div = unsafeWindow.document.getElementById('topictoc');
var i = div.innerHTML;
var text = txt || anch;
i += "" + text + " (#"+anch+")
";
div.innerHTML = i;
}
unsafeWindow.hasTocDiv = false;
unsafeWindow.writeAddOnInfo = function(data) {
var div = unsafeWindow.document.getElementById('marforioaddons');
if (div) {
var p = unsafeWindow.document.createElement('p');
if (data.description) {
p.setAttribute('title', data.description);
}
div.appendChild(p);
if (data.url) {
var a = unsafeWindow.document.createElement('a');
a.href = data.url;
a.target = 'addonscriptwindow';
p.appendChild(a);
p = a;
}
var span;
var attributes = ['name', 'author', 'version'];
for (var i in attributes) {
var attr = attributes[i];
if (data[attr]) {
span = unsafeWindow.document.createElement('span');
span.setAttribute('class',attr);
span.innerHTML = data[attr];
p.appendChild(span);
}
}
}
} ;
unsafeWindow.writeAddOnInfo({
'name' : 'Marforio Add-Ons',
'url' : 'http://oblomov.dnsalias.org/marforio/marforio.user.js',
'description' : 'Add permalinks, SmartQuotes, extended editor to Marforio.',
'author' : 'Oblomov',
'version' : '5.1.1'
});
unsafeWindow.rawInsertMessageText = function(txt) {
var txtarea = unsafeWindow.document.PostTopic.Message ;
var startPos = txtarea.selectionStart;
var endPos = txtarea.selectionEnd;
var scrollTop = txtarea.scrollTop;
txtarea.value = txtarea.value.substring(0, startPos) + txt +
txtarea.value.substring(endPos, txtarea.value.length);
txtarea.focus();
txtarea.selectionStart = startPos;
txtarea.selectionEnd = startPos+txt.length;
txtarea.scrollTop = scrollTop;
unsafeWindow.getPreview();
}
// Heavily inspired by @ http://developer.mozilla.org/en/docs/skins/common/wikibits.js
unsafeWindow.insertMessageText = function(before, after, dflt, ask) {
var txtarea = unsafeWindow.document.PostTopic.Message ;
if (txtarea.selectionStart || txtarea.selectionStart == '0') {
var startPos = txtarea.selectionStart;
var endPos = txtarea.selectionEnd;
var scrollTop = txtarea.scrollTop;
// If we are at a boundary of a paired tag and no
// text is selected, just move the cursor after/before
// the tag. Otherwise, move the selected text across.
if (after) {
// Since we manipulate start/end position to handle
// whitespace even though we don't know if we're
// doing the boundary thing, use a copy instead of the original one
var sPos = startPos;
var ePos = endPos;
var txt = txtarea.value.substring(sPos,ePos) || "" ;
if (txt.indexOf(before) == 0) {
txt = txt.substring(before.length,txt.length);
sPos += before.length;
}
if (txt.indexOf(after) == 0) {
txt = txt.substring(after.length,txt.length);
sPos += after.length;
}
if ((txt.lastIndexOf(before) >= 0) && (txt.lastIndexOf(before) == txt.length-before.length)) {
txt = txt.substring(0,txt.length - before.length);
ePos -= before.length;
}
if ((txt.lastIndexOf(after) >= 0) && (txt.lastIndexOf(after) == txt.length-after.length)) {
txt = txt.substring(0,txt.length - after.length);
ePos -= after.length;
}
var pre = txtarea.value.substring(0, sPos) || "" ;
var prews = pre.match(/\s+$/) || "";
var aft = txtarea.value.substring(ePos,txtarea.value.length) || "";
var aftws = aft.match(/^\s+/) || "";
var manipulated = true;
var handlews = true;
// if we're doing cleanups, we only check if we're already where we want to be
if (unsafeWindow.doingCleanUp) {
if (aft.indexOf(after) == 0 && pre.lastIndexOf(before) >=0 && pre.length - pre.lastIndexOf(before) == before.length) {
unsafeWindow.rawInsertMessageText(txt);
} else {
manipulated = false;
}
} else if (aft.indexOf(before) == aftws.length) {
txtarea.selectionEnd = ePos+before.length+aftws.length;
if ((pre.lastIndexOf(after) >= 0) && (pre.length - pre.lastIndexOf(after) == after.length+prews.length)) {
txtarea.selectionStart = sPos-after.length-prews.length;
unsafeWindow.rawInsertMessageText(prews+txt+aftws);
txtarea.selectionStart = txtarea.selectionStart + prews.length;
txtarea.selectionEnd = txtarea.selectionEnd - aftws.length;
} else {
if (txt.match(/^\s*$/) && prews.length==0) {
txtarea.selectionStart = txtarea.selectionEnd;
handlews = false;
} else {
unsafeWindow.rawInsertMessageText(before+txt+aftws);
txtarea.selectionStart = txtarea.selectionStart + before.length;
txtarea.selectionEnd = txtarea.selectionEnd - aftws.length;
if (txt.match(/^\s*$/))
handlews = false;
}
}
} else if (aft.indexOf(after) == aftws.length) {
txtarea.selectionEnd = ePos+after.length+aftws.length;
if ((pre.lastIndexOf(before) >= 0) && (pre.length - pre.lastIndexOf(before) == before.length + prews.length)) {
txtarea.selectionStart = sPos-before.length-prews.length;
unsafeWindow.rawInsertMessageText(prews+txt+aftws);
txtarea.selectionStart = txtarea.selectionStart + prews.length;
txtarea.selectionEnd = txtarea.selectionEnd - aftws.length;
} else {
txtarea.selectionStart = sPos-prews.length;
unsafeWindow.rawInsertMessageText(after+prews+txt+aftws);
txtarea.selectionStart = txtarea.selectionStart + after.length+prews.length;
txtarea.selectionEnd = txtarea.selectionEnd - aftws.length;
}
} else if ((pre.lastIndexOf(before) >= 0) && (pre.length - pre.lastIndexOf(before) == before.length+prews.length)) {
txtarea.selectionStart = sPos-before.length-prews.length;
txtarea.selectionEnd = ePos+aftws.length;
unsafeWindow.rawInsertMessageText(prews+txt+aftws+before);
txtarea.selectionStart = txtarea.selectionStart + prews.length;
txtarea.selectionEnd = txtarea.selectionStart + txt.length;
} else if ((pre.lastIndexOf(after) >= 0) && (pre.length - pre.lastIndexOf(after) == after.length+prews.length)) {
txtarea.selectionStart = sPos-after.length-prews.length;
unsafeWindow.rawInsertMessageText(prews+txt+after);
txtarea.selectionStart = txtarea.selectionStart + prews.length;
txtarea.selectionEnd = txtarea.selectionStart + txt.length;
} else {
manipulated = false;
}
if (manipulated) {
if (txt.match(/^\s*$/) && handlews) {
txtarea.selectionEnd = txtarea.selectionEnd + aftws.length;
txtarea.selectionStart = txtarea.selectionEnd;
}
unsafeWindow.getPreview();
return;
}
}
var myText = txtarea.value.substring(startPos, endPos);
// exclude the last space char, if present
if (myText && myText.charAt(myText.length-1)==" ") {
endPos -= 1;
myText = myText.substring(0,myText.length-1);
}
if (!myText) {
myText = dflt || "" ;
}
if (ask)
myText = prompt(ask, myText) ;
var subst;
if (!after) {
subst = before;
} else {
subst = before+myText+after;
}
txtarea.value = txtarea.value.substring(0, startPos) + subst +
txtarea.value.substring(endPos, txtarea.value.length);
txtarea.focus();
//set new selection
if (after) {
txtarea.selectionStart = startPos+before.length;
txtarea.selectionEnd = startPos+before.length+myText.length;
} else {
txtarea.selectionStart = startPos+before.length;
txtarea.selectionEnd = startPos+before.length;
}
txtarea.scrollTop = scrollTop;
unsafeWindow.getPreview();
} else {
alert('Uh ... something went wrong, contact the Marforio script author');
}
} ;
// Useful regular expressions to detect links and such
unsafeWindow.smartRx = {
'hyperlink' : [
/^(https?:\/\/\S+)(\s+(.*)?\s*)?$/,
/^(\s*(.+?):?\s+)(https?:\/\/\S+)\s*$/,
/^user:(.+)$/i
],
'email' : [
/^((mailto:)?\S+@\S+)(\s+(.*)?\s*)?$/,
/^(\s*(.+?):?\s+)((mailto:)?\S+@\S+)\s*$/
],
'embedTall' : [
/^\S+\.(pdf|doc|rtf|sxw|odt)/i
],
'embedShort' : [
/^\S+\.(xls|sxc|ods|ppt|sxi|odp)/i
],
'flash' : [
/^http:\/\/(\w+\.)?youtube\.\w+\/watch\?v=(\S+?)((&|#).*)?$/i,
/^http:\/\/(\w+\.)?youtube\.\w+\/v\/\S+$/i,
/^http:\/\/\S+\.(swf|avi|mpe?g|mp4|flv)/i
],
'image' : [
/^\S+\.(png|jpe?g|gif|bmp|jp2|ico|svg)$/i
],
'quotable' : [
/^.*\/post\.asp\?method=(?:Topic|Reply)Quote&(.*)&FORUM_ID=\d+$/i
]
} ;
// Redefine the insertsmilie function, except for the popup lists of smilies
if (!unsafeWindow.location.href.match(/\/faccine\d+\.asp/i))
unsafeWindow.insertsmilie = unsafeWindow.insertMessageText ;
unsafeWindow.tagWrap = function(tag, dflt, help, ask, askdflt) {
if (unsafeWindow.helpstat) {
alert(help);
} else if (unsafeWindow.basic) {
unsafeWindow.insertMessageText('['+tag+']','[/'+tag+']', dflt)
} else {
unsafeWindow.insertMessageText('['+tag+']','[/'+tag+']', askdflt, ask)
}
} ;
unsafeWindow.bold = function() {
unsafeWindow.tagWrap('b', '',
"Il Tag Bold cambia il testo in grassetto.\n\nUSO: [b]Questo testo è in grassetto[/b]",
"Il testo sarà formattato in GRASSETTO.", "testo")
} ;
unsafeWindow.italicize = function() {
unsafeWindow.tagWrap('i', '',
"Il Tag Italicize cambia il testo in corsivo.\n\nUSO: [i]Questo testo è in corsivo[/i]",
"Il testo sarà formattato in corsivo.", "testo")
} ;
unsafeWindow.underline = function() {
unsafeWindow.tagWrap('u', '',
"Il Tag Underline cambia il testo in sottolineato.\n\nUSO: [u]Questo testo è sottolineato[/u]",
"Il testo sarà formattato in sottolineato.", "testo")
}
unsafeWindow.strike = function() {
unsafeWindow.tagWrap('s', '',
"Il Tag Strike-Through cambia il testo in barrato.\n\nUSO: [s]Questo testo è barrato[/s]",
"Il testo sarà formattato in barrato.", "testo")
}
unsafeWindow.spoiler = function() {
unsafeWindow.tagWrap('spoiler', '',
"Il Tag Spoiler cambia il testo in nascosto.\n\nUSO: [spoiler]Questo testo è nascosto[/spoiler]",
"Il testo sarà formattato in nascosto.", "testo")
}
unsafeWindow.left = function() {
unsafeWindow.tagWrap('left', '',
"Il Tag Left allinea il testo a Sinistra.\n\nUSO: [left]Questo testo è allineato a Sinistra[/left]",
"Il testo sarà allineato a Sinistra.", "testo")
}
unsafeWindow.center = function() {
unsafeWindow.tagWrap('center', '',
"Il Tag Center allinea il testo al Centro.\n\nUSO: [center]Questo testo è allineato al Centro[/center]",
"Il testo sarà allineato al Centro.", "testo")
}
unsafeWindow.right = function() {
unsafeWindow.tagWrap('right', '',
"Il Tag Right allinea il testo a Destra.\n\nUSO: [right]Questo testo è allineato a Destra[/right]",
"Il testo sarà allineato a Destra.", "testo")
}
unsafeWindow.hr = function() {
unsafeWindow.insertMessageText('[hr]');
}
unsafeWindow.getUserProfile = function(nick) {
var req = new XMLHttpRequest() ;
var url ;
if (req) {
window.status = 'Retrieving user ID' ;
req.open('GET','http://www.marforio.org/forum/members.asp?mode=search&M_NAME='+escape(nick)+'&initial=1&method=nameasc&submit1=Cerca', false);
req.overrideMimeType('text/html; charset=windows-1252');
req.onload = function() {
var profile = /\s+ 0)
postbody += '&';
postbody += v + '=' + encodeURIComponent(block[v])
}
var req = new XMLHttpRequest() ;
var url ;
if (req) {
window.status = 'Retrieving user ID' ;
req.open('POST','http://www.marforio.org/forum/pop_preview.asp', true);
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
req.setRequestHeader("Content-length", postbody.length);
req.setRequestHeader("Connection", "close");
req.onload = function() {
if (req.status == 200) {
var span = '';
var i = req.responseText.indexOf(span);
var j = req.responseText.indexOf("\r");
var snip = req.responseText.substring(i+span.length, j);
var doc = unsafeWindow.document;
doc.getElementById('previewdiv').innerHTML = snip;
var area = doc.PostTopic.Message;
area.style.height = area.scrollHeight;
unsafeWindow.runningPreview = false;
if (unsafeWindow.changedSincePreview)
unsafeWindow.getPreview();
}
}
req.send(postbody);
unsafeWindow.runningPreview = true;
unsafeWindow.changedSincePreview = false;
} else {
return ;
}
}
unsafeWindow.cleanUpPaste = function() {
var txtarea = unsafeWindow.document.PostTopic.Message ;
var sPos = txtarea.selectionStart;
var ePos = txtarea.selectionEnd;
var txt = txtarea.value.substring(sPos,ePos) ;
var clean = false;
// we want to look at the keys in a given order
var keys = ['flash', 'embedTall', 'embedShort', 'image', 'hyperlink', 'email'];
unsafeWindow.doingCleanUp = true;
for (var k in keys) {
var key = keys[k];
var ar = unsafeWindow.smartRx[key];
for (var i in ar) {
var rx = ar[i];
if (txt.match(rx)) {
unsafeWindow[key].call() ;
clean = true;
break;
}
}
if (clean)
break;
}
unsafeWindow.doingCleanUp = false;
txtarea.selectionStart = txtarea.selectionEnd;
} ;
unsafeWindow.addHeadLink = function(url, rel, rev) {
var link = unsafeWindow.document.createElement('link');
link.setAttribute('href', url);
link.setAttribute('rel', rel);
rev && link.setAttribute('rev', rev);
unsafeWindow.document.getElementsByTagName('head')[0].appendChild(link);
} ;
unsafeWindow.imagifyLink = function(url, el, sep, maxw, maxh) {
var jsimg = new unsafeWindow.Image();
jsimg.onload = function() {
var img = unsafeWindow.document.createElement('img');
img.src = url;
img.setAttribute('align', 'absmiddle');
img.style.border = 'none' ;
var imgratio = img.width/img.height;
if (maxh)
img.width=maxh*imgratio;
else
img.width=maxw;
el.parentNode.insertBefore(img, el);
el.parentNode.insertBefore(sep, el);
}
jsimg.src=url;
}
unsafeWindow.brandProfileLink = function(a, roles, role_img, role_lnk) {
var newlinks = 0;
if (!a || !roles || (roles.length==0))
return newlinks;
var itsarole = (a.textContent || 'Questo utente') + ' è un ' ;
switch (roles.length) {
case 1:
itsarole += roles[0]; break;
case 2:
itsarole += roles.join(' e un '); break;
default:
itsarole += roles.slice(0,roles.length-1).join(', un ') + ' e un ' + roles[roles.length-1];
} ;
for (var i = 0; i < roles.length; i++) {
role = roles[i];
if (!role_img[role])
continue;
a.setAttribute('title', itsarole);
var img = unsafeWindow.document.createElement('img');
img.src = role_img[role];
img.setAttribute('align', 'absmiddle');
img.style.border = 'none' ;
img.style.paddingTop = '2px' ;
var link = document.createElement("a") ;
link.href = role_lnk[role] || "#";
link.setAttribute('alt', itsarole);
link.setAttribute('title', itsarole);
link.appendChild(img);
var el = a.firstChild ;
var avatar = false;
if (el.tagName == 'IMG' && !(el.width==24 && el.height==24))
avatar = true;
var imgratio = img.width/img.height;
if (!avatar) {
if (imgratio > 1)
img.width=24;
else
img.width=24*imgratio;
a.parentNode.insertBefore(link, a);
newlinks++ ;
a.parentNode.insertBefore(document.createTextNode("\u00A0"), a);
} else {
img.width=96;
a.parentNode.insertBefore(link, a.nextSibling) ;
a.parentNode.insertBefore(document.createElement('br'), link) ;
}
}
return newlinks;
} ;
unsafeWindow.preloadImage = function(url) {
unsafeWindow.status = 'Preloading '+url ;
var jsimg = new Image();
jsimg.src = url;
};
unsafeWindow.preloadRoleImages = function() {
unsafeWindow.status = 'Preloading images' ;
var role, url;
for (role in unsafeWindow.role_img) {
url = unsafeWindow.role_img[role];
unsafeWindow.preloadImage(url);
}
unsafeWindow.status = 'Finished preloading' ;
};
unsafeWindow.preloadRoleImages();
unsafeWindow.linkifyQuote = function(text, id) {
var type = 0;
var headmatch = /\[i\]Messaggio inserito da (.+?)\[\/i\]/m.exec(text);
if (!headmatch) {
type = 1;
headmatch = /\[red\](.+?)\s+ha scritto:\s*\[\/red\]/m.exec(text);
}
if (!headmatch) {
type = 2;
headmatch = /Messaggio di \[red\](.+?)\[\/red\]/m.exec(text);
}
if (!headmatch)
return text;
var nick = headmatch[1];
var nicklink = unsafeWindow.getUserProfile(nick);
if (nicklink)
nick = '[url="'+nicklink+'"]'+nick+'[/url]';
var newmsg = '';
switch (type) {
case 0:
newmsg = '[i][url="?whichpage=-1&'+id+'"]Messaggio[/url] inserito da '+nick+'[/i]';
break;
case 1:
newmsg = '[red]'+nick+' ha [url="?whichpage=-1&'+id+'"]scritto:[/url][/red]';
break;
case 2:
newmsg = '[url="?whichpage=-1&'+id+'"]Messaggio[/url] di [red]'+nick+'[/red]';
break;
}
return text.replace(headmatch[0], newmsg);
};
unsafeWindow.smartQuote = function(src, id) {
unsafeWindow.status = 'Retrieving original text' ;
var req = new XMLHttpRequest() ;
if (req) {
req.onload = function() {
if (req.status == 200) {
var area = /