Browse Source

extracted script-loader and processor from core

Gildas 7 years ago
parent
commit
0692d5e80f

+ 13 - 4
extension/core/bg/config.js

@@ -52,6 +52,11 @@ singlefile.config = (() => {
 	};
 
 	let pendingUpgradePromise;
+	browser.runtime.onMessage.addListener(request => {
+		if (request.getConfig) {
+			return getConfig();
+		}
+	});
 	upgrade();
 
 	async function upgrade() {
@@ -135,16 +140,20 @@ singlefile.config = (() => {
 		}
 	}
 
+	async function getConfig() {
+		await pendingUpgradePromise;
+		const config = await browser.storage.local.get();
+		config.tabsData = undefined;
+		return Object.keys(config).length ? config : DEFAULT_CONFIG;
+	}
+
 	return {
 		async set(config) {
 			await pendingUpgradePromise;
 			await browser.storage.local.set(config);
 		},
 		async get() {
-			await pendingUpgradePromise;
-			const config = await browser.storage.local.get();
-			config.tabsData = undefined;
-			return Object.keys(config).length ? config : DEFAULT_CONFIG;
+			return getConfig();
 		},
 		async reset() {
 			await pendingUpgradePromise;

+ 4 - 131
extension/core/bg/core.js

@@ -18,76 +18,19 @@
  *   along with SingleFile.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-/* global browser, SingleFile, singlefile, Blob */
+/* global browser, singlefile */
 
 singlefile.core = (() => {
 
 	const FORBIDDEN_URLS = ["https://chrome.google.com", "https://addons.mozilla.org"];
 
-	const contentScriptFiles = [
-		"/lib/browser-polyfill/custom-browser-polyfill.js",
-		"/lib/single-file/doc-helper.js",
-		"/lib/single-file/base64.js",
-		"/lib/single-file/parse-srcset.js",
-		"/lib/fetch/content/fetch.js",
-		"/lib/single-file/single-file-core.js",
-		"/lib/single-file/single-file-browser.js",
-		"/extension/index.js",
-		"/extension/ui/content/content-ui.js",
-		"/extension/core/content/content.js"
-	];
-	const frameScriptFiles = [
-		"/lib/browser-polyfill/custom-browser-polyfill.js",
-		"/extension/index.js",
-		"/lib/single-file/doc-helper.js",
-		"/lib/single-file/timeout.js",
-		"/lib/single-file/frame-tree.js",
-		"/extension/core/content/content-frame.js"
-	];
-
-	const optionalContentScriptFiles = {
-		compressHTML: [
-			"/lib/single-file/htmlmini.js",
-			"/lib/single-file/serializer.js"
-		],
-		compressCSS: [
-			"/lib/single-file/uglifycss.js"
-		],
-		removeAlternativeFonts: [
-			"/lib/single-file/fonts-minifier.js"
-		],
-		removeUnusedStyles: [
-			"/lib/single-file/css-what.js",
-			"/lib/single-file/parse-css.js",
-			"/lib/single-file/rules-matcher.js",
-			"/lib/single-file/css-minifier.js"
-		],
-		lazyLoadImages: [
-			"/lib/single-file/lazy-loader.js",
-		]
-	};
-
-	browser.runtime.onMessage.addListener((request, sender) => {
-		if (request.getConfig) {
-			return singlefile.config.get();
-		}
-		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 { saveTab, autoSaveTab, isAllowedURL };
 
 	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 = saveStart(tab, options);
+			const processPromise = singlefile.scriptLoader.executeScripts(tab, options);
 			try {
 				await processPromise;
 			} catch (error) {
@@ -99,13 +42,8 @@ singlefile.core = (() => {
 
 	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) {
-				reject(error);
-			}
+		return new Promise(async resolve => {
+			await browser.tabs.sendMessage(tab.id, { autoSavePage: true, options });
 			resolve();
 		});
 	}
@@ -114,69 +52,4 @@ singlefile.core = (() => {
 		return url && (url.startsWith("http://") || url.startsWith("https://") || url.startsWith("file://")) && !FORBIDDEN_URLS.find(storeUrl => url.startsWith(storeUrl));
 	}
 
-	async function processBackgroundTab(tab, message) {
-		const options = await singlefile.config.get();
-		options.content = message.content;
-		options.url = message.url;
-		options.framesData = message.framesData;
-		options.canvasData = message.canvasData;
-		options.stylesheetContents = message.stylesheetContents;
-		options.imageData = message.imageData;
-		options.insertSingleFileComment = true;
-		options.insertFaviconLink = true;
-		options.backgroundTab = true;
-		options.autoSave = true;
-		options.incognito = tab.incognito;
-		let index = 0, maxIndex = 0;
-		options.onprogress = async event => {
-			if (event.type == event.RESOURCES_INITIALIZED) {
-				maxIndex = event.details.max;
-			}
-			if (event.type == event.RESOURCES_INITIALIZED || event.type == event.RESOURCE_LOADED) {
-				index++;
-				singlefile.ui.button.onProgress(tab.id, index, maxIndex, { autoSave: true });
-			} else if (event.type == event.PAGE_ENDED) {
-				singlefile.ui.button.onEnd(tab.id, { autoSave: true });
-			}
-		};
-		const processor = new (SingleFile.getClass())(options);
-		await processor.initialize();
-		await processor.preparePageData();
-		const page = processor.getPageData();
-		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" }));
-		return singlefile.download.downloadPage(page, options);
-	}
-
-	async function saveStart(tab, options) {
-		if (!options.removeFrames) {
-			await executeScripts(tab.id, frameScriptFiles, true);
-		}
-		await executeScripts(tab.id, getContentScriptFiles(options), false);
-		if (options.frameId) {
-			await browser.tabs.sendMessage(tab.id, { saveFrame: true, options }, { frameId: options.frameId });
-		} else {
-			await browser.tabs.sendMessage(tab.id, { savePage: true, options });
-		}
-	}
-
-	async function autoSaveStart(tab, options) {
-		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 })));
-	}
-
-	function getContentScriptFiles(options) {
-		let files = contentScriptFiles;
-		Object.keys(optionalContentScriptFiles).forEach(option => {
-			if (options[option]) {
-				files = optionalContentScriptFiles[option].concat(files);
-			}
-		});
-		return files;
-	}
-
 })();

+ 68 - 0
extension/core/bg/processor.js

@@ -0,0 +1,68 @@
+/*
+ * Copyright 2018 Gildas Lormeau
+ * contact : gildas.lormeau <at> gmail.com
+ * 
+ * This file is part of SingleFile.
+ *
+ *   SingleFile is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU Lesser General Public License as published by
+ *   the Free Software Foundation, either version 3 of the License, or
+ *   (at your option) any later version.
+ *
+ *   SingleFile is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU Lesser General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Lesser General Public License
+ *   along with SingleFile.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* global browser, SingleFile, singlefile, Blob */
+
+singlefile.processor = (() => {
+
+	browser.runtime.onMessage.addListener((request, sender) => {
+		if (request.saveContent) {
+			saveContent(request, sender.tab.id, sender.tab.incognito);
+		}
+	});
+
+	return true;
+
+	async function saveContent(message, tabId, incognito) {
+		const options = await singlefile.config.get();
+		options.content = message.content;
+		options.url = message.url;
+		options.framesData = message.framesData;
+		options.canvasData = message.canvasData;
+		options.stylesheetContents = message.stylesheetContents;
+		options.imageData = message.imageData;
+		options.insertSingleFileComment = true;
+		options.insertFaviconLink = true;
+		options.backgroundTab = true;
+		options.autoSave = true;
+		options.incognito = incognito;
+		let index = 0, maxIndex = 0;
+		options.onprogress = async event => {
+			if (event.type == event.RESOURCES_INITIALIZED) {
+				maxIndex = event.details.max;
+			}
+			if (event.type == event.RESOURCES_INITIALIZED || event.type == event.RESOURCE_LOADED) {
+				index++;
+				singlefile.ui.button.onProgress(tabId, index, maxIndex, { autoSave: true });
+			} else if (event.type == event.PAGE_ENDED) {
+				singlefile.ui.button.onEnd(tabId, { autoSave: true });
+			}
+		};
+		const processor = new (SingleFile.getClass())(options);
+		await processor.initialize();
+		await processor.preparePageData();
+		const page = processor.getPageData();
+		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" }));
+		return singlefile.download.downloadPage(page, options);
+	}
+
+})();

+ 96 - 0
extension/core/bg/script-loader.js

@@ -0,0 +1,96 @@
+/*
+ * Copyright 2018 Gildas Lormeau
+ * contact : gildas.lormeau <at> gmail.com
+ * 
+ * This file is part of SingleFile.
+ *
+ *   SingleFile is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU Lesser General Public License as published by
+ *   the Free Software Foundation, either version 3 of the License, or
+ *   (at your option) any later version.
+ *
+ *   SingleFile is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU Lesser General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Lesser General Public License
+ *   along with SingleFile.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* global browser, singlefile */
+
+singlefile.scriptLoader = (() => {
+
+	const contentScriptFiles = [
+		"/lib/browser-polyfill/custom-browser-polyfill.js",
+		"/lib/single-file/doc-helper.js",
+		"/lib/single-file/base64.js",
+		"/lib/single-file/parse-srcset.js",
+		"/lib/fetch/content/fetch.js",
+		"/lib/single-file/single-file-core.js",
+		"/lib/single-file/single-file-browser.js",
+		"/extension/index.js",
+		"/extension/ui/content/content-ui.js",
+		"/extension/core/content/content.js"
+	];
+	const frameScriptFiles = [
+		"/lib/browser-polyfill/custom-browser-polyfill.js",
+		"/extension/index.js",
+		"/lib/single-file/doc-helper.js",
+		"/lib/single-file/timeout.js",
+		"/lib/single-file/frame-tree.js",
+		"/extension/core/content/content-frame.js"
+	];
+
+	const optionalContentScriptFiles = {
+		compressHTML: [
+			"/lib/single-file/htmlmini.js",
+			"/lib/single-file/serializer.js"
+		],
+		compressCSS: [
+			"/lib/single-file/uglifycss.js"
+		],
+		removeAlternativeFonts: [
+			"/lib/single-file/fonts-minifier.js"
+		],
+		removeUnusedStyles: [
+			"/lib/single-file/css-what.js",
+			"/lib/single-file/parse-css.js",
+			"/lib/single-file/rules-matcher.js",
+			"/lib/single-file/css-minifier.js"
+		],
+		lazyLoadImages: [
+			"/lib/single-file/lazy-loader.js",
+		]
+	};
+
+	return { executeScripts };
+
+	async function executeScripts(tab, options) {
+		if (!options.removeFrames) {
+			await executeContentScripts(tab.id, frameScriptFiles, true);
+		}
+		await executeContentScripts(tab.id, getContentScriptFiles(options), false);
+		if (options.frameId) {
+			await browser.tabs.sendMessage(tab.id, { saveFrame: true, options }, { frameId: options.frameId });
+		} else {
+			await browser.tabs.sendMessage(tab.id, { savePage: true, options });
+		}
+	}
+
+	async function executeContentScripts(tabId, scriptFiles, allFrames) {
+		return Promise.all(scriptFiles.map(file => browser.tabs.executeScript(tabId, { file, allFrames })));
+	}
+
+	function getContentScriptFiles(options) {
+		let files = contentScriptFiles;
+		Object.keys(optionalContentScriptFiles).forEach(option => {
+			if (options[option]) {
+				files = optionalContentScriptFiles[option].concat(files);
+			}
+		});
+		return files;
+	}
+
+})();

+ 5 - 0
extension/core/bg/storage.js

@@ -24,6 +24,11 @@ singlefile.storage = (() => {
 
 	let persistentData;
 	let temporaryData;
+	browser.tabs.onRemoved.addListener(async tabId => {
+		const tabsData = await singlefile.storage.get();
+		delete tabsData[tabId];
+		await singlefile.storage.set(tabsData);
+	});
 	getPersistent().then(tabsData => persistentData = tabsData);
 	return {
 		getTemporary,

+ 2 - 2
extension/core/content/content-autosave.js

@@ -47,7 +47,7 @@ this.singlefile.autosave = this.singlefile.autosave || (async () => {
 				if (!options.removeFrames && this.frameTree) {
 					framesData = await frameTree.getAsync(options);
 				}
-				browser.runtime.sendMessage({ processContent: true, content: docHelper.serialize(document, false), canvasData: docData.canvasData, stylesheetContents: docData.stylesheetContents, imageData: docData.imageData, framesData, url: location.href });
+				browser.runtime.sendMessage({ saveContent: true, content: docHelper.serialize(document, false), canvasData: docData.canvasData, stylesheetContents: docData.stylesheetContents, imageData: docData.imageData, framesData, url: location.href });
 				docHelper.postProcessDoc(document, window);
 				singlefile.pageAutoSaved = true;
 			}
@@ -75,7 +75,7 @@ this.singlefile.autosave = this.singlefile.autosave || (async () => {
 	function onUnload() {
 		if (!singlefile.pageAutoSaved) {
 			const docData = docHelper.preProcessDoc(document, window, options);
-			browser.runtime.sendMessage({ processContent: true, content: docHelper.serialize(document), canvasData: docData.canvasData, stylesheetContents: docData.stylesheetContents, imageData: docData.imageData, framesData: this.frameTree && !options.removeFrames && frameTree.getSync(options), url: location.href });
+			browser.runtime.sendMessage({ saveContent: true, content: docHelper.serialize(document), canvasData: docData.canvasData, stylesheetContents: docData.stylesheetContents, imageData: docData.imageData, framesData: this.frameTree && !options.removeFrames && frameTree.getSync(options), url: location.href });
 		}
 	}
 

+ 2 - 0
manifest.json

@@ -46,6 +46,8 @@
 			"extension/index.js",
 			"extension/core/bg/storage.js",
 			"extension/core/bg/download.js",
+			"extension/core/bg/script-loader.js",
+			"extension/core/bg/processor.js",
 			"extension/core/bg/config.js",
 			"extension/core/bg/core.js",
 			"extension/ui/bg/bg-ui.js",