lxieyang / chrome-extension-boilerplate-react

A Chrome Extensions boilerplate using React 18 and Webpack 5.
MIT License
3.42k stars 1.07k forks source link

Offscreen support #162

Open Chaysen opened 1 year ago

Chaysen commented 1 year ago

Hi, I was wondering if you could add support for offscreen script https://developer.chrome.com/docs/extensions/reference/offscreen/

Thanks for the awesome boilerplate !!

dimadolgopolovn commented 2 months ago

Hey. I just had to implement this myself. Nothing really stops you from adding an offscreen document into the file structure but you'll have to add a few lines for webpack.

I'll try to suggest a pull request for this later but here are the instructions for now:

In your webpack.config.js:

In your manifest.json add this.

"permissions": [..., "offscreen"],

Create src/pages/Offscreen/index.html.

</head>
<body>
  <script src="offscreen.ts" type="module"></script>
  <textarea id="text"></textarea>
  OFFSCREEN HTML
</body>

Create src/pages/Offscreen/offscreen.ts:

console.log("Offscreen.ts works")

Add these lines to your background script.

const OFFSCREEN_DOCUMENT_PATH = 'offscreen.html'

// ------------ OFFSCREEN DOCUMENT ------------
const createOffscreenDocument = async () => {
  console.log('Try creating offscreen doc')
  if (!(await hasDocument())) {
    console.log('Creating offscreen doc')
    console.log(OFFSCREEN_DOCUMENT_PATH)

    await chrome.offscreen
      .createDocument({
        url: OFFSCREEN_DOCUMENT_PATH,
        // TODO: HERE YOU NEED TO PUT YOUR REASON FOR OFFSCREEN FOR EXAMPLE DOM_PARSER
        reasons: [chrome.offscreen.Reason.DOM_PARSER],
        justification:
          'YOUR_JUSTIFICATION',
      })
      .then((e: any) => {
        console.log('Created offscreen doc')
        console.log(e)
      })
      .catch((e: any) => {
        console.log('err')
        console.log(e)
      })
  }
  // Now that we have an offscreen document, we can dispatch the
  // message.
}
createOffscreenDocument()

async function hasDocument() {
  // Check all windows controlled by the service worker if one of them is the offscreen document
  try {
    // @ts-ignore clients
    if (clients) {
      // @ts-ignore clients
      const matchedClients = await clients.matchAll()
      for (const client of matchedClients) {
        if (client.url.endsWith(OFFSCREEN_DOCUMENT_PATH)) {
          return true
        }
      }
    }
  } catch (e) {
    console.log(e)
  }
  return false
}