Zero, introduce

This article is to introduce a Chrome browser plug-in implementation process, mainly including:

  1. What is a browser plug-in
  2. Plug-in directory
  3. Plug-in communication
  4. Plug-in to debug
  5. Project implementation
  6. Plug-in release
  7. Reference documentation

What is a browser plug-in

Browser plug-in is a tool for adding new functions based on the original functions of the browser. It is not stand-alone software and needs to be attached to the corresponding browser to function. Major browsers now allow add-ons to enhance and diversify your browser. The development of browser plug-in, in fact, is similar to the development of a Web application, are composed of HTML+JS+CSS, this paper will introduce the implementation of a picture collection function plug-in. The plug-in is mainly used to collect web page pictures and store them to the server.

Plug-in directory

The directory of the Chrome plug-in implemented in this article is shown below:

2.1 the manifest. Json file

There is a manifest.json file in the root directory, which provides a list of functionality and configuration files for the entire plug-in. It is very important and must be placed in the root directory. Manifest_version, name, and Version are indispensable, and Description and ICONS are recommended.

{	
    "manifest_version": 2, // Version of the manifest file, this must be written, and it must be 2"name": "Picture capture"// The name of the plug-in"version": "1.0.0"// The version of the plug-in"description": "This is an image capture plugin.", // Plug-in description"icons": {// Plugin icon"16": "static/img/icon.png"
    		"48": "static/img/icon.png"
        	"128": "static/img/icon.png"}},Copy the code

2.2 Page Template

The template directory is used to place page templates, such as popup.html and background.html.

Popup.html is a window page that pops up when you click on the plug-in icon. The page closes immediately when the focus is removed from the window and is used to interact with the user. In the picture acquisition plug-in provides “preview all pictures” and “display acquisition button” two buttons for users to operate.

{
	 "browser_action": {
        "default_icon": "static/img/icon.png"."default_title": ""."default_popup": "template/popup.html"}},Copy the code

Background-html is a background page, which has the longest life cycle of any type of page in the plug-in. It opens with the browser and closes with the browser. Therefore, background-html usually places the code that needs to be run all the time, run on startup, and run globally in background-html. This can be interpreted as a background script that the plug-in runs in the browser. For example, sometimes the plug-in needs to interact with the server for data synchronization and other operations, which are not perceived by users, so it can be placed in the background page to run this part of the logic.

The background page is specified using the background field of the manifest:

{// 2 ways to specify, if you specify JS, then a background page will be generated automatically"page": "template/background.html"
	// "scripts": ["static/js/background.js"]}Copy the code

2.3 Static Files

The static directory places static files, including images, JS scripts, and CSS styles.

Icon. PNG is the plug-in icon.

Content-script. js is a JAVASCRIPT script that is injected into a Web page by a plug-in. By using the standard DOM, it can read the details of a Web page or modify the DOM structure of a page, and the communication between a Web page and a plug-in can also be realized through it. In the picture acquisition plug-in, mainly used to operate the web page to get the picture.

Popup. js is the JS script of popup. HTML. In the image capture plug-in, the main user collects user interactions and tells Content-script.js to manipulate the web page to capture images.

Background. js is the JAVASCRIPT script of background. HTML. In the picture acquisition plug-in, it is mainly used to store the collected pictures to the server.

Content-script.css is the CSS style that the plug-in injects into a Web page.

Conten-script can be injected through the manifest configuration:

{
	"content_scripts": [{
        "matches": ["<all_urls>"], // <all_urls> matches all addresses"js": ["Static/js/jquery - 1.8.3. Js." "."static/js/content-script.js"], // Multiple js are injected sequentially"css": ["static/css/content-script.css"], / / CSS injection"run_at": "document_end"Document_start, document_end, or document_IDLE, the last one indicates when the page is idle, default document_idle}]}Copy the code

3. Plug-in communication

3.1 Plug-in context communication

Both popup.js and background.js run in the context of the plug-in, and because they run in the same thread, communication between them is relatively simple, with pages calling each other directly to pass information. Such as chrome. The extension. GetViews () method can return to belong to your plugin window object of each activity page lists, and chrome. The extension. GetBackgroundPage () method can return to the page background.

// background.js
var views = chrome.extension.getViews({type:'popup'}); // Return the popup objectif(views.length > 0) {
    console.log(views[0].location.href);
}
function test(){
	console.log('I am background');
}

// popup.js
var bg= chrome.extension.getBackgroundPage(); bg.test(); / / access background function of the console. The log (bg) document) body. The innerHTML); // Access the BACKGROUND DOMCopy the code

3.2 Content-Script communicates with the plug-in context

Content-script.js is a script embedded in a Web page, so it actually runs in the context of the Web page and is completely isolated from the plug-in context. It cannot communicate with each other by calling methods like a plug-in context-related page, and it needs communication channels to assist communication. In the image capture plug-in, Content-script.js receives the message from popup.js to capture the web image, and sends the message to background.js to store the image.

Popup.js or background.js sends an active message to content-script.js:

function sendMsgToContentScript(message, callback){
	chrome.tabs.query({active: true, currentWindow: true}, function(tabs){
		chrome.tabs.sendMessage(tabs[0].id, message, function(response){
			if(callback) callback(response);
		})
	})
}

sendMsgToContentScript({type: 'popMsg', value: 'Hi, I'm Popup.'}, function(response){
	console.log('Reply from Content:' + response);
})
Copy the code

Content-script.js Receives messages:

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse){
	if(request.type === 'popMsg'){		console.log('Received message from Popup:' + request.value);
	}
	sendResponse('This is Content-script, I got your message');
})
Copy the code

Content-script.js sends a message to popup.js or background.js:

chrome.runtime.sendMessage({type: 'contentMsg', value: 'Hello, I'm content-script'},function(response){
	console.log('Received a reply from the background:'+ response);
})
Copy the code

Popup.js and background.js receive messages:

	chrome.runtime.onMessage.addListener(function(request, sender, sendResonse){
		console.log()
		if(request.type === 'contentMsg'){
			console.log('Received message from Content-script:' + request.value);
		}
		sendResonse('I'm backstage and I got your message. ');
	})
Copy the code

The popup popup page must be open before content-script.js sends a message to popup. Otherwise, background.js is used as a relay.

4. Plug-in debugging

4.1 Installing the Plug-in development Package

1. Open the plug-in management page. You can also enter Chrome :// Extensions in the address bar to access the plug-in management page.

2. Select Developer mode. After this option is selected, the plug-in application folder can be directly loaded. Otherwise, only the compressed file in. CRX format can be installed, and plug-in updates cannot be synchronized in time.

3. Plug-in update. Any changes to your code during development will require you to reload the plugin. Click the update button on the plugin and refresh the page just in case.

4.2 debugging content – script. Js

Content-script.js is a script that runs on a Web page. You can debug it by opening the developer tool of the Web page.

4.3 debugging background. Js

Since background.js and content-script.js do not run in the same context, background.js is not visible to the debug window of a Web page. Debugging background.js requires opening the plug-in debug window. Click “View Template /background.html” of your plugin on the plugin admin page, and the plugin debug window will appear, just like normal Web page debugging.

4.4 debugging popup. Js

Popup.js and background.js are in the same context, but to see popup.js, you need to do one more step:

5. Project realization

5.1 Popup window web page implementation

Popup window web page provides user interface, mainly contains the following functions:

  • Popup. js tells Content-script.js to read the DOM of the Web page, filter out the DOM of the image, and retrieve the image link. Then operate DOM to create a dialog box on the Web page, and put all pictures in the dialog box for centralized preview & collection operations.
  • Popup. js will notify Content-Script to manipulate the DOM of the Web page and add a capture button to the image. Popup. js notifies Content-Script to remove the capture button from the Web page when unchecked.

<! -- popup.html --> <div> <div id="preViewAllImg">
      <img src="https://s10.mogucdn.com/mlcdn/c45406/190219_4949lfk7le758fei1825i6dkd4g9i_40x42.png"<div > <div class="collect_btn_wrap" id="showCollectBtn">
      	<div class="collect_btn">
          <div class="show_collect_check"><img class="collect_check_img" src=""The /></div> page displays the favorites button </div> </div> <scripttype="text/javascript" src=".. / static/js/jquery - 1.8.3. Js. ""></script>
<script type="text/javascript" src=".. /static/js/popup.js"></script> <! -- popup.js --> $(function () {

    function sendMsgToContentScript(message, callback){
        chrome.tabs.query({active: true, currentWindow: true}, function(tabs){
            chrome.tabs.sendMessage(tabs[0].id, message, function(response){
                if(callback) callback(response); })})} $('#preViewAllImg').click(e => {
        sendMsgToContentScript({type: 'REQUEST_PREVIEW_ALL_IMG', title: 'I'm Popup, please grab all loaded images and preview them'}, function(response){
            console.log('I'm Popup, from content:'+ response); }); }); // Whether to display the capture button $('#showCollectBtn').click(() => {
        var src = $('.collect_check_img').attr('src');
        var status = src === ' '; // status: trueAccording to the $('.collect_check_img')[0].src = src === ' ' ? 'https://s10.mogucdn.com/mlcdn/c45406/190219_0728g95i8bkl3i08jic6lhjhh7gae_24x18.png' : ' '; SendMsgToContentScript ({send a message to content-script to show or hide the favorites button for a single itemtype: 'REQUEST_SWITCH_COLLECT_BTN', title: 'This is Popup, please${status? 'Show ':' hide '}Capture button ', Status},function(response){
                console.log('I'm Popup, from content:' + response);
        });
    });
})
Copy the code

5.2 Content-script Insertion script implementation

Content-script listens to the message from popup.js, operates the DOM of the Web page according to the message notification, reads the image link, adds the image capture button, collects the image, and sends a message to the background to inform it of storing the collected image link.

<! -- content-script.js --> chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
    if(request.type === 'REQUEST_PREVIEW_ALL_IMG'){

        console.log('I'm Content-script and received a message from Popup:' + request.title);

        sendResponse('I'm Content-script and have received your message to preview all images');

        PreviewAllImg();

    }else if(request.type === 'REQUEST_SWITCH_COLLECT_BTN'){

        console.log('I'm Content-script and received a message from Popup:'+ request.title); SendResponse (' I'm Content-script, received${request.status ? 'Show ':' hide '}Collect button message ');if(request.status){
            ShowCollectBtn();
        }else{ ClearCollectBtn(); }}else if(request.type === 'COLLECT_RESULT'){
        console.log('I'm Content-script and received a message from background:'+ request.title); SendResponse (' I'm Content-script, received yours${request.title}The news of the `); }}); // Preview all loaded imagesfunction PreviewAllImg(){
    GetAllAttrList('img'['src'.'data-src']).then((res) => { ShowImgPanel(res); })} // Display the capture buttonfunction ShowCollectBtn(){
    $('img').each((index, item) => {
        let src = $(item).attr('src') || $(item).attr('data-src');
        $($(item).parent()).css('position'.'relative');
        $($(item).parent()).find('.collect_img_btn').remove();
        $($(item).parent()).append('<div class="collect_img_btn" data-src="'+src+'" > collection < / div >');

    });
    $('.collect_img_btn').click((e) => {
        e.stopPropagation();
        e.preventDefault();
        let src = $(e.target).data('src');
        chrome.runtime.sendMessage({type: 'SEND_IMG', src: src},function(response){
            console.log('I'm Content-script, and I got a reply from the background:'+ response); })}); } // Clear the collection buttonfunction ClearCollectBtn(){
    $('.collect_img_btn').remove(); } // Display preview image dialog boxfunction ShowImgPanel(list){
    var panelDOM = $('<div id="collect_img_panel">' +
            '<div class="collect_img_panel_close">x</div>' +
            '<div class="collect_img_panel_content">x</div>' +
            '</div>');
        $('body').append(panelDOM);
        $('body').append('<div id="collect_img_panel_mask"></div>');
        let $item = ' ';
        $.each(list, function(index, item) {
            $item = $item + '<div class="collect_img_panel_item">' +
                '<div class="collect_img_panel_item_img" style="background-image: url(' + item + ')"></div>' +
                '<div class="collect_img_panel_item_mask"></div>' +
                '<div class="collect_img_panel_item_btn" data-src="'+ item+'> < div style = "box-sizing: border-box; +
                '</div>';
        });
        $('.collect_img_panel_content').html($item);
        $('.collect_img_panel_item_btn').click((e)=>{
            let src = $(e.target).data('src');
            chrome.runtime.sendMessage({type: 'SEND_IMG', src: src},function(response){
                console.log('I'm Content-script, and I got a reply from the background:'+ response); })}); $(".collect_img_panel_close").click(function() {$('#collect_img_panel').remove();
            $('#collect_img_panel_mask').remove(); }); } // Collect all qualified objects based on tags and attributesfunction GetAllAttrList(obj, attrArr){
    return new Promise((resolve) => {
        let list = [];
        $(obj).each((index, item) => {
            GetAttrContent(item, attrArr).then(res => {
                list.push(res);
                if(index === $(obj).length - 1){ resolve(list); }}); }); }); } // Get the property content of the objectfunction GetAttrContent(obj, attrArr){
    return new Promise((resolve) => {
        $.each(attrArr, (attrIndex, attrItem) => {
            let attrContent = $(obj).attr(attrItem);
            if(attrContent){ resolve(attrContent); }})}); }Copy the code

5.3 Background Background page implementation

The background page listens for messages from The Content-Script and stores the captured images to the server.

<! -- background.html --> <div> <scripttype="text/javascript" src=".. / static/js/jquery - 1.8.3. Js. ""></script>
     <script type="text/javascript" src=".. /static/js/background.js"></script> </div> <! --background.js--> chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
    if(request.type === 'SEND_IMG'){
        alert('I'm background, link to image:' + request.src);

        sendResponse('Taking pictures'); requestStoreImg(request.src); }}); // Store imagesfunction requestStoreImg(src) {

		$.ajax({
            type: 'get',
            url: 'https:/www.mogu.com/*/store',
            data: {
                url: src
            },
            success: function(res) {
                if (res.status && res.status.code && res.status.code === 1001) {
                		sendMsgToContentScript({type: 'COLLECT_RESULT', title: 'Picture captured successfully'}, function(response){
    				            alert('I'm background, from content' + response);
    				        });
                } else {
                    sendMsgToContentScript({type: 'COLLECT_RESULT', title: 'Image capture failed'}, function(response){
    				            alert('I'm background, from content' + response);
    				        });
                }
            },
            error: function(res){
            			sendMsgToContentScript({type: 'COLLECT_RESULT', title: 'Interface exception collection failed'}, function(response){
    				            alert('I'm background, from content'+ response); }); }})}function sendMsgToContentScript(message, callback){
    chrome.tabs.query({active: true, currentWindow: true}, function(tabs){
        chrome.tabs.sendMessage(tabs[0].id, message, function(response){
            if(callback) callback(response); })})}Copy the code

Vi. Plug-in release

Development completed, through the plug-in page of the “package extension” package generation. CRX package.

Sign up for a Google account, log into the Developer information Center, fill out all the information required and publish.

Vii. Reference documents

Developer.chrome.com/extensions open. Chrome. 360. Cn/extension_d…