Not only does it pass the default JSLint settings, it also no longer leaks *any*...
[jquery.git] / ajax / ajax.js
1 // AJAX Plugin
2 // Docs Here:
3 // http://jquery.com/docs/ajax/
4
5 if ( typeof XMLHttpRequest == 'undefined' && typeof window.ActiveXObject == 'function') {
6         XMLHttpRequest = function() {
7                 return new ActiveXObject((navigator.userAgent.toLowerCase().indexOf('msie 5') >= 0) ?
8                         "Microsoft.XMLHTTP" : "Msxml2.XMLHTTP");
9         };
10 }
11
12 //
13 // Counter for holding the active query's
14 $.xmlActive=0;
15
16 $.xml = function( type, url, data, ret ) {
17         var xml = new XMLHttpRequest();
18
19         if ( xml ) {
20                 //
21                 // Increase the query counter
22                 $.xmlActive++;
23
24                 //
25                 // Show loader if needed
26                 if ($.xmlCreate) {
27                         $.xmlCreate();
28                 }
29
30                 //
31                 // Open the socket
32                 xml.open(type || "GET", url, true);
33
34                 if ( data ) {
35                         xml.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
36                 }
37
38                 //
39                 // Set header so calling script knows that it's an XMLHttpRequest
40                 xml.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
41
42                 /* Force "Connection: close" for Mozilla browsers to work around
43                  * a bug where XMLHttpReqeuest sends an incorrect Content-length
44                  * header. See Mozilla Bugzilla #246651.
45                  */
46                 if ( xml.overrideMimeType ) {
47                         xml.setRequestHeader('Connection', 'close');
48                 }
49
50                 xml.onreadystatechange = function() {
51                         if ( xml.readyState == 4 ) {
52                                 if ( ret ) { ret(xml); }
53
54                                 //
55                                 // Decrease counter
56                                 $.xmlActive--;
57
58                                 //
59                                 // Hide loader if needed
60                                 if ($.xmlActive <= 0) {
61                                         if ($.xmlDestroy) {
62                                                 $.xmlDestroy();
63                                         }
64                                 }
65                         }
66                 };
67
68                 xml.send(data);
69         }
70 };
71
72 $.httpData = function(r,type) {
73         return r.getResponseHeader("content-type").indexOf("xml") > 0 || type == "xml" ?
74                 r.responseXML : r.responseText;
75 };
76
77 $.get = function( url, ret, type ) {
78         $.xml( "GET", url, null, function(r) {
79                 if ( ret ) { ret( $.httpData(r,type) ); }
80         });
81 };
82
83 $.getXML = function( url, ret ) {
84         $.get( url, ret, "xml" );
85 };
86
87 $.post = function( url, data, ret, type ) {
88         $.xml( "POST", url, $.param(data), function(r) {
89                 if ( ret ) { ret( $.httpData(r,type) ); }
90         });
91 };
92
93 $.postXML = function( url, data, ret ) {
94         $.post( url, data, ret, "xml" );
95 };
96
97 $.param = function(a) {
98         var s = [];
99         if (a && typeof a == 'object' && a.constructor == Array) {
100                 for ( var i=0; i < a.length; i++ ) {
101                         s[s.length] = a[i].name + "=" + encodeURIComponent( a[i].value );
102                 }
103         } else {
104                 for ( var j in a ) {
105                         s[s.length] = j + "=" + encodeURIComponent( a[j] );
106                 }
107         }
108         return s.join("&");
109 };
110
111 $.fn.load = function(a,o,f) {
112         // Arrrrghhhhhhhh!!
113         // I overwrote the event plugin's .load
114         // this won't happen again, I hope -John
115         if ( a && a.constructor == Function ) {
116                 return this.bind("load", a);
117         }
118
119         var t = "GET";
120         if ( o && o.constructor == Function ) {
121                 f = o;
122                 o = null;
123         }
124         if (o !== null) {
125                 o = $.param(o);
126                 t = "POST";
127         }
128         var self = this;
129         $.xml(t,a,o,function(h){
130                 h = h.responseText;
131                 self.html(h).find("script").each(function(){
132                         try {
133                                 $.eval( this.text || this.textContent || this.innerHTML );
134                         } catch(e){}
135                 });
136                 if(f){f(h);}
137         });
138         return this;
139 };
140
141 /**
142  * function:    $.fn.formValues
143  * usage:               $('#frmLogin').formValues()
144  * docs:                        Gets the form values and creates a key=>value array of the found values (only for ENABLED elements!)
145  */
146 $.fn.formValues = function() {
147         var a = [];
148         this.find("input[@type='submit'],input[@type='hidden'],textarea,input[@checked],input[@type='password'],input[@type='text'],option[@selected]").filter(":enabled").each(function() {
149                         var o = {};
150                         o.name = this.name || this.id || this.parentNode.name || this.parentNode.id;
151                         o.value = this.value;
152                         a.push(o);
153                 });
154         return a;
155 };
156
157 /**
158  * function:    $.update
159  * usage:               $.update('someJQueryObject', 'someurl', 'array');
160  * docs:                        Mimics the ajaxUpdater from prototype. Posts the key=>value array to the url and
161  *                                      puts the results from that call in the jQuery object specified.
162  *                                      --> If you set the blnNoEval to true, the script tags are NOT evaluated.
163  */
164 $.update = function(objElement, strURL, arrValues, fncCallback) {
165         $.post(strURL, arrValues, function(strHTML) {
166                 //
167                 // Update the element with the new HTML
168                 objElement.html(strHTML);
169
170                 //
171                 // Evaluate the scripts
172                 objElement.html(strHTML).find("script").each(function(){
173                         try { $.eval( this.text || this.textContent || this.innerHTML ); } catch(e){}
174                 });
175
176                 //
177                 // Callback handler
178                 if (fncCallback) { fncCallback(); }
179         });
180 };