121 lines
3.4 KiB
JavaScript
121 lines
3.4 KiB
JavaScript
|
/**
|
||
|
* 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 ] );
|
||
|
}
|
||
|
} );
|
||
|
|