handler-save-assets.js 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. import browser from 'webextension-polyfill';
  2. import { getBlockConnection } from '../helper';
  3. function getFilename(url) {
  4. try {
  5. const filename = new URL(url).pathname.split('/').pop();
  6. const hasExtension = /\.[0-9a-z]+$/i.test(filename);
  7. if (!hasExtension) return null;
  8. return filename;
  9. } catch (e) {
  10. return null;
  11. }
  12. }
  13. export default async function ({ data, id, name, outputs }) {
  14. const nextBlockId = getBlockConnection({ outputs });
  15. try {
  16. const hasPermission = await browser.permissions.contains({
  17. permissions: ['downloads'],
  18. });
  19. if (!hasPermission) {
  20. throw new Error('no-permission');
  21. }
  22. let sources = [data.url];
  23. let index = 0;
  24. const downloadFile = (url) => {
  25. const options = { url, conflictAction: data.onConflict };
  26. let filename = data.filename || getFilename(url);
  27. if (filename) {
  28. if (data.onConflict === 'overwrite' && index !== 0) {
  29. filename = `(${index}) ${filename}`;
  30. }
  31. options.filename = filename;
  32. index += 1;
  33. }
  34. return browser.downloads.download(options);
  35. };
  36. if (data.type === 'element') {
  37. sources = await this._sendMessageToTab({
  38. id,
  39. name,
  40. data,
  41. tabId: this.activeTab.id,
  42. });
  43. await Promise.all(sources.map((url) => downloadFile(url)));
  44. } else if (data.type === 'url') {
  45. await downloadFile(data.url);
  46. }
  47. return {
  48. nextBlockId,
  49. data: sources,
  50. };
  51. } catch (error) {
  52. error.nextBlockId = nextBlockId;
  53. throw error;
  54. }
  55. }