391 lines
12 KiB
JavaScript
391 lines
12 KiB
JavaScript
/*
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one
|
|
* or more contributor license agreements. See the NOTICE file
|
|
* distributed with this work for additional information
|
|
* regarding copyright ownership. The ASF licenses this file
|
|
* to you under the Apache License, Version 2.0 (the
|
|
* "License"); you may not use this file except in compliance
|
|
* with the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing,
|
|
* software distributed under the License is distributed on an
|
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
* KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations
|
|
* under the License.
|
|
*
|
|
*/
|
|
|
|
var exec = require('cordova/exec'),
|
|
modulemapper = require('cordova/modulemapper'),
|
|
utils = require('cordova/utils'),
|
|
File = require('./File'),
|
|
FileError = require('./FileError'),
|
|
ProgressEvent = require('./ProgressEvent'),
|
|
origFileReader = modulemapper.getOriginalSymbol(window, 'FileReader');
|
|
|
|
/**
|
|
* This class reads the mobile device file system.
|
|
*
|
|
* For Android:
|
|
* The root directory is the root of the file system.
|
|
* To read from the SD card, the file name is "sdcard/my_file.txt"
|
|
* @constructor
|
|
*/
|
|
var FileReader = function() {
|
|
this._readyState = 0;
|
|
this._error = null;
|
|
this._result = null;
|
|
this._localURL = '';
|
|
this._realReader = origFileReader ? new origFileReader() : {};
|
|
};
|
|
|
|
// States
|
|
FileReader.EMPTY = 0;
|
|
FileReader.LOADING = 1;
|
|
FileReader.DONE = 2;
|
|
|
|
utils.defineGetter(FileReader.prototype, 'readyState', function() {
|
|
return this._localURL ? this._readyState : this._realReader.readyState;
|
|
});
|
|
|
|
utils.defineGetter(FileReader.prototype, 'error', function() {
|
|
return this._localURL ? this._error: this._realReader.error;
|
|
});
|
|
|
|
utils.defineGetter(FileReader.prototype, 'result', function() {
|
|
return this._localURL ? this._result: this._realReader.result;
|
|
});
|
|
|
|
function defineEvent(eventName) {
|
|
utils.defineGetterSetter(FileReader.prototype, eventName, function() {
|
|
return this._realReader[eventName] || null;
|
|
}, function(value) {
|
|
this._realReader[eventName] = value;
|
|
});
|
|
}
|
|
defineEvent('onloadstart'); // When the read starts.
|
|
defineEvent('onprogress'); // While reading (and decoding) file or fileBlob data, and reporting partial file data (progress.loaded/progress.total)
|
|
defineEvent('onload'); // When the read has successfully completed.
|
|
defineEvent('onerror'); // When the read has failed (see errors).
|
|
defineEvent('onloadend'); // When the request has completed (either in success or failure).
|
|
defineEvent('onabort'); // When the read has been aborted. For instance, by invoking the abort() method.
|
|
|
|
function initRead(reader, file) {
|
|
// Already loading something
|
|
if (reader.readyState == FileReader.LOADING) {
|
|
throw new FileError(FileError.INVALID_STATE_ERR);
|
|
}
|
|
|
|
reader._result = null;
|
|
reader._error = null;
|
|
reader._readyState = FileReader.LOADING;
|
|
|
|
if (typeof file.localURL == 'string') {
|
|
reader._localURL = file.localURL;
|
|
} else {
|
|
reader._localURL = '';
|
|
return true;
|
|
}
|
|
|
|
reader.onloadstart && reader.onloadstart(new ProgressEvent("loadstart", {target:reader}));
|
|
}
|
|
|
|
/**
|
|
* Abort reading file.
|
|
*/
|
|
FileReader.prototype.abort = function() {
|
|
if (origFileReader && !this._localURL) {
|
|
return this._realReader.abort();
|
|
}
|
|
this._result = null;
|
|
|
|
if (this._readyState == FileReader.DONE || this._readyState == FileReader.EMPTY) {
|
|
return;
|
|
}
|
|
|
|
this._readyState = FileReader.DONE;
|
|
|
|
// If abort callback
|
|
if (typeof this.onabort === 'function') {
|
|
this.onabort(new ProgressEvent('abort', {target:this}));
|
|
}
|
|
// If load end callback
|
|
if (typeof this.onloadend === 'function') {
|
|
this.onloadend(new ProgressEvent('loadend', {target:this}));
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Read text file.
|
|
*
|
|
* @param file {File} File object containing file properties
|
|
* @param encoding [Optional] (see http://www.iana.org/assignments/character-sets)
|
|
*/
|
|
FileReader.prototype.readAsText = function(file, encoding) {
|
|
if (initRead(this, file)) {
|
|
return this._realReader.readAsText(file, encoding);
|
|
}
|
|
|
|
// Default encoding is UTF-8
|
|
var enc = encoding ? encoding : "UTF-8";
|
|
var me = this;
|
|
var execArgs = [this._localURL, enc, file.start, file.end];
|
|
|
|
// Read file
|
|
exec(
|
|
// Success callback
|
|
function(r) {
|
|
// If DONE (cancelled), then don't do anything
|
|
if (me._readyState === FileReader.DONE) {
|
|
return;
|
|
}
|
|
|
|
// DONE state
|
|
me._readyState = FileReader.DONE;
|
|
|
|
// Save result
|
|
me._result = r;
|
|
|
|
// If onload callback
|
|
if (typeof me.onload === "function") {
|
|
me.onload(new ProgressEvent("load", {target:me}));
|
|
}
|
|
|
|
// If onloadend callback
|
|
if (typeof me.onloadend === "function") {
|
|
me.onloadend(new ProgressEvent("loadend", {target:me}));
|
|
}
|
|
},
|
|
// Error callback
|
|
function(e) {
|
|
// If DONE (cancelled), then don't do anything
|
|
if (me._readyState === FileReader.DONE) {
|
|
return;
|
|
}
|
|
|
|
// DONE state
|
|
me._readyState = FileReader.DONE;
|
|
|
|
// null result
|
|
me._result = null;
|
|
|
|
// Save error
|
|
me._error = new FileError(e);
|
|
|
|
// If onerror callback
|
|
if (typeof me.onerror === "function") {
|
|
me.onerror(new ProgressEvent("error", {target:me}));
|
|
}
|
|
|
|
// If onloadend callback
|
|
if (typeof me.onloadend === "function") {
|
|
me.onloadend(new ProgressEvent("loadend", {target:me}));
|
|
}
|
|
}, "File", "readAsText", execArgs);
|
|
};
|
|
|
|
|
|
/**
|
|
* Read file and return data as a base64 encoded data url.
|
|
* A data url is of the form:
|
|
* data:[<mediatype>][;base64],<data>
|
|
*
|
|
* @param file {File} File object containing file properties
|
|
*/
|
|
FileReader.prototype.readAsDataURL = function(file) {
|
|
if (initRead(this, file)) {
|
|
return this._realReader.readAsDataURL(file);
|
|
}
|
|
|
|
var me = this;
|
|
var execArgs = [this._localURL, file.start, file.end];
|
|
|
|
// Read file
|
|
exec(
|
|
// Success callback
|
|
function(r) {
|
|
// If DONE (cancelled), then don't do anything
|
|
if (me._readyState === FileReader.DONE) {
|
|
return;
|
|
}
|
|
|
|
// DONE state
|
|
me._readyState = FileReader.DONE;
|
|
|
|
// Save result
|
|
me._result = r;
|
|
|
|
// If onload callback
|
|
if (typeof me.onload === "function") {
|
|
me.onload(new ProgressEvent("load", {target:me}));
|
|
}
|
|
|
|
// If onloadend callback
|
|
if (typeof me.onloadend === "function") {
|
|
me.onloadend(new ProgressEvent("loadend", {target:me}));
|
|
}
|
|
},
|
|
// Error callback
|
|
function(e) {
|
|
// If DONE (cancelled), then don't do anything
|
|
if (me._readyState === FileReader.DONE) {
|
|
return;
|
|
}
|
|
|
|
// DONE state
|
|
me._readyState = FileReader.DONE;
|
|
|
|
me._result = null;
|
|
|
|
// Save error
|
|
me._error = new FileError(e);
|
|
|
|
// If onerror callback
|
|
if (typeof me.onerror === "function") {
|
|
me.onerror(new ProgressEvent("error", {target:me}));
|
|
}
|
|
|
|
// If onloadend callback
|
|
if (typeof me.onloadend === "function") {
|
|
me.onloadend(new ProgressEvent("loadend", {target:me}));
|
|
}
|
|
}, "File", "readAsDataURL", execArgs);
|
|
};
|
|
|
|
/**
|
|
* Read file and return data as a binary data.
|
|
*
|
|
* @param file {File} File object containing file properties
|
|
*/
|
|
FileReader.prototype.readAsBinaryString = function(file) {
|
|
if (initRead(this, file)) {
|
|
return this._realReader.readAsBinaryString(file);
|
|
}
|
|
|
|
var me = this;
|
|
var execArgs = [this._localURL, file.start, file.end];
|
|
|
|
// Read file
|
|
exec(
|
|
// Success callback
|
|
function(r) {
|
|
// If DONE (cancelled), then don't do anything
|
|
if (me._readyState === FileReader.DONE) {
|
|
return;
|
|
}
|
|
|
|
// DONE state
|
|
me._readyState = FileReader.DONE;
|
|
|
|
me._result = r;
|
|
|
|
// If onload callback
|
|
if (typeof me.onload === "function") {
|
|
me.onload(new ProgressEvent("load", {target:me}));
|
|
}
|
|
|
|
// If onloadend callback
|
|
if (typeof me.onloadend === "function") {
|
|
me.onloadend(new ProgressEvent("loadend", {target:me}));
|
|
}
|
|
},
|
|
// Error callback
|
|
function(e) {
|
|
// If DONE (cancelled), then don't do anything
|
|
if (me._readyState === FileReader.DONE) {
|
|
return;
|
|
}
|
|
|
|
// DONE state
|
|
me._readyState = FileReader.DONE;
|
|
|
|
me._result = null;
|
|
|
|
// Save error
|
|
me._error = new FileError(e);
|
|
|
|
// If onerror callback
|
|
if (typeof me.onerror === "function") {
|
|
me.onerror(new ProgressEvent("error", {target:me}));
|
|
}
|
|
|
|
// If onloadend callback
|
|
if (typeof me.onloadend === "function") {
|
|
me.onloadend(new ProgressEvent("loadend", {target:me}));
|
|
}
|
|
}, "File", "readAsBinaryString", execArgs);
|
|
};
|
|
|
|
/**
|
|
* Read file and return data as a binary data.
|
|
*
|
|
* @param file {File} File object containing file properties
|
|
*/
|
|
FileReader.prototype.readAsArrayBuffer = function(file) {
|
|
if (initRead(this, file)) {
|
|
return this._realReader.readAsArrayBuffer(file);
|
|
}
|
|
|
|
var me = this;
|
|
var execArgs = [this._localURL, file.start, file.end];
|
|
|
|
// Read file
|
|
exec(
|
|
// Success callback
|
|
function(r) {
|
|
// If DONE (cancelled), then don't do anything
|
|
if (me._readyState === FileReader.DONE) {
|
|
return;
|
|
}
|
|
|
|
// DONE state
|
|
me._readyState = FileReader.DONE;
|
|
|
|
if (r instanceof Array) {
|
|
r = new Uint8Array(r).buffer;
|
|
}
|
|
me._result = r;
|
|
|
|
// If onload callback
|
|
if (typeof me.onload === "function") {
|
|
me.onload(new ProgressEvent("load", {target:me}));
|
|
}
|
|
|
|
// If onloadend callback
|
|
if (typeof me.onloadend === "function") {
|
|
me.onloadend(new ProgressEvent("loadend", {target:me}));
|
|
}
|
|
},
|
|
// Error callback
|
|
function(e) {
|
|
// If DONE (cancelled), then don't do anything
|
|
if (me._readyState === FileReader.DONE) {
|
|
return;
|
|
}
|
|
|
|
// DONE state
|
|
me._readyState = FileReader.DONE;
|
|
|
|
me._result = null;
|
|
|
|
// Save error
|
|
me._error = new FileError(e);
|
|
|
|
// If onerror callback
|
|
if (typeof me.onerror === "function") {
|
|
me.onerror(new ProgressEvent("error", {target:me}));
|
|
}
|
|
|
|
// If onloadend callback
|
|
if (typeof me.onloadend === "function") {
|
|
me.onloadend(new ProgressEvent("loadend", {target:me}));
|
|
}
|
|
}, "File", "readAsArrayBuffer", execArgs);
|
|
};
|
|
|
|
module.exports = FileReader;
|