Skip to content

Commit c371a50

Browse files
committed
fix(tpl/upload): apply workaround for mobile devices that cannot select directory
Most mobile browsers can pass the test for `webkitdirectory` on HTML file input. However they actually has no ability to select directory based on OS file selector UI. If all files has no path information, fallback to file upload mode.
1 parent 657051d commit c371a50

File tree

2 files changed

+90
-35
lines changed

2 files changed

+90
-35
lines changed

src/tpl/asset/main.js

Lines changed: 48 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -412,8 +412,7 @@
412412
var classHidden = 'hidden';
413413
var classActive = 'active';
414414

415-
function onClickOpt(e) {
416-
var optTarget = e.target;
415+
function onClickOpt(optTarget, clearInput) {
417416
if (optTarget === optActive) {
418417
return;
419418
}
@@ -422,7 +421,31 @@
422421
optActive = optTarget;
423422
addClass(optActive, classActive);
424423

425-
fileInput.value = '';
424+
if (clearInput) {
425+
fileInput.value = '';
426+
}
427+
return true;
428+
}
429+
430+
function onClickOptFile(e) {
431+
if (onClickOpt(optFile, Boolean(e))) {
432+
fileInput.name = file;
433+
fileInput.webkitdirectory = false;
434+
}
435+
}
436+
437+
function onClickOptDirFile(e) {
438+
if (onClickOpt(optDirFile, Boolean(e))) {
439+
fileInput.name = dirFile;
440+
fileInput.webkitdirectory = true;
441+
}
442+
}
443+
444+
function onClickOptInnerDirFile(e) {
445+
if (onClickOpt(optInnerDirFile, Boolean(e))) {
446+
fileInput.name = innerDirFile;
447+
fileInput.webkitdirectory = true;
448+
}
426449
}
427450

428451
if (typeof fileInput.webkitdirectory === 'undefined') {
@@ -433,25 +456,13 @@
433456
optInnerDirFile && removeClass(optInnerDirFile, classHidden);
434457

435458
if (optFile) {
436-
optFile.addEventListener('click', onClickOpt);
437-
optFile.addEventListener('click', function () {
438-
fileInput.name = file;
439-
fileInput.webkitdirectory = false;
440-
});
459+
optFile.addEventListener('click', onClickOptFile);
441460
}
442461
if (optDirFile) {
443-
optDirFile.addEventListener('click', onClickOpt);
444-
optDirFile.addEventListener('click', function () {
445-
fileInput.name = dirFile;
446-
fileInput.webkitdirectory = true
447-
});
462+
optDirFile.addEventListener('click', onClickOptDirFile);
448463
}
449464
if (optInnerDirFile) {
450-
optInnerDirFile.addEventListener('click', onClickOpt);
451-
optInnerDirFile.addEventListener('click', function () {
452-
fileInput.name = innerDirFile;
453-
fileInput.webkitdirectory = true
454-
});
465+
optInnerDirFile.addEventListener('click', onClickOptInnerDirFile);
455466
}
456467

457468
if (sessionStorage) {
@@ -472,6 +483,25 @@
472483
optInnerDirFile && optInnerDirFile.click();
473484
}
474485
}
486+
487+
optFile && fileInput.addEventListener('change', function (e) {
488+
// workaround fix for mobile device, select dir not work but still act like select files
489+
// switch back to file
490+
if (optActive === optFile) {
491+
return;
492+
}
493+
var files = e.target.files;
494+
if (!files || !files.length) {
495+
return;
496+
}
497+
498+
var nodir = Array.prototype.slice.call(files).every(function (file) {
499+
return !file.webkitRelativePath;
500+
});
501+
if (nodir) {
502+
onClickOptFile(); // prevent clear input files
503+
}
504+
});
475505
}
476506

477507
function enableAddDragDrop() {

src/tpl/asset/main.js.go

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -370,42 +370,50 @@ ele && ele.classList.remove(className);
370370
function enableAddDir() {
371371
var classHidden = 'hidden';
372372
var classActive = 'active';
373-
function onClickOpt(e) {
374-
var optTarget = e.target;
373+
function onClickOpt(optTarget, clearInput) {
375374
if (optTarget === optActive) {
376375
return;
377376
}
378377
removeClass(optActive, classActive);
379378
optActive = optTarget;
380379
addClass(optActive, classActive);
380+
if (clearInput) {
381381
fileInput.value = '';
382382
}
383+
return true;
384+
}
385+
function onClickOptFile(e) {
386+
if (onClickOpt(optFile, Boolean(e))) {
387+
fileInput.name = file;
388+
fileInput.webkitdirectory = false;
389+
}
390+
}
391+
function onClickOptDirFile(e) {
392+
if (onClickOpt(optDirFile, Boolean(e))) {
393+
fileInput.name = dirFile;
394+
fileInput.webkitdirectory = true;
395+
}
396+
}
397+
function onClickOptInnerDirFile(e) {
398+
if (onClickOpt(optInnerDirFile, Boolean(e))) {
399+
fileInput.name = innerDirFile;
400+
fileInput.webkitdirectory = true;
401+
}
402+
}
383403
if (typeof fileInput.webkitdirectory === 'undefined') {
384404
addClass(uploadType, classNone);
385405
return;
386406
}
387407
optDirFile && removeClass(optDirFile, classHidden);
388408
optInnerDirFile && removeClass(optInnerDirFile, classHidden);
389409
if (optFile) {
390-
optFile.addEventListener('click', onClickOpt);
391-
optFile.addEventListener('click', function () {
392-
fileInput.name = file;
393-
fileInput.webkitdirectory = false;
394-
});
410+
optFile.addEventListener('click', onClickOptFile);
395411
}
396412
if (optDirFile) {
397-
optDirFile.addEventListener('click', onClickOpt);
398-
optDirFile.addEventListener('click', function () {
399-
fileInput.name = dirFile;
400-
fileInput.webkitdirectory = true
401-
});
413+
optDirFile.addEventListener('click', onClickOptDirFile);
402414
}
403415
if (optInnerDirFile) {
404-
optInnerDirFile.addEventListener('click', onClickOpt);
405-
optInnerDirFile.addEventListener('click', function () {
406-
fileInput.name = innerDirFile;
407-
fileInput.webkitdirectory = true
408-
});
416+
optInnerDirFile.addEventListener('click', onClickOptInnerDirFile);
409417
}
410418
if (sessionStorage) {
411419
var uploadTypeField = 'upload-type';
@@ -423,6 +431,23 @@ optDirFile && optDirFile.click();
423431
optInnerDirFile && optInnerDirFile.click();
424432
}
425433
}
434+
optFile && fileInput.addEventListener('change', function (e) {
435+
// workaround fix for mobile device, select dir not work but still act like select files
436+
// switch back to file
437+
if (optActive === optFile) {
438+
return;
439+
}
440+
var files = e.target.files;
441+
if (!files || !files.length) {
442+
return;
443+
}
444+
var nodir = Array.prototype.slice.call(files).every(function (file) {
445+
return !file.webkitRelativePath;
446+
});
447+
if (nodir) {
448+
onClickOptFile(); // prevent clear input files
449+
}
450+
});
426451
}
427452
function enableAddDragDrop() {
428453
function onDragEnterOver(e) {

0 commit comments

Comments
 (0)