1
0
Эх сурвалжийг харах

always auto-save pages in background

Gildas 7 жил өмнө
parent
commit
0e0009f231

+ 25 - 7
extension/core/bg/core.js

@@ -83,20 +83,33 @@ singlefile.core = (() => {
 		if (request.processContent) {
 			processBackgroundTab(sender.tab, request);
 		}
-	});	
+	});
 	browser.tabs.onRemoved.addListener(async tabId => {
 		const tabsData = await singlefile.storage.get();
 		delete tabsData[tabId];
 		await singlefile.storage.set(tabsData);
 	});
 
-	return { processTab, isAllowedURL };	
+	return { saveTab, autoSaveTab, isAllowedURL };
 
-	async function processTab(tab, processOptions) {
+	async function saveTab(tab, processOptions) {
 		const options = await singlefile.config.get();
 		Object.keys(processOptions).forEach(key => options[key] = processOptions[key]);
 		return new Promise(async (resolve, reject) => {
-			const processPromise = processStart(tab, options);
+			const processPromise = saveStart(tab, options);
+			try {
+				await processPromise;
+			} catch (error) {
+				reject(error);
+			}
+			resolve();
+		});
+	}
+
+	async function autoSaveTab(tab) {
+		const options = await singlefile.config.get();
+		return new Promise(async (resolve, reject) => {
+			const processPromise = autoSaveStart(tab, options);
 			try {
 				await processPromise;
 			} catch (error) {
@@ -162,15 +175,20 @@ singlefile.core = (() => {
 		});
 	}
 
-	async function processStart(tab, options) {
+	async function saveStart(tab, options) {
 		await executeScripts(tab.id, getContentScriptFiles(options), false);
 		if (options.frameId) {
-			await browser.tabs.sendMessage(tab.id, { processStartFrame: true, options }, { frameId: options.frameId });
+			await browser.tabs.sendMessage(tab.id, { saveFrame: true, options }, { frameId: options.frameId });
 		} else {
-			await browser.tabs.sendMessage(tab.id, { processStart: true, options });
+			await browser.tabs.sendMessage(tab.id, { savePage: true, options });
 		}
 	}
 
+	async function autoSaveStart(tab, options) {
+		await executeScripts(tab.id, getContentScriptFiles(options), false);
+		await browser.tabs.sendMessage(tab.id, { autoSavePage: true, options });
+	}
+
 	async function executeScripts(tabId, scriptFiles, allFrames) {
 		return Promise.all(scriptFiles.map(file => browser.tabs.executeScript(tabId, { file, allFrames })));
 	}

+ 3 - 3
extension/core/content/content-frame.js

@@ -24,11 +24,11 @@ this.singlefile.frame = this.singlefile.frame || (() => {
 
 	if (window != top) {
 		browser.runtime.onMessage.addListener(message => {
-			if (message.processStartFrame) {
+			if (message.saveFrame) {
 				message.options.content = docHelper.serialize(document);
-				message.processStartFrame = null;
+				message.saveFrameFrame = null;
 				message.options.frameId = null;
-				message.processStart = true;
+				message.savePage = true;
 				message.options.url = document.location.href;
 				top.postMessage("__SingleFile__::" + JSON.stringify(message), "*");
 			}

+ 41 - 32
extension/core/content/content.js

@@ -18,7 +18,7 @@
  *   along with SingleFile.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-/* global browser, SingleFile, singlefile, frameTree, document, Blob, MouseEvent, getSelection, prompt, addEventListener, Node, window */
+/* global browser, SingleFile, singlefile, frameTree, document, Blob, MouseEvent, getSelection, prompt, addEventListener, Node, window, docHelper, location */
 
 this.singlefile.top = this.singlefile.top || (() => {
 
@@ -26,53 +26,62 @@ this.singlefile.top = this.singlefile.top || (() => {
 	let autoSaveTimeout;
 
 	browser.runtime.onMessage.addListener(message => {
-		if (message.processStart) {
+		if (message.savePage) {
 			savePage(message);
 		}
+		if (message.autoSavePage) {
+			autoSavePage();
+		}
 	});
 
 	addEventListener("message", event => {
 		if (typeof event.data == "string" && event.data.startsWith("__SingleFile__::")) {
 			const message = JSON.parse(event.data.substring("__SingleFile__".length + 2));
-			if (message.processStart) {
+			if (message.savePage) {
 				savePage(message);
 			}
 		}
 	});
 	return true;
 
-	async function savePage(message) {
-		const options = message.options;
-		if ((!processing || options.autoSave) && !options.frameId) {
-			if (!autoSaveTimeout && options.autoSave && options.autoSaveDelay) {
-				autoSaveTimeout = setTimeout(() => savePage(message), options.autoSaveDelay * 1000);
+	async function autoSavePage() {
+		const [autoSaveEnabled, options] = await Promise.all([browser.runtime.sendMessage({ isAutoSaveEnabled: true }), browser.runtime.sendMessage({ getConfig: true })]);
+		if (autoSaveEnabled) {
+			if (options.autoSaveDelay && !autoSaveTimeout) {
+				autoSaveTimeout = setTimeout(() => {
+					autoSavePage();
+				}, options.autoSaveDelay * 1000);
 			} else {
-				autoSaveTimeout = null;
-				if (!options.autoSave) {
-					processing = true;
-				}
-				try {
-					const page = await processPage(options);
-					await downloadPage(page, options);
-					revokeDownloadURL(page);
-				} catch (error) {
-					console.error(error); // eslint-disable-line no-console
-					browser.runtime.sendMessage({ processError: true, error, options: { autoSave: options.autoSave } });
-				}
-				if (options.autoSave && options.autoSaveLoadOrUnload) {
-					singlefile.pageAutoSaved = true;
-				}
-				if (!options.autoSave) {
-					processing = false;
+				const docData = docHelper.preProcessDoc(document, window, options);
+				let framesData = [];
+				if (!options.removeFrames && this.frameTree) {
+					framesData = await frameTree.getAsync(options);
 				}
+				browser.runtime.sendMessage({ processContent: true, content: docHelper.serialize(document, false), canvasData: docData.canvasData, emptyStyleRulesText: docData.emptyStyleRulesText, framesData, url: location.href });
+				docHelper.postProcessDoc(document, window);
+				singlefile.pageAutoSaved = true;
 			}
 		}
 	}
 
-	async function processPage(options) {
-		if (options.shadowEnabled && !options.autoSave) {
-			singlefile.ui.init();
+	async function savePage(message) {
+		const options = message.options;
+		if (!processing && !options.frameId) {
+			processing = true;
+			try {
+				const page = await processPage(options);
+				await downloadPage(page, options);
+				revokeDownloadURL(page);
+			} catch (error) {
+				console.error(error); // eslint-disable-line no-console
+				browser.runtime.sendMessage({ processError: true, error, options: { autoSave: false } });
+			}
+			processing = false;
 		}
+	}
+
+	async function processPage(options) {
+		singlefile.ui.init();
 		const processor = new (SingleFile.getClass())(options);
 		options.insertSingleFileComment = true;
 		options.insertFaviconLink = true;
@@ -84,12 +93,12 @@ this.singlefile.top = this.singlefile.top || (() => {
 		options.win = window;
 		options.onprogress = event => {
 			if (event.type == event.RESOURCES_INITIALIZED || event.type == event.RESOURCE_LOADED) {
-				browser.runtime.sendMessage({ processProgress: true, index: event.details.index, maxIndex: event.details.max, options: { autoSave: options.autoSave } });
-				if (options.shadowEnabled && !options.autoSave) {
+				browser.runtime.sendMessage({ processProgress: true, index: event.details.index, maxIndex: event.details.max, options: { autoSave: false } });
+				if (options.shadowEnabled) {
 					singlefile.ui.onprogress(event);
 				}
 			} else if (event.type == event.PAGE_ENDED) {
-				browser.runtime.sendMessage({ processEnd: true, options: { autoSave: options.autoSave } });
+				browser.runtime.sendMessage({ processEnd: true, options: { autoSave: false } });
 			}
 		};
 		if (options.selected) {
@@ -107,7 +116,7 @@ this.singlefile.top = this.singlefile.top || (() => {
 		const date = new Date();
 		page.filename = page.title + (options.appendSaveDate ? " (" + date.toISOString().split("T")[0] + " " + date.toLocaleTimeString() + ")" : "") + ".html";
 		page.url = URL.createObjectURL(new Blob([page.content], { type: "text/html" }));
-		if (options.shadowEnabled && !options.autoSave) {
+		if (options.shadowEnabled) {
 			singlefile.ui.end();
 		}
 		if (options.displayStats) {

+ 6 - 2
extension/ui/bg/bg-ui.js

@@ -23,11 +23,15 @@
 singlefile.ui = (() => {
 
 	return {
-		async processTab(tab, options = {}) {
+		async saveTab(tab, options = {}) {
 			const tabId = tab.id;
 			try {
 				singlefile.ui.button.onInitialize(tabId, options, 1);
-				await singlefile.core.processTab(tab, options);
+				if (options.autoSave) {
+					await singlefile.core.autoSaveTab(tab, options);
+				} else {
+					await singlefile.core.saveTab(tab, options);
+				}
 				singlefile.ui.button.onInitialize(tabId, options, 2);
 			} catch (error) {
 				console.log(error); // eslint-disable-line no-console

+ 3 - 3
extension/ui/bg/ui-autosave.js

@@ -21,15 +21,15 @@
 /* global browser, singlefile */
 
 singlefile.ui.autosave = (() => {
-
+	
 	browser.tabs.onUpdated.addListener(async (tabId, changeInfo, tab) => {
 		const [config, tabsData] = await Promise.all([singlefile.config.get(), singlefile.storage.get()]);
 		if ((config.autoSaveLoad || config.autoSaveLoadOrUnload) && (tabsData.autoSaveAll || (tabsData.autoSaveUnpinned && !tab.pinned) || (tabsData[tab.id] && tabsData[tab.id].autoSave))) {
 			if (changeInfo.status == "complete") {
-				singlefile.ui.processTab(tab, { autoSave: true });
+				singlefile.ui.saveTab(tab, { autoSave: true });
 			}
 		}
-	});
+	});	
 	browser.runtime.onMessage.addListener((request, sender) => {
 		if (request.isAutoSaveEnabled) {
 			return isEnabled(sender.tab.id);

+ 2 - 2
extension/ui/bg/ui-button.js

@@ -32,9 +32,9 @@ singlefile.ui.button = (() => {
 		if (singlefile.core.isAllowedURL(tab.url)) {
 			const tabs = await browser.tabs.query({ currentWindow: true, highlighted: true });
 			if (!tabs.length) {
-				singlefile.ui.processTab(tab);
+				singlefile.ui.saveTab(tab);
 			} else {
-				tabs.forEach(tab => singlefile.core.isAllowedURL(tab.url) && singlefile.ui.processTab(tab));
+				tabs.forEach(tab => singlefile.core.isAllowedURL(tab.url) && singlefile.ui.saveTab(tab));
 			}
 		}
 	});

+ 6 - 6
extension/ui/bg/ui-menu.js

@@ -147,25 +147,25 @@ singlefile.ui.menu = (() => {
 			refresh();
 			browser.menus.onClicked.addListener(async (event, tab) => {
 				if (event.menuItemId == MENU_ID_SAVE_PAGE) {
-					singlefile.ui.processTab(tab);
+					singlefile.ui.saveTab(tab);
 				}
 				if (event.menuItemId == MENU_ID_SAVE_SELECTED) {
-					singlefile.ui.processTab(tab, { selected: true });
+					singlefile.ui.saveTab(tab, { selected: true });
 				}
 				if (event.menuItemId == MENU_ID_SAVE_FRAME) {
-					singlefile.ui.processTab(tab, { frameId: event.frameId });
+					singlefile.ui.saveTab(tab, { frameId: event.frameId });
 				}
 				if (event.menuItemId == MENU_ID_SAVE_SELECTED_TABS) {
 					const tabs = await browser.tabs.query({ currentWindow: true, highlighted: true });
-					tabs.forEach(tab => singlefile.core.isAllowedURL(tab.url) && singlefile.ui.processTab(tab));
+					tabs.forEach(tab => singlefile.core.isAllowedURL(tab.url) && singlefile.ui.saveTab(tab));
 				}
 				if (event.menuItemId == MENU_ID_SAVE_UNPINNED_TABS) {
 					const tabs = await browser.tabs.query({ currentWindow: true, pinned: false });
-					tabs.forEach(tab => singlefile.core.isAllowedURL(tab.url) && singlefile.ui.processTab(tab));
+					tabs.forEach(tab => singlefile.core.isAllowedURL(tab.url) && singlefile.ui.saveTab(tab));
 				}
 				if (event.menuItemId == MENU_ID_SAVE_ALL_TABS) {
 					const tabs = await browser.tabs.query({ currentWindow: true });
-					tabs.forEach(tab => singlefile.core.isAllowedURL(tab.url) && singlefile.ui.processTab(tab));
+					tabs.forEach(tab => singlefile.core.isAllowedURL(tab.url) && singlefile.ui.saveTab(tab));
 				}
 				if (event.menuItemId == MENU_ID_AUTO_SAVE_TAB) {
 					const tabsData = await singlefile.storage.get();