2

In my short coder life I see such behavior for the first time:

An extension at its own works like I expect, but if I pull some variables into the console, I realize, that they are loaded multiple times (three, four and five, depends from placement of console.log in the background.js). This is the list of them - to see in the background.js too:

  • console.log("domen: "+currentDomain);
  • console.log("language/countrysubdomen: "+savedApi);
  • console.log("index: "+badgeText);

Is it something, that one can neglect? Should it be avoided? How? These variables are loaded in file, which is 60 lines long - I was going through this file some times and recognizes no cause for multiple loading.

Why is it happen? What is in the background.js wrong and how it could be improved to get this issue away?

manifest

{
  "name": " App",
  "description": "",
  "version": "1.0",
  "background": {
    "scripts": [
      "background.js",
      "psl.js"
    ],
    "persistent": false
  },
  "options_page": "options.html",
  "options_ui": {
    "page": "options.html",
    "chrome_style": true,
    "open_in_tab": false
  },
  "permissions": [
    "webNavigation",
    "activeTab",
    "tabs",
    "http://*/*",
    "https://*/*",
    "storage",
    "background"
  ],
  "browser_action": {
    "default_title": "metrics",
    "default_icon": {
      "19": "icon19.png",
      "38": "icon38.png"
    },
    "default_popup": "popup.html"
  },
  "icons": {
    "16": "icon16.png",
    "19": "icon19.png",
    "24": "icon24.png",
    "32": "icon32.png",
    "38": "icon38.png",
    "48": "icon48.png",
    "128": "icon128.png"
  },
  "web_accessible_resources": [
    "welcome.html"
  ],
  "manifest_version": 2
}

background

var currentDomain = "";
var currentHost = "";
var currentFullpath = "";
var currentUrl = "";
var currentFolder = "";
var badgeText = "";

chrome.runtime.onInstalled.addListener(function (object) {
  if (chrome.runtime.OnInstalledReason.INSTALL === object.reason) {
    chrome.tabs.create({ url: chrome.extension.getURL("welcome.html") }, function (tab) {
      console.log("New tab launched with instructions to use the extension");
    });
  }
});

chrome.tabs.onUpdated.addListener(function (tabid, changeInfo, tab) {
  chrome.tabs.query({ 'active': true, 'currentWindow': true }, function (tabs) {
    let newUrl = new URL(tabs[0].url);
    currentHost = newUrl.host;
    currentUrl = tabs[0].url;
    currentFullpath = currentUrl.substring(0, currentUrl.lastIndexOf("/"));
    currentFolder = currentUrl.split("/");
    parsed = psl.parse(currentHost);
    currentDomain = parsed.domain;

    console.log("domen: " + currentDomain);

    chrome.storage.sync.get('savedApi', ({ savedApi }) => {
      console.log("language/countrysubdomen: " + savedApi);

      if (savedApi == null)
        savedApi = 'de';
      if (currentDomain == null)
        return false;

      var xhr = new XMLHttpRequest();
      var protocol = "https://";
      var middle = ".myservice.com/seo/__loadModule/domain/"
      var end = "/mobile/1/_action/_data_visindex_normal/";

      xhr.open("GET", protocol + savedApi + middle + currentDomain + end, true);

      xhr.responseType = 'document';

      xhr.send();

      xhr.onreadystatechange = function () {
        if (this.readyState == 4) {
          function getElementByXpath(path) {
            return xhr.response.evaluate(path, xhr.response, null, XPathResult.STRING_TYPE, null).stringValue;
          }

          badgeText = getElementByXpath("normalize-space(//div[@class='data']/span[@class='value']/text())");
          console.log("index: " + badgeText);

          chrome.browserAction.setTitle({ title: "The number of " + currentDomain + " is " + String(badgeText) });
          chrome.browserAction.setBadgeText({ text: String(badgeText) });
          chrome.browserAction.setBadgeBackgroundColor({ color: '#1d2554' });
        };
      };
    });
  });
});
Codebling
  • 10,764
  • 2
  • 38
  • 66
Evgeniy
  • 2,337
  • 2
  • 28
  • 68
  • 1
    Please edit your question to put all the relevant code inline. People will be reluctant to follow the google drive links. – Max Lemieux Feb 23 '20 at 19:04
  • really? Could you maybe explain such unwillingness? Do you mean there are another file hosters, where people aren' such reluctant? Are 120 code lines is not something, what make the post unreadable? – Evgeniy Feb 23 '20 at 19:30
  • 1
    I am reluctant to follow all external links, and the inline code is placed in scrolling containers here, so it's not a problem. – Max Lemieux Feb 23 '20 at 19:59
  • 1
    @MaxLemieux nice, they are no longer external - something to say about subject? – Evgeniy Feb 23 '20 at 22:32
  • It's possible that chrome.tabs.onUpdated.addListener is firing on repeated "loading/loaded" state changes which occur during a complex page load. – Max Lemieux Feb 24 '20 at 06:04
  • @MaxLemieux this would mean, there is nothing wrong, which should be fixed, correct? Or are there any other methods to get the current url of an active tab, as with `chrome.tabs.onUpdated.addListener `? – Evgeniy Feb 24 '20 at 10:21
  • Updating these variables doesn't seem to be a problem, however it may be possible for you to get the URL without using an event listener - see https://stackoverflow.com/questions/18436245/how-to-fetch-url-of-current-tab-in-my-chrome-extension-using-javascript/58687656#comment39408670_21877205 – Max Lemieux Feb 24 '20 at 18:06
  • @MaxLemieux I need an event listener, because i want to monitor not only initial url, which was opened with tab, but next url user surfs or inputs manually too. – Evgeniy Feb 25 '20 at 23:11
  • Seems fine to do this - no problem. – Max Lemieux Feb 26 '20 at 02:38

1 Answers1

1

You added a listener to chrome.tabs.onUpdated, so the listener may be triggered for a number of reasons:

  1. a tab begins loading
  2. a tab stops loading
  3. the title of a tab changes or is set for the first time
  4. the favicon is set

This is a non-exhaustive list. For a complete list, see the chrome.tabs.onUpdated event documentation.

It is quite normal that your onUpdated listener should be called multiple times. To see why it is being called, insert this line at the top of your listener:

chrome.tabs.onUpdated.addListener(function (tabid, changeInfo, tab) {
  console.log('chrome.tabs.onUpdated listener called. Changed info: ' + JSON.stringify(changeInfo));
Codebling
  • 10,764
  • 2
  • 38
  • 66