location other than /webim in javascript, fixed for safari

git-svn-id: https://webim.svn.sourceforge.net/svnroot/webim/trunk@34 c66351dc-e62f-0410-b875-e3a5c0b9693f
This commit is contained in:
Evgeny Gryaznov 2007-10-30 12:24:14 +00:00
parent bcb41ec0ff
commit 8bdbd14358
9 changed files with 1177 additions and 5 deletions

View File

@ -0,0 +1,30 @@
var myAgent = "";
var myVer = 0;
var myRealAgent = "";
function detectAgent() {
var AGENTS = ["opera","msie","safari","firefox","netscape","mozilla"];
var agent = navigator.userAgent.toLowerCase();
for (var i = 0; i < AGENTS.length; i++) {
var agentStr = AGENTS[i];
if (agent.indexOf(agentStr) != -1) {
myAgent = agentStr;
if (!window.RegExp)
break;
var versionExpr = new RegExp(agentStr + "[ \/]?([0-9]+(\.[0-9]+)?)");
if (versionExpr.exec(agent) != null) {
myVer = parseFloat(RegExp.$1);
}
break;
}
}
myRealAgent = myAgent;
if( navigator.product == "Gecko")
myAgent = "moz";
}
detectAgent();
function getEl(name) {
return document.getElementById(name);
}

View File

@ -0,0 +1,526 @@
/*
* Web Messenger common script
* http://sourceforge.net/projects/webim
*
* Based on Prototype JavaScript framework, version 1.3.1
* http://prototype.conio.net/ (c) 2005 Sam Stephenson <sam@conio.net>
*/
//- getEl, myAgent, myRealAgent
//- localized
//- onComplete, obj, params, $apply$
//- threadParams, servl, frequency, user, threadid, token
//- updaterOptions, url, company, agentservl, noclients, wroot
var Class = {
create: function() {
return function() {
this./**/initialize./**/apply(this, arguments);
};
},
inherit: function(child,parent,body) {
Object./**/extend(Object.extend(child.prototype, parent.prototype), body );
}
};
Object.extend = function(destination, source) {
for (property in source) {
destination[property] = source[property];
}
return destination;
};
Object.prototype.extend = function(_object) {
return Object.extend.apply(this, [this, _object]);
};
Function.prototype./**/bind = function(_object) {
var __method = this;
return function() {
return __method.apply(_object, arguments);
}
};
Function.prototype./**/bindAsEventListener = function(_object) {
var __method = this;
return function(event) {
__method.call(_object, event || window.event);
}
};
Number.prototype./**/toColorPart = function() {
var digits = this.toString(16);
if (this < 16) return '0' + digits;
return digits;
};
var Try = {
these: function() {
var returnValue;
for (var i = 0; i < arguments.length; i++) {
var lambda = arguments[i];
try {
returnValue = lambda();
break;
} catch (e) {}
}
return returnValue;
}
};
/*--------------------------------------------------------------------------*/
var PeriodicalExecuter = Class.create();
PeriodicalExecuter.prototype = {
initialize: function(callback, frequency) {
this.callback = callback;
this.frequency = frequency;
this./**/currentlyExecuting = false;
this./**/registerCallback();
},
registerCallback: function() {
setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
},
onTimerEvent: function() {
if (!this.currentlyExecuting) {
try {
this.currentlyExecuting = true;
this.callback();
} finally {
this.currentlyExecuting = false;
}
}
}
};
/*--------------------------------------------------------------------------*/
function findObj( id )
{
var x;
if( !( x = document[ id ] ) && document.all ) x = document.all[ id ];
if( !x && document.getElementById ) x = document.getElementById( id );
if( !x && !document.all && document.getElementsByName )
{
x = document.getElementsByName( id );
if( x.length == 0 ) return null;
if( x.length == 1 ) return x[ 0 ];
}
return x;
}
if (!Array.prototype./**/push) {
Array.prototype.push = function() {
var startLength = this.length;
for (var i = 0; i < arguments.length; i++)
this[startLength + i] = arguments[i];
return this.length;
};
}
function $() {
var elems = new Array();
for (var i = 0; i < arguments.length; i++) {
var elem = arguments[i];
if (typeof elem == 'string')
elem = findObj(elem);
if (arguments.length == 1)
return elem;
elems.push(elem);
}
return elems;
}
if (!Function.prototype.apply) {
Function.prototype.apply = function(obj, params) {
var parameterStrings = new Array();
if (!obj) obj = window;
if (!params) params = new Array();
for (var i = 0; i < params.length; i++)
parameterStrings[i] = 'params[' + i + ']';
obj.$apply$ = this;
var result = eval('obj.$apply$(' +
parameterStrings.join(', ') + ')');
obj.$apply$ = null;
return result;
};
}
var Ajax = {
getTransport: function() {
return Try.these(
function() {return new ActiveXObject('Msxml2.XMLHTTP')},
function() {return new ActiveXObject('Microsoft.XMLHTTP')},
function() {return new XMLHttpRequest()}
) || false;
},
getXml: function(_response) {
if( _response &&
_response.status >= 200 &&
_response.status < 300 ) {
var xmlDoc = _response.responseXML;
if( xmlDoc && xmlDoc.documentElement )
return xmlDoc.documentElement;
}
return null;
},
getError: function(_response) {
return _response.statusText || "connection error N" + _response.status;
},
emptyFunction: function() {}
};
Ajax./**/Base = function() {};
Ajax.Base.prototype = {
setOptions: function(_options) {
this._options = {
_method: 'post',
asynchronous: true,
parameters: ''
}.extend(_options || {});
},
responseIsSuccess: function() {
return this./**/transport.status == undefined
|| this.transport.status == 0
|| (this.transport.status >= 200 && this.transport.status < 300);
},
responseIsFailure: function() {
return !this.responseIsSuccess();
}
};
Ajax./**/Request = Class.create();
Ajax.Request./**/Events =
['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
Class.inherit( Ajax.Request, Ajax.Base, {
initialize: function(url, _options) {
this.transport = Ajax.getTransport();
this.setOptions(_options);
this.request(url);
},
request: function(url) {
var parameters = this._options.parameters || '';
if (parameters.length > 0) parameters += '&_=';
try {
if (this._options._method == 'get' && parameters.length > 0)
url += '?' + parameters;
this.transport.open(this._options._method, url, this._options.asynchronous);
if (this._options.asynchronous) {
this.transport.onreadystatechange = this.onStateChange.bind(this);
setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10);
}
this.setRequestHeaders();
var pbody = this._options.postBody ? this._options.postBody : parameters;
this.transport.send(this._options._method == 'post' ? pbody : null);
} catch (e) {
this.dispatchException(e);
}
},
setRequestHeaders: function() {
var requestHeaders =
['X-Requested-With', 'XMLHttpRequest'];
if (this._options._method == 'post') {
requestHeaders.push('Content-type',
'application/x-www-form-urlencoded');
/* Force "Connection: close" for Mozilla browsers to work around
* a bug where XMLHttpReqeuest sends an incorrect Content-length
* header. See Mozilla Bugzilla #246651.
*/
if (this.transport.overrideMimeType)
requestHeaders.push('Connection', 'close');
}
if (this._options.requestHeaders)
requestHeaders.push.apply(requestHeaders, this._options.requestHeaders);
for (var i = 0; i < requestHeaders.length; i += 2)
this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i+1]);
},
onStateChange: function() {
var readystate = this.transport.readyState;
if (readystate != 1)
this.respondToReadyState(this.transport.readyState);
},
header: function(name) {
try {
return this.transport.getResponseHeader(name);
} catch (e) {}
},
evalResponse: function() {
try {
return eval(this.transport.responseText);
} catch (e) {
this.dispatchException(e);
}
},
respondToReadyState: function(readystate) {
var event = Ajax.Request.Events[readystate];
if (event == 'Complete') {
try {
(this._options['on' + this.transport.status]
|| this._options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')]
|| Ajax.emptyFunction)(this.transport);
} catch (e) {
this.dispatchException(e);
}
if ((this.header('Content-type') || '').match("text\\/javascript"))
this.evalResponse();
}
try {
(this._options['on' + event] || Ajax.emptyFunction)(this.transport);
} catch (e) {
this.dispatchException(e);
}
/* Avoid memory leak in MSIE: clean up the oncomplete event handler */
if (event == 'Complete')
this.transport.onreadystatechange = Ajax.emptyFunction;
},
dispatchException: function(exception) {
(this._options.onException || Ajax.emptyFunction)(this, exception);
}
});
var EventHelper = {
register : function(obj, ev,func){
var oldev = obj[ev];
if (typeof oldev != 'function') {
obj[ev] = func;
} else {
obj[ev] = function() {
oldev();
func();
}
}
}
};
/*
Behaviour v1.1 by Ben Nolan, June 2005. Based largely on the work
of Simon Willison (see comments by Simon below).
http://ripcord.co.nz/behaviour/
*/
var Behaviour = {
list : new Array,
register : function(sheet){
Behaviour.list.push(sheet);
},
init : function(){
EventHelper.register(window, 'onload', function(){
Behaviour.apply();
});
},
apply : function(){
for (h=0;sheet=Behaviour.list[h];h++){
for (selector in sheet) {
list = document.getElementsBySelector(selector);
if (!list)
continue;
for( i = 0; element = list[i]; i++ ) {
sheet[selector]( element );
}
}
}
}
};
Behaviour.init();
function getAllChildren(e) {
// Returns all children of element. Workaround required for IE5/Windows. Ugh.
return e.all ? e.all : e.getElementsByTagName('*');
}
document.getElementsBySelector = function(selector) {
// Attempt to fail gracefully in lesser browsers
if (!document.getElementsByTagName) {
return new Array();
}
// Split selector in to tokens
var tokens = selector.split(' ');
var currentContext = new Array(document);
for (var i = 0; i < tokens.length; i++) {
token = tokens[i].replace(/^\s+/,'').replace(/\s+$/,'');;
if (token.indexOf('#') > -1) {
// Token is an ID selector
var bits = token.split('#');
var tag_name = bits[0];
var id = bits[1];
var element = document.getElementById(id);
if (element == null || tag_name && element.nodeName.toLowerCase() != tag_name ) {
// tag with that ID not found, return false
return new Array();
}
// Set currentContext to contain just this element
currentContext = new Array(element);
continue; // Skip to next token
}
if (token.indexOf('.') > -1) {
// Token contains a class selector
var bits = token.split('.');
var tag_name = bits[0];
var class_name = bits[1];
if (!tag_name) {
tag_name = '*';
}
// Get elements matching tag, filter them for class selector
var found = new Array;
var foundCount = 0;
for (var h = 0; h < currentContext.length; h++) {
var elements;
if (tag_name == '*') {
elements = getAllChildren(currentContext[h]);
} else {
elements = currentContext[h].getElementsByTagName(tag_name);
}
if( elements == null )
continue;
for (var j = 0; j < elements.length; j++) {
found[foundCount++] = elements[j];
}
}
currentContext = new Array;
var currentContextIndex = 0;
for (var k = 0; k < found.length; k++) {
if (found[k].className && found[k].className.match(new RegExp("\\b"+class_name+"\\b"))) {
currentContext[currentContextIndex++] = found[k];
}
}
continue; // Skip to next token
}
// [evgeny] code for attribute selection is removed...
if (!currentContext[0]){
return;
}
// If we get here, token is JUST an element (not a class or ID selector)
tag_name = token;
var found = new Array;
var foundCount = 0;
for (var h = 0; h < currentContext.length; h++) {
var elements = currentContext[h].getElementsByTagName(tag_name);
for (var j = 0; j < elements.length; j++) {
found[foundCount++] = elements[j];
}
}
currentContext = found;
}
return currentContext;
};
var NodeUtils = {
getNodeValue: function(parent,name) {
var nodes = parent.getElementsByTagName( name );
if( nodes.length == 0 )
return "";
nodes = nodes[0].childNodes;
var reslt = "";
for( i = 0; i < nodes.length; i++ )
reslt += nodes[i].nodeValue;
return reslt;
},
getNodeText: function(_node) {
var _nodes = _node.childNodes;
var _text = "";
for( i = 0; i < _nodes.length; i++ )
_text += _nodes[i].nodeValue;
return _text;
},
getAttrValue: function(parent,name) {
for( k=0; k < parent.attributes.length; k++ )
if( parent.attributes[k].nodeName == name )
return parent.attributes[k].nodeValue;
return null;
}
};
var CommonUtils = {
getRow: function(_id,_table) {
var _row = _table.rows[_id];
if( _row != null )
return _row;
if( _table.rows['head'] != null )
return null;
for( k=0; k < _table.rows.length; k++ ) {
if( _table.rows[k].id == _id )
return _table.rows[k];
}
return null;
},
getCell: function(_id,_row,_table) {
var _cell = _row.cells[_id];
if( _cell != null )
return _cell;
if( _table.rows['head'] != null )
return null;
for( k=0; k < _row.cells.length; k++ ) {
if( _row.cells[k].id == _id )
return _row.cells[k];
}
return null;
},
insertCell: function(_row,_id,_className,_align,_height, _inner) {
var cell = _row.insertCell(-1);
cell.id = _id;
if(_align)
cell.align = _align;
cell.className = _className;
if(_height)
cell.height = _height;
cell.innerHTML = _inner;
}
};

View File

@ -0,0 +1,330 @@
var FrameUtils = {
getDocument: function(frm) {
if (frm.contentDocument) {
return frm.contentDocument;
} else if (frm.contentWindow) {
return frm.contentWindow.document;
} else if (frm.document) {
return frm.document;
} else {
alert( myRealAgent + ": cannot find document in frame " + frm);
//for( var a in frm )
// alert( a );
return null;
}
},
initFrame: function(frm) {
var doc = this.getDocument(frm);
doc.open();
doc.write("<html><head>");
doc.write("<link rel=\"stylesheet\" type=\"text/css\" media=\"all\" href=\""+Chat.webimRoot+"/chat.css\" />");
doc.write("</head><body bgcolor='#FFFFFF' text='#000000' link='#C28400' vlink='#C28400' alink='#C28400' marginwidth='0' marginheight='0' leftmargin='0' rightmargin='0' topmargin='0' bottommargin='0'>");
doc.write("<table width='100%' cellspacing='0' cellpadding='0' border='0'><tr><td valign='top' class='message' id='content'></td></tr></table><a id='bottom'/>");
doc.write("</body></html>");
doc.close();
frm.onload = function() {
if( frm./**/myHtml ) {
FrameUtils.getDocument(frm).getElementById('content').innerHTML += frm.myHtml;
FrameUtils.scrollDown(frm);
}
};
},
insertIntoFrame: function(frm, htmlcontent) {
var vcontent = this.getDocument(frm).getElementById('content');
if( vcontent == null ) {
if( !frm.myHtml ) frm.myHtml = "";
frm.myHtml += htmlcontent;
} else {
vcontent.innerHTML += htmlcontent;
}
},
scrollDown: function(frm) {
var vbottom = this.getDocument(frm).getElementById('bottom');
if( myAgent == 'opera' ) {
frm.contentWindow.scrollTo(0,this.getDocument(frm).getElementById('content').clientHeight);
} else if( vbottom )
vbottom.scrollIntoView(false);
}
};
Ajax.ChatThreadUpdater = Class.create();
Class.inherit( Ajax.ChatThreadUpdater, Ajax.Base, {
initialize: function(_options) {
this.setOptions(_options);
this._options.onComplete = this.requestComplete.bind(this);
this.updater = {};
this.frequency = (this._options.frequency || 2);
FrameUtils.initFrame(this._options.container);
if( this._options.message ) {
this._options.message.onkeydown = this.handleKeyDown.bind(this);
this._options.message.onfocus = (function() { this.focused = true; }).bind(this);
this._options.message.onblur = (function() { this.focused = false; }).bind(this)
}
this.update();
},
updateOptions: function(act) {
this._options.parameters = 'act='+act+'&thread=' + (this._options.threadid || -1) +
'&token=' + (this._options.token || 0)+
'&lastid=' + (this._options.lastid || 0);
if( this._options.user )
this._options.parameters += "&user=true";
},
enableInput: function(val) {
if( this._options.message )
this._options.message.disabled = !val;
},
stopUpdate: function() {
this.enableInput(true);
if( this.updater._options )
this.updater._options.onComplete = undefined;
clearTimeout(this.timer);
},
update: function() {
this.updateOptions("refresh");
this.updater = new Ajax.Request(this._options.servl, this._options);
},
requestComplete: function(_response) {
this.enableInput(true);
var xmlRoot = Ajax.getXml(_response);
if( xmlRoot && xmlRoot.tagName == 'thread' ) {
this.updateContent( xmlRoot );
} else {
this.handleError(_response, xmlRoot, 'refresh messages failed');
}
this.timer = setTimeout(this.update.bind(this), this.frequency * 1000);
},
postMessage: function(msg) {
this.stopUpdate();
this.updateOptions("post");
var postOptions = {}.extend(this._options);
postOptions.parameters += "&message=" + encodeURIComponent(msg);
postOptions.onComplete = (function(presponse) {
this.requestComplete( presponse );
if( this._options.message ) {
this._options.message.value = '';
this._options.message.focus();
}
}).bind(this);
this.enableInput(false);
this.updater = new Ajax.Request(this._options.servl, postOptions);
},
changeName: function(newname) {
new Ajax.Request(this._options.servl, {parameters:'act=rename&thread=' + (this._options.threadid || -1) +
'&token=' + (this._options.token || 0) + '&name=' + encodeURIComponent(newname)});
},
onThreadClosed: function(_response) {
var xmlRoot = Ajax.getXml(_response);
if( xmlRoot && xmlRoot.tagName == 'closed' ) {
setTimeout('window.close()', 2000);
} else {
this.handleError(_response, xmlRoot, 'cannot close');
}
},
closeThread: function() {
var _params = 'act=close&thread=' + (this._options.threadid || -1) + '&token=' + (this._options.token || 0);
if( this._options.user )
_params += "&user=true";
new Ajax.Request(this._options.servl, {parameters:_params, onComplete: this.onThreadClosed.bind(this)});
},
processMessage: function(_target, message) {
var destHtml = NodeUtils.getNodeText(message);
FrameUtils.insertIntoFrame(_target, destHtml );
},
setupAvatar: function(avatar) {
var imageLink = NodeUtils.getNodeText(avatar);
if( this._options.avatar && this._options.user ) {
this._options.avatar.innerHTML = imageLink != ""
? "<img src=\""+Chat.webimRoot+"/images/free.gif\" width=\"7\" height=\"1\" border=\"0\" alt=\"\" /><img src=\""
+imageLink+ "\" border=\"0\" alt=\"\"/>"
: "";
}
},
updateContent: function(xmlRoot) {
var haveMessage = false;
var result_div = this._options.container;
var _lastid = NodeUtils.getAttrValue(xmlRoot, "lastid");
if( _lastid )
this._options.lastid = _lastid;
for( var i = 0; i < xmlRoot.childNodes.length; i++ ) {
var node = xmlRoot.childNodes[i];
haveMessage = true;
if( node.tagName == 'message' )
this.processMessage(result_div, node);
else if( node.tagName == 'avatar' )
this.setupAvatar(node);
// TODO thread events
}
if( haveMessage ) {
FrameUtils.scrollDown(this._options.container);
if( !this.focused )
window.focus();
}
},
handleKeyDown: function(k) {
if( k ){ ctrl=k.ctrlKey;k=k.which; } else { k=event.keyCode;ctrl=event.ctrlKey; }
if( this._options.message && ((k==13 && ctrl) || (k==10)) ) {
this.postMessage( this._options.message.value );
return false;
}
return true;
},
handleError: function(_response, xmlRoot, _action) {
if( xmlRoot && xmlRoot.tagName == 'error' ) {
this.setStatus(NodeUtils.getNodeValue(xmlRoot,"descr"));
} else {
this.setStatus(_action+', ' + Ajax.getError(_response));
}
},
setStatus: function(k) {
if( this.statusTimeout )
clearTimeout(this.statusTimeout);
window.status = k;
this.statusTimeout = setTimeout(this.clearStatus.bind(this), 4000);
},
clearStatus: function() {
window.status = "";
}
});
HSplitter = Class.create();
HSplitter.prototype = {
initialize: function(_options) {
this._options = _options;
this.captured = 0;
if( this._options.first && this._options.second && this._options.control ) {
this._options.control.onmousedown = this.onmousedownEvent.bind(this);
this._options.control.onmouseup = this.onmouseupEvent.bind(this);
this._options.control.onmousemove = this.onmouseMoveEvent.bind(this);
}
},
onmousedownEvent: function(e) {
var ev = e || event;
if( this._options.control.setCapture )
this._options.control.setCapture();
this.start_height = this._options.first.style.pixelHeight || this._options.first.clientHeight;
this.start_offset = ev.screenY;
this._options.maxfirst = this._options.first.style.pixelHeight + this._options.second.clientHeight - this._options.minsec;
this.captured = 1;
},
onmouseupEvent: function() {
if( this.captured ) {
if( this._options.control.releaseCapture )
this._options.control.releaseCapture();
this.captured = 0;
}
},
onmouseMoveEvent: function(e) {
var ev = e || event;
if( this.captured ) {
var new_height = this.start_height - (ev.screenY - this.start_offset);
if( new_height > this._options.maxfirst )
new_height = this._options.maxfirst;
else if( new_height < this._options.minfirst )
new_height = this._options.minfirst;
if( myAgent == 'moz' )
this._options.first.style.height=new_height+'px';
else
this._options.first.style.pixelHeight = new_height;
}
}
};
var Chat = {
threadUpdater : {},
hSplitter : {},
applyName: function() {
Chat.threadUpdater.changeName($('uname').value);
$('changename1').style.display='none';
$('changename2').style.display='inline';
},
showNameField: function() {
$('changename1').style.display='inline';
$('changename2').style.display='none';
}
};
Behaviour.register({
'#postmessage a' : function(el) {
el.onclick = function() {
var message = $('msgwnd');
if( message )
Chat.threadUpdater.postMessage(message.value);
};
},
'select#predefined' : function(el) {
el.onchange = function() {
var message = $('msgwnd');
message.value = this.options[this.selectedIndex].innerText || this.options[this.selectedIndex].innerHTML;
this.selectedIndex = 0;
message.focus();
};
},
'div#changename2 a' : function(el) {
el.onclick = function() {
Chat.showNameField();
return false;
};
},
'div#changename1 a' : function(el) {
el.onclick = function() {
Chat.applyName();
return false;
};
},
'div#changename1 input#uname' : function(el) {
el.onkeydown = function(e) {
var ev = e || event;
if( ev.keyCode == 13 ) {
Chat.applyName();
}
};
},
'a#refresh' : function(el) {
el.onclick = function() {
Chat.threadUpdater.stopUpdate();
Chat.threadUpdater.update();
};
},
'a.closethread' : function(el) {
el.onclick = function() {
Chat.threadUpdater.closeThread();
};
}
});
EventHelper.register(window, 'onload', function(){
Chat.webimRoot = threadParams.wroot;
Chat.hSplitter = new HSplitter({control:$("spl1"), first:$("msgwndtd"), second:$("chatwndtd"), minfirst:30, minsec:30});
Chat.threadUpdater = new Ajax.ChatThreadUpdater(({container:myRealAgent=='safari'?self.frames[0]:$("chatwnd"),avatar:$("avatarwnd"),message:$("msgwnd")}).extend( threadParams || {} ));
});

View File

@ -0,0 +1,286 @@
Ajax.PeriodicalUpdater = Class.create();
Class.inherit( Ajax.PeriodicalUpdater, Ajax.Base, {
initialize: function(_options) {
this.setOptions(_options);
this._options.onComplete = this.requestComplete.bind(this);
this._options.onException = this.handleException.bind(this);
this.frequency = (this._options.frequency || 2);
this.updater = {};
this.update();
},
handleException: function(_request, ex) {
if( this._options.handleError )
this._options.handleError( ex.name + " occured: " + ex.message );
this.stopUpdate();
this.timer = setTimeout(this.update.bind(this), this.frequency * 1000);
},
stopUpdate: function() {
if( this.updater._options )
this.updater._options.onComplete = undefined;
clearTimeout(this.timer);
},
update: function() {
if( this._options.updateParams )
this._options.parameters = (this._options.updateParams)();
this.updater = new Ajax.Request(this._options.url, this._options);
},
requestComplete: function(presponse) {
if (presponse != null && presponse.status == 200 ) {
var xmlDoc = presponse.responseXML;
(this._options.updateContent || Ajax.emptyFunction)( xmlDoc );
} else {
if( this._options.handleError )
this._options.handleError(Ajax.getError(_response));
}
this.timer = setTimeout(this.update.bind(this), this.frequency * 1000);
}
});
var HtmlGenerationUtils = {
insertSplitter: function( _row ) {
var cell = _row.insertCell(-1);
cell.style.backgroundImage = 'url('+webimRoot+'/images/tablediv3.gif)';
cell.innerHTML = '<img src="'+webimRoot+'/images/free.gif" width="3" height="1" border="0" alt="">';
},
removeHr: function(_table, _index ) {
_table.deleteRow(_index+2);
_table.deleteRow(_index+1);
_table.deleteRow(_index);
},
insertHr: function(_table, _index) {
var row = _table.insertRow(_index);
var cell = row.insertCell(-1);
cell.colSpan = 13;
cell.height = 2;
row = _table.insertRow(_index);
cell = row.insertCell(-1);
cell.colSpan = 13;
cell.style.backgroundColor = '#E1E1E1';
cell.innerHTML = '<img src="'+webimRoot+'/images/free.gif" width="1" height="1" border="0" alt="">';
row = _table.insertRow(_index);
cell = row.insertCell(-1);
cell.colSpan = 13;
cell.height = 2;
},
popupLink: function(link, title, wndid, inner, width, height) {
return '<a href="'+link+'" target="_blank" title="'+title+'" onclick="this.newWindow = window.open(\''+link+'\', \''+
wndid+'\', \'toolbar=0,scrollbars=0,location=0,status=1,menubar=0,width='+width+',height='+height+',resizable=1\');this.newWindow.focus();this.newWindow.opener=window;return false;">'+
inner+'</a>';
},
generateOneRowTable: function(content) {
return '<table width="100%" cellspacing="0" cellpadding="0" border="0"><tr>' + content + '</tr></table>';
},
viewOpenCell: function(username,servlet,id,canview,canopen,ban,message) {
var cellsCount = 2;
var link = servlet+"?thread="+id;
var innerContent = ( ban == "full" ) ? "<i style='color:#aaaaaa;'>"+username+"</i>" : ( ( ban == "other" ) ? "<i>"+username+"</i>" : username );
var gen = '<td class="table" style="padding-left:0px; padding-right:0px;">';
gen += HtmlGenerationUtils.popupLink( canopen ? link : link+"&viewonly=true", localized[canopen ? 0 : 1], "ImCenter"+id, innerContent, 600, 420);
gen += '</td><td><img src="'+webimRoot+'/images/free.gif" width="5" height="1" border="0" alt=""></td>';
if( canopen ) {
gen += '<td width="30" align="center">';
gen += HtmlGenerationUtils.popupLink( link, localized[0], "ImCenter"+id, '<img src="'+webimRoot+'/images/tbliclspeak.gif" width="15" height="15" border="0" alt="'+localized[0]+'">', 600, 420);
gen += '</td>';
cellsCount++;
}
return HtmlGenerationUtils.generateOneRowTable(gen);
}
};
Ajax.ThreadListUpdater = Class.create();
Class.inherit( Ajax.ThreadListUpdater, Ajax.Base, {
initialize: function(_options) {
this.setOptions(_options);
this._options.updateParams = this.updateParams.bind(this);
this._options.handleError = this.handleError.bind(this);
this._options.updateContent = this.updateContent.bind(this);
this._options.lastrevision = 0;
this.delta = 0;
this.t = this._options.table;
this.periodicalUpdater = new Ajax.PeriodicalUpdater(this._options);
},
updateParams: function() {
return "company=" + this._options.company + "&since=" + this._options.lastrevision;
},
setStatus: function(msg) {
this._options.status.innerHTML = msg;
},
handleError: function(s) {
this.setStatus( s );
},
updateThread: function(node) {
var id, stateid, vstate, canview = false, canopen = false, ban = null;
for( var i = 0; i < node.attributes.length; i++ ) {
var attr = node.attributes[i];
if( attr.nodeName == "id" )
id = attr.nodeValue;
else if( attr.nodeName == "stateid" )
stateid = attr.nodeValue;
else if( attr.nodeName == "state" )
vstate = attr.nodeValue;
else if( attr.nodeName == "canopen" )
canopen = true;
}
function setcell(_table, row,id,pcontent) {
var cell = CommonUtils.getCell( id, row, _table );
if( cell )
cell.innerHTML = pcontent;
}
var row = CommonUtils.getRow("thr"+id, this.t);
if( stateid == "closed" ) {
if( row ) {
HtmlGenerationUtils.removeHr(this.t, row.rowIndex+1);
this.t.deleteRow(row.rowIndex);
}
return;
}
var vname = NodeUtils.getNodeValue(node,"name");
var vaddr = NodeUtils.getNodeValue(node,"addr");
var vtime = NodeUtils.getNodeValue(node,"time");
var agent = NodeUtils.getNodeValue(node,"agent");
var modified = NodeUtils.getNodeValue(node,"modified");
var message = NodeUtils.getNodeValue(node,"message");
var etc = "";
var startRow = CommonUtils.getRow(stateid, this.t);
var endRow = CommonUtils.getRow(stateid+"end", this.t);
if( row != null && (row.rowIndex <= startRow.rowIndex || row.rowIndex >= endRow.rowIndex ) ) {
HtmlGenerationUtils.removeHr(this.t, row.rowIndex+1);
this.t.deleteRow(row.rowIndex);
row = null;
}
if( row == null ) {
row = this.t.insertRow(startRow.rowIndex+1);
HtmlGenerationUtils.insertHr(this.t, startRow.rowIndex+2);
row.id = "thr"+id;
CommonUtils.insertCell(row, "name", "table", null, 30, HtmlGenerationUtils.viewOpenCell(vname,this._options.agentservl,id,canview,canopen,ban,message) );
HtmlGenerationUtils.insertSplitter(row);
CommonUtils.insertCell(row, "contid", "table", "center", null, vaddr );
HtmlGenerationUtils.insertSplitter(row);
CommonUtils.insertCell(row, "state", "table", "center", null, vstate );
HtmlGenerationUtils.insertSplitter(row);
CommonUtils.insertCell(row, "op", "table", "center", null, agent );
HtmlGenerationUtils.insertSplitter(row);
CommonUtils.insertCell(row, "time", "table", "center", null, this.getTimeSince(vtime) );
HtmlGenerationUtils.insertSplitter(row);
CommonUtils.insertCell(row, "wait", "table", "center", null, (stateid!='chat' ? this.getTimeSince(modified) : '-') );
HtmlGenerationUtils.insertSplitter(row);
CommonUtils.insertCell(row, "etc", "table", "center", null, etc );
if( stateid == 'wait' || stateid == 'prio' )
return true;
} else {
setcell(this.t, row,"name",HtmlGenerationUtils.viewOpenCell(vname,this._options.agentservl,id,canview,canopen,ban,message));
setcell(this.t, row,"contid",vaddr);
setcell(this.t, row,"state",vstate);
setcell(this.t, row,"op",agent);
setcell(this.t, row,"time",this.getTimeSince(vtime));
setcell(this.t, row,"wait",(stateid!='chat' ? this.getTimeSince(modified) : '-'));
setcell(this.t, row,"etc",etc);
}
return false;
},
updateQueueMessages: function() {
function updateQueue(t,id,nclients) {
var startRow = t.rows[id];
var endRow = t.rows[id+"end"];
if( startRow == null || endRow == null )
return;
var _status = endRow.cells["status"];
if( _status == null )
return;
_status.innerHTML = (startRow.rowIndex + 1 == endRow.rowIndex) ? nclients : "";
_status.height = (startRow.rowIndex + 1 == endRow.rowIndex) ? 30 : 10;
}
updateQueue(this.t, "wait", this._options.noclients);
updateQueue(this.t, "prio", this._options.noclients);
updateQueue(this.t, "chat", this._options.noclients);
},
getTimeSince: function(srvtime) {
var secs = Math.floor(((new Date()).getTime()-srvtime-this.delta)/1000);
var minutes = Math.floor(secs/60);
var prefix = "";
secs = secs % 60;
if( secs < 10 )
secs = "0" + secs;
if( minutes >= 60 ) {
var hours = Math.floor(minutes/60);
minutes = minutes % 60;
if( minutes < 10 )
minutes = "0" + minutes;
prefix = hours + ":";
}
return prefix + minutes+":"+secs;
},
updateContent: function(xmldoc) {
var root = xmldoc.documentElement;
var newAdded = false;
if( root.tagName == 'threads' ) {
var _time = NodeUtils.getAttrValue(root, "time");
var _revision = NodeUtils.getAttrValue(root, "revision" );
if( _time )
this.delta = (new Date()).getTime() - _time;
if( _revision )
this._options.lastrevision = _revision;
for( var i = 0; i < root.childNodes.length; i++ ) {
var node = root.childNodes[i];
if( node.tagName == 'thread' )
if( this.updateThread(node) )
newAdded = true;
}
this.updateQueueMessages();
this.setStatus( "Up to date" );
if( newAdded )
window.focus();
} else if( root.tagName == 'error' ) {
this.setStatus( "error: " + NodeUtils.getNodeValue(root,"descr") );
} else {
this.setStatus( "wrong response" );
}
}
});
var webimRoot = "";
EventHelper.register(window, 'onload', function(){
webimRoot = updaterOptions.wroot;
new Ajax.ThreadListUpdater(({table:$("threadlist"),status:$("connstatus")}).extend(updaterOptions || {}));
});

View File

@ -1 +1 @@
var myAgent="";var kj=0;var myRealAgent="";function lj(){var oj=["\157pe\162a","\u006d\u0073\u0069\145","\163\141\146ar\u0069","\146i\u0072\u0065f\u006f\170","\u006e\u0065ts\143a\u0070\145","\u006d\u006f\u007ai\u006cl\u0061"];var ai=navigator.userAgent.toLowerCase();for(var i=0;i<oj.length;i++){var pj=oj[i];if(ai.indexOf(pj)!=-1){myAgent=pj;if(!window.RegExp)break;var dj=new RegExp(pj+"\u005b\u0020\/\u005d\u003f(\u005b\060\u002d9\135\u002b(\.\u005b\060\u002d9\u005d+)?)");if(dj.exec(ai)!=null){kj=parseFloat(RegExp.$1);} break;} } myRealAgent=myAgent;if(navigator.product=="G\u0065c\153\u006f")myAgent="moz";} lj();function getEl(name){return document.getElementById(name);}
var myAgent="";var pj=0;var myRealAgent="";function dj(){var ej=["\157pe\u0072\u0061","\155\u0073\151\145","s\141f\141\u0072\u0069","f\u0069r\145\u0066\u006f\170","\u006e\145t\163ca\u0070\u0065","\u006d\157\172\u0069l\154\141"];var vi=navigator.userAgent.toLowerCase();for(var i=0;i<ej.length;i++){var fj=ej[i];if(vi.indexOf(fj)!=-1){myAgent=fj;if(!window.RegExp)break;var gj=new RegExp(fj+"\u005b\040\/]?(\u005b\u0030\055\071]\u002b\u0028\.[0\u002d\071\135\u002b\u0029?\051");if(gj.exec(vi)!=null){pj=parseFloat(RegExp.$1);} break;} } myRealAgent=myAgent;if(navigator.product=="G\u0065c\u006bo")myAgent="\u006d\u006f\u007a";} dj();function getEl(name){return document.getElementById(name);}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -125,7 +125,7 @@ function print_thread_mesages($threadid, $token, $lastid, $isuser,$format) {
if( $format == "xml" ) {
start_xml_output();
print("<thread lastID=\"$lastid\">");
print("<thread lastid=\"$lastid\">");
foreach( $output as $msg ) {
print "<message>".myiconv($webim_encoding,"utf-8",escape_with_cdata($msg))."</message>\n";
}