2012-08-27 14 views
7

estoy creando mi panel de la barra lateral elementos personalizados como esto:¿Cómo se puede comunicar el panel personalizado de la barra lateral de DevTools Elements al panel?

chrome.devtools.panels.elements.createSidebarPane(
    "MyPane", 
    function (sidebar) { 
     sidebar.setPage('my-pane.html'); 
    } 
); 

mi-pane.html:

<html> 
    <head> 
    <script src="my-pane.js"></script> 
    </head> 
    <body> 
    <!-- custom UI --> 
    </body> 
</html> 

Dentro de mi-pane.js estoy viendo elemento seleccionado en ese momento:

chrome.devtools.panels.elements.onSelectionChanged.addListener(function() { 
    chrome.devtools.inspectedWindow.eval("$0", function (res) { 
     <!-- process res and want to push detailed results into custom panel --> 
    }); 
}); 
// expecting request from panel here 
chrome.extension.onMessage.addListener(function (msg, _, sendResponse) { 
    console.log(msg, _, sendResponse); 
}); 

Hasta el punto anterior, todo funciona bien: puedo obtener una selección y crear una interfaz de usuario HTML personalizada en un panel. Yendo más lejos, quiero mostrar una interfaz de usuario más detallada en otro panel. Esto es lo que estoy tratando (inmediatamente después de la creación panel):

chrome.devtools.panels.create(
    'My details', 
    'icon.png', 
    'my-panel.html', 
    function (panel) { 
     panel.onShown.addListener(function (window) { 
      chrome.extension.sendMessage({}, function (response) { 
       console.log(response); 
      }); 
     }); 
    } 
); 

Y estas líneas fallar con la (in) famoso:

Port error: Could not establish connection. Receiving end does not exist.

es el patrón sendMessage/onMessage una manera correcta para comunicarse entre panel y panel, ambos representados como páginas .html?

EDITAR

tratado de evitar DevTools logística en conjunto y páginas de acceso a través de DOM (tanto mi-pane.html y mi-panel.html parecen estar en <iframe/> s dentro de una página solo padre):

.. 
panel.onShown.addListener(function (window) { 
    console.log(["PANEL", 
     window 
      .top 
      .frames[0] // Assume this is my-pane.html 
      .document 
      .getElementsByTagName('ol') 
    ]); 
}); 
.. 

esto no funcionó:

Unsafe JavaScript attempt to access frame with URL chrome-extension://<..>/devtools.html from frame with URL chrome-extension://<..>/devtools.html. Domains, protocols and ports must match.

EDITAR 2

tonto de mí! Por supuesto, la suposición anterior sobre la primera <iframe/> siendo la correcta es completamente falsa. A continuación se produce resultado más significativo:

panel.onShown.addListener(function (window) { 
    for (var i = 0; i < window.top.frames.length; i++) { 
     try { 
      console.log(["PANEL", 
       window.top.frames[i].document.getElementsByTagName('ol') 
      ]); 
      break; 
     } catch (e) { 
      console.log('BAD!', e); 
     } 
    } 
}); 

Datos 3 (solución, pero no la respuesta )

chrome.devtools.panels.create(
    'My Panel', 
    'icon.png', 
    'my-panel.html', // Must define function callbackInMyPanelPage(doc) { .. } 
    function (panel) { 
     panel.onShown.addListener(function (window) { 
      for (var i = 0; i < window.top.frames.length; i++) { 
       try { 
        // Use any unique marker to identify our pane document, 
        // at worst case a security exception will be thrown.. 
        var $el = window.top.frames[i].document.getElementById('myPane'); 

        if ($el) { 
         try { 
          // pass pane's document to panel page 
          window.callbackInMyPanelPage(window.top.frames[i].document); 
         } catch(ex) {} // Don't interfere with a handler below 
         break; 
        } 
       } catch (e) { 
        console.warn('Cannot access <iframe/>', e); 
       } 
      } 
     }); 
    } 
); 

Bono: una visualización de qué tipo de comunicación (flecha verde) que estaba tratando de lograr

+0

Su código no incluye la definición de un detector de eventos 'onMessage'. –

+1

@RobW gracias por recordar: he intentado genérico ** chrome.extension.onMessage.addListener (..) ** en dos lugares: 1. Inside _my-pane.js_, justo después de suscribirse a onSelectionChanged 2. Dentro de _devtools.js_, entre la creación del panel y el panel. Por lo que tengo entendido, esto se llama [Solicitudes únicas simples] (http://developer.chrome.com/extensions/messaging.html) – esteewhy

+0

¿Está seguro de que no se produjo ningún error que haya provocado el fallo del enlace del evento? Puede abrir otra instancia de devtools dentro de una instancia de devtools para buscar errores (no tuve tiempo de seguir a fondo el flujo de su código, podría usar varios 'console.log's, o la alerta rápida n dirty' ('somenumber') 'para comprobar esto usted mismo). –

Respuesta

0

Basado en su último comentario

So far got onMessage event handler working after putting it into background.js. But that's what i'd like to avoid exactly. Instead, i'd prefer that my-pane.html and my-panel.html talking directly to each other. This is certainly possible when NOT using HTML pages as pane and panel content.

me di cuenta de lo que sucedió ...

Su panel/panel no es un proceso de extensión, se considera un contenido en secuencias de comandos. Por lo tanto, deberá usar chrome.tabs.sendMessage en lugar de chrome.extension.sendMessage.

Cuestiones relacionadas