0

アイテムをクリックしてcontext-menuダイアログを表示し(JQuery / Bootstrapを使用)、ユーザーが選択したテキストをAJAX経由でWebサービスに送信できるようにしています(これはすべて完全に機能します)。notification送信したら、「送信していただきありがとうございます」というアドオンSDKを表示する予定です。

これで、通知を表示するためにコンテンツスクリプトからアドオンスクリプトにメッセージを送信する必要があることがわかりましたが、コールバック関数から送信されたときにメッセージが到着しません。

私のアドオンコード(抜粋):

var pageMod = require("page-mod");
pageMod.PageMod({
  include: ['*'],
  contentScriptWhen: "end",
  contentScriptFile: [ data.url("js/content.js") ],

  onAttach: function onAttach( worker, mod) {
    worker.port.on("submittedNotif", function(msg) {
        console.log('Hello');
        notifications.notify({ ... });
    })
  }
});

コンテンツスクリプトは次のとおりです。メッセージが届いた状況と届かなかった状況を示しました。

// Handle the context-menu Item's click and show the dialog

self.on("click", function(node,data) {
    self.port.emit("submittedNotif", '*** DOES NOT ARRIVE ***');
    showDialog( 'DialogName', function (response) { /* Do stuff */ });
})

self.port.emit("submittedNotif", '*** Arrives OK ***');

function showDialog( str, response) {
    // Dialog stuff
    self.port.emit("submittedNotif", '*** DOES NOT ARRIVE ***');
}

グローバルオブジェクトだと言われselfているので、確かにパラメータとして渡す必要はありません。コンテンツスクリプト内のどこで使用されているかによって、経由での送信self.port.emitの動作がどのように異なるかは私にはわかりません。たとえば、スレッドの問題は認識していません。おそらくこれは私のJavaScriptの知識のギャップですが、誰かが私が間違っていることを教えてもらえますか?

4

2 に答える 2

1

クリックイベントがどこから来るのかは私にはわかりません

self.on('click')

代わりに行う必要があるのは、クリックハンドラーを、クリックされるページのDOM内の何か、たとえば、言及したダイアログにバインドすることです。確認ダイアログが表示されたときにイベントを発行することでこれを行う、この非常に単純なビルダーの例を確認してください。

https://builder.addons.mozilla.org/addon/1049875/latest/

main.js:

var data = require("self").data;
var notifications = require("notifications");
var pageMod = require("page-mod");
pageMod.PageMod({
  include: ['*'],
  contentScriptWhen: "end",
  contentScriptFile: [ data.url("jquery.js"), data.url("content.js") ],

  onAttach: function onAttach( worker, mod) {
    worker.port.on("submittedNotif", function(msg) {
        notifications.notify({
            title: 'Notification!',
            text: 'This is the notification: '+ msg
        });
    })
  }
});

content.js:

$(function() {
    if(confirm("send submitted event?")) {
        self.port.emit("submittedNotif", '*** DOES NOT ARRIVE ***');
        showDialog( 'DialogName', function (response) { /* Do stuff */ });
    }
});


//self.port.emit("submittedNotif", '*** Arrives OK ***');

function showDialog( str, response) {
    // Dialog stuff
    self.port.emit("submittedNotif", '*** DOES NOT ARRIVE ***');
}
于 2012-04-22T22:30:11.320 に答える
0

私は自分の問題を解決しました。これがその方法と私が学んだことです。

まず、コンテンツスクリプトとcontext-menuアイテムのクリックハンドラー:

self.on("click", function(node,data) {
    self.postMessage({ kind:'submittedNotif', msg: 'Just clicked'})
    showDialog( self, 'DialogName', function (response) { /* Do stuff */ });
})

さて、古いものself.port.emitは私をどこにも連れて行きませんでした、しかしアイテムに切り替えて、そしてアイテムにself.postMessage加えることは最終的に私が望むイベントを私に与えます。onMessage()context-menu

ここで、パラメーター'eventHandler'として[グローバルであることについて言われたことに反する...?!]メソッドも渡しselfます。showDialog()self

function showDialog( eventHandler, str, response) {
    // Dialog stuff
    eventHandler.postMessage({ kind:'submittedNotif', msg: 'Thank you for your submission'});
}

繰り返しますが、をドロップしself.port.emit、に切り替えてself.postMessage、渡されたハンドラーでそれを呼び出します。

そして最後に、notifications.notify({ ... });呼び出しはPageMod'sonAttach()からメニューItem'sに移動されますonMessage()。つまり、そのクリックに応答して発生するすべてのことが、メニュー項目のスコープ内で発生するようになりました。

すべてが動作します。portおそらくこれはすべて振り返ってみると明らかなようですが、ドキュメントは明確ではなく明らかに混乱しています、特にとの違いpostMessage()

于 2012-04-24T20:30:11.027 に答える