Liam
Liam

Reputation: 53

Getting ""Uncaught TypeError: Could not add listener" When Using " chrome.webNavigation.onCompleted.addListener"

When trying to use Chrome's WebNavigation.onCompleted to run background.js on a certain url I get the error "Uncaught TypeError: Could not add listener". For permissions in my manifest.json I have given the extension access to activetab and webrequest.

I have tried using other listeners like chrome.browserAction.onClicked.addListener and it worked perfectly. I am also using the latest version of chrome (v73).

background.js :

 chrome.webNavigation.onCompleted.addListener(function(tab) {
    var eurl = tab.url.split("/skill/");
    if(eurl[0] === "https://www.duolingo.com") {
        chrome.tabs.executeScript(tab.ib, {
            file: 'jquery-3.3.1.min.js'
        });
        chrome.tabs.executeScript(tab.ib, {
            file: 'duohelperinjector.js'
        });}

}, {url: [{urlMatches : '*://duolingo.com/skill/*'}]});

manifest.json :

{
    "name": "DuoHelper",
    "version": "0.0.1",
    "manifest_version": 2,
    "description": "A Chrome Extension That Helps With Duolingo",
    "homepage_url": "https://github.com/TechHax/DuoHelper",
    "background": {
      "scripts": [
        "background.js"
      ],
      "persistent": true
    },
    "browser_action": {
      "default_title": "DuoHelper"
    },
    "permissions": [
      "webNavigation",
      "activeTab"
    ]
  }

The error I'm getting:

Uncaught TypeError: Could not add listener

I would, with the extension working properly, like to have the chrome extension inject the javascript files on the active tab if its url is *://duolingo.com/skill/*.

Upvotes: 1

Views: 1045

Answers (1)

woxxom
woxxom

Reputation: 73526

See the documentation: urlMatches is a RE2 regular expression, not a URL match pattern.

Solution 1.

The correct RE2 expression would be 'https?://(www\\.)?duolingo\\.com/skill/.*'

Solution 2.

A better approach is to do a plain string comparison of the host name and path because it's much faster than using regular expressions and the documentation explicitly advises to use regexps only when absolutely unavoidable:

chrome.webNavigation.onCompleted.addListener(info => {
  chrome.tabs.executeScript(info.tabId, {file: 'jquery-3.3.1.min.js'});
  chrome.tabs.executeScript(info.tabId, {file: 'duohelperinjector.js'});
}, {
  url: [{
    hostSuffix: '.duolingo.com',
    pathPrefix: '/skill/',
  }],
});

Note how hostSuffix utilizes an implicit dot added by the API before the first component to match any subdomain of duolingo.com. Also, the callback parameter is not a tab, but a different object with tabId inside.

Solution 3.

Use declarativeContent API as shown in the documentation, but instead of ShowPageAction specify RequestContentScript, which despite the warning in the documentation actually works in the stable Chrome.

Upvotes: 2

Related Questions