mirror of
				https://github.com/Mibew/design.git
				synced 2025-10-31 10:31:05 +03:00 
			
		
		
		
	Move JavaScript's ChatServer class to separate file
This commit is contained in:
		
							parent
							
								
									83636a02ef
								
							
						
					
					
						commit
						d53e1d8020
					
				| @ -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("<html><head>");b.write('<link rel="stylesheet" type="text/css" media="all" href="'+Chat.cssfile+'">');b.write("</head><body bgcolor='#FFFFFF' text='#000000' link='#C28400' vlink='#C28400' alink='#C28400'>");b.write("<table width='100%' cellspacing='0' cellpadding='0' border='0'><tr><td valign='top' class='message' id='content'></td></tr></table><a id='bottom' name='bottom'></a>"); | ||||
| b.write("</body></html>");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<this.callPeriodically.length;a++)this.callFunctions(this.callPeriodically[a].functionsListBuilder(), | ||||
| this.callPeriodically[a].callbackFunction);if(0==this.buffer.length)this.runUpdater();else try{this.sendRequests(this.buffer),this.buffer=[]}catch(b){this.options.onUpdateError(b)}},receiveResponse:function(a){""==a.response&&this.runUpdater();try{var b=this.mibewAPI.decodePackage(a.response),c;for(c in b.requests)this.processRequest(b.requests[c])}catch(d){this.options.onResponseError(d)}finally{this.runUpdater()}},registerFunction:function(a,b){a in this.functions||(this.functions[a]=[]);this.functions[a].push(b)}, | ||||
| onTransportError:function(a,b){this.restartUpdater();this.options.onTransportError(b)},onTimeout:function(){this.restartUpdater();this.options.onTimeout()}};ChatThreadUpdater=Class.create(); | ||||
| b.scrollIntoView(!1)}};ChatThreadUpdater=Class.create(); | ||||
| ChatThreadUpdater.prototype={initialize:function(a,b,c){this._options=c;this.thread=b;this.chatServer=a;this.focused=this.skipNextsound=this.cansend=!0;this.ownThread=null!=this._options.message;FrameUtils.initFrame(this._options.container);this._options.message&&(this._options.message.onkeydown=this.handleKeyDown.bind(this),this._options.message.onfocus=function(){this.focused=!0}.bind(this),this._options.message.onblur=function(){this.focused=!1}.bind(this));this.chatServer.callFunctionsPeriodically(this.updateFunctionBuilder.bind(this), | ||||
| this.updateChatState.bind(this));this.chatServer.registerFunction("updateMessages",this.updateMessages.bind(this));this.chatServer.registerFunction("setupAvatar",this.setupAvatar.bind(this));this.chatServer.runUpdater()},handleException:function(){this.setStatus("offline, reconnecting");this.enableInput(!0)},handleTimeout:function(){this.setStatus("timeout, reconnecting");this.enableInput(!0)},enableInput:function(a){this._options.message&&(this._options.message.disabled=!a)},refresh:function(){this.chatServer.restartUpdater()}, | ||||
| postMessage:function(a){""!=a&&this.cansend&&(this.cansend=!1,this.skipNextsound=!0,"opera"!=myRealAgent&&this.enableInput(!1),this.chatServer.callFunctions([{"function":"post",arguments:{references:{},"return":{},message:a,threadId:this.thread.threadid,token:this.thread.token,user:this.thread.user}}],function(){this.enableInput(!0);this.cansend=!0;this.skipNextsound=!1;this._options.message&&(this._options.message.value="",this._options.message.focus())}.bind(this),!0))},changeName:function(a){this.skipNextsound= | ||||
|  | ||||
							
								
								
									
										15
									
								
								src/messenger/webim/js/164/chatserver.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/messenger/webim/js/164/chatserver.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | ||||
| /* | ||||
|  This file is part of Mibew Messenger project. | ||||
|  http://mibew.org
 | ||||
| 
 | ||||
|  Copyright (c) 2005-2011 Mibew Messenger Community | ||||
|  License: http://mibew.org/license.php
 | ||||
| */ | ||||
| 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,d){try{if(!(a instanceof Array))throw Error("The first arguments must be an array");for(var c in a)a.hasOwnProperty(c)&&this.mibewAPI.checkFunction(a[c],!1);var e=this.generateToken();this.callbacks[e]=b;this.buffer.push({token:e,functions:a});d&&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,d=this.mibewAPI.getResultFunction(a.functions,this.callbacks.hasOwnProperty(a.token));if(null===d)for(var c in a.functions)a.functions.hasOwnProperty(c)&&(this.processFunction(a.functions[c],b),this.buffer.push(this.mibewAPI.buildResult(b.getResults(),a.token)));else this.callbacks.hasOwnProperty(a.token)&& | ||||
| (this.callbacks[a.token](d.arguments),delete this.callbacks[a.token])},processFunction:function(a,b){if(this.functions.hasOwnProperty(a["function"])){var d=b.getArgumentsList(a),c={},e;for(e in this.functions[a["function"]])this.functions[a["function"]].hasOwnProperty(e)&&c.extend(this.functions[a["function"]][e](d));b.storeFunctionResults(a,c)}},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<this.callPeriodically.length;a++)this.callFunctions(this.callPeriodically[a].functionsListBuilder(), | ||||
| this.callPeriodically[a].callbackFunction);if(0==this.buffer.length)this.runUpdater();else try{this.sendRequests(this.buffer),this.buffer=[]}catch(b){this.options.onUpdateError(b)}},receiveResponse:function(a){""==a.response&&this.runUpdater();try{var b=this.mibewAPI.decodePackage(a.response),d;for(d in b.requests)this.processRequest(b.requests[d])}catch(c){this.options.onResponseError(c)}finally{this.runUpdater()}},registerFunction:function(a,b){a in this.functions||(this.functions[a]=[]);this.functions[a].push(b)}, | ||||
| onTransportError:function(a,b){this.restartUpdater();this.options.onTransportError(b)},onTimeout:function(){this.restartUpdater();this.options.onTimeout()}}; | ||||
| @ -44,6 +44,10 @@ | ||||
| 		<arg value="mibew_api:1:common"/> | ||||
| 		  <arg value="--js"/> | ||||
| 		  <arg value="mibew_api.js"/> | ||||
| 	  <arg value="--module"/> | ||||
| 		<arg value="chatserver:1:common"/> | ||||
| 		  <arg value="--js"/> | ||||
| 		  <arg value="chatserver.js"/> | ||||
| 	</java> | ||||
| 
 | ||||
| 	<java jar="${closure.c}" fork="true"> | ||||
|  | ||||
| @ -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 = { | ||||
|   /** | ||||
|  | ||||
							
								
								
									
										387
									
								
								src/messenger/webim/js/source/chatserver.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										387
									
								
								src/messenger/webim/js/source/chatserver.js
									
									
									
									
									
										Normal file
									
								
							| @ -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() | ||||
|     } | ||||
| } | ||||
| @ -38,6 +38,7 @@ var chatParams = { | ||||
| } | ||||
| //--> | ||||
| </script> | ||||
| <script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/chatserver.js"></script> | ||||
| <script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/chat.js"></script> | ||||
| <style type="text/css"> | ||||
| #header{ | ||||
|  | ||||
| @ -38,6 +38,7 @@ var chatParams = { | ||||
| } | ||||
| //--> | ||||
| </script> | ||||
| <script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/chatserver.js"></script> | ||||
| <script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/chat.js"></script> | ||||
| <style type="text/css"> | ||||
| .tplimage { | ||||
|  | ||||
| @ -79,6 +79,7 @@ | ||||
| 		window.onresize = setTrueHeight;		 | ||||
| 		//--> | ||||
| 	</script> | ||||
| 	<script type="text/javascript" src="${webimroot}/js/${jsver}/chatserver.js"></script> | ||||
| 	<script type="text/javascript" src="${webimroot}/js/${jsver}/chat.js"></script> | ||||
| </head> | ||||
| <body class="body"> | ||||
|  | ||||
| @ -38,6 +38,7 @@ var chatParams = { | ||||
| } | ||||
| //--> | ||||
| </script> | ||||
| <script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/chatserver.js"></script> | ||||
| <script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/chat.js"></script> | ||||
| <style type="text/css"> | ||||
| .isound { background: url(${tplroot}/images/buttons/sound.gif) no-repeat; width: 19px; height: 19px; } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user