1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
/**
 *   Swingjax AJAX Class
 *
 *   Copyright(c)2009 Markus Diersbock. All Rights Reserved.
 *
 *   Terms: You may freely use this source code in both
 *   commercial and non-commercial applications, provided
 *   all copyright notices remain intact.
 *
 *   Author:     Markus Diersbock <markus@swingnote.com>
 *   Class:      Swingjax
 *   Revisions:  2009/11/13 Created
 *               2011/03/17 Bug fixes
 *
 *   Use: http://www.swingnote.com/downloads/swingjax_example.htm           
 */
var = Swingjax (function () {

    /*
        Private Properties
    */
    var VERSION = "1.3.2";

    // connection object
    var _xhr = null;
    
    // data to package
    var _parameterData = "";
    
    // http||https
    var _sendProtocol = "http";
    
    // requested file location
    var _requestPath = "";       
    
    // requested file
    var _requestFile = "";       

    // that
    var _that = null;
    
    /*
        Private Functions
    */
    
    /**
    *   Func:         _encodeVars
    *   Description:    encodes values in string of name/value pairs
    *   Parameters:     vars_in     string to encode
    *   Returns:        list of name/value pairs with values encoded
    */
    function _encodeVars(vars_in) {     
        var rtn = "";
        var i = 0;

        if (vars_in.length) {
            var vars_ary = vars_in.split("&");

            for (i in vars_ary) {
                var tmp_ary = vars_ary[i].split("=");
                rtn += tmp_ary[0] + "=";

                if (typeof tmp_ary[1] !== "undefined") {
                  rtn += encodeURIComponent(tmp_ary[1]);
                }
            }
        }

        return rtn;
    }          

    /**
    *   Func:         _createXHR
    *   Description:    creates XMLRequestObject
    *   Parameters:     n/a
    *   Returns:        XMLRequestObject
    */
    function _createXHR() {

        // no soup for you
        if (_xhr) {
            return;
        }

        try {
            _xhr = new XMLHttpRequest();
            return;
        } 
        catch (e) {}
        
        try {
            _xhr = new ActiveXObject("Msxml2.XMLHTTP");
            return;
        }
        catch (e) {}
        
        try {
            _xhr = new ActiveXObject("Microsoft.XMLHTTP");
            return;
        }
        catch (e) {
            _xhr = null;
            _that.isError = true;
            _that.errorDetail += "xhr Creation Failed: " + e.message + "|";
        }
    }     

    /**
    *   Func:         _responseCallback
    *   Description:    Processes readyState status, fires
    *                   onProcessing()/onCompletion() for callback
    *                   binding to object creator 
    *   Parameters:     n/a
    *   Returns:        n/a
    */
    function _responseCallback() {

        switch (_xhr.readyState){
            case 1:
                // fall thru
            case 2:
                _that.transactionStatus = "Sending Request to Server";
                _that.onProcessing();
                break;
            case 3:
                _that.transactionStatus = "Awaiting Data from Server";
                _that.onProcessing();
                break;
            case 4:
                // Ok
                if (_xhr.status === 200) {
                    _that.responseText = _xhr.responseText;
                    _that.responseXML = _xhr.responseXML;
                    _that.transactionStatus = "Completed";
                    _that.onCompletion();
                } else if (_xhr.status === 304) {
                    // # TODO Add 304 Cache functionality
                } else {
                    _that.isError = true;
                    _that.errorDetail += "Response Callback: Retrieving Data|";
                    _that.transactionStatus = "Error Retrieving Remote Data";
                }
                break;
        }

     }   

    /*
        Exposed Interface
    */
    var _interface = {

        /*
            Public Properties
        */
        version: VERSION,

        // transaction method GET||POST
        sendMethod: "GET",

        // async true||false
        isAsync: true,

        // response received as text
        responseText: "",

        // response received as xml
        responseXML: "",

        // text of transaction status
        transactionStatus: "",

        // error true||false
        isError: false,

        // error details delimited by pipe
        errorDetail: "",

        /*
            Public Events for Binding
        */
        
        // delegate fires when requests are in process
        onProcessing: null,   
        
        // delegate fires when request is complete
        onCompletion: null,
        
        
        /*
            Public Methods
        */

        /**
        *   Method:         addParameter
        *   Description:    encodes value, concats name/value to
        *                   parameters
        *   Parameters:     name_in     name
        *                   value_in    value
        *   Returns:        n/a
        */
        addParameter: function (name_in, value_in) {
            _parameterData += "&";
            _parameterData += name_in + "=" + encodeURIComponent(value_in);
        }
        ,       
        /**
        *   Method:         addParametersRaw
        *   Description:    encodes values in string of name/value
        *                   pairs, appends to parameters
        *   Parameters:     vars_in     string of one or more name/value
        *                   pairs
        *   Returns:        n/a
        */
        addParametersRaw: function (vars_in) {
            _parameterData += "&";
            _parameterData += _encodeVars(vars_in);
        }
        ,
        /**
        *   Method:         addURL
        *   Description:    creates qualified url, assigns protocol
        *                   value based on optional third argument 
        *   Parameters:     url_path    path (example: www.xyz.com/abc)
        *                   url_file    file
        *                   is_ssl      (optional; defaults to false)
        *                               true||false (will convert to
        *                               https||http
        *   Returns:        n/a
        */
        addURL: function (url_path, url_file) {
            _requestPath = url_path;
            
            // if user didn't append slash for path, do it
            if (_requestPath.substr(_requestPath.length - 1) !== "/") {
                _requestPath += "/";
            }
            
            _requestFile = url_file;
            
            // if optional is_ssl argument is passed
            if (arguments.length === 3) {
                // assign protocol value based on is_ssl
                _sendProtocol = (arguments[2] === false ? "http" : "https");
            }
            
            return true;
        }
        ,
        /**
        *   Method:         sendRequest
        *   Description:    transmits data via GET/POST requests
        *   Parameters:     n/a
        *   Returns:        n/a
        *   
        *   Notes:          "Host" header used for proxy servers
        */
        sendRequest: function () { 
        
            // create connection object
            try {
                _that = this;
                _createXHR();
            } 
            catch (e) {
               this.isError = true;
               this.errorDetail += "Create XHR: " + e.message + "|";
            }    

            // process data to send
            if (_xhr !== null) {
            
                // don't allow caching
                var build_uri = _sendProtocol
                                + "://" 
                                + _requestPath
                                + _requestFile
                                + "?" 
                                + "no_cache=" + (Math.random() * 99999);
                
                switch (this.sendMethod) {
                    case "POST":
                        try {
                            _xhr.open(this.sendMethod, build_uri, this.isAsync);
                            _xhr.setRequestHeader("Host", _requestPath.split("/")[0]);
                            _xhr.setRequestHeader("User-Agent", "Swingjax");
                            _xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
                            _xhr.setRequestHeader("Content-Length", _parameterData.length);
                        } 
                        catch (e) {
                            this.isError = true;
                            this.errorDetail += "Open Conn/Set Headers (POST): " + e.message + "|";
                        }
                        break;
                    case "GET":
                        try {
                            _xhr.open(this.sendMethod, build_uri + _parameterData, this.isAsync);
                            _xhr.setRequestHeader("Host", _requestPath.split("/")[0]);
                            _xhr.setRequestHeader("User-Agent", "Swingjax");
                            _xhr.setRequestHeader("Pragma", "no-cache");
                            _xhr.setRequestHeader("Cache-Control", "no-cache");
                            _xhr.setRequestHeader("Content-Type", "text/html");
                            _parameterData = null; 
                        }
                        catch (e) {
                            this.isError = true;
                            this.errorDetail += "Open Conn/Set Headers (GET): " + e.message + "|";
                        }
                        break;
                    default:
                        this.isError = true;
                        this.errorDetail += "Method Unset: " + e.message + "|"; 
                }
                
                // sending request
                try {
                    _xhr.onreadystatechange = _responseCallback;
                    _xhr.send(_parameterData);
                } 
                catch (e) {
                    this.isError = true;
                    this.errorDetail += "Send Request: " + e.message + "|";
                }
            }
        }

    };
    
    return  _interface;
})();