Skip to content

Commit

Permalink
Support Promise[Blob].
Browse files Browse the repository at this point in the history
The old code didn't accept promises containing blobs which cause issues
when working with canvas. There are two ways to get a binary content from
a canvas: `canvas.toDataURL()` and `canvas.toBlob()`. Working with the
first one involves a substring to remove the data url part and a base64
decode. The other one ends up with a Promise[Blob], fixed by this
commit. Now, we can extract the binary content of a canvas like:

```js
var p = new JSZip.external.Promise(function (resolve, reject) {
    canvas.toBlob(function (blob) {
        resolve(blob);
    });
});
```
  • Loading branch information
dduponchel committed Jul 18, 2016
1 parent 3a4a815 commit af944ad
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 33 deletions.
35 changes: 18 additions & 17 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -418,23 +418,24 @@ exports.extend = function() {
*/
exports.prepareContent = function(name, inputData, isBinary, isOptimizedBinaryString, isBase64) {

var promise = null;
if (support.blob && inputData instanceof Blob && typeof FileReader !== "undefined") {
promise = new external.Promise(function (resolve, reject) {
var reader = new FileReader();

reader.onload = function(e) {
resolve(e.target.result);
};
reader.onerror = function(e) {
reject(e.target.error);
};
reader.readAsArrayBuffer(inputData);
});
} else {
// if data is already a promise, this flatten it.
promise = external.Promise.resolve(inputData);
}
// if inputData is already a promise, this flatten it.
var promise = external.Promise.resolve(inputData).then(function(data) {
if (support.blob && data instanceof Blob && typeof FileReader !== "undefined") {
return new external.Promise(function (resolve, reject) {

This comment has been minimized.

Copy link
@jimmywarting

jimmywarting May 10, 2021

Contributor

You can pretty much just do return data.arrayBuffer() now days and not have to deal with the FileReader

var reader = new FileReader();

reader.onload = function(e) {
resolve(e.target.result);
};
reader.onerror = function(e) {
reject(e.target.error);
};
reader.readAsArrayBuffer(data);
});
} else {
return data;
}
});

return promise.then(function(data) {
var dataType = exports.getTypeOf(data);
Expand Down
55 changes: 39 additions & 16 deletions test/asserts/file.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,21 @@

QUnit.module("file", function () {

function str2blob (str) {
var u8 = new Uint8Array(str.length);
for(var i = 0; i < str.length; i++) {
u8[i] = str.charCodeAt(i);
}
try {
// don't use an Uint8Array, see the comment on utils.newBlob
return new Blob([u8.buffer], {type:"text/plain"});
} catch (e) {
var Builder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder;
var builder = new Builder();
builder.append(u8.buffer);
return builder.getBlob("text/plain");
}
}

QUnit.module("add");

Expand Down Expand Up @@ -356,21 +371,6 @@ QUnit.module("file", function () {

if (JSZip.support.blob) {
test("add file: file(name, Blob)", function() {
var str2blob = function (str) {
var array = new Uint8Array(str.length);
for(var i = 0; i < str.length; i++) {
array[i] = str.charCodeAt(i);
}
try {
// don't use an Uint8Array, see the comment on utils.newBlob
return new Blob([array.buffer], {type:"text/plain"});
} catch (e) {
var Builder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder;
var builder = new Builder();
builder.append(array.buffer);
return builder.getBlob("text/plain");
}
};
var zip = new JSZip();
zip.file("file.txt", str2blob("\xE2\x82\xAC15\n"));
testFileDataGetters({name : "utf8", zip : zip, textData : "€15\n", rawData : "\xE2\x82\xAC15\n"});
Expand Down Expand Up @@ -408,7 +408,7 @@ QUnit.module("file", function () {
});
}

test("add file: file(name, polyfill Promise)", function() {
test("add file: file(name, polyfill Promise[string])", function() {
var str2promise = function (str) {
return new JSZip.external.Promise(function(resolve, reject) {
setTimeout(function () {
Expand All @@ -429,6 +429,29 @@ QUnit.module("file", function () {
testFileDataGetters({name : "empty content", zip : zip, textData : ""});
});

if (JSZip.support.blob) {
test("add file: file(name, polyfill Promise[Blob])", function() {
var str2promiseOfBlob = function (str) {
return new JSZip.external.Promise(function(resolve, reject) {
setTimeout(function () {
resolve(str2blob(str));
}, 10);
});
};
var zip = new JSZip();
zip.file("file.txt", str2promiseOfBlob("\xE2\x82\xAC15\n"));
testFileDataGetters({name : "utf8", zip : zip, textData : "€15\n", rawData : "\xE2\x82\xAC15\n"});

zip = new JSZip();
zip.file("file.txt", str2promiseOfBlob("test\r\ntest\r\n"));
testFileDataGetters({name : "\\r\\n", zip : zip, textData : "test\r\ntest\r\n"});

zip = new JSZip();
zip.file("file.txt", str2promiseOfBlob(""));
testFileDataGetters({name : "empty content", zip : zip, textData : ""});
});
}

if (JSZip.support.nodebuffer) {
test("add file: file(name, Buffer)", function() {
var str2buffer = function (str) {
Expand Down

0 comments on commit af944ad

Please sign in to comment.