|
361 | 361 | }); |
362 | 362 | }.bind(this); |
363 | 363 |
|
364 | | - if(dataTransfer["items"] && dataTransfer.items[0] && dataTransfer.items[0].webkitGetAsEntry) { |
365 | | - // chrome |
366 | | - var traverseFileTree = function (item, path) { |
367 | | - path = path || ""; |
368 | | - if (item.isFile) { |
369 | | - // Get file |
370 | | - item.file(function (file) { |
371 | | - doFileUpload(file, path); |
372 | | - }.bind(this)); |
373 | | - } else if (item.isDirectory) { |
374 | | - // Get folder contents |
375 | | - var dirReader = item.createReader(); |
376 | | - dirReader.readEntries(function (entries) { |
377 | | - for (var i = 0; i < entries.length; i++) { |
378 | | - traverseFileTree(entries[i], path + item.name + "/"); |
379 | | - } |
380 | | - }); |
381 | | - } |
382 | | - }.bind(this); |
383 | | - |
384 | | - for (var i = 0; i < dataTransfer.items.length; i++) { |
385 | | - // webkitGetAsEntry is where the magic happens |
386 | | - var item = dataTransfer.items[i].webkitGetAsEntry(); |
387 | | - if (item) { |
388 | | - traverseFileTree(item); |
389 | | - } |
390 | | - } |
391 | | - } else if(dataTransfer["files"]) { |
392 | | - // default filelist upload |
393 | | - for (var i=0; i<dataTransfer["files"].length; i++) { |
394 | | - file = dataTransfer["files"][i]; |
395 | | - |
396 | | - if (window.FileList && file.name && file.size) { // check for size (folder has size=0) |
397 | | - doFileUpload(file); |
398 | | - } else if (!empty(file.type) && file.size < 1) { //throw error for 0 byte file |
399 | | - Ext.MessageBox.alert(t('error'), t('error_empty_file_upload')); |
400 | | - win.close(); |
401 | | - } |
402 | | - } |
403 | | - |
404 | | - // if no files are uploaded (doesn't match criteria, ...) close the progress win immediately |
405 | | - if(!this.activeUploads) { |
406 | | - win.close(); |
407 | | - } |
408 | | - } |
409 | | - |
410 | | - // check in 5 sec. if there're active uploads |
411 | | - // if not, close the progressbar |
412 | | - // this is necessary since the folder upload is async, so we don't know if the progress is |
413 | | - // necessary or not, not really perfect solution, but works as it should |
414 | | - window.setTimeout(function () { |
415 | | - if(!this.activeUploads) { |
416 | | - win.close(); |
417 | | - } |
418 | | - }.bind(this), 5000); |
| 364 | + if (dataTransfer["items"] && dataTransfer.items[0] && dataTransfer.items[0].webkitGetAsEntry) { |
| 365 | + // Chrome-specific folder support |
| 366 | + const MAX_DEPTH = 20; |
| 367 | + const queue = []; |
| 368 | + |
| 369 | + for (let i = 0; i < dataTransfer.items.length; i++) { |
| 370 | + const item = dataTransfer.items[i].webkitGetAsEntry(); |
| 371 | + if (item) { |
| 372 | + queue.push({ item, path: "", depth: 0 }); |
| 373 | + } |
| 374 | + } |
| 375 | + |
| 376 | + const processNext = () => { |
| 377 | + if (queue.length === 0) return; |
| 378 | + |
| 379 | + const { item, path, depth } = queue.shift(); |
| 380 | + |
| 381 | + if (depth > MAX_DEPTH) { |
| 382 | + setTimeout(processNext, 0); |
| 383 | + return; |
| 384 | + } |
| 385 | + |
| 386 | + if (item.isFile) { |
| 387 | + item.file( |
| 388 | + (file) => { |
| 389 | + doFileUpload(file, path); |
| 390 | + setTimeout(processNext, 0); |
| 391 | + }, |
| 392 | + () => { |
| 393 | + setTimeout(processNext, 0); |
| 394 | + } |
| 395 | + ); |
| 396 | + } else if (item.isDirectory) { |
| 397 | + const dirReader = item.createReader(); |
| 398 | + |
| 399 | + const readEntries = () => { |
| 400 | + dirReader.readEntries( |
| 401 | + (entries) => { |
| 402 | + if (entries.length === 0) { |
| 403 | + setTimeout(processNext, 0); |
| 404 | + return; |
| 405 | + } |
| 406 | + |
| 407 | + for (let i = 0; i < entries.length; i++) { |
| 408 | + queue.push({ |
| 409 | + item: entries[i], |
| 410 | + path: path + item.name + "/", |
| 411 | + depth: depth + 1, |
| 412 | + }); |
| 413 | + } |
| 414 | + |
| 415 | + readEntries(); |
| 416 | + }, |
| 417 | + () => { |
| 418 | + setTimeout(processNext, 0); |
| 419 | + } |
| 420 | + ); |
| 421 | + }; |
| 422 | + |
| 423 | + readEntries(); |
| 424 | + } else { |
| 425 | + setTimeout(processNext, 0); |
| 426 | + } |
| 427 | + }; |
| 428 | + |
| 429 | + processNext(); |
| 430 | + } else if (dataTransfer["files"]) { |
| 431 | + |
| 432 | + // Fallback: flat file list |
| 433 | + for (let i = 0; i < dataTransfer["files"].length; i++) { |
| 434 | + const file = dataTransfer["files"][i]; |
| 435 | + |
| 436 | + if (window.FileList && file.name && file.size) { |
| 437 | + doFileUpload(file); |
| 438 | + } else if (!empty(file.type) && file.size < 1) { |
| 439 | + Ext.MessageBox.alert(t('error'), t('error_empty_file_upload')); |
| 440 | + win.close(); |
| 441 | + } |
| 442 | + } |
| 443 | + |
| 444 | + if (!this.activeUploads) { |
| 445 | + win.close(); |
| 446 | + } |
| 447 | + } |
| 448 | + |
| 449 | + // Close progress window if no uploads detected after delay |
| 450 | + setTimeout(function () { |
| 451 | + if (!this.activeUploads) { |
| 452 | + win.close(); |
| 453 | + } |
| 454 | + }.bind(this), 5000); |
419 | 455 | }, |
420 | 456 |
|
421 | 457 | getTreeNodeListeners: function () { |
|
0 commit comments