download.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /*
  2. * Copyright 2010-2020 Gildas Lormeau
  3. * contact : gildas.lormeau <at> gmail.com
  4. *
  5. * This file is part of SingleFile.
  6. *
  7. * The code in this file is free software: you can redistribute it and/or
  8. * modify it under the terms of the GNU Affero General Public License
  9. * (GNU AGPL) as published by the Free Software Foundation, either version 3
  10. * of the License, or (at your option) any later version.
  11. *
  12. * The code in this file is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
  15. * General Public License for more details.
  16. *
  17. * As additional permission under GNU AGPL version 3 section 7, you may
  18. * distribute UNMODIFIED VERSIONS OF THIS file without the copy of the GNU
  19. * AGPL normally required by section 4, provided you include this license
  20. * notice and a URL through which recipients can access the Corresponding
  21. * Source.
  22. */
  23. /* global browser, infobar, document, URL, Blob, MouseEvent, setTimeout, open */
  24. const MAX_CONTENT_SIZE = 32 * (1024 * 1024);
  25. export {
  26. downloadPage
  27. };
  28. async function downloadPage(pageData, options) {
  29. if (options.includeInfobar) {
  30. await infobar.includeScript(pageData);
  31. }
  32. if (options.includeBOM) {
  33. pageData.content = "\ufeff" + pageData.content;
  34. }
  35. if (options.backgroundSave || options.openEditor || options.saveToGDrive || options.saveToGitHub || options.saveWithCompanion) {
  36. for (let blockIndex = 0; blockIndex * MAX_CONTENT_SIZE < pageData.content.length; blockIndex++) {
  37. const message = {
  38. method: "downloads.download",
  39. taskId: options.taskId,
  40. confirmFilename: options.confirmFilename,
  41. filenameConflictAction: options.filenameConflictAction,
  42. filename: pageData.filename,
  43. saveToClipboard: options.saveToClipboard,
  44. saveToGDrive: options.saveToGDrive,
  45. saveToGitHub: options.saveToGitHub,
  46. githubToken: options.githubToken,
  47. githubUser: options.githubUser,
  48. githubRepository: options.githubRepository,
  49. githubBranch: options.githubBranch,
  50. saveWithCompanion: options.saveWithCompanion,
  51. forceWebAuthFlow: options.forceWebAuthFlow,
  52. filenameReplacementCharacter: options.filenameReplacementCharacter,
  53. openEditor: options.openEditor,
  54. openSavedPage: options.openSavedPage,
  55. compressHTML: options.compressHTML,
  56. backgroundSave: options.backgroundSave,
  57. bookmarkId: options.bookmarkId,
  58. replaceBookmarkURL: options.replaceBookmarkURL,
  59. applySystemTheme: options.applySystemTheme,
  60. defaultEditorMode: options.defaultEditorMode,
  61. includeInfobar: options.includeInfobar,
  62. warnUnsavedPage: options.warnUnsavedPage
  63. };
  64. message.truncated = pageData.content.length > MAX_CONTENT_SIZE;
  65. if (message.truncated) {
  66. message.finished = (blockIndex + 1) * MAX_CONTENT_SIZE > pageData.content.length;
  67. message.content = pageData.content.substring(blockIndex * MAX_CONTENT_SIZE, (blockIndex + 1) * MAX_CONTENT_SIZE);
  68. } else {
  69. message.content = pageData.content;
  70. }
  71. await browser.runtime.sendMessage(message);
  72. }
  73. } else {
  74. if (options.saveToClipboard) {
  75. saveToClipboard(pageData);
  76. } else {
  77. await downloadPageForeground(pageData);
  78. }
  79. if (options.openSavedPage) {
  80. open(URL.createObjectURL(new Blob([pageData.content], { type: "text/html" })));
  81. }
  82. browser.runtime.sendMessage({ method: "ui.processEnd" });
  83. }
  84. await browser.runtime.sendMessage({ method: "downloads.end", taskId: options.taskId, hash: pageData.hash, woleetKey: options.woleetKey });
  85. }
  86. async function downloadPageForeground(pageData) {
  87. if (pageData.filename && pageData.filename.length) {
  88. const link = document.createElement("a");
  89. link.download = pageData.filename;
  90. link.href = URL.createObjectURL(new Blob([pageData.content], { type: "text/html" }));
  91. link.dispatchEvent(new MouseEvent("click"));
  92. URL.revokeObjectURL(link.href);
  93. }
  94. return new Promise(resolve => setTimeout(resolve, 1));
  95. }
  96. function saveToClipboard(page) {
  97. const command = "copy";
  98. document.addEventListener(command, listener);
  99. document.execCommand(command);
  100. document.removeEventListener(command, listener);
  101. function listener(event) {
  102. event.clipboardData.setData("text/html", page.content);
  103. event.clipboardData.setData("text/plain", page.content);
  104. event.preventDefault();
  105. }
  106. }