Closed Bug 593913 Opened 15 years ago Closed 14 years ago

support communication between objects and their individual ContentSymbionts

Categories

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

defect

Tracking

(Not tracked)

RESOLVED WONTFIX

People

(Reporter: myk, Unassigned)

Details

Some high-level APIs that use content frames create and/or interact with multiple frames per instance of some object they expose to consumers. For example, each Widget instance creates one content frame per window. Each Sidebar instance will create one content frame per sidebar open in a window. Each PageMod instance interacts with one content frame per page it modifies. And each `context-menu` Item instance might interact with one content frame per page for which it is added to the context menu (pending the outcome of API deliberations in bug 578849). The current model for communication between such object instances and the ContentSymbiont instances they create was designed to meet the needs of Panel, which only creates a single content frame for each Panel. Nevertheless, I think the model is still going to work ok for these other APIs. But we may want to enhance it to provide a way for objects to communicate with their ContentSymbionts individually. Over in bug 588737, we are making some changes to the ContentSymbiont API in order to make it more similar to Web Workers <http://www.whatwg.org/specs/web-workers/current-work/>. At first glance, however, Web Workers is not particularly instructive regarding this issue. Web Workers does describe a way for multiple JavaScript contexts to share access to the same worker. But our case is different, because in our case we want a single object to have exclusive access to multiple ContentSymbionts. My initial thinking is that we should continue to allow consumers to call postMessage on objects to post messages to all of the object's ContentSymbionts as well as to register "message" event handlers on objects that receive messages from all of its ContentSymbionts (i.e. keep the existing model, extending it to work transparently with multiple ContentSymbionts per object). However, for consumers that want to communicate with specific ContentSymbionts, we should add a "ContentScriptStart" event to objects that fires each time an object creates a ContentSymbiont and whose parameter list includes a Port instance for communicating with the specific ContentSymbiont. let pageMod = require("page-mod").PageMod({ ... }); pageMod.on("ContentScriptStart", function(port) { port.postMessage("Hello, content script!"); port.on("message", function(message) { console.log("A content script says what? " + message); } }; The Port might also provide additional information that allows an object to uniquely identify the ContentSymbiont with which it is communicating, like a reference to a Window (in the case of Widget and Sidebar) or a Tab (in the case of PageMod and context-menu Item). We might also add a `ports` property to objects that is a read-only enumerable Collection or List (bug 588728) of ports, so consumers can iterate ports and selectively communicate with them (f.e. to let page mods for certain pages know when there is updated information for those pages). Dietrich, Drew, Irakli: do y'all have any thoughts on this proposed API? Note: this is not an 0.8 blocker, since it is not necessary to enable communication with specific ContentSymbionts in order to make these APIs E10S-compatible. For E10S-compatibility, it is sufficient to implement a single postMessage/message handler interface that communicates with all ContentSymbionts. We can add this API as an enhancement to the existing feature set in a future release (0.9?).
Please find my thoughts inline: (In reply to comment #0) > Some high-level APIs that use content frames create and/or interact with > multiple frames per instance of some object they expose to consumers. > > For example, each Widget instance creates one content frame per window. Each > Sidebar instance will create one content frame per sidebar open in a window. > Each PageMod instance interacts with one content frame per page it modifies. > And each `context-menu` Item instance might interact with one content frame per > page for which it is added to the context menu (pending the outcome of API > deliberations in bug 578849). > > The current model for communication between such object instances and the > ContentSymbiont instances they create was designed to meet the needs of Panel, > which only creates a single content frame for each Panel. > > Nevertheless, I think the model is still going to work ok for these other APIs. > But we may want to enhance it to provide a way for objects to communicate with > their ContentSymbionts individually. > > Over in bug 588737, we are making some changes to the ContentSymbiont API in > order to make it more similar to Web Workers > <http://www.whatwg.org/specs/web-workers/current-work/>. At first glance, > however, Web Workers is not particularly instructive regarding this issue. > > Web Workers does describe a way for multiple JavaScript contexts to share > access to the same worker. But our case is different, because in our case we > want a single object to have exclusive access to multiple ContentSymbionts. > > My initial thinking is that we should continue to allow consumers to call > postMessage on objects to post messages to all of the object's ContentSymbionts > as well as to register "message" event handlers on objects that receive > messages from all of its ContentSymbionts (i.e. keep the existing model, > extending it to work transparently with multiple ContentSymbionts per object). > > However, for consumers that want to communicate with specific ContentSymbionts, > we should add a "ContentScriptStart" event to objects that fires each time an > object creates a ContentSymbiont and whose parameter list includes a Port > instance for communicating with the specific ContentSymbiont. > > let pageMod = require("page-mod").PageMod({ ... }); > pageMod.on("ContentScriptStart", function(port) { > port.postMessage("Hello, content script!"); > port.on("message", function(message) { > console.log("A content script says what? " + message); > } > }; > That's exactly an API I use for sidebars with an only difference being that "open" / "close" events are emitted instead of "ContentScriptStart" / "ContentScriptStop". BTW it matches API from node.js http://nodejs.org/api.html#net-server-204 and some devs may benefit from that. > The Port might also provide additional information that allows an object to > uniquely identify the ContentSymbiont with which it is communicating, like a > reference to a Window (in the case of Widget and Sidebar) or a Tab (in the case of PageMod and context-menu Item). I would rather keep it without additions, keeping in mind that reference to the window shouldn't be possible in the scope where symbiont is initialized (it's a non ui process). If we get a feedback from users that they absolutely need that we can think of ways how to identify tab / window and expose that id as property of port. > > We might also add a `ports` property to objects that is a read-only enumerable > Collection or List (bug 588728) of ports, so consumers can iterate ports and > selectively communicate with them (f.e. to let page mods for certain pages know > when there is updated information for those pages). > I don't think we either have to add property with list of open ports, for exactly same reasons why we are not exposing list of the listeners. Besides maintaining such a list is pretty easy if we have open / close events. As an alternative we can provide example in the docs how to have this list. BTW as I mentioned node.js API's are almost the same and I never had a need of maintaining list of connected clients since listeners are defined in the lexical scope where port references to the associated listener. > Dietrich, Drew, Irakli: do y'all have any thoughts on this proposed API? > > Note: this is not an 0.8 blocker, since it is not necessary to enable > communication with specific ContentSymbionts in order to make these APIs > E10S-compatible. For E10S-compatibility, it is sufficient to implement a > single postMessage/message handler interface that communicates with all > ContentSymbionts. We can add this API as an enhancement to the existing > feature set in a future release (0.9?).
(In reply to comment #1) > That's exactly an API I use for sidebars with an only difference being that > "open" / "close" events are emitted instead of "ContentScriptStart" / > "ContentScriptStop". That seems reasonable for Sidebar. I'm not sure how well they work for the other APIs, though. Something to noodle on. > I would rather keep it without additions, keeping in mind that reference to > the window shouldn't be possible in the scope where symbiont is initialized > (it's a non ui process). By Window and Tab, I actually meant the Window and Tab objects exposed by the windows and tabs modules, which are safe to expose in the addon process. > If we get a feedback from users that they absolutely need that > we can think of ways how to identify tab / window and expose that id as > property of port. Sure, we can leave that for later. It was just an idea. > I don't think we either have to add property with list of open ports, for > exactly same reasons why we are not exposing list of the listeners. Besides > maintaining such a list is pretty easy if we have open / close events. The reasoning is actually different than for event listeners, where we don't expose the list of listeners in order to prevent modules from accessing each others' listeners. In this case, ports are always specific to a particular instance of an object, which is itself specific to a particular module. So it's possible to expose the list of them, and doing so would make it easier to iterate them (because you wouldn't have to collect them on "open"). Nevertheless, as you mentioned, it isn't that complicated to collect them on "open", so it's probably worth leaving this out and seeing how common it is for folks to want to iterate ports before deciding to add this functionality.
The Add-on SDK is no longer a Mozilla Labs experiment and has become a big enough project to warrant its own Bugzilla product, so the "Add-on SDK" product has been created for it, and I am moving its bugs to that product. To filter bugmail related to this change, filter on the word "looptid".
Component: Jetpack SDK → General
Product: Mozilla Labs → Add-on SDK
QA Contact: jetpack-sdk → general
Version: Trunk → unspecified
We're working on this for the Widget API in another bug. We should address this there (and then have separate bugs for each additional API we need to modify to acquire whatever mechanism we decide upon).
Status: NEW → RESOLVED
Closed: 14 years ago
Resolution: --- → WONTFIX
You need to log in before you can comment on or make changes to this bug.