1
0
Fork 0
lasertank-js/lib/FileLoader.js

121 lines
3.4 KiB
JavaScript
Raw Normal View History

/**
* Loads a file from disk and returns a binary string
*
* Copyright (C) 2012 Mike Gerwitz
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
* The file uses a number of features introduced in the HTML5 and ECMAScript
* specs, as it depends on FileReader.
*/
/**
* Load file into memory as binary string from a given file element
*
* This class handles the loading of only a single file (as that is all this
* project requires).
*/
ltjs.FileLoader = Class( 'FileLoader',
{
/**
* DOM file element to watch
* @type {HTMLInputElement}
*/
'private _element': null,
/**
* Callback to call on file load
* @type {function(Error,string)}
*/
'private _callback': null,
/**
* Initialize file loader, monitoring the given file element
*
* @param {HtmlInputElement} element file element to monitor
*/
__construct: function( element )
{
if ( element.type !== 'file' )
{
throw TypeError( 'Expected file element, given ' + element.type );
}
this._element = element;
},
/**
* Bind callback to file load event
*
* The given callback will be called when the file is loaded. It must accept
* two arguments: the first will be used to indicate an error (otherwise
* null) and the second argument will contain the binary string of data
* (unless an error occurred, in which case it will be undefined).
*
* @param {function(Error,string)} callback file load callback
*
* @return {FileLoader} self
*/
'public onLoad': function( callback )
{
this._callback = callback;
// we do not want to monitor the change event until *after* a callback
// is registered (it is otherwise pointless)
this._element.addEventListener( 'change', this._loadFile.bind( this ) );
// attempt to load file immediately (in case a file has already been
// selected)
this._loadFile( { target: this._element } );
return this;
},
/**
* Process file and invokes callback with result
*
* Called on filename change.
*
* @param {Object} event change event
*
* @return {undefined}
*/
'private _loadFile': function( event )
{
var _self = this,
files = event.target.files;
if ( files.length === 0 ) return;
var reader = new FileReader();
reader.onload = function( revent )
{
_self._callback.call( this.__inst, null, revent.target.result );
};
reader.onerror = function( e )
{
_self._callback.call( this.__inst, e );
};
// load file
reader.readAsBinaryString( files[ 0 ] );
}
} );