Remove IE polyfills and special casing (#2947)

* Remove IE polyfills and special casing

* dashboard: remove `resize-observer-polyfill`

* deps: remove url-parse to use global `URL` instead

* Update documentation for browser support

* Add a migration guide

* Update e2e test platforms

* Remove polyfills from examples and add those missing in CDN bundle

* Use Node.js v16.x on CI because of `AbortController`

* Update bundle builder to produce two builds: `uppy.js` without polyfills, `uppy.legacy.js` with polyfills.

* Upgrade create-react-app deps

* remove null coalescing operator as it's not supported by the build chain

* disable Safari testing (for now)


Co-authored-by: Renée Kooi <renee@kooi.me>
This commit is contained in:
Antoine du Hamel 2021-06-28 11:34:51 +02:00 committed by GitHub
parent a194865fe5
commit c315329399
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
49 changed files with 9386 additions and 7935 deletions

View file

@ -1,8 +1,11 @@
IE 10 [production]
last 2 Safari versions last 2 Safari versions
last 2 Chrome versions last 2 Chrome versions
last 2 ChromeAndroid versions last 2 ChromeAndroid versions
last 2 Firefox versions last 2 Firefox versions
last 2 FirefoxAndroid versions last 2 FirefoxAndroid versions
last 2 Edge versions last 2 Edge versions
iOS 11.2 iOS >=13.4
[legacy]
IE 11

View file

@ -65,7 +65,7 @@ jobs:
- name: Install Node.js - name: Install Node.js
uses: actions/setup-node@v2-beta uses: actions/setup-node@v2-beta
with: with:
node-version: 14.x node-version: 16.x
- name: Install npm 7 - name: Install npm 7
run: npm install --global npm@7 run: npm install --global npm@7
- name: Install dependencies - name: Install dependencies

View file

@ -17,7 +17,7 @@ jobs:
- name: Install Node.js - name: Install Node.js
uses: actions/setup-node@v2-beta uses: actions/setup-node@v2-beta
with: with:
node-version: 14.x node-version: 16.x
- name: Install npm 7 - name: Install npm 7
run: npm install --global npm@7 run: npm install --global npm@7
- name: Install dependencies - name: Install dependencies

View file

@ -14,6 +14,8 @@ In the current stage we aim to release a new version at least every month.
### next ### next
- **BREAKING CHANGE**: Remove built-in polyfills for Internet Explorer and Safari ≤13.0.
## June 2021 ## June 2021
To be released: 2021-06-28 To be released: 2021-06-28

View file

@ -155,31 +155,50 @@ The ⓒ mark means that [`@uppy/companion`](https://uppy.io/docs/companion), a s
<img src="https://saucelabs.com/browser-matrix/transloadit-uppy.svg" alt="Sauce Test Status"/> <img src="https://saucelabs.com/browser-matrix/transloadit-uppy.svg" alt="Sauce Test Status"/>
</a> </a>
We aim to support IE11 and recent versions of Safari, Edge, Chrome, Firefox and Opera. We aim to support recent versions of Safari, Edge, Chrome, Firefox and Opera.
We still run end-to-end tests with IE10, but we are not actively supporting it or fixing visual / minor issues. We still provide a bundle which should work on IE11, but we are not running tests on it.
### Polyfills ### Polyfills
Uppy heavily uses Promises. If your target environment [does not support Promises](https://caniuse.com/#feat=promises), use a polyfill like `es6-promise` before initializing Uppy. Here's a list of polyfills you'll need to include to make Uppy work in older browsers, such as IE11:
When using remote providers like Google Drive or Dropbox, the Fetch API is used. If your target environment does not support the [Fetch API](https://caniuse.com/#feat=fetch), use a polyfill like `whatwg-fetch` before initializing Uppy. The Fetch API polyfill must be loaded _after_ the Promises polyfill, because Fetch uses Promises. - [abortcontroller-polyfill](https://github.com/mo/abortcontroller-polyfill)
- [es6-promise](https://github.com/stefanpenner/es6-promise)
- [math-log2](https://github.com/sindresorhus/math-log2)
- [md-gum-polyfill](https://github.com/mozdevs/mediaDevices-getUserMedia-polyfill)
- [resize-observer-polyfill](https://github.com/que-etc/resize-observer-polyfill)
- [symbol-es6](https://github.com/rousan/symbol-es6)
- [url-polyfill](https://github.com/lifaon74/url-polyfill)
- [whatwg-fetch](https://github.com/github/fetch)
With a module bundler, you can use the required polyfills like so: If you're using a bundler, you need import them before Uppy:
```shell
npm install es6-promise whatwg-fetch
```
```js ```js
import 'es6-promise/auto' import 'es6-promise/auto';
import 'whatwg-fetch' import 'whatwg-fetch';
import Uppy from '@uppy/core' import 'abortcontroller-polyfill/dist/polyfill-patch-fetch';
// Order matters: AbortController needs fetch which needs Promise.
import mathLog2 from 'math-log2';
import 'md-gum-polyfill';
import ResizeObserver from 'resize-observer-polyfill';
import 'symbol-es6';
import 'url-polyfill';
Math.log2 ??= mathLog2;
window.ResizeObserver ??= ResizeObserver;
export { default } from '@uppy/core';
export * from '@uppy/core';
``` ```
If you're using Uppy from CDN, `es6-promise` and `whatwg-fetch` are already included in the bundle, so no need to include anything additionally: If you're using Uppy from CDN, those polyfills are already included in the legacy
bundle, so no need to include anything additionally:
```html ```html
<script src="https://releases.transloadit.com/uppy/v1.29.1/uppy.min.js"></script> <script nomodule src="https://releases.transloadit.com/uppy/v2.0.0/uppy.legacy.min.js"></script>
<script type="module">import"https://releases.transloadit.com/uppy/v2.0.0/uppy.min.js";</script>
``` ```
## FAQ ## FAQ

View file

@ -7,11 +7,14 @@ const browserify = require('browserify')
const exorcist = require('exorcist') const exorcist = require('exorcist')
const glob = require('glob') const glob = require('glob')
const path = require('path') const path = require('path')
const { minify } = require('terser')
const { transformFileAsync } = require('@babel/core')
function handleErr (err) { function handleErr (err) {
console.error(chalk.red('✗ Error:'), chalk.red(err.message)) console.error(chalk.red('✗ Error:'), chalk.red(err.message))
} }
// eslint-disable-next-line no-shadow
function buildBundle (srcFile, bundleFile, { minify = false, standalone = '' } = {}) { function buildBundle (srcFile, bundleFile, { minify = false, standalone = '' } = {}) {
const b = browserify(srcFile, { debug: true, standalone }) const b = browserify(srcFile, { debug: true, standalone })
if (minify) { if (minify) {
@ -31,10 +34,59 @@ function buildBundle (srcFile, bundleFile, { minify = false, standalone = '' } =
} else { } else {
console.info(chalk.green(`✓ Built Bundle [${standalone}]:`), chalk.magenta(bundleFile)) console.info(chalk.green(`✓ Built Bundle [${standalone}]:`), chalk.magenta(bundleFile))
} }
resolve() resolve([bundleFile, standalone])
}) })
}) })
} }
async function minifyBundle ([bundleFile, standalone]) {
const minifiedFilePath = bundleFile.replace(/\.js$/, '.min.js')
const sourceMapPath = `${minifiedFilePath}.map`
const js = await fs.promises.readFile(bundleFile, 'utf-8')
const { code, map } = await minify(js, {
sourceMap: {
content: fs.readFileSync(`${bundleFile}.map`, 'utf-8'),
url:sourceMapPath,
},
toplevel: true,
})
return Promise.all([
fs.promises.writeFile(minifiedFilePath, code),
fs.promises.writeFile(sourceMapPath, map),
])
.then(() => console.info(chalk.green(`✓ Built Minified Bundle [${standalone}]:`), chalk.magenta(minifiedFilePath)))
}
async function transpileDownForIE ([bundleFile, standalone]) {
const minifiedFilePath = bundleFile.replace(/\.js$/, '.min.js')
const sourceMapPath = `${minifiedFilePath}.map`
const { code: js, map: inputMap } = await transformFileAsync(bundleFile, {
compact: false,
highlightCode: false,
inputSourceMap: true,
browserslistEnv: 'legacy',
presets: [['@babel/preset-env', {
modules: false,
loose: true,
targets: { ie:11 },
}]],
})
const { code, map } = await minify(js, {
sourceMap: {
content: inputMap,
url: sourceMapPath,
},
toplevel: true,
})
return Promise.all([
fs.promises.writeFile(bundleFile, js),
fs.promises.writeFile(`${bundleFile}.map`, JSON.stringify(inputMap)),
fs.promises.writeFile(minifiedFilePath, code),
fs.promises.writeFile(sourceMapPath, map),
]).then(() => {
console.info(chalk.green(`✓ Built Bundle [${standalone} (ES5)]:`), chalk.magenta(bundleFile))
console.info(chalk.green(`✓ Built Minified Bundle [${standalone} (ES5)]:`), chalk.magenta(minifiedFilePath))
})
}
mkdirp.sync('./packages/uppy/dist') mkdirp.sync('./packages/uppy/dist')
mkdirp.sync('./packages/@uppy/robodog/dist') mkdirp.sync('./packages/@uppy/robodog/dist')
@ -42,25 +94,20 @@ mkdirp.sync('./packages/@uppy/locales/dist')
const methods = [ const methods = [
buildBundle( buildBundle(
'./packages/uppy/bundle.js', './packages/uppy/index.js',
'./packages/uppy/dist/uppy.js', './packages/uppy/dist/uppy.js',
{ standalone: 'Uppy' } { standalone: 'Uppy' }
), ).then(minifyBundle),
buildBundle( buildBundle(
'./packages/uppy/bundle.js', './packages/uppy/bundle.js',
'./packages/uppy/dist/uppy.min.js', './packages/uppy/dist/uppy.legacy.js',
{ standalone: 'Uppy', minify: true } { standalone: 'Uppy (with polyfills)' }
), ).then(transpileDownForIE),
buildBundle( buildBundle(
'./packages/@uppy/robodog/bundle.js', './packages/@uppy/robodog/bundle.js',
'./packages/@uppy/robodog/dist/robodog.js', './packages/@uppy/robodog/dist/robodog.js',
{ standalone: 'Robodog' } { standalone: 'Robodog' }
), ).then(minifyBundle),
buildBundle(
'./packages/@uppy/robodog/bundle.js',
'./packages/@uppy/robodog/dist/robodog.min.js',
{ standalone: 'Robodog', minify: true }
),
] ]
// Build minified versions of all the locales // Build minified versions of all the locales

View file

@ -1,7 +1,3 @@
// Polyfills, primarily for testing in IE11
require('es6-promise/auto')
require('whatwg-fetch')
const DragDrop = require('./DragDrop.js') const DragDrop = require('./DragDrop.js')
const Dashboard = require('./Dashboard.js') const Dashboard = require('./Dashboard.js')

View file

@ -30,15 +30,15 @@
"website" "website"
], ],
"devDependencies": { "devDependencies": {
"@babel/cli": "7.10.5", "@babel/cli": "^7.14.5",
"@babel/core": "7.11.1", "@babel/core": "^7.14.6",
"@babel/eslint-parser": "7.11.3", "@babel/eslint-parser": "7.11.3",
"@babel/eslint-plugin": "7.11.3", "@babel/eslint-plugin": "7.11.3",
"@babel/plugin-proposal-class-properties": "7.10.4", "@babel/plugin-proposal-class-properties": "7.10.4",
"@babel/plugin-transform-object-assign": "7.10.4", "@babel/plugin-transform-object-assign": "7.10.4",
"@babel/plugin-transform-react-jsx": "7.10.4", "@babel/plugin-transform-react-jsx": "7.10.4",
"@babel/polyfill": "7.10.4", "@babel/polyfill": "7.10.4",
"@babel/preset-env": "7.11.0", "@babel/preset-env": "^7.14.7",
"@babel/register": "7.10.5", "@babel/register": "7.10.5",
"@goto-bus-stop/envify": "5.0.0", "@goto-bus-stop/envify": "5.0.0",
"@jamen/lorem": "0.2.0", "@jamen/lorem": "0.2.0",
@ -47,6 +47,7 @@
"@wdio/local-runner": "5.18.6", "@wdio/local-runner": "5.18.6",
"@wdio/mocha-framework": "5.18.6", "@wdio/mocha-framework": "5.18.6",
"@wdio/sauce-service": "5.16.10", "@wdio/sauce-service": "5.16.10",
"abortcontroller-polyfill": "^1.7.3",
"adm-zip": "0.4.14", "adm-zip": "0.4.14",
"aliasify": "2.1.0", "aliasify": "2.1.0",
"autoprefixer": "9.7.4", "autoprefixer": "9.7.4",
@ -91,6 +92,8 @@
"last-commit-message": "1.0.0", "last-commit-message": "1.0.0",
"lerna": "^3.22.1", "lerna": "^3.22.1",
"lint-staged": "9.5.0", "lint-staged": "9.5.0",
"math-log2": "^2.0.0",
"md-gum-polyfill": "^1.0.0",
"mime-types": "2.1.26", "mime-types": "2.1.26",
"minify-stream": "2.0.1", "minify-stream": "2.0.1",
"minimist": "^1.2.5", "minimist": "^1.2.5",
@ -113,18 +116,22 @@
"remark-cli": "^8.0.1", "remark-cli": "^8.0.1",
"remark-lint-uppy": "file:private/remark-lint-uppy", "remark-lint-uppy": "file:private/remark-lint-uppy",
"replacestream": "^4.0.3", "replacestream": "^4.0.3",
"resize-observer-polyfill": "^1.5.1",
"resolve": "^1.17.0", "resolve": "^1.17.0",
"rimraf": "2.7.1", "rimraf": "2.7.1",
"sass": "1.29.0", "sass": "1.29.0",
"size-limit": "4.5.6", "size-limit": "4.5.6",
"stringify-object": "3.3.0", "stringify-object": "3.3.0",
"symbol-es6": "^0.1.2",
"tar": "4.4.13", "tar": "4.4.13",
"temp-write": "3.4.0", "temp-write": "3.4.0",
"terser": "^5.7.0",
"tinyify": "3.0.0", "tinyify": "3.0.0",
"tsd": "^0.11.0", "tsd": "^0.11.0",
"tsify": "5.0.1", "tsify": "5.0.1",
"tus-node-server": "0.3.2", "tus-node-server": "0.3.2",
"typescript": "~4.1", "typescript": "~4.1",
"url-polyfill": "^1.1.12",
"verdaccio": "^4.8.0", "verdaccio": "^4.8.0",
"watchify": "3.11.1", "watchify": "3.11.1",
"webdriverio": "5.18.6", "webdriverio": "5.18.6",
@ -158,7 +165,6 @@
"start": "npm-run-all --parallel watch start:companion web:start", "start": "npm-run-all --parallel watch start:companion web:start",
"test:companion": "npm run --prefix ./packages/@uppy/companion test", "test:companion": "npm run --prefix ./packages/@uppy/companion test",
"test:endtoend:build-ci": "bash ./bin/endtoend-build-ci", "test:endtoend:build-ci": "bash ./bin/endtoend-build-ci",
"test:endtoend:build": "bash ./bin/endtoend-build",
"test:endtoend:local": "npm run test:endtoend:build && wdio test/endtoend/wdio.local.conf.js", "test:endtoend:local": "npm run test:endtoend:build && wdio test/endtoend/wdio.local.conf.js",
"test:endtoend:providers": "npm run test:endtoend:build && . ./test/endtoend/providers/env.sh && wdio test/endtoend/wdio.local.conf.js --spec test/endtoend/providers/provider.*.test.js", "test:endtoend:providers": "npm run test:endtoend:build && . ./test/endtoend/providers/env.sh && wdio test/endtoend/wdio.local.conf.js --spec test/endtoend/providers/provider.*.test.js",
"test:endtoend:prepare-ci": "npm-run-all --parallel --race test:endtoend:registry test:endtoend:build-ci", "test:endtoend:prepare-ci": "npm-run-all --parallel --race test:endtoend:registry test:endtoend:build-ci",

View file

@ -26,8 +26,7 @@
"@uppy/utils": "file:../utils", "@uppy/utils": "file:../utils",
"@uppy/xhr-upload": "file:../xhr-upload", "@uppy/xhr-upload": "file:../xhr-upload",
"cuid": "^2.1.1", "cuid": "^2.1.1",
"qs-stringify": "^1.1.0", "qs-stringify": "^1.1.0"
"url-parse": "^1.4.7"
}, },
"devDependencies": { "devDependencies": {
"whatwg-fetch": "3.6.2" "whatwg-fetch": "3.6.2"

View file

@ -25,8 +25,6 @@
* the XHRUpload code, but at least it's not horrifically broken :) * the XHRUpload code, but at least it's not horrifically broken :)
*/ */
// If global `URL` constructor is available, use it
const URL_ = typeof URL === 'function' ? URL : require('url-parse')
const { BasePlugin } = require('@uppy/core') const { BasePlugin } = require('@uppy/core')
const Translator = require('@uppy/utils/lib/Translator') const Translator = require('@uppy/utils/lib/Translator')
const RateLimitedQueue = require('@uppy/utils/lib/RateLimitedQueue') const RateLimitedQueue = require('@uppy/utils/lib/RateLimitedQueue')
@ -38,9 +36,7 @@ const MiniXHRUpload = require('./MiniXHRUpload')
const isXml = require('./isXml') const isXml = require('./isXml')
function resolveUrl (origin, link) { function resolveUrl (origin, link) {
return origin return new URL(link, origin || undefined).toString()
? new URL_(link, origin).toString()
: new URL_(link).toString()
} }
/** /**

View file

@ -23,7 +23,6 @@
"dependencies": { "dependencies": {
"@uppy/utils": "file:../utils", "@uppy/utils": "file:../utils",
"namespace-emitter": "^2.0.1", "namespace-emitter": "^2.0.1",
"qs-stringify": "^1.1.0", "qs-stringify": "^1.1.0"
"url-parse": "^1.4.7"
} }
} }

View file

@ -1,7 +1,6 @@
'use strict' 'use strict'
const qsStringify = require('qs-stringify') const qsStringify = require('qs-stringify')
const URL = require('url-parse')
const RequestClient = require('./RequestClient') const RequestClient = require('./RequestClient')
const tokenStorage = require('./tokenStorage') const tokenStorage = require('./tokenStorage')

View file

@ -11,11 +11,7 @@ const justErrorsLogger = {
// Print logs to console with namespace + timestamp, // Print logs to console with namespace + timestamp,
// set by logger: Uppy.debugLogger or debug: true // set by logger: Uppy.debugLogger or debug: true
const debugLogger = { const debugLogger = {
debug: (...args) => { debug: (...args) => console.debug(`[Uppy] [${getTimeStamp()}]`, ...args),
// IE 10 doesnt support console.debug
const debug = console.debug || console.log
debug.call(console, `[Uppy] [${getTimeStamp()}]`, ...args)
},
warn: (...args) => console.warn(`[Uppy] [${getTimeStamp()}]`, ...args), warn: (...args) => console.warn(`[Uppy] [${getTimeStamp()}]`, ...args),
error: (...args) => console.error(`[Uppy] [${getTimeStamp()}]`, ...args), error: (...args) => console.error(`[Uppy] [${getTimeStamp()}]`, ...args),
} }

View file

@ -34,7 +34,11 @@
"lodash.debounce": "^4.0.8", "lodash.debounce": "^4.0.8",
"lodash.throttle": "^4.1.1", "lodash.throttle": "^4.1.1",
"memoize-one": "^5.0.4", "memoize-one": "^5.0.4",
"preact": "^10.5.13", "preact": "^10.5.13"
},
"devDependencies": {
"@uppy/google-drive": "*",
"@uppy/status-bar": "*",
"resize-observer-polyfill": "^1.5.0" "resize-observer-polyfill": "^1.5.0"
}, },
"peerDependencies": { "peerDependencies": {

View file

@ -11,7 +11,6 @@ const getDroppedFiles = require('@uppy/utils/lib/getDroppedFiles')
const getTextDirection = require('@uppy/utils/lib/getTextDirection') const getTextDirection = require('@uppy/utils/lib/getTextDirection')
const trapFocus = require('./utils/trapFocus') const trapFocus = require('./utils/trapFocus')
const cuid = require('cuid') const cuid = require('cuid')
const ResizeObserver = require('resize-observer-polyfill').default || require('resize-observer-polyfill')
const createSuperFocus = require('./utils/createSuperFocus') const createSuperFocus = require('./utils/createSuperFocus')
const memoize = require('memoize-one').default || require('memoize-one') const memoize = require('memoize-one').default || require('memoize-one')
const FOCUSABLE_ELEMENTS = require('@uppy/utils/lib/FOCUSABLE_ELEMENTS') const FOCUSABLE_ELEMENTS = require('@uppy/utils/lib/FOCUSABLE_ELEMENTS')

View file

@ -1,9 +1,17 @@
/* global globalThis */
const Core = require('@uppy/core') const Core = require('@uppy/core')
const StatusBarPlugin = require('@uppy/status-bar') const StatusBarPlugin = require('@uppy/status-bar')
const GoogleDrivePlugin = require('@uppy/google-drive') const GoogleDrivePlugin = require('@uppy/google-drive')
const DashboardPlugin = require('./index') const DashboardPlugin = require('./index')
describe('Dashboard', () => { describe('Dashboard', () => {
beforeAll(() => {
globalThis.ResizeObserver = require('resize-observer-polyfill').default || require('resize-observer-polyfill')
})
afterAll(() => {
delete globalThis.ResizeObserver
})
it('can safely be added together with the StatusBar without id conflicts', () => { it('can safely be added together with the StatusBar without id conflicts', () => {
const core = new Core() const core = new Core()
core.use(StatusBarPlugin) core.use(StatusBarPlugin)

View file

@ -222,7 +222,6 @@ module.exports = class Editor extends Component {
render () { render () {
const { currentImage, i18n, opts } = this.props const { currentImage, i18n, opts } = this.props
const { actions } = opts const { actions } = opts
// eslint-disable-next-line compat/compat
const imageURL = URL.createObjectURL(currentImage.data) const imageURL = URL.createObjectURL(currentImage.data)
return ( return (

View file

@ -10,12 +10,8 @@ const isPreviewSupported = require('@uppy/utils/lib/isPreviewSupported')
const SharedHandler = require('../SharedHandler') const SharedHandler = require('../SharedHandler')
const CloseWrapper = require('../CloseWrapper') const CloseWrapper = require('../CloseWrapper')
// location.origin does not exist in IE
function getOrigin () { function getOrigin () {
if ('origin' in location) { return location.origin
return location.origin // eslint-disable-line compat/compat
}
return `${location.protocol}//${location.hostname}${location.port ? `:${location.port}` : ''}`
} }
/** /**

View file

@ -1,4 +1,15 @@
require('es6-promise/auto') require('es6-promise/auto')
require('whatwg-fetch') require('whatwg-fetch')
require('abortcontroller-polyfill/dist/polyfill-patch-fetch')
// Order matters: AbortController needs fetch which needs Promise.
module.exports = require('./') const mathLog2 = require('math-log2')
require('md-gum-polyfill')
const ResizeObserver = require('resize-observer-polyfill')
require('symbol-es6')
require('url-polyfill')
if (typeof Math.log2 !== 'function') Math.log2 = mathLog2
if (typeof window.ResizeObserver !== 'function') window.ResizeObserver = ResizeObserver
module.exports = require('.')

View file

@ -23,8 +23,7 @@
}, },
"dependencies": { "dependencies": {
"@uppy/utils": "file:../utils", "@uppy/utils": "file:../utils",
"exifr": "^6.0.0", "exifr": "^6.0.0"
"math-log2": "^1.0.1"
}, },
"devDependencies": { "devDependencies": {
"namespace-emitter": "2.0.1" "namespace-emitter": "2.0.1"

View file

@ -3,7 +3,6 @@ const Translator = require('@uppy/utils/lib/Translator')
const dataURItoBlob = require('@uppy/utils/lib/dataURItoBlob') const dataURItoBlob = require('@uppy/utils/lib/dataURItoBlob')
const isObjectURL = require('@uppy/utils/lib/isObjectURL') const isObjectURL = require('@uppy/utils/lib/isObjectURL')
const isPreviewSupported = require('@uppy/utils/lib/isPreviewSupported') const isPreviewSupported = require('@uppy/utils/lib/isPreviewSupported')
const MathLog2 = require('math-log2') // Polyfill for IE.
const exifr = require('exifr/dist/mini.legacy.umd.js') const exifr = require('exifr/dist/mini.legacy.umd.js')
/** /**
@ -65,22 +64,16 @@ module.exports = class ThumbnailGenerator extends UIPlugin {
* @returns {Promise} * @returns {Promise}
*/ */
createThumbnail (file, targetWidth, targetHeight) { createThumbnail (file, targetWidth, targetHeight) {
// bug in the compatibility data
// eslint-disable-next-line compat/compat
const originalUrl = URL.createObjectURL(file.data) const originalUrl = URL.createObjectURL(file.data)
const onload = new Promise((resolve, reject) => { const onload = new Promise((resolve, reject) => {
const image = new Image() const image = new Image()
image.src = originalUrl image.src = originalUrl
image.addEventListener('load', () => { image.addEventListener('load', () => {
// bug in the compatibility data
// eslint-disable-next-line compat/compat
URL.revokeObjectURL(originalUrl) URL.revokeObjectURL(originalUrl)
resolve(image) resolve(image)
}) })
image.addEventListener('error', (event) => { image.addEventListener('error', (event) => {
// bug in the compatibility data
// eslint-disable-next-line compat/compat
URL.revokeObjectURL(originalUrl) URL.revokeObjectURL(originalUrl)
reject(event.error || new Error('Could not create thumbnail')) reject(event.error || new Error('Could not create thumbnail'))
}) })
@ -96,8 +89,6 @@ module.exports = class ThumbnailGenerator extends UIPlugin {
return this.canvasToBlob(resizedImage, this.thumbnailType, 80) return this.canvasToBlob(resizedImage, this.thumbnailType, 80)
}) })
.then(blob => { .then(blob => {
// bug in the compatibility data
// eslint-disable-next-line compat/compat
return URL.createObjectURL(blob) return URL.createObjectURL(blob)
}) })
} }
@ -178,7 +169,7 @@ module.exports = class ThumbnailGenerator extends UIPlugin {
image = this.protect(image) image = this.protect(image)
var steps = Math.ceil(MathLog2(image.width / targetWidth)) var steps = Math.ceil(Math.log2(image.width / targetWidth))
if (steps < 1) { if (steps < 1) {
steps = 1 steps = 1
} }

View file

@ -32,8 +32,7 @@
"@uppy/tus": "file:../tus", "@uppy/tus": "file:../tus",
"@uppy/utils": "file:../utils", "@uppy/utils": "file:../utils",
"component-emitter": "^1.2.1", "component-emitter": "^1.2.1",
"socket.io-client": "~2.2.0", "socket.io-client": "~2.2.0"
"url-parse": "^1.4.7"
}, },
"peerDependencies": { "peerDependencies": {
"@uppy/core": "^1.0.0" "@uppy/core": "^1.0.0"

View file

@ -1,5 +1,4 @@
const fetchWithNetworkError = require('@uppy/utils/lib/fetchWithNetworkError') const fetchWithNetworkError = require('@uppy/utils/lib/fetchWithNetworkError')
const URL = require('url-parse')
/** /**
* A Barebones HTTP API client for Transloadit. * A Barebones HTTP API client for Transloadit.

View file

@ -18,7 +18,6 @@
"url": "git+https://github.com/transloadit/uppy.git" "url": "git+https://github.com/transloadit/uppy.git"
}, },
"dependencies": { "dependencies": {
"abortcontroller-polyfill": "^1.4.0",
"lodash.throttle": "^4.1.1" "lodash.throttle": "^4.1.1"
} }
} }

View file

@ -1,20 +1,6 @@
/** /**
* Little AbortController proxy module so we can swap out the implementation easily later. * Little AbortController proxy module so we can swap out the implementation easily later.
*/ */
const { AbortController, AbortSignal } = require('abortcontroller-polyfill/dist/abortcontroller')
function createAbortError (message = 'Aborted') {
try {
return new DOMException(message, 'AbortError')
} catch {
// For Internet Explorer
const error = new Error(message)
error.name = 'AbortError'
return error
}
}
exports.AbortController = AbortController exports.AbortController = AbortController
exports.AbortSignal = AbortSignal exports.AbortSignal = AbortSignal
exports.createAbortError = createAbortError exports.createAbortError = (message = 'Aborted') => new DOMException(message, 'AbortError')

View file

@ -18,7 +18,7 @@ module.exports = function dataURItoBlob (dataURI, opts, toFile) {
let bytes let bytes
try { try {
bytes = new Uint8Array(array) // eslint-disable-line compat/compat bytes = new Uint8Array(array)
} catch (err) { } catch (err) {
return null return null
} }

View file

@ -1,10 +1,3 @@
module.exports = function isTouchDevice () { module.exports = function isTouchDevice () {
// works on most browsers return 'ontouchstart' in window || 'maxTouchPoints' in navigator
if ('ontouchstart' in window) {
return true
}
// works on IE10/11 and Surface
// eslint-disable-next-line compat/compat
return !!navigator.maxTouchPoints
} }

View file

@ -207,7 +207,7 @@ module.exports = class Webcam extends UIPlugin {
|| this.opts.modes.indexOf('picture') !== -1) || this.opts.modes.indexOf('picture') !== -1)
const videoConstraints = { const videoConstraints = {
...(this.opts.videoConstraints ?? { facingMode: this.opts.facingMode }), ...(this.opts.videoConstraints || { facingMode: this.opts.facingMode }),
// facingMode takes precedence over deviceId, and not needed // facingMode takes precedence over deviceId, and not needed
// when specific device is selected // when specific device is selected
...(deviceId ? { deviceId, facingMode: null } : {}), ...(deviceId ? { deviceId, facingMode: null } : {}),

View file

@ -1,4 +1,15 @@
require('es6-promise/auto') require('es6-promise/auto')
require('whatwg-fetch') require('whatwg-fetch')
require('abortcontroller-polyfill/dist/polyfill-patch-fetch')
// Order matters: AbortController needs fetch which needs Promise.
module.exports = require('./') const mathLog2 = require('math-log2')
require('md-gum-polyfill')
const ResizeObserver = require('resize-observer-polyfill')
require('symbol-es6')
require('url-polyfill')
if (typeof Math.log2 !== 'function') Math.log2 = mathLog2
if (typeof window.ResizeObserver !== 'function') window.ResizeObserver = ResizeObserver
module.exports = require('.')

View file

@ -1,5 +1,3 @@
require('es6-promise/auto')
require('whatwg-fetch')
const Uppy = require('@uppy/core') const Uppy = require('@uppy/core')
const Dashboard = require('@uppy/dashboard') const Dashboard = require('@uppy/dashboard')
const Tus = require('@uppy/tus') const Tus = require('@uppy/tus')

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,3 @@
require('es6-promise/auto')
require('whatwg-fetch')
const Uppy = require('@uppy/core') const Uppy = require('@uppy/core')
const DragDrop = require('@uppy/drag-drop') const DragDrop = require('@uppy/drag-drop')
const XHRUpload = require('@uppy/xhr-upload') const XHRUpload = require('@uppy/xhr-upload')

View file

@ -1,5 +1,3 @@
require('es6-promise/auto')
require('whatwg-fetch')
const Uppy = require('@uppy/core') const Uppy = require('@uppy/core')
const Dashboard = require('@uppy/dashboard') const Dashboard = require('@uppy/dashboard')
const GoogleDrive = require('@uppy/google-drive') const GoogleDrive = require('@uppy/google-drive')

View file

@ -1,6 +1,4 @@
/* eslint-disable */ /* eslint-disable */
require('es6-promise/auto')
require('whatwg-fetch')
const Uppy = require('@uppy/core') const Uppy = require('@uppy/core')
const ThumbnailGenerator = require('@uppy/thumbnail-generator') const ThumbnailGenerator = require('@uppy/thumbnail-generator')
const FileInput = require('@uppy/file-input') const FileInput = require('@uppy/file-input')

View file

@ -1,5 +1,3 @@
require('es6-promise/auto')
require('whatwg-fetch')
const Uppy = require('@uppy/core') const Uppy = require('@uppy/core')
const Dashboard = require('@uppy/dashboard') const Dashboard = require('@uppy/dashboard')
const Transloadit = require('@uppy/transloadit') const Transloadit = require('@uppy/transloadit')

View file

@ -1,5 +1,3 @@
require('es6-promise/auto')
require('whatwg-fetch')
const Uppy = require('@uppy/core') const Uppy = require('@uppy/core')
const Dashboard = require('@uppy/dashboard') const Dashboard = require('@uppy/dashboard')
const Tus = require('@uppy/tus') const Tus = require('@uppy/tus')

View file

@ -1,5 +1,3 @@
require('es6-promise/auto')
require('whatwg-fetch')
const Uppy = require('@uppy/core') const Uppy = require('@uppy/core')
const DragDrop = require('@uppy/drag-drop') const DragDrop = require('@uppy/drag-drop')
const Tus = require('@uppy/tus') const Tus = require('@uppy/tus')

View file

@ -1,5 +1,3 @@
import 'es6-promise/auto'
import 'whatwg-fetch'
import { import {
Core, Core,
Dashboard, Dashboard,

View file

@ -1,5 +1,3 @@
require('es6-promise/auto')
require('whatwg-fetch')
const Uppy = require('@uppy/core') const Uppy = require('@uppy/core')
const Dashboard = require('@uppy/dashboard') const Dashboard = require('@uppy/dashboard')
const Url = require('@uppy/url') const Url = require('@uppy/url')

View file

@ -15,10 +15,12 @@ exports.config = {
logLevel: 'warn', logLevel: 'warn',
capabilities: [ capabilities: [
{ browserName: 'firefox', version: '80.0', platform: 'Windows 10' }, { browserName: 'firefox', version: 'latest', platform: 'Windows 10' },
{ browserName: 'chrome', version: '80.0', platform: 'Windows 10' }, { browserName: 'firefox', version: 'latest-1', platform: 'Windows 10' },
{ browserName: 'MicrosoftEdge', version: '85', platform: 'Windows 10' }, { browserName: 'chrome', version: 'latest', platform: 'Windows 10' },
{ browserName: 'safari', version: '11.1', platform: 'macOS 10.13' }, { browserName: 'chrome', version: 'latest-1', platform: 'Windows 10' },
// { browserName: 'safari', version: 'latest', platform: 'macOS 11' },
// { browserName: 'safari', version: '13.1', platform: 'macOS 10.15' },
// { browserName: 'Safari', platformName: 'iOS', platformVersion: '12.2', deviceOrientation: 'portrait', deviceName: 'iPhone 8 Simulator' }, // { browserName: 'Safari', platformName: 'iOS', platformVersion: '12.2', deviceOrientation: 'portrait', deviceName: 'iPhone 8 Simulator' },
{ browserName: 'chrome', platformName: 'Android', platformVersion: '6.0', deviceOrientation: 'portrait', deviceName: 'Android Emulator' }, { browserName: 'chrome', platformName: 'Android', platformVersion: '6.0', deviceOrientation: 'portrait', deviceName: 'Android Emulator' },
].map(createCapability), ].map(createCapability),

View file

@ -1,6 +1,3 @@
require('es6-promise/auto')
require('whatwg-fetch')
const Uppy = require('@uppy/core') const Uppy = require('@uppy/core')
const FileInput = require('@uppy/file-input') const FileInput = require('@uppy/file-input')
const XHRUpload = require('@uppy/xhr-upload') const XHRUpload = require('@uppy/xhr-upload')

View file

@ -0,0 +1,58 @@
---
title: "Uppy 2.0.0: New major release"
date: 2021-06-30 # TODO
author: aduh95
image: null # TODO
published: false
---
# Uppy 2.0.0
## Browser support
In Uppy v2.0, we've removed all built-in polyfills. If you need your app to
support older browser (such as IE 11), you can add some polyfills to your bundle
to make it work:
- [abortcontroller-polyfill](https://github.com/mo/abortcontroller-polyfill)
- [es6-promise](https://github.com/stefanpenner/es6-promise)
- [math-log2](https://github.com/sindresorhus/math-log2)
- [md-gum-polyfill](https://github.com/mozdevs/mediaDevices-getUserMedia-polyfill)
- [resize-observer-polyfill](https://github.com/que-etc/resize-observer-polyfill)
- [symbol-es6](https://github.com/rousan/symbol-es6)
- [url-polyfill](https://github.com/lifaon74/url-polyfill)
- [whatwg-fetch](https://github.com/github/fetch)
If you're using a bundler, you need import them before Uppy:
```js
import "es6-promise/auto";
import "whatwg-fetch";
import "abortcontroller-polyfill/dist/polyfill-patch-fetch";
// Order matters: AbortController needs fetch which needs Promise.
import mathLog2 from "math-log2";
import "md-gum-polyfill";
import ResizeObserver from "resize-observer-polyfill";
import "symbol-es6";
import "url-polyfill";
Math.log2 ??= mathLog2;
window.ResizeObserver ??= ResizeObserver;
export { default } from "@uppy/core";
export * from "@uppy/core";
```
If you're using Uppy from CDN, we now provide two bundles, one for up-to-date
browsers that do not include polyfills and use modern syntax, and one for legacy
browsers. When migrating, be mindful about which browsers you want to support:
```html
<!-- Modern browsers (recommended) -->
<script src="https://releases.transloadit.com/uppy/v2.0.0/uppy.min.js"></script>
<!-- Legacy browsers (IE11+) -->
<script nomodule src="https://releases.transloadit.com/uppy/v2.0.0/uppy.legacy.min.js"></script>
<script type="module">import"https://releases.transloadit.com/uppy/v2.0.0/uppy.min.js";</script>
```

View file

@ -163,15 +163,28 @@ When using remote providers like Google Drive or Dropbox, the Fetch API is used.
With a module bundler, you can use the required polyfills like so: With a module bundler, you can use the required polyfills like so:
```shell ```shell
npm install es6-promise whatwg-fetch npm install es6-promise whatwg-fetch abortcontroller-polyfill math-log2 md-gum-polyfill resize-observer-polyfill symbol-es6 url-polyfill
``` ```
```js ```js
import 'es6-promise/auto' import 'es6-promise/auto';
import 'whatwg-fetch' import 'whatwg-fetch';
import Uppy from '@uppy/core' import 'abortcontroller-polyfill/dist/polyfill-patch-fetch';
// Order matters: AbortController needs fetch which needs Promise.
import mathLog2 from 'math-log2';
import 'md-gum-polyfill';
import ResizeObserver from 'resize-observer-polyfill';
import 'symbol-es6';
import 'url-polyfill';
Math.log2 ??= mathLog2;
window.ResizeObserver ??= ResizeObserver;
export { default } from '@uppy/core';
export * from '@uppy/core'
``` ```
If you're using Uppy from CDN, `es6-promise` and `whatwg-fetch` are already included in the bundle, no need to include anything additionally: If you're using Uppy from CDN, those polyfills are already included in the bundle, no need to include anything additionally:
```html ```html
<script src="https://releases.transloadit.com/uppy/v1.29.1/uppy.min.js"></script> <script src="https://releases.transloadit.com/uppy/v1.29.1/uppy.min.js"></script>

View file

@ -146,11 +146,7 @@ const nullLogger = {
```js ```js
const debugLogger = { const debugLogger = {
debug: (...args) => { debug: (...args) => console.debug(`[Uppy] [${getTimeStamp()}]`, ...args),
// IE 10 doesnt support console.debug
const debug = console.debug || console.log
debug.call(console, `[Uppy] [${getTimeStamp()}]`, ...args)
},
warn: (...args) => console.warn(`[Uppy] [${getTimeStamp()}]`, ...args), warn: (...args) => console.warn(`[Uppy] [${getTimeStamp()}]`, ...args),
error: (...args) => console.error(`[Uppy] [${getTimeStamp()}]`, ...args) error: (...args) => console.error(`[Uppy] [${getTimeStamp()}]`, ...args)
} }

View file

@ -1,5 +1,3 @@
require('es6-promise/auto')
require('whatwg-fetch')
const Uppy = require('@uppy/core') const Uppy = require('@uppy/core')
const Dashboard = require('@uppy/dashboard') const Dashboard = require('@uppy/dashboard')
const GoogleDrive = require('@uppy/google-drive') const GoogleDrive = require('@uppy/google-drive')

View file

@ -1,5 +1,3 @@
require('es6-promise/auto')
require('whatwg-fetch')
const Uppy = require('@uppy/core') const Uppy = require('@uppy/core')
const DragDrop = require('@uppy/drag-drop') const DragDrop = require('@uppy/drag-drop')
const ProgressBar = require('@uppy/progress-bar') const ProgressBar = require('@uppy/progress-bar')

View file

@ -1,5 +1,3 @@
require('es6-promise/auto')
require('whatwg-fetch')
const Uppy = require('@uppy/core') const Uppy = require('@uppy/core')
const FileInput = require('@uppy/file-input') const FileInput = require('@uppy/file-input')
const StatusBar = require('@uppy/status-bar') const StatusBar = require('@uppy/status-bar')

View file

@ -1,5 +1,3 @@
require('es6-promise/auto')
require('whatwg-fetch')
const Uppy = require('@uppy/core') const Uppy = require('@uppy/core')
const Dashboard = require('@uppy/dashboard') const Dashboard = require('@uppy/dashboard')
const Webcam = require('@uppy/webcam') const Webcam = require('@uppy/webcam')

View file

@ -1,5 +1,3 @@
require('es6-promise/auto')
require('whatwg-fetch')
const Uppy = require('@uppy/core') const Uppy = require('@uppy/core')
const FileInput = require('@uppy/file-input') const FileInput = require('@uppy/file-input')
const XHRUpload = require('@uppy/xhr-upload') const XHRUpload = require('@uppy/xhr-upload')