소스 검색

Use Array.findIndex instead of Array.indexOf in uppy.removePlugin (#2793)

* move findIndex to @uppy/utils, add tests

* use Array.findIndex instead of Array.indexOf in uppy.removePlugin

because strict comparison started failing with Vue3 Proxies
Artur Paikin 4 년 전
부모
커밋
502a755458

+ 12 - 4
packages/@uppy/core/src/index.js

@@ -8,10 +8,10 @@ const DefaultStore = require('@uppy/store-default')
 const getFileType = require('@uppy/utils/lib/getFileType')
 const getFileNameAndExtension = require('@uppy/utils/lib/getFileNameAndExtension')
 const generateFileID = require('@uppy/utils/lib/generateFileID')
+const findIndex = require('@uppy/utils/lib/findIndex')
 const supportsUploadProgress = require('./supportsUploadProgress')
 const { justErrorsLogger, debugLogger } = require('./loggers')
 const Plugin = require('./Plugin') // Exported from here.
-
 class RestrictionError extends Error {
   constructor (...args) {
     super(...args)
@@ -1321,14 +1321,22 @@ class Uppy {
     }
 
     const list = this.plugins[instance.type].slice()
-    const index = list.indexOf(instance)
+    // list.indexOf failed here, because Vue3 converted the plugin instance
+    // to a Proxy object, which failed the strict comparison test:
+    // obj !== objProxy
+    const index = findIndex(list, item => item.id === instance.id)
     if (index !== -1) {
       list.splice(index, 1)
       this.plugins[instance.type] = list
     }
 
-    const updatedState = this.getState()
-    delete updatedState.plugins[instance.id]
+    const state = this.getState()
+    const updatedState = {
+      plugins: {
+        ...state.plugins,
+        [instance.id]: undefined
+      }
+    }
     this.setState(updatedState)
   }
 

+ 1 - 10
packages/@uppy/provider-views/src/ProviderView/ProviderView.js

@@ -5,20 +5,11 @@ const Browser = require('../Browser')
 const LoaderView = require('../Loader')
 const generateFileID = require('@uppy/utils/lib/generateFileID')
 const getFileType = require('@uppy/utils/lib/getFileType')
+const findIndex = require('@uppy/utils/lib/findIndex')
 const isPreviewSupported = require('@uppy/utils/lib/isPreviewSupported')
 const SharedHandler = require('../SharedHandler')
 const CloseWrapper = require('../CloseWrapper')
 
-/**
- * Array.prototype.findIndex ponyfill for old browsers.
- */
-function findIndex (array, predicate) {
-  for (let i = 0; i < array.length; i++) {
-    if (predicate(array[i])) return i
-  }
-  return -1
-}
-
 // location.origin does not exist in IE
 function getOrigin () {
   if ('origin' in location) {

+ 1 - 9
packages/@uppy/utils/src/RateLimitedQueue.js

@@ -1,12 +1,4 @@
-/**
- * Array.prototype.findIndex ponyfill for old browsers.
- */
-function findIndex (array, predicate) {
-  for (let i = 0; i < array.length; i++) {
-    if (predicate(array[i])) return i
-  }
-  return -1
-}
+const findIndex = require('@uppy/utils/lib/findIndex')
 
 function createCancelError () {
   return new Error('Cancelled')

+ 13 - 0
packages/@uppy/utils/src/findIndex.js

@@ -0,0 +1,13 @@
+/**
+ * Array.prototype.findIndex ponyfill for old browsers.
+ *
+ * @param {Array} array
+ * @param {Function} predicate
+ * @returns {number}
+ */
+module.exports = function findIndex (array, predicate) {
+  for (let i = 0; i < array.length; i++) {
+    if (predicate(array[i])) return i
+  }
+  return -1
+}

+ 23 - 0
packages/@uppy/utils/src/findIndex.test.js

@@ -0,0 +1,23 @@
+const findIndex = require('./findIndex')
+
+describe('findIndex', () => {
+  it('should return index of an object in an array, that matches a predicate', () => {
+    const arr = [
+      { name: 'foo' },
+      { name: 'bar' },
+      { name: '123' }
+    ]
+    const index = findIndex(arr, item => item.name === 'bar')
+    expect(index).toEqual(1)
+  })
+
+  it('should return -1 when no object in an array matches a predicate', () => {
+    const arr = [
+      { name: 'foo' },
+      { name: 'bar' },
+      { name: '123' }
+    ]
+    const index = findIndex(arr, item => item.name === 'hello')
+    expect(index).toEqual(-1)
+  })
+})