Getting started with Google Plugins

A Google extension is essentially a configuration (entry) file manifest.json and a collection of HTML, CSS, JS, and image files

  • The manifest. Json
{
  // The name of the plug-in
  "name": "Test plug-in".// The description of the plug-in
  "description": "April's Google plugin."."version": 0.1."manifest_version": 2.// Icon position
  "icons": {
    "19": "icons/icon19.png"."38": "icons/icon38.png"."48": "icons/icon48.png"."128": "icons/icon128.png"
  },
  // Set the extension icon in the Chrome toolbar
  "browser_action": {
    "default_title": "april".// Click the page location shown by the extension icon
    "default_popup": "popup/popup.html"
  },
  // The extension can reside in the background. The most commonly used is to specify the subproperty scripts, which means that a page containing all the specified scripts is automatically created when the extension is started.
  "background": {
    "scripts": [
      "background.js"]},// Define the permissions that extensions need to apply to Chorme
  "permissions": [
    // Interface that can be requested across domains
    "https://www.baidu.com/"./ / store
    "storage".// Browser TAB
    "tabs".// Current active TAB
    "activeTab".// Browser notifications
    "notifications".// Right-click the menu
    "contextMenus",].// Custom pages replace chrome's corresponding pages with new tabs, Bookmarks, and History.
  "chrome_url_overrides": {
        "newtab": "tab.html"
   },
   // Need to inject the JS directly into the page
  "content_scripts": [{// Match URL,
      
        means match all
      
      "matches": [
        "<all_urls>"]."js": [
        "content-script.js"].// Inject scripts into the page through plug-ins. Content-scripts shares the DOM with the original page, but not the JS. Optional values: "document_start", "document_end", or "document_IDLE". The last value indicates when the page is idle, and the default is document_idle
      "run_at": "document_start"}}}]Copy the code
  • debugging
├─ images/ ├─ Popup.html ├─ Manifest.json ├─ content-script.jsCopy the code

Open the Extensions page (Chrome :// Extensions /), open developer mode, click on the image to load the extension you are working on, select your folder, and you can see it. After each configuration file change, you need to reload it by hitting the refresh button.

Major problems encountered

  • Message communication PopUP communicates with content

popup.js

// Send information to content-script
function sendMessageToContentScript(message, callback) {
    getCurrentTabId((tab) = > {
        // Add the current page URL to the parameterschrome.tabs.sendMessage(tab.id, { ... message,url: tab.url }, function(response) {
            if (callback) callback(response)
        })
    })
},
Copy the code
// Get the current TAB ID
function getCurrentTabId(callback) {
    chrome.tabs.query({ active: true.currentWindow: true }, function(tabs) {
        if (callback) callback(tabs.length ? tabs[0] : null)})}Copy the code
// Test communication event
document.getElementById('getSume').onclick = function() {
    sendMessageToContentScript({ cmd: 'update_font_size'.size: 42 }, function(response) {
        // Response is a message sent from content-script
        alert(response)
    })
}
Copy the code

content-script.js

// Receive messages from the background
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
    console.log(
        'Received from' + (sender.tab ? 'content-script(' + sender.tab.url + ') ' : 'popup or background) + 'message:',
        request
    )
    sendResponse('I got your message:' + JSON.stringify(request))
})
Copy the code
  • Chrome.runtime. onMessage with asynchronous response

Error code: popup.js keeps getting undefined

chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) => {
    let key = await getKey()
    sendResponse(key)
})
Copy the code

Solution:

chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) = >{(async() = > {let key = await getKey()
        sendResponse(key)
    })()
    return true
})
Copy the code
  • Content-script.js passing Blob data to popup problem: If the parameter is Blob, it is fine to print it in content-script.js, but it becomes object object when passed to the back end. As shown in the figure:

    Parse (json.stringify (form_data)) the Google extension can only transmit jSON-compatible data.Blob and JSON are incompatible. To upload a file, the Blob object can be converted into a dataURL by the sender, which is parsed back to the Blob object and regenerated into a FormData object to upload the file

    The sender:

    let file = null
    let reader = new FileReader()
    // Convert blob to dataURL
    reader.readAsDataURL(data)
    reader.onload = function(e) {
        file = e.target.result
        sendResponse({
            file,
        })
    }
    Copy the code

    Receiver:

    this.sendMessageToContentScript(item, async function(response) {
        // dataURL is converted to Blob
        const dataURLtoBlob = (dataUrl) = > {
            let arr = dataUrl.split(', '),
                mime = arr[0].match(/ : (. *?) ; /) [1],
                bstr = atob(arr[1]),
                n = bstr.length,
                u8arr = new Uint8Array(n)
            while (n--) {
                u8arr[n] = bstr.charCodeAt(n)
            }
            return new Blob([u8arr], {
                type: mime,
            })
        }
        const { file } = response
    
        let formData = new FormData()
        formData.append('file', dataURLtoBlob(file))
        let { data } = await axios.post('XXXX', formData, {
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',}})})Copy the code

— Received the demand, feel that they can not handle, after understanding some of the imagination is not so difficult brave Niuniu how afraid of difficulties over

Reference article:

  • Getting started with Google Plugins
  • Google plug-in on the most complete a Chinese version
  • Official material in English only
  • Develop plug-ins using VUE