Newer
Older
// to cancel request set src to something else
// we use src="javascript:false;" because it doesn't
// trigger ie6 prompt on https
iframe.setAttribute('src', 'javascript:false;');
qq.remove(iframe);
}
},
_upload: function(id, params){
Daniel Vincent Grippi
a validé
var input = this._inputs[id];
Daniel Vincent Grippi
a validé
if (!input){
throw new Error('file with passed id was not added, or already uploaded or cancelled');
}
Daniel Vincent Grippi
a validé
var fileName = this.getName(id);
Daniel Vincent Grippi
a validé
var iframe = this._createIframe(id);
var form = this._createForm(iframe, params);
form.appendChild(input);
$(form).append($('<input type="hidden" name="authenticity_token" value="'+$("meta[name='csrf-token']").attr("content")+'"/>'));
Daniel Vincent Grippi
a validé
var self = this;
this._attachLoadEvent(iframe, function(){
var response = self._getIframeContentJSON(iframe);
self._options.onComplete(id, fileName, response);
self._dequeue(id);
Daniel Vincent Grippi
a validé
delete self._inputs[id];
// timeout added to fix busy state in FF3.6
setTimeout(function(){
qq.remove(iframe);
}, 1);
});
form.submit();
qq.remove(form);
},
Daniel Vincent Grippi
a validé
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
_attachLoadEvent: function(iframe, callback){
qq.attach(iframe, 'load', function(){
// when we remove iframe from dom
// the request stops, but in IE load
// event fires
if (!iframe.parentNode){
return;
}
// fixing Opera 10.53
if (iframe.contentDocument &&
iframe.contentDocument.body &&
iframe.contentDocument.body.innerHTML == "false"){
// In Opera event is fired second time
// when body.innerHTML changed from false
// to server response approx. after 1 sec
// when we upload file with iframe
return;
}
callback();
});
},
/**
* Returns json object received by iframe from server.
*/
_getIframeContentJSON: function(iframe){
// iframe.contentWindow.document - for IE<7
var doc = iframe.contentDocument ? iframe.contentDocument: iframe.contentWindow.document,
response;
this.log("converting iframe's innerHTML to JSON");
this.log("innerHTML = " + doc.body.innerHTML);
Daniel Vincent Grippi
a validé
response = eval("(" + doc.body.innerHTML + ")");
} catch(err){
response = {};
}
Daniel Vincent Grippi
a validé
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
return response;
},
/**
* Creates iframe with unique name
*/
_createIframe: function(id){
// We can't use following code as the name attribute
// won't be properly registered in IE6, and new window
// on form submit will open
// var iframe = document.createElement('iframe');
// iframe.setAttribute('name', id);
var iframe = qq.toElement('<iframe src="javascript:false;" name="' + id + '" />');
// src="javascript:false;" removes ie6 prompt on https
iframe.setAttribute('id', id);
iframe.style.display = 'none';
document.body.appendChild(iframe);
return iframe;
},
/**
* Creates form, that will be submitted to iframe
*/
_createForm: function(iframe, params){
// We can't use the following code in IE6
// var form = document.createElement('form');
// form.setAttribute('method', 'post');
// form.setAttribute('enctype', 'multipart/form-data');
// Because in this case file won't be attached to request
var form = qq.toElement('<form method="post" enctype="multipart/form-data"></form>');
var queryString = qq.obj2url(params, this._options.action);
Daniel Vincent Grippi
a validé
Daniel Vincent Grippi
a validé
form.setAttribute('target', iframe.name);
form.style.display = 'none';
document.body.appendChild(form);
return form;
}
Daniel Vincent Grippi
a validé
/**
* Class for uploading files using xhr
Daniel Vincent Grippi
a validé
*/
qq.UploadHandlerXhr = function(o){
qq.UploadHandlerAbstract.apply(this, arguments);
Daniel Vincent Grippi
a validé
this._files = [];
this._xhrs = [];
// current loaded size in bytes for each file
Daniel Vincent Grippi
a validé
};
// static method
qq.UploadHandlerXhr.isSupported = function(){
var input = document.createElement('input');
input.type = 'file';
Daniel Vincent Grippi
a validé
return (
'multiple' in input &&
typeof File != "undefined" &&
typeof (new XMLHttpRequest()).upload != "undefined" );
Daniel Vincent Grippi
a validé
};
// @inherits qq.UploadHandlerAbstract
qq.extend(qq.UploadHandlerXhr.prototype, qq.UploadHandlerAbstract.prototype)
qq.extend(qq.UploadHandlerXhr.prototype, {
Daniel Vincent Grippi
a validé
/**
* Adds file to the queue
* Returns id to use with upload, cancel
**/
Daniel Vincent Grippi
a validé
add: function(file){
if (!(file instanceof File)){
throw new Error('Passed obj in not a File (in qq.UploadHandlerXhr)');
}
return this._files.push(file) - 1;
Daniel Vincent Grippi
a validé
},
getName: function(id){
var file = this._files[id];
// fix missing name in Safari 4
return file.fileName != null ? file.fileName : file.name;
},
getSize: function(id){
var file = this._files[id];
return file.fileSize != null ? file.fileSize : file.size;
},
* Returns uploaded bytes for file identified by id
*/
return this._loaded[id] || 0;
Daniel Vincent Grippi
a validé
/**
* Sends the file identified by id and additional query params to the server
* @param {Object} params name-value string pairs
*/
Daniel Vincent Grippi
a validé
var file = this._files[id],
name = this.getName(id),
size = this.getSize(id);
Daniel Vincent Grippi
a validé
var xhr = this._xhrs[id] = new XMLHttpRequest();
var self = this;
Daniel Vincent Grippi
a validé
xhr.upload.onprogress = function(e){
if (e.lengthComputable){
Daniel Vincent Grippi
a validé
self._options.onProgress(id, name, e.loaded, e.total);
}
};
xhr.onreadystatechange = function(){
Daniel Vincent Grippi
a validé
if (xhr.readyState == 4){
self._onComplete(id, xhr);
Daniel Vincent Grippi
a validé
}
};
// build query string
params = params || {};
params['qqfile'] = name;
var queryString = qq.obj2url(params, this._options.action);
Daniel Vincent Grippi
a validé
Daniel Vincent Grippi
a validé
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
xhr.setRequestHeader("X-File-Name", encodeURIComponent(name));
xhr.setRequestHeader("Content-Type", "application/octet-stream");
xhr.setRequestHeader("X-CSRF-Token", $("meta[name='csrf-token']").attr("content"));
xhr.setRequestHeader("Accept", "application/json");
Daniel Vincent Grippi
a validé
xhr.send(file);
},
_onComplete: function(id, xhr){
// the request was aborted/cancelled
if (!this._files[id]) return;
var name = this.getName(id);
var size = this.getSize(id);
this._options.onProgress(id, name, size, size);
if (xhr.status == 200){
this.log("xhr - server response received");
this.log("responseText = " + xhr.responseText);
try {
response = eval("(" + xhr.responseText + ")");
} catch(err){
response = {};
}
this._completed_files.push({file: this._files[id], response: response});
this._options.onComplete(id, name, response);
} else {
this._completed_files.push({file: this._files[id], response: {}});
Daniel Vincent Grippi
a validé
}
this._xhrs[id] = null;
this._dequeue(id);
Daniel Vincent Grippi
a validé
},
_cancel: function(id){
this._options.onCancel(id, this.getName(id));
if (this._xhrs[id]){
this._xhrs[id].abort();
this._xhrs[id] = null;
Daniel Vincent Grippi
a validé
}
}