]> git.pond.sub.org Git - eow/blob - static/dojo-release-1.1.1/dojo/io/iframe.js
add Dojo 1.1.1
[eow] / static / dojo-release-1.1.1 / dojo / io / iframe.js
1 if(!dojo._hasResource["dojo.io.iframe"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
2 dojo._hasResource["dojo.io.iframe"] = true;
3 dojo.provide("dojo.io.iframe");
4
5 dojo.io.iframe = {
6         create: function(/*String*/fname, /*String*/onloadstr, /*String?*/uri){
7                 //      summary:
8                 //              Creates a hidden iframe in the page. Used mostly for IO
9                 //              transports.  You do not need to call this to start a
10                 //              dojo.io.iframe request. Just call send().
11                 //      fname: String
12                 //              The name of the iframe. Used for the name attribute on the
13                 //              iframe.
14                 //      onloadstr: String
15                 //              A string of JavaScript that will be executed when the content
16                 //              in the iframe loads.
17                 //      uri: String
18                 //              The value of the src attribute on the iframe element. If a
19                 //              value is not given, then dojo/resources/blank.html will be
20                 //              used.
21                 if(window[fname]){ return window[fname]; }
22                 if(window.frames[fname]){ return window.frames[fname]; }
23                 var cframe = null;
24                 var turi = uri;
25                 if(!turi){
26                         if(dojo.config["useXDomain"] && !dojo.config["dojoBlankHtmlUrl"]){
27                                 console.debug("dojo.io.iframe.create: When using cross-domain Dojo builds,"
28                                         + " please save dojo/resources/blank.html to your domain and set djConfig.dojoBlankHtmlUrl"
29                                         + " to the path on your domain to blank.html");
30                         }
31                         turi = (dojo.config["dojoBlankHtmlUrl"]||dojo.moduleUrl("dojo", "resources/blank.html"));
32                 }
33                 var ifrstr = dojo.isIE ? '<iframe name="'+fname+'" src="'+turi+'" onload="'+onloadstr+'">' : 'iframe';
34                 cframe = dojo.doc.createElement(ifrstr);
35                 with(cframe){
36                         name = fname;
37                         setAttribute("name", fname);
38                         id = fname;
39                 }
40                 dojo.body().appendChild(cframe);
41                 window[fname] = cframe;
42         
43                 with(cframe.style){
44                         if(dojo.isSafari < 3){
45                                 //We can't change the src in Safari 2.0.3 if absolute position. Bizarro.
46                                 position = "absolute";
47                         }
48                         left = top = "1px";
49                         height = width = "1px";
50                         visibility = "hidden";
51                 }
52
53                 if(!dojo.isIE){
54                         this.setSrc(cframe, turi, true);
55                         cframe.onload = new Function(onloadstr);
56                 }
57
58                 return cframe;
59         },
60
61         setSrc: function(/*DOMNode*/iframe, /*String*/src, /*Boolean*/replace){
62                 //summary:
63                 //              Sets the URL that is loaded in an IFrame. The replace parameter
64                 //              indicates whether location.replace() should be used when
65                 //              changing the location of the iframe.
66                 try{
67                         if(!replace){
68                                 if(dojo.isSafari){
69                                         iframe.location = src;
70                                 }else{
71                                         frames[iframe.name].location = src;
72                                 }
73                         }else{
74                                 // Fun with DOM 0 incompatibilities!
75                                 var idoc;
76                                 if(dojo.isIE || dojo.isSafari > 2){
77                                         idoc = iframe.contentWindow.document;
78                                 }else if(dojo.isSafari){
79                                         idoc = iframe.document;
80                                 }else{ //  if(d.isMozilla){
81                                         idoc = iframe.contentWindow;
82                                 }
83         
84                                 //For Safari (at least 2.0.3) and Opera, if the iframe
85                                 //has just been created but it doesn't have content
86                                 //yet, then iframe.document may be null. In that case,
87                                 //use iframe.location and return.
88                                 if(!idoc){
89                                         iframe.location = src;
90                                         return;
91                                 }else{
92                                         idoc.location.replace(src);
93                                 }
94                         }
95                 }catch(e){ 
96                         console.debug("dojo.io.iframe.setSrc: ", e); 
97                 }
98         },
99
100         doc: function(/*DOMNode*/iframeNode){
101                 //summary: Returns the document object associated with the iframe DOM Node argument.
102                 var doc = iframeNode.contentDocument || // W3
103                         (
104                                 (
105                                         (iframeNode.name) && (iframeNode.document) && 
106                                         (document.getElementsByTagName("iframe")[iframeNode.name].contentWindow) &&
107                                         (document.getElementsByTagName("iframe")[iframeNode.name].contentWindow.document)
108                                 )
109                         ) ||  // IE
110                         (
111                                 (iframeNode.name)&&(document.frames[iframeNode.name])&&
112                                 (document.frames[iframeNode.name].document)
113                         ) || null;
114                 return doc;
115         },
116
117         /*=====
118         dojo.io.iframe.__ioArgs = function(kwArgs){
119                 //      summary:
120                 //              All the properties described in the dojo.__ioArgs type, apply
121                 //              to this type. The following additional properties are allowed
122                 //              for dojo.io.iframe.send():
123                 //      method: String?
124                 //              The HTTP method to use. "GET" or "POST" are the only supported
125                 //              values.  It will try to read the value from the form node's
126                 //              method, then try this argument. If neither one exists, then it
127                 //              defaults to POST.
128                 //      handleAs: String?
129                 //              Specifies what format the result data should be given to the
130                 //              load/handle callback. Valid values are: text, html, javascript,
131                 //              json. IMPORTANT: For all values EXCEPT html, The server
132                 //              response should be an HTML file with a textarea element. The
133                 //              response data should be inside the textarea element. Using an
134                 //              HTML document the only reliable, cross-browser way this
135                 //              transport can know when the response has loaded. For the html
136                 //              handleAs value, just return a normal HTML document.  NOTE: xml
137                 //              or any other XML type is NOT supported by this transport.
138                 //      content: Object?
139                 //              If "form" is one of the other args properties, then the content
140                 //              object properties become hidden form form elements. For
141                 //              instance, a content object of {name1 : "value1"} is converted
142                 //              to a hidden form element with a name of "name1" and a value of
143                 //              "value1". If there is not a "form" property, then the content
144                 //              object is converted into a name=value&name=value string, by
145                 //              using dojo.objectToQuery().
146         }
147         =====*/
148
149         send: function(/*dojo.io.iframe.__ioArgs*/args){
150                 //summary: function that sends the request to the server.
151                 //This transport can only process one send() request at a time, so if send() is called
152                 //multiple times, it will queue up the calls and only process one at a time.
153                 if(!this["_frame"]){
154                         this._frame = this.create(this._iframeName, dojo._scopeName + ".io.iframe._iframeOnload();");
155                 }
156
157                 //Set up the deferred.
158                 var dfd = dojo._ioSetArgs(
159                         args,
160                         function(/*Deferred*/dfd){
161                                 //summary: canceller function for dojo._ioSetArgs call.
162                                 dfd.canceled = true;
163                                 dfd.ioArgs._callNext();
164                         },
165                         function(/*Deferred*/dfd){
166                                 //summary: okHandler function for dojo._ioSetArgs call.
167                                 var value = null;
168                                 try{
169                                         var ioArgs = dfd.ioArgs;
170                                         var dii = dojo.io.iframe;
171                                         var ifd = dii.doc(dii._frame);
172                                         var handleAs = ioArgs.handleAs;
173
174                                         //Assign correct value based on handleAs value.
175                                         value = ifd; //html
176                                         if(handleAs != "html"){
177                                                 value = ifd.getElementsByTagName("textarea")[0].value; //text
178                                                 if(handleAs == "json"){
179                                                         value = dojo.fromJson(value); //json
180                                                 }else if(handleAs == "javascript"){
181                                                         value = dojo.eval(value); //javascript
182                                                 }
183                                         }
184                                 }catch(e){
185                                         value = e;
186                                 }finally{
187                                         ioArgs._callNext();                             
188                                 }
189                                 return value;
190                         },
191                         function(/*Error*/error, /*Deferred*/dfd){
192                                 //summary: errHandler function for dojo._ioSetArgs call.
193                                 dfd.ioArgs._hasError = true;
194                                 dfd.ioArgs._callNext();
195                                 return error;
196                         }
197                 );
198
199                 //Set up a function that will fire the next iframe request. Make sure it only
200                 //happens once per deferred.
201                 dfd.ioArgs._callNext = function(){
202                         if(!this["_calledNext"]){
203                                 this._calledNext = true;
204                                 dojo.io.iframe._currentDfd = null;
205                                 dojo.io.iframe._fireNextRequest();
206                         }
207                 }
208
209                 this._dfdQueue.push(dfd);
210                 this._fireNextRequest();
211                 
212                 //Add it the IO watch queue, to get things like timeout support.
213                 dojo._ioWatch(
214                         dfd,
215                         function(/*Deferred*/dfd){
216                                 //validCheck
217                                 return !dfd.ioArgs["_hasError"];
218                         },
219                         function(dfd){
220                                 //ioCheck
221                                 return (!!dfd.ioArgs["_finished"]);
222                         },
223                         function(dfd){
224                                 //resHandle
225                                 if(dfd.ioArgs._finished){
226                                         dfd.callback(dfd);
227                                 }else{
228                                         dfd.errback(new Error("Invalid dojo.io.iframe request state"));
229                                 }
230                         }
231                 );
232
233                 return dfd;
234         },
235
236         _currentDfd: null,
237         _dfdQueue: [],
238         _iframeName: dojo._scopeName + "IoIframe",
239
240         _fireNextRequest: function(){
241                 //summary: Internal method used to fire the next request in the bind queue.
242                 try{
243                         if((this._currentDfd)||(this._dfdQueue.length == 0)){ return; }
244                         var dfd = this._currentDfd = this._dfdQueue.shift();
245                         var ioArgs = dfd.ioArgs;
246                         var args = ioArgs.args;
247
248                         ioArgs._contentToClean = [];
249                         var fn = dojo.byId(args["form"]);
250                         var content = args["content"] || {};
251                         if(fn){
252                                 if(content){
253                                         // if we have things in content, we need to add them to the form
254                                         // before submission
255                                         for(var x in content){
256                                                 if(!fn[x]){
257                                                         var tn;
258                                                         if(dojo.isIE){
259                                                                 tn = dojo.doc.createElement("<input type='hidden' name='"+x+"'>");
260                                                         }else{
261                                                                 tn = dojo.doc.createElement("input");
262                                                                 tn.type = "hidden";
263                                                                 tn.name = x;
264                                                         }
265                                                         tn.value = content[x];
266                                                         fn.appendChild(tn);
267                                                         ioArgs._contentToClean.push(x);
268                                                 }else{
269                                                         fn[x].value = content[x];
270                                                 }
271                                         }
272                                 }
273                                 //IE requires going through getAttributeNode instead of just getAttribute in some form cases, 
274                                 //so use it for all.  See #2844
275                                 var actnNode = fn.getAttributeNode("action");
276                                 var mthdNode = fn.getAttributeNode("method");
277                                 var trgtNode = fn.getAttributeNode("target");
278                                 if(args["url"]){
279                                         ioArgs._originalAction = actnNode ? actnNode.value : null;
280                                         if(actnNode){
281                                                 actnNode.value = args.url;
282                                         }else{
283                                                 fn.setAttribute("action",args.url);
284                                         }
285                                 }
286                                 if(!mthdNode || !mthdNode.value){
287                                         if(mthdNode){
288                                                 mthdNode.value= (args["method"]) ? args["method"] : "post";
289                                         }else{
290                                                 fn.setAttribute("method", (args["method"]) ? args["method"] : "post");
291                                         }
292                                 }
293                                 ioArgs._originalTarget = trgtNode ? trgtNode.value: null;
294                                 if(trgtNode){
295                                         trgtNode.value = this._iframeName;
296                                 }else{
297                                         fn.setAttribute("target", this._iframeName);
298                                 }
299                                 fn.target = this._iframeName;
300                                 fn.submit();
301                         }else{
302                                 // otherwise we post a GET string by changing URL location for the
303                                 // iframe
304                                 var tmpUrl = args.url + (args.url.indexOf("?") > -1 ? "&" : "?") + ioArgs.query;
305                                 this.setSrc(this._frame, tmpUrl, true);
306                         }
307                 }catch(e){
308                         dfd.errback(e);
309                 }
310         },
311
312         _iframeOnload: function(){
313                 var dfd = this._currentDfd;
314                 if(!dfd){
315                         this._fireNextRequest();
316                         return;
317                 }
318
319                 var ioArgs = dfd.ioArgs;
320                 var args = ioArgs.args;
321                 var fNode = dojo.byId(args.form);
322         
323                 if(fNode){
324                         // remove all the hidden content inputs
325                         var toClean = ioArgs._contentToClean;
326                         for(var i = 0; i < toClean.length; i++) {
327                                 var key = toClean[i];
328                                 if(dojo.isSafari < 3){
329                                         //In Safari (at least 2.0.3), can't use form[key] syntax to find the node,
330                                         //for nodes that were dynamically added.
331                                         for(var j = 0; j < fNode.childNodes.length; j++){
332                                                 var chNode = fNode.childNodes[j];
333                                                 if(chNode.name == key){
334                                                         dojo._destroyElement(chNode);
335                                                         break;
336                                                 }
337                                         }
338                                 }else{
339                                         dojo._destroyElement(fNode[key]);
340                                         fNode[key] = null;
341                                 }
342                         }
343         
344                         // restore original action + target
345                         if(ioArgs["_originalAction"]){
346                                 fNode.setAttribute("action", ioArgs._originalAction);
347                         }
348                         if(ioArgs["_originalTarget"]){
349                                 fNode.setAttribute("target", ioArgs._originalTarget);
350                                 fNode.target = ioArgs._originalTarget;
351                         }
352                 }
353
354                 ioArgs._finished = true;
355         }
356 }
357
358 }