]> git.wh0rd.org - tt-rss.git/blob - lib/dojo/request/iframe.js.uncompressed.js
upgrade dojo to 1.8.3 (refs #570)
[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 });