Chrome Extension Development Guide

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:

98c90306f2e5830a8d0b6026d4f99a59.gif

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.jsonnamed .

mkdir hello_extension
cd hello_extension
touch manifest.json

manifest.jsonAdd 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.jsonin default_icon.

create html file

One is also configured in the above action default_popup, and then we create a file hello.htmlnamed 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.

3fe8eae40e38e5edb14b740297592713.pnga1aa543d6406465695deac54cdb993ef.png

  • Turn on developer mode

d4b82e1fbfd9c5497f04e60ec95c7718.png
image.png
  • Click to load the unpacked extension

9e334e86b2a212b9cd9fb2120ef3888e.png43858a3696f641488669864c2d2edc31.pngAfter selecting our folder, it will be displayed on the extension page9564deb1ca2ae7acfb003ffbd552167a.png

fixed extension

261ba3dd6c0b867895bd5f40a1d4a113.pngClick Pin, and our extension can be displayed in the toolbar. Then we click on the icon to pop up the corresponding page.2a076dc4c14ff58f0295cfb22abe03a7.png

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. 72a56dc28107d94534eb6a2c83c4c8f5.pngDo 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.jsnamed and add the following code:

console.log("This is a popup!")

Next:

  1. refresh extension

  2. open the popup

  3. right click popup

  4. Select Inspect

719c513b73bd86f64a3296e98427434e.png
image.png
  1. Switch to the Console tab in the developer tools.

c3e12073221f2d325d613c9438e79ec6.png
image.png

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. 20cc4fb8ecca0db7e5b6d9d9d0c28d1b.pngClick the error button to view the specific error information.2197de4416e564902b423ea9e16da634.png

Extended project structure

There are many ways to expand the project structure, but manifest.jsonthe file must be located in the root directory, the following is a structure example.84cb5d0b359ed5520ed2be23cc211acf.png

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>

ba3234c89de0c488dfc17c73c19fb20c.png0c2d0da5fe7d501454b47a9b20095f1a.png

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_scriptsconfigure . Note that matchesthe 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 matchesis 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 here19e56e2761b4c33bb2b04a3b02ebef86.png

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") {
    // 在卸载扩展时执行的代码
  }
});
ca38136c4296540c0a0cef9d97ae230b.png
image.png

set monitor

/**
 * 注意需要声明权限
 */
chrome.bookmarks.onCreated.addListener(function (id, bookmark) {
  console.log(
    "Bookmark created with title: " +
      bookmark.title +
      " and url: " +
      bookmark.url
  );
});
ea660ba23d3154545797c38ea00bde84.png
image.png

filter events

/**
 * 注意需要声明 webNavigation 权限
 */
chrome.webNavigation.onCompleted.addListener(() => {
  console.info("The user has loaded my favorite website!");
});

bd6e18bd96754e5e7ae4b5ae6fe0be39.pngAll 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.sendMessageand register it in the Content Script chrome.runtime.onMessage.addListenerto 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_workerin , 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_OPENthe 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.

ac7d6df2700b8103827b195d9d66ebe9.png

Guess you like

Origin blog.csdn.net/qiwoo_weekly/article/details/130234301