diff options
author | Richard Beales <[email protected]> | 2013-03-18 07:32:01 +0000 |
---|---|---|
committer | Richard Beales <[email protected]> | 2013-03-18 07:32:01 +0000 |
commit | 7c97d17aaf373339a8bcd917ad59ca6018148f0d (patch) | |
tree | 5a3c04f0f9529be392c1263d3feb75806eb43797 /lib/dojo/request/iframe.js.uncompressed.js | |
parent | 70db7424e7068701e60cc5bcdfe8f858be508179 (diff) | |
parent | c670a80ddd9b03bd4ea6d940a9ed682fd26248d7 (diff) |
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'lib/dojo/request/iframe.js.uncompressed.js')
-rw-r--r-- | lib/dojo/request/iframe.js.uncompressed.js | 430 |
1 files changed, 430 insertions, 0 deletions
diff --git a/lib/dojo/request/iframe.js.uncompressed.js b/lib/dojo/request/iframe.js.uncompressed.js new file mode 100644 index 000000000..aee6b0c4d --- /dev/null +++ b/lib/dojo/request/iframe.js.uncompressed.js @@ -0,0 +1,430 @@ +define("dojo/request/iframe", [ + 'module', + 'require', + './watch', + './util', + './handlers', + '../_base/lang', + '../io-query', + '../query', + '../has', + '../dom', + '../dom-construct', + '../_base/window'/*=====, + '../request', + '../_base/declare' =====*/ +], function(module, require, watch, util, handlers, lang, ioQuery, query, has, dom, domConstruct, win/*=====, request, declare =====*/){ + var mid = module.id.replace(/[\/\.\-]/g, '_'), + onload = mid + '_onload'; + + if(!win.global[onload]){ + win.global[onload] = function(){ + var dfd = iframe._currentDfd; + if(!dfd){ + iframe._fireNextRequest(); + return; + } + + var response = dfd.response, + options = response.options, + formNode = dom.byId(options.form) || dfd._tmpForm; + + if(formNode){ + // remove all the hidden content inputs + var toClean = dfd._contentToClean; + for(var i=0; i<toClean.length; i++){ + var key = toClean[i]; + //Need to cycle over all nodes since we may have added + //an array value which means that more than one node could + //have the same .name value. + for(var j=0; j<formNode.childNodes.length; j++){ + var childNode = formNode.childNodes[j]; + if(childNode.name === key){ + domConstruct.destroy(childNode); + break; + } + } + } + + // restore original action + target + dfd._originalAction && formNode.setAttribute('action', dfd._originalAction); + if(dfd._originalMethod){ + formNode.setAttribute('method', dfd._originalMethod); + formNode.method = dfd._originalMethod; + } + if(dfd._originalTarget){ + formNode.setAttribute('target', dfd._originalTarget); + formNode.target = dfd._originalTarget; + } + } + + if(dfd._tmpForm){ + domConstruct.destroy(dfd._tmpForm); + delete dfd._tmpForm; + } + + dfd._finished = true; + }; + } + + function create(name, onloadstr, uri){ + if(win.global[name]){ + return win.global[name]; + } + + if(win.global.frames[name]){ + return win.global.frames[name]; + } + + if(!uri){ + if(has('config-useXDomain') && !has('config-dojoBlankHtmlUrl')){ + console.warn('dojo/request/iframe: When using cross-domain Dojo builds,' + + ' please save dojo/resources/blank.html to your domain and set dojoConfig.dojoBlankHtmlUrl' + + ' to the path on your domain to blank.html'); + } + uri = (has('config-dojoBlankHtmlUrl')||require.toUrl('dojo/resources/blank.html')); + } + + var frame = domConstruct.place( + '<iframe id="'+name+'" name="'+name+'" src="'+uri+'" onload="'+onloadstr+ + '" style="position: absolute; left: 1px; top: 1px; height: 1px; width: 1px; visibility: hidden">', + win.body()); + + win.global[name] = frame; + + return frame; + } + + function setSrc(_iframe, src, replace){ + var frame = win.global.frames[_iframe.name]; + + if(frame.contentWindow){ + // We have an iframe node instead of the window + frame = frame.contentWindow; + } + + try{ + if(!replace){ + frame.location = src; + }else{ + frame.location.replace(src); + } + }catch(e){ + console.log('dojo/request/iframe.setSrc: ', e); + } + } + + function doc(iframeNode){ + if(iframeNode.contentDocument){ + return iframeNode.contentDocument; + } + var name = iframeNode.name; + if(name){ + var iframes = win.doc.getElementsByTagName('iframe'); + if(iframeNode.document && iframes[name].contentWindow && iframes[name].contentWindow.document){ + return iframes[name].contentWindow.document; + }else if(win.doc.frames[name] && win.doc.frames[name].document){ + return win.doc.frames[name].document; + } + } + return null; + } + + function createForm(){ + return domConstruct.create('form', { + name: mid + '_form', + style: { + position: 'absolute', + top: '-1000px', + left: '-1000px' + } + }, win.body()); + } + + function fireNextRequest(){ + // summary: + // Internal method used to fire the next request in the queue. + var dfd; + try{ + if(iframe._currentDfd || !iframe._dfdQueue.length){ + return; + } + do{ + dfd = iframe._currentDfd = iframe._dfdQueue.shift(); + }while(dfd && (dfd.canceled || (dfd.isCanceled && dfd.isCanceled())) && iframe._dfdQueue.length); + + if(!dfd || dfd.canceled || (dfd.isCanceled && dfd.isCanceled())){ + iframe._currentDfd = null; + return; + } + + var response = dfd.response, + options = response.options, + c2c = dfd._contentToClean = [], + formNode = dom.byId(options.form), + notify = util.notify, + data = options.data || null, + queryStr; + + if(!dfd._legacy && options.method === 'POST' && !formNode){ + formNode = dfd._tmpForm = createForm(); + }else if(options.method === 'GET' && formNode && response.url.indexOf('?') > -1){ + queryStr = response.url.slice(response.url.indexOf('?') + 1); + data = lang.mixin(ioQuery.queryToObject(queryStr), data); + } + + if(formNode){ + if(!dfd._legacy){ + var parentNode = formNode; + do{ + parentNode = parentNode.parentNode; + }while(parentNode !== win.doc.documentElement); + + // Append the form node or some browsers won't work + if(!parentNode){ + formNode.style.position = 'absolute'; + formNode.style.left = '-1000px'; + formNode.style.top = '-1000px'; + win.body().appendChild(formNode); + } + + if(!formNode.name){ + formNode.name = mid + '_form'; + } + } + + // if we have things in data, we need to add them to the form + // before submission + if(data){ + var createInput = function(name, value){ + domConstruct.create('input', { + type: 'hidden', + name: name, + value: value + }, formNode); + c2c.push(name); + }; + for(var x in data){ + var val = data[x]; + if(lang.isArray(val) && val.length > 1){ + for(var i=0; i<val.length; i++){ + createInput(x, val[i]); + } + }else{ + if(!formNode[x]){ + createInput(x, val); + }else{ + formNode[x].value = val; + } + } + } + } + + //IE requires going through getAttributeNode instead of just getAttribute in some form cases, + //so use it for all. See #2844 + var actionNode = formNode.getAttributeNode('action'), + methodNode = formNode.getAttributeNode('method'), + targetNode = formNode.getAttributeNode('target'); + + if(response.url){ + dfd._originalAction = actionNode ? actionNode.value : null; + if(actionNode){ + actionNode.value = response.url; + }else{ + formNode.setAttribute('action', response.url); + } + } + + if(!dfd._legacy){ + dfd._originalMethod = methodNode ? methodNode.value : null; + if(methodNode){ + methodNode.value = options.method; + }else{ + formNode.setAttribute('method', options.method); + } + }else{ + if(!methodNode || !methodNode.value){ + if(mthdNode){ + mthdNode.value = options.method; + }else{ + fn.setAttribute("method", options.method); + } + } + } + + dfd._originalTarget = targetNode ? targetNode.value : null; + if(targetNode){ + targetNode.value = iframe._iframeName; + }else{ + formNode.setAttribute('target', iframe._iframeName); + } + formNode.target = iframe._iframeName; + + notify && notify.emit('send', response, dfd.promise.cancel); + iframe._notifyStart(response); + formNode.submit(); + }else{ + // otherwise we post a GET string by changing URL location for the + // iframe + + var extra = ''; + if(response.options.data){ + extra = response.options.data; + if(typeof extra !== 'string'){ + extra = ioQuery.objectToQuery(extra); + } + } + var tmpUrl = response.url + (response.url.indexOf('?') > -1 ? '&' : '?') + extra; + notify && notify.emit('send', response, dfd.promise.cancel); + iframe._notifyStart(response); + iframe.setSrc(iframe._frame, tmpUrl, true); + } + }catch(e){ + dfd.reject(e); + } + } + + // dojo/request/watch handlers + function isValid(response){ + return !this.isFulfilled(); + } + function isReady(response){ + return !!this._finished; + } + function handleResponse(response, error){ + if(!error){ + try{ + var options = response.options, + doc = iframe.doc(iframe._frame), + handleAs = options.handleAs; + + if(handleAs !== 'html'){ + if(handleAs === 'xml'){ + // IE6-8 have to parse the XML manually. See http://bugs.dojotoolkit.org/ticket/6334 + if(doc.documentElement.tagName.toLowerCase() === 'html'){ + query('a', doc.documentElement).orphan(); + var xmlText = doc.documentElement.innerText; + xmlText = xmlText.replace(/>\s+</g, '><'); + response.text = lang.trim(xmlText); + }else{ + response.data = doc; + } + }else{ + // 'json' and 'javascript' and 'text' + response.text = doc.getElementsByTagName('textarea')[0].value; // text + } + handlers(response); + }else{ + response.data = doc; + } + }catch(e){ + error = e; + } + } + + if(error){ + this.reject(error); + }else if(this._finished){ + this.resolve(response); + }else{ + this.reject(new Error('Invalid dojo/request/iframe request state')); + } + } + function last(response){ + this._callNext(); + } + + var defaultOptions = { + method: 'POST' + }; + function iframe(url, options, returnDeferred){ + var response = util.parseArgs(url, util.deepCreate(defaultOptions, options), true); + url = response.url; + options = response.options; + + if(options.method !== 'GET' && options.method !== 'POST'){ + throw new Error(options.method + ' not supported by dojo/request/iframe'); + } + + if(!iframe._frame){ + iframe._frame = iframe.create(iframe._iframeName, onload + '();'); + } + + var dfd = util.deferred(response, null, isValid, isReady, handleResponse, last); + dfd._callNext = function(){ + if(!this._calledNext){ + this._calledNext = true; + iframe._currentDfd = null; + iframe._fireNextRequest(); + } + }; + dfd._legacy = returnDeferred; + + iframe._dfdQueue.push(dfd); + iframe._fireNextRequest(); + + watch(dfd); + + return returnDeferred ? dfd : dfd.promise; + } + + /*===== + iframe = function(url, options){ + // summary: + // Sends a request using an iframe element with the given URL and options. + // url: String + // URL to request + // options: dojo/request/iframe.__Options? + // Options for the request. + // returns: dojo/request.__Promise + }; + iframe.__BaseOptions = declare(request.__BaseOptions, { + // form: DOMNode? + // A form node to use to submit data to the server. + // data: String|Object? + // Data to transfer. When making a GET request, this will + // be converted to key=value parameters and appended to the + // URL. + }); + iframe.__MethodOptions = declare(null, { + // method: String? + // The HTTP method to use to make the request. Must be + // uppercase. Only `"GET"` and `"POST"` are accepted. + // Default is `"POST"`. + }); + iframe.__Options = declare([iframe.__BaseOptions, iframe.__MethodOptions]); + + iframe.get = function(url, options){ + // summary: + // Send an HTTP GET request using an iframe element with the given URL and options. + // url: String + // URL to request + // options: dojo/request/iframe.__BaseOptions? + // Options for the request. + // returns: dojo/request.__Promise + }; + iframe.post = function(url, options){ + // summary: + // Send an HTTP POST request using an iframe element with the given URL and options. + // url: String + // URL to request + // options: dojo/request/iframe.__BaseOptions? + // Options for the request. + // returns: dojo/request.__Promise + }; + =====*/ + iframe.create = create; + iframe.doc = doc; + iframe.setSrc = setSrc; + + // TODO: Make these truly private in 2.0 + iframe._iframeName = mid + '_IoIframe'; + iframe._notifyStart = function(){}; + iframe._dfdQueue = []; + iframe._currentDfd = null; + iframe._fireNextRequest = fireNextRequest; + + util.addCommonMethods(iframe, ['GET', 'POST']); + + return iframe; +}); |