file-debug.js revision e66eba403ebf8a09e090b3785e8ea63aa1de7f3d
664N/AYUI.add('file', function(Y) {
664N/A
664N/A /**
664N/A * The File class provides a wrapper for a file pointer, either through an HTML5
664N/A * implementation or as a reference to a file pointer stored in Flash. The File wrapper
664N/A * also implements the mechanics for uploading a file and tracking its progress.
664N/A * @module file
664N/A */
664N/A /**
664N/A * The class provides a wrapper for a file pointer.
664N/A * @class File
664N/A * @extends Base
664N/A * @constructor
664N/A */
664N/A var Lang = Y.Lang,
664N/A Bind = Y.bind,
664N/A Win = Y.config.win;
664N/A
664N/A var YFile = function(o) {
664N/A
1241N/A var file = null;
664N/A
664N/A if (Y.File.isValidFile(o)) {
664N/A file = o;
664N/A }
664N/A else if (Y.File.isValidFile(o.file)) {
664N/A file = o.file;
664N/A }
664N/A else {
664N/A file = false;
664N/A }
664N/A
664N/A YFile.superclass.constructor.apply(this, arguments);
664N/A
815N/A if (file && Y.File.canUpload()) {
1190N/A if (!this.get("file")) {
664N/A this._set("file", file);
1182N/A }
664N/A if (!this.get("html5")) {
703N/A this._set("html5", true);
749N/A }
664N/A if (!this.get("name")) {
672N/A this._set("name", file.name || file.fileName);
672N/A }
672N/A if (this.get("size") != (file.size || file.fileSize)) {
664N/A this._set("size", file.size || file.fileSize);
672N/A }
664N/A if (!this.get("type")) {
664N/A this._set("type", file.type);
664N/A }
664N/A if (file.hasOwnProperty("lastModifiedDate") && !this.get("dateModified")) {
664N/A this._set("dateModified", file.lastModifiedDate);
1182N/A }
703N/A }
749N/A else if (this.get("uploader")) {
664N/A
664N/A }
664N/A };
664N/A
664N/A
664N/A Y.extend(YFile, Y.Base, {
664N/A
664N/A initializer : function (cfg) {
664N/A if (!this.get("id")) {
664N/A this._set("id", Y.guid("file"));
664N/A }
664N/A },
664N/A
664N/A _swfEventHandler: function (event) {
664N/A if (event.id === this.get("id")) {
664N/A switch (event.type) {
664N/A case "uploadstart":
664N/A this.fire("uploadstart", {uploader: this.get("uploader")});
664N/A break;
664N/A case "uploadprogress":
664N/A this.fire("uploadprogress", {originEvent: event,
1190N/A bytesLoaded: event.bytesLoaded,
664N/A bytesTotal: event.bytesTotal,
664N/A percentLoaded: Math.min(100, Math.round(10000*event.bytesLoaded/event.bytesTotal)/100)
664N/A });
1182N/A this._set("bytesUploaded", event.bytesLoaded);
664N/A break;
664N/A case "uploadcomplete":
664N/A this.fire("uploadfinished", {originEvent: event});
664N/A break;
664N/A case "uploadcompletedata":
664N/A this.fire("uploadcomplete", {originEvent: event,
664N/A data: event.data});
1182N/A break;
664N/A case "uploadcancel":
664N/A this.fire("uploadcancel", {originEvent: event});
664N/A break;
664N/A case "uploaderror":
703N/A this.fire("uploaderror", {originEvent: event});
703N/A
1190N/A }
703N/A }
703N/A },
703N/A
703N/A _uploadEventHandler: function (event) {
703N/A switch (event.type) {
703N/A case "progress":
703N/A this.fire("uploadprogress", {originEvent: event,
703N/A bytesLoaded: event.loaded,
703N/A bytesTotal: this.get("size"),
703N/A percentLoaded: Math.min(100, Math.round(10000*event.loaded/this.get("size"))/100)
703N/A });
703N/A this._set("bytesUploaded", event.loaded);
703N/A break;
703N/A
703N/A case "load":
664N/A this.fire("uploadcomplete", {originEvent: event,
664N/A data: event.target.responseText});
664N/A var xhrupload = this.get("xhr").upload,
664N/A xhr = this.get("xhr"),
664N/A boundEventHandler = this.get("boundEventHandler");
664N/A
664N/A xhrupload.removeEventListener ("progress", boundEventHandler);
664N/A xhrupload.removeEventListener ("error", boundEventHandler);
664N/A xhrupload.removeEventListener ("abort", boundEventHandler);
664N/A xhr.removeEventListener ("load", boundEventHandler);
664N/A xhr.removeEventListener ("readystatechange", boundEventHandler);
664N/A
664N/A this._set("xhr", null);
664N/A break;
664N/A
749N/A case "error":
749N/A var xhr = this.get("xhr");
749N/A Y.log("An error has occurred: " + status + ", " + statusText);
664N/A this.fire("uploaderror", {originEvent: event,
749N/A status: xhr.status,
749N/A statusText: xhr.statusText});
749N/A break;
664N/A
749N/A case "abort":
this.fire("uploadcancel", {originEvent: event});
break;
case "readystatechange":
this.fire("readystatechange", {readyState: event.target.readyState,
originEvent: event});
break;
}
},
/**
* Starts the upload of a specific file.
*
* @method startUpload
* @param url {String} The URL to upload the file to.
* @param parameters {Object} (optional) A set of key-value pairs to send as variables along with the file upload HTTP request.
* @param fileFieldName {String} (optional) The name of the POST variable that should contain the uploaded file ('Filedata' by default)
* @return {Boolean} This method always returns true.
*/
startUpload: function(url, parameters, fileFieldName) {
if (this.get("html5")) {
this._set("bytesUploaded", 0);
this._set("xhr", new XMLHttpRequest());
this._set("boundEventHandler", Bind(this._uploadEventHandler, this));
var uploadData = new FormData(),
fileField = fileFieldName || "Filedata",
xhr = this.get("xhr"),
xhrupload = this.get("xhr").upload,
boundEventHandler = this.get("boundEventHandler");
Y.each(parameters, function (value, key) {uploadData.append(key, value);});
uploadData.append(fileField, this.get("file"));
xhrupload.addEventListener ("progress", boundEventHandler, false);
xhrupload.addEventListener ("error", boundEventHandler, false);
xhrupload.addEventListener ("abort", boundEventHandler, false);
xhr.addEventListener ("load", boundEventHandler, false);
xhr.addEventListener ("readystatechange", boundEventHandler, false);
xhr.open("POST", url, true);
xhr.send(uploadData);
this.fire("uploadstart", {xhr: xhr});
}
else if (this.get("uploader")) {
var myUploader = this.get("uploader"),
fileField = fileFieldName || "Filedata",
id = this.get("id"),
params = parameters || null;
this._set("bytesUploaded", 0);
myUploader.on("uploadstart", this._swfEventHandler, this);
myUploader.on("uploadprogress", this._swfEventHandler, this);
myUploader.on("uploadcomplete", this._swfEventHandler, this);
myUploader.on("uploadcompletedata", this._swfEventHandler, this);
myUploader.on("uploaderror", this._swfEventHandler, this);
myUploader.callSWF("upload", [id, url, params, fileField]);
}
},
/**
* Cancels the upload of a specific file, if currently in progress.
*
* @method cancelUpload
*/
cancelUpload: function () {
if (this.get("html5")) {
this.get('xhr').abort();
}
else if (this.get("uploader")) {
this.get("uploader").callSWF("cancel", [this.get("id")]);
}
},
}, {
NAME: 'file',
ATTRS: {
html5: {
readOnly: true,
value: false
},
id: {
writeOnce: "initOnly",
value: null
},
size: {
writeOnce: "initOnly",
value: 0
},
name: {
writeOnce: "initOnly",
value: null
},
dateCreated: {
writeOnce: "initOnly",
value: null
},
dateModified: {
writeOnce: "initOnly",
value: null
},
bytesUploaded: {
readOnly: true,
value: 0
},
type: {
writeOnce: "initOnly",
value: null
},
file: {
writeOnce: "initOnly",
value: null
},
uploader: {
writeOnce: "initOnly",
value: null
},
xhr: {
readOnly: true,
value: null
},
boundEventHandler: {
readOnly: true,
value: null
}
},
/**
* Checks whether a specific native file instance is valid
*
* @method isValidFile
* @param file {File} A native File() instance.
*/
isValidFile: function (file) {
return (Win && Win.File && file instanceof File);
},
/**
* Checks whether the browser has a native upload capability
* via XMLHttpRequest Level 2.
*
* @method canUpload
*/
canUpload: function () {
return (Win && Win.FormData && Win.XMLHttpRequest);
},
FOO: "BAR"
});
Y.File = YFile;
}, '@VERSION@' ,{requires:['base']});