Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I share code between different parts of Chrome Extension?

Let's say, I have a function:

var rand = function(n) {
    return Math.floor(Math.random() * n);
}

Can I use this function in both Content Script and Background Script without copypaste?

Thank you.

like image 597
Oleg Avatar asked Jun 15 '14 08:06

Oleg


People also ask

Can chrome extensions communicate with each other?

In addition to sending messages between different components in your extension, you can use the messaging API to communicate with other extensions.

Can you see the code for chrome extensions?

When the page loads, click on the CRX icon in the extensions bar in Chrome and select “View source.” 4. You should be able to see the selected extension's source code in the Chrome window.

Can you copy chrome extensions to another computer?

If you want to export Chrome extensions manually, you have to enable 'Developer mode' in the browser and pack the extension in a CRX file. CRX is a file that Chrome automatically downloads and installs when you add an extension.

Can you share Google extensions?

Share Extensions. Export your favorite Google Chrome™ extensions as BBCode, HTML, Wiki, Markdown or text. Share extensions via Twitter, Google Mail™.


2 Answers

Yes. You could have an external JS file which is loaded as part of the background and the content script (like any normal JS file). Just add it to the background and content script file arrays in the manifest and it will be loaded for you.

For example if our shared function reside in sharedFunctions.js, the content script using them is in mainContentScript.js and the background code in mainBackground.js (all in the js subfolder) we can do something like this in the manifest:

 "background": {
   "scripts": [ "js/sharedFunctions.js", "js/mainBackground.js" ]
 },

 "content_scripts": [
    {
      "matches": ["*://*/*"],
      "js": ["js/sharedFunctions.js", "js/mainContentScript.js"]
    }
 ]

Note: Make sure to load it in the right order, before other files using it.

Or you can also add it as a script tag (with a relative URL) in the background.html and in the manifest only add it to the content script's JS array. So the manifest will look like:

 "background": {
   "page": "background.html"
 },
 "content_scripts": [
     {
       "matches": ["*://*/*"],
       "js": ["js/sharedFunctions.js", "js/mainContentScript.js"]
     }
  ]

and the background.html file will have this script tag:

 <script type="text/javascript" src="js/sharedFunctions.js"></script>

Edit: Also, For sharing with other scopes in other parts of the extension (unfortunately not available in the content script).

You can also have the functions you want to share reside in the background script and reach them via chrome.runtime.getBackgroundPage() which you can read more about here: https://developer.chrome.com/extensions/runtime#method-getBackgroundPage

So, let's say you have your rand() function declared as a global variable in the background script (which means it's a property on the background's window object), you can do something of this sort at the beginning the script in the other scope (this can be a popup context like a browserAction window):

var background, newRandomNumber;
chrome.runtime.getBackgroundPage(function(backgroundWindow){
 background = backgroundWindow;
 newRandomNumber = background.rand();
})

This way you can also use the variable background to access any property or method set on the background's window object. Be mindful, that this function runs asynchrounusly, meaning that only after the callback is called will the variables background and newRandomNumber will be defined.

like image 118
Lior Avatar answered Oct 16 '22 07:10

Lior


Yes, you can, by putting it in a separate JS file and loading it in both.

Say, you have a file utils.js that contain all such functions.

Then you can load the background page like this:

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

And the content script like this:

"content_scripts": [
  {
    "matches": ["..."],
    "js": ["utils.js", "content.js"]
  }
],

Or, if you're using programmatic injection, chain the calls like this:

chrome.tabs.executeScript(tabId, {file: "utils.js"}, function(){
  chrome.tabs.executeScript(tabId, {file: "content.js"}, yourActualCallback);
});
like image 36
Xan Avatar answered Oct 16 '22 07:10

Xan