Reputation: 5113
I'm using a context-menu
item click to show a dialog (using JQuery/Bootstrap) that lets users submit the text they selected to a web service via AJAX (this all works perfectly). Once submitted, I intend to display an Add-on SDK notification
to say 'Thanks for your submission'.
Now, I know I need to send a message from the content script to the Add-on script to show the notification, but my message doesn't arrive when sent from a callback function.
My add-on code (extract):
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({ ... });
})
}
});
Content-script follows. I've indicated the situations where the message arrived, and where it doesn't.
// 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 ***');
}
I'm told self
is a global object, so I shouldn't have to pass it as a parameter, surely. It's just not clear to me how trying to send via self.port.emit
should work differently depending on where it's used within the content script. I'm not aware of any threading issue, for example. Perhaps this is a gap in my JavaScript knowledge, but can anyone tell me what I'm doing wrong?
Upvotes: 0
Views: 914
Reputation: 5113
I solved my own problem. Here's how, and what I learned.
Firstly, the content-script, and the context-menu
Item's click handler:
self.on("click", function(node,data) {
self.postMessage({ kind:'submittedNotif', msg: 'Just clicked'})
showDialog( self, 'DialogName', function (response) { /* Do stuff */ });
})
Now, the old self.port.emit
got me nowhere, but switching to self.postMessage
and adding an onMessage()
to the context-menu
Item finally gives me the event I want.
I now also pass self
to the showDialog()
method [which goes against what I was told about self
being global...?!], as the parameter 'eventHandler':
function showDialog( eventHandler, str, response) {
// Dialog stuff
eventHandler.postMessage({ kind:'submittedNotif', msg: 'Thank you for your submission'});
}
Again, I drop the self.port.emit
, switching to self.postMessage
, and calling that on the handler that was passed-in.
And finally, the notifications.notify({ ... });
call gets moved from the PageMod
's onAttach()
to the menu Item's onMessage()
. In short, everything that happens in response to that click now happens within the scope of the menu item.
All works now. Perhaps this all seems obvious in retrospect - but the documentation definitely confused rather than clarified, especially the difference between port
and postMessage()
Upvotes: 0
Reputation: 5830
It isn't clear to me where the click event would come from in
self.on('click')
What you need to do instead is bind a click handler to something in the page's DOM that would get clicked, eg your dialog tha you mention. Check out this fairly simple builder example that does this by by emitting an event when a confirm dialog is shown:
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 ***');
}
Upvotes: 1