/** | |
* 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; | |
} | |
})(); |