diff --git a/src/messenger/webim/js/164/chat.js b/src/messenger/webim/js/164/chat.js index 4fd6b7c4..6548b009 100644 --- a/src/messenger/webim/js/164/chat.js +++ b/src/messenger/webim/js/164/chat.js @@ -7,14 +7,7 @@ */ var FrameUtils={getDocument:function(a){return a.contentDocument?a.contentDocument:a.contentWindow?a.contentWindow.document:a.document?a.document:null},initFrame:function(a){var b=this.getDocument(a);b.open();b.write("");b.write('');b.write("");b.write("
"); b.write("");b.close();a.onload=function(){a.myHtml&&(FrameUtils.getDocument(a).getElementById("content").innerHTML+=a.myHtml,FrameUtils.scrollDown(a))}},insertIntoFrame:function(a,b){var c=this.getDocument(a).getElementById("content");null==c?(a.myHtml||(a.myHtml=""),a.myHtml+=b):c.innerHTML+=b},scrollDown:function(a){var b=this.getDocument(a).getElementById("bottom");if("opera"==myAgent)try{a.contentWindow.scrollTo(0,this.getDocument(a).getElementById("content").clientHeight)}catch(c){}b&& -b.scrollIntoView(!1)}};ChatServer=Class.create(); -ChatServer.prototype={initialize:function(a){this.updateTimer=null;this.options={servl:"",requestsFrequency:2,onTimeout:function(){},onTransportError:function(){},onCallError:function(){},onUpdateError:function(){},onResponseError:function(){}}.extend(a);this.callbacks={};this.callPeriodically=[];this.ajaxOptions={_method:"post",asynchronous:!0,timeout:5E3,onComplete:this.receiveResponse.bind(this),onException:this.onTransportError.bind(this),onTimeout:this.onTimeout.bind(this)};this.ajaxRequest= -null;this.buffer=[];this.functions={};this.mibewAPI=new MibewAPI(new MibewAPICoreInteraction)},callFunctions:function(a,b,c){try{if(!(a instanceof Array))throw Error("The first arguments must be an array");for(var d in a)a.hasOwnProperty(d)&&this.mibewAPI.checkFunction(a[d],!1);var e=this.generateToken();this.callbacks[e]=b;this.buffer.push({token:e,functions:a});c&&this.update()}catch(f){return this.options.onCallError(f),!1}return!0},callFunctionsPeriodically:function(a,b){this.callPeriodically.push({functionsListBuilder:a, -callbackFunction:b})},generateToken:function(){var a;do a="wnd"+(new Date).getTime().toString()+Math.round(50*Math.random()).toString();while(a in this.callbacks);return a},processRequest:function(a){var b=new MibewAPIExecutionContext,c=this.mibewAPI.getResultFunction(a.functions,this.callbacks.hasOwnProperty(a.token));if(null===c)for(var d in a.functions)a.functions.hasOwnProperty(d)&&(this.processFunction(a.functions[d],b),this.buffer.push(this.mibewAPI.buildResult(b.getResults(),a.token)));else this.callbacks.hasOwnProperty(a.token)&& -(this.callbacks[a.token](c.arguments),delete this.callbacks[a.token])},processFunction:function(a,b){if(this.functions.hasOwnProperty(a["function"])){var c=b.getArgumentsList(a),d={},e;for(e in this.functions[a["function"]])this.functions[a["function"]].hasOwnProperty(e)&&d.extend(this.functions[a["function"]][e](c));b.storeFunctionResults(a,d)}},sendRequests:function(a){this.ajaxRequest=new Ajax.Request(this.options.servl,this.ajaxOptions.extend({parameters:"data="+this.mibewAPI.encodePackage(a)}))}, -runUpdater:function(){null==this.updateTimer&&this.update();this.updateTimer=setTimeout(this.update.bind(this),1E3*this.options.requestsFrequency)},restartUpdater:function(){this.updateTimer&&clearTimeout(this.updateTimer);this.ajaxRequest._options&&(this.ajaxRequest._options.onComplete=void 0);this.update();this.updateTimer=setTimeout(this.update.bind(this),1E3)},update:function(){this.updateTimer&&clearTimeout(this.updateTimer);for(var a=0;a + + + + diff --git a/src/messenger/webim/js/source/chat.js b/src/messenger/webim/js/source/chat.js index e1d5b761..7e12fa1f 100644 --- a/src/messenger/webim/js/source/chat.js +++ b/src/messenger/webim/js/source/chat.js @@ -59,383 +59,6 @@ var FrameUtils = { } }; -ChatServer = Class.create(); -/** - * @todo Think about error handling - */ -ChatServer.prototype = { - /** - * @constructor - */ - initialize: function(options) { - var chatServer = this; - - /** - * Update timer - */ - this.updateTimer = null; - - /** - * Options for the ChatServer object - * @private - * @todo Check onResponseError handler - */ - this.options = { - // Server gateway URL - servl: "", - // Frequency for automatic updater - requestsFrequency: 2, - // Call on request timeout - onTimeout: function() {}, - // Call when transport error was caught - onTransportError: function(e) {}, - // Call when callFunctions related error was caught - onCallError: function(e) {}, - // Call when update related error was caught - onUpdateError: function(e) {}, - // Call when response related error was caught - onResponseError: function(e) {} - }.extend(options); - - /** - * Binds request's token and callback function - * @type Object - * @private - */ - this.callbacks = {}; - - /** - * Array of periodically called functions - * @type Array - * @private - */ - this.callPeriodically = []; - - /** - * Options for an Ajax.Request object - * @type Array - * @private - */ - this.ajaxOptions = { - _method: 'post', - asynchronous: true, - timeout: 5000, - onComplete: chatServer.receiveResponse.bind(chatServer), - onException: chatServer.onTransportError.bind(chatServer), - onTimeout: chatServer.onTimeout.bind(chatServer) - } - - /** - * An object of the Ajax.Request class - * @type Ajax.Request - * @private - */ - this.ajaxRequest = null; - - /** - * This buffer store requests and responses between sending packages - * @private - */ - this.buffer = []; - - /** - * Contains object of registered functions handlers - * @private - */ - this.functions = {} - - /** - * An instance of the MibewAPI class - * @type MibewAPI - * @private - */ - this.mibewAPI = new MibewAPI(new MibewAPICoreInteraction()); - }, - - /** - * Make call to the chat server - * - * @param {Oblect[]} functionsList List of the function objects. See Mibew API - * for details. - * @param {Function} callbackFunction - * @param {Boolean} forceSend Force requests buffer send right after call - * @returns {Boolean} boolean true on success and false on failure - */ - callFunctions: function(functionsList, callbackFunction, forceSend) { - try { - // Check function objects - if (!(functionsList instanceof Array)) { - throw new Error("The first arguments must be an array"); - } - for (var i in functionsList) { - // Filter 'Prototype' properties - if (! functionsList.hasOwnProperty(i)) { - continue; - } - this.mibewAPI.checkFunction(functionsList[i], false); - } - - // Generate request token - var token = this.generateToken(); - // Store callback function - this.callbacks[token] = callbackFunction; - - // Add request to buffer - this.buffer.push({ - 'token': token, - 'functions': functionsList - }); - if (forceSend) { - // Force update - this.update(); - } - } catch (e) { - // Handle errors - this.options.onCallError(e); - return false; - } - return true; - }, - - /** - * Call function at every request to build functions list - * - * @param {Function} functionsListBuilder Call before every request to build a - * list of functions that must be called - * @param {Function} callbackFunction Call after response received - */ - callFunctionsPeriodically: function(functionsListBuilder, callbackFunction) { - this.callPeriodically.push({ - functionsListBuilder: functionsListBuilder, - callbackFunction: callbackFunction - }); - }, - - /** - * Generates unique request token - * - * @private - * @returns {String} Request token - */ - generateToken: function() { - var token; - do { - // Create token - token = "wnd" + - (new Date()).getTime().toString() + - (Math.round(Math.random() * 50)).toString(); - // Check token uniqueness - } while(token in this.callbacks); - return token; - }, - - /** - * Process request - * - * @param {Object} requestObject Request object. See Mibew API for details. - * @private - */ - processRequest: function(requestObject) { - var context = new MibewAPIExecutionContext(); - - // Get result function - var resultFunction = this.mibewAPI.getResultFunction( - requestObject.functions, - this.callbacks.hasOwnProperty(requestObject.token) - ); - - if (resultFunction === null) { - // Result function not found - for (var i in requestObject.functions) { - if (! requestObject.functions.hasOwnProperty(i)) { - continue; - } - // Execute functions - this.processFunction(requestObject.functions[i], context); - // Build and store result - this.buffer.push(this.mibewAPI.buildResult( - context.getResults(), - requestObject.token - )); - } - } else { - // Result function found - if (this.callbacks.hasOwnProperty(requestObject.token)) { - // Invoke callback - this.callbacks[requestObject.token](resultFunction.arguments); - // Remove callback - delete this.callbacks[requestObject.token]; - } - } - }, - - /** - * Process function - * - * @param {Object} functionObject Function object. See Mibew API for details - * @param {MibewAPIExecutionContext} context Execution context - * @private - */ - processFunction: function(functionObject, context) { - if (! this.functions.hasOwnProperty(functionObject["function"])) { - return; - } - // Get function arguments with replaced refences - var functionArguments = context.getArgumentsList(functionObject); - - var results = {}; - for (var i in this.functions[functionObject["function"]]) { - if (! this.functions[functionObject["function"]].hasOwnProperty(i)) { - continue; - } - // Get results - results.extend(this.functions[functionObject["function"]][i]( - functionArguments - )); - } - - // Add function results to the execution context - context.storeFunctionResults(functionObject, results); - }, - - /** - * Send the request to the chat server - * - * @param {Object[]} requestsList Array of requests that must be sent to the - * chat server - * @private - */ - sendRequests: function(requestsList) { - // Create new AJAX request - this.ajaxRequest = new Ajax.Request( - this.options.servl, - this.ajaxOptions.extend({ - parameters: 'data=' + this.mibewAPI.encodePackage(requestsList) - }) - ); - }, - - /** - * Sets up next automatic updater iteration - */ - runUpdater: function() { - if (this.updateTimer == null) { - this.update(); - } - this.updateTimer = setTimeout( - this.update.bind(this), - this.options.requestsFrequency * 1000 - ); - }, - - /** - * Restarts the automatic updater - */ - restartUpdater: function() { - // Clear timeout - if (this.updateTimer) { - clearTimeout(this.updateTimer); - } - // Clear request onComplete callback - if (this.ajaxRequest._options) { - this.ajaxRequest._options.onComplete = undefined; - } - // Update thread - this.update(); - // Restart updater. Try to reconnect after a while - this.updateTimer = setTimeout( - this.update.bind(this), - 1000 - ); - }, - - /** - * Send request for update thread and client code's requests - * @private - */ - update: function() { - if (this.updateTimer) { - clearTimeout(this.updateTimer); - } - for (var i = 0; i < this.callPeriodically.length; i++) { - this.callFunctions( - this.callPeriodically[i].functionsListBuilder(), - this.callPeriodically[i].callbackFunction - ); - } - // Check buffer length - if (this.buffer.length == 0) { - // Rerun updater later - this.runUpdater(); - return; - } - try { - // Send requests - this.sendRequests(this.buffer); - // Clear requests buffer - this.buffer = []; - } catch (e) { - // Handle errors - this.options.onUpdateError(e); - } - }, - - /** - * Process response from the Core - * - * @param {String} responseObject The response object provided by - * Ajax.Request class - * @private - */ - receiveResponse: function(responseObject) { - // Do not parse empty responses - if (responseObject.response == '') { - this.runUpdater(); - } - try { - var packageObject = this.mibewAPI.decodePackage(responseObject.response); - for (var i in packageObject.requests) { - this.processRequest(packageObject.requests[i]); - } - } catch (e) { - this.options.onResponseError(e); - } finally { - this.runUpdater(); - } - }, - - /** - * Add function that can be called by the Core - * - * @param {String} functionName Name of the function - * @param {Function} handler Provided function - */ - registerFunction: function(functionName, handler) { - if (!(functionName in this.functions)) { - this.functions[functionName] = []; - } - this.functions[functionName].push(handler); - }, - - /** - * Call on all AJAX transport errors - * @param {Ajax.Request} transport AJAX Transport object - * @param {Error} e Error object - */ - onTransportError: function (transport, e) { - this.restartUpdater(); - this.options.onTransportError(e); - }, - - /** - * Call on all timeouts - */ - onTimeout: function(transport) { - this.restartUpdater(); - this.options.onTimeout() - } -} - ChatThreadUpdater = Class.create(); ChatThreadUpdater.prototype = { /** diff --git a/src/messenger/webim/js/source/chatserver.js b/src/messenger/webim/js/source/chatserver.js new file mode 100644 index 00000000..14dc6336 --- /dev/null +++ b/src/messenger/webim/js/source/chatserver.js @@ -0,0 +1,387 @@ +/** + * @preserve This file is part of Mibew Messenger project. + * http://mibew.org + * + * Copyright (c) 2005-2011 Mibew Messenger Community + * License: http://mibew.org/license.php + */ + +/** + * This class implemets server interaction functionality + */ +ChatServer = Class.create(); +/** + * @todo Think about error handling + */ +ChatServer.prototype = { + /** + * @constructor + */ + initialize: function(options) { + var chatServer = this; + + /** + * Update timer + */ + this.updateTimer = null; + + /** + * Options for the ChatServer object + * @private + * @todo Check onResponseError handler + */ + this.options = { + // Server gateway URL + servl: "", + // Frequency for automatic updater + requestsFrequency: 2, + // Call on request timeout + onTimeout: function() {}, + // Call when transport error was caught + onTransportError: function(e) {}, + // Call when callFunctions related error was caught + onCallError: function(e) {}, + // Call when update related error was caught + onUpdateError: function(e) {}, + // Call when response related error was caught + onResponseError: function(e) {} + }.extend(options); + + /** + * Binds request's token and callback function + * @type Object + * @private + */ + this.callbacks = {}; + + /** + * Array of periodically called functions + * @type Array + * @private + */ + this.callPeriodically = []; + + /** + * Options for an Ajax.Request object + * @type Array + * @private + */ + this.ajaxOptions = { + _method: 'post', + asynchronous: true, + timeout: 5000, + onComplete: chatServer.receiveResponse.bind(chatServer), + onException: chatServer.onTransportError.bind(chatServer), + onTimeout: chatServer.onTimeout.bind(chatServer) + } + + /** + * An object of the Ajax.Request class + * @type Ajax.Request + * @private + */ + this.ajaxRequest = null; + + /** + * This buffer store requests and responses between sending packages + * @private + */ + this.buffer = []; + + /** + * Contains object of registered functions handlers + * @private + */ + this.functions = {} + + /** + * An instance of the MibewAPI class + * @type MibewAPI + * @private + */ + this.mibewAPI = new MibewAPI(new MibewAPICoreInteraction()); + }, + + /** + * Make call to the chat server + * + * @param {Oblect[]} functionsList List of the function objects. See Mibew API + * for details. + * @param {Function} callbackFunction + * @param {Boolean} forceSend Force requests buffer send right after call + * @returns {Boolean} boolean true on success and false on failure + */ + callFunctions: function(functionsList, callbackFunction, forceSend) { + try { + // Check function objects + if (!(functionsList instanceof Array)) { + throw new Error("The first arguments must be an array"); + } + for (var i in functionsList) { + // Filter 'Prototype' properties + if (! functionsList.hasOwnProperty(i)) { + continue; + } + this.mibewAPI.checkFunction(functionsList[i], false); + } + + // Generate request token + var token = this.generateToken(); + // Store callback function + this.callbacks[token] = callbackFunction; + + // Add request to buffer + this.buffer.push({ + 'token': token, + 'functions': functionsList + }); + if (forceSend) { + // Force update + this.update(); + } + } catch (e) { + // Handle errors + this.options.onCallError(e); + return false; + } + return true; + }, + + /** + * Call function at every request to build functions list + * + * @param {Function} functionsListBuilder Call before every request to build + * a list of functions that must be called + * @param {Function} callbackFunction Call after response received + */ + callFunctionsPeriodically: function(functionsListBuilder, callbackFunction) { + this.callPeriodically.push({ + functionsListBuilder: functionsListBuilder, + callbackFunction: callbackFunction + }); + }, + + /** + * Generates unique request token + * + * @private + * @returns {String} Request token + */ + generateToken: function() { + var token; + do { + // Create token + token = "wnd" + + (new Date()).getTime().toString() + + (Math.round(Math.random() * 50)).toString(); + // Check token uniqueness + } while(token in this.callbacks); + return token; + }, + + /** + * Process request + * + * @param {Object} requestObject Request object. See Mibew API for details. + * @private + */ + processRequest: function(requestObject) { + var context = new MibewAPIExecutionContext(); + + // Get result function + var resultFunction = this.mibewAPI.getResultFunction( + requestObject.functions, + this.callbacks.hasOwnProperty(requestObject.token) + ); + + if (resultFunction === null) { + // Result function not found + for (var i in requestObject.functions) { + if (! requestObject.functions.hasOwnProperty(i)) { + continue; + } + // Execute functions + this.processFunction(requestObject.functions[i], context); + // Build and store result + this.buffer.push(this.mibewAPI.buildResult( + context.getResults(), + requestObject.token + )); + } + } else { + // Result function found + if (this.callbacks.hasOwnProperty(requestObject.token)) { + // Invoke callback + this.callbacks[requestObject.token](resultFunction.arguments); + // Remove callback + delete this.callbacks[requestObject.token]; + } + } + }, + + /** + * Process function + * + * @param {Object} functionObject Function object. See Mibew API for details + * @param {MibewAPIExecutionContext} context Execution context + * @private + */ + processFunction: function(functionObject, context) { + if (! this.functions.hasOwnProperty(functionObject["function"])) { + return; + } + // Get function arguments with replaced refences + var functionArguments = context.getArgumentsList(functionObject); + + var results = {}; + for (var i in this.functions[functionObject["function"]]) { + if (! this.functions[functionObject["function"]].hasOwnProperty(i)) { + continue; + } + // Get results + results.extend(this.functions[functionObject["function"]][i]( + functionArguments + )); + } + + // Add function results to the execution context + context.storeFunctionResults(functionObject, results); + }, + + /** + * Send the request to the chat server + * + * @param {Object[]} requestsList Array of requests that must be sent to the + * chat server + * @private + */ + sendRequests: function(requestsList) { + // Create new AJAX request + this.ajaxRequest = new Ajax.Request( + this.options.servl, + this.ajaxOptions.extend({ + parameters: 'data=' + this.mibewAPI.encodePackage(requestsList) + }) + ); + }, + + /** + * Sets up next automatic updater iteration + */ + runUpdater: function() { + if (this.updateTimer == null) { + this.update(); + } + this.updateTimer = setTimeout( + this.update.bind(this), + this.options.requestsFrequency * 1000 + ); + }, + + /** + * Restarts the automatic updater + */ + restartUpdater: function() { + // Clear timeout + if (this.updateTimer) { + clearTimeout(this.updateTimer); + } + // Clear request onComplete callback + if (this.ajaxRequest._options) { + this.ajaxRequest._options.onComplete = undefined; + } + // Update thread + this.update(); + // Restart updater. Try to reconnect after a while + this.updateTimer = setTimeout( + this.update.bind(this), + 1000 + ); + }, + + /** + * Send request for update thread and client code's requests + * @private + */ + update: function() { + if (this.updateTimer) { + clearTimeout(this.updateTimer); + } + for (var i = 0; i < this.callPeriodically.length; i++) { + this.callFunctions( + this.callPeriodically[i].functionsListBuilder(), + this.callPeriodically[i].callbackFunction + ); + } + // Check buffer length + if (this.buffer.length == 0) { + // Rerun updater later + this.runUpdater(); + return; + } + try { + // Send requests + this.sendRequests(this.buffer); + // Clear requests buffer + this.buffer = []; + } catch (e) { + // Handle errors + this.options.onUpdateError(e); + } + }, + + /** + * Process response from the Core + * + * @param {String} responseObject The response object provided by + * Ajax.Request class + * @private + */ + receiveResponse: function(responseObject) { + // Do not parse empty responses + if (responseObject.response == '') { + this.runUpdater(); + } + try { + var packageObject = this.mibewAPI.decodePackage(responseObject.response); + for (var i in packageObject.requests) { + this.processRequest(packageObject.requests[i]); + } + } catch (e) { + this.options.onResponseError(e); + } finally { + this.runUpdater(); + } + }, + + /** + * Add function that can be called by the Core + * + * @param {String} functionName Name of the function + * @param {Function} handler Provided function + */ + registerFunction: function(functionName, handler) { + if (!(functionName in this.functions)) { + this.functions[functionName] = []; + } + this.functions[functionName].push(handler); + }, + + /** + * Call on all AJAX transport errors + * @param {Ajax.Request} transport AJAX Transport object + * @param {Error} e Error object + */ + onTransportError: function (transport, e) { + this.restartUpdater(); + this.options.onTransportError(e); + }, + + /** + * Call on all timeouts + */ + onTimeout: function(transport) { + this.restartUpdater(); + this.options.onTimeout() + } +} \ No newline at end of file diff --git a/src/messenger/webim/styles/dialogs/default/templates/chat.tpl b/src/messenger/webim/styles/dialogs/default/templates/chat.tpl index 65bd8ea0..f48cc0d5 100644 --- a/src/messenger/webim/styles/dialogs/default/templates/chat.tpl +++ b/src/messenger/webim/styles/dialogs/default/templates/chat.tpl @@ -38,6 +38,7 @@ var chatParams = { } //--> +