6

I need to migrate some chrome extensions to manifest v3. I have an extension that is using background script to intercept some ajax requests to get the relative video file. I've started to modify the manifest file but I'm not sure on how to proceed with manifest background section and it's relative JavaScript file.

At the moment I've modified the manifest in this way:

{
  "manifest_version": 3,
  "name": "__MSG_extName__",
  "description": "__MSG_extDescription__",
  "default_locale": "en",
  "permissions": [
    "tabs",
    "activeTab",
    "webRequest"
  ],
  "host_permissions": [
    "https://*"
  ],
  "icons": {
    "16": "icons/16.png",
    "48": "icons/48.png",
    "128": "icons/128.png"
  },
  "background": {
    "scripts": [
      "js/background.js"
    ],
    "persistent": true
  },
  "web_accessible_resources": [{
    "resources": ["room.html"]
  }],
  "action": {},
  "version": "2.1.0",
  "content_security_policy": {
    "extension_pages": "script-src 'self' ; object-src 'self'"
  }
}

It's not clear for me how to modify the background section if I've understand I need to remove the persistent and replace the scripts with service_workers that is a string right?

For the background.js file content instead I don't know if it will work as it is or if I need to register a service worker?

//
let payload = {}

chrome.runtime.onInstalled.addListener(function() {
  chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
    chrome.declarativeContent.onPageChanged.addRules([
      {
        conditions: [
          new chrome.declarativeContent.PageStateMatcher({
            pageUrl: { urlMatches: 'www.mywebsite.com/video/*', schemes: ["https"] },
          })
        ],
        actions: [ new chrome.declarativeContent.ShowPageAction() ]
      }
    ]);
  });
});

//
chrome.runtime.onInstalled.addListener( () => {
  chrome.tabs.create({
    url: browser.runtime.getURL('instructions.html')
  })
})

//
chrome.runtime.onUpdateAvailable.addListener( () => {
  chrome.runtime.reload()
})

//
chrome.pageAction.onClicked.addListener( () => {
  chrome.windows.create({
    url: browser.runtime.getURL('popup.html'),
    width: 500,
    height: 295,
    type: 'popup'
  })
})

//
chrome.webRequest.onCompleted.addListener( (details) => {
  payload.url = details.url
},{
  urls: ["https://*.akamaihd.net/*/index_0_av.m3u8*"],
  types: ["xmlhttprequest"]
},["responseHeaders"])

chrome.webRequest.onCompleted.addListener( (details) => {
  payload.streamInfo = details.url
},{
  urls: ["https://*.mywebsite.com/video/*/*.json*"],
  types: ["xmlhttprequest"]
},["responseHeaders"])

// 
chrome.runtime.onMessage.addListener( (message) => {
  console.log(message)
  if( message.action === 'openPopup' ){
    chrome.windows.create({
      url: browser.runtime.getURL('popup.html'),
      width: 500,
      height: 295,
      type: 'popup'
    })
  }
  if( message.status === 'ready' ){
    chrome.runtime.sendMessage( payload )
  }
  else if( message.status === 'refresh' ){
    chrome.runtime.sendMessage( payload )
  }
})

Can anyone help me please?

Or Assayag
  • 5,662
  • 13
  • 57
  • 93
newbiedev
  • 2,607
  • 3
  • 17
  • 65

1 Answers1

5

There's no need to register anything explicitly.
All you need is to declare the script in manifest.json correctly.

  1. Move the background service worker script into the extension root if you want your extension to run in Chrome 92 or older. This is where your manifest.json is.

  2. Specify just one background service worker script in manifest.json:

    "background": {
      "service_worker": "background.js"
    }
    

    This file can load other files inside by using the synchronous built-in importScripts.

  3. Rework your code so it doesn't use global variables like payload by switching to chrome.storage.local. It supports only the JSON-compatible types (strings, numbers, boolean, null, and arrays/objects that recursively consist only of these types) so in case your data can't be serialized you'll have to force the service worker to persist.

wOxxOm
  • 65,848
  • 11
  • 132
  • 136
  • Thank you for the help. At the moment I need the `payload` variable to pass the extracted url back to the front end but I don't need to store it because it will change everytime based on the video file the user will select. It can be an issue if I leve it there? – newbiedev Dec 15 '20 at 22:05
  • The service worker automatically terminates after 30 seconds (if there are no open messaging channels) so if you use the variable within this time span there'll be no problem. Until Chrome developers decide to change the timeout, of course, but that's unlikely. – wOxxOm Dec 15 '20 at 22:07
  • I need to test the extension after migration but I think that 30 seconds are fine for the scope of the variable. Just another thing, do I need to migrate `pageAction` to action as reported into documentations? – newbiedev Dec 16 '20 at 07:46
  • Thank you. I'm testing the changes and on chrome 87 for macOS at the moment some things will not work at the moment, this because the manifest v3 at the moment seems working only on dev channel. I will start modify my extensions and when the v3 will be fully implemented I will update them on the CWS – newbiedev Dec 16 '20 at 08:52
  • Note that Chrome can now load the background service workers from nested directories (the bug has been fixed in May). – Michael T Nov 22 '21 at 10:58