Browse Source

fix(Android <input />): Support file extensions in file input accept attributes (#357)

The current implementation doesn't support a list of file extensions in the accept attribute (e.g. `<input type="file" accept=".jpg, .png">`) while that is a valid value per the HTML spec. I've updated the implementation to convert any file extensions to mime types before we set the type(s) on the intent to rectify the issue. In addition I've updated the `acceptsImages` and `acceptsVideo` methods to handle file extensions as well.
Ryan Linton 5 years ago
parent
commit
803a3b095b

+ 38
- 5
android/src/main/java/com/reactnativecommunity/webview/RNCWebViewModule.java View File

16
 import android.support.v4.content.ContextCompat;
16
 import android.support.v4.content.ContextCompat;
17
 import android.support.v4.content.FileProvider;
17
 import android.support.v4.content.FileProvider;
18
 import android.util.Log;
18
 import android.util.Log;
19
+import android.webkit.MimeTypeMap;
19
 import android.webkit.ValueCallback;
20
 import android.webkit.ValueCallback;
20
 import android.webkit.WebChromeClient;
21
 import android.webkit.WebChromeClient;
21
 import android.widget.Toast;
22
 import android.widget.Toast;
248
     if (acceptTypes.isEmpty()) {
249
     if (acceptTypes.isEmpty()) {
249
       _acceptTypes = DEFAULT_MIME_TYPES;
250
       _acceptTypes = DEFAULT_MIME_TYPES;
250
     }
251
     }
252
+    if (acceptTypes.matches("\\.\\w+")) {
253
+      _acceptTypes = getMimeTypeFromExtension(acceptTypes.replace(".", ""));
254
+    }
251
     Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
255
     Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
252
     intent.addCategory(Intent.CATEGORY_OPENABLE);
256
     intent.addCategory(Intent.CATEGORY_OPENABLE);
253
     intent.setType(_acceptTypes);
257
     intent.setType(_acceptTypes);
264
   }
268
   }
265
 
269
 
266
   private Boolean acceptsImages(String types) {
270
   private Boolean acceptsImages(String types) {
267
-    return types.isEmpty() || types.toLowerCase().contains("image");
271
+    String mimeType = types;
272
+    if (types.matches("\\.\\w+")) {
273
+        mimeType = getMimeTypeFromExtension(types.replace(".", ""));
274
+    }
275
+    return mimeType.isEmpty() || mimeType.toLowerCase().contains("image");
268
   }
276
   }
269
   private Boolean acceptsImages(String[] types) {
277
   private Boolean acceptsImages(String[] types) {
270
-    return isArrayEmpty(types) || arrayContainsString(types, "image");
278
+    String[] mimeTypes = getAcceptedMimeType(types);
279
+    return isArrayEmpty(mimeTypes) || arrayContainsString(mimeTypes, "image");
271
   }
280
   }
272
 
281
 
273
   private Boolean acceptsVideo(String types) {
282
   private Boolean acceptsVideo(String types) {
274
-    return types.isEmpty() || types.toLowerCase().contains("video");
283
+    String mimeType = types;
284
+    if (types.matches("\\.\\w+")) {
285
+        mimeType = getMimeTypeFromExtension(types.replace(".", ""));
286
+    }
287
+    return mimeType.isEmpty() || mimeType.toLowerCase().contains("video");
275
   }
288
   }
276
   private Boolean acceptsVideo(String[] types) {
289
   private Boolean acceptsVideo(String[] types) {
277
-    return isArrayEmpty(types) || arrayContainsString(types, "video");
290
+    String[] mimeTypes = getAcceptedMimeType(types);
291
+    return isArrayEmpty(mimeTypes) || arrayContainsString(mimeTypes, "video");
278
   }
292
   }
279
 
293
 
280
   private Boolean arrayContainsString(String[] array, String pattern){
294
   private Boolean arrayContainsString(String[] array, String pattern){
290
     if (isArrayEmpty(types)) {
304
     if (isArrayEmpty(types)) {
291
         return new String[]{DEFAULT_MIME_TYPES};
305
         return new String[]{DEFAULT_MIME_TYPES};
292
     }
306
     }
293
-    return types;
307
+    String[] mimeTypes = new String[types.length];
308
+    for (int i = 0; i < types.length; i++) {
309
+        String t = types[i];
310
+        // convert file extensions to mime types
311
+        if (t.matches("\\.\\w+")) {
312
+            String mimeType = getMimeTypeFromExtension(t.replace(".", ""));
313
+            mimeTypes[i] = mimeType;
314
+        } else {
315
+            mimeTypes[i] = t;
316
+        }
317
+    }
318
+    return mimeTypes;
319
+  }
320
+
321
+  private String getMimeTypeFromExtension(String extension) {
322
+    String type = null;
323
+    if (extension != null) {
324
+        type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
325
+    }
326
+    return type;
294
   }
327
   }
295
 
328
 
296
   private Uri getOutputUri(String intentType) {
329
   private Uri getOutputUri(String intentType) {