index.js (2531B)
1 /** 2 * Create a blob builder even when vendor prefixes exist 3 */ 4 5 var BlobBuilder = typeof BlobBuilder !== 'undefined' ? BlobBuilder : 6 typeof WebKitBlobBuilder !== 'undefined' ? WebKitBlobBuilder : 7 typeof MSBlobBuilder !== 'undefined' ? MSBlobBuilder : 8 typeof MozBlobBuilder !== 'undefined' ? MozBlobBuilder : 9 false; 10 11 /** 12 * Check if Blob constructor is supported 13 */ 14 15 var blobSupported = (function() { 16 try { 17 var a = new Blob(['hi']); 18 return a.size === 2; 19 } catch(e) { 20 return false; 21 } 22 })(); 23 24 /** 25 * Check if Blob constructor supports ArrayBufferViews 26 * Fails in Safari 6, so we need to map to ArrayBuffers there. 27 */ 28 29 var blobSupportsArrayBufferView = blobSupported && (function() { 30 try { 31 var b = new Blob([new Uint8Array([1,2])]); 32 return b.size === 2; 33 } catch(e) { 34 return false; 35 } 36 })(); 37 38 /** 39 * Check if BlobBuilder is supported 40 */ 41 42 var blobBuilderSupported = BlobBuilder 43 && BlobBuilder.prototype.append 44 && BlobBuilder.prototype.getBlob; 45 46 /** 47 * Helper function that maps ArrayBufferViews to ArrayBuffers 48 * Used by BlobBuilder constructor and old browsers that didn't 49 * support it in the Blob constructor. 50 */ 51 52 function mapArrayBufferViews(ary) { 53 return ary.map(function(chunk) { 54 if (chunk.buffer instanceof ArrayBuffer) { 55 var buf = chunk.buffer; 56 57 // if this is a subarray, make a copy so we only 58 // include the subarray region from the underlying buffer 59 if (chunk.byteLength !== buf.byteLength) { 60 var copy = new Uint8Array(chunk.byteLength); 61 copy.set(new Uint8Array(buf, chunk.byteOffset, chunk.byteLength)); 62 buf = copy.buffer; 63 } 64 65 return buf; 66 } 67 68 return chunk; 69 }); 70 } 71 72 function BlobBuilderConstructor(ary, options) { 73 options = options || {}; 74 75 var bb = new BlobBuilder(); 76 mapArrayBufferViews(ary).forEach(function(part) { 77 bb.append(part); 78 }); 79 80 return (options.type) ? bb.getBlob(options.type) : bb.getBlob(); 81 }; 82 83 function BlobConstructor(ary, options) { 84 return new Blob(mapArrayBufferViews(ary), options || {}); 85 }; 86 87 if (typeof Blob !== 'undefined') { 88 BlobBuilderConstructor.prototype = Blob.prototype; 89 BlobConstructor.prototype = Blob.prototype; 90 } 91 92 module.exports = (function() { 93 if (blobSupported) { 94 return blobSupportsArrayBufferView ? Blob : BlobConstructor; 95 } else if (blobBuilderSupported) { 96 return BlobBuilderConstructor; 97 } else { 98 return undefined; 99 } 100 })();