Build a Design Picker Extension with Vanilla Javascript
Tags: javascript, webdev, css, html
Published: 2021-07-30 02:55:36

# Introduction

Sometimes you like the fonts and color palettes used in websites that you visit and wish to check out what they are. Most people use different extensions for this purpose. 

Fetching a CSS property from wherever you click is so easy, that if you could build an extension, fetching the most relevant properties you want in one go improves your productivity. 

I'm going to walk you through the steps I've used to build a simple extension using pure JavaScript and CSS.

If you'd like to explore it first, Check out ->   [Github Link](https://github.com/ashikvarma11/design-picker) 

# Files

### Manifest file


```
{
  "manifest_version": 2,
  "name": "Picker Extension",
  "version": "1.0.0",
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "html": ["popup/popup.html"],
      "js": ["content.js"]
    }
  ],
  "permissions": ["tabs"],
  "icons": { "16": "icon.png", "48": "icon.png", "128": "icon.png" },

  "browser_action": {
    "default_popup": "popup/popup.html",
    "default_title": "Picker"
  }
}

``` 

A `manifest.json` file is where the configuration for your project exists. The browser derives the name, paths to your scripts, icons, permissions, etc. through this file. Furthermore, we have a list of options to specify the nature of your extension, like, how it should be rendered when the user opens a new tab or which all websites should this extension be applied to, etc.

### Content Script

A content script is a JavaScript file that has access to the DOM of the website that you visit. This means that you can get and set the properties of any element in the DOM tree.

### Pop up

This is the window that pops up when you click on the extension icon. Pop-up doesn't have access to the content of the website that you visit. This is also referred to as "Extension" in the Chrome development docs. It has its DOM and is standalone. But, we can make the connection between your Content Script and Popup script through a series of "Message Passing".


# Get your Design

In the Content script ->

```
function listenToClick() {
  document.addEventListener("click", function (event) {
    payLoad = {
      ...payLoad,
      fontFamily: window
        .getComputedStyle(currElement, null)
        .getPropertyValue("font-family"),
      fontSize: window
        .getComputedStyle(currElement, null)
        .getPropertyValue("font-size"),
      color: window
        .getComputedStyle(currElement, null)
        .getPropertyValue("color"),
      backgroundColor: window
        .getComputedStyle(currElement, null)
        .getPropertyValue("background-color"),
    };
  });
}
``` 
Two global variables - `payLoad` and `currElement` - are initialized outside this function. Whenever the user **hover** over an element, the **currElement** will be set. Further, clicking the element fetches the design using the code above.

# Initiate a Handshake

You need to ping the content script and get the design values you obtained in the content script as response.

In the Popup script ->

```
function initiateHandshake() {
  chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
    chrome.tabs.sendMessage(
      tabs[0].id,
      { message: "handshake" },applyValuesToView);
  });
}

function applyValuesToView(response) {
  let message = response;
  if (message != undefined) {
    if (message["color"]) font_col.innerHTML = message["color"];
    if (message["backgroundColor"]) bg_col.innerHTML = message["backgroundColor"];
    if (message["fontSize"]) font_size.innerHTML = message["fontSize"];
    if (message["fontFamily"]) font_fam.innerHTML = message["fontFamily"];
  }
}
``` 
Whenever the user opens the popup, a **handshake** message is sent to the content-script and in response, it will send the design data fetched when an element was clicked. 

# Send Response for Handshake


```
function listenToPopUp() {
  chrome.runtime.onMessage.addListener(function (
    request,
    sender,
    sendResponse
  ) {
    if (request.message === "handshake") sendResponse(payLoad);
  });
}
``` 


# Copy design value

```
function copyDesign(event) {
  var tempInput = document.createElement("input");
  tempInput.value = event.target.innerText;
  document.body.appendChild(tempInput);
  tempInput.select();
  document.execCommand("copy");
  document.body.removeChild(tempInput);
  toggleSnackBar();
}
``` 

This is a hack for copying the text to the clipboard. An ** input** element is created to simulate click and copy through the JavaScript code.

*We use a similar approach whenever we want to download content from a link.*


# Publish the Extension

Navigate to `chrome://extensions/` and click on the `Load unpacked` button.
A prompt will appear to select your folder. Add the whole folder and it will install your extension **locally**. 

*This will run only on **your** browser.* 

# That's it.

Feel free to fork the repo and customize your extension as you like.
Thank you, for reading.