preface
Before I always wanted to know some knowledge about the Google plug-in, through the Google plug-in can better realize the Google debugging tools, just need to share, recently this two weeks to learn and understand the Google plug-in, and then wrote the article, write I know and some thinking. At the same time, I also want to use Google plug-in to write some small tools, not only learn new things, but also have a certain interest. Of course, because of time reasons, if the author of this piece of understanding is not correct, welcome criticism ~
What is a Google Plugin
Google Plugin, full name Google Browser extension. What is Google Chrome Extension? The official explanation is as follows:
Extensions allow you to add features to Chrome without delving into native code. You can create new extensions for Chrome using the core technologies you are already familiar with in web development (HTML, CSS, and JavaScript).
The students who have doubts will ask why people are still called Google plug-in, which is just like what Lu Xun said: there is no way in the world, and when more people walk, there will be a way. Google Chrome extension originally is not Google plug-in, Google plug-in should be the bottom of the browser things, but too many people, so this article also uses the Google plug-in to collectively refer to Google Chrome extension.
The basic use
The following is a brief introduction of the main components of Google Plug-in. At present, the popular version of Google Plug-in is version 2.0. All the following instructions are based on version 2.0, version 3.0 is easier than version 2.0.
The configuration file
The core file of the Google plugin is the manifest.json (manifest) file. The manifest.json file has the following basic Api:
{"name": "Chrome Extension ", "version": "1.0.0"," Manifest_version ": 2, "description": "A litlle chrome extension demo" }Copy the code
It contains the name, version, and related description of the written Google plug-in, where manifest_version represents the manifest file version. Manifest.json is the core part of Google plug-in. The author believes that this file is equivalent to an entry configuration file for the plug-in. The development only needs to configure the corresponding JS file in this file and call the Api provided by Google Browser to achieve the purpose of improving the plug-in.
Basic Usage Api
There are many more apis in the listing file, but here are just a few that I think are important to get a sense of how Google plug-ins are developed.
- browser_action
{... "browser_action": { "default_icon": { "16": "images/get_started16.png", "32": "Images /get_started32.png"}, "default_title":" Google stroking translation ", "default_popup": "popup.html"},... }Copy the code
Browser_action sets the name of the icon in the upper right corner of the browser. Default_popup allows you to configure a small window that appears when you click the icon, where you can do some temporary things.
- permissions
{... "permissions": [ "activeTab", "storage", "tabs", "contextMenus" ], ... }Copy the code
Permissions can be configured with Google Plugin permissions, such as contextMenus (right-click menu), Tabs (Tabs), and storage (local storage).
- content_scripts
{... "content_scripts": { "matches": ["<all_urls>"], "css": ["content/content_script.css"], "js": ["content/content_script.js"] }, ... }Copy the code
Content-scripts, which is a form of Google plugin that injects scripts to pages (even though it is called Script, it can also include CSS), makes it easy to configure javascript and CSS to a given page.
- background
{... "background" : {" scripts ": [" background. Js]", "persistent" : false},...}Copy the code
Background is a resident page that has the longest life cycle of any type of page in the plug-in. It opens with the browser and closes with the browser, so it usually places global code that needs to be run all the time, run on startup, in the background.
The author also draws a distribution of the above mentioned scripts in the browser, as shown below:
Above, after introducing the basic and important Api of Google Plugin manifest file, interested students can start to write a few simple tools to realize their lofty ambitions and ideals, and sublimate their noble soul. Accordingly, THE author also shares an interesting Google plug-in tool implementation process, through the development of this tool can also deepen the understanding of Google plug-in.
precondition
Because some students do not quite know how to develop Google plug-in, or to say the preconditions. First you need to open the administrative extension and open developer mode. Click the “load decompressed program” button to load the local Google plug-in. If the code is updated during development, you need to refresh the loaded plug-in. Click “close” and then open it again without refreshing the development page.
Google word translation plugin
The most frequently used Google plug-in is the translation tool. For the English words or sentences I don’t understand on the web page, I can directly select them with the mouse and translate them into Chinese easily and quickly. So how does the Google Chrome translation tool work?
thinking
How to do a dash word translation plug-in, the first thing to consider are the following:
- How to achieve translation effect
- How do we select the elements we need
- How do I display the cross word translation panel after selecting the element
- All browser tabs need to support translation effects
After thinking about the above points, with these doubts, THE author in the following one answer, but also listed some points encountered.
Delimit word translation panel
First of all, regardless of the function of the plug-in, write the style of the panel for the translation of the underline word, and achieve the following effect:
The HTML code is as follows:
<span class="close">X</span></header> <main> <div class="source"> <div class="title">英文</div> <div class="content">test</div> </div> <div class="result"> <div class="content">... </div> </div> </main> </div>Copy the code
Once you’ve done the simple styling above, start thinking about how to display the cross word translation panel on the current page of your browser. For Google Chrome, the interaction on a web page is content_scripts, which introduces the JAVASCRIPT or CSS required for the cross word translation panel to generate the current panel.
Second, configure content_scripts in the configuration file, introduce JS files, and dynamically generate DOM elements. The general idea is to generate a translation panel by listening to the release of the mouse, add opacity style on top of the generated elements, and use Google’s free translation Api for translation. The code is as follows:
// manifest.json { ... "content_scripts": { "matches": ["<all_urls>"], "css": ["content_script.css"], "js": ["content_script.js"] }, "permissions": [ "activeTab" ], ... } // content_script.js class TranslatePanel { createPanel = () => { let wrapper = document.createElement('div') Wrapper. InnerHTML = '<header> Google delimit translation plugin <span class="close">X</span></header> <main> <div class="source"> <div Class ="title"> English </div> <div class="content">test</div> </div> <div class="result"> <div class="title"> Simplified Chinese </div> <div class="content">... </div> </div> </main> ` wrapper.classList.add('translate-panel') wrapper.querySelector('.close').onclick = () => { this.wrapper.classList.remove('show') } document.body.appendChild(wrapper) this.wrapper = wrapper } showPanel = () => { this.wrapper.classList.add('show') } translateSelect = (content) => { const source = this.wrapper.querySelector('.source .content') const result = this.wrapper.querySelector('.result .content') source.innerHTML = content result.innerHTML = 'In translation... ' fetch(`https://translate.google.cn/translate_a/single?client=at&sl=en&tl=zh-CN&dt=t&q=${content}`) .then(res => res.json()) .then(res => { result.innerHTML = res[0][0][0] }) } locationPanel = (target) => { this.wrapper.style.top = target.y + 'px' this.wrapper.style.left = target.x + 'px' ### } } let panel = new TranslatePanel() panel.createPanel() Window.onmouseup = (target) => {// Get the selected content const Content = window.getSelection().toString().trim() if (! content) return panel.locationPanel({ x: target.pageX, y: target.pageY }) panel.translateSelect(content) panel.showPanel() }Copy the code
In the above process, the author used Google’s free translation excuse, but this interface still has some problems according to the current use, we temporarily put aside. So now, the slide word translation panel has been basically written.
Script communication
Every time a word is selected, it will trigger the word translation function. At this time, there is an urgent need for a switch to control the translation function. This switch can be placed on the popup script. The implementation of the specific style will not be introduced, but mainly look at the HTML structure.
The basic effect is as follows:
<div class="switch-wrapper"> <div class="switch-desc"> Whether to enable delimit translation </div> <input type="checkbox" class="switch" /> </div>Copy the code
In the meantime, now that we have panels and underline translation panels, let’s think about how to communicate between popup scripts and content_script scripts. First of all, in the popup script, we need to check whether there is a storage state for cross word translation when opening the window, and we need to store it when the state changes, and then send the request under the current Tab.
// popup.js
let switchWrapp = document.querySelector('.switch')
chrome.storage.sync.get(['checked'], (target) => {
if (target) {
switchWrapp.checked = target.checked
}
})
switchWrapp.onclick = (e) => {
chrome.storage.sync.set({ checked: e.target.checked })
chrome.tabs.query( {active: true, currentWindow: true }, (tabs) => {
chrome.tabs.sendMessage(tabs[0].id, { checked: e.target.checked })
})
}
Copy the code
Chrome.storage in the code above can be used to store data and track data. Storage. sync allows chrome to synchronize data between tabs without storing data in the background. Storage also has a number of apis such as onChanged to listen to storage data changes. Content_script.js needs to add a listening event after sending the status to enable or disable strobe translation.
Content_script.js let checked = false window.onmouseup = (target) => {··· if (! content || ! Checked) return ···} Chrome.storage.sync.get (['checked'], (target) => { if (target) checked = target.checked }) chrome.runtime.onMessage.addListener((target) => { if (target) { checked = target.checked } })Copy the code
In the development process, this operation can be completed on the current Tab, but when multiple tabs are opened, there will be the situation that the translation panel cannot be displayed when the translation is opened. After thinking about the above, the author should store checked at this time. It should not be in a content_script script.
Content_script.js let panel = new TranslatePanel() panel.createpanel () window.onmouseup = (target) => {// Get the selected content const content = window.getSelection().toString().trim() if (! content) return window.chrome.storage.sync.get(['checked'], (result) => { if (result.checked) { panel.locationPanel({ x: target.pageX, y: target.pageY }) panel.translateSelect(content) panel.showPanel() } }) } chrome.runtime.onMessage.addListener((target) => { if (target.type == 'CHECKED') { chrome.storage.sync.set({ checked: target.checked }) } })Copy the code
The popup script communicates with the content_script script, and the translation plugin can turn the translation function on or off using the popup button. In the same way, other modules can communicate with each other in this way, except that other scripts communicate with content_script by using tabs and looking up the current Tab to send the request.
Right click to the translation page
When turning off delimit translation, you can no longer directly translate the selected content is not very friendly, this time can be right click when the translation menu item. Because this part of the content needs to be there all the time and it needs to be in the background.
/ / backgrond. Js / / when extension first installation, update to the new version or Chrome update to new version produced in Chrome. Runtime. OnInstalled. AddListener (() = > { Chrome. ContextMenus. Create ({" id ":" SELECT_TRANSLATE ", "title" : "% s" translation, "contexts" : ["selection"] }) }) chrome.contextMenus.onClicked.addListener((target) => { if (target.menuItemId == 'SELECT_TRANSLATE') { chrome.tabs.create({url: `https://translate.google.cn/?sl=en&tl=zh-CN&text=${target.selectionText}&op=translate`}) } })Copy the code
Cross-domain problem
In the process of development, some students also see a problem, such as Google’s translation Api needs the same source to call the interface normally, and then only in the Google Translate page using delimit translation, scene was very embarrassing…
So, normally speaking, this cross word translation is also very unreasonable. Next, we need to solve this cross-domain problem.
At that time, the author tried to use JSONP, that is, to use embedded scripts to cross domains. However, there were still some problems, mainly because the interface of Google translation does not support callback functions. Meanwhile, I also checked some materials and found that background can be notified in content_script. Background calls the Google Translate Api to avoid this situation, mainly because background is very high, can call almost any Chrome extension Api, and it can be unlimited cross-domain. That is, you can access any website across domains without requiring the other party to set CORS. The specific code added is as follows:
// content_script.js translateSelect = (content) => { const source = this.wrapper.querySelector('.source .content') Const result = this. Wrapper. QuerySelector ('. The result. The content ') source. The innerHTML = the content result. The innerHTML = 'translation... ' chrome.runtime.sendMessage({ type: 'QUERY_TRANSLATE', queryContent: content }, (res) => { result.innerHTML = res[0][0][0] }) } // background.js chrome.runtime.onMessage.addListener((request, sender, callBack) => { if (request.type == 'QUERY_TRANSLATE') { fetch(`https://translate.google.cn/translate_a/single?client=at&sl=en&tl=zh-CN&dt=t&q=${request.queryContent}`) .then(res => res.json()) .then(res => { callBack(res) }) return true } })Copy the code
Listening events that send messages in background return true to keep the message channel open with content_script and send requests asynchronously.
Now think about it, if you use the background of the plug-in, you can go to cross-domain to request some excuses. If it is not used properly, it feels very dangerous. You can get some information from other websites.
Points to be improved
- Support translation of other languages. The Google Translate interface has two apis, SL (the language before the text is translated) and TL (the language into which the text needs to be translated), which support the translation of other languages by changing the corresponding values;
- Perfect style, to achieve the first selected icon in translation. Adding one more step feels more friendly to the interaction, without having to switch the operation;
The code structure
After introducing the React Developer plugin, I originally planned to share another development tool about Google DevTool, which is similar to React Developer Tools. However, due to the lack of time, there are a lot of points involved. At the same time, access to a lot of data for this piece of introduction is shallow, so decided to focus on introduce cross word translation, from the development of the cross word translation can make readers more quickly realize that Google plug-in, some of the Google browser, extrapolate, if for devtool tools plug-in development interested students can also go to look at. In addition, some students may think that the current development efficiency is a little low. At present, The development of Google plug-in can also be developed based on React + ANTD, which can achieve the effect of efficient and fast development of a plug-in.
At the end
When learning the Google plug-in, THE author encountered some problems, such as less documents, official documents are in English and often 404, but fortunately, Google Browser provides a lot of Api, the author also felt a lot of fun when writing the plug-in. This article is still written more easy to understand, if there is something wrong or unclear place, welcome to raise your hand to speak
More and more
- The official document: developer.chrome.com/docs/extens…
- React + ANTD scaffolding: github.com/jhen0409/re…
- Full code: github.com/ting0130/ch…