7

次のようなカスタム Elements サイドバー ペインを作成しています。

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 を構築できます。さらに、別の Panel でより詳細な 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);
            });
        });
    }
);

そして、これらの行は (in)famous で失敗します:

ポート エラー: 接続を確立できませんでした。受信側が存在しません。

sendMessage/onMessage パターンは、両方とも .html ページとして表されるペインとパネルの間で通信する正しい方法ですか?

編集

DevTools ロジスティクスを完全に回避し、DOM 経由でページにアクセスしようとしました ( my-pane.htmlmy-panel.html の<iframe/>両方が単一の親ページ内の s にあるようです):

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

EDIT 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.extension.sendMessageの代わりにchrome.tabs.sendMessageを使用する必要があります。

于 2012-12-11T17:22:19.280 に答える