Last active
December 16, 2015 21:49
-
-
Save mattparker/5502902 to your computer and use it in GitHub Desktop.
Patches for YUI2 Uploader for IE9+
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//////////////////////////////////////////////////// | |
//////////////////////////////////////////////////// | |
// Patch | |
// | |
// Was using a non-standard quirk of IE to do | |
// document.createElement('<iframe id="' + frameId + '" name="' + frameId + '" />') | |
// when it should really be just document.createElement('iframe') and then add attributes | |
// IE9 is strict about this and breaks. | |
// | |
// | |
YAHOO.util.Connect.createFrame = function (secureUri) { | |
// IE does not allow the setting of id and name attributes as object | |
// properties via createElement(). A different iframe creation | |
// pattern is required for IE. | |
var frameId = 'yuiIO' + this._transaction_id, | |
io; | |
if(YAHOO.env.ua.ie){ | |
// This doesn't work in IE9+ : | |
// io = document.createElement('<iframe id="' + frameId + '" name="' + frameId + '" />'); | |
io = document.createElement('iframe'); | |
io.id = frameId; | |
io.name = frameId; | |
// IE will throw a security exception in an SSL environment if the | |
// iframe source is undefined. | |
if(typeof secureUri == 'boolean'){ | |
io.src = 'javascript:false'; | |
} | |
} | |
else{ | |
io = document.createElement('iframe'); | |
io.id = frameId; | |
io.name = frameId; | |
} | |
io.style.position = 'absolute'; | |
io.style.top = '-1000px'; | |
io.style.left = '-1000px'; | |
document.body.appendChild(io); | |
}; | |
//////////////////////////////////////////////////// | |
//////////////////////////////////////////////////// | |
// Patch | |
// | |
// The test for IE8 was *only* for IE8: but IE9 (and presumably higher, | |
// I can't test IE10) behave in this respect in the same way as IE8. | |
// | |
// The particular issue was to do with the 'enctype' header - see the | |
// commment below. | |
// | |
// The only line that's changed is the one that sets the value of ie8. | |
// | |
// | |
YAHOO.util.Connect.uploadFile = function (o, callback, uri, postData) { | |
// Each iframe has an id prefix of "yuiIO" followed | |
// by the unique transaction id. | |
var frameId = 'yuiIO' + o.tId, | |
uploadEncoding = 'multipart/form-data', | |
io = document.getElementById(frameId), | |
// This was doing exact === 8 on the documentMode, so anything greater was in | |
// effect being treated as < 8. | |
ie8 = (document.documentMode && document.documentMode >= 8) ? true : false, | |
oConn = this, | |
args = (callback && callback.argument)?callback.argument:null, | |
oElements, | |
i, | |
prop, | |
obj, | |
rawFormAttributes, | |
uploadCallback; | |
// Track original HTML form attribute values. | |
rawFormAttributes = { | |
action:this._formNode.getAttribute('action'), | |
method:this._formNode.getAttribute('method'), | |
target:this._formNode.getAttribute('target') | |
}; | |
// Initialize the HTML form properties in case they are | |
// not defined in the HTML form. | |
this._formNode.setAttribute('action', uri); | |
this._formNode.setAttribute('method', 'POST'); | |
this._formNode.setAttribute('target', frameId); | |
if(YAHOO.env.ua.ie && !ie8){ | |
// IE does not respect property enctype for HTML forms. | |
// Instead it uses the property - "encoding". | |
this._formNode.setAttribute('encoding', uploadEncoding); | |
} | |
else{ | |
this._formNode.setAttribute('enctype', uploadEncoding); | |
} | |
if(postData){ | |
oElements = this.appendPostData(postData); | |
} | |
// Start file upload. | |
this._formNode.submit(); | |
// Fire global custom event -- startEvent | |
this.startEvent.fire(o, args); | |
if(o.startEvent){ | |
// Fire transaction custom event -- startEvent | |
o.startEvent.fire(o, args); | |
} | |
// Start polling if a callback is present and the timeout | |
// property has been defined. | |
if(callback && callback.timeout){ | |
this._timeOut[o.tId] = window.setTimeout(function(){ oConn.abort(o, callback, true); }, callback.timeout); | |
} | |
// Remove HTML elements created by appendPostData | |
if(oElements && oElements.length > 0){ | |
for(i=0; i < oElements.length; i++){ | |
this._formNode.removeChild(oElements[i]); | |
} | |
} | |
// Restore HTML form attributes to their original | |
// values prior to file upload. | |
for(prop in rawFormAttributes){ | |
if(YAHOO.lang.hasOwnProperty(rawFormAttributes, prop)){ | |
if(rawFormAttributes[prop]){ | |
this._formNode.setAttribute(prop, rawFormAttributes[prop]); | |
} | |
else{ | |
this._formNode.removeAttribute(prop); | |
} | |
} | |
} | |
// Reset HTML form state properties. | |
this.resetFormState(); | |
// Create the upload callback handler that fires when the iframe | |
// receives the load event. Subsequently, the event handler is detached | |
// and the iframe removed from the document. | |
uploadCallback = function() { | |
if(callback && callback.timeout){ | |
window.clearTimeout(oConn._timeOut[o.tId]); | |
delete oConn._timeOut[o.tId]; | |
} | |
// Fire global custom event -- completeEvent | |
oConn.completeEvent.fire(o, args); | |
if(o.completeEvent){ | |
// Fire transaction custom event -- completeEvent | |
o.completeEvent.fire(o, args); | |
} | |
obj = { | |
tId : o.tId, | |
argument : callback.argument | |
}; | |
try | |
{ | |
// responseText and responseXML will be populated with the same data from the iframe. | |
// Since the HTTP headers cannot be read from the iframe | |
obj.responseText = io.contentWindow.document.body?io.contentWindow.document.body.innerHTML:io.contentWindow.document.documentElement.textContent; | |
obj.responseXML = io.contentWindow.document.XMLDocument?io.contentWindow.document.XMLDocument:io.contentWindow.document; | |
} | |
catch(e){} | |
if(callback && callback.upload){ | |
if(!callback.scope){ | |
callback.upload(obj); | |
} | |
else{ | |
callback.upload.apply(callback.scope, [obj]); | |
} | |
} | |
// Fire global custom event -- uploadEvent | |
oConn.uploadEvent.fire(obj); | |
if(o.uploadEvent){ | |
// Fire transaction custom event -- uploadEvent | |
o.uploadEvent.fire(obj); | |
} | |
YAHOO.util.Event.removeListener(io, "load", uploadCallback); | |
setTimeout( | |
function(){ | |
document.body.removeChild(io); | |
oConn.releaseObject(o); | |
}, 100); | |
}; | |
// Bind the onload handler to the iframe to detect the file upload response. | |
YAHOO.util.Event.addListener(io, "load", uploadCallback); | |
}; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment