20

Chrome devtools パネルの拡張機能があります。...を使用してページにメッセージを送信できますがchrome.devtools.inspectedWindow.eval、開発パネルでメッセージを受信するにはどうすればよいですか? 具体的には、ページで発生するイベントにフックする開発パネルが必要です。コンテンツ スクリプトやバックグラウンド ページのイベントをリッスンできません。

chrome.extension.sendMessageコンテンツ スクリプトとchrome.extension.onMessage.addListener開発パネル スクリプトを試しました。しかし、sendMessage不平を言うPort error: Could not establish connection. Receiving end does not exist.

この問題は、接続が長時間続く場合にも発生します。

コンテンツ スクリプトまたは背景ページ:

var port = chrome.extension.connect({name: "test"});
port.postMessage({msg: "testing"});

開発ツール パネルの JavaScript で:

chrome.extension.onConnect.addListener(function(port) {
    port.onMessage.addListener(function(msg) {
         // never gets here
    });
 });

コンテンツ スクリプト (開発ツール パネル) でトリガーされたイベントをリッスンするにはどうすればよいですか? Firefox のアドオン SDK からのこのような図は素晴らしいでしょう: https://addons.mozilla.org/en-US/developers/docs/sdk/latest/static-files/media/content-scripting-overview.png

4

1 に答える 1

53

目標は、通信用のチャネル (「ポート」) を作成することです。接続が正しく維持されている限り、ポートの作成方法は問題ではありません。

バックグラウンド スクリプトは devtools パネルがいつ作成されるかを認識しないため、devtools スクリプトはポートを開始する必要があります。

双方向通信方法を示す基本的な例を次に示します。

devtools.js

chrome.devtools.panels.create('Test', '/icon.png', '/panel.html', function(extensionPanel) {
    var _window; // Going to hold the reference to panel.html's `window`

    var data = [];
    var port = chrome.runtime.connect({name: 'devtools'});
    port.onMessage.addListener(function(msg) {
        // Write information to the panel, if exists.
        // If we don't have a panel reference (yet), queue the data.
        if (_window) {
            _window.do_something(msg);
        } else {
            data.push(msg);
        }
    });
    
    extensionPanel.onShown.addListener(function tmp(panelWindow) {
        extensionPanel.onShown.removeListener(tmp); // Run once only
        _window = panelWindow;

        // Release queued data
        var msg;
        while (msg = data.shift()) 
            _window.do_something(msg);
        // Just to show that it's easy to talk to pass a message back:
        _window.respond = function(msg) {
            port.postMessage(msg);
        };
    });
});

これで、パネルはポート経由でメッセージを送受信できるようになりました。パネルのスクリプト ( CSPのための外部スクリプト ファイル) は次のようになります。

panel.js

function do_something(msg) {
    document.body.textContent += '\n' + msg; // Stupid example, PoC
}
document.documentElement.onclick = function() {
    // No need to check for the existence of `respond`, because
    // the panel can only be clicked when it's visible...
    respond('Another stupid example!');
};

次に、背景ページのスクリプト:

background.js

var ports = [];
chrome.runtime.onConnect.addListener(function(port) {
    if (port.name !== "devtools") return;
    ports.push(port);
    // Remove port when destroyed (eg when devtools instance is closed)
    port.onDisconnect.addListener(function() {
        var i = ports.indexOf(port);
        if (i !== -1) ports.splice(i, 1);
    });
    port.onMessage.addListener(function(msg) {
        // Received message from devtools. Do something:
        console.log('Received message from devtools page', msg);
    });
});
// Function to send a message to all devtools.html views:
function notifyDevtools(msg) {
    ports.forEach(function(port) {
        port.postMessage(msg);
    });
}

テストするnotifyDevtools('Foo');には、バックグラウンド ページで実行するだけです (例:コンソール経由)。このデモでは、メッセージはすべての devtools に送信されます。受信すると、受信したメッセージが devtools パネルに表示されます。

以下を使用して拡張機能をまとめます。

manifest.json

{
  "name": "Test",
  "manifest_version": 2,
  "version": "1",
  "devtools_page": "devtools.html",
  "background":{"scripts":["background.js"]}
}

panel.html

<script src="panel.js"></script> <!-- Doctype etc not added for conciseness-->

devtools.html

<script src="devtools.js"></script>

こちらもご覧ください

于 2012-07-26T20:44:44.637 に答える