I am having some weird results with message passing. I have a content script interacting with a script embedded in my popup page. Currently, they are repeatedly sending the same messages and responses to eachother. I feel like this has something to do with my event listeners firing too much, or maybe the methods i've written to pass the messages are creating some sort of accidental message loop.
My popup script has some logic to inject my content script into every webpage the user visits:
document.addEventListener('DOMContentLoaded', function () { chrome.tabs.onUpdated.addListener(contextSwitch); }); //after navigating to a new url function contextSwitch() { var tabid = arguments[0]; var changeinfo = arguments[1]; var tab = arguments[2]; //keeps the script from being injected into a tab that's still loading. if(changeinfo.status === "complete"){ chrome.tabs.executeScript(tabid, {file : "inject.js"}, postInject); } else if (changeinfo.status ==="loading"){ console.log("loading fired"); } else{ console.log("Something went wrong."); console.log(changeinfo); } } //this fires after the script is injected. function postInject() { chrome.runtime.onConnect.addListener(function(port) { port.onMessage.addListener(messageBroker); port.postMessage({status:"connected"}); }); } //helps pick and choose what to do based on nthe message received function messageBroker() { var msg = arguments[0]; var sender = arguments[1]; if(msg.status == "initialized"){ sender.postMessage({status:"inject",contents:{notes:page.Notes}}); } } The content script opens up a port like this:
var extPort = chrome.runtime.connect({ name : "CS:" + window.location.href }); extPort.onMessage.addListener(function() { var msg = arguments[0]; var sender = arguments[1]; //the popup page sends the "connected" message after the port connects. if (msg.status === "connected") { var initmsg = { status : "initialized", contents : { url : window.location.href } }; sender.postMessage(initmsg); } if (msg.status === "inject") { var contents = msg.contents; if (contents) { for (item in contents) { //do stuff with the contents } } } sender.postMessage({ status : "received" }); }); Here is my manifest file:
{ "name": "name", "version": "0.0.1", "description": "chrome extension", "permissions": [ "activeTab", "tabs","<all_urls>","http://*/","https://*/" ], "browser_action": { "default_title": "ext", "default_icon": "icon.png", "default_popup": "popup.html" }, "background": { "scripts": ["chrome.js"], "persistent": false }, "manifest_version": 2, "content_security_policy": "script-src 'self' https://ajax.googleapis.com; object-src 'self'" } My background script is embedded into my popup like this:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>popup</title> <meta name="description" content=""> <meta name="author" content="alex"> <script src="chrome.js"></script> </head> <body style="width:400px;height:400px;"> <div id=menu> Menu </div> <a href="#" id="button1">button1</a> <a href="#" id="button2">button2</a> </body> </html> My goal for this back and forth message passing is this:
- inject the script into any appropriate page
- the script tells the background that it's been injected and is ready to receive orders.
- the background page gives it orders.
- the content script performs some operation based upon those orders.