I did my research and struggled with it for a while, but I need your help.
I am creating a Chrome DevTools extension. It should pass the currently selected item from the Elements panel as a reference to the JS object defined in the script content.
It is important that I pass the link to the selected element or another way to identify the element from the contents of the script.
I understand the workflow with "isolated worlds" in Chrome DevTools. I also understand the messaging between extension pages, background page, and content scripts. This only happens with JSON primitives, therefore, the JS transfer fails.
How to transfer the element selected on the devtools Elements toolbar to the content script that is on the checked page?
Edit
Here is what I know so far:
Getting a link to the selected item:
chrome.devtools.inspectedWindow.eval("(" + function(){ console.log($0) }.toString() + ")()")
This function expression will be executed in the context of the page being checked, and not in the context of the devtools extension, and not in the context of an "isolated world" of script content. I do not believe that you can pass a link to another context using closure.
The reference to the selected DOM element $0 cannot be returned, because it cannot be serialized in JSON due to circular references.
The chrome.devtools namespace is not available outside the devtools extension page. Reference $0 cannot be used outside the evaluated expression in chrome.devtools.inspectedWindow
Bypass
As a workaround, I decided to use a common DOM to mark the selected item with a data attribute and use it to reselect in the context of the script content. Messages are used to pass a data attribute marker.
Here is a simplified version of the code:
On the devtools extension page:
// setup a communication port port = chrome.runtime.connect({name: "devtools"}); chrome.devtools.panels.elements.onSelectionChanged.addListener(function(){ // expression to run in the context of the inspected page var expression = "(" + mark.toString() + ")()" // evaluate the expression and handle the result chrome.devtools.inspectedWindow.eval(expression, dispatchToContentScript) }); function mark(){ // mark the currently selected element $0.setAttribute('data-selected') // send the marker to the callback return { marker: 'data-selected' } } function dispatchToContentScript(data){ // dispatch data to the content script which is listening to the same port. port.postMessage(data) }
In the contents of the script:
var port = chrome.runtime.connect({name: "devtools"}); port.onMessage.addListener(function(data) { // re-select the element in the context of the content script var el = document.querySelector('['+ data.marker +']') })
This is not a clean solution, but I can use it for my needs.
Is there an easier way to achieve the same result - to identify from the contents of the script element selected in the panel "Elements" devtools?
javascript google-chrome-devtools google-chrome-extension
Razvan caliman
source share