cdeng cdeng - 22 days ago 8
Javascript Question

How to get the data of a D3 node in Chrome Extension content script

The D3 example we were using is this:
https://bl.ocks.org/mbostock/raw/1341021/

If you copy & paste the following code into console and run, all bounded data will be shown in the console.

var svgs = document.getElementsByTagName("svg");
for (var i = 0; i < svgs.length; i++) {
var babbies = svgs[i].getElementsByTagName("*");
for (var j = 0; j < babbies.length; j++) {
console.log(babbies[j].__data__);
}
}


Unfortunately, if we use the same code in content script of the Chrome Extension, the data of all nodes (
babbies[j].__data__
) are showing
undefined
. We have ran the debugger and the nodes
babbies
in content script looked great though.

So we did some research on the content scripts and realized that Content scripts are executed in an "isolated world" environment. Due to that reason, content scripts seemed not to be able to read the bounded data of D3 node.

We also tried to inject scripts into the page via this method. However, injected scripts behave as they were included by the page itself, and are not connected to the extension in any way.

We were wondering if there is any way to access bounded data of D3 node in content script or extension code?

Answer

As you found out, you can not directly access the page script scope (e.g. variables and functions). However, you can communicate with the script which you have injected into the page context through the DOM. Usually, this means using window.postMessage() and window.addEventListener(). If you are wanting to manipulate the data within your content script, you will need to inject a script to the page context and message the data back to your content script.

An example from MDN (while intended for WebExtensions, it works just fine in a Chrome extension) [The code below is copied from that MDN page.]:

page-script.js:

var messenger = document.getElementById("from-page-script");

messenger.addEventListener("click", messageContentScript);

function messageContentScript() {
  window.postMessage({
    direction: "from-page-script",
    message: "Message from the page"
  }, "*");

content-script.js:

window.addEventListener("message", function(event) {
  if (event.source == window &&
      event.data.direction &&
      event.data.direction == "from-page-script") {
    alert("Content script received message: \"" + event.data.message + "\"");
  }
});

References: