4

Im trying to write a Chrome extension that has a dev tools panel. This extension needs to call functions defined on a property on window in a webpage that I also have made. In other words, the extension is only for my own web page and I control both. Example:

// This script is added in my own webpage application when it loads
window.myTest = () => { /* do something */ }

I want to be able to call the function window.myTest from my Chrome extension. I need to make similar functionality like https://github.com/zalmoxisus/redux-devtools-extension.

It seems that I need to do this by inject script/code from my backend page. I have all working, extension with backend page that gets invoked and I can see that the code that I inject gets called in the page context (testing by console.log gets written to the console output of the page).

Here is my code:

manifest.json

{
  "manifest_version": 2,

  "name": "MyTest",
  "description": "MyTest",
  "version": "0.0.1",

  "minimum_chrome_version": "10.0",

  "devtools_page": "devtools.html",

  "background": {
    "scripts": ["background.js"]
  },

  "content_scripts": [{
    "matches": ["<all_urls>"],
    "js": ["testscript.js"]
  }],

  "permissions": [
    "tabs",
    "<all_urls>"
  ]
}

testscript.js

window.myTest(); // myTest is undefined in the context of the injected script

background.js

// empty, but here to be able to open background page

I also have a pannel that sends a message to the background page when a button is clicked. I know that the panel and sending the message also work. But window.myTest is still undefined.

Edit Removed the injection from background.js, because I did not use it and have same issue as described.

  • You don't have to inject manually testscript.js as long you declare it in your manifest "content_scripts" section. – nicecatch Dec 15 '16 at 10:38
  • What if using some like `setTimeout(func, 5000)` to call `window.myTest()`? I mean can you ensure `myTest` has been declared when injected scripts run? – Haibara Ai Dec 15 '16 at 11:49
  • 1
    Possible duplicate of [Building a Chrome Extension - Inject code in a page using a Content script](http://stackoverflow.com/questions/9515704/building-a-chrome-extension-inject-code-in-a-page-using-a-content-script) – Makyen Dec 15 '16 at 15:39
  • If this is for a web page you have also made, then it is inappropriate to be injecting into ``. You should limit your `matches` to only the pages you are affecting. – Makyen Dec 15 '16 at 15:43
  • @AndreaConte, While the OP clearly does not need to inject the same script into the page via *both* a *manifest.json* `content_scripts` entry *and* `tabs.executeScript()`, for an extension that only interacts with the page in the rare condition that the user has the DevTools open, it is probably much more appropriate to be injecting using `tabs.executeScript()`, so that the injection only occurs when the functionality is needed, instead of always being injected when the vast majority of time it will never be used. We can't know which is better, because the OP has not shared enough info. – Makyen Dec 15 '16 at 15:49

1 Answers1

2

Finally, I got the specs on this. Mozilla and Chrome follow the same specs for extensions.

Content scripts get a "clean" view of the DOM. This means:

  • Content scripts cannot see JavaScript variables defined by page scripts.
  • If a page script redefines a built-in DOM property, the content script sees the original version of the property, not the redefined version.

https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Content_scripts

Shyam Swaroop
  • 793
  • 10
  • 7