1
votes

The chrome extension opens in a new tab, and gets the info for the open windows and tabs when it's loaded, but I have to refresh it to get any new tabs or windows opened.

Here's the code from the manifest file:

 "background": {
    "page": "background.html",
    "persistent": true
    },
"content_security_policy": "script-src 'self' 'unsafe-eval' https://code.jquery.com; object-src 'self'",

"permissions": [
  "contextMenus",
  "notifications",
  "tabs",
  "clipboardWrite",
  "unlimitedStorage"
],
"content_scripts": [{
        "matches": ["*://*/*"],
        "js": ["jan13.js", "background.js"],
        "css": ["jan13.css"]
        }

The background.html page calls on the two scripts "jan13.js" and "background.js".

<!DOCTYPE html>
<html>
<head></head>
<body>
<script src="jquery.min.js"></script>
<script src="background.js"></script>
<script src="jan13.js"></script>
</body>
</html>

The "background.js" file just opens up the extension in its own tab like this:

chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.create({'url': chrome.extension.getURL('popup.html'), 'selected': true});
});

And then "jan13.js" does all the actual work:

$(document).ready(function() {

 chrome.windows.getAll({populate:true},function(windows){

    for (i=0; i < windows.length; i++) {
        a = (i+1);

        $('<div/>', {
            id: 'win'+a,
        }).attr('class', 'box1').html("<h3>Window"+a+"</h3>").appendTo('.container');

        windows[i].tabs.forEach(function(tab){

            var favic = tab.favIconUrl;

            var link = $('<a>', {
                text:tab.title,
                href:tab.url,
                }); 
           link.attr("target", "_blank");
           $('#win'+a).append(link); 

            $(link).prepend($('<img>', {id:'favic', src: favic}));
        });
    };

    $('<div/>').attr('class', 'button').text("Toggle").appendTo('.box1');

    $('.button').click(function() {
        var b = $(this).parent().closest('div');
        $(b[0]).toggleClass("box1a");
    });       
  });
});

I've tried putting this code in the "background.js" and/or "background.html":

chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
    $.getScript("jan13.js");
});
chrome.tabs.onCreated.addListener(function(tab) {     
    $.getScript("jan13.js");
});

But I get the following error:

Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' 'unsafe-eval' https://code.jquery.com". Either the 'unsafe-inline' keyword, a hash ('sha256-VCQyoq7QBv4UrBn0VODLZE8rJZdjIt7Kb3PziCSqIXM='), or a nonce ('nonce-...') is required to enable inline execution.

I also regularly get this error:

Uncaught ReferenceError: $ is not defined

But it doesn't stop the extension from running.

When I try putting "background.js" and/or "jan13.js" into the manifest like this:

"background": {
    "scripts": ["background.js", "jan13.js"],
    "persistent": true
    },

The extension doesn't open at all. I click on the toolbar icon and nothing happens. That's why I put it in the "background.html" instead. It seems convoluted to me but it's the only way I've made it work.

Again the original question is how do I add the eventListener so that the extension automatically gets any new tabs or windows opened? It works if I refresh the page.

EDIT: Changed the manifest file to this:

{
"manifest_version": 2,
"name": "Session Sync",
"version": "0.1.0",
"description": "Sync browser sessions",
"author": "Mischa Bertrand-Chetty",
"browser_action": {
    "default_title": "Starting Session Sync..."
    },
"background": {
    "scripts": ["jquery.min.js","background.js", "jan13.js"],
    "persistent": true
    },
"content_security_policy": "script-src 'self' 'unsafe-eval' https://code.jquery.com; object-src 'self'",

"permissions": [
  "contextMenus",
  "notifications",
  "tabs",
  "clipboardWrite",
  "unlimitedStorage"
],
"content_scripts": [{
        "matches": ["*://*/*"],
        "css": ["jan13.css"]
        }
    ],
"incognito": "spanning"
}

The good news is I don't get the Reference error anymore. However the original problem, that it doesn't listen for any new tabs or windows is still there. I still have to refresh the page to get the new tab and windows.

1
Download jquery file store local folder and give reference of downloaded file in your extension. - Maharshi
I did...that's why I reference "jquery.min.js" in "background.html" and also in the main html file. - Mitch
Is there a reason that you are using a background.html instead of just "background": {"scripts": ["jquery.min.js","background.js", "jan13.js"],"persistent": true}? - Makyen
You are using background.js and jan13.js as both background scripts and content scripts. This is almost always a Bad Idea™. In this case it certainly is, because A) Both scripts use APIs not available to content scripts, and B) You try to use jQuery in jan13.js, don't load jQuery in the content_script entry. - Makyen
Just realized it wasn't working before because I didn't add "jquery.min.js" to the background scripts as well. I've done it the way you've described. But I still need to refresh it when I want it to be updated. - Mitch

1 Answers

1
votes

Move your code which injects the DOM elements into a named function so you can call it from your tab onCreated and onUpdated handlers, rather than reloading the script. You probably also don't want to reload the entire script and completely rescan the windows every time: you presumably want to do that once for each updated/created tab. Then you won't need the CSP rules, since you won't be reloading the script.

In background.js, put your function and the handlers that call it:

function scanTabs() {
  chrome.windows.getAll({populate: true}, function(windows) {
..etc..
}
$(document).ready(scanTabs);
chrome.tabs.onUpdated.addListener(scanTabs);
chrome.tabs.onCreated.addListener(scanTabs);

You don't need jan13.js at all.

Hopefully that's enough to get you on the right track.