Skip to content

Commit 3dbf7cb

Browse files
committed
v8.0.20240630
1 parent 53d1119 commit 3dbf7cb

File tree

5 files changed

+161
-120
lines changed

5 files changed

+161
-120
lines changed

.github/workflows/node.js.yml

+4-3
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,15 @@ jobs:
1616

1717
strategy:
1818
matrix:
19-
node-version: [12, 14, 16, 17]
19+
node-version: [12, 14, 16, 18, 20, 22]
2020

2121
steps:
22-
- uses: actions/checkout@v2
22+
- uses: actions/checkout@v4
2323
- name: Use Node.js ${{ matrix.node-version }}
24-
uses: actions/setup-node@v1
24+
uses: actions/setup-node@v4
2525
with:
2626
node-version: ${{ matrix.node-version }}
2727
- run: npm i
2828
- run: npm run build --if-present
29+
- run: npm run lint
2930
- run: npm test

Blob.js

+106-99
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,40 @@
88
* See https://github.com/eligrey/Blob.js/blob/master/LICENSE.md
99
*/
1010

11+
function array2base64 (input) {
12+
var byteToCharMap = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
13+
14+
var output = [];
15+
16+
for (var i = 0; i < input.length; i += 3) {
17+
var byte1 = input[i];
18+
var haveByte2 = i + 1 < input.length;
19+
var byte2 = haveByte2 ? input[i + 1] : 0;
20+
var haveByte3 = i + 2 < input.length;
21+
var byte3 = haveByte3 ? input[i + 2] : 0;
22+
23+
var outByte1 = byte1 >> 2;
24+
var outByte2 = ((byte1 & 0x03) << 4) | (byte2 >> 4);
25+
var outByte3 = ((byte2 & 0x0F) << 2) | (byte3 >> 6);
26+
var outByte4 = byte3 & 0x3F;
27+
28+
if (!haveByte3) {
29+
outByte4 = 64;
30+
31+
if (!haveByte2) {
32+
outByte3 = 64;
33+
}
34+
}
35+
36+
output.push(
37+
byteToCharMap[outByte1], byteToCharMap[outByte2],
38+
byteToCharMap[outByte3], byteToCharMap[outByte4]
39+
);
40+
}
41+
42+
return output.join("");
43+
}
44+
1145
(function(global) {
1246
(function (factory) {
1347
if (typeof define === "function" && define.amd) {
@@ -263,39 +297,6 @@
263297
}
264298
return view;
265299
}
266-
function array2base64 (input) {
267-
var byteToCharMap = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
268-
269-
var output = [];
270-
271-
for (var i = 0; i < input.length; i += 3) {
272-
var byte1 = input[i];
273-
var haveByte2 = i + 1 < input.length;
274-
var byte2 = haveByte2 ? input[i + 1] : 0;
275-
var haveByte3 = i + 2 < input.length;
276-
var byte3 = haveByte3 ? input[i + 2] : 0;
277-
278-
var outByte1 = byte1 >> 2;
279-
var outByte2 = ((byte1 & 0x03) << 4) | (byte2 >> 4);
280-
var outByte3 = ((byte2 & 0x0F) << 2) | (byte3 >> 6);
281-
var outByte4 = byte3 & 0x3F;
282-
283-
if (!haveByte3) {
284-
outByte4 = 64;
285-
286-
if (!haveByte2) {
287-
outByte3 = 64;
288-
}
289-
}
290-
291-
output.push(
292-
byteToCharMap[outByte1], byteToCharMap[outByte2],
293-
byteToCharMap[outByte3], byteToCharMap[outByte4]
294-
);
295-
}
296-
297-
return output.join("");
298-
}
299300

300301
var create = Object.create || function (a) {
301302
function c () {}
@@ -384,6 +385,7 @@
384385
this.type = this.type.toLowerCase();
385386
}
386387
}
388+
Blob.isPolyfill = true;
387389

388390
Blob.prototype.arrayBuffer = function () {
389391
return Promise.resolve(this._buffer.buffer || this._buffer);
@@ -415,6 +417,7 @@
415417
return a;
416418
}
417419

420+
File.isPolyfill = true;
418421
File.prototype = create(Blob.prototype);
419422
File.prototype.constructor = File;
420423

@@ -430,79 +433,21 @@
430433
return "[object File]";
431434
};
432435

433-
/********************************************************/
434-
/* FileReader constructor */
435-
/********************************************************/
436-
function FileReader () {
437-
if (!(this instanceof FileReader)) {
438-
throw new TypeError("Failed to construct 'FileReader': Please use the 'new' operator, this DOM object constructor cannot be called as a function.");
439-
}
440-
441-
var delegate = document.createDocumentFragment();
442-
this.addEventListener = delegate.addEventListener;
443-
this.dispatchEvent = function (evt) {
444-
var local = this["on" + evt.type];
445-
if (typeof local === "function") local(evt);
446-
delegate.dispatchEvent(evt);
447-
};
448-
this.removeEventListener = delegate.removeEventListener;
449-
}
450-
451-
function _read (fr, blob, kind) {
452-
if (!(blob instanceof Blob)) {
453-
throw new TypeError("Failed to execute '" + kind + "' on 'FileReader': parameter 1 is not of type 'Blob'.");
454-
}
455-
456-
fr.result = "";
457-
458-
setTimeout(function () {
459-
this.readyState = FileReader.LOADING;
460-
fr.dispatchEvent(new Event("load"));
461-
fr.dispatchEvent(new Event("loadend"));
462-
});
463-
}
464-
465-
FileReader.EMPTY = 0;
466-
FileReader.LOADING = 1;
467-
FileReader.DONE = 2;
468-
FileReader.prototype.error = null;
469-
FileReader.prototype.onabort = null;
470-
FileReader.prototype.onerror = null;
471-
FileReader.prototype.onload = null;
472-
FileReader.prototype.onloadend = null;
473-
FileReader.prototype.onloadstart = null;
474-
FileReader.prototype.onprogress = null;
475-
476-
FileReader.prototype.readAsDataURL = function (blob) {
477-
_read(this, blob, "readAsDataURL");
478-
this.result = "data:" + blob.type + ";base64," + array2base64(blob._buffer);
479-
};
480-
481-
FileReader.prototype.readAsText = function (blob) {
482-
_read(this, blob, "readAsText");
483-
this.result = textDecode(blob._buffer);
484-
};
485-
486-
FileReader.prototype.readAsArrayBuffer = function (blob) {
487-
_read(this, blob, "readAsText");
488-
// return ArrayBuffer when possible
489-
this.result = (blob._buffer.buffer || blob._buffer).slice();
490-
};
491-
492-
FileReader.prototype.abort = function () {};
493-
494436
/********************************************************/
495437
/* URL */
496438
/********************************************************/
439+
497440
URL.createObjectURL = function (blob) {
498441
return blob instanceof Blob
499442
? "data:" + blob.type + ";base64," + array2base64(blob._buffer)
500443
: createObjectURL.call(URL, blob);
501444
};
445+
URL.createObjectURL.isPolyfill = true;
502446

503447
URL.revokeObjectURL = function (url) {
504448
revokeObjectURL && revokeObjectURL.call(URL, url);
505449
};
450+
URL.revokeObjectURL.isPolyfill = true;
506451

507452
/********************************************************/
508453
/* XHR */
@@ -521,12 +466,10 @@
521466

522467
exports.Blob = Blob;
523468
exports.File = File;
524-
exports.FileReader = FileReader;
525-
exports.URL = URL;
526469
}
527470

528471
function fixFileAndXHR () {
529-
var isIE = !!global.ActiveXObject || (
472+
var isIE = !!global.ActiveXObject || (typeof document !== "undefined" &&
530473
"-ms-scroll-limit" in document.documentElement.style &&
531474
"-ms-ime-align" in document.documentElement.style
532475
);
@@ -549,7 +492,6 @@
549492
try {
550493
new File([], "");
551494
exports.File = global.File;
552-
exports.FileReader = global.FileReader;
553495
} catch (e) {
554496
try {
555497
exports.File = new Function("class File extends Blob {" +
@@ -563,7 +505,7 @@
563505
"return new File([], \"\"), File"
564506
)();
565507
} catch (e) {
566-
exports.File = function (b, d, c) {
508+
exports.File = function File(b, d, c) {
567509
var blob = new Blob(b, c);
568510
var t = c && void 0 !== c.lastModified ? new Date(c.lastModified) : new Date();
569511

@@ -581,6 +523,7 @@
581523
return blob;
582524
};
583525
}
526+
exports.File.isPolyfill = true;
584527
}
585528
}
586529

@@ -594,6 +537,70 @@
594537
FakeBlobBuilder();
595538
}
596539

540+
/********************************************************/
541+
/* FileReader constructor */
542+
/********************************************************/
543+
function FileReader () {
544+
if (!(this instanceof FileReader)) {
545+
throw new TypeError("Failed to construct 'FileReader': Please use the 'new' operator, this DOM object constructor cannot be called as a function.");
546+
}
547+
548+
var delegate = document.createDocumentFragment();
549+
this.addEventListener = delegate.addEventListener;
550+
this.dispatchEvent = function (evt) {
551+
var local = this["on" + evt.type];
552+
if (typeof local === "function") local(evt);
553+
delegate.dispatchEvent(evt);
554+
};
555+
this.removeEventListener = delegate.removeEventListener;
556+
}
557+
558+
function _read (fr, blob, kind) {
559+
if (!(blob instanceof exports.Blob)) {
560+
throw new TypeError("Failed to execute '" + kind + "' on 'FileReader': parameter 1 is not of type 'Blob'.");
561+
}
562+
563+
fr.result = "";
564+
565+
setTimeout(function () {
566+
this.readyState = FileReader.LOADING;
567+
fr.dispatchEvent(new Event("load"));
568+
fr.dispatchEvent(new Event("loadend"));
569+
});
570+
}
571+
572+
FileReader.EMPTY = 0;
573+
FileReader.LOADING = 1;
574+
FileReader.DONE = 2;
575+
FileReader.prototype.error = null;
576+
FileReader.prototype.onabort = null;
577+
FileReader.prototype.onerror = null;
578+
FileReader.prototype.onload = null;
579+
FileReader.prototype.onloadend = null;
580+
FileReader.prototype.onloadstart = null;
581+
FileReader.prototype.onprogress = null;
582+
583+
FileReader.prototype.readAsDataURL = function (blob) {
584+
_read(this, blob, "readAsDataURL");
585+
this.result = "data:" + blob.type + ";base64," + array2base64(blob._buffer);
586+
};
587+
588+
FileReader.prototype.readAsText = function (blob) {
589+
_read(this, blob, "readAsText");
590+
this.result = textDecode(blob._buffer);
591+
};
592+
593+
FileReader.prototype.readAsArrayBuffer = function (blob) {
594+
_read(this, blob, "readAsText");
595+
// return ArrayBuffer when possible
596+
this.result = (blob._buffer.buffer || blob._buffer).slice();
597+
};
598+
599+
FileReader.prototype.abort = function () {};
600+
601+
exports.FileReader = global.FileReader || FileReader;
602+
exports.URL = global.URL || URL;
603+
597604
if (strTag) {
598605
if (!exports.File.prototype[strTag]) exports.File.prototype[strTag] = "File";
599606
if (!exports.Blob.prototype[strTag]) exports.Blob.prototype[strTag] = "Blob";

CHANGELOG.md

+7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# `blob-polyfill` CHANGELOG
22

3+
## v8.0.20240630
4+
* [Blob.js] Change Blob.prototype to global.Blob.prototype (@tmisirpash)
5+
* [Blob.js] Make it work in environments where global.Blob exists, but global.FileReader does not (@bjornstar)
6+
* [Blob.js] Add `isPolyfill` property to the polyfilled versions so we can differentiate them (@bjornstar)
7+
* [test] Unskip tests and update to work in environments with global.Blob & global.File & global.URL (@bjornstar)
8+
* [.github] Update action versions and test node v12-v22 (@bjornstar)
9+
310
## v7.0.20220408
411
* [Blob.js] Do not modify array that is passed into constructor (@zyrong)
512
* [.github] Start automated tests on github (@bjornstar)

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "blob-polyfill",
3-
"version": "7.0.20220408",
3+
"version": "8.0.20240630",
44
"description": "Blob.js implements the W3C Blob interface in browsers that do not natively support it.",
55
"main": "Blob.js",
66
"scripts": {

0 commit comments

Comments
 (0)