(function() { var _THREADS = []; var _ie; function _config(pObj, pEvent, pHandler) { if ( typeof pObj == 'object' ) { if ( pEvent.substring(0, 2) == 'on' ) pEvent = pEvent.substring(2, pEvent.length); if ( pObj.addEventListener ) pObj.addEventListener(pEvent, pHandler, false); else if ( pObj.attachEvent ) pObj.attachEvent('on' + pEvent, pHandler); } } // xhr = XMLHttpRequest function _xhr() { try { return new XMLHttpRequest(); } catch ( _e ) { _ie = true; try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch ( _e1 ) { try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch ( _e2 ) { return false; } } } } function _HANDLER() { var _ID = arguments[0]; if ( _THREADS[_ID] ) { if ( _ie && _THREADS[_ID]._XHR.readyState != 4 ) return false; switch ( _THREADS[_ID]._XHR.readyState ) { case 3 : if ( _THREADS[_ID]._HANDLER.stream ) { var _data = _THREADS[_ID]._XHR.responseText.substr(_THREADS[_ID]._index).replace(/^ +| +$/g, ''); //alert(_data); _THREADS[_ID]._rtlen = _THREADS[_ID]._XHR.responseText.length; if ( _THREADS[_ID]._index < _THREADS[_ID]._rtlen && _data.length ) try { _THREADS[_ID]._HANDLER.stream(_data); } catch(_e) { //alert("#stream\n\n" + _e + "\n\n" + _e.description); } if ( _THREADS[ _ID ] ) _THREADS[ _ID ]._index = _THREADS[ _ID ]._rtlen; } break; case 4 : try { switch ( _THREADS[ _ID ]._XHR.status ) { case 200: var _data = ( _THREADS[ _ID ]._MODE == 'XML' ) ? _THREADS[ _ID ]._XHR.responseXML : _THREADS[ _ID ]._XHR.responseText; if ( _ie && _THREADS[ _ID ]._HANDLER.stream ) _THREADS[ _ID ]._HANDLER.stream(_data); var _request = ( _THREADS[ _ID ]._HANDLER.request ) ? _THREADS[ _ID ]._HANDLER.request : false; if ( _THREADS[ _ID ]._MODE == 'XML' && _data.documentElement && _data.documentElement.hasAttribute( 'ControllerKey' ) ) { this._CONTROLLER_KEY = _data.documentElement.getAttribute( 'ControllerKey' ); _data.documentElement.removeAttribute( 'ControllerKey' ); } if ( _THREADS[ _ID ]._CACHE ) this._CACHED[ _ID ] = _data; delete _THREADS[ _ID ]; if ( _request ) try { _request( _data ); } catch ( _e ) { alert("#request\n\n" + _ID + "\n\n" + _e + "\n\n" + _e.description); } break; // [case : status 200] case 404: delete _THREADS[ _ID ]; alert( 'Page Not Found!' ); break; // [case : status 404] default: delete _THREADS[ _ID ]; } } catch( e ) { //alert( "e\n\n" + e ); } break; default : } } } function _execute( ) { var _ID = arguments[0]; var _ACTION = 'act=' + _ID; var _TARGET = this._PATH + this._CONTROLLER + _THREADS[ _ID ]._ACCESS; var _SEND = null; _THREADS[ _ID ]._XHR.open( ( ( _THREADS[ _ID ]._POST ) ? 'POST' : 'GET' ), _TARGET, true); if ( _THREADS[ _ID ]._POST ) { _THREADS[ _ID ]._XHR.setRequestHeader( 'Content-Type','application/x-www-form-urlencoded' ); _THREADS[ _ID ]._XHR.setRequestHeader( 'Cache-Control', 'no-store, no-cache, must-revalidate' ); _THREADS[ _ID ]._XHR.setRequestHeader( 'Cache-Control', 'post-check=0, pre-check=0' ); _THREADS[ _ID ]._XHR.setRequestHeader( 'Pragma', 'no-cache' ); _SEND = _THREADS[ _ID ]._POST; if ( this._CONTROLLER_KEY && typeof _SEND.documentElement == 'object' ) _SEND.documentElement.setAttribute( 'ControllerKey', this._CONTROLLER_KEY ); } _THREADS[ _ID ]._XHR.setRequestHeader( 'BackgroundRequest', Date.parse( new Date ) ); var _this = this; _THREADS[ _ID ]._XHR.onreadystatechange = function( ){ _HANDLER.call( _this, _ID ); }; _THREADS[ _ID ]._XHR.send( _SEND ); } function usage( ) { return ""+ "Description:\n"+ "\t.go({string access, [mixed handler[, XMLObject post]]})\n\n"+ "Parameters:\n"+ "\taccess : assinatura de acesso à camada de controle.\n"+ "\thandler : uma função a ser executada no fim da requisição\n"+ "\t\tou um objeto que poderá conter dois índices sendo\n"+ "\t\tque ambos deverão ser uma função que será executada\n"+ "\t\tconforme o status do objeto xhr, sendo que na posição\n"+ "\t\t'stream' será a função a ser executada a cada iteração\n"+ "\t\tdo objeto xhr e na posição 'request' será a função\n"+ "\t\ta ser executada no fim da requisição.\n"+ "\tpost : se especificado deverá ser uma query string ou um\n"+ "\tXML bem formatado.\n\n"; } // @PARAM access : // assinatura de acesso à camada de controle // // @PARAM handler : // OBS : neste caso a conexão assumirá que se trata de uma stream // objeto contendo dois duas funções, sendo, // no índice stream deverá conter uma função que será execultada // a cada mudança de status do objeto xhr // // @PARAM handler : // funcão a ser executada no retorno da requisição // OBS : neste caso a conexão assumirá que se trata de uma // requisição função que será execultada no final da requisição // // @PARAM post: // este parâmetro define se a conexão é via GET ou POST // caso o parâmetro não esteja presente a conexão será execultada // via GET, por outro lado, caso ele exista deverá ser uma query // string válida ou um xml bem formatado // function go( ) { if ( arguments.length != 1 ) return { 'error' : "#0\n\n" + usage( ) }; var _argv = arguments[ 0 ]; if ( ( ! _argv.access ) || ( typeof _argv.access != 'string' ) || ( ! _argv.access.length ) ) return { 'error' : "#1\n\n" + usage( ) }; var _ID = _argv.access; _THREADS[ _ID ] = { '_ACCESS' : _argv.access, '_HANDLER' : { }, '_POST' : ( ( _argv.post && _argv.post != null ) ? _argv.post : false ), // [GET | POST] '_MODE' : 'TEXT', // [XML | TEXT] '_TYPE' : null, // [4 for request | 3 for stream] '_XHR' : null, // [4 for request | 3 for stream] '_CACHE' : ( ( _argv.cache && _argv.cache === true ) ? true : false ) }; if ( _argv.mode && ( _argv.mode == 'XML' || _argv.mode == 'TEXT' ) ) _THREADS[ _ID ]._MODE = _argv.mode; if ( _argv.handler ) switch ( typeof _argv.handler ) { case 'function' : _THREADS[ _ID ]._HANDLER = { 'request' : _argv.handler }; break; case 'object' : for ( var i in _argv.handler ) if ( i != 'stream' && i != 'request' ) { delete _THREADS[ _ID ]; return { 'error' : "#2\n\n" + usage( ) }; } else if ( i == 'stream' ) { _THREADS[ _ID ]._index = 0; _THREADS[ _ID ]._rtlen = 0; } _THREADS[ _ID ]._HANDLER = _argv.handler; break; } if ( _THREADS[ _ID ]._CACHE && this._CACHED[ _ID ] ) { if ( _THREADS[ _ID ]._HANDLER.request ) _THREADS[ _ID ]._HANDLER.request( this._CACHED[ _ID ] ); } else { if ( ! ( _THREADS[ _ID ]._XHR = _xhr( ) ) ) { delete _THREADS[_ID]; return { 'error' : "#3 it cannot make a xhr object" }; } _execute.call( this, _ID ); } return { 'success' : "your thread is running and the response will be manipulated by the handler" }; } function _abort() { for ( var _ID in _THREADS ) { // @TODO // try/catch for unknown error of IE. // Check, store and retrieve the try/catch. try { if ( _THREADS[_ID] && _THREADS[_ID]._XHR && _THREADS[_ID]._XHR.abort ) _THREADS[_ID]._XHR.abort(); delete _THREADS[_ID]; } catch(e){} } } function Connector( ) { var _argv = arguments; this._PATH = ''; this._CONTROLLER = ''; this._CACHED = [ ]; if ( ( _argv.length == 1 ) && ( typeof _argv[0] == 'object' ) ) { _argv = _argv[ 0 ]; if ( _argv.path && ( typeof _argv.path == 'string' ) ) { var host = window.location.protocol + "//" + window.location.host; if ( _argv.path.indexOf( host ) != 0 && _argv.path.indexOf( '/' ) != 0 ) _argv.path = host + '/' + _argv.path; if ( _argv.path.lastIndexOf( '/' ) != ( _argv.path.length - 1 ) ) _argv.path += '/'; this._PATH = _argv.path; } if ( _argv.controller ) this._CONTROLLER = _argv.controller; this._CONTROLLER_KEY = ( _argv.key ) ? _argv.key : false; } } Connector.prototype.go = go; Connector.prototype.abort = _abort; Connector.prototype.cache = function( ) { return this; }; window.XConnector = Connector; _config( window, 'onbeforeunload', _abort ); } )();