101 lines
2.5 KiB
JavaScript
Executable File
101 lines
2.5 KiB
JavaScript
Executable File
/**
|
|
* Create a blob builder even when vendor prefixes exist
|
|
*/
|
|
|
|
var BlobBuilder = typeof BlobBuilder !== 'undefined' ? BlobBuilder :
|
|
typeof WebKitBlobBuilder !== 'undefined' ? WebKitBlobBuilder :
|
|
typeof MSBlobBuilder !== 'undefined' ? MSBlobBuilder :
|
|
typeof MozBlobBuilder !== 'undefined' ? MozBlobBuilder :
|
|
false;
|
|
|
|
/**
|
|
* Check if Blob constructor is supported
|
|
*/
|
|
|
|
var blobSupported = (function() {
|
|
try {
|
|
var a = new Blob(['hi']);
|
|
return a.size === 2;
|
|
} catch(e) {
|
|
return false;
|
|
}
|
|
})();
|
|
|
|
/**
|
|
* Check if Blob constructor supports ArrayBufferViews
|
|
* Fails in Safari 6, so we need to map to ArrayBuffers there.
|
|
*/
|
|
|
|
var blobSupportsArrayBufferView = blobSupported && (function() {
|
|
try {
|
|
var b = new Blob([new Uint8Array([1,2])]);
|
|
return b.size === 2;
|
|
} catch(e) {
|
|
return false;
|
|
}
|
|
})();
|
|
|
|
/**
|
|
* Check if BlobBuilder is supported
|
|
*/
|
|
|
|
var blobBuilderSupported = BlobBuilder
|
|
&& BlobBuilder.prototype.append
|
|
&& BlobBuilder.prototype.getBlob;
|
|
|
|
/**
|
|
* Helper function that maps ArrayBufferViews to ArrayBuffers
|
|
* Used by BlobBuilder constructor and old browsers that didn't
|
|
* support it in the Blob constructor.
|
|
*/
|
|
|
|
function mapArrayBufferViews(ary) {
|
|
return ary.map(function(chunk) {
|
|
if (chunk.buffer instanceof ArrayBuffer) {
|
|
var buf = chunk.buffer;
|
|
|
|
// if this is a subarray, make a copy so we only
|
|
// include the subarray region from the underlying buffer
|
|
if (chunk.byteLength !== buf.byteLength) {
|
|
var copy = new Uint8Array(chunk.byteLength);
|
|
copy.set(new Uint8Array(buf, chunk.byteOffset, chunk.byteLength));
|
|
buf = copy.buffer;
|
|
}
|
|
|
|
return buf;
|
|
}
|
|
|
|
return chunk;
|
|
});
|
|
}
|
|
|
|
function BlobBuilderConstructor(ary, options) {
|
|
options = options || {};
|
|
|
|
var bb = new BlobBuilder();
|
|
mapArrayBufferViews(ary).forEach(function(part) {
|
|
bb.append(part);
|
|
});
|
|
|
|
return (options.type) ? bb.getBlob(options.type) : bb.getBlob();
|
|
};
|
|
|
|
function BlobConstructor(ary, options) {
|
|
return new Blob(mapArrayBufferViews(ary), options || {});
|
|
};
|
|
|
|
if (typeof Blob !== 'undefined') {
|
|
BlobBuilderConstructor.prototype = Blob.prototype;
|
|
BlobConstructor.prototype = Blob.prototype;
|
|
}
|
|
|
|
module.exports = (function() {
|
|
if (blobSupported) {
|
|
return blobSupportsArrayBufferView ? Blob : BlobConstructor;
|
|
} else if (blobBuilderSupported) {
|
|
return BlobBuilderConstructor;
|
|
} else {
|
|
return undefined;
|
|
}
|
|
})();
|