Building The Cruxify Chrome Extension

And how you can also build and publish your own browser extension!

Ankit Singla
Abstract.ai
6 min readMay 6, 2020

--

Did you know that as many as 188,620 extensions were reported published on the Chrome Web Store by Extension Monitor during a scan of the entire Chrome Web Store in 2019.

I also built and published my chrome extension Cruxify recently, when I was browsing a document on chrome and felt the need to save some pieces of text locally for future reference.

Through Cruxify, I wanted to be able to go about copying pieces of text while reading a doc online, all of which would be available to me, appended one after the other in order. A download capability to store the text file locally was also essential.

I’ll walk you through the coding part progressively. Hope you’ll find some helpful information that will aid you in developing your own chrome extension and getting it published on the chrome web store. This article is divided into two parts: Implementing the cruxify feature, and downloading the crux as a text file.

Part-1: Implementing the Cruxify feature

Step-1: First we provide the initial json for manifest.json file, which is the only file that every extension must contain. We use it to specify basic metadata about our extension and aspects of the extensions functionality.

Here we provide the name for the extension, followed by a short and catchy description about its functionality and a version number. Since manifest_version: 1 was deprecated, we need to specify the manifest_version:2. It is also required to specify the permissions that our extension needs from the user to achieve its functionality, and we specify these next. The clipboardRead permission will allow us to read the clipboard, and we will do that each time the user copies something to the clipboard from a webpage.

Step-2: Moving forward, since the interaction with the clipboard is taking place in the context of the web page, we need what is called a content script to be able to automatically detect copy events.

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.

Here, we are adding an EventListener for copy events that take place in the context of the web page. Then in the callback, we are using MessagePassing to communicate the occurrence of this event to our background script.

I named it oncopy.js. This serves as our content script.
How has a new Javascript file we just defined automatically become a content script?
Well, it hasn’t till now. But it will be once we declare it in the manifest file.
Remember? It stores metadata for our extension.

So, we now need to add the following JSON to our manifest file:

The matches key here is used to specify which all urls we want our content script to run. Here, I am passing the special value <all_urls>, but you can refer this for other options available for injecting content scripts.

Step-3: Now, I mentioned a background script above, which is at the receiving end of the message communicated by our content script. A background script helps manage events, which are essentially browser triggers. A background page is loaded when needed, and unloaded when it goes idle.

Lets define a background page for our extension and name itbackground.html

We now define the background script by the name background.js

This code listens for the copy event. Inside, it pastes the clipboard contents into a textarea element clip by first bringing it in focus and then executing the paste command. Now, we don’t want that the user copy the same text twice by mistake, and thus we maintain the previously pasted text as well, and compare the currently copied text with it. If they are found same, we return. Otherwise we update the value of the crux textarea element, which holds all that has been previously copied by appending the current copiedText to crux value. Finally, we send the response.

Let’s also add details of our background page to the manifest file at this point.

Here, one thing to note is that I have set the “persistent” key to true, but you should probably avoid doing that until it is absolutely needed. Non-persistent background pages are actually Event Pages. Event pages are unloaded when the browser detects that the page is not doing anything. On the other hand, background pages persist till the user closes the browser, thus making the extension less efficient with memory, as mentioned here.

Step-4: To display the crux in our extension popup, we will define a file and name it popup.html

Then we put our javascript into the index.js file.

Here, we are using chrome.extension.getBackgroundPage() to interact with our background page through the popup. It captures the value of the crux element and displays it to the user in a textarea element, also named crux.

Don’t forget to add it to the manifest file so that browser knows that popup.html is our popup page.

Content Security Policy
Chrome’s extension system has incorporated the Content Security Policy to make extensions more secure and for us to be able to govern the types of content that can be loaded and executed by our extensions. Inline javascript is thus not executed, and no inline <script> blocks and inline event handlers can be placed.
But, chrome developer documentation provides some relaxation and says “inline scripts can be allowed by specifying the base64-encoded hash of the source code in the policy. This hash must be prefixed by the used hash algorithm (sha256, sha384 or sha512)”.

For this, we need to first obtain the digest of a string on the command line simply via the openssl program. For example:

echo -n index.js | openssl dgst -sha256 -binary | openssl enc -base64

This should return a hash and we need to specify it in our popup.html :

and manifest.json :

Now we are good to go for this part where we have implemented our core functionality.

We should also add some other elements such as a title, or an icon to the popup and also write CSS to make the popup look more appealing. I am skipping this part as it is upto your choice what kind of styling you want to add to your extensions.

Part-2: Downloading the file

Step-1: Let’s first specify the downloads permission in our manifest file. This is required if we want to download files through our extensions.

Step-2: Next we will need to provide a download button in the extension popup. You can append it to the contents of the html<body> tag.

Step-3: Next we need to attach the click event listener to the download-button in our index.js file. For this, we shall append the following code to our index.js

As soon as the download button is clicked, the event listener fires. It first attempts to create a Blob out of the value of the crux, which is specified to be of the type text/plain, following which a URL is generated for the blob we just created by making use of URL.createObjectURL(). Finally, the download is initiated with a DownloadItem parameter which has url and filename properties set to appropriate values.

You would notice that a download shelf appears at the bottom of the window when downloading a file in chrome. I wanted to get rid of it, which is easy to do if you want to disable it for all downloads. But I just wanted to hide it for downloads through Cruxify without interfering with other downloads initiated by the user from elsewhere.

To hide the downloads shelf, I inserted this code inside the click event listener of the download button.

To re-enable the display of the download shelf, we have to listen for the onChangedevent chrome.downloads which fires when the download status changes i.e. if the DonwloadItem’s state now is either complete or interrupted

This will re-enable the download shelf in both the cases: download complete and download interrupted.

Conclusion

With this, we shall conclude this article.

That said, you can download Cruxify from the chrome web store by visiting the given link. It offers some more features such as an editable crux, which records manual edits that a user makes to the crux, also enabling the user to use it as an in-browser notes app.

https://chrome.google.com/webstore/detail/cruxify/mnljcegcgmhgfphlnkmdccppmjcjkfjp

Hope this article comes in handy when you are working on your own chrome extension. All the best!

--

--

Ankit Singla
Abstract.ai

A Software Engineer who loves to explore things!