I'm trying to access a global variable from a website — random OGS Example — through TypeScript in order to get data from the current board game.
I'm pretty new to TS so I'm not really sure how I would type this variable either. The global variable itself was originally created in TS actually, but it has a bazillion methods and properties, since there are so many functionalities. So, if I'm going to type it myself, I would rather only type what I need, if that's possible, or somehow import it from a package somewhere — I don't think the author has published it publicly anywhere.
In parallel to all this, there's also the question of whether or not global variables are available by default to browser extensions, which might not be the case.
So, what I've been trying (I've tried a million other variations...) to do is something like* — inside content.ts
, which is run when inside the OGS domain —:
interface Goban {
bounded_height: number;
}
declare var goban: Goban;
goban = window["global_goban"];
console.log(goban.bounded_height.toString());
The error I usually get is:
Uncaught ReferenceError: goban is not defined
So what am I missing? Do I have to create a declaration file (.d.ts
)? What is the proper way of dealing with this sort of import of a global variable from 3rd party code?
*: Depending on how you're trying to deal with the window
object, you might have to add "suppressImplicitAnyIndexErrors": true
to your tsconfig.json
in order to have TS not complaining statically.
For those unfamiliar with how to develop browser extensions, the simplest way to start, in TS, is to:
manifest.json
, for example:
{
"manifest_version": 2,
"name": "Name",
"version": "0.0.2",
"description": "Description.",
"content_scripts": [
{
"matches": ["*://*.online-go.com/*"],
"js": ["content.js"]
}
]
}
content.ts
file, with the code from the previous section.tsc
.manifest.json
and the content.js
into a browser as an unpacked browser extension.Content scripts can't access global variables directly, they work in an "isolated world". From the Content Script Environment MDN Docs:
However, content scripts get a "clean" view of the DOM. This means:
- Content scripts cannot see JavaScript variables defined by page scripts.
But you can still work around it by sharing resources through the web_accessible_resources
key in your manifest.json
.
Here is one way how this could be done:
manifest.json
:
{
"manifest_version": 2,
"name": "Name",
"version": "0.0.2",
"description": "Description.",
"content_scripts": [
{
"matches": ["*://*.online-go.com/*"],
"js": ["content.js"]
}
],
"web_accessible_resources": ["script.js"]
}
You can add whichever script you might need to the web_accessible_resources
key, just like the ones used in the matches
key above for example. You can also use wildcards, like *
, to match several at the same time.
You might still need to add this to your
compilerOptions
inside yourtsconfig.json
:"suppressImplicitAnyIndexErrors": true
.
script.ts
:
interface Goban {
bounded_height: number;
}
declare var goban: Goban;
goban = window['global_goban'];
console.log(goban.bounded_height.toString());
content.ts
:
const script = document.createElement('script');
script.src = chrome.extension.getURL('script.js');
document.head.append(script);
You might also need to install @types/chrome
through, for example, npm i --save @types/chrome
.
Also, content scripts can communicate with page scripts using window.postMessage
and window.addEventListener
.
Further resources: