source: trunk/phpgwapi/js/tools/xconnector.js @ 2601

Revision 2601, 8.6 KB checked in by rodsouza, 14 years ago (diff)

Ticket #1009 - Melhorando a forma de criar cache em uma requisição background.

Line 
1(function()
2{
3        var _THREADS = [];
4        var _ie;
5
6        function _config(pObj, pEvent, pHandler)
7        {
8                if ( typeof pObj == 'object' )
9                {
10                        if ( pEvent.substring(0, 2) == 'on' )
11                                pEvent = pEvent.substring(2, pEvent.length);
12
13                        if ( pObj.addEventListener )
14                                pObj.addEventListener(pEvent, pHandler, false);
15                        else if ( pObj.attachEvent )
16                                pObj.attachEvent('on' + pEvent, pHandler);
17                }
18        }
19
20        // xhr = XMLHttpRequest
21        function _xhr()
22        {
23                try
24                {
25                        return new XMLHttpRequest();
26                }
27                catch ( _e )
28                {
29                        _ie = true;
30                        try
31                        {
32                                return new ActiveXObject('Msxml2.XMLHTTP');
33                        }
34                        catch ( _e1 )
35                        {
36                                try
37                                {
38                                        return new ActiveXObject('Microsoft.XMLHTTP');
39                                }
40                                catch ( _e2 )
41                                {
42                                        return false;
43                                }
44                        }
45                }
46        }
47
48        function _HANDLER()
49        {
50                var _ID = arguments[0];
51
52                if  ( _THREADS[_ID] )
53                {
54                        if ( _ie && _THREADS[_ID]._XHR.readyState != 4 )
55                                return false;
56
57                        switch ( _THREADS[_ID]._XHR.readyState )
58                        {
59                                case 3 :
60                                        if ( _THREADS[_ID]._HANDLER.stream )
61                                        {
62                                                var _data = _THREADS[_ID]._XHR.responseText.substr(_THREADS[_ID]._index).replace(/^ +| +$/g, '');
63                                                //alert(_data);
64                                                _THREADS[_ID]._rtlen = _THREADS[_ID]._XHR.responseText.length;
65
66                                                if ( _THREADS[_ID]._index < _THREADS[_ID]._rtlen && _data.length )
67                                                        try
68                                                        {
69                                                                _THREADS[_ID]._HANDLER.stream(_data);
70                                                        }
71                                                        catch(_e)
72                                                        {
73                                                                //alert("#stream\n\n" + _e + "\n\n" + _e.description);
74                                                        }
75
76                                                if ( _THREADS[ _ID ] )
77                                                        _THREADS[ _ID ]._index = _THREADS[ _ID ]._rtlen;
78                                        }
79                                break;
80                                case 4 :
81                                        try
82                                        {
83                                                switch ( _THREADS[ _ID ]._XHR.status )
84                                                {
85                                                        case 200:
86                                                                var _data = ( _THREADS[ _ID ]._MODE == 'XML' ) ?
87                                                                        _THREADS[ _ID ]._XHR.responseXML :
88                                                                        _THREADS[ _ID ]._XHR.responseText;
89
90                                                                if ( _ie && _THREADS[ _ID ]._HANDLER.stream )
91                                                                        _THREADS[ _ID ]._HANDLER.stream(_data);
92
93                                                                var _request = ( _THREADS[ _ID ]._HANDLER.request ) ?
94                                                                        _THREADS[ _ID ]._HANDLER.request : false;
95
96                                                                if ( _THREADS[ _ID ]._MODE == 'XML' && _data.documentElement && _data.documentElement.hasAttribute( 'ControllerKey' ) )
97                                                                {
98                                                                        this._CONTROLLER_KEY = _data.documentElement.getAttribute( 'ControllerKey' );
99                                                                        _data.documentElement.removeAttribute( 'ControllerKey' );
100                                                                }
101
102                                                                delete _THREADS[ _ID ];
103
104                                                                if ( _request )
105                                                                        try
106                                                                        {
107                                                                                if ( this._cache )
108                                                                                {
109                                                                                        this._CACHED[ _ID ] = _data;
110                                                                                        this._cache = false;
111                                                                                }
112
113                                                                                _request( _data );
114                                                                        }
115                                                                        catch( e )
116                                                                        {
117                                                                                //alert("#request\n\n" + _ID + "\n\n" + _e + "\n\n" + _e.description);
118                                                                        }
119
120                                                        break; // [case : status 200]
121                                                        case 404:
122                                                                delete _THREADS[ _ID ];
123                                                                alert( 'Page Not Found!' );
124                                                        break; // [case : status 404]
125                                                        default:
126                                                                delete _THREADS[ _ID ];
127                                                }
128                                        }
129                                        catch( e )
130                                        {
131                                        }
132                                break;
133                                default :
134                        }
135                }
136        }
137
138        function _execute( )
139        {
140                var _ID = arguments[0];
141
142                var _ACTION = 'act=' + _ID;
143                var _TARGET = this._PATH + this._CONTROLLER + _THREADS[ _ID ]._ACCESS;
144
145                var _SEND = null;
146
147                //if ( _THREADS[_ID]._METHOD == 'GET' )
148                //      _TARGET += '?' + _ACTION;
149
150                //_TARGET += _ID;
151
152                _THREADS[ _ID ]._XHR.open( ( ( _THREADS[ _ID ]._POST ) ? 'POST' : 'GET' ), _TARGET, true);
153
154                if ( _THREADS[ _ID ]._POST )
155                {
156                        _THREADS[ _ID ]._XHR.setRequestHeader( 'Content-Type','application/x-www-form-urlencoded' );
157                        _THREADS[ _ID ]._XHR.setRequestHeader( 'Cache-Control',  'no-store, no-cache, must-revalidate' );
158                        _THREADS[ _ID ]._XHR.setRequestHeader( 'Cache-Control', 'post-check=0, pre-check=0' );
159                        _THREADS[ _ID ]._XHR.setRequestHeader( 'Pragma', 'no-cache' );
160
161                        _SEND = _THREADS[ _ID ]._POST;
162
163                        if ( this._CONTROLLER_KEY && typeof _SEND.documentElement == 'object' )
164                                _SEND.documentElement.setAttribute( 'ControllerKey', this._CONTROLLER_KEY );
165                }
166
167                _THREADS[ _ID ]._XHR.setRequestHeader( 'BackgroundRequest', Date.parse( new Date ) );
168
169                var _this = this;
170                _THREADS[ _ID ]._XHR.onreadystatechange = function( ){ _HANDLER.call( _this, _ID ); };
171                _THREADS[ _ID ]._XHR.send( _SEND );
172        }
173
174        function usage( )
175        {
176                return ""+
177                        "Description:\n"+
178                        "\t<obj>.go({string access, [mixed handler[, XMLObject post]]})\n\n"+
179                        "Parameters:\n"+
180                        "\taccess : assinatura de acesso à camada de controle.\n"+
181                        "\thandler : uma função a ser executada no fim da requisição\n"+
182                        "\t\tou um objeto que poderá conter dois índices sendo\n"+
183                        "\t\tque ambos deverão ser uma função que será executada\n"+
184                        "\t\tconforme o status do objeto xhr, sendo que na posição\n"+
185                        "\t\t'stream' será a função a ser executada a cada iteração\n"+
186                        "\t\tdo objeto xhr e na posição 'request' será a função\n"+
187                        "\t\ta ser executada no fim da requisição.\n"+
188                        "\tpost : se especificado deverá ser uma query string ou um\n"+
189                        "\tXML bem formatado.\n\n";
190        }
191
192        // @PARAM <string> access :
193        //              assinatura de acesso à camada de controle
194        //
195        // @PARAM <object> handler :
196        //              OBS : neste caso a conexão assumirá que se trata de uma stream
197        //              objeto contendo dois duas funções, sendo,
198        //              no índice stream deverá conter uma função que será execultada
199        //              a cada mudança de status do objeto xhr
200        //
201        // @PARAM <function> handler :
202        //              funcão a ser executada no retorno da requisição
203        //              OBS : neste caso a conexão assumirá que se trata de uma
204        //              requisição função que será execultada no final da requisição
205        //
206        // @PARAM <XMLObject> post:
207        //              este parâmetro define se a conexão é via GET ou POST
208        //              caso o parâmetro não esteja presente a conexão será execultada
209        //              via GET, por outro lado, caso ele exista deverá ser uma query
210        //              string válida ou um xml bem formatado
211        //
212        function go( )
213        {
214                if ( arguments.length != 1 )
215                        return { 'error' : "#0\n\n" + usage( ) };
216
217                var _argv = arguments[ 0 ];
218
219                if ( ( ! _argv.access ) || ( typeof _argv.access != 'string' ) || ( ! _argv.access.length ) )
220                        return { 'error' : "#1\n\n" + usage( ) };
221
222                var _ID = _argv.access;
223
224                _THREADS[ _ID ] = {
225                        '_ACCESS'       : _argv.access,
226                        '_HANDLER'      : { },
227                        '_POST'         : ( ( _argv.post ) ? _argv.post : false ),  // [GET | POST]
228                        '_MODE'         : 'TEXT', // [XML | TEXT]
229                        '_TYPE'         : null, // [4 for request | 3 for stream]
230                        '_XHR'          : null  // [4 for request | 3 for stream]
231                };
232
233                if ( _argv.mode && ( _argv.mode == 'XML' || _argv.mode == 'TEXT' ) )
234                        _THREADS[ _ID ] = _argv.mode;
235
236                if ( _argv.handler )
237                        switch ( typeof _argv.handler )
238                        {
239                                case 'function' :
240                                        _THREADS[ _ID ]._HANDLER = { 'request' : _argv.handler };
241                                        break;
242                                case 'object' :
243                                        for ( var i in _argv.handler )
244                                                if ( i != 'stream' && i != 'request' )
245                                                {
246                                                        delete _THREADS[ _ID ];
247                                                        return { 'error' : "#2\n\n" + usage( ) };
248                                                }
249                                                else if ( i == 'stream' )
250                                                {
251                                                        _THREADS[ _ID ]._index = 0;
252                                                        _THREADS[ _ID ]._rtlen = 0;
253                                                }
254                                                _THREADS[ _ID ]._HANDLER = _argv.handler;
255                                        break;
256                        }
257
258                if ( this._cache && this._CACHED[ _ID ] )
259                {
260                        this._cache = false;
261                        if ( _THREADS[ _ID ]._HANDLER.request )
262                                _THREADS[ _ID ]._HANDLER.request( this._CACHED[ _ID ] );
263                }
264                else
265                {
266                        if ( ! ( _THREADS[ _ID ]._XHR = _xhr( ) ) )
267                        {
268                                delete _THREADS[_ID];
269                                return { 'error' : "#3 it cannot make a xhr object" };
270                        }
271
272                        _execute.call( this, _ID );
273                }
274
275                return { 'success' : "your thread is running and the response will be manipulated by the handler" };
276        }
277
278        function _abort()
279        {
280                for ( var _ID in _THREADS )
281                {
282                        // @TODO
283                        // try/catch for unknown error of IE.
284                        // Check, store and retrieve the try/catch.
285                        try
286                        {
287                                if ( _THREADS[_ID] && _THREADS[_ID]._XHR && _THREADS[_ID]._XHR.abort )
288                                        _THREADS[_ID]._XHR.abort();
289
290                                delete _THREADS[_ID];
291                        }
292                        catch(e){}
293                }
294        }
295
296        function Connector( )
297        {
298                var _argv = arguments;
299
300                this._PATH = '';
301
302                this._CONTROLLER  = '';
303
304                this._cache = false;
305
306                this._CACHED = [ ];
307
308                if ( ( _argv.length == 1 ) && ( typeof _argv[0] == 'object' ) )
309                {
310                        _argv = _argv[ 0 ];
311
312                        if ( _argv.path && ( typeof _argv.path == 'string' ) )
313                        {
314                                if ( _argv.path.indexOf('/') != 0 )
315                                        _argv.path = '/' + _argv.path;
316
317                                if ( _argv.path.lastIndexOf('/') != ( _argv.path.length - 1) )
318                                        _argv.path += '/';
319
320                                this._PATH = _argv.path;
321                        }
322
323                        if ( _argv.controller )
324                                this._CONTROLLER = _argv.controller;
325
326                        this._CONTROLLER_KEY = ( _argv.key ) ?
327                                _argv.key : false;
328                }
329        }
330
331        Connector.prototype.go = go;
332        Connector.prototype.abort = _abort;
333        Connector.prototype.cache = function( )
334        {
335                _cache = true;
336
337                if ( arguments.length == 1 && arguments[ 0 ].constructor == Boolean )
338                        _cache = arguments[ 0 ];
339
340                this._cache = _cache;
341
342                return this;
343        };
344        window.XConnector = Connector;
345
346        _config( window, 'onbeforeunload', _abort );
347}
348)();
Note: See TracBrowser for help on using the repository browser.