Closed Bug 653594 Opened 13 years ago Closed 13 years ago

Problem with Panel's 'port' property

Categories

(Add-on SDK Graveyard :: General, defect)

defect
Not set
normal

Tracking

(Not tracked)

RESOLVED FIXED

People

(Reporter: wbamberg, Assigned: ochameau)

References

Details

Attachments

(1 file)

Taking the following trivial add-on:

***
var panel = require("panel").Panel({
  contentScript: "self.postMessage('showing');"
});

panel.on("message", function() {
  console.log("panel is showing");
});

panel.show();
***

If I try to change it to use 'port' as follows:

***
var panel = require("panel").Panel({
  contentScript: "self.port.emit('showing');"
});

panel.port.on("showing", function() {
  console.log("panel is showing");
});

panel.show();
***

I get this:

***
error: An exception occurred.
Traceback (most recent call last):
  File "resource://jid0-z6c2yzbah2l9exwgyvktsf9ubhg-api-utils-lib/content/worker.js", line 363, in
    get port() this._port._public,
TypeError: this._port is null
FAIL
***

A similar transformation but using page-mod works as expected.
This was due to the fact that Panel doesn't call Worker constructor immediatly,
so `port` is still not initialized when we try to access it.

Here is one way to solve this problem.
We have almost the same problem with postMessage. postMessage doesn't work until Worker constructor is called. Actually, it throw an exception saying that it has been destroyed.

With this patch I solved both: port is now defined AND we can emit an event as soon as we want! (Things that we can't do with postMessage)
Assignee: nobody → poirot.alex
Attachment #529000 - Flags: review?(myk)
Thanks Alex! On a related note, over in bug 649629 comment 4 Myk talks about setting up event listeners in the constructor: is this possible, using something like the syntax he suggests there? (Or rather: will it be possible, when this bug is fixed?)
(In reply to comment #2)
We can implement this syntax quite easily. This is unrelated to main bug 649629 issue that is specific to Widget AP. So we can work on syntax in parallel of Widget port attribute addition.
It could be a good idea to fill a specific bug for this enhancement.
(In reply to comment #3)
> (In reply to comment #2)
> We can implement this syntax quite easily. This is unrelated to main bug 649629
> issue that is specific to Widget AP. So we can work on syntax in parallel of
> Widget port attribute addition.

Sure. It just came up as I was looking at explaining how to migrate from the old style.

> It could be a good idea to fill a specific bug for this enhancement.

-> bug 653629
Blocks: 649629
Comment on attachment 529000 [details] [diff] [review]
Fix Panel.port and add unit tests.

Review of attachment 529000 [details] [diff] [review]:

Looks good, works well, r=myk!

::: packages/addon-kit/tests/test-panel.js
@@ +28,5 @@
+  test.waitUntilDone();
+  let panel = Panel({
+    contentURL: "about:buildconfig",
+    contentScript: "self.port.emit('loaded');" +
+                   "self.port.on('addon-to-content', "+

Nit: space before plus sign.

@@ +46,5 @@
+tests.testPanelEmitEarly = function(test) {
+  test.waitUntilDone();
+  let panel = Panel({
+    contentURL: "about:buildconfig",
+    contentScript: "self.port.on('addon-to-content', "+

Nit: space before plus sign.

::: packages/api-utils/lib/content/worker.js
@@ +470,5 @@
+    this._inited = true;
+    
+    // Flush all events that has been fired before the worker is initialized.
+    let self = this;
+    this._earlyEvents.forEach(function (args) self._emitEventToContent(args));

Nit: it might be better to start using .bind in these situations to avoid the extra variable definition, i.e.:

    this._earlyEvents.forEach((function (args) this._emitEventToContent(args)).
                              bind(this));
Attachment #529000 - Flags: review?(myk) → review+
a=myk for commission during freeze.
Status: NEW → RESOLVED
Closed: 13 years ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: