Search code examples
javascriptgoogle-chrome-extensionscopecrossrider

Global variable created inside CrossRider's appAPI.ready() function not available to page?


I am trying to create a Chrome extension using CrossRider and am struggling with how to create a global variable.

My extension is essentially going to dynamically append a few JavaScript files to the page if a button is clicked, and I need it to also create a global variable and set some properties.

I tried the following:

appAPI.ready(function($) {
    console.log('inside crossrider extension ready()');
    window.foobar = 'barfoo';
    return;
});

When I refresh the page, the message inside crossrider extension ready() is printed out to the console, so I know the extension is loaded and working, but when I try executing window.foobar or foobar in the console an error is thrown saying it's undefined.

This is my first time creating an extension, so what am I missing here? Why isn't the global variable I create inside of CrossRider's appAPI.ready() function available outside of it?


Solution

  • I can't find a duplicate target, so I'll explain what's happening.

    I don't know the Crossrider terminology, but when a Chrome extension executes code in a page, this is called a Content Script.

    However, the code does not execute in the same context as the page itself. It's called an isolated world and means, among other things, that the window object is not shared.

    Content scripts execute in a special environment called an isolated world. They have access to the DOM of the page they are injected into, but not to any JavaScript variables or functions created by the page. It looks to each content script as if there is no other JavaScript executing on the page it is running on. The same is true in reverse: JavaScript running on the page cannot call any functions or access any variables defined by content scripts.

    So if you want to set a variable accessible to the page, you need to set it in the page context. How? There are many ways, but they all amount to inserting a <script> element into the page.

    var script = document.createElement('script');
    script.textContent = "window.foobar = 'barfoo';";
    (document.head||document.documentElement).appendChild(script);
    script.parentNode.removeChild(script);
    

    All of that assumes that you don't control the page in question. If you do, there are other ways of communicating the the page, because DOM is shared. You can, for instance, raise a custom DOM event if the page listens to it.