content-download.js 3.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /*
  2. * Copyright 2010-2019 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, document, URL, Blob, MouseEvent */
  24. this.singlefile.extension.core.content.download = this.singlefile.extension.core.content.download || (() => {
  25. const singlefile = this.singlefile;
  26. const MAX_CONTENT_SIZE = 32 * (1024 * 1024);
  27. return { downloadPage };
  28. async function downloadPage(pageData, options) {
  29. if (options.includeInfobar) {
  30. await singlefile.common.ui.content.infobar.includeScript(pageData);
  31. }
  32. if (options.backgroundSave || options.openEditor || options.saveToGDrive) {
  33. for (let blockIndex = 0; blockIndex * MAX_CONTENT_SIZE < pageData.content.length; blockIndex++) {
  34. const message = {
  35. method: "downloads.download",
  36. taskId: options.taskId,
  37. confirmFilename: options.confirmFilename,
  38. filenameConflictAction: options.filenameConflictAction,
  39. filename: pageData.filename,
  40. saveToClipboard: options.saveToClipboard,
  41. saveToGDrive: options.saveToGDrive,
  42. forceWebAuthFlow: options.forceWebAuthFlow,
  43. extractAuthCode: options.extractAuthCode,
  44. filenameReplacementCharacter: options.filenameReplacementCharacter,
  45. openEditor: options.openEditor,
  46. compressHTML: options.compressHTML,
  47. backgroundSave: options.backgroundSave
  48. };
  49. message.truncated = pageData.content.length > MAX_CONTENT_SIZE;
  50. if (message.truncated) {
  51. message.finished = (blockIndex + 1) * MAX_CONTENT_SIZE > pageData.content.length;
  52. message.content = pageData.content.substring(blockIndex * MAX_CONTENT_SIZE, (blockIndex + 1) * MAX_CONTENT_SIZE);
  53. } else {
  54. message.content = pageData.content;
  55. }
  56. await browser.runtime.sendMessage(message);
  57. }
  58. } else {
  59. if (options.saveToClipboard) {
  60. saveToClipboard(pageData);
  61. } else {
  62. downloadPageForeground(pageData);
  63. }
  64. browser.runtime.sendMessage({ method: "ui.processEnd" });
  65. }
  66. await browser.runtime.sendMessage({ method: "downloads.end", taskId: options.taskId });
  67. }
  68. function downloadPageForeground(pageData) {
  69. if (pageData.filename && pageData.filename.length) {
  70. const link = document.createElement("a");
  71. link.download = pageData.filename;
  72. link.href = URL.createObjectURL(new Blob([pageData.content], { type: "text/html" }));
  73. link.dispatchEvent(new MouseEvent("click"));
  74. URL.revokeObjectURL(link.href);
  75. }
  76. }
  77. function saveToClipboard(page) {
  78. const command = "copy";
  79. document.addEventListener(command, listener);
  80. document.execCommand(command);
  81. document.removeEventListener(command, listener);
  82. function listener(event) {
  83. event.clipboardData.setData("text/html", page.content);
  84. event.clipboardData.setData("text/plain", page.content);
  85. event.preventDefault();
  86. }
  87. }
  88. })();