Преглед изворни кода

send chunked content to the background page if content size > 64MB

Gildas пре 7 година
родитељ
комит
d568c42465
2 измењених фајлова са 29 додато и 2 уклоњено
  1. 16 1
      extension/core/bg/download.js
  2. 13 1
      extension/core/content/content.js

+ 16 - 1
extension/core/bg/download.js

@@ -22,10 +22,25 @@
 
 singlefile.download = (() => {
 
+	const partialContents = new Map();
+
 	browser.runtime.onMessage.addListener((request, sender) => {
 		if (request.download) {
 			try {
-				if (request.content) {
+				if (request.truncated) {
+					let partialContent = partialContents.get(sender.tab.id);
+					if (!partialContent) {
+						partialContent = [];
+						partialContents.set(sender.tab.id, partialContent);
+					}
+					partialContent.push(request.content);
+					if (request.finished) {
+						partialContents.delete(sender.tab.id);
+						request.url = URL.createObjectURL(new Blob(partialContent, { type: "text/html" }));
+					} else {
+						return Promise.resolve({});
+					}
+				} else if (request.content) {
 					request.url = URL.createObjectURL(new Blob([request.content], { type: "text/html" }));
 				}
 				return downloadPage(request, { confirmFilename: request.confirmFilename, incognito: sender.tab.incognito, conflictAction: request.filenameConflictAction })

+ 13 - 1
extension/core/content/content.js

@@ -23,6 +23,7 @@
 this.singlefile.top = this.singlefile.top || (() => {
 
 	const MESSAGE_PREFIX = "__SingleFile__::";
+	const MAX_CONTENT_SIZE = 64 * (1024 * 1024);
 	const SingleFile = SingleFileBrowser.getClass();
 
 	let processing = false;
@@ -153,7 +154,18 @@ this.singlefile.top = this.singlefile.top || (() => {
 		if (options.backgroundSave) {
 			const response = await browser.runtime.sendMessage({ download: true, url: page.url, confirmFilename: options.confirmFilename, filenameConflictAction: options.filenameConflictAction, filename: page.filename });
 			if (response.notSupported) {
-				const response = await browser.runtime.sendMessage({ download: true, content: page.content, confirmFilename: options.confirmFilename, filenameConflictAction: options.filenameConflictAction, filename: page.filename });
+				let response;
+				for (let blockIndex = 0; (!response || !response.notSupported) && (blockIndex * MAX_CONTENT_SIZE < page.content.length); blockIndex++) {
+					const message = { download: true, confirmFilename: options.confirmFilename, filenameConflictAction: options.filenameConflictAction, filename: page.filename };
+					message.truncated = page.content.length > MAX_CONTENT_SIZE;
+					if (message.truncated) {
+						message.finished = (blockIndex + 1) * MAX_CONTENT_SIZE > page.content.length;
+						message.content = page.content.substring(blockIndex * MAX_CONTENT_SIZE, (blockIndex + 1) * MAX_CONTENT_SIZE);
+					} else {
+						message.content = page.content;
+					}
+					response = await browser.runtime.sendMessage(message);
+				}
 				if (response.notSupported) {
 					downloadPageFallback(page, options);
 				}