Mar 22, 2012, 6:34:21 PM3/22/12
to dev-platform, dev-apps...@lists.mozilla.org
Hi everybody - I wanted to sum up some recent thinking about "Social in Firefox" and ask for feedback on some concrete implementation ideas.
Let's keep followups in dev-apps-firefox unless there is a stricly platform issue. Mounir's right, forking is bad for human brains.
As context for all this, I'll offer that social activity is, for many of our users, the main reason they use a browser. Facebook, Tumblr, Pinterest, Twitter, LinkedIn, GooglePlus, and sites like them are the hubs and spokes of many user's online lives - and yet, unlike search, we don't offer our users any tools to help navigate and manage relationships with them.
We'd like to provide an opt-in way for users to use Firefox to have a more active, "always visible" relationship with these services. If users don't want any of this, they never see it. But if they switch it on, we'd like to make a set of social interactions more pleasant, easy, and engaging. We propose to do this in-content - rather than by tying into server-provided APIs - but with content that is drawn in different places, with different life cycles, than typical web-navigation content.
The basic set of interactions we'd like to support are:
* To manage a list of social services (discover, install, delete)
* To display to the user which social services they are currently signed in to
* To easily sign in and out of a service, and to switch which service the user is interacting with, or to switch off social interaction
* To recommend the current page to their friends on a network - either as a standalone URL or with a comment.
* To see which of a user's contacts are online
* To initiate real-time communication with a contact through chat, voice, or video
* To see updates from contacts and to be notified when new updates are available
* To receive, at the user's discretion, ambient or immediate notification when interesting events have occurred
The new APIs are fairly small and focused but they would have implications for resource consumption and the interactions with the browser window. They would not be available to vanilla webpages - only to pages loaded into "special" browser elements. Specifically, I propose that Firefox would:
1. Manage a list of social service providers.
2. Run a long-running worker, per provider, with the ability to maintain a network pipe to the server
We've made a prototype where we essentially do this:
1. Make an iframe on the hidden window
2. Set the src of the iframe to the URL of some "worker.js" (read from the provider's metadata)
3. When the JS has loaded, make a Sandbox whose prototype is linked to the provider's principal
4. Import the WebSocket, indexedDB, XMLHttpRequest,
atob/btoa, and timeout/interval functions from the iframe's window into the Sandbox
5. eval the text content of the frame in the Sandbox
6. as connections to the worker are made, invoke an "onconnect" handler in the Sandbox
(which is the provider's responsibility to implement), passing in a bidrectional MessagePort.
It's not a full Worker, as it's just running on the main thread - but the API would be designed to be asynchronous and ready to run inside a worker. It can respond to messages from content and receive both WebSocket-pushed and XMLHttpRequest-long-poll-based I/O. To a developer it feels like a Shared Worker so we have a small delta if we go down that path in the future. Managing resource consumption on this worker, which is hidden, is obviously a concern, and ideas are really welcome. The new global compartment checking will help for sure.
In addition to the window API described in #5, I propose that we also expose the IdleService to this worker. This would make chat and presence applications much easier to get right.
3. Offer a portion of browser window visual space to the service provider for content.
This could take the form of a sidebar, or a chunk of the navigation bar. We have prototyped an element that can zoom between a small rectangular element to the right of the search box and a full-height sidebar which includes the navbar and content region. When "minimized" the element can be used for "who am I signed in as" and notification/badge content ("you have X new messages"). The URLs for this content would be retrieved from the service provider metadata. On mobile, this could take the form of a sideswipe bar. A navigation-bar toolbar button would be made available to switch between the user's installed providers on a per-window basis.
A new API would be made available to content running in this sidebar to get a reference to the long-running worker, if any, from which postMessage and onMessage communication could run. This API would not be made available to normal service provider content; only content running in the "provider" context would see it.
4. Offer an always-on "recommend/share this" button in the navigation/location bar, or on a swipe/gesture.
(Nomenclature note - we're distinguishing between the "single bit" action, which we call "recommend" and the more involved action, which we call "share". A Like, comment-free-Digg, or +1 is a recommend; a tweet with some explanatory text is a share.)
In the current prototypes for Share, this button goes in the URL bar next to the bookmark, frecency, and reload glyphs. It could obviously also have a keyboard shortcut, etc.
We've talked about a lot of possible interactions for this - one of the simplest is that, for whatever the currently selected service provider is, we pull a 16x16 icon from the metadata (or in response to a message fired at the worker), and style the button with that. A click on the button dispatches an event to the worker, with the URL of the current page. We could do a second click for "add a comment" (converting a "recommend" into a "share"), or we could do a click-and-hold, or we could do a doorhanger panel on the first click with the understanding that if there is no further interaction it was just a recommend.
5. Offer an API to create a service-pinned window
Chat, voice, and video interactions are a poor match for page-scoped data - they tend to have their own lifespan which is longer, or shorter, than a typical page view. I propose that we offer an API to create a new window (browser, that is - it may or may not be a new ChromeWindow) that is "pinned" to a service provider, with the intent that it would be primarily used for these communications.
The window would have access to the Worker (as described in #3); it could offer minimal navigation chrome since the URL isn't relevant; perhaps we display the domain name and some way of getting at the certificate and that's it. Any attempt to navigate away from the service provider's domain would be intercepted and directed back at a tabbedbrowser in another window. "Deactivating" the service provider would close all the service-pinned windows.
The browser element created this way could float in a window, or be pinned to a ChromeWindow, perhaps by stacking along the bottom. Creative ideas for how to handle this in mobile?
That's the basics. Now, some more speculative ideas...
6. Interact with WebContacts to pull contacts from the provider.
The WebContacts system (see bug #674720) could use a postMessage-based protocol to get contact data directly from the service provider without any adapters or glue.
7. Offer the Notifications API to service provider content
The Notification constructor (see bug #573588 and recent dev-webapps and b2g threads) could be exposed directly to the Worker, allowing providers that are not currently visible a way to indicate to the user that interesting data is available. The notifications need not be delivered to the OS right away - they could easily be queued, in a service-provider keyed way, until the user indicates a desire to see them. The B2G team has lots of creative possibilities here.
If you want to chat realtime, we're hanging out in #socialdev on IRC.
Mike & the social hacking team