📄 iframeio.js
字号:
/* Copyright (c) 2004-2006, The Dojo Foundation All Rights Reserved. Licensed under the Academic Free License version 2.1 or above OR the modified BSD license. For more information on Dojo licensing, see: http://dojotoolkit.org/community/licensing.shtml*/dojo.provide("dojo.io.IframeIO");dojo.require("dojo.io.BrowserIO");dojo.require("dojo.uri.*");// FIXME: is it possible to use the Google htmlfile hack to prevent the// background click with this transport?dojo.io.createIFrame = function(/*String*/fname, /*String*/onloadstr, /*String?*/uri){ //summary: Creates a hidden iframe in the page. Used mostly for data transports. //fname: String // The name of the iframe. Used for the name attribute on the iframe. //onloadstr: String // A string of Javascript that will be executed when the content in the iframe loads. //uri: String // The value of the src attribute on the iframe element. If a value is not // given, then iframe_history.html will be used. if(window[fname]){ return window[fname]; } if(window.frames[fname]){ return window.frames[fname]; } var r = dojo.render.html; var cframe = null; var turi = uri||dojo.uri.dojoUri("iframe_history.html?noInit=true"); var ifrstr = ((r.ie)&&(dojo.render.os.win)) ? '<iframe name="'+fname+'" src="'+turi+'" onload="'+onloadstr+'">' : 'iframe'; cframe = document.createElement(ifrstr); with(cframe){ name = fname; setAttribute("name", fname); id = fname; } dojo.body().appendChild(cframe); window[fname] = cframe; with(cframe.style){ if(!r.safari){ //We can't change the src in Safari 2.0.3 if absolute position. Bizarro. position = "absolute"; } left = top = "0px"; height = width = "1px"; visibility = "hidden"; /* if(djConfig.isDebug){ position = "relative"; height = "300px"; width = "600px"; visibility = "visible"; } */ } if(!r.ie){ dojo.io.setIFrameSrc(cframe, turi, true); cframe.onload = new Function(onloadstr); } return cframe;}dojo.io.IframeTransport = new function(){ //summary: The object that implements the dojo.io.bind transport that //uses an iframe to communicate to the server. var _this = this; this.currentRequest = null; this.requestQueue = []; this.iframeName = "dojoIoIframe"; this.fireNextRequest = function(){ //summary: Internal method used to fire the next request in the bind queue. try{ if((this.currentRequest)||(this.requestQueue.length == 0)){ return; } // dojo.debug("fireNextRequest"); var cr = this.currentRequest = this.requestQueue.shift(); cr._contentToClean = []; var fn = cr["formNode"]; var content = cr["content"] || {}; if(cr.sendTransport) { content["dojo.transport"] = "iframe"; } if(fn){ if(content){ // if we have things in content, we need to add them to the form // before submission for(var x in content){ if(!fn[x]){ var tn; if(dojo.render.html.ie){ tn = document.createElement("<input type='hidden' name='"+x+"' value='"+content[x]+"'>"); fn.appendChild(tn); }else{ tn = document.createElement("input"); fn.appendChild(tn); tn.type = "hidden"; tn.name = x; tn.value = content[x]; } cr._contentToClean.push(x); }else{ fn[x].value = content[x]; } } } if(cr["url"]){ cr._originalAction = fn.getAttribute("action"); fn.setAttribute("action", cr.url); } if(!fn.getAttribute("method")){ fn.setAttribute("method", (cr["method"]) ? cr["method"] : "post"); } cr._originalTarget = fn.getAttribute("target"); fn.setAttribute("target", this.iframeName); fn.target = this.iframeName; fn.submit(); }else{ // otherwise we post a GET string by changing URL location for the // iframe var query = dojo.io.argsFromMap(this.currentRequest.content); var tmpUrl = cr.url + (cr.url.indexOf("?") > -1 ? "&" : "?") + query; dojo.io.setIFrameSrc(this.iframe, tmpUrl, true); } }catch(e){ this.iframeOnload(e); } } this.canHandle = function(/*dojo.io.Request*/kwArgs){ //summary: Tells dojo.io.bind() if this is a good transport to //use for the particular type of request. //description: This type of transport cannot //handle text/xml or application/xml return types, is limited to GET //or POST requests, and cannot do synchronous binds. return ( ( dojo.lang.inArray([ "text/plain", "text/html", "text/javascript", "text/json", "application/json"], kwArgs["mimetype"]) )&&( dojo.lang.inArray(["post", "get"], kwArgs["method"].toLowerCase()) )&&( // never handle a sync request ! ((kwArgs["sync"])&&(kwArgs["sync"] == true)) ) ); //boolean } this.bind = function(/*dojo.io.Request*/kwArgs){ //summary: function that sends the request to the server. //This transport can only process one bind request at a time, so if bind is called //multiple times, it will queue up the calls and only process one at a time. //The following are acceptable properties in kwArgs (in addition to the //normal dojo.io.Request object properties). //url: String: URL the server URL to use for the request. //transport: String: specify "IframeTransport" to force the use of this transport. //sendTransport: boolean: If true, then dojo.transport=iframe will be added to the request. //formNode: DOMNode: a form element node. The form elements' names and values will be used in // the request. This makes it possible to upload files using this transport. //method: String: the HTTP method to use. Must be GET or POST. Default is POST. //mimetype: Specifies what format the result data should be given to the load/handle callback. Valid values are: // text/plain, text/html, text/javascript, text/json, application/json. IMPORTANT: For all values EXCEPT text/html, // The server response should be an HTML file with a textarea element. The response data should be inside the textarea // element. Using an HTML document the only reliable, cross-browser way this transport can know // when the response has loaded. For the text/html mimetype, just return a normal HTML document. //content: Object: If a formNode is one of the other kwArgs properties, then the content // object properties become hidden form form elements. For instance, a content // object of {name1 : "value1"} is converted to a hidden form element with a name // of "name1" and a value of "value1". If there is not a formNode property, then // the content object is converted into a name=value&name=value string, by // using dojo.io.argsFromMap(). No encoding is passed to that method, so the // names and values will be encoded using dojo.string.encodeAscii(). if(!this["iframe"]){ this.setUpIframe(); } this.requestQueue.push(kwArgs); this.fireNextRequest(); return; } this.setUpIframe = function(){ // NOTE: IE 5.0 and earlier Mozilla's don't support an onload event for // iframes. OTOH, we don't care. this.iframe = dojo.io.createIFrame(this.iframeName, "dojo.io.IframeTransport.iframeOnload();"); } this.iframeOnload = function(errorObject /* Object */){ if(!_this.currentRequest){ _this.fireNextRequest(); return; } var req = _this.currentRequest; if(req.formNode){ // remove all the hidden content inputs var toClean = req._contentToClean; for(var i = 0; i < toClean.length; i++) { var key = toClean[i]; if(dojo.render.html.safari){ //In Safari (at least 2.0.3), can't use formNode[key] syntax to find the node, //for nodes that were dynamically added. var fNode = req.formNode; for(var j = 0; j < fNode.childNodes.length; j++){ var chNode = fNode.childNodes[j]; if(chNode.name == key){ var pNode = chNode.parentNode; pNode.removeChild(chNode); break; } } }else{ var input = req.formNode[key]; req.formNode.removeChild(input); req.formNode[key] = null; } } // restore original action + target if(req["_originalAction"]){ req.formNode.setAttribute("action", req._originalAction); } if(req["_originalTarget"]){ req.formNode.setAttribute("target", req._originalTarget); req.formNode.target = req._originalTarget; } } var contentDoc = function(iframe_el){ var doc = iframe_el.contentDocument || // W3 ( (iframe_el.contentWindow)&&(iframe_el.contentWindow.document) ) || // IE ( (iframe_el.name)&&(document.frames[iframe_el.name])&& (document.frames[iframe_el.name].document) ) || null; return doc; }; var value; var success = false; if (errorObject){ this._callError(req, "IframeTransport Request Error: " + errorObject); }else{ var ifd = contentDoc(_this.iframe); // handle successful returns // FIXME: how do we determine success for iframes? Is there an equiv of // the "status" property? try{ var cmt = req.mimetype; if((cmt == "text/javascript")||(cmt == "text/json")||(cmt == "application/json")){ // FIXME: not sure what to do here? try to pull some evalulable // text from a textarea or cdata section? // how should we set up the contract for that? var js = ifd.getElementsByTagName("textarea")[0].value; if(cmt == "text/json" || cmt == "application/json") { js = "(" + js + ")"; } value = dj_eval(js); }else if(cmt == "text/html"){ value = ifd; }else{ // text/plain value = ifd.getElementsByTagName("textarea")[0].value; } success = true; }catch(e){ // looks like we didn't get what we wanted! this._callError(req, "IframeTransport Error: " + e); } } // don't want to mix load function errors with processing errors, thus // a separate try..catch try { if(success && dojo.lang.isFunction(req["load"])){ req.load("load", value, req); } } catch(e) { throw e; } finally { _this.currentRequest = null; _this.fireNextRequest(); } } this._callError = function(req /* Object */, message /* String */){ var errObj = new dojo.io.Error(message); if(dojo.lang.isFunction(req["error"])){ req.error("error", errObj, req); } } dojo.io.transports.addTransport("IframeTransport");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -