]> git.wh0rd.org Git - tt-rss.git/blob - lib/dojo/request/iframe.js.uncompressed.js
aee6b0c4df125bf99e9c2c325087b7da3b3bbbae
[tt-rss.git] / lib / dojo / request / iframe.js.uncompressed.js
1 define("dojo/request/iframe", [
2         'module',
3         'require',
4         './watch',
5         './util',
6         './handlers',
7         '../_base/lang',
8         '../io-query',
9         '../query',
10         '../has',
11         '../dom',
12         '../dom-construct',
13         '../_base/window'/*=====,
14         '../request',
15         '../_base/declare' =====*/
16 ], function(module, require, watch, util, handlers, lang, ioQuery, query, has, dom, domConstruct, win/*=====, request, declare =====*/){
17         var mid = module.id.replace(/[\/\.\-]/g, '_'),
18                 onload = mid + '_onload';
19
20         if(!win.global[onload]){
21                 win.global[onload] = function(){
22                         var dfd = iframe._currentDfd;
23                         if(!dfd){
24                                 iframe._fireNextRequest();
25                                 return;
26                         }
27
28                         var response = dfd.response,
29                                 options = response.options,
30                                 formNode = dom.byId(options.form) || dfd._tmpForm;
31
32                         if(formNode){
33                                 // remove all the hidden content inputs
34                                 var toClean = dfd._contentToClean;
35                                 for(var i=0; i<toClean.length; i++){
36                                         var key = toClean[i];
37                                         //Need to cycle over all nodes since we may have added
38                                         //an array value which means that more than one node could
39                                         //have the same .name value.
40                                         for(var j=0; j<formNode.childNodes.length; j++){
41                                                 var childNode = formNode.childNodes[j];
42                                                 if(childNode.name === key){
43                                                         domConstruct.destroy(childNode);
44                                                         break;
45                                                 }
46                                         }
47                                 }
48
49                                 // restore original action + target
50                                 dfd._originalAction && formNode.setAttribute('action', dfd._originalAction);
51                                 if(dfd._originalMethod){
52                                         formNode.setAttribute('method', dfd._originalMethod);
53                                         formNode.method = dfd._originalMethod;
54                                 }
55                                 if(dfd._originalTarget){
56                                         formNode.setAttribute('target', dfd._originalTarget);
57                                         formNode.target = dfd._originalTarget;
58                                 }
59                         }
60
61                         if(dfd._tmpForm){
62                                 domConstruct.destroy(dfd._tmpForm);
63                                 delete dfd._tmpForm;
64                         }
65
66                         dfd._finished = true;
67                 };
68         }
69
70         function create(name, onloadstr, uri){
71                 if(win.global[name]){
72                         return win.global[name];
73                 }
74
75                 if(win.global.frames[name]){
76                         return win.global.frames[name];
77                 }
78
79                 if(!uri){
80                         if(has('config-useXDomain') && !has('config-dojoBlankHtmlUrl')){
81                                 console.warn('dojo/request/iframe: When using cross-domain Dojo builds,' +
82                                         ' please save dojo/resources/blank.html to your domain and set dojoConfig.dojoBlankHtmlUrl' +
83                                         ' to the path on your domain to blank.html');
84                         }
85                         uri = (has('config-dojoBlankHtmlUrl')||require.toUrl('dojo/resources/blank.html'));
86                 }
87
88                 var frame = domConstruct.place(
89                         '<iframe id="'+name+'" name="'+name+'" src="'+uri+'" onload="'+onloadstr+
90                         '" style="position: absolute; left: 1px; top: 1px; height: 1px; width: 1px; visibility: hidden">',
91                         win.body());
92
93                 win.global[name] = frame;
94
95                 return frame;
96         }
97
98         function setSrc(_iframe, src, replace){
99                 var frame = win.global.frames[_iframe.name];
100
101                 if(frame.contentWindow){
102                         // We have an iframe node instead of the window
103                         frame = frame.contentWindow;
104                 }
105
106                 try{
107                         if(!replace){
108                                 frame.location = src;
109                         }else{
110                                 frame.location.replace(src);
111                         }
112                 }catch(e){
113                         console.log('dojo/request/iframe.setSrc: ', e);
114                 }
115         }
116
117         function doc(iframeNode){
118                 if(iframeNode.contentDocument){
119                         return iframeNode.contentDocument;
120                 }
121                 var name = iframeNode.name;
122                 if(name){
123                         var iframes = win.doc.getElementsByTagName('iframe');
124                         if(iframeNode.document && iframes[name].contentWindow && iframes[name].contentWindow.document){
125                                 return iframes[name].contentWindow.document;
126                         }else if(win.doc.frames[name] && win.doc.frames[name].document){
127                                 return win.doc.frames[name].document;
128                         }
129                 }
130                 return null;
131         }
132
133         function createForm(){
134                 return domConstruct.create('form', {
135                         name: mid + '_form',
136                         style: {
137                                 position: 'absolute',
138                                 top: '-1000px',
139                                 left: '-1000px'
140                         }
141                 }, win.body());
142         }
143
144         function fireNextRequest(){
145                 // summary:
146                 //              Internal method used to fire the next request in the queue.
147                 var dfd;
148                 try{
149                         if(iframe._currentDfd || !iframe._dfdQueue.length){
150                                 return;
151                         }
152                         do{
153                                 dfd = iframe._currentDfd = iframe._dfdQueue.shift();
154                         }while(dfd && (dfd.canceled || (dfd.isCanceled && dfd.isCanceled())) && iframe._dfdQueue.length);
155
156                         if(!dfd || dfd.canceled || (dfd.isCanceled && dfd.isCanceled())){
157                                 iframe._currentDfd = null;
158                                 return;
159                         }
160
161                         var response = dfd.response,
162                                 options = response.options,
163                                 c2c = dfd._contentToClean = [],
164                                 formNode = dom.byId(options.form),
165                                 notify = util.notify,
166                                 data = options.data || null,
167                                 queryStr;
168
169                         if(!dfd._legacy && options.method === 'POST' && !formNode){
170                                 formNode = dfd._tmpForm = createForm();
171                         }else if(options.method === 'GET' && formNode && response.url.indexOf('?') > -1){
172                                 queryStr = response.url.slice(response.url.indexOf('?') + 1);
173                                 data = lang.mixin(ioQuery.queryToObject(queryStr), data);
174                         }
175
176                         if(formNode){
177                                 if(!dfd._legacy){
178                                         var parentNode = formNode;
179                                         do{
180                                                 parentNode = parentNode.parentNode;
181                                         }while(parentNode !== win.doc.documentElement);
182
183                                         // Append the form node or some browsers won't work
184                                         if(!parentNode){
185                                                 formNode.style.position = 'absolute';
186                                                 formNode.style.left = '-1000px';
187                                                 formNode.style.top = '-1000px';
188                                                 win.body().appendChild(formNode);
189                                         }
190
191                                         if(!formNode.name){
192                                                 formNode.name = mid + '_form';
193                                         }
194                                 }
195
196                                 // if we have things in data, we need to add them to the form
197                                 // before submission
198                                 if(data){
199                                         var createInput = function(name, value){
200                                                 domConstruct.create('input', {
201                                                         type: 'hidden',
202                                                         name: name,
203                                                         value: value
204                                                 }, formNode);
205                                                 c2c.push(name);
206                                         };
207                                         for(var x in data){
208                                                 var val = data[x];
209                                                 if(lang.isArray(val) && val.length > 1){
210                                                         for(var i=0; i<val.length; i++){
211                                                                 createInput(x, val[i]);
212                                                         }
213                                                 }else{
214                                                         if(!formNode[x]){
215                                                                 createInput(x, val);
216                                                         }else{
217                                                                 formNode[x].value = val;
218                                                         }
219                                                 }
220                                         }
221                                 }
222
223                                 //IE requires going through getAttributeNode instead of just getAttribute in some form cases,
224                                 //so use it for all.  See #2844
225                                 var actionNode = formNode.getAttributeNode('action'),
226                                         methodNode = formNode.getAttributeNode('method'),
227                                         targetNode = formNode.getAttributeNode('target');
228
229                                 if(response.url){
230                                         dfd._originalAction = actionNode ? actionNode.value : null;
231                                         if(actionNode){
232                                                 actionNode.value = response.url;
233                                         }else{
234                                                 formNode.setAttribute('action', response.url);
235                                         }
236                                 }
237
238                                 if(!dfd._legacy){
239                                         dfd._originalMethod = methodNode ? methodNode.value : null;
240                                         if(methodNode){
241                                                 methodNode.value = options.method;
242                                         }else{
243                                                 formNode.setAttribute('method', options.method);
244                                         }
245                                 }else{
246                                         if(!methodNode || !methodNode.value){
247                                                 if(mthdNode){
248                                                         mthdNode.value = options.method;
249                                                 }else{
250                                                         fn.setAttribute("method", options.method);
251                                                 }
252                                         }
253                                 }
254
255                                 dfd._originalTarget = targetNode ? targetNode.value : null;
256                                 if(targetNode){
257                                         targetNode.value = iframe._iframeName;
258                                 }else{
259                                         formNode.setAttribute('target', iframe._iframeName);
260                                 }
261                                 formNode.target = iframe._iframeName;
262
263                                 notify && notify.emit('send', response, dfd.promise.cancel);
264                                 iframe._notifyStart(response);
265                                 formNode.submit();
266                         }else{
267                                 // otherwise we post a GET string by changing URL location for the
268                                 // iframe
269
270                                 var extra = '';
271                                 if(response.options.data){
272                                         extra = response.options.data;
273                                         if(typeof extra !== 'string'){
274                                                 extra = ioQuery.objectToQuery(extra);
275                                         }
276                                 }
277                                 var tmpUrl = response.url + (response.url.indexOf('?') > -1 ? '&' : '?') + extra;
278                                 notify && notify.emit('send', response, dfd.promise.cancel);
279                                 iframe._notifyStart(response);
280                                 iframe.setSrc(iframe._frame, tmpUrl, true);
281                         }
282                 }catch(e){
283                         dfd.reject(e);
284                 }
285         }
286
287         // dojo/request/watch handlers
288         function isValid(response){
289                 return !this.isFulfilled();
290         }
291         function isReady(response){
292                 return !!this._finished;
293         }
294         function handleResponse(response, error){
295                 if(!error){
296                         try{
297                                 var options = response.options,
298                                         doc = iframe.doc(iframe._frame),
299                                         handleAs = options.handleAs;
300
301                                 if(handleAs !== 'html'){
302                                         if(handleAs === 'xml'){
303                                                 // IE6-8 have to parse the XML manually. See http://bugs.dojotoolkit.org/ticket/6334
304                                                 if(doc.documentElement.tagName.toLowerCase() === 'html'){
305                                                         query('a', doc.documentElement).orphan();
306                                                         var xmlText = doc.documentElement.innerText;
307                                                         xmlText = xmlText.replace(/>\s+</g, '><');
308                                                         response.text = lang.trim(xmlText);
309                                                 }else{
310                                                         response.data = doc;
311                                                 }
312                                         }else{
313                                                 // 'json' and 'javascript' and 'text'
314                                                 response.text = doc.getElementsByTagName('textarea')[0].value; // text
315                                         }
316                                         handlers(response);
317                                 }else{
318                                         response.data = doc;
319                                 }
320                         }catch(e){
321                                 error = e;
322                         }
323                 }
324
325                 if(error){
326                         this.reject(error);
327                 }else if(this._finished){
328                         this.resolve(response);
329                 }else{
330                         this.reject(new Error('Invalid dojo/request/iframe request state'));
331                 }
332         }
333         function last(response){
334                 this._callNext();
335         }
336
337         var defaultOptions = {
338                 method: 'POST'
339         };
340         function iframe(url, options, returnDeferred){
341                 var response = util.parseArgs(url, util.deepCreate(defaultOptions, options), true);
342                 url = response.url;
343                 options = response.options;
344
345                 if(options.method !== 'GET' && options.method !== 'POST'){
346                         throw new Error(options.method + ' not supported by dojo/request/iframe');
347                 }
348
349                 if(!iframe._frame){
350                         iframe._frame = iframe.create(iframe._iframeName, onload + '();');
351                 }
352
353                 var dfd = util.deferred(response, null, isValid, isReady, handleResponse, last);
354                 dfd._callNext = function(){
355                         if(!this._calledNext){
356                                 this._calledNext = true;
357                                 iframe._currentDfd = null;
358                                 iframe._fireNextRequest();
359                         }
360                 };
361                 dfd._legacy = returnDeferred;
362
363                 iframe._dfdQueue.push(dfd);
364                 iframe._fireNextRequest();
365
366                 watch(dfd);
367
368                 return returnDeferred ? dfd : dfd.promise;
369         }
370
371         /*=====
372         iframe = function(url, options){
373                 // summary:
374                 //              Sends a request using an iframe element with the given URL and options.
375                 // url: String
376                 //              URL to request
377                 // options: dojo/request/iframe.__Options?
378                 //              Options for the request.
379                 // returns: dojo/request.__Promise
380         };
381         iframe.__BaseOptions = declare(request.__BaseOptions, {
382                 // form: DOMNode?
383                 //              A form node to use to submit data to the server.
384                 // data: String|Object?
385                 //              Data to transfer. When making a GET request, this will
386                 //              be converted to key=value parameters and appended to the
387                 //              URL.
388         });
389         iframe.__MethodOptions = declare(null, {
390                 // method: String?
391                 //              The HTTP method to use to make the request. Must be
392                 //              uppercase. Only `"GET"` and `"POST"` are accepted.
393                 //              Default is `"POST"`.
394         });
395         iframe.__Options = declare([iframe.__BaseOptions, iframe.__MethodOptions]);
396
397         iframe.get = function(url, options){
398                 // summary:
399                 //              Send an HTTP GET request using an iframe element with the given URL and options.
400                 // url: String
401                 //              URL to request
402                 // options: dojo/request/iframe.__BaseOptions?
403                 //              Options for the request.
404                 // returns: dojo/request.__Promise
405         };
406         iframe.post = function(url, options){
407                 // summary:
408                 //              Send an HTTP POST request using an iframe element with the given URL and options.
409                 // url: String
410                 //              URL to request
411                 // options: dojo/request/iframe.__BaseOptions?
412                 //              Options for the request.
413                 // returns: dojo/request.__Promise
414         };
415         =====*/
416         iframe.create = create;
417         iframe.doc = doc;
418         iframe.setSrc = setSrc;
419
420         // TODO: Make these truly private in 2.0
421         iframe._iframeName = mid + '_IoIframe';
422         iframe._notifyStart = function(){};
423         iframe._dfdQueue = [];
424         iframe._currentDfd = null;
425         iframe._fireNextRequest = fireNextRequest;
426
427         util.addCommonMethods(iframe, ['GET', 'POST']);
428
429         return iframe;
430 });