Software Developement
July 30, 2021

Embedding panel into webpage with WebExtension

Add panel to your Web extension
Reupload of my posts from Blogspot from 5-Jul-20

Hi

Recently I've made a chrome extension which acts like Tabs Aside feature from legacy Microsoft Edge. Today I'd like to tell you how I integrate such elements into website pages.

Let's jump in

Note: it is advised to check the extensions development tutorial

Prerequisites

First, let's create some essential files:

  • background.js - JavaScript file which will catch user's input and manage panes' states
  • inject-script.js - will initialize/close pane on specific page
  • manifest.json - standard Chromium extension manifest
  • pane.html - our pane's HTML layout

Let's navigate to the manifest file and add insert those strings:

{
	"web_accessible_resources": [ "*" ],
	"background":
	{
		"scripts": [ "background.js" ],
		"persistent": false
	}
}

First entry allows us to access any file from extension resources (like CSS, JS, images, etc.) from any webpage. The second one declares that the extension should have script running in background. <code>persistent</code> key should be presented but it doesn't bring any difference since in any way the background script will be running indefinitely because of set event listeners

For more information about the manifest see Manifest File Format

Listening to button clicks

Now let's open background script and write some code:

At first, we retrieve the pane's URL (which depends on extension's ID assigned by your browser) and store it into a variable to prevent typos in future

Next part requires some explanation: not every webpage allows us to do what we want (inject something into it). For example, we can't inject out pane into settings page or new tab page or another extension's page. Instead, we can open our pane as standalone webpage (of course if you need to open it anyway). So, for these cases we need to check if it's a system page or not. All system pages have special protocol (e.g. edge:// for Microsoft Edge) and regular pages use http or https protocols. So, we check if the target page has right protocol

The next thing is that there're some websites which also doesn't allow to inject anything. Those are Google Chrome Webstore and Microsoft Edge add-ons Webstore. So, we also exclude them

Note: There's a high probability that there're more websites with such restriction. So, some additional research is advised

So, if page meets all this conditions, that means that we can run our script which will inject or close our pane. In other case, we should either open the pane in new tab or close this tab if it's already opened

We can also set up listeners to close standalone panes if they lost focus

Pane layout

Let's jump into pane.html and set up basic pane layout:

As you can see, it's the most common layout for any webpage. You can customize this page whatever you want. However, we've also added a CSS selector which will collapse our pane's width to 40% if it's embedded into page to make it look like it's a real sidebar pane. Also, we've included inject-script.js into the bottom of the page to make it run after pane is loaded

Pane initialization

Now let's write initialization script which will load our pane. Instead of injecting our pane as a div and having to deal with CSS conflicts, we just insert our pane via iframe

First, we are checking if the script is running on the standalone pane or on an embedded one. If it's not, then that means that we need to show or hide the pane from webpage. To do that we trying to get our pane's iframe. If we can't retrieve any that means that the pane isn't opened yet. So, we create new iframe settings some styles to make it look right and navigating it to our pane's HTML file. If we found the iframe that means that the pane is already opened, and we just delete the iframe from the DOM

If the script is running on the standalone page or inside an <code>iframe</code>, we try to initialize the pane. But at first, we must check presence of the pane and if there's no - end script execution. We need to do this because chrome.tabs.executeScript we call on the background script, runs our initialization script on the active tab including its iframes

Then if it's an embedded pane we add an embedded attribute to it to trigger the CSS selector mentioned above. After that we can perform the rest of our initialization

Note: in extensions usually, we cannot use inline JavaScript (for security reasons) as well as set up inline event listeners. Consider this while developing

Conclusion

Hope this article will help you with your own project. If you still have any questions left, feel free to ask them in the comment section below. You can also leave a topic suggestion for my next article in the comment section as well

Hope this article will help you with your own project. If you still have any questions left, feel free to ask them in the comment section below. You can also leave a topic suggestion for my next article in the comment section as well

If you like ❤️ this, you can Buy Me a Coffee ☕ or follow me on Twitter 🗨. Thanks for your time ;)

Cheers,
XFox 🦊