7

我正在创建我的自定义元素侧边栏窗格,如下所示:

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

我的窗格.html:

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

在 my-pane.js 中,我正在查看当前选定的元素:

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

到目前为止,一切都很好:我可以在窗格中获得一个选择并围绕它构建一个自定义 HTML UI。更进一步,我想在另一个面板中显示一些更详细的 UI。这就是我正在尝试的(在窗格创建后立即):

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

这些行因(不)著名而失败:

端口错误:无法建立连接。接收端不存在。

sendMessage/onMessage 模式是否是窗格和面板之间通信的正确方式,两者都表示为 .html 页面?

编辑

试图完全避免 DevTools 物流并通过 DOM 访问页面(my-pane.htmlmy-panel.html似乎都在<iframe/>单个父页面中):

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

这没有用:

不安全的 JavaScript 尝试从 URL 为 chrome-extension://<..>/devtools.html 的框架访问具有 URL chrome-extension://<..>/devtools.html 的框架。域、协议和端口必须匹配。

编辑 2

傻我!当然,上述关于第一个<iframe/>是正确的假设是完全错误的。以下产生更有意义的结果:

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

编辑3(解决方案但不是答案

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

奖励:我试图实现的通信类型(绿色箭头)的可视化

4

1 回答 1

0

根据您最后的评论

到目前为止,onMessage 事件处理程序在将其放入 background.js 后开始工作。但这正是我想避免的。相反,我更喜欢 my-pane.html 和 my-panel.html 直接相互交谈。当不使用 HTML 页面作为窗格和面板内容时,这当然是可能的。

我明白发生了什么...

您的面板/窗格不是扩展过程,它被视为内容脚本。所以你需要使用chrome.tabs.sendMessage而不是chrome.extension.sendMessage

于 2012-12-11T17:22:19.280 回答