Search code examples
javascriptconsole-applicationclipboardchrome-extension-manifest-v3

upgrading chrome extension from manifest version2 to v3, need to get clipboard text in background.js


Hi I am converting Google chrome extension from manifest version-2 to version-3

facing 2 issues those are mentioned below, but before that I will explain what extension in expected to do.

On click specific button on webpage I am calling console application that is copying JSON string in clipboard, then in chrome extension background.js I am getting clipboard data and passing it to content.js which is showing it in web page.

Errors / challenges:
1- Need to get clipboard text into a variable in background.js. I am able to get it in content.js but I need it to get it in background.js

2- I am getting these 2 error in background.js console, but extension is working

Unchecked runtime.lastError: Native host has exited.
Unchecked runtime.lastError: The message port closed before a response was received. 

My Background.js looks like this

var port = null;
var tabId = null;
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { 
            tabId=sender.tab.id;
            var hostName = "my.console.app";
            port = chrome.runtime.connectNative(hostName);
            port.onDisconnect.addListener(onDisconnected);
            sendResponse({status: 'ok'}); 
            return true; 
  });
 
 
function onDisconnected() {    
    port = null;
    SendResponse();
}

//this funciton need to upgrade to manifest version 3 because in v3 `chrome.extension.getBackgroundPage` is not compatible
function SendResponse() {
    bg = chrome.extension.getBackgroundPage();
    bg.document.body.innerHTML = ""; // clear the background page
    var helper = null;
    if (helper == null) {
        helper = bg.document.createElement("textarea");
        helper.style.position = "absolute";
        helper.style.border = "none";
        document.body.appendChild(helper);
    }

    //Focus the textarea
    helper.select();

    // perform a Paste in the selected control, here the textarea
    bg.document.execCommand("Paste"); 

    // Send data back to content_script
    chrome.tabs.sendMessage(tabId, { action: "MY_CUSTOM_EVENT", response: helper.value });
}

content.js

document.addEventListener("MY_CUSTOM_EVENT", function (data) {
    chrome.runtime.sendMessage({ runConsoleApp: true }, response => {
         
    });
});


 

async function copyToTheClipboard(textToCopy){
      
    navigator.clipboard.readText()
    .then(text => {
        //console.log('Pasted content: ', text);
        $('.simulateEidResponse').html(text).trigger('click'); 
    })
    .catch(err => {
        console.error('Failed to read clipboard contents: ', err);
    }); 
}


Solution

  • Currently there's no way to do it in the background script due to crbug.com/1404835.
    In the future the workaround will be execCommand + offscreen API.

    The only reliable solution that works regardless of whether the tab is focused or not is to use document.execCommand("Paste") in the content script.

    // background.js

    chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
      if (msg.runConsoleApp) {
        chrome.runtime.connectNative('my.console.app')
          .onDisconnect.addListener(() => sendResponse(true));
        return true;
      }
    });
    

    // content.js

    document.addEventListener('MY_CUSTOM_EVENT', async e => {
      await chrome.runtime.sendMessage({ runConsoleApp: true });
      document.querySelector('.simulateEidResponse').focus();
      document.execCommand('selectAll');
      document.execCommand('paste');
    });