diff --git a/README.md b/README.md index 93b5b5c..b95bf97 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ text = await blob.text() // awaits a promise dataUrl = await blob.dataUrl() // awaits a promise stream = blob.stream() // returns a web ReadableStream -// BinaryString has been avoided +// BinaryString has been avoided // - Binaries just don't work well with strings face it. // Send the blob with ajax instead or use ArrayBuffer if you want to work with the data // @@ -32,8 +32,8 @@ stream = blob.stream() // returns a web ReadableStream // Just bonuses // ------------ - -json = await blob.json() // awaits a promise +json = await blob.json() // awaits a promise (rejects if fail to parse) +img = await blob.image() // awaits a new Image object (rejects if fail to load) // returns a blob url (same as [webkit]URL.createObjectURL(blob)) // can also return null if it's not possible like on chrome for iOS... diff --git a/index.js b/index.js index 70127ed..c673377 100644 --- a/index.js +++ b/index.js @@ -8,8 +8,28 @@ var fullStreamSupport = false var basicStreamSupport = false var fetchTransform = false - var url = window.URL || window.webkitURL - + var URL = window.URL || window.webkitURL + + function promisify(obj) { + return new Promise(function(resolve, reject) { + obj.onload = + obj.onerror = function(evt) { + obj.onload = + obj.onerror = null + + evt.type === 'load' + ? resolve(obj.result || obj) + : reject(obj.error) + } + }) + } + + function toImage(url) { + var img = new Image + img.src = url + return promisify(img) + } + try { new ReadableStream({}) basicStreamSupport = true @@ -27,41 +47,31 @@ if(!blob.arrayBuffer) { blob.arrayBuffer = function arrayBuffer() { - var fr = new FileReader() + var fr = new FileReader fr.readAsArrayBuffer(this) - return new Promise(function(resolve, reject) { - fr.onload = function(evt) { resolve(evt.target.result) } - fr.onerror = function(evt) { reject(evt.target.error) } - }) + return promisify(fr) } } - if(!blob.text) { blob.text = function text() { - var fr = new FileReader() + var fr = new FileReader fr.readAsText(this) - return new Promise(function(resolve, reject) { - fr.onload = function(evt) { resolve(evt.target.result) } - fr.onerror = function(evt) { reject(evt.target.error) } - }) + return promisify(fr) } } - + if(!blob.dataURL) { blob.dataURL = function dataURL() { - var fr = new FileReader() + var fr = new FileReader fr.readAsDataURL(this) - return new Promise(function(resolve, reject) { - fr.onload = function(evt) { resolve(evt.target.result) } - fr.onerror = function(evt) { reject(evt.target.error) } - }) + return promisify(fr) } } - + if(!blob.url) { blob.url = function url() { - return url ? null : url.createObjectURL(this) + return URL ? URL.createObjectURL(this) : null } } @@ -71,6 +81,12 @@ } } + if(!blob.image) { + blob.image = function image() { + return Promise.resolve(this.url() || this.dataURL()).then(toImage) + } + } + if(!blob.stream) { blob.stream = @@ -82,11 +98,11 @@ type: 'bytes', autoAllocateChunkSize: 524288, - pull: function(controller) { + pull: function (controller) { var v = controller.byobRequest.view var chunk = blob.slice(position, position + v.byteLength) return chunk.arrayBuffer() - .then(function(buffer) { + .then(function (buffer) { let uint8array = new Uint8Array(buffer) let bytesRead = uint8array.byteLength @@ -96,8 +112,6 @@ if(position >= blob.size) controller.close() - - resolve() }) } }) @@ -109,10 +123,10 @@ var blob = this return new ReadableStream({ - pull: function(controller) { + pull: function (controller) { var chunk = blob.slice(position, position + 524288) - return chunk.arrayBuffer().then(function(buffer) { + return chunk.arrayBuffer().then(function (buffer) { position += buffer.byteLength let uint8array = new Uint8Array(buffer) controller.enqueue(uint8array)