You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

96 lines
2.1 KiB

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