Yo Oliver,
I'd take offense if you weren't dead on. I've long considered the strict symmetry of our dynamic service APIs a thorn, especially when you look at the api exposed by Gears - which I find to be much more clear and idiomatic.
So here's a little bit of history and context to understand why things are the way they are. Once upon a time we allowed any function on a service to be invoked synchronously OR asynchronously. Basically, you could say something like:
CODE
foo = BrowserPlus.DragAndDrop.ListTargets({});
This would *block* the browser execution thread and go invoke the correct function. The problem was that we allowed this invocation across the board - So you could
also do something like:
CODE
bar = BrowserPlus.Uploader.upload({params});
this latter usage is a long running operation. By allowing any function to be invoked either way, we were seeing a lot of usability issues (folks were always opting for the sync usage cause it felt simpler). Add to that, some functions *should* return fast but something that the developer of the service has overlooked causes them to take a while in certain (all too common) cases... In an API review with Douglas Crockford he suggested we simply kill the sync usage, given the massive precedent in JS libraries out there today.
So that's how we got here.
How do we make things better? what platform changes would be needed to allow usage of browserplus services to be more idiomatic and pleasant to use?
Here are some things we've been talking about for a while, that really are not that much work, and I think would make the BrowserPlus world a better place:
1. Factory model. This would allow you to instantiate distinct instances of services. Given a distinct instance, you could now have multiple instances in a page and this lays the groundwork for some of the following improvements. Something like this:
CODE
BrowserPlus.create("DragAndDrop", "1", function (instance) {
// now do something with instance
instance.addDropTarget({...} , function() {});
}
NOTE: still going crazy with the async stuff and code blocks. I don't know how to "fix" this one without introducing a nasty tendency to block up the browser thread.
2. Add instance properties. This speaks to the ugly API of the DragAndDrop service. Here's the trick. You may pass callbacks to browserplus services as parameters. However, the lifetime of that callback is tied to the function invocation. This means once a function invocation returns, browserplus guarantees that your callback parameters will no longer be invoked. For things like upload progress, this is great. For drag and drop, this is really insufficient. Once we have the instances above, you could do something like:
CODE
instance.setProperty("hoverCallback", function(x) {});
So to be clear, what we lack is a clean way to set properties on "instances" of services, stuff that should persist for the lifetime of the session/pageview.
3. Javascript wrappers. This is kinda a catchall. Imagine if a service author could somehow bundle a little pile of javascript with their service. Then once you load a service that javascript is injected into your page from the local machine. This would allow service authors to craft custom APIs, and would make it much easier to do things like implement emerging standards using browserplus.
The problems with this are that while the calling conventions of services are ugly, they're symmetric and discoverable today. That lets us have the nice documentation that's in service explorer. When you let a service author create a custom javascript wrapper, you gain a perhaps more idiomatic API, but loose the ability to automatically generate documentation. Roads out of this are a) YUIDoc (or a moral equivalent) or B) });