Bladeren bron

added infobar

Gildas 7 jaren geleden
bovenliggende
commit
f9f809d90c

+ 6 - 0
extension/core/bg/bg.js

@@ -47,6 +47,12 @@ singlefile.core = (() => {
 		"/extension/core/content/content.js"
 	];
 
+	browser.runtime.onMessage.addListener(request => {
+		if (request.getConfig) {
+			return singlefile.config.get();
+		}
+	});
+
 	return {
 		async processTab(tab, processOptions = {}) {
 			const options = await singlefile.config.get();

+ 5 - 1
extension/core/bg/config.js

@@ -39,7 +39,8 @@ singlefile.config = (() => {
 		maxResourceSizeEnabled: false,
 		maxResourceSize: 10,
 		removeAudioSrc: true,
-		removeVideoSrc: true
+		removeVideoSrc: true,
+		displayInfobar: true
 	};
 
 	let pendingUpgradePromise;
@@ -105,6 +106,9 @@ singlefile.config = (() => {
 		if (config.removeHiddenElements === undefined) {
 			config.removeHiddenElements = true;
 		}
+		if (config.displayInfobar === undefined) {
+			config.displayInfobar = true;
+		}
 	}
 
 	return {

+ 4 - 1
extension/ui/bg/options.js

@@ -40,6 +40,7 @@
 	const confirmFilenameInput = document.getElementById("confirmFilenameInput");
 	const removeAudioSrcInput = document.getElementById("removeAudioSrcInput");
 	const removeVideoSrcInput = document.getElementById("removeVideoSrcInput");
+	const displayInfobarInput = document.getElementById("displayInfobarInput");
 	let pendingSave = Promise.resolve();
 	document.getElementById("resetButton").addEventListener("click", async () => {
 		await bgPage.singlefile.config.reset();
@@ -70,6 +71,7 @@
 		confirmFilenameInput.checked = config.confirmFilename;
 		removeAudioSrcInput.checked = config.removeAudioSrc;
 		removeVideoSrcInput.checked = config.removeVideoSrc;
+		displayInfobarInput.checked = config.displayInfobar;
 	}
 
 	async function update() {
@@ -91,7 +93,8 @@
 			maxResourceSize: maxResourceSizeInput.value,
 			confirmFilename: confirmFilenameInput.checked,
 			removeAudioSrc: removeAudioSrcInput.checked,
-			removeVideoSrc: removeVideoSrcInput.checked
+			removeVideoSrc: removeVideoSrcInput.checked,
+			displayInfobar: displayInfobarInput.checked
 		});
 		await pendingSave;
 		await bgPage.singlefile.ui.update();

+ 115 - 0
extension/ui/content/infobar.js

@@ -0,0 +1,115 @@
+/*
+ * 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, document, Node */
+
+this.singlefile.infobar = this.singlefile.infobar || (() => {
+
+	const INFOBAR_TAGNAME = "singlefile-infobar";
+	const LINK_ICON = "<svg style=\"vertical-align: middle\" xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"#9AA0A6\"><path d=\"M19 19H5V5h7V3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14c1.1 0 2-.9 2-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7z\"/></svg>";
+	const SINGLEFILE_COMMENT = "Archive processed by SingleFile";
+
+	document.addEventListener("DOMContentLoaded", async () => {
+		const singleFileComment = document.documentElement.childNodes[0];
+		if (singleFileComment.nodeType == Node.COMMENT_NODE && singleFileComment.textContent.includes(SINGLEFILE_COMMENT)) {
+			const info = singleFileComment.textContent.split("\n");
+			const [, , url, saveDate] = info;
+			const config = await browser.runtime.sendMessage({ getConfig: true });
+			if (config.displayInfobar) {
+				initInfobar(url, saveDate);
+			}
+		}
+	});
+	return true;
+
+	function initInfobar(url, saveDate) {
+		let infobarElement = document.querySelector(INFOBAR_TAGNAME);
+		if (!infobarElement) {
+			infobarElement = document.createElement(INFOBAR_TAGNAME);
+			infobarElement.style.all = "unset";
+			infobarElement.style.display = "block";
+			infobarElement.style.fontSize = "15px";
+			infobarElement.style.color = "#9aa0a6";
+			infobarElement.style.position = "fixed";
+			infobarElement.style.top = "16px";
+			infobarElement.style.right = "16px";
+			infobarElement.style.height = "auto";
+			infobarElement.style.width = "32px";
+			infobarElement.style.lineHeight = "32px";
+			infobarElement.style.borderRadius = "16px";
+			infobarElement.style.border = "2px solid #737373";
+			infobarElement.style.zIndex = 2147483647;
+			infobarElement.style.textAlign = "center";
+			infobarElement.style.transition = "all 250ms";
+			const linkElement = document.createElement("a");
+			linkElement.style.all = "unset";
+			linkElement.style.display = "inline-block";
+			linkElement.style.paddingLeft = "8px";
+			linkElement.style.lineHeight = "32px";
+			linkElement.style.cursor = "pointer";
+			linkElement.target = "_blank";
+			linkElement.rel = "noopener noreferrer";
+			linkElement.title = "Open original page";
+			linkElement.href = url.split("url: ")[1];
+			linkElement.innerHTML = LINK_ICON;
+			hideInfobar(infobarElement, linkElement, saveDate);
+			infobarElement.onmouseover = () => infobarElement.style.opacity = 1;
+			document.body.appendChild(infobarElement);
+			document.addEventListener("click", event => {
+				let element = event.target;
+				while (element && element != infobarElement) {
+					element = element.parentElement;
+				}
+				if (element != infobarElement) {
+					hideInfobar(infobarElement, linkElement, saveDate);
+				}
+			});
+		}
+	}
+
+	function displayInfobar(infobarElement, linkElement, saveDate) {
+		infobarElement.style.opacity = 1;
+		infobarElement.onmouseout = null;
+		infobarElement.style.paddingLeft = infobarElement.style.paddingRight = "16px";
+		infobarElement.textContent = saveDate.split("saved date: ")[1];
+		infobarElement.style.width = "auto";
+		infobarElement.style.backgroundColor = "#f9f9f9";
+		infobarElement.style.cursor = "auto";
+		infobarElement.appendChild(linkElement);
+		infobarElement.onclick = null;
+	}
+
+	function hideInfobar(infobarElement, linkElement, saveDate) {
+		infobarElement.style.opacity = .7;
+		infobarElement.onmouseout = () => infobarElement.style.opacity = .7;
+		infobarElement.style.paddingLeft = infobarElement.style.paddingRight = "0px";
+		infobarElement.style.width = "32px";
+		infobarElement.style.backgroundColor = "#737373";
+		infobarElement.style.cursor = "pointer";
+		infobarElement.textContent = "❔";
+		infobarElement.onclick = event => {
+			if (event.button === 0) {
+				displayInfobar(infobarElement, linkElement, saveDate);
+				return false;
+			}
+		};
+	}
+
+})();

+ 9 - 0
extension/ui/pages/help.html

@@ -58,6 +58,15 @@
 							<u>check</u> this option</p>
 					</li>
 
+					<li>
+						<span class="option">display an infobar when viewing archives</span>
+						<p>Check this option to display the ❔ button at the top right of the page when viewing a saved page. By clicking this
+							icon, you can get more information about the saved date and open the original URL.
+						</p>
+						<p class="notice">It is recommended to
+							<u>check</u> this option</p>
+					</li>
+
 					<li>
 						<span class="option">append the save date to the file name</span>
 						<p>Check this option to append the save date of the webpage to the file name.

+ 4 - 0
extension/ui/pages/options.html

@@ -18,6 +18,10 @@
 			<label for="shadowEnabledInput">overlay a shadow on the page during processing</label>
 			<input type="checkbox" id="shadowEnabledInput">
 		</div>
+		<div class="option">
+			<label for="displayInfobarInput">display an infobar when viewing archives</label>
+			<input type="checkbox" id="displayInfobarInput">
+		</div>
 	</details>
 	<details>
 		<summary>File name</summary>

+ 13 - 0
manifest.json

@@ -8,6 +8,19 @@
     },
     "version": "1.2.29",
     "description": "Save a complete page into a single HTML file",
+    "content_scripts": [
+        {
+            "matches": [
+                "<all_urls>"
+            ],
+            "run_at": "document_start",
+            "js": [
+                "lib/browser-polyfill/custom-browser-polyfill.js",
+                "extension/index.js",
+                "extension/ui/content/infobar.js"
+            ]
+        }
+    ],
     "background": {
         "scripts": [
             "lib/browser-polyfill/custom-browser-polyfill.js",