3

I'm migrating an extension from manifest v2 to manifest v3 (and refactor and redesign...)

In the old version we were using an iframe within the tab, like this:

background.js

const open = () => {
    const oldIframe = document.getElementById('cm-frame');

    if (oldIframe) {
        oldIframe.remove();
        return;
    }

    const iframe = document.createElement('iframe');
    iframe.setAttribute('id', 'cm-frame');
    iframe.setAttribute('style', 'top: 10px;right: 10px;width: 450px;height: 100%;z-index: 2147483650;border: none; position:fixed;');
    iframe.setAttribute('allow', '');
    iframe.src = chrome.extension.getURL('index.html');
    iframe.frameBorder = 0;
    
    document.body.appendChild(iframe);
};

chrome.browserAction.onClicked.addListener(function (tab) {
    chrome.tabs.executeScript({
        code: '(' + open.toString() + ')();'
    }, () => { });
});

I've tried the same approach using chrome.actions.onClicked.addListener with chrome.scripting.executeScript and had no luck.

I know we could just use a popup ("default_popup": "popup.html",) but the iframe works better in terms of integration and design.

Tebo
  • 355
  • 2
  • 5
  • 17
  • Open devtools and inspect the console. You should see an error about `chrome.extension.getURL` which no longer exists in MV3. Use `chrome.runtime`. Also [check background.js console](/a/10258029). – wOxxOm Jan 26 '22 at 17:52
  • I wasn't seeing any errors, I was able to make it work though... I'll paste the code as an answer – Tebo Jan 26 '22 at 20:56
  • Thanks for pointing in the direction to check the console on the extension! – Tebo Jan 26 '22 at 21:02

1 Answers1

4

I was able to make it work.

background.js

chrome.action.onClicked.addListener(async function (tab) {
  chrome.scripting.executeScript({
    target: { tabId: tab.id },
    func: () => {
      const oldIframe = document.getElementById('cm-frame');

      if (oldIframe) {
        oldIframe.remove();
        return;
      }

      const iframe = document.createElement('iframe');
      iframe.setAttribute('id', 'cm-frame');
      iframe.setAttribute(
        'style',
        'top: 10px;right: 10px;width: 400px;height: calc(100% - 20px);z-index: 2147483650;border: none; position:fixed;'
      );
      iframe.setAttribute('allow', '');
      iframe.src = chrome.runtime.getURL('popup.html');

      document.body.appendChild(iframe);
    },
  });
});

This my manifest.json file in case someone also needs it (I had to add stuff to permissions and web_accessible_resources to make it work and load correctly):

{
  "manifest_version": 3,
  "name": "Contact Mapping Extension",
  "background": { "service_worker": "background.bundle.js" },
  "action": {
    "default_icon": "icon-34.png"
  },
  "icons": {
    "128": "icon-128.png"
  },
  "content_scripts": [
    {
      "matches": ["http://*/*", "https://*/*", "<all_urls>"],
      "js": ["contentScript.bundle.js"],
      "css": ["content.styles.css"]
    }
  ],
  "web_accessible_resources": [
    {
      "resources": ["content.styles.css", "icon-128.png", "icon-34.png", "popup.html"],
      "matches": ["<all_urls>"]
    }
  ],
  "permissions": [
    "tabs",
    "activeTab",
    "scripting"
  ]
}
Tebo
  • 355
  • 2
  • 5
  • 17