-1

I'm creating a basic browser extension that converts the current HTML body to an image that can be downloaded via html2canvas. The problem is that the extension only saves an image of the extension popup window, and not the webpage.

HTML:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h2>Screenshot</h2>
    <input type="button" id="screenshot" value="Screenshot Body"/>
    <script src="screenshot.js"></script>
    <script src="html2canvas.js"></script>
</body>
</html>

JavaScript:

const screenshotEl = document.getElementById("screenshot")

screenshotEl.addEventListener("click", takeScreenshot);

function takeScreenshot() {
    html2canvas(document.body).then(function(canvas) {

        var dataURL = canvas.toDataURL("image/png", 1.0);
        chrome.downloads.download({
        url: dataURL,
        filename: "screenshot.png",
        saveAs: true
      });
    });
}

Any idea on how I can fix this? Thanks.

Mulloy
  • 156
  • 1
  • 8

1 Answers1

2

The html2canvas runs in the scope of the extension popup, but you want it to be running in the user's browser DOM scope. You can do that by sending a message from the popup JS file to a content script. The content script will run in the DOM context and take the photo you need.

In the popup JS file, you will send a message like this:

(async () => {
  const [tab] = await chrome.tabs.query({active: true, lastFocusedWindow: true});
  const response = await chrome.tabs.sendMessage(tab.id, {action: "screenshot"});
  console.log(response); // the content script responds with the data or a success message
})();

Then wait for the message in the content script:

chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse) {
    if (request.action === "screenshot") {
      html2canvas(document.body).then(function(canvas) {
        var dataURL = canvas.toDataURL("image/png", 1.0);
        chrome.downloads.download({
          url: dataURL,
          filename: "screenshot.png",
          saveAs: true
        });
      });
      sendResponse({message: "success"});
    }
  }
);

Be sure to also import the html2canvas.js source in the content script context instead of the popup context as well.

Jacob K
  • 1,096
  • 4
  • 10