Przeglądaj źródła

use a unique id for each task

Former-commit-id: ab4ab62272c68e0fe7426c35f34e01b91f44eff0
Gildas 6 lat temu
rodzic
commit
60fb0c033e

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

@@ -126,13 +126,13 @@ singlefile.extension.core.bg.autosave = (() => {
 			}
 			const blob = new Blob([pageData.content], { type: "text/html" });
 			if (options.saveToGDrive) {
-				await singlefile.extension.core.bg.downloads.uploadPage(tab.id, pageData.filename, blob, options, {});
+				await singlefile.extension.core.bg.downloads.uploadPage(message.taskId, pageData.filename, blob, options, {});
 			} else {
 				pageData.url = URL.createObjectURL(blob);
 				await singlefile.extension.core.bg.downloads.downloadPage(pageData, options);
 			}
 		} finally {
-			singlefile.extension.core.bg.business.onSaveEnd(tab.id);
+			singlefile.extension.core.bg.business.onSaveEnd(message.taskId);
 			if (pageData && pageData.url) {
 				URL.revokeObjectURL(pageData.url);
 			}

+ 52 - 43
extension/core/bg/business.js

@@ -42,26 +42,28 @@ singlefile.extension.core.bg.business = (() => {
 		"extension/ui/content/content-ui-main.js"
 	];
 
-	const pendingSaves = new Map();
+	const tasks = [];
+	let currentTaskId = 0;
 
 	return {
-		isSavingTab: tab => pendingSaves.has(tab.id),
+		isSavingTab: tab => Boolean(tasks.find(taskInfo => taskInfo.tab.id == tab.id)),
 		saveTabs,
 		saveLink,
 		cancelTab,
-		cancelAllTabs: () => Array.from(pendingSaves).forEach(([tabId]) => cancelTab(tabId)),
-		getTabsInfo: () => Array.from(pendingSaves).map(mapSaveInfo),
-		getTabInfo: tabId => pendingSaves.get(tabId),
-		setCancelCallback: (tabId, cancelCallback) => {
-			const saveInfo = pendingSaves.get(tabId);
-			if (saveInfo) {
-				saveInfo.cancel = cancelCallback;
+		cancelTask: taskId => cancelTask(tasks.find(taskInfo => taskInfo.taskId == taskId)),
+		cancelAllTasks: () => Array.from(tasks).forEach(cancelTask),
+		getTasksInfo: () => tasks.map(mapTaskInfo),
+		getTaskInfo: taskId => tasks.find(taskInfo => taskInfo.id == taskId),
+		setCancelCallback: (taskId, cancelCallback) => {
+			const taskInfo = tasks.find(taskInfo => taskInfo.id == taskId);
+			if (taskInfo) {
+				taskInfo.cancel = cancelCallback;
 			}
 		},
-		onSaveEnd: tabId => {
-			const saveInfo = pendingSaves.get(tabId);
-			if (saveInfo) {
-				saveInfo.resolve();
+		onSaveEnd: taskId => {
+			const taskInfo = tasks.find(taskInfo => taskInfo.id == taskId);
+			if (taskInfo) {
+				taskInfo.resolve();
 			}
 		},
 		onTabUpdated: cancelTab,
@@ -82,50 +84,54 @@ singlefile.extension.core.bg.business = (() => {
 			tabOptions.extensionScriptFiles = extensionScriptFiles;
 			if (options.autoSave) {
 				if (autosave.isEnabled(tab)) {
-					pendingSaves.set(tab.id, { status: "pending", tab, options: tabOptions, method: "content.autosave" });
+					tasks.push({ id: currentTaskId, status: "pending", tab, options: tabOptions, method: "content.autosave" });
+					currentTaskId++;
 				}
 			} else {
 				ui.onStart(tabId, INJECT_SCRIPTS_STEP);
 				const scriptsInjected = await singlefile.extension.injectScript(tabId, tabOptions);
 				if (scriptsInjected) {
 					ui.onStart(tabId, EXECUTE_SCRIPTS_STEP);
-					pendingSaves.set(tab.id, { status: "pending", tab, options: tabOptions, method: "content.save" });
+					tasks.push({ id: currentTaskId, status: "pending", tab, options: tabOptions, method: "content.save" });
+					currentTaskId++;
 				} else {
 					ui.onForbiddenDomain(tab);
 				}
 			}
 		}));
-		const processingCount = Array.from(pendingSaves).filter(([, saveInfo]) => saveInfo.status == "processing").length;
+		const processingCount = tasks.filter(taskInfo => taskInfo.status == "processing").length;
 		for (let index = 0; index < Math.min(tabs.length, (maxParallelWorkers - processingCount)); index++) {
 			runTask();
 		}
 	}
 
 	function runTask() {
-		const nextPendingSave = Array.from(pendingSaves).find(([, saveInfo]) => saveInfo.status == "pending");
-		if (nextPendingSave) {
-			const [tabId, saveInfo] = nextPendingSave;
+		const taskInfo = tasks.find(taskInfo => taskInfo.status == "pending");
+		if (taskInfo) {
+			const tabId = taskInfo.tab.id;
+			const taskId = taskInfo.id;
 			return new Promise((resolve, reject) => {
-				saveInfo.status = "processing";
-				saveInfo.resolve = async () => {
-					if (saveInfo.options.autoClose && !saveInfo.cancelled) {
-						singlefile.extension.core.bg.tabs.remove(tabId);
+				taskInfo.status = "processing";
+				taskInfo.resolve = async () => {
+					if (taskInfo.options.autoClose && !taskInfo.cancelled) {
+						singlefile.extension.core.bg.tabs.remove(taskInfo.tab.id);
 					}
-					pendingSaves.delete(tabId);
+					tasks.splice(tasks.findIndex(taskInfo => taskInfo.id == taskId), 1);
 					resolve();
 					await runTask();
 				};
-				saveInfo.reject = async error => {
-					pendingSaves.delete(tabId);
+				taskInfo.reject = async error => {
+					tasks.splice(tasks.findIndex(taskInfo => taskInfo.id == taskId), 1);
 					reject(error);
 					await runTask();
 				};
-				singlefile.extension.core.bg.tabs.sendMessage(tabId, { method: saveInfo.method, options: saveInfo.options })
+				taskInfo.options.taskId = taskId;
+				singlefile.extension.core.bg.tabs.sendMessage(tabId, { method: taskInfo.method, options: taskInfo.options })
 					.catch(error => {
 						if (error && (!error.message || (error.message != ERROR_CONNECTION_LOST_CHROMIUM && error.message != ERROR_CONNECTION_ERROR_CHROMIUM && error.message != ERROR_CONNECTION_LOST_GECKO))) {
 							console.log(error); // eslint-disable-line no-console
 							singlefile.extension.ui.bg.main.onError(tabId);
-							saveInfo.reject(error);
+							taskInfo.reject(error);
 						}
 					});
 			});
@@ -140,24 +146,27 @@ singlefile.extension.core.bg.business = (() => {
 	}
 
 	function cancelTab(tabId) {
-		if (pendingSaves.has(tabId)) {
-			const saveInfo = pendingSaves.get(tabId);
-			saveInfo.cancelled = true;
-			singlefile.extension.core.bg.tabs.sendMessage(tabId, { method: "content.cancelSave" });
-			if (saveInfo.cancel) {
-				saveInfo.cancel();
-			}
-			if (saveInfo.method == "content.autosave") {
-				singlefile.extension.ui.bg.main.onEnd(tabId, true);
-			}
-			singlefile.extension.ui.bg.main.onCancelled(saveInfo.tab);
-			pendingSaves.delete(tabId);
-			saveInfo.resolve();
+		Array.from(tasks).filter(taskInfo => taskInfo.tab.id == tabId).forEach(cancelTask);
+	}
+
+	function cancelTask(taskInfo) {
+		const tabId = taskInfo.tab.id;
+		const taskId = taskInfo.id;
+		taskInfo.cancelled = true;
+		singlefile.extension.core.bg.tabs.sendMessage(tabId, { method: "content.cancelSave" });
+		if (taskInfo.cancel) {
+			taskInfo.cancel();
+		}
+		if (taskInfo.method == "content.autosave") {
+			singlefile.extension.ui.bg.main.onEnd(tabId, true);
 		}
+		singlefile.extension.ui.bg.main.onCancelled(taskInfo.tab);
+		tasks.splice(tasks.findIndex(taskInfo => taskInfo.id == taskId), 1);
+		taskInfo.resolve();
 	}
 
-	function mapSaveInfo([tabId, saveInfo]) {
-		return [tabId, { index: saveInfo.tab.index, url: saveInfo.tab.url, title: saveInfo.tab.title, cancelled: saveInfo.cancelled, status: saveInfo.status }];
+	function mapTaskInfo(taskInfo) {
+		return { id: taskInfo.id, tabId: taskInfo.tab.id, index: taskInfo.tab.index, url: taskInfo.tab.url, title: taskInfo.tab.title, cancelled: taskInfo.cancelled, status: taskInfo.status };
 	}
 
 })();

+ 10 - 10
extension/core/bg/downloads.js

@@ -60,18 +60,18 @@ singlefile.extension.core.bg.downloads = (() => {
 			return {};
 		}
 		if (message.method.endsWith(".end")) {
-			singlefile.extension.core.bg.business.onSaveEnd(sender.tab.id);
+			singlefile.extension.core.bg.business.onSaveEnd(message.taskId);
 			return {};
 		}
 		if (message.method.endsWith(".getInfo")) {
-			return singlefile.extension.core.bg.business.getTabsInfo();
+			return singlefile.extension.core.bg.business.getTasksInfo();
 		}
 		if (message.method.endsWith(".cancel")) {
-			singlefile.extension.core.bg.business.cancelTab(message.tabId);
+			singlefile.extension.core.bg.business.cancelTask(message.taskId);
 			return {};
 		}
 		if (message.method.endsWith(".cancelAll")) {
-			singlefile.extension.core.bg.business.cancelAllTabs(message.tabId);
+			singlefile.extension.core.bg.business.cancelAllTasks();
 			return {};
 		}
 	}
@@ -120,7 +120,7 @@ singlefile.extension.core.bg.downloads = (() => {
 	async function downloadBlob(blob, tabId, incognito, message) {
 		try {
 			if (message.saveToGDrive) {
-				await uploadPage(tabId, message.filename, blob, {
+				await uploadPage(message.taskId, message.filename, blob, {
 					forceWebAuthFlow: message.forceWebAuthFlow,
 					extractAuthCode: message.extractAuthCode
 				}, {
@@ -171,13 +171,13 @@ singlefile.extension.core.bg.downloads = (() => {
 		return authInfo;
 	}
 
-	async function uploadPage(tabId, filename, blob, authOptions, uploadOptions) {
+	async function uploadPage(taskId, filename, blob, authOptions, uploadOptions) {
 		try {
 			await getAuthInfo(authOptions);
-			const saveInfo = singlefile.extension.core.bg.business.getTabInfo(tabId);
-			if (saveInfo && !saveInfo.cancelled) {
+			const taskInfo = singlefile.extension.core.bg.business.getTaskInfo(taskId);
+			if (taskInfo && !taskInfo.cancelled) {
 				const uploadInfo = await gDrive.upload(filename, blob, uploadOptions);
-				singlefile.extension.core.bg.business.setCancelCallback(tabId, uploadInfo.cancelUpload);
+				singlefile.extension.core.bg.business.setCancelCallback(taskId, uploadInfo.cancelUpload);
 				return await uploadInfo.uploadPromise;
 			}
 		}
@@ -198,7 +198,7 @@ singlefile.extension.core.bg.downloads = (() => {
 				} else {
 					await singlefile.extension.core.bg.config.removeAuthInfo();
 				}
-				await uploadPage(tabId, filename, blob, authOptions, uploadOptions);
+				await uploadPage(taskId, filename, blob, authOptions, uploadOptions);
 			} else {
 				throw error;
 			}

+ 1 - 0
extension/core/content/content-bootstrap.js

@@ -141,6 +141,7 @@ this.singlefile.extension.core.content.bootstrap = this.singlefile.extension.cor
 		Object.keys(updatedResources).forEach(url => updatedResources[url].retrieved = false);
 		browser.runtime.sendMessage({
 			method: "autosave.save",
+			taskId: options.taskId,
 			content: helper.serialize(document),
 			canvases: docData.canvases,
 			fonts: docData.fonts,

+ 2 - 1
extension/core/content/content-download.js

@@ -39,6 +39,7 @@ this.singlefile.extension.core.content.download = this.singlefile.extension.core
 			for (let blockIndex = 0; blockIndex * MAX_CONTENT_SIZE < pageData.content.length; blockIndex++) {
 				const message = {
 					method: "downloads.download",
+					taskId: options.taskId,
 					confirmFilename: options.confirmFilename,
 					filenameConflictAction: options.filenameConflictAction,
 					filename: pageData.filename,
@@ -68,7 +69,7 @@ this.singlefile.extension.core.content.download = this.singlefile.extension.core
 			}
 			browser.runtime.sendMessage({ method: "ui.processEnd" });
 		}
-		await browser.runtime.sendMessage({ method: "downloads.end" });
+		await browser.runtime.sendMessage({ method: "downloads.end", taskId: options.taskId });
 	}
 
 	function downloadPageForeground(pageData) {

+ 1 - 0
extension/ui/bg/ui-editor.js

@@ -185,6 +185,7 @@ singlefile.extension.ui.bg.editor = (() => {
 
 	browser.runtime.onMessage.addListener(message => {
 		if (message.method == "content.save") {
+			tabData.options = message.options;
 			savePage();
 			browser.runtime.sendMessage({ method: "ui.processInit" });
 			return {};

+ 10 - 11
extension/ui/bg/ui-pendings.js

@@ -62,28 +62,27 @@
 
 	function updateTable(results) {
 		if (results.length) {
-			results.sort(([, tabInfo1], [, tabInfo2]) => tabInfo1.index - tabInfo2.index);
-			results.forEach(([tabId, tabInfo]) => {
+			results.sort((taskInfo1, taskInfo2) => taskInfo1.index - taskInfo2.index);
+			results.forEach((taskInfo) => {
 				const row = document.createElement("div");
 				const cellURL = document.createElement("span");
 				const cellStatus = document.createElement("span");
 				const cellCancel = document.createElement("span");
 				const buttonCancel = document.createElement("button");
-				row.dataset.tabId = tabId;
 				row.className = "result-row";
 				if (URLDisplayed) {
-					cellURL.textContent = tabInfo.url;
+					cellURL.textContent = taskInfo.url;
 				} else {
-					cellURL.textContent = tabInfo.title;
+					cellURL.textContent = taskInfo.title;
 				}
 				cellURL.className = "result-url-title";
-				cellURL.onclick = () => selectTab(tabId);
-				if (tabInfo.cancelled) {
+				cellURL.onclick = () => selectTab(taskInfo.tabId);
+				if (taskInfo.cancelled) {
 					cellStatus.textContent = statusText.cancelling;
 				} else {
-					cellStatus.textContent = statusText[tabInfo.status];
+					cellStatus.textContent = statusText[taskInfo.status];
 					buttonCancel.textContent = "×";
-					buttonCancel.onclick = () => cancel(tabId);
+					buttonCancel.onclick = () => cancel(taskInfo.id);
 					cellCancel.appendChild(buttonCancel);
 				}
 				cellStatus.className = "result-status";
@@ -96,8 +95,8 @@
 		}
 	}
 
-	async function cancel(tabId) {
-		await browser.runtime.sendMessage({ method: "downloads.cancel", tabId });
+	async function cancel(taskId) {
+		await browser.runtime.sendMessage({ method: "downloads.cancel", taskId });
 		await refresh();
 	}