Reputation: 2031
I am working on a Chrome devtools extension that exposes a function (extensionEntryPoint
) to the inspected page. The problem is that extensionEntryPoint
is not available at the initial scripts in the inspected page loads and runs. I can use it from window.onload
, but that is too late.
Here's my code:
manifest.json
:
{
"name": "Extension",
"version": "1",
"manifest_version": 2,
"permissions": [
"activeTab"
],
"web_accessible_resources": ["api.js"],
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content-script.js"],
"run_at": "document_start",
"all_frames": true
}
]
}
content-script.js
:
const script = document.createElement("script");
script.src = chrome.extension.getURL("api.js");
document.documentElement.appendChild(script);
api.js
:
function extensionEntryPoint(data) {
console.log("Thanks for calling, I'll debug your data now!")
}
Ideally, I would want for extensionEntryPoint
to be available to any script on the page as it's loading (e.g. before DOMContentLoaded
fires). Is this possible?
Upvotes: 1
Views: 310
Reputation: 73866
Due to a quirk/bug in Chrome currently your script is queued among other page scripts and hence it's not guaranteed to be the first one to run.
Solution: put the contents of api.js inside a literal string and assign it to script.textContent.
And then you can remove web_accessible_resources from manifest.json.
content-script.js:
const script = document.createElement("script");
script.textContent = `
// the actual contents of api.js
// .......
`;
document.documentElement.appendChild(script);
script.remove();
To preserve syntax highlighting of the code in an IDE, put the code into a function, but only if it's small as the browser will have to do the extraneous work parsing that code twice and stringifying it.
script.textContent = '(' + (() => {
// the actual contents of api.js
// .......
}) + ')()';
If you build your code prior to running it (e.g. via node.js), you can write a script that embeds the contents of api.js for example after a special comment placeholder inside your content script.
Upvotes: 1