[chromium-dev] Re: [chromium-extensions] Inter-extension communication API proposal

2009-07-30 Thread James Robinson
On Tue, Jul 28, 2009 at 6:02 PM, Matt Perry mpcompl...@chromium.org wrote:

 Two suggestions (one I accidentally sent only to James):

 chrome.extension.Port:

 // ID of the extension at the other side of this port.
 String senderID;

 Port currently has a 'tab' property if the sender was a tab.  Maybe we
 should group these:

 chrome.extension.Port:
   Object sender:
 Object tab; // if the sender was a tab
 String id;  // ID of the sending extension.


 chrome.extension:



 // Open a channel to another extension with the provided ID.


 // If no extension with the provided ID exists, nothing happens.



 // Otherwise the chrome.extension.onConnectExternal event is fired


 // to all components of the extension with the provided ID each time



 // the method is called.


 // The channel can optionally be named. This name will be sent along



 // with the onConnectExternal event


 Port connectExternal(string ID, [string channelName])



 It makes more sense to me to have the API mirror the regular connect event:

   chrome.extension.connect();  // connects to my own extension

   other = new chrome.Extension('abcef...');
   other.connect();  // connects to extension abcdef...


The reason I shied away from this is that the behavior of the statement new
chrome.Extension('abdef...').connect() is very different depending on if
'abcdef...' is the ID of the extension containing that code or a different
one.  It's also not clear from the documentation what an extension should
expect to be able to do with the result of new
chrome.Extension('abcdef...').  According to
http://dev.chromium.org/developers/design-documents/extensions/content-scripts
the
available APIs in addition to connect() are the onConnect event, which
another extension should _not_ have access to, and getURL(path), which seems
like it would just return chrome-extension://abcdef.../path.  Based on that
I don't see much value in exposing the new chrome.Extension('abcdef...')
syntax for inter-extension interaction.

- James

--~--~-~--~~~---~--~~
Chromium Developers mailing list: chromium-dev@googlegroups.com 
View archives, change email options, or unsubscribe: 
http://groups.google.com/group/chromium-dev
-~--~~~~--~~--~--~---



[chromium-dev] Re: [chromium-extensions] Inter-extension communication API proposal

2009-07-30 Thread Matt Perry
On Thu, Jul 30, 2009 at 10:44 AM, James Robinson jam...@google.com wrote:

 On Tue, Jul 28, 2009 at 6:02 PM, Matt Perry mpcompl...@chromium.orgwrote:

 Two suggestions (one I accidentally sent only to James):

 chrome.extension.Port:

 // ID of the extension at the other side of this port.
 String senderID;

 Port currently has a 'tab' property if the sender was a tab.  Maybe we
 should group these:

 chrome.extension.Port:
   Object sender:
 Object tab; // if the sender was a tab
 String id;  // ID of the sending extension.


 chrome.extension:



 // Open a channel to another extension with the provided ID.


 // If no extension with the provided ID exists, nothing happens.



 // Otherwise the chrome.extension.onConnectExternal event is fired


 // to all components of the extension with the provided ID each time



 // the method is called.


 // The channel can optionally be named. This name will be sent along



 // with the onConnectExternal event


 Port connectExternal(string ID, [string channelName])



 It makes more sense to me to have the API mirror the regular connect
 event:

   chrome.extension.connect();  // connects to my own extension

   other = new chrome.Extension('abcef...');
   other.connect();  // connects to extension abcdef...


 The reason I shied away from this is that the behavior of the statement
 new chrome.Extension('abdef...').connect() is very different depending on
 if 'abcdef...' is the ID of the extension containing that code or a
 different one.


How is it different? Sounds like a bug to me.

 It's also not clear from the documentation what an extension should expect
 to be able to do with the result of new chrome.Extension('abcdef...').
  According to
 http://dev.chromium.org/developers/design-documents/extensions/content-scripts
  the
 available APIs in addition to connect() are the onConnect event, which
 another extension should _not_ have access to, and getURL(path), which seems
 like it would just return chrome-extension://abcdef.../path.  Based on that
 I don't see much value in exposing the new chrome.Extension('abcdef...')
 syntax for inter-extension interaction.


The value is consistency. extensionObject.connect() is how you open a port
to that extension. It should be the same regardless of who you're talking
to.

--~--~-~--~~~---~--~~
Chromium Developers mailing list: chromium-dev@googlegroups.com 
View archives, change email options, or unsubscribe: 
http://groups.google.com/group/chromium-dev
-~--~~~~--~~--~--~---



[chromium-dev] Re: [chromium-extensions] Inter-extension communication API proposal

2009-07-30 Thread James Robinson
[bcc chromium-dev]

On Thu, Jul 30, 2009 at 2:01 PM, Matt Perry mpcompl...@chromium.org wrote:



 On Thu, Jul 30, 2009 at 10:44 AM, James Robinson jam...@google.comwrote:

 On Tue, Jul 28, 2009 at 6:02 PM, Matt Perry mpcompl...@chromium.orgwrote:

 Two suggestions (one I accidentally sent only to James):

 chrome.extension.Port:


 // ID of the extension at the other side of this port.
 String senderID;

  Port currently has a 'tab' property if the sender was a tab.  Maybe we
 should group these:

 chrome.extension.Port:
   Object sender:
 Object tab; // if the sender was a tab
 String id;  // ID of the sending extension.


 chrome.extension:



 // Open a channel to another extension with the provided ID.


 // If no extension with the provided ID exists, nothing happens.



 // Otherwise the chrome.extension.onConnectExternal event is fired


 // to all components of the extension with the provided ID each time



 // the method is called.


 // The channel can optionally be named. This name will be sent along



 // with the onConnectExternal event


 Port connectExternal(string ID, [string channelName])



 It makes more sense to me to have the API mirror the regular connect
 event:

   chrome.extension.connect();  // connects to my own extension

   other = new chrome.Extension('abcef...');
   other.connect();  // connects to extension abcdef...


 The reason I shied away from this is that the behavior of the statement
 new chrome.Extension('abdef...').connect() is very different depending on
 if 'abcdef...' is the ID of the extension containing that code or a
 different one.


 How is it different? Sounds like a bug to me.


  It's also not clear from the documentation what an extension should expect
 to be able to do with the result of new chrome.Extension('abcdef...').
  According to
 http://dev.chromium.org/developers/design-documents/extensions/content-scripts
  the
 available APIs in addition to connect() are the onConnect event, which
 another extension should _not_ have access to, and getURL(path), which seems
 like it would just return chrome-extension://abcdef.../path.  Based on that
 I don't see much value in exposing the new chrome.Extension('abcdef...')
 syntax for inter-extension interaction.


 The value is consistency. extensionObject.connect() is how you open a
 port to that extension. It should be the same regardless of who you're
 talking to.



In extension A with id 'a', the code:

new chrome.Extension('a').connect()

would fire an onConnect event at components of extension A.  With the
proposal, doing that same line of code in extension B with id 'b' an
onConnectExternal event would be fired at components of extension A.  The
most consistent thing to do would be to use connect() and onConnect
everywhere, but an extension needs to be aware of when a connection is
coming from another component within the same extension and when it is
coming from a different extension.  Hence the
connectExternal/onConnectExternal calls instead of reusing
connect/onConnect.

- James

--~--~-~--~~~---~--~~
Chromium Developers mailing list: chromium-dev@googlegroups.com 
View archives, change email options, or unsubscribe: 
http://groups.google.com/group/chromium-dev
-~--~~~~--~~--~--~---



[chromium-dev] Re: [chromium-extensions] Inter-extension communication API proposal

2009-07-28 Thread Aaron Boodman

+chromium-dev

I think this is great. I suggest creating a wiki page with a design
for this so that we can refer to it whenever we implement, and a bug
that refers to the wiki page.

Up until now, we've been putting our designs here:
http://dev.chromium.org/developers/design-documents/extensions (see
proposed api), but that page isn't editable without a @chromium.org
account.

I've been thinking we should move that content to the wiki so that it
is editable by all. So if you want, you could be the first.


Besides that, a few minor comments:

1. I think we should add a permission for inter-extension
communication once we have a permissions mechanism. That is, an
extension should have to declare in the manifest which extensions it
would like to contact. This is just a security precaution against the
extension accidentally leaking privileges if it gets XSS'd or
something.

On Tue, Jul 28, 2009 at 10:58 AM, James Robinsonjam...@google.com wrote:

 I think that extensions should be able to communicate with each other
 using message passing.  Currently, it's possible to do something like
 this:

 var ext = new chrome.Extension('abcdefgh...');
 var port = ext.connect('channel from another world!');
 port.postMessage({message: im in ur channel});

 However, there are a few problems with this approach.  First, it's
 probably a bug that it works.  The more serious issue is that a
 onConnect event is fired at extension 'abcdefgh...' and there is no
 way for that extension to know that the port is not from a content
 script within the same extension but from another extension.  An
 extension should be able to allow other extensions to open connections
 to it, be explicitly aware of where the connection is coming from, and
 then communicate with it using the existing chrome.extension.Port
 system.

 This would require two new APIs on the chrome.extension object, based
 on the ones presented in 
 http://dev.chromium.org/developers/design-documents/extensions/content-scripts:

 // Open a channel to another extension with the provided ID.
 // If no extension with the provided ID exists, nothing happens.
 // Otherwise the chrome.extension.onConnectExternal event is fired
 // to all components of the extension with the provided ID each time
 // the method is called.
 // The channel can optionally be named. This name will be sent along
 with the
 // onConnectExternal event
 Port connectExternal(String ID, [String channelName])

2. I think we can merge connect() and connectExternal() by adding an
optional param to connect() that specifies the target extension. If
omitted it defaults to the current extension.

 // Fired when another extension opens a channel to this extension via
 // chrome.extension.connectExternal().
 // If a channelName was provided, it is accessible via port.name.
 Event onConnectExternal(Object port)

 In order for an extension to know what the other side of a connection
 is I'd also propose adding the following property to the
 chrome.extension.Port class:

 // ID of the extension at the other side of this port.
 String senderID;

 An extension could check this field in the onConnectExternal handler
 and compare it to a whitelist/blacklist to decide whether to attach
 onMessage handlers.  An extension might also want to expose some UI to
 the user listing all connected extensions.

 The other issue to address is startup order.  The order in which the
 scripts within different background pages is not defined, which is
 entirely reasonable, but it means that doing the obvious thing:

 script
 var port = chrome.extension.connectExternal('abcdef..');
 /script

 would work unreliably depending on the exact order in which the
 background pages get loaded, the event handlers get registered, and
 the events are fired.  To resolve this I think that all connectExternal
 () events be queued until each extension's background page has loaded,
 so that any handler registration code in top-level scripts has a
 chance to run.

This seems reasonable. It might be possible to be even cleverer if we
know who wants to connect to who by way of what they declare in their
manifests.

- a

--~--~-~--~~~---~--~~
Chromium Developers mailing list: chromium-dev@googlegroups.com 
View archives, change email options, or unsubscribe: 
http://groups.google.com/group/chromium-dev
-~--~~~~--~~--~--~---



[chromium-dev] Re: [chromium-extensions] Inter-extension communication API proposal

2009-07-28 Thread Aaron Boodman

On Tue, Jul 28, 2009 at 11:30 AM, Drew Wilsonatwil...@chromium.org wrote:
 SGTM. Note that we're essentially duplicating (assumedly intentionally so)
 the window.postMessage() APIs which require specifying a target domain and
 whose connect event has a source and origin attribute specifying the
 window that sent the message.

Yeah, intentionally so. It seemed OK in this instance to not try and
couple ourselves directly to postMessage() since the shape of
extensions and web pages are slightly different.

In the future, if it gets easier to use IDL (I hear other teams on
Chromium are working on this), we might adopt something closer to
postMessage().

 It's an excellent point about connectExternal and startup ordering - in
 fact, one of the problems with window.postMessage now is that there's no
 guarantee that your message will be delivered if the target window has not
 loaded yet.

I brought this up in the original design discussions, that messages
should be queued until the page either loads or fails. Web platform
APIs should be deterministic!

Blech. In extensions, we queue the messages :).

- a

--~--~-~--~~~---~--~~
Chromium Developers mailing list: chromium-dev@googlegroups.com 
View archives, change email options, or unsubscribe: 
http://groups.google.com/group/chromium-dev
-~--~~~~--~~--~--~---



[chromium-dev] Re: [chromium-extensions] Inter-extension communication API proposal

2009-07-28 Thread James Robinson
Thanks for the feedback.  I've created
http://code.google.com/p/chromium/wiki/InterExtensionCommunication with the
proposal and would appreciate if someone with an @chromium account could
link to it from
http://dev.chromium.org/developers/design-documents/extensions.  I copied
the proposal pretty much unchanged to get the page started but since it's a
wiki anyone should be able to edit freely.  Some comment replies inline:

On Tue, Jul 28, 2009 at 2:30 PM, Drew Wilson atwil...@chromium.org wrote:

 SGTM. Note that we're essentially duplicating (assumedly intentionally so)
 the window.postMessage() APIs which require specifying a target domain and
 whose connect event has a source and origin attribute specifying the
 window that sent the message. It might be valuable to just explicitly adopt
 those interfaces wholesale, substituting extension IDs for domains.
 It's an excellent point about connectExternal and startup ordering - in
 fact, one of the problems with window.postMessage now is that there's no
 guarantee that your message will be delivered if the target window has not
 loaded yet.

 -atw

 On Tue, Jul 28, 2009 at 11:19 AM, Aaron Boodman a...@chromium.org wrote:


 +chromium-dev

 I think this is great. I suggest creating a wiki page with a design
 for this so that we can refer to it whenever we implement, and a bug
 that refers to the wiki page.

 Up until now, we've been putting our designs here:
 http://dev.chromium.org/developers/design-documents/extensions (see
 proposed api), but that page isn't editable without a @chromium.org
 account.

 I've been thinking we should move that content to the wiki so that it
 is editable by all. So if you want, you could be the first.


 Besides that, a few minor comments:

 1. I think we should add a permission for inter-extension
 communication once we have a permissions mechanism. That is, an
 extension should have to declare in the manifest which extensions it
 would like to contact. This is just a security precaution against the
 extension accidentally leaking privileges if it gets XSS'd or
 something.


I agree completely.




 On Tue, Jul 28, 2009 at 10:58 AM, James Robinsonjam...@google.com
 wrote:
 
  I think that extensions should be able to communicate with each other
  using message passing.  Currently, it's possible to do something like
  this:
 
  var ext = new chrome.Extension('abcdefgh...');
  var port = ext.connect('channel from another world!');
  port.postMessage({message: im in ur channel});
 
  However, there are a few problems with this approach.  First, it's
  probably a bug that it works.  The more serious issue is that a
  onConnect event is fired at extension 'abcdefgh...' and there is no
  way for that extension to know that the port is not from a content
  script within the same extension but from another extension.  An
  extension should be able to allow other extensions to open connections
  to it, be explicitly aware of where the connection is coming from, and
  then communicate with it using the existing chrome.extension.Port
  system.
 
  This would require two new APIs on the chrome.extension object, based
  on the ones presented in
 http://dev.chromium.org/developers/design-documents/extensions/content-scripts
 :
 
  // Open a channel to another extension with the provided ID.
  // If no extension with the provided ID exists, nothing happens.
  // Otherwise the chrome.extension.onConnectExternal event is fired
  // to all components of the extension with the provided ID each time
  // the method is called.
  // The channel can optionally be named. This name will be sent along
  with the
  // onConnectExternal event
  Port connectExternal(String ID, [String channelName])

 2. I think we can merge connect() and connectExternal() by adding an
 optional param to connect() that specifies the target extension. If
 omitted it defaults to the current extension.


This sounds like it should be possible, but since connect() takes an
optional param 'name' of type string already and the ID will also be of type
string it seems like this would be ambiguous.




  // Fired when another extension opens a channel to this extension via
  // chrome.extension.connectExternal().
  // If a channelName was provided, it is accessible via port.name.
  Event onConnectExternal(Object port)
 
  In order for an extension to know what the other side of a connection
  is I'd also propose adding the following property to the
  chrome.extension.Port class:
 
  // ID of the extension at the other side of this port.
  String senderID;
 
  An extension could check this field in the onConnectExternal handler
  and compare it to a whitelist/blacklist to decide whether to attach
  onMessage handlers.  An extension might also want to expose some UI to
  the user listing all connected extensions.
 
  The other issue to address is startup order.  The order in which the
  scripts within different background pages is not defined, which is
  entirely reasonable, but 

[chromium-dev] Re: [chromium-extensions] Inter-extension communication API proposal

2009-07-28 Thread Aaron Boodman

On Tue, Jul 28, 2009 at 12:09 PM, James Robinsonjam...@google.com wrote:
 Thanks for the feedback.  I've
 created http://code.google.com/p/chromium/wiki/InterExtensionCommunication with
 the proposal and would appreciate if someone with an @chromium account could
 link to it

Done. I also created a bug:
http://code.google.com/p/chromium/issues/detail?id=17910

 This sounds like it should be possible, but since connect() takes an
 optional param 'name' of type string already and the ID will also be of type
 string it seems like this would be ambiguous.

Yeah, I don't feel too strongly about it. I was bringing it up more as
a possibility. I presume that whenever someone implements this they
will pick the best of the several ways to phrase this.

 We'll always know what extension the onConnectExternal event will be fired
 at when the connectExternal() call is made, so at the very least we could
 promise that no onConnectExternal event will be fired at an extension until
 its background page, if there is one, has fully loaded.  Queuing until all
 extensions' background pages load is a simpler way to guarantee the same
 thing.

 Using the manifests could be a way to have a clever implementation, but in
 general the best you can get out of manifests is a partial order of
 extensions and you might get cycles.

True. I guess I am worried about blocking an extension from
communicating with, eg, itself, until all other extensions have loaded
their background pages. This doesn't seem fair.

- a

--~--~-~--~~~---~--~~
Chromium Developers mailing list: chromium-dev@googlegroups.com 
View archives, change email options, or unsubscribe: 
http://groups.google.com/group/chromium-dev
-~--~~~~--~~--~--~---



[chromium-dev] Re: [chromium-extensions] Inter-extension communication API proposal

2009-07-28 Thread Aaron Boodman

On Tue, Jul 28, 2009 at 12:20 PM, Aaron Boodmana...@chromium.org wrote:
 We'll always know what extension the onConnectExternal event will be fired
 at when the connectExternal() call is made, so at the very least we could
 promise that no onConnectExternal event will be fired at an extension until
 its background page, if there is one, has fully loaded.  Queuing until all
 extensions' background pages load is a simpler way to guarantee the same
 thing.

 Using the manifests could be a way to have a clever implementation, but in
 general the best you can get out of manifests is a partial order of
 extensions and you might get cycles.

 True. I guess I am worried about blocking an extension from
 communicating with, eg, itself, until all other extensions have loaded
 their background pages. This doesn't seem fair.

I like your other proposal best, of just queuing onConnect events
fired at an extension until its background page has loaded. We should
do this for extensions talking to themselves, too.

- a

--~--~-~--~~~---~--~~
Chromium Developers mailing list: chromium-dev@googlegroups.com 
View archives, change email options, or unsubscribe: 
http://groups.google.com/group/chromium-dev
-~--~~~~--~~--~--~---



[chromium-dev] Re: [chromium-extensions] Inter-extension communication API proposal

2009-07-28 Thread Matt Perry
Two suggestions (one I accidentally sent only to James):

chrome.extension.Port:

// ID of the extension at the other side of this port.
String senderID;

Port currently has a 'tab' property if the sender was a tab.  Maybe we
should group these:

chrome.extension.Port:
  Object sender:
Object tab; // if the sender was a tab
String id;  // ID of the sending extension.


chrome.extension:



// Open a channel to another extension with the provided ID.


// If no extension with the provided ID exists, nothing happens.



// Otherwise the chrome.extension.onConnectExternal event is fired


// to all components of the extension with the provided ID each time



// the method is called.


// The channel can optionally be named. This name will be sent along



// with the onConnectExternal event


Port connectExternal(string ID, [string channelName])



It makes more sense to me to have the API mirror the regular connect event:

   chrome.extension.connect();  // connects to my own extension

   other = new chrome.Extension('abcef...');
  other.connect();  // connects to extension abcdef...

--~--~-~--~~~---~--~~
Chromium Developers mailing list: chromium-dev@googlegroups.com 
View archives, change email options, or unsubscribe: 
http://groups.google.com/group/chromium-dev
-~--~~~~--~~--~--~---