- Specify HTML5 - Allow drag and drop for loading configurationsmaster
parent
09a385d9b0
commit
ac7a4358d6
@ -0,0 +1,79 @@
|
|||||||
|
function BinaryFileUploader(o) {
|
||||||
|
this.options = null;
|
||||||
|
|
||||||
|
|
||||||
|
this._defaultOptions = {
|
||||||
|
element: null, // HTML file element
|
||||||
|
onFileLoad: function(file) {
|
||||||
|
console.log(file.toString());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
this._init = function(o) {
|
||||||
|
if (!this.hasFileUploaderSupport()) return;
|
||||||
|
|
||||||
|
this._verifyDependencies();
|
||||||
|
|
||||||
|
this.options = this._mergeObjects(this._defaultOptions, o);
|
||||||
|
this._verifyOptions();
|
||||||
|
|
||||||
|
this.addFileChangeListener();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
this.hasFileUploaderSupport = function() {
|
||||||
|
return !!(window.File && window.FileReader && window.FileList && window.Blob);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.addFileChangeListener = function() {
|
||||||
|
this.options.element.addEventListener(
|
||||||
|
'change',
|
||||||
|
this._bind(this, this.onFileChange)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.onFileChange = function(e) {
|
||||||
|
// TODO accept multiple files
|
||||||
|
var file = e.target.files[0],
|
||||||
|
reader = new FileReader();
|
||||||
|
|
||||||
|
reader.onload = this._bind(this, this.onFileLoad);
|
||||||
|
reader.readAsBinaryString(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.onFileLoad = function(e) {
|
||||||
|
var content = e.target.result,
|
||||||
|
string = new BinaryString(content);
|
||||||
|
this.options.onFileLoad(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
this._mergeObjects = function(starting, override) {
|
||||||
|
var merged = starting;
|
||||||
|
for (key in override) merged[key] = override[key];
|
||||||
|
|
||||||
|
return merged;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._verifyOptions = function() {
|
||||||
|
if (!(this.options.element && this.options.element.type && this.options.element.type === 'file')) {
|
||||||
|
throw 'Invalid element param in options. Must be a file upload DOM element';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof this.options.onFileLoad !== 'function') {
|
||||||
|
throw 'Invalid onFileLoad param in options. Must be a function';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this._verifyDependencies = function() {
|
||||||
|
if (!window.BinaryString) throw 'BinaryString is missing. Check that you\'ve correctly included it';
|
||||||
|
}
|
||||||
|
|
||||||
|
// helper function for binding methods to objects
|
||||||
|
this._bind = function(object, method) {
|
||||||
|
return function() {return method.apply(object, arguments);};
|
||||||
|
}
|
||||||
|
|
||||||
|
this._init(o);
|
||||||
|
}
|
@ -0,0 +1,168 @@
|
|||||||
|
function BinaryString(source) {
|
||||||
|
this._source = null;
|
||||||
|
this._bytes = [];
|
||||||
|
this._pos = 0;
|
||||||
|
this._length = 0;
|
||||||
|
|
||||||
|
this._init = function(source) {
|
||||||
|
this._source = source;
|
||||||
|
this._bytes = this._stringToBytes(this._source);
|
||||||
|
this._length = this._bytes.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.current = function() {return this._pos;}
|
||||||
|
|
||||||
|
this.rewind = function() {return this.jump(0);}
|
||||||
|
this.end = function() {return this.jump(this.length() - 1);}
|
||||||
|
this.next = function() {return this.jump(this.current() + 1);}
|
||||||
|
this.prev = function() {return this.jump(this.current() - 1);}
|
||||||
|
|
||||||
|
this.jump = function(pos) {
|
||||||
|
if (pos < 0 || pos >= this.length()) return false;
|
||||||
|
|
||||||
|
this._pos = pos;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.readByte = function(pos) {
|
||||||
|
pos = (typeof pos == 'number') ? pos : this.current();
|
||||||
|
return this.readBytes(1, pos)[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
this.readBytes = function(length, pos) {
|
||||||
|
length = length || 1;
|
||||||
|
pos = (typeof pos == 'number') ? pos : this.current();
|
||||||
|
|
||||||
|
if (pos > this.length() ||
|
||||||
|
pos < 0 ||
|
||||||
|
length <= 0 ||
|
||||||
|
pos + length > this.length() ||
|
||||||
|
pos + length < 0
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var bytes = [];
|
||||||
|
|
||||||
|
for (var i = pos; i < pos + length; i++) {
|
||||||
|
bytes.push(this._bytes[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.length = function() {return this._length;}
|
||||||
|
|
||||||
|
this.toString = function() {
|
||||||
|
var string = '',
|
||||||
|
length = this.length();
|
||||||
|
|
||||||
|
for (var i = 0; i < length; i++) {
|
||||||
|
string += String.fromCharCode(this.readByte(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.toUtf8 = function() {
|
||||||
|
var inc = 0,
|
||||||
|
string = '',
|
||||||
|
length = this.length();
|
||||||
|
|
||||||
|
// determine if first 3 characters are the BOM
|
||||||
|
// then skip them in output if so
|
||||||
|
if (length >= 3 &&
|
||||||
|
this.readByte(0) === 0xEF &&
|
||||||
|
this.readByte(1) === 0xBB &&
|
||||||
|
this.readByte(2) === 0xBF
|
||||||
|
) {
|
||||||
|
inc = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; inc < length; inc++) {
|
||||||
|
var byte1 = this.readByte(inc),
|
||||||
|
byte2 = 0,
|
||||||
|
byte3 = 0,
|
||||||
|
byte4 = 0,
|
||||||
|
code1 = 0,
|
||||||
|
code2 = 0,
|
||||||
|
point = 0;
|
||||||
|
|
||||||
|
switch (true) {
|
||||||
|
// single byte character; same as ascii
|
||||||
|
case (byte1 < 0x80):
|
||||||
|
code1 = byte1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// 2 byte character
|
||||||
|
case (byte1 >= 0xC2 && byte1 < 0xE0):
|
||||||
|
byte2 = this.readByte(++inc);
|
||||||
|
|
||||||
|
code1 = ((byte1 & 0x1F) << 6) +
|
||||||
|
(byte2 & 0x3F);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// 3 byte character
|
||||||
|
case (byte1 >= 0xE0 && byte1 < 0xF0):
|
||||||
|
byte2 = this.readByte(++inc);
|
||||||
|
byte3 = this.readByte(++inc);
|
||||||
|
|
||||||
|
code1 = ((byte1 & 0xFF) << 12) +
|
||||||
|
((byte2 & 0x3F) << 6) +
|
||||||
|
(byte3 & 0x3F);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// 4 byte character
|
||||||
|
case (byte1 >= 0xF0 && byte1 < 0xF5):
|
||||||
|
byte2 = this.readByte(++inc);
|
||||||
|
byte3 = this.readByte(++inc);
|
||||||
|
byte4 = this.readByte(++inc);
|
||||||
|
|
||||||
|
point = ((byte1 & 0x07) << 18) +
|
||||||
|
((byte2 & 0x3F) << 12) +
|
||||||
|
((byte3 & 0x3F) << 6) +
|
||||||
|
(byte4 & 0x3F)
|
||||||
|
point -= 0x10000;
|
||||||
|
|
||||||
|
code1 = (point >> 10) + 0xD800;
|
||||||
|
code2 = (point & 0x3FF) + 0xDC00;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw 'Invalid byte ' + this._byteToString(byte1) + ' whilst converting to UTF-8';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
string += (code2) ? String.fromCharCode(code1, code2)
|
||||||
|
: String.fromCharCode(code1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.toArray = function() {return this.readBytes(this.length() - 1, 0);}
|
||||||
|
|
||||||
|
|
||||||
|
this._stringToBytes = function(str) {
|
||||||
|
var bytes = [],
|
||||||
|
chr = 0;
|
||||||
|
|
||||||
|
for (var i = 0; i < str.length; i++) {
|
||||||
|
chr = str.charCodeAt(i);
|
||||||
|
bytes.push(chr & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._byteToString = function(byte) {
|
||||||
|
var asString = byte.toString(16).toUpperCase();
|
||||||
|
while (asString.length < 2) {
|
||||||
|
asString = '0' + asString;
|
||||||
|
}
|
||||||
|
|
||||||
|
return '0x' + asString;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._init(source);
|
||||||
|
}
|
Loading…
Reference in new issue