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

added entries in the context menu

Gildas пре 7 година
родитељ
комит
fb35843ef8
3 измењених фајлова са 50 додато и 6 уклоњено
  1. 32 4
      extension/core/scripts/bg/bg.js
  2. 17 2
      extension/core/scripts/content/client.js
  3. 1 0
      manifest.json

+ 32 - 4
extension/core/scripts/bg/bg.js

@@ -23,6 +23,8 @@
 (() => {
 
 	const CHROME_STORE_URL = "https://chrome.google.com";
+	const MENU_ID_SAVE_PAGE = "save-page";
+	const MENU_ID_SAVE_SELECTED = "save-selected";
 
 	chrome.tabs.onActivated.addListener(activeInfo => chrome.tabs.get(activeInfo.tabId, tab => {
 		if (!chrome.runtime.lastError) {
@@ -48,13 +50,39 @@
 
 	chrome.browserAction.onClicked.addListener(tab => {
 		if (isAllowedURL(tab.url)) {
-			chrome.tabs.query({ currentWindow: true, highlighted: true }, tabs => tabs.forEach(tab => {
-				singlefile.ui.init(tab.id);
-				chrome.tabs.sendMessage(tab.id, { processStart: true, options: singlefile.config.get() });
-			}));
+			chrome.tabs.query({ currentWindow: true, highlighted: true }, tabs => tabs.forEach(processTab));
 		}
 	});
 
+	chrome.runtime.onInstalled.addListener(function () {
+		chrome.contextMenus.create({
+			id: MENU_ID_SAVE_PAGE,
+			contexts: ["page"],
+			title: "Save page with SingleFile"
+		});
+		chrome.contextMenus.create({
+			id: MENU_ID_SAVE_SELECTED,
+			contexts: ["selection"],
+			title: "Save selection with SingleFile"
+		});
+	});
+
+	chrome.contextMenus.onClicked.addListener((event, tab) => {
+		if (event.menuItemId == MENU_ID_SAVE_PAGE) {
+			processTab(tab);
+		}
+		if (event.menuItemId == MENU_ID_SAVE_SELECTED) {
+			processTab(tab, { selected: true });
+		}
+	});
+
+	function processTab(tab, processOptions = {}) {
+		const options = singlefile.config.get();
+		Object.keys(processOptions).forEach(key => options[key] = processOptions[key]);
+		singlefile.ui.init(tab.id);
+		chrome.tabs.sendMessage(tab.id, { processStart: true, options });
+	}
+
 	function isAllowedURL(url) {
 		return (url.startsWith("http://") || url.startsWith("https://")) && !url.startsWith(CHROME_STORE_URL);
 	}

+ 17 - 2
extension/core/scripts/content/client.js

@@ -18,7 +18,7 @@
  *   along with SingleFile.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-/* global chrome, SingleFile, singlefile, document, Blob, MouseEvent */
+/* global chrome, SingleFile, singlefile, document, Blob, MouseEvent, getSelection */
 
 (() => {
 
@@ -27,7 +27,7 @@
 			fixInlineScripts();
 			const options = request.options;
 			options.url = document.location.href;
-			options.content = getDoctype(document) + document.documentElement.outerHTML;
+			options.content = options.selected ? getSelectedContent() : getDoctype(document) + document.documentElement.outerHTML;
 			options.jsEnabled = true;
 			options.onprogress = event => {
 				if (event.type == event.RESOURCES_INITIALIZED) {
@@ -90,6 +90,21 @@
 		return "";
 	}
 
+	function getSelectedContent() {
+		const selection = getSelection();
+		const range = selection.rangeCount ? selection.getRangeAt(0) : null;
+		let node;
+		if (range && range.startOffset != range.endOffset) {
+			node = range.commonAncestorContainer;
+			if (node.nodeType != node.ELEMENT_NODE) {
+				node = node.parentElement;
+			}
+			const clonedNode = node.cloneNode(true);
+			node.parentElement.replaceChild(clonedNode, node);
+		}
+		return node.outerHTML;
+	}
+
 	function fixInlineScripts() {
 		document.querySelectorAll("script").forEach(element => element.textContent = element.textContent.replace(/<\/script>/gi, "<\\/script>"));
 	}

+ 1 - 0
manifest.json

@@ -46,6 +46,7 @@
     ],
     "permissions": [
         "tabs",
+        "contextMenus",
         "http://*/*",
         "https://*/*"
     ],