foreword
Chrome extensions (also commonly called plug-ins) are also software programs, developed using the web (HTML, CSS, and JavaScript) technology stack. Allows users to customize the Chrome browsing experience. Developers can optimize the experience by adding special effects or functions. For example: efficiency tools, information aggregation, etc. You can check out a wide variety of extensions in the Chrome Store. For example, some translation extensions, JSON formatting extensions, etc. have greatly improved our development or work efficiency. This article aims to help you understand the basic concepts and development process of Chrome extension development. And finally develop a background color extraction extension to deepen the impression of Chrome extension. This article is based on Manifest V3, and most of the content is translated from https://developer.chrome.com/docs/extensions/mv3/. In the end, the extended functions we want to implement are as follows:
basic concept
Manifest
The extension's manifest is the only required file, and the filename must be manifest.json
. The manifest must be placed in the root directory of the extension. It records important metadata, resource definitions, permission declarations and identifies which files are running in the background and on the page.
Service Worker
The extended Service Worker user handles and listens to browser events. Such as jumping to a new page, removing bookmarks, closing tabs, etc. It can use all Chrome APIs, but cannot directly interact with web pages (Content Scripts are required to interact with web pages).
Content Scripts
Content Script can execute JavaScript in the context of the web page. It is also possible to read and modify the DOM of the page they are injected into. Content Script can only use part of the Chrome API. The rest can be accessed indirectly through Service Workers.
Popups and Pages
Extensions can contain various HTML files, such as popups, page options, etc., which can access Chrome APIs.
Develop a simple extension
Let's develop a simple extension of Hello Extensions .
Create manifest.json file
Create a new directory and create a file manifest.json
named .
mkdir hello_extension
cd hello_extension
touch manifest.json
manifest.json
Add the following code to the :
{
"manifest_version": 3,
"name": "Hello Extensions",
"description": "Base Level Extension",
"version": "1.0",
"action": {
"default_popup": "hello.html",
"default_icon": "hello_extensions.png"
}
}
The above JSON file describes the function and configuration of the extension. For example, the action describes the icon of the extension that needs to be displayed in Chrome and the page that pops up after clicking the icon. You can download the icon here to your directory, and then change the name to the one configured manifest.json
in default_icon
.
create html file
One is also configured in the above action default_popup
, and then we create a file hello.html
named and add the following code.
<html>
<body>
<h1>Hello Extensions</h1>
</body>
</html>
load extension
Load unpackaged extensions in development mode.
Type it in the Chrome browser address bar
chrome://extensions
. It can also be opened in the following two ways.
Turn on developer mode
Click to load the unpacked extension
After selecting our folder, it will be displayed on the extension page
fixed extension
Click Pin, and our extension can be displayed in the toolbar. Then we click on the icon to pop up the corresponding page.
reload extension
Let's go back to the code and change the name of the extension to "Hello Extensions of the world!"
{
"manifest_version": 3,
"name": "Hello Extensions of the world!",
...
}
After saving, go back to the extension page, click refresh, and you can see that the name has changed. Do I need to reload the extension every time I make a change? You can refer to the table below.
Extensions | Do you need to reload |
---|---|
The manifest | Yes |
Service worker | Yes |
Content Scripts | Yes (plus the host page) |
The popup | No |
Options page | No |
Other extension HTML pages | No |
View console logs and errors
Console logs
During development, you can debug your code through browser console logs. In the previous code add<script src="popup.js"></script>
<html>
<body>
<h1>Hello Extensions</h1>
<script src="popup.js"></script>
</body>
</html>
Create a file popup.js
named and add the following code:
console.log("This is a popup!")
Next:
refresh extension
open the popup
right click popup
Select Inspect
Switch to the Console tab in the developer tools.
Error logs
Below we modify popup.js
, remove a quotation mark
console.log("This is a popup!) // ❌ 错误代码
After refreshing, and then click to open the extension, you can see the error button appears. Click the error button to view the specific error information.
Extended project structure
There are many ways to expand the project structure, but manifest.json
the file must be located in the root directory, the following is a structure example.
Content Script
Content Script runs in the context of the web page. Through the standard DOM, Content Script can read the details of the page accessed by the browser, modify it, and pass this information to the parent extension.
Ability to understand Content Script
Content Script can directly use part of chrome API, such as:
i18n
storage
runtime:
connect
getManifest
getURL
id
onConnect
onMessage
sendMessage
Others can be implemented by sending messages. Content Script can access the files in the extension after declaring them as Web Accessible Resources. Content Script runs in an independent environment, and it can modify its JavaScript environment without conflicting with pages or other extended Content Scripts.
<html>
<button id="mybutton">click me</button>
<script>
var greeting = "hello, ";
var button = document.getElementById("mybutton");
button.person_name = "Bob";
button.addEventListener(
"click",
() => alert(greeting + button.person_name + "."),
false
);
</script>
</html>
Content Script Injection
There are three methods of Content Script injection, namely static declaration, dynamic declaration, and programming injection. Static declaration is relatively simple, just need to content_scripts
configure . Note that matches
the field to indicate which pages need to run the Content Script script.
"content_scripts": [
{
"matches": ["https://*.google.com/*"],
"css": ["styles.css"],
"js": ["content-script.js"]
}
],
The main usage scenario of dynamic declaration is when it matches
is not clear. Programming injection needs to be used in response to events or in some specific occasions. Our final example uses static declarations.
Service Worker
Chrome extensions are event-based programs that modify or enhance the browsing experience of the Chrome browser. Events are triggered by the browser, such as navigating to a new page, deleting a bookmark or closing a tab. The extension listens to these events through scripts in the Service Worker. Then execute specific instructions. The Service Worker is loaded when needed and unloaded when it goes to sleep. for example:
The extension is installed for the first time or updated to a new version
An extended event is fired
Content Script or other extension sent a message
Once the Service Worker is loaded, the Service Worker will remain running as long as there are events. Once idle for 30 seconds, the browser stops it. The Service Worker remains dormant until an event it listens to occurs, at which point it executes the corresponding event listener, then idles and unloads.
Service Worker logs can be viewed here
Register Service Worker
"background": {
"service_worker": "background.js"
},
Initialize the extension
chrome.runtime.onInstalled.addListener(function (details) {
console.log("onInstalled event has been triggered with details: ", details);
// 检查安装、更新或卸载的原因
if (details.reason == "install") {
// 在安装扩展时执行的代码
} else if (details.reason == "update") {
// 在更新扩展时执行的代码
} else if (details.reason == "uninstall") {
// 在卸载扩展时执行的代码
}
});
set monitor
/**
* 注意需要声明权限
*/
chrome.bookmarks.onCreated.addListener(function (id, bookmark) {
console.log(
"Bookmark created with title: " +
bookmark.title +
" and url: " +
bookmark.url
);
});
filter events
/**
* 注意需要声明 webNavigation 权限
*/
chrome.webNavigation.onCompleted.addListener(() => {
console.info("The user has loaded my favorite website!");
});
All events are printed when unfiltered. Different events correspond to different functions, and you need to select the appropriate event to monitor.
Service Worker communicates with Content Script
We can pass the event of clicking the extended tab chrome.tabs.sendMessage
and register it in the Content Script chrome.runtime.onMessage.addListener
to receive it .
Color extraction extension development
Based on the above knowledge points, we need to implement the following functions: 1. Click the extension button in the navigation bar to pop up a panel displaying details 2. Click the mouse on the page element on the current page to display the corresponding background color on the pop-up panel 3. Click to copy The button can copy the background color of the current element
Here we only list the core code as follows:
manifest configuration
{
"manifest_version": 3,
"name": "EasyColor",
"description": "Chrome extension for obtaining color in an easy way",
"version": "0.0.1",
"action": {
"default_icon": "images/icon-48.png"
},
"icons": {
"16": "images/icon-16.png",
"32": "images/icon-32.png",
"48": "images/icon-48.png",
"128": "images/icon-128.png"
},
"background": {
"service_worker": "background.js"
},
"content_scripts": [
{
"matches": ["http://*/*", "https://*/*"],
"css": ["css/styles.css"],
"js": ["scripts/content.js"],
"run_at": "document_start"
}
],
"web_accessible_resources": [
{
"resources": ["/pages/panel.html"],
"matches": ["http://*/*", "https://*/*"]
}
]
}
Click the extension button in the navigation bar to pop up a display panel
First, service_worker
in , we define a background.js to listen to the extension click event and send it to content_scripts.
chrome.action.onClicked.addListener(function (tab) {
//open pages
chrome.tabs.sendMessage(tab.id, {
action: "EVENT_PANEL_OPEN",
});
});
Listen to EVENT_PANEL_OPEN
the event and add an iframe to the current page to display the panel.
chrome.runtime.onMessage.addListener((req, sender, sendResp) => {
const data = req;
if (data.action === "EVENT_PANEL_OPEN") {
let easyPanel = document.getElementById(easyPanelId);
if (easyPanel == null) {
easyPanel = document.createElement("iframe");
easyPanel.id = easyPanelId;
easyPanel.src = chrome.runtime.getURL("../pages/panel.html");
easyPanel.style.width = "100%";
easyPanel.style.height = "100%";
easyPanel.style.borderRadius = "20px";
easyPanel.style.border = "none";
const container = document.createElement("div");
container.id = easyContainerId;
container.style.width = "200px";
container.style.height = "250px";
container.style.position = "fixed";
container.style.top = "10px";
container.style.right = "10px";
container.style.zIndex = "10000";
container.style.boxShadow = "3px 2px 22px 1px rgba(0, 0, 0, 0.24)";
container.style.borderRadius = "20px";
container.appendChild(easyPanel);
document.body.appendChild(container);
}
document.addEventListener("mousemove", handleMouseMove);
document.addEventListener(
"click",
function (e) {
e.stopPropagation();
e.preventDefault();
return false;
},
true
);
}
});
Click to display the corresponding color
Add a click event to content_scripts to get the background color of the current element, and then pass it to the iframe for display.
document.addEventListener("mousedown", function (e) {
let easyPanel = document.getElementById(easyPanelId);
if (easyPanel == null) {
return;
}
const cpStyle = window.getComputedStyle(e.target);
easyPanel.contentWindow.postMessage(
{
type: "computedStyle",
data: JSON.stringify({
color: cpStyle.color,
backgroundColor: cpStyle.backgroundColor,
}),
},
"*"
);
});
The above is the core code of the element color selection plug-in we implemented. For more details, please refer to: https://github.com/yangpeng7/ChromeExtensionBestPractice
reference resources
https://developer.chrome.com/docs/extensions/mv3/
- END -
About Qi Wu Troupe
Qi Wu Troupe is the largest front-end team of 360 Group, and participates in the work of W3C and ECMA members (TC39) on behalf of the group. Qi Wu Troupe attaches great importance to talent training, and has various development directions such as engineers, lecturers, translators, business interface people, and team leaders for employees to choose from, and provides corresponding technical, professional, general, and leadership training course. Qi Dance Troupe welcomes all kinds of outstanding talents to pay attention to and join Qi Dance Troupe with an open and talent-seeking attitude.