From d585ff70cf241b62794a2d84e71496fc24528462 Mon Sep 17 00:00:00 2001
From: hackademix <giorgio@maone.net>
Date: Aug 13 2018 20:49:10 +0000
Subject: [PATCH 1/4] Renamed "unused_data" to "activityReport" and "active_connection" to "activeMessagPorts".


---

diff --git a/main_background.js b/main_background.js
index 15c8d34..7d2a5c7 100644
--- a/main_background.js
+++ b/main_background.js
@@ -170,8 +170,8 @@ function options_listener(changes, area){
 }
 
 
-var active_connections = {};
-var unused_data = {};
+var activeMessagePorts = {};
+var activityReports = {};
 function createReport(initializer = null) {
 	let template =  {
 		"accepted": [],
@@ -197,7 +197,7 @@ function createReport(initializer = null) {
 async function openReportInTab(data) {
 	let popupURL = await browser.browserAction.getPopup({});
 	let tab = await browser.tabs.create({url: `${popupURL}#fromTab=${data.tabId}`});
-	unused_data[tab.id] = createReport(data);
+	activityReports[tab.id] = createReport(data);
 }
 
 /**
@@ -222,8 +222,8 @@ function debug_print_local(){
 			console.log("%c "+i+" = "+items[i], 'color: blue;');
 		}
 	}
-	console.log("%c Variable 'unused_data': ", 'color: red;');
-	console.log(unused_data);
+	console.log("%c Variable 'activityReports': ", 'color: red;');
+	console.log(activityReports);
 	webex.storage.local.get(storage_got);
 }
 
@@ -254,11 +254,11 @@ function updateReport(tabId, oldReport, updateUI = false){
 			if (Array.isArray(newReport[status])) newReport[status].push(script);
 		}
 	}
-	unused_data[tabId] = newReport;
+	activityReports[tabId] = newReport;
 	dbg_print(newReport);
-	if (updateUI && active_connections[tabId]) {
+	if (updateUI && activeMessagePorts[tabId]) {
 		dbg_print(`[TABID: ${tabId}] Sending script blocking report directly to browser action.`);
-		active_connections[tabId].postMessage({show_info: newReport});
+		activeMessagePorts[tabId].postMessage({show_info: newReport});
 	}
 }
 
@@ -283,8 +283,8 @@ function updateReport(tabId, oldReport, updateUI = false){
 *
 */
 async function addReportEntry(tabId, scriptHashOrUrl, action, update = false) {
-	if(!unused_data[tabId]) {
-		unused_data[tabId] = createReport({url: (await browser.tabs.get(tabId)).url});
+	if(!activityReports[tabId]) {
+		activityReports[tabId] = createReport({url: (await browser.tabs.get(tabId)).url});
 	}
 	let type, actionValue;
 	for (type of ["accepted", "blocked", "whitelisted", "blacklisted"]) {
@@ -310,10 +310,10 @@ async function addReportEntry(tabId, scriptHashOrUrl, action, update = false) {
 	let scriptName = actionValue[0];
 	try {
 		entryType = listManager.getStatus(scriptName, type);
-		let entries = unused_data[tabId][entryType];
+		let entries = activityReports[tabId][entryType];
 		if(isNew(entries, scriptName)){
-			dbg_print(unused_data);
-			dbg_print(unused_data[tabId]);
+			dbg_print(activityReports);
+			dbg_print(activityReports[tabId]);
 			dbg_print(entryType);
 			entries.push(actionValue);
 		}
@@ -322,9 +322,9 @@ async function addReportEntry(tabId, scriptHashOrUrl, action, update = false) {
 		entryType = "unknown";
 	}
 	
-	if (active_connections[tabId]) {
+	if (activeMessagePorts[tabId]) {
 		try {
-			active_connections[tabId].postMessage({show_info: unused_data[tabId]});
+			activeMessagePorts[tabId].postMessage({show_info: activityReports[tabId]});
 		} catch(e) {
 		}
 	}
@@ -400,20 +400,20 @@ function connected(p) {
 			dbg_print(`[TABID:${tab.id}] Injecting contact finder`);
 			//inject_contact_finder(tabs[0]["id"]);
 		}
-		if (update || m.update && unused_data[m.tabId]) {
+		if (update || m.update && activityReports[m.tabId]) {
 			let tabId = "tabId" in m ?  m.tabId : tabs.pop().id;
 			dbg_print(`%c updating tab ${tabId}`, "color: red;");
-			active_connections[tabId] = p;
-			await updateReport(tabId, unused_data[tabId], true);
+			activeMessagePorts[tabId] = p;
+			await updateReport(tabId, activityReports[tabId], true);
 		} else {
 			for(let tab of tabs) {
-				if(unused_data[tab.id]){
+				if(activityReports[tab.id]){
 					// If we have some data stored here for this tabID, send it
 					dbg_print(`[TABID: ${tab.id}] Sending stored data associated with browser action'`);								
-					p.postMessage({"show_info": unused_data[tab.id]});
+					p.postMessage({"show_info": activityReports[tab.id]});
 				} else{
 					// create a new entry
-					let report = unused_data[tab.id] = createReport({"url": tab.url, tabId: tab.id});
+					let report = activityReports[tab.id] = createReport({"url": tab.url, tabId: tab.id});
 					p.postMessage({show_info: report});							
 					dbg_print(`[TABID: ${tab.id}] No data found, creating a new entry for this window.`);	
 				}
@@ -430,11 +430,11 @@ function connected(p) {
 */
 function delete_removed_tab_info(tab_id, remove_info){
 	dbg_print("[TABID:"+tab_id+"]"+"Deleting stored info about closed tab");
-	if(unused_data[tab_id] !== undefined){
-		delete unused_data[tab_id];
+	if(activityReports[tab_id] !== undefined){
+		delete activityReports[tab_id];
 	}
-	if(active_connections[tab_id] !== undefined){
-		delete active_connections[tab_id];
+	if(activeMessagePorts[tab_id] !== undefined){
+		delete activeMessagePorts[tab_id];
 	}
 }
 
@@ -741,7 +741,7 @@ function license_read(script_src, name, external = false){
 }
 
 /* *********************************************************************************************** */
-// TODO: Test if this script is being loaded from another domain compared to unused_data[tabid]["url"]
+// TODO: Test if this script is being loaded from another domain compared to activityReports[tabid]["url"]
 
 /**
 *	Asynchronous function, returns the final edited script as a string, 
@@ -774,7 +774,7 @@ async function get_script(response, url, tabId = -1, whitelisted = false, index 
 	
 	let sourceHash = hash(response);
  	let domain = get_domain(url);
-	let report = unused_data[tabId] || (unused_data[tabId] = createReport({url, tabId}));
+	let report = activityReports[tabId] || (activityReports[tabId] = createReport({url, tabId}));
 	let blockedCount = report.blocked.length + report.blacklisted.length;
 	dbg_print(`amt. blocked on page: ${blockedCount}`);
 	if (blockedCount > 0 || !verdict) {
@@ -1074,7 +1074,7 @@ async function handle_html(response, whitelisted) {
 	let {url, tabId, type} = request;
 	url = ListStore.urlItem(url);
 	if (type === "main_frame") { 
-		delete unused_data[tabId];
+		delete activityReports[tabId];
 		browser.browserAction.setBadgeText({
 			text: "✓",
 			tabId

From c1d3257ad3f7f630eafbbca5b7e7b27e32b146c2 Mon Sep 17 00:00:00 2001
From: hackademix <giorgio@maone.net>
Date: Aug 13 2018 22:55:39 +0000
Subject: [PATCH 2/4] Fix for bug #54459: "Back/forth navigation does not change tab status information"


---

diff --git a/main_background.js b/main_background.js
index 7d2a5c7..1f3cdae 100644
--- a/main_background.js
+++ b/main_background.js
@@ -255,6 +255,7 @@ function updateReport(tabId, oldReport, updateUI = false){
 		}
 	}
 	activityReports[tabId] = newReport;
+	browser.sessions.setTabValue(tabId, url, newReport);
 	dbg_print(newReport);
 	if (updateUI && activeMessagePorts[tabId]) {
 		dbg_print(`[TABID: ${tabId}] Sending script blocking report directly to browser action.`);
@@ -283,9 +284,10 @@ function updateReport(tabId, oldReport, updateUI = false){
 *
 */
 async function addReportEntry(tabId, scriptHashOrUrl, action, update = false) {
-	if(!activityReports[tabId]) {
-		activityReports[tabId] = createReport({url: (await browser.tabs.get(tabId)).url});
-	}
+	let report = activityReports[tabId];
+	if (!report) report = activityReports[tabId] = 
+			createReport({url: (await browser.tabs.get(tabId)).url});
+			
 	let type, actionValue;
 	for (type of ["accepted", "blocked", "whitelisted", "blacklisted"]) {
 		if (type in action) {
@@ -310,7 +312,7 @@ async function addReportEntry(tabId, scriptHashOrUrl, action, update = false) {
 	let scriptName = actionValue[0];
 	try {
 		entryType = listManager.getStatus(scriptName, type);
-		let entries = activityReports[tabId][entryType];
+		let entries = report[entryType];
 		if(isNew(entries, scriptName)){
 			dbg_print(activityReports);
 			dbg_print(activityReports[tabId]);
@@ -324,11 +326,13 @@ async function addReportEntry(tabId, scriptHashOrUrl, action, update = false) {
 	
 	if (activeMessagePorts[tabId]) {
 		try {
-			activeMessagePorts[tabId].postMessage({show_info: activityReports[tabId]});
+			activeMessagePorts[tabId].postMessage({show_info: report});
 		} catch(e) {
 		}
 	}
 	
+	browser.sessions.setTabValue(tabId, report.url, report);
+	
 	return entryType;
 }
 
@@ -438,6 +442,27 @@ function delete_removed_tab_info(tab_id, remove_info){
 	}
 }
 
+/**
+*	Called when the tab gets updated / activated
+*
+*	Here we check if  new tab's url matches activityReports[tabId].url, and if 
+* it doesn't we use the session cached value (if any).
+*
+*/
+
+async function onTabUpdated(tabId, changedInfo, tab) {
+	let {url} = tab;
+	let report = activityReports[tabId];
+	if (!(report && report.url === url)) {
+		let cache = await browser.sessions.getTabValue(tabId, url);
+		updateBadge(tabId, activityReports[tabId] = cache);
+	}
+}
+
+async function onTabActivated({tabId}) {
+	await onTabUpdated(tabId, {}, await browser.tabs.get(tabId));
+}
+
 /* *********************************************************************************************** */
 
 var fname_data = require("./fname_data.json").fname_data;
@@ -775,18 +800,7 @@ async function get_script(response, url, tabId = -1, whitelisted = false, index 
 	let sourceHash = hash(response);
  	let domain = get_domain(url);
 	let report = activityReports[tabId] || (activityReports[tabId] = createReport({url, tabId}));
-	let blockedCount = report.blocked.length + report.blacklisted.length;
-	dbg_print(`amt. blocked on page: ${blockedCount}`);
-	if (blockedCount > 0 || !verdict) {
-		webex.browserAction.setBadgeText({
-			text: "!",
-			tabId
-		});
-		webex.browserAction.setBadgeBackgroundColor({
-			color: "red",
-			tabId
-		});
-	}
+	updateBadge(tabId, report, !verdict);
 	let category = await addReportEntry(tabId, sourceHash, {"url": domain, [verdict ? "accepted" : "blocked"]: [url, reason]});
 	let scriptSource = verdict ? response : editedSource;
 	switch(category) {
@@ -798,6 +812,15 @@ async function get_script(response, url, tabId = -1, whitelisted = false, index 
 	}
 }
 
+
+function updateBadge(tabId, report = null, forceRed = false) {
+	let blockedCount = report ? report.blocked.length + report.blacklisted.length : 0;
+	let [text, color] = blockedCount > 0 || forceRed 
+		? [blockedCount && blockedCount.toString() || "!" , "red"] : ["✓", "green"]
+	browser.browserAction.setBadgeText({text, tabId});
+	browser.browserAction.setBadgeBackgroundColor({color, tabId});
+}
+
 /**
 * 	Tests if a request is google analytics or not
 */
@@ -1074,15 +1097,8 @@ async function handle_html(response, whitelisted) {
 	let {url, tabId, type} = request;
 	url = ListStore.urlItem(url);
 	if (type === "main_frame") { 
-		delete activityReports[tabId];
-		browser.browserAction.setBadgeText({
-			text: "✓",
-			tabId
-		});
-		browser.browserAction.setBadgeBackgroundColor({
-			color: "green",
-			tabId
-		});
+		activityReports[tabId] = createReport({url, tabId});
+		updateBadge(tabId);
 	}
 	return await edit_html(text, url, tabId, whitelisted);
 }
@@ -1106,7 +1122,8 @@ async function init_addon(){
 	webex.runtime.onConnect.addListener(connected);
 	webex.storage.onChanged.addListener(options_listener);
 	webex.tabs.onRemoved.addListener(delete_removed_tab_info);
-
+	browser.tabs.onUpdated.addListener(onTabUpdated);
+	browser.tabs.onActivated.addListener(onTabActivated);
 	// Prevents Google Analytics from being loaded from Google servers
 	let all_types = [
 		"beacon", "csp_report", "font", "image", "imageset", "main_frame", "media",
diff --git a/manifest.json b/manifest.json
index e77f69b..17f8670 100644
--- a/manifest.json
+++ b/manifest.json
@@ -20,6 +20,7 @@
 	"webRequestBlocking",
 	"activeTab",
 	"notifications",
+	"sessions",
 	"storage",
 	"tabs",
 	"<all_urls>"

From d6902eea60acea9f1ea3828e1cdb0bf6288e7b06 Mon Sep 17 00:00:00 2001
From: hackademix <giorgio@maone.net>
Date: Aug 13 2018 22:58:14 +0000
Subject: [PATCH 3/4] Removed browser->webex "shim".


---

diff --git a/contact_finder.js b/contact_finder.js
index 90f0108..48f9c27 100644
--- a/contact_finder.js
+++ b/contact_finder.js
@@ -289,45 +289,9 @@ function main(){
 	new_debug_button("Complain to website",handler);
 }
 
-// See main_background.js
-var webex;
-var myPort;
-function set_webex(){
-	if(typeof(browser) == "object"){
-		webex = browser;
-	}
-	if(typeof(chrome) == "object"){
-		webex = chrome;
-	}
-}
-set_webex();
-var myPort = webex.runtime.connect({name:"contact_finder"});
+var myPort = browser.runtime.connect({name:"contact_finder"});
 
 myPort.onMessage.addListener(function(m) {
 	prefs = m;
 	main();
 });
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/html/preferences_panel/pref.js b/html/preferences_panel/pref.js
index 757bf5e..4642d32 100644
--- a/html/preferences_panel/pref.js
+++ b/html/preferences_panel/pref.js
@@ -19,25 +19,7 @@
 * along with GNU LibreJS.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-/**
-*	
-*	Sets global variable "webex" to either "chrome" or "browser" for
-*	use on Chrome or a Firefox variant.
-*
-*	Change this to support a new browser that isn't Chrome or Firefox,
-*	given that it supports webExtensions.
-*
-*	(Use the variable "webex" for all API calls after calling this)
-*/
 var store;
-function set_webex(){
-	if(typeof(browser) == "undefined"){
-		webex = chrome;
-	} else{
-		webex = browser;
-	}
-}
-set_webex();
 
 function storage_got(items){
 	var inputs = document.getElementsByTagName("input");
@@ -67,7 +49,7 @@ function storage_got(items){
 
 
 }
-webex.storage.local.get(storage_got);
+browser.storage.local.get(storage_got);
 
 document.getElementById("save_changes").addEventListener("click", function(){
 	var inputs = document.getElementsByTagName("input");
@@ -91,7 +73,5 @@ document.getElementById("save_changes").addEventListener("click", function(){
 	}
 	console.log(data);
 
-	webex.storage.local.set(data);
+	browser.storage.local.set(data);
 });
-
-
diff --git a/main_background.js b/main_background.js
index 1f3cdae..35081ea 100644
--- a/main_background.js
+++ b/main_background.js
@@ -111,26 +111,6 @@ var reserved_objects = [
 	"eval"
 ];
 
-/**
-*	
-*	Sets global variable "webex" to either "chrome" or "browser" for
-*	use on Chrome or a Firefox variant.
-*
-*	Change this to support a new browser that isn't Chrome or Firefox,
-*	given that it supports webExtensions.
-*
-*	(Use the variable "webex" for all API calls after calling this)
-*/
-var webex;
-function set_webex(){
-	if(typeof(browser) == "object"){
-		webex = browser;
-	}
-	if(typeof(chrome) == "object"){
-		webex = chrome;
-	}
-}
-
 // Generates JSON key for local storage
 function get_storage_key(script_name,src_hash){
 	return script_name;
@@ -154,7 +134,7 @@ function options_listener(changes, area){
 	function flushed(){
 		dbg_print("cache flushed");
 	}	
-	//var flushingCache = webex.webRequest.handlerBehaviorChanged(flushed);
+	//var flushingCache = browser.webRequest.handlerBehaviorChanged(flushed);
 	
 
 	dbg_print("Items updated in area" + area +": ");
@@ -206,7 +186,7 @@ async function openReportInTab(data) {
 *
 */
 function debug_delete_local(){
-	webex.storage.local.clear();
+	browser.storage.local.clear();
 	dbg_print("Local storage cleared");
 }
 
@@ -224,7 +204,7 @@ function debug_print_local(){
 	}
 	console.log("%c Variable 'activityReports': ", 'color: red;');
 	console.log(activityReports);
-	webex.storage.local.get(storage_got);
+	browser.storage.local.get(storage_got);
 }
 
 /**
@@ -362,7 +342,7 @@ function connected(p) {
 		function cb(items){
 			p.postMessage(items);
 		}
-		webex.storage.local.get(cb);
+		browser.storage.local.get(cb);
 		return;		
 	}
 	p.onMessage.addListener(async function(m) {
@@ -1118,10 +1098,9 @@ var listManager = new ListManager(whitelist, blacklist,
 */
 async function init_addon(){
 	await whitelist.load();
-	set_webex();
-	webex.runtime.onConnect.addListener(connected);
-	webex.storage.onChanged.addListener(options_listener);
-	webex.tabs.onRemoved.addListener(delete_removed_tab_info);
+	browser.runtime.onConnect.addListener(connected);
+	browser.storage.onChanged.addListener(options_listener);
+	browser.tabs.onRemoved.addListener(delete_removed_tab_info);
 	browser.tabs.onUpdated.addListener(onTabUpdated);
 	browser.tabs.onActivated.addListener(onTabActivated);
 	// Prevents Google Analytics from being loaded from Google servers
@@ -1131,7 +1110,7 @@ async function init_addon(){
 		"web_manifest", "websocket", "xbl", "xml_dtd", "xmlhttprequest", "xslt", 
 		"other"
 	];
-	webex.webRequest.onBeforeRequest.addListener(
+	browser.webRequest.onBeforeRequest.addListener(
 		block_ga,
 		{urls: ["<all_urls>"], types: all_types},
 		["blocking"]
@@ -1151,7 +1130,7 @@ function inject_contact_finder(tab_id){
 	function executed(result) {
 	  dbg_print("[TABID:"+tab_id+"]"+"finished executing contact finder: " + result);
 	}
-	var executing = webex.tabs.executeScript(tab_id, {file: "/contact_finder.js"}, executed);
+	var executing = browser.tabs.executeScript(tab_id, {file: "/contact_finder.js"}, executed);
 }
 
 init_addon();

From 63f3970ac6424c8627c2d055609f60024e93082c Mon Sep 17 00:00:00 2001
From: hackademix <giorgio@maone.net>
Date: Aug 13 2018 23:08:00 +0000
Subject: [PATCH 4/4] Cope with tabId changes on session restore.


---

diff --git a/main_background.js b/main_background.js
index 35081ea..799c69f 100644
--- a/main_background.js
+++ b/main_background.js
@@ -435,6 +435,8 @@ async function onTabUpdated(tabId, changedInfo, tab) {
 	let report = activityReports[tabId];
 	if (!(report && report.url === url)) {
 		let cache = await browser.sessions.getTabValue(tabId, url);
+		// on session restore tabIds may change
+		if (cache && cache.tabId !== tabId) cache.tabId = tabId; 
 		updateBadge(tabId, activityReports[tabId] = cache);
 	}
 }

