handlerHandleDownload.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. import browser from 'webextension-polyfill';
  2. const getFileExtension = (str) => /(?:\.([^.]+))?$/.exec(str)[1];
  3. function determineFilenameListener(item, suggest) {
  4. const filesname =
  5. JSON.parse(sessionStorage.getItem('rename-downloaded-files')) || {};
  6. const suggestion = filesname[item.id];
  7. if (!suggestion) return true;
  8. const hasFileExt = getFileExtension(suggestion.filename);
  9. if (!hasFileExt) {
  10. const filExtension = getFileExtension(item.filename);
  11. suggestion.filename += `.${filExtension}`;
  12. }
  13. if (!suggestion.waitForDownload) delete filesname[item.id];
  14. sessionStorage.setItem('rename-downloaded-files', JSON.stringify(filesname));
  15. suggest({
  16. filename: suggestion.filename,
  17. conflictAction: suggestion.onConflict,
  18. });
  19. return false;
  20. }
  21. function handleDownload({ data, id: blockId }) {
  22. const nextBlockId = this.getBlockConnections(blockId);
  23. const getFilesname = () =>
  24. JSON.parse(sessionStorage.getItem('rename-downloaded-files')) || {};
  25. return new Promise((resolve) => {
  26. if (!this.activeTab.id) throw new Error('no-tab');
  27. const hasListener =
  28. BROWSER_TYPE === 'chrome' &&
  29. chrome.downloads.onDeterminingFilename.hasListeners(() => {});
  30. if (!hasListener) {
  31. chrome.downloads.onDeterminingFilename.addListener(
  32. determineFilenameListener
  33. );
  34. }
  35. let downloadId = null;
  36. const handleCreated = ({ id }) => {
  37. if (downloadId) return;
  38. const names = getFilesname();
  39. downloadId = id;
  40. names[id] = data;
  41. sessionStorage.setItem('rename-downloaded-files', JSON.stringify(names));
  42. browser.downloads.onCreated.removeListener(handleCreated);
  43. };
  44. browser.downloads.onCreated.addListener(handleCreated);
  45. if (!data.waitForDownload) {
  46. resolve({
  47. nextBlockId,
  48. data: data.filename,
  49. });
  50. return;
  51. }
  52. let isResolved = false;
  53. let currentFilename = data.filename;
  54. const timeout = setTimeout(() => {
  55. if (isResolved) return;
  56. isResolved = true;
  57. resolve({
  58. nextBlockId,
  59. data: currentFilename,
  60. });
  61. }, data.timeout);
  62. const resolvePromise = (id) => {
  63. if (data.saveData) {
  64. this.addDataToColumn(data.dataColumn, currentFilename);
  65. }
  66. if (data.assignVariable) {
  67. this.setVariable(data.variableName, currentFilename);
  68. }
  69. clearTimeout(timeout);
  70. isResolved = true;
  71. const filesname = getFilesname();
  72. delete filesname[id];
  73. sessionStorage.setItem(
  74. 'rename-downloaded-files',
  75. JSON.stringify(filesname)
  76. );
  77. chrome.downloads.onDeterminingFilename.removeListener(
  78. determineFilenameListener
  79. );
  80. resolve({
  81. nextBlockId,
  82. data: currentFilename,
  83. });
  84. };
  85. const handleChanged = ({ state, id, filename }) => {
  86. if (this.engine.isDestroyed || isResolved) {
  87. browser.downloads.onChanged.removeListener(handleChanged);
  88. return;
  89. }
  90. if (downloadId !== id) return;
  91. if (filename) currentFilename = filename.current;
  92. if (state && state.current === 'complete') {
  93. resolvePromise(id);
  94. } else {
  95. browser.downloads.search({ id }).then(([download]) => {
  96. if (!download || !download.endTime) return;
  97. resolvePromise(id);
  98. });
  99. }
  100. };
  101. browser.downloads.onChanged.addListener(handleChanged);
  102. });
  103. }
  104. export default handleDownload;