Chrome Extension Development – Background page and content script communication.

As of today, Google has some awesome developer docs for getting started with Chrome extension development. When it comes to more advanced maneuvers however, Stack Overflow is a better option. I hope Google fixes their Chrome docs, but in the meantime if you’re looking for a way to call your background page functions from a content script, here’s a quick guide for getting it to work.

Manifest.json

{
 "manifest_version": 2,
 "name": "Oracle Projects and Task Management",
 "description": "Manage your Oracle Fusion PPM To-do and Project Tasks from your browser.",
 "version": "1.0",
 "background": {
 "page" : "background.html",
 "persistent": true
 },
 "permissions": [
 "https://*/",
 "contextMenus",
 "background",
 "notifications",
 "declarativeContent",
 "tabs",
 "activeTab"
 ],
 "icons": { 
 "16": "img/icon.png",
 "48": "img/icon.png",
 "128": "img/icon.png" 
 },
 "browser_action": {
 "default_icon": { 
 "19": "img/icon.png", 
 "38": "img/icon.png" 
 },
 "default_popup": "popup.html"
 },
 "content_scripts": [
 {
 "matches": ["https://bug.oraclecorp.com/*&rptno=*"],
 "js": ["js/jquery-2.0.3.min.js", "js/bugdb.js"],
 "css": ["css/bootstrap.min.css", "css/bootstrap-theme.min.css"]
 }
 ],
 "content_security_policy": "script-src 'self' https://ssl.google-analytics.com; object-src 'self'",
 "web_accessible_resources": [
 "img/icon.png",
 "css/bootstrap.min.css", 
 "css/bootstrap-theme.min.css"
 ]
}

Requirement:

I was developing a chrome extension for Oracle’s PPM Task Management Cloud offering with a Browser Action ( popup.html ) that would communicate with a background page ( background.html ) and multiple content scripts that were run on URLs that matched Oracle’s internal Bug DB web application’s pattern ( https://bug.oraclecorp.com/*&rptno=* ).

The content script (bugdb.js) was supposed to check if a user is logged in by calling a background page function ( bgApplicationController.isBgUserLoggedIn() ) , and then attach a function from the background page ( bgApplicationController.createTodoTask() ) to a DOM element on the current page accessed by the content script. Simple enough, right?

Well the caveat here is that we need to use Chrome’s messaging APIs to be able to communicate between content scripts and the background page.

Content Script – bugdb.js

chrome.runtime.sendMessage({
  type: 'checkUserLoggedIn',
}, function(response) {
  if(response == "true"){
  var bugText = $("#bugText").text();
 
 ...

 $("#bugText").append(btn);
   btn.click(function(){
      chrome.runtime.sendMessage({
         type: 'createBugTask'
      }, function(response) {
      console.log("Backgrund.js message response was :"+response);
      });
   });
   }
});

So what’s going on here?

We’re using chrome.runtime.sendmessage to send a message to the background page. The ‘type’ object field is checked on the background page, along with other data fields if needed. The background page can then invoke functions and send a response back to the content script by passing data in its callback. Check out the code in the background page script below :

Background Page Script – background.js

chrome.runtime.onMessage.addListener(function(message, sender, handler) {
   if (message && message.type == 'createBugTask') {
     var bugText = message.bugText;
     bgApplicationController.createTodoTask(bgUser, bugText);
     handler(bugText);
   } else if(message && message.type == 'checkUserLoggedIn') {
      if(window.bgApplicationController.isBgUserLoggedIn()){
        handler("true");
      } else {
        handler("false")
      }
   }
 });

Hope that helps! Also do note that the APIs used in this blog post are current as of Feb 2016, however the coding practices are not. Google discourages the use of persistent background pages – something I haven’t taken care of.