Embedding panel into webpage with WebExtension
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' statesinject-script.js
- will initialize/close pane on specific pagemanifest.json
- standard Chromium extension manifestpane.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 🦊