/** * DokuWiki Ajax-Chat plugin * AJAX functions * * @license GPL2 (http://www.gnu.org/licenses/gpl.html) * @author Pavel Vitis */ AJAXCHAT_SHORT_INTERVAL = 5; AJAXCHAT_MIDDLE_INTERVAL = 10; AJAXCHAT_LONG_INTERVAL = 30; AJAXCHAT_MAXIMUM_INTERVAL = 5*60; AJAXCHAT_CHECKTIMEOUT = 3*1000; AJAXCHAT_SENDTIMEOUT = 30*1000; AJAXCHAT_NOMESSAGES = "– no messages –"; AJAXCHAT_MESSAGESCLEARED = "– messages cleared –"; var ajax_chat = null; function Mouse_monitor_class(window) { this.lastmousex = 0; this.lastmousey = 0; this.mousemovehooked = false; this.mousemoved = false; this.window = window; this.document = window.document; var self = this; self.onMouseMove = function() { }; self.mouseEvent = function(e) { if (false === self.mousemovehooked) { return; } var posx = 0; var posy = 0; if (!e) { var e = self.window.event; } if (!e) { var e = self.document.event; } if (!e) { return; } if (e.pageX || e.pageY) { posx = e.pageX; posy = e.pageY; } else { if (e.clientX || e.clientY) { posx = e.clientX + self.document.body.scrollLeft; posy = e.clientY + self.document.body.scrollTop; } } if (self.lastmousex != 0 && self.lastmousey != 0) { if ((posx == 0 && posy == 0) || posx != self.lastmousex || posy != self.lastmousey) { self.mousemoved = true; if (self.onMouseMove) { try { self.onMouseMove(); } catch (e) {}; } self.onMouseMove = null; self.unhookMouseEvent(); // setTimeout(function(){self.unhookMouseEvent();}, 100); } } self.lastmousex = posx; self.lastmousey = posy; }; self.hookMouseEvent = function() { if (true === self.mousemovehooked) { return; } // Init to current mouse position self.mousemoved = false; // self.refreshMousePos(); self.lastmousex = 0; self.lastmousey = 0; addEvent(self.document, 'mousemove', self.mouseEvent); self.mousemovehooked = true; }; self.unhookMouseEvent = function() { if (false === self.mousemovehooked) { return; } removeEvent(self.document, 'mousemove', self.mouseEvent); self.mousemovehooked = false; }; self.sleep = function(delay) { var start = (new Date()).getTime(); while ((new Date()).getTime() - start < delay) { }; }; } //prepare class function Ajax_chat_class(objectName, outId, pageId, lastRefresh, window) { this.objectName = objectName; this.check_sack = new sack(DOKU_BASE + 'lib/plugins/chat/ajax.php'); this.check_sack.AjaxFailedAlert = ''; this.check_sack.encodeURIString = false; this.send_sack = new sack(DOKU_BASE + 'lib/plugins/chat/ajax.php'); this.send_sack.AjaxFailedAlert = ''; this.send_sack.encodeURIString = false; this.timer = null; this.lastChatAreaUpdate = new Date().getTime(); this.chat_timer = null; this.outObj = document.getElementById(outId); this.pageId = pageId; this.lastRefresh = lastRefresh; this.lastSend = lastRefresh; this.refresh = AJAXCHAT_SHORT_INTERVAL; this.clearing = false; this.sending = false; this.sendQueue = new Array(); var self = this; this.mouseMonitor = new Mouse_monitor_class(window); this.onMouseMove = function(func) { self.mouseMonitor.onMouseMove = function() { func(); // self.updateInfo('requestTimerInfo', 'mouseMoved'+(new Date()).getTime()); // self.mouseMonitor.unhookMouseEvent(); }; self.mouseMonitor.hookMouseEvent(); }; this.check_sack.onLoading = function() { self.updateInfo('requestTimerInfo', 'Timer initialized'); self.check_sack.requestTimer = setTimeout( function() { // alert('timeout'); self.check_sack.requestTimer = null; try { if (self.check_sack.xmlhttp.abort) { self.check_sack.xmlhttp.abort(); } } catch (e) { } self.updateInfo('requestTimerInfo', 'Timeout, aborted connection'); self.check_sack.onError(); }, AJAXCHAT_CHECKTIMEOUT); }; this.check_sack.onError = function() { if (self.check_sack.requestTimer !== null) { clearTimeout(self.check_sack.requestTimer); self.check_sack.requestTimer = null; self.updateInfo('requestTimerInfo', 'Error, timer aborted'); } else { self.updateInfo('requestTimerInfo', 'Error, no timer'); } self.updateInfo('ajaxActive','error, waiting'); self.check_sack.onCompletion(); }; this.check_sack.onLoaded = function() { if (self.check_sack.requestTimer !== null) { clearTimeout(self.check_sack.requestTimer); self.check_sack.requestTimer = null; self.updateInfo('requestTimerInfo', 'OK, timer cleared'); } }; this.send_sack.onLoading = function() { self.updateInfo('requestTimerInfo', 'Timer initialized'); self.send_sack.requestTimer = setTimeout( function() { self.send_sack.requestTimer = null; try { if (self.send_sack.xmlhttp.abort) { self.send_sack.xmlhttp.abort(); } } catch (e) { } self.updateInfo('requestTimerInfo', 'Timeout, aborted connection'); self.send_sack.onError(); }, AJAXCHAT_SENDTIMEOUT ); }; this.send_sack.onError = function() { if (self.send_sack.requestTimer !== null) { clearTimeout(self.send_sack.requestTimer); self.send_sack.requestTimer = null; self.updateInfo('requestTimerInfo', 'Error, timer aborted'); } else { self.updateInfo('requestTimerInfo', 'Error, no timer'); } self.updateInfo('ajaxActive','error, waiting'); self.send_sack.onCompletion(); }; this.send_sack.onLoaded = function() { if (self.send_sack.requestTimer !== null) { clearTimeout(self.send_sack.requestTimer); self.send_sack.requestTimer = null; self.updateInfo('requestTimerInfo', 'OK, timer cleared'); } // if (200 != self.send_sack.responseStatus[0]*1) { // self.send_sack.onCompletion(); // } }; this.getUpdateTimeFromResponse = function(resp) { var time = resp.substring(0, resp.indexOf('\n')).replace(/(.*.*)/, '$2'); // alert(time*1); if (time == null || time == '') { time = 0; } return time*1; }; self.updateInfo('ajaxRefreshInterval', this.refresh+'sec'); } Ajax_chat_class.prototype.updateInfo = function(infoTag, infoValue) { var infoDiv = document.getElementById('chat-info-pad'); if (infoDiv) { if (infoDiv.elements[infoTag]) { infoDiv.elements[infoTag].value = infoValue; } } }; Ajax_chat_class.prototype.chatClear = function(user) { var self = this; self.clearing = true; // self.chatCheckAbort(); self.send_sack.oldOnError = self.send_sack.onError; self.send_sack.onError = function() { self.send_sack.oldOnError(); self.clearing = false; self.send_sack.onError = self.send_sack.oldOnError; // alert('onerror'); }; this.send_sack.onCompletion = function() { var data = self.send_sack.response; if (data !== '') { self.updateInfo('ajaxLastStatus','Messages cleared'); self.outObj.innerHTML = AJAXCHAT_MESSAGESCLEARED; self.outObj.style.display = 'block'; updated = self.getUpdateTimeFromResponse(data); self.lastRefresh = updated;//((new Date().getTime())/1000); self.clearing = false; self.send_sack.onError = self.send_sack.oldOnError; } }; self.outObj.innerHTML = AJAXCHAT_MESSAGESCLEARED; if (this.send_sack.encVar) { this.send_sack.encVar('call', 'clear'); this.send_sack.encVar('pageId', self.pageId); this.send_sack.encVar('time', self.lastRefresh); this.send_sack.encVar('user', user); this.send_sack.runAJAX(); } else { this.send_sack.runAJAX( 'call=clear'+ '&pageId='+encodeURIComponent(this.pageId)+ '&time='+this.lastRefresh+ '&user='+encodeURIComponent(user)); } }; Ajax_chat_class.prototype.chatSend = function(user,message) { var self = this; if (true == self.clearing) { return; } self.sending = true; // self.chatCheckAbort(); // sleep(1000); self.send_sack.oldOnError = self.send_sack.onError; self.send_sack.onError = function() { if (self.send_sack.onError !== self.send_sack.oldOnError) { self.send_sack.oldOnError(); } self.sending = false; self.send_sack.onError = self.send_sack.oldOnError; // alert('onerror'); }; this.send_sack.onCompletion = function() { var data = self.send_sack.response; if (200 == self.send_sack.responseStatus[0]*1) { // alert(data); var sentDiv = document.getElementById('chatListSentMessage'); if (sentDiv) { sentDiv.innerHTML = ''; sentDiv.style.display = 'none'; } if (data !== '') { var updated = self.getUpdateTimeFromResponse(data); var actualData = data.replace(/[^\n]+\n[ ]*/,''); if (actualData.length == 0) { // alert(data); } self.outObj.innerHTML = (actualData.length > 0 ? actualData+(self.lastRefresh > 0 ? self.outObj.innerHTML : '') : AJAXCHAT_NOMESSAGES); self.outObj.style.display = 'block'; self.lastRefresh = updated;//((new Date().getTime())/1000); self.lastSend = updated; // remove first message from queue self.sendQueue.shift(); } } else { // alert(data); // alert(self.send_sack.responseStatus[0]*1); } /* if (self.sendQueue !== null && self.sendQueue.length > 0) { var msgrec = self.sendQueue[0]; self.send_sack.runAJAX( 'call=send'+ '&pageId='+encodeURIComponent(self.pageId)+ '&time='+self.lastRefresh+ '&user='+encodeURIComponent(msgrec[0])+ '&msg='+encodeURIComponent(msgrec[1])); } else */ { self.sending = false; self.send_sack.onError = self.send_sack.oldOnError; } }; this.requestTimeout = AJAXCHAT_SENDTIMEOUT; // add message to send queue var msgrec = new Array(); msgrec[0] = user; msgrec[1] = message; // self.sendQueue.push(msgrec); if (this.send_sack.encVar) { this.send_sack.encVar('call', 'send'); this.send_sack.encVar('pageId', self.pageId); this.send_sack.encVar('time', self.lastRefresh); this.send_sack.encVar('user', user); this.send_sack.encVar('msg', message); this.send_sack.runAJAX(); } else { this.send_sack.runAJAX( 'call=send'+ '&pageId='+encodeURIComponent(self.pageId)+ '&time='+self.lastRefresh+ '&user='+encodeURIComponent(user)+ '&msg='+encodeURIComponent(message)); } }; Ajax_chat_class.prototype.chatCheck = function() { try { // alert(this); var self = this; if (true == self.sending) { return; } if (self.chat_timer !== null) { clearTimeout(self.chat_timer); self.chat_timer = null; } this.check_sack.onCompletion = function() { if (true == self.clearing || true == self.sending) { return; } var data = self.check_sack.response; if (200 != self.check_sack.responseStatus[0]*1) { self.updateInfo('ajaxActive','waiting'); self.updateInfo('ajaxLastStatus','Error '+self.check_sack.responseStatus[0]+', waiting'); } else { self.updateInfo('ajaxActive','waiting'); if(data === '') { self.updateInfo('ajaxLastStatus','No change'); } else { var updated = self.getUpdateTimeFromResponse(data); if ((updated == 0 || updated > self.lastRefresh) && false == self.clearing && false == self.sending) { var actualData = data.replace(/[^\n]+\n[ ]*/,''); if (actualData !== self.lastMessage) { self.outObj.innerHTML = (actualData.length > 0 ? actualData+(self.lastRefresh > 0 ? self.outObj.innerHTML : '') : AJAXCHAT_NOMESSAGES); self.outObj.style.display = 'block'; // alert(updated); // alert(((new Date().getTime())/1000)); self.updateInfo('ajaxLastStatus','New messages fetched'); if (actualData.length > 0) { chatNotifySound(); } else { } self.lastMessage = actualData; } self.lastRefresh = updated;//((new Date().getTime())/1000); } } } }; this.updateInfo('ajaxActive','checking...'); // alert(self.lastRefresh); if (self.check_sack.encVar) { self.check_sack.encVar('call', 'checkAndGet'); self.check_sack.encVar('pageId', self.pageId); self.check_sack.encVar('time', self.lastRefresh); self.check_sack.runAJAX(); } else { self.check_sack.runAJAX( 'call=checkAndGet&pageId='+encodeURIComponent(self.pageId)+'&time='+self.lastRefresh); } var now = new Date().getTime(); if ((now - self.lastChatAreaUpdate)/1000 >= 5*60) { self.refresh = AJAXCHAT_MAXIMUM_INTERVAL; self.updateInfo('ajaxRefreshInterval',self.refresh+'sec'); } else { if ((now - self.lastChatAreaUpdate)/1000 >= 60) { self.refresh = AJAXCHAT_LONG_INTERVAL; self.updateInfo('ajaxRefreshInterval',self.refresh+'sec'); self.onMouseMove(function(){ if (self.refresh > AJAXCHAT_MIDDLE_INTERVAL) { // alert(self.refresh); self.refresh = AJAXCHAT_MIDDLE_INTERVAL; self.lastChatAreaUpdate = new Date().getTime()-(30*1000); self.updateInfo('ajaxRefreshInterval',self.refresh+'sec'); // self.chatCheck(); self.chat_timer = setTimeout(self.objectName+".chatCheck()", 100); } }); } else { if ((now - self.lastChatAreaUpdate)/1000 >= 30) { self.refresh = AJAXCHAT_MIDDLE_INTERVAL; self.updateInfo('ajaxRefreshInterval',self.refresh+'sec'); } } } // Add fuzziness to timer to avoid high loads on server at the same time from multiple clients var timeoutFuzzy = (Math.round(Math.random()) > 0 ? 1 : -1) * Math.round(Math.random()*((self.refresh*1000)/10)); self.updateInfo('ajaxNextCheck', 'Next check: ' + self.refresh + 's ' + (timeoutFuzzy > 0 ? "+"+timeoutFuzzy+"ms" : timeoutFuzzy < 0 ? timeoutFuzzy+"ms" : "")); } catch (e) { } // Set new timer self.chat_timer = setTimeout(self.objectName+".chatCheck()", (self.refresh*1000) + timeoutFuzzy); }; Ajax_chat_class.prototype.chatCheckAbort = function() { var self = this; if (null != self.check_sack.requestTimer) { clearTimeout(self.check_sack.requestTimer); self.check_sack.requestTimer = null; this.updateInfo('ajaxActive','aborted check...'); } if (self.check_sack.xmlhttp && self.check_sack.xmlhttp.abort) { try { // self.check_sack.resetData(); self.check_sack.xmlhttp.abort(); // alert('aborted'); } catch (e) { } } }; function chatSetCookie(name, value, expire) { try { // New code DokuCookie.setValue(name, value, expire); } catch (e) { // Old code var expiref = new Date(); fixDate(expiref); expiref.setTime(expiref.getTime() + expire); setCookie(name, value, expiref); } } function chatGetCookie(name) { var value; try { // New code value = DokuCookie.getValue(name); } catch (e) { // Old code value = getCookie(name); } return value; } function new_ajax_chat(outId, pageId, lastRefresh) { ajax_chat = new Ajax_chat_class("ajax_chat", outId, pageId, lastRefresh, window); } function chatRefresh(event) { if (ajax_chat === null) { return; } var list = document.getElementById('chat-last-message'); if (list) { if (list.className.indexOf(' chat-line-last') != -1) { list.className = list.className.replace(/ chat-line-last/gi, ''); } } ajax_chat.chatCheck(); } function chatClick(event) { if (ajax_chat === null) { return; } if (ajax_chat.refresh > AJAXCHAT_SHORT_INTERVAL) { ajax_chat.refresh = AJAXCHAT_SHORT_INTERVAL; ajax_chat.lastChatAreaUpdate = (new Date()).getTime(); ajax_chat.updateInfo('ajaxRefreshInterval',ajax_chat.refresh+'sec'); } chatRefresh(); } function chatAreaUpdated(event) { if (ajax_chat === null) { return; } var now = new Date().getTime(); if ((now - ajax_chat.lastChatAreaUpdate)/1000 < 30) { if (ajax_chat.refresh > AJAXCHAT_SHORT_INTERVAL) { ajax_chat.refresh = AJAXCHAT_SHORT_INTERVAL; ajax_chat.updateInfo('ajaxRefreshInterval',ajax_chat.refresh+'sec'); chatRefresh(); } else { } } else { chatRefresh(); } ajax_chat.lastChatAreaUpdate = now; } function chatSendMessage(user,msg) { // do not allow to send more than 1 message per second if (ajax_chat.lastSend > 0) { var now = (new Date()).getTime(); if (now - (ajax_chat.lastSend*1000) < 1000) { return false; // ajax_chat.sleep(now - (ajax_chat.lastSend*1000)); } } // format date-time var time = new Date(); var timeF; if ((''+time.getHours()).length > 1) { timeF = time.getHours()+":"; } else { timeF = "0"+time.getHours()+":"; } if ((''+time.getMinutes()).length > 1) { timeF += time.getMinutes()+":"; } else { timeF += "0"+time.getMinutes()+":"; } if ((''+time.getSeconds()).length > 1) { timeF += time.getSeconds()+""; } else { timeF += "0"+time.getSeconds()+""; } var list = document.getElementById('chatListSentMessage'); // format message list.innerHTML = "" + user + " (" + timeF+ "):
" + msg + "
\n"; // show sent-message div list.style.display = 'block'; list.style.height = ''; // do real sending ajax_chat.chatSend(user,msg); return true; } function focusChatPrompt() { var form = document.getElementById('chatForm'); if (form) { if (form.chatMessage) { form.chatMessage.focus(); } } } function chatClearMessages(user) { var list = document.getElementById('chatList'); list.innerHTML = " "; ajax_chat.chatClear(user); focusChatPrompt(); } function chatEventKeyUp() { var input = document.getElementById('chatForm').chatMessage; } function chatEventClear() { var form = document.getElementById('chatForm'); chatClearMessages(form.user.value); return false; } function chatEventSubmit() { try { focusChatPrompt(); var form = document.getElementById('chatForm'); if (form.chatMessage.value === '') { return false; } if (chatSendMessage(form.user.value, form.chatMessage.value)) { form.chatMessage.value = ''; } } catch (e) { }; return false; } /* function chatEventMouseMove(e) { if (ajax_chat.refresh > AJAXCHAT_MIDDLE_INTERVAL) { ajax_chat.refresh = AJAXCHAT_MIDDLE_INTERVAL; ajax_chat.updateInfo('ajaxRefreshInterval',ajax_chat.refresh+'sec'); ajax_chat.lastChatAreaUpdate = new Date().getTime()-(30*1000); ajax_chat.chatCheck(); } } */ function saveChatUser() { var input = document.getElementById('chatForm').user; if (!input) { return; } if (null !== input.timer) { clearTimeout(input.timer); input.timer = null; } input.lastKey = null; chatSetCookie('chatName', input.value, 365*24*60*60*1000); } function chatEventUserChanged(e) { var input = document.getElementById('chatForm').user; if (!input) { return; } if (null !== input.timer) { clearTimeout(input.timer); input.timer = null; } var now = new Date(); if (!input.lastKey) { input.lastKey = now.getTime(); input.timer = setTimeout('saveChatUser()', 1000); } else { input.lastKey = now.getTime(); input.timer = setTimeout('saveChatUser()', 1000); } } function chatNotifySound() { var soundPlayer = document.getElementById('newmsg_sound'); if (soundPlayer) { try { soundPlayer.play(); } catch (e) {}; } } function chatSetVolume(vol,silent,cookie) { var soundPlayer = document.getElementById('newmsg_sound'); if (soundPlayer) { try { soundPlayer.setVolume(vol); if (!silent && (vol > 0)) { soundPlayer.play(); } var img = document.getElementById('chatVolumeIcon'); if (img) { img.src = DOKU_BASE+'lib/plugins/chat/volume'+vol+'.gif'; img.title = 'Set notify volume ('+(vol > 0 ? vol : 'muted')+')'; img.style.width = ''; img.style.paddingRight = '10px'; img.style.paddingTop = '2px'; } } catch (e) {}; if (cookie) { chatSetCookie('chatVolume', vol+'', 365*24*60*60*1000); } } } function chatToggleVolume() { var soundPlayer = document.getElementById('newmsg_sound'); if (soundPlayer) { try { var volume = soundPlayer.getVolume()+1; if (volume > 4) { volume = 0; } chatSetVolume(volume,false,true); } catch (e) {}; } } function chatInitialize() { var form = document.getElementById('chatForm'); var list = document.getElementById('chatList'); if (form) { if (form.user && 'text' == form.user.type) { var cname = chatGetCookie('chatName'); if (null !== cname) { form.user.value = cname; } else { saveChatUser(); } } if (form.chatMessage) { addEvent(form, 'submit', chatEventSubmit); addEvent(form.user, 'keyup', chatEventUserChanged); addEvent(form.chatMessage, 'keyup', chatAreaUpdated); setTimeout('focusChatPrompt()', 1000); } if (form.clearButton) { addEvent(form.clearButton, 'click', chatEventClear); } new_ajax_chat('chatList', form.pageId.value, 0); ajax_chat.chatCheck(); } if (list) { addEvent(list, 'mouseup', chatClick); } } (function(){ //preload images (new Image()).src = DOKU_BASE+'lib/plugins/chat/volume0.gif'; (new Image()).src = DOKU_BASE+'lib/plugins/chat/volume1.gif'; (new Image()).src = DOKU_BASE+'lib/plugins/chat/volume2.gif'; (new Image()).src = DOKU_BASE+'lib/plugins/chat/volume3.gif'; (new Image()).src = DOKU_BASE+'lib/plugins/chat/volume4.gif'; addEvent(window, 'load', chatInitialize); })();