Extensión Chrome DevTools: cómo get el elemento seleccionado del panel de elementos en el script de contenido?

Hice mi investigación y luché con esto por un time, pero necesito su ayuda.

Estoy construyendo una extensión de Chrome DevTools. Debería pasar el elemento seleccionado actualmente del panel 'Elementos' como reference a un object JS definido en un script de contenido.

Es importante que pase la reference al elemento seleccionado, o alguna otra forma de identificar el elemento del script de contenido.

Entiendo el flujo de trabajo con 'mundos aislados' en Chrome DevTools. También entiendo los posts entre páginas de extensión, página de background y secuencias de commands de contenido. Esto solo ocurre con las primitivas JSON, por lo tanto, no pasa el scope de JS.

¿Cómo puedo pasar el elemento seleccionado en el panel de elementos devtools al script de contenido que vive en la página inspeccionada?

Editar

Esto es lo que sé hasta ahora:

Obtener una reference al elemento seleccionado:

chrome.devtools.inspectedWindow.eval("(" + function(){ console.log($0) }.toString() + ")()") 
  • Esa expresión de function se ejecutará en el context de la página inspeccionada, no en el context de la extensión devtools y no en el context del 'mundo aislado' del script de contenido. No creo que sea posible pasar una reference a un context diferente utilizando cierres.

  • La reference al elemento DOM seleccionado $0 no se puede devolver porque no se puede serializar a JSON debido a references circulares.

  • El espacio de nombres chrome.devtools no está disponible fuera de la página de extensiones de devtools. La reference de $0 no se puede usar fuera de la expresión evaluada en chrome.devtools.inspectedWindow

Solución

Como solución, elegí usar DOM compartido para marcar el elemento seleccionado con un atributo de datos y usarlo para volver a seleccionarlo en el context del script de contenido. La postría se usa para pasar el marcador de attributes de datos.

Aquí hay una versión simplificada del código:

En la página de extensión de devtools :

 // 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) } 

En el script de contenido :

 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 +']') }) 

No es una solución limpia, pero puedo usarla para mis necesidades.

¿Existe alguna manera más sencilla de lograr el mismo resultado: identificar desde un script de contenido el elemento seleccionado en el panel de "Elementos" de devtools?

2 Solutions collect form web for “Extensión Chrome DevTools: cómo get el elemento seleccionado del panel de elementos en el script de contenido?”

La API para chrome.devtools.inspectedWindow se ha actualizado para admitir la ejecución de scripts en el context del script de contenido.

Esta actualización en la API oficial de Chrome obsoleta nuestros piratas informáticos descritos anteriormente. Ahora podemos lograr el resultado esperado con:

 chrome.devtools.inspectedWindow.eval("aContentScriptFunction($0)", { useContentScriptContext: true }); 

El parámetro $0 hará reference al elemento seleccionado en el panel Elementos .

mi forma de hacerlo también es un truco. En lugar de inyectar un script de contenido definido en tu extensión, puedes inyectar una label de script que apunte a tus files en línea (o localmente, en relación con el html inspeccionado):

 //devtools.js var str = "var s = document.createElement('script');" + "s.src = 'http://extentionDomain/extentionFile.js';" + "document.body.appendChild(s);"; chrome.devtools.inspectedWindow.eval(str); 

file en línea define un global:

 var myExtention = { doStuff: function(selectedElement){ ..}} 

y devtools puede llamarlo y pasarle el elemento seleccionado:

 chrome.devtools.panels.elements.onSelectionChanged.addListener(function(){ chrome.devtools.inspectedWindow.eval('myExtention.doStuff($0)');}); 

sin embargo, no he encontrado una forma de enviar una reference desde la window inspeccionada a la extensión devtools con esta configuration.

  • Ejecute el script después de hacer clic en popup.html (extensión de Chrome)
  • ¿Cómo hago que la window de una extensión de Chrome parpadee en la barra de tareas?
  • extensión de Chrome: abre una nueva pestaña desde un formulario en window emergente
  • El CSP del manifiesto de extensión de Chrome se ignora en la página pública
  • chrome.tabCapture.capture silencia automáticamente la pestaña? ¿Hay otro método que no se silencia?
  • ¿Cómo hacer reference a la información de la versión en una extensión de Google Chrome?
  • La creación de un menu de context dynamic en la extensión de Chrome está fallando
  • mismo localStorage para http y https?
  • ¿Cómo puedo cancelar la inserción del server HTTP / 2 cuando uso fetch?
  • Enfoque automático de la nueva pestaña de Chrome
  • Página de background en extensión pop-chrome
  • Javascript tiene muchos buenos JS marco (como Node.js AngularJS Vue.js React.js) es el mejor lenguaje de script.