#9 Fix for bug #54459: "Back/forth navigation does not change tab status information"
Merged 5 years ago by quidam. Opened 5 years ago by gioma1.
gioma1/librejs fix/badge-bf-sync  into  master

file modified
+1 -37
@@ -289,45 +289,9 @@ 

  	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();

  });

- 

- 

- 

- 

- 

- 

- 

- 

- 

- 

- 

- 

- 

- 

- 

- 

- 

- 

- 

- 

- 

- 

- 

- 

@@ -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 @@ 

  

  

  }

- 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 @@ 

  	}

  	console.log(data);

  

- 	webex.storage.local.set(data);

+ 	browser.storage.local.set(data);

  });

- 

- 

file modified
+78 -80
@@ -111,26 +111,6 @@ 

  	"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 flushed(){

  		dbg_print("cache flushed");

  	}	

- 	//var flushingCache = webex.webRequest.handlerBehaviorChanged(flushed);

+ 	//var flushingCache = browser.webRequest.handlerBehaviorChanged(flushed);

  	

  

  	dbg_print("Items updated in area" + area +": ");
@@ -170,8 +150,8 @@ 

  }

  

  

- var active_connections = {};

- var unused_data = {};

+ var activeMessagePorts = {};

+ var activityReports = {};

  function createReport(initializer = null) {

  	let template =  {

  		"accepted": [],
@@ -197,7 +177,7 @@ 

  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);

  }

  

  /**
@@ -206,7 +186,7 @@ 

  *

  */

  function debug_delete_local(){

- 	webex.storage.local.clear();

+ 	browser.storage.local.clear();

  	dbg_print("Local storage cleared");

  }

  
@@ -222,9 +202,9 @@ 

  			console.log("%c "+i+" = "+items[i], 'color: blue;');

  		}

  	}

- 	console.log("%c Variable 'unused_data': ", 'color: red;');

- 	console.log(unused_data);

- 	webex.storage.local.get(storage_got);

+ 	console.log("%c Variable 'activityReports': ", 'color: red;');

+ 	console.log(activityReports);

+ 	browser.storage.local.get(storage_got);

  }

  

  /**
@@ -254,11 +234,12 @@ 

  			if (Array.isArray(newReport[status])) newReport[status].push(script);

  		}

  	}

- 	unused_data[tabId] = newReport;

+ 	activityReports[tabId] = newReport;

+ 	browser.sessions.setTabValue(tabId, url, 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,9 +264,10 @@ 

  *

  */

  async function addReportEntry(tabId, scriptHashOrUrl, action, update = false) {

- 	if(!unused_data[tabId]) {

- 		unused_data[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,10 +292,10 @@ 

  	let scriptName = actionValue[0];

  	try {

  		entryType = listManager.getStatus(scriptName, type);

- 		let entries = unused_data[tabId][entryType];

+ 		let entries = report[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,13 +304,15 @@ 

  		entryType = "unknown";

  	}

  	

- 	if (active_connections[tabId]) {

+ 	if (activeMessagePorts[tabId]) {

  		try {

- 			active_connections[tabId].postMessage({show_info: unused_data[tabId]});

+ 			activeMessagePorts[tabId].postMessage({show_info: report});

  		} catch(e) {

  		}

  	}

  	

+ 	browser.sessions.setTabValue(tabId, report.url, report);

+ 	

  	return entryType;

  }

  
@@ -358,7 +342,7 @@ 

  		function cb(items){

  			p.postMessage(items);

  		}

- 		webex.storage.local.get(cb);

+ 		browser.storage.local.get(cb);

  		return;		

  	}

  	p.onMessage.addListener(async function(m) {
@@ -400,20 +384,20 @@ 

  			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,14 +414,37 @@ 

  */

  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(activeMessagePorts[tab_id] !== undefined){

+ 		delete activeMessagePorts[tab_id];

  	}

- 	if(active_connections[tab_id] !== undefined){

- 		delete active_connections[tab_id];

+ }

+ 

+ /**

+ *	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);

+ 		// on session restore tabIds may change

+ 		if (cache && cache.tabId !== tabId) cache.tabId = tabId; 

+ 		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;
@@ -741,7 +748,7 @@ 

  }

  

  /* *********************************************************************************************** */

- // 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,19 +781,8 @@ 

  	

  	let sourceHash = hash(response);

   	let domain = get_domain(url);

- 	let report = unused_data[tabId] || (unused_data[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

- 		});

- 	}

+ 	let report = activityReports[tabId] || (activityReports[tabId] = createReport({url, 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 +794,15 @@ 

  	}

  }

  

+ 

+ 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 +1079,8 @@ 

  	let {url, tabId, type} = request;

  	url = ListStore.urlItem(url);

  	if (type === "main_frame") { 

- 		delete unused_data[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);

  }
@@ -1102,11 +1100,11 @@ 

  */

  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

  	let all_types = [

  		"beacon", "csp_report", "font", "image", "imageset", "main_frame", "media",
@@ -1114,7 +1112,7 @@ 

  		"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"]
@@ -1134,7 +1132,7 @@ 

  	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();

file modified
+1
@@ -20,6 +20,7 @@ 

  	"webRequestBlocking",

  	"activeTab",

  	"notifications",

+ 	"sessions",

  	"storage",

  	"tabs",

  	"<all_urls>"

Reference: https://savannah.gnu.org/bugs/?54459

As a side benefit, on extension updates and session restore we don't lose context, as we use the per-tab cached one if available.

Pull-Request has been merged by quidam

5 years ago