0

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' }); 
    }
});
English Rain
  • 311
  • 5
  • 13
  • 1
    The web_accessible_resources script was added to the page as a `script` DOM element so it runs in [page context](/a/9517879) not in the special inherent "isolated world" of content scripts. You need to add an [MCVE](/help/mcve) in the question if further assistance is necessary. – wOxxOm Apr 04 '21 at 03:54
  • Hi @wOxxOm, i've added the MCVE. Would appreciate any pointers on solving this. In case any additional info is needed, please let me know, thank you. – English Rain Apr 04 '21 at 09:31
  • 1
    I don't see why you're doing it though so all I can say is don't do it: use a content script instead. – wOxxOm Apr 04 '21 at 09:36
  • Why: I'm not using any content script at all. My background script (ghi.js) injects a button into DOM. That button has an onClick function attached which NEEDS to be defined in the web_accessible_resources script (abc.js) because if i define it in ghi.js the button can't find the function. I've updated the question to include Manifest.json & background.js. – English Rain Apr 04 '21 at 09:53
  • @wOxxOm Hey! The problem is solved. I figured, since only abc.ts has that interval ID in scope, i should just clear that interval everytime abc.ts initiates, and that's it! Didn't even need to put it in a try...catch block. Thanks for your help in brainstorming this! :) – English Rain Apr 04 '21 at 10:27
  • 1
    You're already using a content script because this is what injection does: it runs the code as a content script. It means you don't need web_accessible_resources. Instead you should add the click listener in js like document.appendChild(element); element.onclick = () => { ... } – wOxxOm Apr 04 '21 at 10:32
  • Darn, you're right. Wish i'd thought of that before making all these different abc.ts, def.ts, ghi.ts & a background.js! Too tired to refactor now, but thanks again! – English Rain Apr 04 '21 at 10:38

1 Answers1

0

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;
English Rain
  • 311
  • 5
  • 13