0

Background.js:

chrome.tabs.executeScript(tab.id, 
{
    file: "exec_script.js"
}, function(res) {
    console.log(res);
});

exec_script.js:

var test = html2canvas(document.body, {
  allowTaint: false,
  letterRendering: true,
  logging: true
}).then(function (canvas) {
    var dataUrl = canvas.toDataURL();
    var bImage = dataUrl.replace('data:image/png;base64,', '');
});
test

As far as I know, the last statement in exec_script.js have to be passed to the callback as the result parameter. But it returns empty object.

But if I make as following in exec_script.js:

var test = "good";
test

It returns a value of the variable to the callback.

Also the tab is not focused.

9
  • "But it returns empty object" Are you sure res is a plain object? What value are you expecting to be passed to callback? Commented Jan 23, 2017 at 7:44
  • I want to see "bImage" value in the callback. Commented Jan 23, 2017 at 7:47
  • Have you tried to return bImage from .then() chained to html2canvas call, chaining .then() to res at callback? Commented Jan 23, 2017 at 7:50
  • Like this link ? Yes, I've tried. The problem is that the chrome.tabs.executeScript doesn't block the extension process until the code in the tab has finished. Commented Jan 23, 2017 at 7:56
  • test does not reference bImage value. test is a Promise, .then() is used to get Promise value. Commented Jan 23, 2017 at 8:43

1 Answer 1

1

The result returned by chrome.tabs.executeScript is produced by the main body of the executed script, in other words it is the standard behavior of synchronous JavaScript.

In your case the synchronous part creates test object, schedules a Promise but doesn't execute it yet (a task/microtask is queued), puts the just initialized test object as the last statement so that it gets picked up by executeScript. Furthermore, since executeScript transfers only JSON-ifiable portion of objects, and test being a complex class object, an empty object is transferred. You can check it manually by inspecting console.log(JSON.stringify(test)) in the console.

To transfer the results of asynchronous code use messaging:

  • background.js

    chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
        console.log(sender.tab, msg);
        // do something
    });
    chrome.tabs.executeScript(tab.id, {file: "exec_script.js"});
    
  • exec_script.js

    var test = html2canvas(document.body, {
      allowTaint: false,
      letterRendering: true,
      logging: true
    }).then(function(canvas) {
        var dataUrl = canvas.toDataURL();
        var bImage = dataUrl.replace('data:image/png;base64,', '');
        chrome.runtime.sendMessage({dataUrl: dataUrl});
    });
    

N.B. only JSON-ifiable portion of objects is transferred via messaging.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.