move to esm, add more API support, remove Promise polyfill

This commit is contained in:
Nolan Lawson 2018-05-19 22:08:47 -07:00
parent 563fec34af
commit 66ee2d8fcb
8 changed files with 452 additions and 822 deletions

View File

@ -10,12 +10,10 @@
"eqnull": true,
"browser": true,
"node": true,
"strict": true,
"globalstrict": true,
"globals": { "Pouch": true},
"white": true,
"indent": 2,
"maxlen": 120,
"esnext": true,
"predef": [
"process",
"global",

14
CHANGELOG.md Normal file
View File

@ -0,0 +1,14 @@
Changelog
====
## V2.0.0
- Removed built-in `Promise` polyfill
- Some APIs that returned Promises now return bare values
- Removed Bower support
- Added ES module support
- Added `arrayBufferToBinaryString` and `binaryStringToArrayBuffer`
## v1.0.0
- Initial release

View File

@ -44,8 +44,12 @@ Now you have a `window.blobUtil` object. Or if you don't like globals, you can u
Browser support
-----
As of v2.0.0, a built-in `Promise` polyfill is no longer provided. Assuming you provide a Promise
polyfill, the supported browsers are:
* Firefox
* Chrome
* Edge
* IE 10+
* Safari 6+
* iOS 6+
@ -100,8 +104,6 @@ So now we have two Kirbys - one with a normal URL, and the other with a blob URL
API
-------
Warning: this API uses [Promises](https://promisesaplus.com/), because it's not 2009 anymore.
### Overview
* [createBlob(parts, options)](#createBlob)
@ -118,6 +120,8 @@ Warning: this API uses [Promises](https://promisesaplus.com/), because it's not
* [imgSrcToBlob(src, type, crossOrigin, quality)](#imgSrcToBlob)
* [arrayBufferToBlob(buffer, type)](#arrayBufferToBlob)
* [blobToArrayBuffer(blob)](#blobToArrayBuffer)
* [arrayBufferToBinaryString(buffer)](#arrayBufferToBinaryString)
* [binaryStringToArrayBuffer(binary)](#binaryStringToArrayBuffer)
<a name="createBlob"></a>
### createBlob(parts, options)
@ -452,10 +456,42 @@ blobUtil.blobToArrayBuffer(blob).then(function (arrayBuff) {
});
```
<a name="arrayBufferToBinaryString"></a>
### arrayBufferToBinaryString(buffer)
Convert an <code>ArrayBuffer</code> to a binary string. Returns the binary string.
**Params**
- buffer `ArrayBuffer`
**Returns**: binary string
**Example**:
```js
var myString = blobUtil.arrayBufferToBinaryString(arrayBuff)
```
<a name="binaryStringToArrayBuffer"></a>
### binaryStringToArrayBuffer(binary)
Convert a binary string to an <code>ArrayBuffer</code> to a binary string. Returns the <code>ArrayBuffer</code>
**Params**
- binary string
**Returns**: `ArrayBuffer`
**Example**:
```js
var myBuffer = blobUtil.binaryStringToArrayBuffer(binaryString)
```
Credits
----
Thanks to [webmodules/blob](https://github.com/webmodules/blob) for the Blob constructor shim, and to the rest of [the PouchDB team](https://github.com/pouchdb/pouchdb/graphs/contributors) for figuring most of this crazy stuff out.
Thanks to the rest of [the PouchDB team](https://github.com/pouchdb/pouchdb/graphs/contributors) for figuring most of this crazy stuff out.
Building the library
----

1035
dist/blob-util.js vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -2,7 +2,8 @@
"name": "blob-util",
"version": "1.3.0",
"description": "Utilities for working with Blob objects in the browser",
"main": "lib/index.js",
"main": "dist/blob-util.cjs.js",
"module": "dist/blob-util.es.js",
"repository": {
"type": "git",
"url": "git://github.com/nolanlawson/blob-util.git"
@ -20,36 +21,35 @@
"url": "https://github.com/nolanlawson/blob-util/issues"
},
"scripts": {
"jshint": "jshint -c .jshintrc lib/*.js test/test.js",
"test": "npm run jshint && zuul ./test/test.js",
"test-local": "zuul ./test/test.js --local 9000",
"build": "mkdirp dist && npm run browserify && npm run min",
"browserify": "browserify . -p bundle-collapser/plugin -s blobUtil | browserify-transform-cli es3ify | derequire > dist/blob-util.js",
"jshint": "jshint -c .jshintrc src/*.js test/test.js",
"test": "npm run build && npm run jshint && zuul --no-coverage ./test/test.js",
"test-local": "npm run build && zuul ./test/test.js --local 9000 --no-coverage",
"clean": "rimraf dist && mkdirp dist",
"build": "run-s clean build-for-node build-for-browser min",
"build-for-node": "rollup -i src/index.js -f es > dist/blob-util.es.js && rollup -i src/index.js -f cjs > dist/blob-util.cjs.js",
"build-for-browser": "rollup -i src/index.js -f umd -n blobUtil > dist/blob-util.js",
"min": "uglifyjs dist/blob-util.js -mc > dist/blob-util.min.js"
},
"dependencies": {
"blob": "0.0.4",
"native-or-lie": "1.0.2"
},
"devDependencies": {
"browserify": "^9.0.3",
"browserify-transform-cli": "^1.1.1",
"bundle-collapser": "^1.1.4",
"chai": "~1.8.1",
"chai-as-promised": "~4.1.0",
"derequire": "^2.0.0",
"es3ify": "^0.1.3",
"istanbul": "^0.2.7",
"jshint": "~2.3.0",
"mkdirp": "^0.5.0",
"mocha": "~1.18",
"native-or-lie": "1.0.2",
"npm-run-all": "^4.1.3",
"request": "^2.36.0",
"rimraf": "^2.6.2",
"rollup": "^0.59.1",
"uglify-js": "^2.4.13",
"zuul": "^3.10.1",
"zuul-ngrok": "nolanlawson/zuul-ngrok#patch-1"
},
"files": [
"lib",
"dist"
]
}

View File

@ -1,39 +1,6 @@
'use strict';
/* jshint -W079 */
var Blob = require('blob');
var Promise = require('native-or-lie');
//
// PRIVATE
//
// From http://stackoverflow.com/questions/14967647/ (continues on next line)
// encode-decode-image-with-base64-breaks-image (2013-04-21)
function binaryStringToArrayBuffer(binary) {
var length = binary.length;
var buf = new ArrayBuffer(length);
var arr = new Uint8Array(buf);
var i = -1;
while (++i < length) {
arr[i] = binary.charCodeAt(i);
}
return buf;
}
// Can't find original post, but this is close
// http://stackoverflow.com/questions/6965107/ (continues on next line)
// converting-between-strings-and-arraybuffers
function arrayBufferToBinaryString(buffer) {
var binary = '';
var bytes = new Uint8Array(buffer);
var length = bytes.byteLength;
var i = -1;
while (++i < length) {
binary += String.fromCharCode(bytes[i]);
}
return binary;
}
/* global Promise */
/* exported createObjectURL, revokeObjectURL, binaryStringToBlob, blobToDataURL,
imgSrcToDataURL, imgSrcToBlob, arrayBufferToBlob, blobToArrayBuffer */
// doesn't download the image more than once, because
// browsers aren't dumb. uses the cache
@ -69,9 +36,37 @@ function imgToCanvas(img) {
return canvas;
}
//
// PUBLIC
//
/**
* Convert a binary string to an array buffer.
* @param {string} binary - binary string
* @returns {ArrayBuffer}
*/
export function binaryStringToArrayBuffer(binary) {
var length = binary.length;
var buf = new ArrayBuffer(length);
var arr = new Uint8Array(buf);
var i = -1;
while (++i < length) {
arr[i] = binary.charCodeAt(i);
}
return buf;
}
/**
* Convert an array buffer to a binary string
* @param {ArrayBuffer} buffer - array buffer
* @returns {string}
*/
export function arrayBufferToBinaryString(buffer) {
var binary = '';
var bytes = new Uint8Array(buffer);
var length = bytes.byteLength;
var i = -1;
while (++i < length) {
binary += String.fromCharCode(bytes[i]);
}
return binary;
}
/**
* Shim for
@ -80,15 +75,32 @@ function imgToCanvas(img) {
* [older browsers that use the deprecated <code>BlobBuilder</code> API]{@link http://caniuse.com/blob}.
*
* @param {Array} parts - content of the <code>Blob</code>
* @param {Object} options - usually just <code>{type: myContentType}</code>
* @param {Object} options - usually <code>{type: myContentType}</code>, you can also pass a string
* @returns {Blob}
*/
function createBlob(parts, options) {
options = options || {};
if (typeof options === 'string') {
options = {type: options}; // do you a solid here
export function createBlob(parts, properties) {
/* global BlobBuilder,MSBlobBuilder,MozBlobBuilder,WebKitBlobBuilder */
parts = parts || [];
properties = properties || {};
if (typeof properties === 'string') {
properties = {type: properties}; // infer content type
}
try {
return new Blob(parts, properties);
} catch (e) {
if (e.name !== 'TypeError') {
throw e;
}
var Builder = typeof BlobBuilder !== 'undefined' ?
BlobBuilder : typeof MSBlobBuilder !== 'undefined' ?
MSBlobBuilder : typeof MozBlobBuilder !== 'undefined' ?
MozBlobBuilder : WebKitBlobBuilder;
var builder = new Builder();
for (var i = 0; i < parts.length; i += 1) {
builder.append(parts[i]);
}
return builder.getBlob(properties.type);
}
return new Blob(parts, options);
}
/**
@ -99,7 +111,7 @@ function createBlob(parts, options) {
* @param {Blob} blob
* @returns {string} url
*/
function createObjectURL(blob) {
export function createObjectURL(blob) {
return (window.URL || window.webkitURL).createObjectURL(blob);
}
@ -110,7 +122,7 @@ function createObjectURL(blob) {
* <code>webkitURL</code> (e.g. Android <4.4).
* @param {string} url
*/
function revokeObjectURL(url) {
export function revokeObjectURL(url) {
return (window.URL || window.webkitURL).revokeObjectURL(url);
}
@ -120,7 +132,7 @@ function revokeObjectURL(url) {
* @param {Blob} blob
* @returns {Promise} Promise that resolves with the binary string
*/
function blobToBinaryString(blob) {
export function blobToBinaryString(blob) {
return new Promise(function (resolve, reject) {
var reader = new FileReader();
var hasBinaryString = typeof reader.readAsBinaryString === 'function';
@ -146,7 +158,7 @@ function blobToBinaryString(blob) {
* @param {string|undefined} type - the content type (optional)
* @returns {Promise} Promise that resolves with the <code>Blob</code>
*/
function base64StringToBlob(base64, type) {
export function base64StringToBlob(base64, type) {
return Promise.resolve().then(function () {
var parts = [binaryStringToArrayBuffer(atob(base64))];
return type ? createBlob(parts, {type: type}) : createBlob(parts);
@ -159,7 +171,7 @@ function base64StringToBlob(base64, type) {
* @param {string|undefined} type - the content type (optional)
* @returns {Promise} Promise that resolves with the <code>Blob</code>
*/
function binaryStringToBlob(binary, type) {
export function binaryStringToBlob(binary, type) {
return Promise.resolve().then(function () {
return base64StringToBlob(btoa(binary), type);
});
@ -170,7 +182,7 @@ function binaryStringToBlob(binary, type) {
* @param {Blob} blob
* @returns {Promise} Promise that resolves with the binary string
*/
function blobToBase64String(blob) {
export function blobToBase64String(blob) {
return blobToBinaryString(blob).then(function (binary) {
return btoa(binary);
});
@ -183,7 +195,7 @@ function blobToBase64String(blob) {
* @param {string} dataURL
* @returns {Promise} Promise that resolves with the <code>Blob</code>
*/
function dataURLToBlob(dataURL) {
export function dataURLToBlob(dataURL) {
return Promise.resolve().then(function () {
var type = dataURL.match(/data:([^;]+)/)[1];
var base64 = dataURL.replace(/^[^,]+,/, '');
@ -200,7 +212,7 @@ function dataURLToBlob(dataURL) {
* @param {Blob} blob
* @returns {Promise} Promise that resolves with the data URL string
*/
function blobToDataURL(blob) {
export function blobToDataURL(blob) {
return blobToBase64String(blob).then(function (base64String) {
return 'data:' + blob.type + ';base64,' + base64String;
});
@ -221,7 +233,7 @@ function blobToDataURL(blob) {
* if the requested type is 'image/jpeg' or 'image/webp'
* @returns {Promise} Promise that resolves with the data URL string
*/
function imgSrcToDataURL(src, type, crossOrigin, quality) {
export function imgSrcToDataURL(src, type, crossOrigin, quality) {
type = type || 'image/png';
return loadImage(src, crossOrigin).then(function (img) {
@ -239,7 +251,7 @@ function imgSrcToDataURL(src, type, crossOrigin, quality) {
* if the requested type is 'image/jpeg' or 'image/webp'
* @returns {Promise} Promise that resolves with the <code>Blob</code>
*/
function canvasToBlob(canvas, type, quality) {
export function canvasToBlob(canvas, type, quality) {
return Promise.resolve().then(function () {
if (typeof canvas.toBlob === 'function') {
return new Promise(function (resolve) {
@ -265,7 +277,7 @@ function canvasToBlob(canvas, type, quality) {
* if the requested type is 'image/jpeg' or 'image/webp'
* @returns {Promise} Promise that resolves with the <code>Blob</code>
*/
function imgSrcToBlob(src, type, crossOrigin, quality) {
export function imgSrcToBlob(src, type, crossOrigin, quality) {
type = type || 'image/png';
return loadImage(src, crossOrigin).then(function (img) {
@ -282,7 +294,7 @@ function imgSrcToBlob(src, type, crossOrigin, quality) {
* @param {string|undefined} type - the content type (optional)
* @returns {Promise} Promise that resolves with the <code>Blob</code>
*/
function arrayBufferToBlob(buffer, type) {
export function arrayBufferToBlob(buffer, type) {
return Promise.resolve().then(function () {
return createBlob([buffer], type);
});
@ -293,7 +305,7 @@ function arrayBufferToBlob(buffer, type) {
* @param {Blob} blob
* @returns {Promise} Promise that resolves with the <code>ArrayBuffer</code>
*/
function blobToArrayBuffer(blob) {
export function blobToArrayBuffer(blob) {
return new Promise(function (resolve, reject) {
var reader = new FileReader();
reader.onloadend = function (e) {
@ -304,20 +316,3 @@ function blobToArrayBuffer(blob) {
reader.readAsArrayBuffer(blob);
});
}
module.exports = {
createBlob : createBlob,
createObjectURL : createObjectURL,
revokeObjectURL : revokeObjectURL,
imgSrcToBlob : imgSrcToBlob,
imgSrcToDataURL : imgSrcToDataURL,
canvasToBlob : canvasToBlob,
dataURLToBlob : dataURLToBlob,
blobToDataURL : blobToDataURL,
blobToBase64String : blobToBase64String,
base64StringToBlob : base64StringToBlob,
binaryStringToBlob : binaryStringToBlob,
blobToBinaryString : blobToBinaryString,
arrayBufferToBlob : arrayBufferToBlob,
blobToArrayBuffer : blobToArrayBuffer
};

View File

@ -1,6 +1,10 @@
'use strict';
var blobUtil = require('../lib');
if (typeof Promise === 'undefined') {
window.Promise = require('native-or-lie');
}
var blobUtil = require('../dist/blob-util.cjs.js');
var chai = require('chai');
chai.use(require("chai-as-promised"));