UNPKG

@qooxdoo/framework

Version:

The JS Framework for Coders

352 lines (303 loc) 11.2 kB
/* ************************************************************************ qooxdoo - the new era of web development http://qooxdoo.org Copyright: 2011 Derrell Lipman License: MIT: https://opensource.org/licenses/MIT See the LICENSE file in the project's top-level directory for details. Authors: * Derrell Lipman(derrell) ************************************************************************ */ /** * FileReaders allow retrieving the data from a local file, after the file * name was selected by an <input type="file"> element. * * NOTE: Instances of this class must be disposed of after use * * For more information see: * http://www.w3.org/TR/FileAPI/ */ qx.Class.define("qx.bom.FileReader", { extend : qx.core.Object, implement: [ qx.core.IDisposable ], /** * Create a new instance. */ construct: function() { // Call the superclass constructor this.base(arguments); // Get a FileReader object this._fileReader = new window.FileReader(); // Bind native handlers to this instance this._handleLoadStart = qx.lang.Function.bind(this._handleLoadStart, this); this._handleProgress = qx.lang.Function.bind(this._handleProgress, this); this._handleLoad = qx.lang.Function.bind(this._handleLoad, this); this._handleAbort = qx.lang.Function.bind(this._handleAbort, this); this._handleError = qx.lang.Function.bind(this._handleError, this); this._handleLoadEnd = qx.lang.Function.bind(this._handleLoadEnd, this); // Be notified of all events qx.bom.Event.addNativeListener(this._fileReader, "loadstart", this._handleLoadStart); qx.bom.Event.addNativeListener(this._fileReader, "progress", this._handleProgress); qx.bom.Event.addNativeListener(this._fileReader, "load", this._handleLoad); qx.bom.Event.addNativeListener(this._fileReader, "abort", this._handleAbort); qx.bom.Event.addNativeListener(this._fileReader, "error", this._handleError); qx.bom.Event.addNativeListener(this._fileReader, "loadend", this._handleLoadEnd); }, events : { /** Fired when progress has begun. */ "loadstart" : "qx.event.type.Data", /** Fired while making progress, presumably at a minimum of every 50ms */ "progress" : "qx.event.type.Data", /** Fired when an error occurs */ "error": "qx.event.type.Data", /** * Fired when progression has failed, after the last "progress" has been * dispatched, or after "loadstart" has been dispatched, if "progress" has * not been dispatched" */ "abort" : "qx.event.type.Data", /** Fired when progression is successful */ "load" : "qx.event.type.Data", /** * Fired when progress has stopped, after any of "error", "abort", or * "load" have been dispatched. */ "loadend" : "qx.event.type.Data" }, statics : { /** * Return the number of files selected by the user, from an <input * type="file"> element. * * @param inputElement {Element} * The Element created as a result of an <input type="file"> tag. * * @return {Integer} * The number of selected files. */ getNumFiles : function(inputElement) { return inputElement.files.length; }, /** * Return the native File object selected from an <input type="file"> * element. * * @param inputElement {Element} * The Element created as a result of an <input type="file"> tag. * * @param index {Integer} * The index of the selected file to return. * * @return {File} * The File object associated with the selected file name. */ getFile : function(inputElement, index) { return inputElement.files[index]; } }, members : { /** The native FileReader object associated this instance */ _fileReader : null, /** * Begin reading from the file referenced by the specified file * object. This is an asynchronous request. When the file is fully loaded, * the "load" event will be fired. * * The data will be provided as an ArrayBuffer object. * * @param fileObj {File} * A File object, as obtained by calling {@link #getFile} with an * element of type <input type="file">. */ readAsArrayBuffer : function(fileObj) { this._fileReader.readAsArrayBuffer(fileObj); }, /** * Begin reading from the file referenced by the specified file * object. This is an asynchronous request. When the file is fully loaded, * the "load" event will be fired. * * The data will be provided in a binary format where each byte is in the * range [0,255]. * * NOTE: On FireFox, this method works if the page was loaded via the * file:// protocol. In Chrome, it does not. * * @param fileObj {File} * A File object, as obtained by calling {@link #getFile} with an * element of type <input type="file">. */ readAsBinaryString : function(fileObj) { this._fileReader.readAsBinaryString(fileObj); }, /** * Begin reading from the file referenced by the specified file * object. This is an asynchronous request. When the file is fully loaded, * the "load" event will be fired. * * The data will be provided as text, in the specified encoding. * * NOTE: On FireFox, this method works if the page was loaded via the * file:// protocol. In Chrome, it does not. * * @param fileObj {File} * A File object, as obtained by calling {@link #getFile} with an * element of type <input type="file">. * * @param encoding {String?"UTF-8"} * The encoding for the resulting string. */ readAsText : function(fileObj, encoding) { this._fileReader.readAsText(fileObj, encoding); }, /** * Begin reading from the file referenced by the specified file * object. This is an asynchronous request. When the file is fully loaded, * the "load" event will be fired. * * The data is returned in DataURL format. * * NOTE: On FireFox, this method works if the page was loaded via the * file:// protocol. In Chrome, it does not. * * @param fileObj {File} * A File object, as obtained by calling {@link #getFile} with an * element of type <input type="file">. */ readAsDataURL : function(fileObj) { this._fileReader.readAsDataURL(fileObj); }, /** * "loadstart" handler * * @param e {Object} * Object which contains a 'progress' object which contains the members: * - lengthComputable {Boolean} True if length is known; false otherwise * - loaded {Number} The number of bytes transferred so far * - total {Number} The length of the entire body being transferred */ _handleLoadStart: function(e) { this.fireDataEvent("loadstart", { progress : e.data }); }, /** * "progress" handler * * @param e {Object} * Object which contains a 'progress' object which contains the members: * - lengthComputable {Boolean} True if length is known; false otherwise * - loaded {Number} The number of bytes transferred so far * - total {Number} The length of the entire body being transferred */ _handleProgress: function(e) { this.fireDataEvent("progress", { progress : e.data }); }, /** * "error" handler * * @param e {Object} * Object which contains a 'progress' object which contains the members: * - lengthComputable {Boolean} True if length is known; false otherwise * - loaded {Number} The number of bytes transferred so far * - total {Number} The length of the entire body being transferred */ _handleError: function(e) { this.fireDataEvent("error", { progress : e.data }); }, /** * "abort" handler * * @param e {Object} * Object which contains a 'progress' object which contains the members: * - lengthComputable {Boolean} True if length is known; false otherwise * - loaded {Number} The number of bytes transferred so far * - total {Number} The length of the entire body being transferred */ _handleAbort: function(e) { this.fireDataEvent("abort", { progress : e.data }); }, /** * "load" handler * * @param e {Object} * Object which contains: * - A 'progress' object which contains the members: * - lengthComputable {Boolean} True if length is known; false otherwise * - loaded {Number} The number of bytes transferred so far * - total {Number} The length of the entire body being transferred * - A 'content' member which contains the loaded file content */ _handleLoad: function(e) { // Add the result to the event data this.fireDataEvent("load", { progress : e.data, content : e.target.result }); }, /** * "loadend" handler * * @param e {Object} * Object which contains a 'progress' object which contains the members: * - lengthComputable {Boolean} True if length is known; false otherwise * - loaded {Number} The number of bytes transferred so far * - total {Number} The length of the entire body being transferred */ _handleLoadEnd: function(e) { this.fireDataEvent("loadend", { progress : e.data }); } }, destruct : function() { // Remove all listeners qx.bom.Event.removeNativeListener(this._fileReader, "loadstart", this._handleLoadStart); qx.bom.Event.removeNativeListener(this._fileReader, "progress", this._handleProgress); qx.bom.Event.removeNativeListener(this._fileReader, "load", this._handleLoad); qx.bom.Event.removeNativeListener(this._fileReader, "abort", this._handleAbort); qx.bom.Event.removeNativeListener(this._fileReader, "error", this._handleError); qx.bom.Event.removeNativeListener(this._fileReader, "loadend", this._handleLoadEnd); this._fileReader = null; } });