preface
The first article of 2020, Technology comes from life, as a coder, I think the most proud thing is probably to solve a real visible problem. Some time ago, when I was sharing with my team, I booked a large training room, but the computer was far away, so I needed a page-turning pen. But as the New Year was approaching, my pocket was tight and I couldn’t afford to buy one, so I decided to develop one by myself.
Since MY powerpoint presentation was on Slides.com, the first thing THAT came to my mind was a Chrome plugin. So, this article will document the implementation of the “flip pen” plugin, and a brief introduction to the Chrome plugin.
Introduction to Chrome Plug-in
This part is a brief introduction to the Chrome plug-in. It mainly introduces the following aspects:
-
Chrome plugin component
-
API Module Introduction
-
Development and commissioning
-
The installation
Main component
Let’s start with a few important components of the Chrome plugin:
-
Background Scripts
-
UI Elements
-
Popup.html
-
Options.html
-
Content Scripts
-
Manifest.json
Background Scripts
Background Scripts run with the browser and handle plugin-related events, such as:
-
The plug-in is installed or updated for the first time
-
Listen for messages in popup or Content Scripts
UI Elements
UI Elements include the Logo in the upper right corner, right-click on the menu, and click on the pop-up page provided by the Logo. We can control their presentation via Chrome’s API, such as:
-
Add a tag to the Logo
-
The icon is dimmed based on whether the current page is available
-
Set different size ICONS
-
Tooltip
-
Right-click menu
-
Popup (described below)
Popup.html
As shown in the picture above, when you click on each plug-in, the popover is actually an HTML file, which is no different from normal HTML. We can also write styles, reference JS processing logic and so on. withBackground Scripts
Mutual communication:
Content Scripts
Content Scripts are js to be injected into the page to run. We can do some page operations here, such as dom manipulation, websocket connection, etc. In the same way,content scripts
Can be withbackground scripts
.popup.js
Mutual communication:
Options.html
This page provides some plug-in configuration information, is also a common HTML, specific need users to configure what, we need to achieve. This page entry: Chrome :// Extensions / -> find the appropriate plugin -> extension options.
Manifest.json
The browser needs to know where our script file is, as well as some other configuration information, which requires us to provide a menifest. Json configuration file, the browser provides us with a lot of configuration information, reference chrome official website example, you can use which to query.
{ // Required "manifest_version": 2."name": "My Extension"."version": "versionString", // Recommended "default_locale": "en"."description": "A plain text description"."icons": {... }, // Pick one (or none)"browser_action": {... },"page_action": {... }, // Optional"action":... ."author":... ."automation":... ."background": { // Recommended "persistent": false, // Optional "service_worker":}."chrome_settings_overrides": {... },"chrome_ui_overrides": { "bookmarks_ui": { "remove_bookmark_shortcut": true."remove_button": true}},"chrome_url_overrides": {... },"commands": {... },"content_capabilities":... ."content_scripts": [{...}], "content_security_policy": "policyString"."converted_from_user_script":... ."current_locale":... ."declarative_net_request":... ."devtools_page": "devtools.html"."event_rules": [{...}], "externally_connectable": { "matches": ["*://*.example.com/*"]},"file_browser_handlers": [...]. ."file_system_provider_capabilities": { "configurable": true."multiple_mounts": true."source": "network" }, "homepage_url": "http://path/to/homepage"."import": [{"id": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}]."incognito": "spanning, split, or not_allowed"."input_components":... ."key": "publicKey"."minimum_chrome_version": "versionString"."nacl_modules": [...]. ."oauth2":... ."offline_enabled": true."omnibox": { "keyword": "aString" }, "optional_permissions": ["tabs"]."options_page": "options.html"."options_ui": { "chrome_style": true."page": "options.html" }, "permissions": ["tabs"]."platforms":... ."replacement_web_app":... ."requirements": {... },"sandbox": [...]. ."short_name": "Short Name"."signature":... ."spellcheck":... ."storage": { "managed_schema": "schema.json" }, "system_indicator":... ."tts_engine": {... },"update_url": "http://path/to/updateInfo.xml"."version_name": "aString"."web_accessible_resources": [...]. }Copy the code
The API module
Now that I’ve covered some of the most important components of the Chrome plugin, I’m sure you’ve got a general idea of what code to write where. Getting back to the topic, the easiest way to understand what the Chrome plugin can do is to look at the API. Here are some of the most important modules:
-
AccessibilityFeatures: invoke the accessibilityFeatures provided by Chrome, such as amplifiers, voice, etc.
-
Alarms: Message notification related.
-
Bookmarks: Bookmarks are related.
-
BrowserAction: Plugin icon related.
-
BrowsingData: Browser data processing, such as periodically clearing local data such as cookies.
-
CertificateProvider: Certificate related.
-
Commands: Shortcut key related.
-
ContentSettings: Customizes browser Settings, such as disabling cookies for a web site.
-
ContextMenus: Handles the browser’s right menu.
-
Cookies: Cookie related, such as modifying or monitoring changes.
-
Debugger: Custom Chrome debugging.
-
DeclarativeContent: Custom plug-in availability state
-
Devtools: Developer tools related
-
Downloads: Chrome downloads
-
Storage: local data of the plug-in
-
Tabs: indicates that the browser TAB is associated
-
TTS /ttsEngine: voice engine
-
VpnProvider: indicates VPN related
-
WebRequest: webRequest related
-
System. The memory/system. The CPU/system. Storage: device memory, CPU, hard disk information, etc
-
… …
Development and commissioning
I believe you can see the above content, in fact, plug-in development is very simple, we are familiar with HTML, CSS, javascript can solve, just need to write the above introduced several components: Background scripts, content scritps, popup. HTML, options. HTML, and then provide a manifest.json configuration file.
For this common project structure, there must be a common code template. Here is a cross-browser plug-in development template that we can clone and develop directly inside.
Plug-in to debug a bit of trouble, for background scripts and popup. HTML, content scripts we need to debug respectively in three different ways.
-
Background Scripts: We need the plugin management page (
chrome://extensions
), click the “background picture” button of the corresponding plug-in, and the developer tool we are familiar with will pop up, as shown in the picture: -
Popup. HTML: Right click on the popover -> Check, as shown:
-
Content Scritps: Since content scritps are injected into the page, we can open any page and then open the developer tools.
The installation
For developed plug-ins, there are three ways to install them:
-
Publish to the Chrome Store, of course, in a way that most users in The country can’t access
-
Package it as a.crx file
-
Import the source folder directly
You need to manually install the last two methods as follows:
-
Open a new browser TAB and type: Chrome :// Extensions in the address bar
-
Open developer mode in the upper right corner
-
Import the plugin source folder by dragging directly into the.crx file or clicking “Load unzipped extensions” in the upper left corner.
Flip Pen Plug-in Development
The above briefly introduces several concepts of Chrome plug-in, as well as the development and debugging way, I believe we have a simple understanding, then we go back to consider, to achieve the page turning pen plug-in, what need to consider? The first thing we need to do is figure out how the user is going to use it, and I’ve made a video here that shows the process.
Having identified the usage process, what do we need to consider? Page turning requires instant messaging, that is, websocket. Let’s think about the process:
-
The user clicks on the plug-in Logo
-
The current page establishes a Websocket connection, notifying the server to create a one-to-one connection
-
The server generates a unique socketId and records it, and the socketId can also be retrieved from Content scripts. The server generates a link with the socketId parameter and sends it to popup.html
-
Popup.html receives the message, generates a TWO-DIMENSIONAL code and displays the RECEIVED URL
-
The mobile phone scans the code to enter the remote control page to send a message. The message body must contain the socketId parameter in the link
-
The server receives the message and sends it to the connection for the specified socketId
The process is clear, it is easy to achieve, let’s step by step.
Implement Websocket service to ensure one-to-one connection
IO. The only thing to note is that we need to ensure one-to-one connections so that the two pages don’t interact with each other. Here we define a global variable that holds all socket connections and clears them when disconnecting. The relevant codes are as follows:
var sockets = {}; io.on('connection'.function(socket) { socket.on('message'.function(data) { console.log(data); if (sockets[data.id]) { sockets[data.id].emit('message', data.data); }}); // Create session socket.on('new', () => { const id = socket.id; sockets[id] = socket; }); Check / / remove the socket.'disconnect', () => { const id = socket.id; if (sockets[id]) { delete sockets[id]; } });});Copy the code
Implement Websocket connection and keyboard messages in Content Scripts
Following the process described above, we need to implement the following functions in Content Scripts:
-
Receive a message from popup.html and establish a WebSocket connection
-
Get the established socketId, generate a link with the socketId parameter, and send it to popup.html
-
To achieve the page to send up, down, left, right keyboard messages
The relevant codes are as follows:
import ext from "./utils/ext"; import io from"socket.io-client"; const conf = { up: 38, down: 40, left: 37, right: 39}; const URL ="https://pen.zhengqingxin.com"; var flipPen = {};function onRequest(request) { if (request.action === "process-page") { if (flipPen.socket) { chrome.runtime.sendMessage({ url: flipPen.url }); return; } var socket = io(URL); socket.on("connect".function// Generate a link with the socketId parameter and send it to popup.html socket.emit() {// generate a link with the socketId parameter and send it to popup.html socket.emit("new"); var rcUrl = `${URL}/index.html? id=${socket.id}`; chrome.runtime.sendMessage({ url: rcUrl }); flipPen = { url: rcUrl, socket }; // Implement sending up, down, left, right keyboard messages to the page socket."message".function(data) { if (data.action) { var keyCode = conf[data.action]; var evt = new KeyboardEvent("keydown", { keyCode: keyCode, which: keyCode }); document.dispatchEvent(evt); }}); }); }} / / receiving from the popup. HTML the news, establish connection ext runtime. OnMessage. AddListener (onRequest);Copy the code
Generate a QR code in popup.html
Here we need to deal with two things:
-
Send a message to Content Scripts notifying its users that they clicked on our plugin and can set up socket connections
-
Receive the link sent back, generate the TWO-DIMENSIONAL code and display
The relevant codes are as follows:
import ext from "./utils/ext"; import QRCode from"qrcode"; chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) { const { url } = message; var canvas = document.getElementById("canvas"); QRCode.toCanvas(canvas, url); }); ext.tabs.query({ active:true, currentWindow: true }, function(tabs) { var activeTab = tabs[0]; chrome.tabs.sendMessage(activeTab.id, { action: "process-page"}); });Copy the code
Remote control page
The remote control page is even simpler. We just need to establish websocket connection and send the corresponding message when pressing the direction button. Note that the received socketId should be brought with it, so that the server can know which page the remote control controls. I’m not going to do the code here.
Write in the last
Here is a list of page-turning pen plug-in implementation process, is it very simple? It’s estimated to be less than 100 lines of code, but the full code is available here. If you want to use the page-turning pen plug-in directly, you can also download it directly.
The above is the introduction of chrome plug-in and the implementation of the pen plug-in introduction, the article if there is an error welcome criticism.
Reference: https://developer.chrome.com/extensions https://developer.chrome.com/extensions/api_index
Author’s brief introduction
Zheng Qingxin is a good future front-end development engineer
———- END ———-
Recruitment information
Good future technology team is testing, background, operation and maintenance, large front-end development and other senior engineer positions, you can search/scan wechat “good future technology” public account to view the “technical recruitment” column for details, welcome interested partners to join us!
Micro front end practice for future magic schools
Children’s English acoustic model training based on TPNN
Practice and research of DIY technology information capture tool
Production and research personnel of the epidemic war, there is no respite