Search code examples
javascriptswiftsafarihtml2canvassafari-extension

WebKitSubtleCrypto error when using dispatchMessage in Safari Extension


I am attempting to build a Safari extension to share screenshots of webpages but when I try to pass the image back to Swift I get an error that makes Safari unstable and kills my task mid-process.

The idea is that when a user taps a tool bar button any selected text and a screenshot of the webpage are saved. I am trying to pass both of those through the userInfo dictionary. If I run my code as is with the dispatchMessage call commented out I do not see any errors. If I uncomment the dispatch call I see the following error:

 WebKitSubtleCrypto is deprecated. Please use SubtleCrypto instead.

Here is my js code:

document.addEventListener("DOMContentLoaded", function(event) {
    safari.self.addEventListener("message", handleMessage);
});

function handleMessage(event) {
    var selectedText = window.getSelection().toString();
    var screenshot;

    if (window.top === window) {
  html2canvas(document.getElementsByTagName('html')).then(function(canvas) {
        screenshot = convertCanvasToImage(canvas);
        console.log("canvas image: " + screenshot)
        safari.extension.dispatchMessage("test", {"selectedText": selectedText, "screenshot" : canvas});
        });
    }
}

function convertCanvasToImage(canvas) {
   var image = new Image();
   image.src = canvas.toDataURL("image/png");
   return image;
}

The html2canvas (latest - 0.5.0-beta4) script is in another file packaged with the extension.

Edit 1

After some more testing it looks as though this error only has to do with passing the 'screenshot' object in the messageDipatch call. If I take out screenshot and only pass the selectedText data it works as expected. I have also tried to pass the screenshot through as a canvas instead of running it through the 'convertCanvasToImage()' call but I am getting the same error with that.


Solution

  • The issue ended up being related to how I was init'ing the image data before converting the canvas to a data url.

    Going from:

    function convertCanvasToImage(canvas) {
       var image = new Image();
       image.src = canvas.toDataURL("image/png");
       return image;
    }
    

    to:

    function convertCanvasToImage(canvas) {
        var imageData = canvas.toDataURL("image/png")
        return imageData;
    }
    

    resolved the issue.

    On the Swift side this is how I am decoding that data (be cautious of the all the forcing in this):

        let imageString = userInfo?["screenshot"] as! String
        let imageData = NSData.init(contentsOf: NSURL(string: imageString) as! URL)
        let image = NSImage(data: imageData as! Data)