Add Syntax Highlighting (this will take a few seconds, probably freezing your browser while it works)
// ==UserScript==
// @name dAway System
// @namespace http://djordje.ungar.on.neobee.net/js/damn_away/
// @description Lets you define your own custom away message for every channel
// @include http://chat.deviantart.com*
// @creator http://artbit.deviantart.com
// ==/UserScript==
// Creating the script node and adding to the head of the page, thus avoiding the use of unsafeWindow
// Thanks userscripts.org
var daway_script = document.createElement('script')
daway_script.appendChild(document.createTextNode((<r><![CDATA[
// start script source
var SCRIPT_NAME = "dAway System";
var SCRIPT_VERSION = "0.4";
function initDawaySystem() {
//Catch and rewire(tm) dAmn functions
var DJO_HELP_WIN_STR = '<div style="background:#88938D; color:#DAE4DA; padding: 4px; margin: 4px; font-size:1.1em;"><a href="http://www.deviantart.com/deviation/54702221/" style="color:inherit !important;"><b>'+SCRIPT_NAME+'</b> v'+SCRIPT_VERSION+'</a> by <a title="Visit ArtBIT\'s page" href="http://artbit.deviantart.com" style="color:inherit !important;">ArtBIT</a></span></div>'
+'<div style="padding:10px;">'
+'<br /><u><b>Here is the list of commands: </b></u><br />'
+'<table style="padding:5px;"><thead></thead>'
+'<tr><td><b>/awayhelp</b></td><td> - This screen</td></tr>'
+'<tr><td><b>/awayall</b></td><td> - Sets the away message for all channels the user is in (similar to dAx\'/setaway),</td></tr>'
+'<tr><td><b>/awayhere</b></td><td> - Sets the away message for the current channel (ONLY).</td></tr>'
+'<tr><td><b>/awaysummary</b></td><td> - Displays a detailed view of all the channels in which you\'re away.</td></tr>'
+'<tr><td><b>/backall</b></td><td> - Clears the away message for all the channels the user is in (similar to dAx\' /setback),</td></tr>'
+'<tr><td><b>/backhere</b></td><td> - Clears the away message for the current channel (ONLY).</td></tr>'
+'</tbody></table>'
+'<br /><u><b>Here is the list of macros that can be used anywhere in your away messages: </b></u><br />'
+'<table style="padding:5px;"><thead></thead>'
+'<tr><td><b>%ME%</b></td><td> - your username. (similar to /me)</td></tr>'
+'<tr><td><b>%TO%</b></td><td> - the username of a person who triggered the away message.</td></tr>'
+'<tr><td><b>%CHANNEL%</b></td><td> - the name of the channel in which the trigger occured (i.e. #flashers).</td></tr>'
+'<tr><td><b>%NO_MSGS%</b></td><td> - the number of messages (the number of times someone tried to contact you) since you started being away.</td></tr>'
+'<tr><td><b>%AWAY_TIME%</b></td><td> - this is the time when you started being away (i.e. 17:08)</td></tr>'
+'<tr><td><b>%AWAY_DURATION%</b></td><td> - this is the duration since you started being away (i.e. 45mins)</td></tr>'
+'<tr><td><b>%RANDOMXX-YY%</b></td><td> - where XX and YY are numerical values, generates a random number betwen XX and YY.</td></tr>'
+'</tbody></table>'
+'<br /><u><b>Example usage:</b></u><br /><br />'
+'<div style="color:#555555;">'
+' <span class="djo_colblk">/awayall</span> I\'m sorry <span class="djo_colblk">%TO%</span>, but <span class="djo_colblk">%ME%</span> is not in the <span class="djo_colblk">%CHANNEL%</span>. Reason: Busy.<br />'
+' <i>result: I\'m sorry <span class="djo_colblk">Someone123</span>, but <span class="djo_colblk">ArtBIT</span> is not in the <span class="djo_colblk">#Flashers</span>. Reason: Busy.</i><br /><br />'
+' <span class="djo_colblk">/awayall</span> <span class="djo_colblk">%TO%</span>: I\'m sorry, but I\'m away atm. I\'ve been away since <span class="djo_colblk">%AWAY_TIME%</span>h and I\'ll be back in <span class="djo_colblk">%RANDOM2-5%</span>h.<br />'
+' <i>result: <span class="djo_colblk">Someone123</span>: I\'m sorry, but I\'m away atm. I\'ve been away since <span class="djo_colblk">17:53</span>h and I\'ll be back in <span class="djo_colblk">3</span>h.</i><br />'
+'</div>'
+'<br /><u><b>Notes: </b></u><br />'
+'<table style="padding:5px;"><thead></thead>'
+'<tr><td>If you use the /awayall and /awayhere commands with no parameters, the default message will be used ("Sorry %TO%, but %ME% is away right now.")</td></tr>'
+'<tr><td>If you use /awayall <b>+</b>some_message or /awayhere <b>+</b>some_message, then some_message will be applied to the end of default message as a reason ("Sorry %TO%, but %ME% is away right now. Reason: <b>some_message</b>")</td></tr>'
+'</tbody></table>'
+'</div>';
var djo_trigger_time_out = 10000;
djo_showInfoWin = function(title,content) {
//alert(content);
var page = '<html>\n<head>\n\t<title>' + title + '</title>\n'
+'<style type="text/css">\n'
+'.djo_colblk {color:#000000;}\n'
+'.djo_winheader {background:#88938D; color:#DAE4DA; padding: 4px; margin: 4px; font-size:1.1em;}\n'
+'.djo_rowlight {background-color:#C3C9C3;}\n'
+'.djo_rownorm {background-color:#CDD2CD;}\n'
+'.djo_timestamp {color:#88938d; fontWeight:bold; fontSize:0.8em; fontStyle:normal;margin:0 5px;}\n'
+'a {color: inherit !important}\n'
+'input.button { border:1px solid; padding:0 .1em; cursor:pointer; border-radius:.4em; -moz-border-radius:.4em }\n'
+'input.button:hover{ background:#dddddd; } \n'
+'.djo_minimized { display:none; visibility:hidden;} \n'
+'.djo_maximized { display:block ; visibility:inherit; }\n'
+'</style>\n'
+'<script type="text/javascript">\n'
+'toggleElementVisibility = function(elem_id) { \n'
+'var e = document.getElementById(elem_id); \n'
+'if(!e) return 0; \n'
+'var b=e.parentNode.firstChild; \n'
+'if(e.className=="djo_minimized") {\n'
+' e.className="djo_maximized" \n'
+' b.value="hide" \n'
+' } else {\n'
+' e.className="djo_minimized" \n'
+' b.value="show" \n'
+' }'
+'}'
+'</script>\n'
+'</head><body style="background-color:#D2D8D2; width:100%; margin:0px auto;">'
+content
+'</body></html>';
var newWindow=window.open('.', '_blank');
newWindow.document.open();
newWindow.document.write(page);
newWindow.document.close();
//newWindow.callerWindow = this.unsafeWindow;
newWindow.focus();
}
//A tweak of the dAmnChanMainChat.prototype.onUserInfo( user, body ) function something like siebenzehn's (http://siebenzehn.deviantart.com/) makeResultBox from dAx
showInfoBox = function(channel, body ) {
var o = dAmn_MakeDiv( "userinfo-outer" )
var i = dAmn_AddDiv( o, "userinfo-inner" );
var u = dAmn_AddDiv( i, "userinfo alt0" );
var t = this;
dAmnChat_AddImgBox( u, "damncr-close", 'close', 'close', function(el){ dAmn_DeleteSelf(el); t.scroll_once = true; dAmn_InvalidateLayout(); }, o );
var r = dAmn_AddDiv( u, 'bodyarea alt1-left-border' );
var b = dAmn_AddDiv( r, 'b read pcusers' );
dAmn_AddDiv(b,'read',body);
channel.addDiv( o, null, 0 );
}
djo_randRange =function(min,max) {
return (Math.floor(Math.random()*(max-min+1))+min);
}
djo_parseSpecialWords = function(channel,from)
{
var msg = String(channel.away_msg);
//alert(msg);
msg = msg.replace(/%TO%/g,from);
msg = msg.replace(/%ME%/g,dAmn_Client_Username);
msg = msg.replace(/%AWAY_TIME%/g,channel.away_time);
msg = msg.replace(/%CHANNEL%/g,dAmn_formatNS(channel.cr.ns));
msg = msg.replace(/%NO_MSGS%/g,channel.no_missed_msgs);
var now = new Date().getTime();
var duration = now - channel.away_time_ms;
msg = msg.replace(/%AWAY_DURATION%/g,djo_milisecondsToString(duration));
var re = new RegExp("%RANDOM(\\d+)-(\\d+)%","g");
var randomSet = msg.match(re);
if(randomSet!=null)
{
for(var i=0; i<randomSet.length;i++)
{
var re = new RegExp("%RANDOM(\\d+)-(\\d+)%","g");
var range = re.exec(randomSet[i]);
var min = Number(range[1]);
var max = Number(range[2]);
var randValue = String(djo_randRange(min,max));
if(null!=range) msg = msg.replace(/%RANDOM\d+-\d+%/,randValue);
}
}
return msg;
}
djo_sSuffix = function(num)
{
return ( (num % 10 != 1) || (num % 100 == 11) ) ? "s" : "";
}
djo_milisecondsToString = function(mil)
{
var period = Math.floor(mil/1000);
var strPeriod = "";
if(period>60)
{
period = Math.floor(period/60);
if(period>60)
{
period = Math.floor(period/60);
strPeriod = "over "+ period + " hour" + djo_sSuffix(period);
}
else
{
strPeriod = "over "+ period + " minute" + djo_sSuffix(period);
}
}
else
{
strPeriod = period + " second" + djo_sSuffix(period);
}
return strPeriod;
}
djo_customAwayAll = function(msg)
{
dAmn_objForEach(dAmnChats,function(chan,name) {
djo_customAwayHere(chan.channels.main,msg);
});
}
djo_customAwayHere = function(channel, msg)
{
var noAwayChans=new Array();
noAwayChans["chat:IdleRPG"]=1;
noAwayChans["chat:help"]=1;
noAwayChans["chat:devart"]=1;
noAwayChans["chat:Trivia"]=1;
noAwayChans["debug:conn"]=1;
noAwayChans["chat:photographers"]=1;
if(msg=="" || msg==undefined) msg ="Sorry %TO%, but %ME% is away right now.";
if(msg.charAt(0)=='+') msg = "Sorry %TO%, but %ME% is away right now. Reason: " + msg.substring(1);
if(!noAwayChans[channel.cr.ns])
{
channel.is_away = true;
var d = new Date();
var h = d.getHours();
var m = d.getMinutes();
var s = d.getSeconds();
if(h<10) h = '0' + h;
if(m<10) m = '0' + m;
if(s<10) s = '0' + s;
channel.away_time_ms = d.getTime();
channel.away_time = h + ':' + m + ':' + s;
channel.away_msg = msg;
channel.missed_messages = new Array();
channel.silent_away = false;
channel.no_missed_msgs = 0;
var parsed_msg = djo_parseSpecialWords(channel,'all');
channel.cr.Send( 'action', 'main', ' is now away: '+parsed_msg);
}
}
djo_deleteAllMessages = function(channel) {
alert("Deleting all messages for channel: " +channel);
channel.missed_messages = new Array();
channel.no_missed_msgs = 0;
}
djo_timestamp = function() {
var d = new Date();
var h = d.getHours();
var m = d.getMinutes();
var s = d.getSeconds();
if(h<10) h = '0' + h;
if(m<10) m = '0' + m;
if(s<10) s = '0' + s;
return (h + ':' + m + ':' + s);
}
djo_onAway = function(channel, from, body)
{
//alert(from);
if (channel.silent_away) return;
window.clearTimeout(channel.away_timeout);
channel.silent_away=true;
channel.away_timeout=window.setTimeout( (function() { channel.silent_away=false;}),djo_trigger_time_out);
if(from==dAmn_Client_Username) return;
var noAwayChans=new Array();
noAwayChans["chat:IdleRPG"]=1;
noAwayChans["chat:help"]=1;
noAwayChans["chat:devart"]=1;
noAwayChans["chat:Trivia"]=1;
noAwayChans["debug:conn"]=1;
noAwayChans["chat:photographers"]=1;
if(!noAwayChans[channel.cr.ns])
{
var msg = djo_parseSpecialWords(channel,from);
channel.no_missed_msgs++;
var missed_msg = '<span class="djo_timestamp">'+djo_timestamp()+' <b><<a title="Visit '+from+'\'s page" href="http://'+from+'.deviantart.com">'+from+'</a>></b></span> ' + dAmnChanChat.prototype.FormatMsg(body,'alpha');
channel.missed_messages.push(missed_msg);
channel.cr.Send( 'msg','main', msg);
}
}
djo_customBackHere = function(channel)
{
if(channel.is_away)
{
channel.is_away = false;
channel.cr.Send( 'action','main', ' is now back.');
}
}
djo_userLink = function(da_username)
{
return '<a title="Visit '+da_username+'\'s page" target="_blank" href="http://'+da_username+'.deviantart.com/">'+da_username+'</a>';
}
djo_customBackAll = function()
{
for(var e in dAmnChats)
//dAmn_objForEach(dAmnChats[e].channels,function(chan,name) {
dAmn_objForEach(dAmnChats,function(chan,name) {
djo_customBackHere(chan.channels.main);
});
}
djo_getChannelInfo = function(channel)
{
var m = channel.missed_messages.length;
if(channel.away_msg=='' && !m) return '';
var away_msg = (channel.away_msg=='') ? " is not currently away in this channel " : channel.away_msg;
var msg ="<table><tbody>";
msg+="<tr><td> - away since: </td><td> "+channel.away_time+"</td></tr>";
msg+="<tr><td> - away message: </td><td> "+away_msg+"</td></tr>";
msg+="<tr><td valign='top'> - "+channel.no_missed_msgs+" personal msg"+djo_sSuffix(channel.no_missed_msgs)+"</td>";
var i = 0;
if(m) {
var channelID = dAmn_formatNS(channel.cr.ns);
var b = "<input value='show' type='button' class='button' onclick='toggleElementVisibility(\""+channelID+"\")'/>";
//var btndel = "<input value='delete all' type='button' class='button' onclick='javascript: alert(opener.document.djo_deleteAllMessages)'/>";
//msg+="<td>"+b+btndel+"<br />";
msg+="<td>"+b+"<br />";
msg+="<div id='"+channelID+"' class='djo_minimized'>";
while(i<m) {
msg+=channel.missed_messages[i]+"<br />";
i++;
}
msg+="</div></td></tr>";
} else {
msg+="<td></td></tr>";
}
msg+="</tbody></table>"
return msg;
}
djo_getSummary = function(channel)
{
//{var info ='<span style="font-size:1.1em;">'+userlink(dAmn_Client_Username,≣)+'</span> - is away in the following rooms:<br /><br />'
var info ='<div class="djo_winheader"><span style="font-size:1.1em;"><b>['+djo_userLink(dAmn_Client_Username)+']</b></span> - is away in the following rooms:</div>'
+'<table width="100%"><tbody><tr><td align="center">'
+'<table style="padding:0px;" width="98%"><thead style="font-size:1.1em;font-weight:bold;"><td style="width:100px;">Channel:</td><td>Info:</td><td></td></thead><tbody>';
var infoList = '';
var row_id = 0;
dAmn_objForEach(dAmnChats,
function(chan,name)
{
var chan_info = djo_getChannelInfo(chan.channels.main);
if(chan_info!='')
{
var imgShoutbox = '';
var rowClass = 'djo_rowlight';
if(row_id++%2==0) rowClass = 'djo_rownorm';
if(chan.channels.main.no_missed_msgs)
imgShoutbox = '<br /><br /><div align="center"><img src="http://e.deviantart.com/emoticons/s/shoutbox.gif" alt="Message" /></div>';
infoList+='<tr class="'+rowClass+'"><td valign="top"><b> '+name.match(/^chat:(.*)$/)[1]+imgShoutbox+'</b></td><td>'+chan_info+'</td></tr>'
}
}
);
if(infoList=='') infoList ='<tr><td valign="top">none</td><td>none</td></tr>'
info += infoList;
info += '<tr><td colspan="3"><div style="font-size:0.8em; text-align:right; padding-right: 5px;color:#000000 !important;""><a href="http://www.deviantart.com/deviation/54702221/" title="Go to deviation page" ><b>'+SCRIPT_NAME+'</b> v'+SCRIPT_VERSION+'</a> by <a title="Visit ArtBIT\'s page" href="http://artbit.deviantart.com" >ArtBIT</a></div></td></tr>';
info +='</tbody></table>';
info +='</td></tr></tbody></table>'
return info;
}
/***************************
dAmn - REWIRED
****************************/
dAmnChanChat.prototype.Init_customAway_rewire = dAmnChanChat.prototype.Init;
dAmnChanChat.prototype.Init = function( cr, name, parent_el )
{
this.Init_customAway_rewire( cr, name, parent_el );
this.is_away = false;
this.away_time_ms = this.away_time = -1;
this.away_msg = "";
this.missed_messages = new Array();
this.no_missed_msgs = 0;
this.away_timeout = -1;
this.silent_away = false;
var cie=this.input;
cie.cmds['awayhere']=[0,''];
cie.cmds['backhere']=[0,''];
cie.cmds['awayall' ]=[0,''];
cie.cmds['backall' ]=[0,''];
cie.cmds['awaysummary']=[0,''];
cie.cmds['awayhelp']=[0,''];
}
dAmnChanChat.prototype.onMsg_customAway_rewire = dAmnChanChat.prototype.onMsg;
dAmnChanChat.prototype.onMsg = function( from, body )
{
//alert(from);
if(-1 != body.search( RegExp("([^A-Za-z0-9]+|^)"+dAmn_Client_Username,"im")))
//and it has awaystats word in the message, and the user is away
if(0 == body.search( RegExp("(awaysummary)","im")) && this.is_away )
{
djo_showAwaySummary(this);
}
else
{
if(this.is_away)
{
djo_onAway(this, from, body);
}
}
this.onMsg_customAway_rewire( from, body);
}
dAmnChatInput_onKey_customAway_rewire=dAmnChatInput_onKey;
dAmnChatInput_onKey = function (e,kc,force)
{
var el = this.chatinput_el;
if( kc == 13 && ( force || !this.multiline || e.shiftKey || e.ctrlKey ) )
{
var input = el.value;
var rex = /^\/(\S*)\s*(.*)$/i.exec(input);
if(rex)
{
var cmd = rex[1];
var param = rex.slice(2).join(' ');
var didsmth = false;
var show_help = false;
if(cmd)
{
switch(cmd)
{
case 'awayhere':
didsmth = true;
show_help = (param=='?');
if(!show_help) djo_customAwayHere(this.channel,param);
break;
case 'backhere':
didsmth = true;
show_help = (param=='?');
if(!show_help) djo_customBackHere(this.channel);
break;
case 'awayall':
didsmth = true;
show_help = (param=='?');
if(!show_help) djo_customAwayAll(param);
break;
case 'backall':
didsmth = true;
show_help = (param=='?');
if(!show_help) djo_customBackAll();
break;
case 'awaysummary':
didsmth = true;
show_help = (param=='?');
//alert(djo_getSummary(this.channel));
if(!show_help) djo_showInfoWin("dAmn awayMessages by ArtBIT - summary for "+dAmn_Client_Username,djo_getSummary(this.channel));
break;
case 'awayhelp':
didsmth = true;
show_help = (param=='?');
djo_showInfoWin("dAmn awayMessages by ArtBIT - HELP",DJO_HELP_WIN_STR);
//showInfoBox(this.channel,DJO_HELP_WIN_STR);
break;
} //end case
if(didsmth)
{
//if(show_help) showInfoBox(this.channel,'Type <b>/awayhelp</b> for more info.<br />');
if (el.value)
{
//add to history array
if (this.history_pos != -1 && this.history[this.history_pos] == el.value)
{ // posting from history.. move to the end
var before = this.history.slice(0,this.history_pos);
var after = this.history.slice(this.history_pos+1);
this.history = before.concat(after).concat( this.history[this.history_pos] );
}
else
{
// add to history -- limit to 300
this.history = this.history.concat( el.value );
if( this.history.length > 300 )
this.history = this.history.slice(1);
}
this.history_pos = -1;
el.value = '';
el.focus();
}
}
}
}
}
if(!didsmth) return this.onKey_customAway_rewire(e,kc,force)?true:false;
else return false;
}
dAmnChatInput.prototype.onKey = dAmnChatInput_onKey;
dAmnChatInput.prototype.onKey_customAway_rewire = dAmnChatInput_onKey_customAway_rewire;
GM_log("dAway System initialized.");
}
var tries = 0;
var maxTries = 100;
function tryInit() {
//alert(unsafeWindow.dAmnChanChat.prototype);
if (dAmnChanChat && dAmnChanChat.prototype) {
initDawaySystem();
} else {
if(tries++ < maxTries) setTimeout(tryInit,100);
}
}
tryInit();
// end script source
]]></r>).toString()))
document.getElementsByTagName('head')[0].appendChild(daway_script)