This tutorial is based on Chrome Extension Manifest Version 2.
The Rundown
We'll have a simple HTML page that allows our user to pick a search engine; this page will be the popup in our Chrome Extension.
In the foreground script we'll listen for when the user copies a piece of text. When they do, we'll get our background script to open a new with the appropriate URL and search parameter.
Let's start.
Our manifest.json
Nothing special here.
{
"name": "Clipboard Search",
"manifest_version": 2,
"description": "Testing clipboard functionality.",
"version": "0.0.0",
"background": {
"scripts":["background.js"]
},
"browser_action": {
"default_popup": "popup.html"
},
"permissions": [
"tabs",
"<all_urls>"
]
}
The only permissions we'll need are the tabs so we can inject our foreground script into specific tabs and \<all_urls> so we can inject our foreground script into specific webpages.
The popup.html
A simple web page.
Nothing complicated here.
We have a select with options, a button for submission, and a div to display their search engine of choice.
<div class="container">
<div class="section1">
<select name="search_engine" id="search_engine">
<option value="" disabled selected>Choose a search engine</option>
<option value="google">Google</option>
<option value="startpage">Start Page</option>
<option value="duckduckgo">Duck Duck Go</option>
<option value="ecoasia">Ecoasia</option>
<option value="bing">Bing</option>
</select>
<button>Select</button>
</div>
<div class="section2">
<div class="search_engine_choice">Your Current Search Engine</div>
</div>
</div>
Here is what we have:
Our foreground script
Not a lot of code here.
document.addEventListener('copy', () => {
navigator.clipboard.readText()
.then(res => {
chrome.runtime.sendMessage({
message: 'search',
payload: `"${res}"`
});
})
.catch(err => console.log(err));
});
We create a listener for the copy event. When triggered, we get the copied material from the clipboard using the readText() method.
We then send the copied text to our background script using the chrome.runtime.sendMessage() method.
Our background script
This is where the bulk of our extension gets written.
Here we have an object that holds all of our search engine strings.
const search_engines = {
google: 'https://www.google.com/search?q=',
startpage: 'https://www.startpage.com/do/dsearch?query=',
duckduckgo: 'https://duckduckgo.com/?q=',
ecoasia: 'https://www.ecosia.org/search?q=',
bing: 'https://www.bing.com/search?q='
}
When our Chrome Extension detects that a user has opened a new tab, we make sure to inject our foreground script into that page.
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
if (/^http/.test(tab.url) && changeInfo.status === 'complete') {
chrome.tabs.executeScript(tabId, { file: './scripts/foreground.js' }, () => {
console.log('The foreground script has been injected.');
});
}
});
In the background listener we listen for the message, "search", from our foreground.
When we receive it, we open up a new tab for our user.
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
if (request.message === 'save_search_engine') {
current_search_engine = request.payload;
sendResponse({ message: 'success' });
} else if (request.message === 'get_current_search_engine') {
sendResponse({ payload: current_search_engine });
} else if (request.message === 'search') {
chrome.tabs.create({
active: true,
url: `${search_engines[current_search_engine]}${request.payload}`
});
}
});
Notice how the url property has a value constructed of the search engine of choice plus the search term, the request.payload, amended to the string.
That's the basics of how this extension works.
You can get the source files here.
Comments