Mediha
Mediha

Reputation: 760

Porting Chrome extension to Edge

I have created a chrome extension to enable clipboard data access. The solution is explained in details here Implementing 'Paste' in custom context menu. Now the problem is how to port this extension to Edge. There is a tool for that I know I used it, and maybe it is working, but my problem is how to "consume" this extension, what is equivalent to chrome.runtime.sendMessage in Edge? In Chrome I used this https://developer.chrome.com/apps/messaging#external-webpage - the part 'Sending messages from webpages', but in Edge I just can't find anything similar. Thanks for your time and help.

Upvotes: 2

Views: 1066

Answers (2)

Mediha
Mediha

Reputation: 760

I managed to solve this. There is no way (at least I couldn't find it) to communicate from web page with extension background script (and only the background script can get data from the clipboard and has the 'browser' object defined). So what I did, I communicated with content script and content script communicated with background script. Here is the code.

PAGE CODE:

contextMenuPaste: function () {
    if (getBrowserName() == 'EDGE') {
         window.postMessage({
            direction: "from-page-script"
         }, "*");
    }
},

window.addEventListener("message", function (event) {
    if (event.source == window &&
        event.data.direction &&
        event.data.direction == "from-content-script") {
        console.log('Data in page script', event.data.message);
    }
});

CONTENT SCRIPT CODE

window.addEventListener("message", (event) => {
  // If message came from page-script send request to background script to get clipboard data
  if (event.source == window &&
    event.data &&
    event.data.direction == "from-page-script") {
    browser.runtime.sendMessage({
        message: "getClipboardData"
      },
      function(clipboardData) {
        messagePageScript(clipboardData);
      }
    );
  }
});

// Send clipboard data to page script
function messagePageScript(clipboardData) {
  window.postMessage({
    direction: "from-content-script",
    message: clipboardData
  }, "*");
}

BACKGROUND SCRIPT CODE

browser.runtime.onMessage.addListener(
  function(req, sender, callback) {
    if (req) {
      if (req.message) {
         if (req.message == "installed") {
           console.log('Checking is extension is installed!');
           callback(true);
         }
         else if(req.message = "getClipboardData") {
           console.log('Get clipboard data');
           callback(getDataFromClipboard());
         }
       }
    }
    return true;
  }
);

function getDataFromClipboard() {
  var bg = browser.extension.getBackgroundPage();
  var helperTextArea = bg.document.getElementById('sandbox');
  if (helperTextArea == null) {
    helperTextArea = bg.document.createElement("textarea");
    document.body.appendChild(helperTextArea);
  }
  helperTextArea.value = '';
  helperTextArea.select();

  // Clipboard data
  var clipboardData = '';

  bg.document.execCommand("Paste");
  clipboardData = helperTextArea.value;
  helperTextArea.value = '';

  return clipboardData;
}

But there is one tiny issue. This code works if I have a break-point set on line

bg.document.execCommand("Paste");

and it doesn't if I don't have that break-point. I thought it is a trimming issue, added pauses, delayed executions but nothing helped. I will start a new question for that issues and will copy solution here (if I find one).

Upvotes: 1

kumarharsh
kumarharsh

Reputation: 19609

There is runtime.sendMessage() in Edge too.

https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/runtime/sendMessage

The thing to keep in mind is that the runtime object is defined on the browser object, not chrome.

Sends a single message to event listeners within your extension or a different extension.

If sending to your extension, omit the extensionId argument. The runtime.onMessage event will be fired in each page in your extension, except for the frame that called runtime.sendMessage.

If sending to a different extension, include the extensionId argument set to the other extension's ID. runtime.onMessageExternal will be fired in the other extension.

Extensions cannot send messages to content scripts using this method. To send messages to content scripts, use tabs.sendMessage.

This is an asynchronous function that returns a Promise.

Upvotes: 1

Related Questions