Search code examples
javascriptgoogle-chromegoogle-chrome-extensionscope

Interval ID set by "web_accessible_resources" script is not getting cleared when script originating from "background > scripts" is trying to clear it


i've made a Chrome extension in which an abc.js is running from the "web_accessible_resources" field of the manifest.json. I've declared a variable therein in the global scope by the name of 'var autoScrollStatus'. I initialize it with a zero, but eventually a setInterval ID gets stored into it.

At one point, i have to clear this setIntervalID from 'var autoScrollStatus'. So a def.js file (initiated from background>scripts in manifest.json) containing the code clearInterval(autoScrollStatus); gets run, but when it reaches this line, def.js crashes with the subject error.

But if i run clearInterval(autoScrollStatus); in the Chrome DevTools, it runs just fine. What's more if i mention delete window.autoScrollStatus; in def.js, this runs without any error too. This clearly means that scope is not a problem here, so why does it still throw ReferenceError only when trying to clear the setInterval() ID?

Any ideas on what's happening here? Thanks!

EDIT - These are the scripts i'm using:

This is abc.ts:

var asSpeeds = {1: 250, 2: 150, 3: 100, 4: 90, 5: 75, 6: 60, 7: 50, 8: 40, 9: 30};
var chordsTA:HTMLTextAreaElement = document.querySelector("#chordsTA");
var asBtn:HTMLButtonElement = document.querySelector("#asBtn");
var autoScrollSpeed = 250;
var autoScrollStatus = 0;

function toggleAutoScroll() {
    if(autoScrollStatus){
        clearInterval(autoScrollStatus);
        autoScrollStatus = 0;
        console.log("Stopped autoscroll.");
        return;
    }
    
    autoScrollStatus = setInterval(_=>{chordsTA.scrollBy(0, 1)}, autoScrollSpeed);
    console.log("Started autoscroll.")
}

var speedUpAS = () => {
    console.log("Speeding upppppppppppppppppppp")
    let asBtnText = asBtn.getAttribute('data-front');
    let newSpeed:number = parseInt(asBtnText.charAt(asBtnText.length - 1))+1;
    if (newSpeed in asSpeeds){
        clearInterval(autoScrollStatus);
        autoScrollStatus = 0;
        autoScrollStatus = setInterval(_=>{chordsTA.scrollBy(0, 1)}, autoScrollSpeed);
    }
}

var speedDnAS = () => {
    console.log("Speeding downnnnnnnnnnnnnnnnnn")
    let asBtnText = asBtn.getAttribute('data-front');
    let newSpeed:number = parseInt(asBtnText.charAt(asBtnText.length - 1))-1;
    if (newSpeed in asSpeeds){
        clearInterval(autoScrollStatus);
        autoScrollStatus = 0;
        autoScrollStatus = setInterval(_=>{chordsTA.scrollBy(0, 1)}, autoScrollSpeed);
    }
}

And this is def.ts:

console.log("deactivating extension");
clearInterval(autoScrollStatus);

In def.ts, I've also tried console.logging autoScrollStatus & other global variables defined in abc.ts file, but each one is getting a ReferenceError, meaning there definitely is a problem of scope (i stand corrected). Any suggestions on solving this? I'm able to access those Global vars in Chrome DevTools without any issue.

Also the manifest.json is this:

{
    "name": "YouTube Overlay",
    "version": "0.1",
    "manifest_version" : 2,
    "description": "Lays overlay on YouTube, can be used for chords/lyrics.",
    "background" : {
      "scripts" : ["bg.js"]
    },
    "permissions": ["activeTab"],
    "browser_action": {},
    "web_accessible_resources": ["abc.js"]
  }

And this is bg.js: (basically it makes the icon act as a Turn On/Off toggle for my extension)

let enable=false;
chrome.browserAction.onClicked.addListener(function (tab) {
    enable = enable ? false : true;
    if(enable){
    //turn on...
        chrome.tabs.executeScript(null, { file: 'ghi.js' }); 
    }else{
    //turn off...
        chrome.tabs.executeScript(null, { file: 'def.js' }); 
    }
});

Solution

  • This was a scope problem. The global variables initialized by abc.ts (initialized from web_accessible_resources) were not visible to def.ts (initialized from background>scripts). So instead of trying to clear the intervalID from abc.ts (on each exit), i just modified my abc.ts to clear the intervalID (on each initialization) so that any previously remaining IntervalID would be cleared, & if none exists, it doesn't throw any error too. This is the new abc.ts:

    clearInterval(autoScrollStatus) // no need to use try...catch as weirdly doesn't throw any error on first run!
    
    // rest of the code same as in my question
    
    var asSpeeds = {1: 250, 2: 150, 3: 100, 4: 90, 5: 75, 6: 60, 7: 50, 8: 40, 9: 30};
    var chordsTA:HTMLTextAreaElement = document.querySelector("#chordsTA");
    var asBtn:HTMLButtonElement = document.querySelector("#asBtn");
    var autoScrollSpeed = 250;
    var autoScrollStatus = 0;