Making a chrome extension

WWhat is a chrome extension ?

AliExpress is an online retail service based in China that is owned by Alibaba. Launched in 2010, it is made up of small businesses in China and other locations, such as Singapore, that offer products to international online buyers.

AliExpress

Manifest

Every extension has a JSON-formatted manifest file, named manifest.json, that provides important information. There a few required fields like manifest_version, name and version. Manifest version is for the browser to determine how to read the manifest file. Version 1 has been deprecated and so the only choice here is 2.

Other optional but inportant to mention fields include:

  • browser_action : You can specify the icon that appears in the chrome top-bar, badges, popup page etc.
  • permissions : Used to mention any extra permissions that the extension might require. Examples: all_tabs, browser_history etc.
  • web_accessible_resources : Any resources that are expected to be usable in the context of a web page. Example: If your extension adds custom icons on all the images to make download them in a single click, then you can specify that icon in these resources and ship it as a part of the packaged extension
  • background : You can specify the backround script here.
  • content_scripts : You can specify the content script here.

Popup or UI

The extension user interface should be purposeful and minimal. Just like extensions themselves, the UI should customize or enhance the browsing experience without distracting from it. The popup can be registered in the manifest, under browser action or page action.

{
    "name": "Drink Water Event",
    ...
    "browser_action": {
      "default_popup": "popup.html"
    }
    ...
}

You can add a CSS or JS as well and link it to the popup via HTML tags.

Background Script

Content Script

Content scripts are files that run in the context of web pages. By using the standard Document Object Model (DOM), they are able to read details of the web pages the browser visits, make changes to them and pass information to their parent extension. They have access to all the chrome APIs dependning on the permissions specified in the manifest file.

For a sample web page

<html>
    <button id="mybutton">click me</button>
    <script>
      var greeting = "hello, ";
      var button = document.getElementById("mybutton");
      button.person_name = "Bob";
      button.addEventListener("click", function() {
        alert(greeting + button.person_name + ".");
      }, false);
    </script>
  </html>

The following content script will give an alert if the button is pressed.

var greeting = "hola, ";
  var button = document.getElementById("mybutton");
  button.person_name = "Roberto";
  button.addEventListener("click", function() {
    alert(greeting + button.person_name + ".");
  }, false);

But the JS of the web page also produces an alert. Therefore a user will see two alerts if the button is pressed and it is worth mentioning here how chrome isolates the two javascript environments.

Isolated worlds do not allow for content scripts, the extension, and the web page to access any variables or functions created by the others. This also gives content scripts the ability to enable functionality that should not be accessible to the web page such as chrome APIs.

Message Passing between various scripts

Since content scripts run in the context of a web page and not the extension, they often need some way of communicating with the rest of the extension. Communication between extensions and their content scripts works by using message passing. Either side can listen for messages sent from the other end, and respond on the same channel. A message can contain any valid JSON object (null, boolean, number, string, array, or object). here is a simple API for one-time requests and a more complex API that allows you to have long-lived connections for exchanging multiple messages.

  • Simple one-time requests : If you only need to send a single message to another part of your extension (and optionally get a response back), you should use the simplified runtime.sendMessage or tabs.sendMessage . This lets you send a one-time JSON-serializable message from a content script to extension , or vice versa, respectively . An optional callback parameter allows you handle the response from the other side, if there is one. Sending a request from a content script looks like this:
    chrome.runtime.sendMessage({greeting: "hello"}, function(response) {
      console.log(response.farewell);
    });
    

    Sending a request from the extension to a content script looks very similar, except that you need to specify which tab to send it to. On the receiving end, you need to set up an runtime.onMessage event listener to handle the message. This looks the same from a content script or extension page.

    chrome.runtime.onMessage.addListener(
    function(request, sender, sendResponse) {
      console.log(sender.tab ?
                  "from a content script:" + sender.tab.url :
                  "from the extension");
      if (request.greeting == "hello")
        sendResponse({farewell: "goodbye"});
    });
    
  • long-lived connections : Sometimes it’s useful to have a conversation that lasts longer than a single request and response. In this case, you can open a long-lived channel from your content script to an extension page , or vice versa, using runtime.connect or tabs.connect, respectively . The channel can optionally have a name, allowing you to distinguish between different types of connections.

Comments