Firefox Social Integration Design Spec
Note that this is the backend for the 'back-end of the Social Browsing feature. User-facing features are defined in the Firefox Social Integration User Interface Design Spec.
Social Browsing for Firefox
The engineering goal of this project is to define a robust platform for Social Service integration in the browser. It should
- Support both "built-in" services (e.g. distributed with the browser) and discovery of new services from web browsing activity
- Support the development of new UX features, and of new addons, which use the user's social services
Social Service Provider
A new object, a "social service provider," is defined and implemented.
A provider has a name, an icon URL, an origin, an optional Worker URL, and an optional Sidebar URL. Data URLs are supported.
The Provider object supports the additional notion of a "built-in" provider, which has some additional capabilities that are not available to providers that are installed from arbitrary content. Built-in providers are included from the Firefox distribution or installed through chrome-privileged code. Specifically a built-in provider may:
- Specify an arbitrary "origin" for their code
- Provide a contentPatch which is applied to content windows created for that provider.
Social Service Registry
A new XPCOM service provides a registry of social services. The registry is initialized at startup. It loads the list of services from a mozIStorageService-mediated database, and populates the list with the "builtin" providers when a new profile is loaded.
It supports the API:
- get/set enabled(boolean): Enables, or disables, the entire Social Browsing feature.
- activateProvider(origin): Activates a service provider (see below)
- deactivateProvider(origin): Deactivates a service provder (see below)
- each(cb): iterates over all providers calling cb on each
- get(origin): returns the provider with the given origin
- get/set currentProvider(provider): Gets/sets a provider as the "selected" provider.
- remove(origin, cb): Removes a provider from the registry, calling the callback when done
- register(manifest): Adds a provider to the registry (see installation notes below)
- observe(subject, topic, data): Observes private browsing and application quit, see below
The registry maintains an "active" bit for each service. If a service is "active", it has a FrameWorker which is running the service's Worker.
The registry broadcasts status-change notifications with these topics:
- social-browsing-enabled: sent when the user enables social browsing, or when a new provider is installed. The data is the origin of the active service.
- social-browsing-disabled: sent when the user disables social browsing. Data is null.
- social-browsing-current-service-changed: sent when the user changes the "selected" service.
- social-service-manifest-changed: sent when the list of installed providers changes. The data is the origin of the service that changed.
The registry manages these preferences:
- social.enabled: boolean, whether social browsing is enabled
- social.provider.current: the origin of the currently focused provider
- social.provider.sidebar-visible: whether the sidebar is currently visible
- social.provider.<origin-of-provider>.notifications-permitted: stores whether a provider is permitted to offer popup notifications
When private browsing is enabled, all social features are immediately turned off. When private browsing is deactivated, the active service provider and sidebar state that the browser previously had are restored.
At browser shutdown, the FrameWorkers for all active services are given a chance to close the messagePorts to their workers. This gives the workers a chance to perform final cleanup.
The user's list of service providers, and the user's preferences for social service providers, should be synchronized through Firefox Sync (P2?).
The registry supports installation of a social service provider from a JSON-encoded manifest file. The manifest file MUST be installed over SSL, and is checked against the Safe Browsing blocklist before validation. On installation, the registry validates the file as follows:
- The name field is required
- The workerURL and sidebarURL, if present, are required to be relative
- The workerURL and sidebarURL, if present, are resolved against the origin
- The iconURL is allowed to reference any domain.
The registry supports a list of "default" providers, which are included as part of the Firefox distribution. These providers are automatically installed into the registry on creation of a new profile. The packaging of the built-in providers is TBD.
The new FrameWorker object implements a W3C Worker-like API using a Sandbox pinned to a hidden IFRAME. It is used to create a headless, limited-privilege execution domain for a persistent, always-running connection to a service provider.
The FrameWorker has no "window" or "document" object. The following objects are present at global scope:
Callers may invoke a "postMessage" method on the FrameWorker to pass messages to the worker. The messages will be delivered through the MessagePort provided in the onconnect method.
XXX Note that we have found that many of these objects did not work properly when imported into a Sandbox context. Various bugfixes are in progress.
Firefox observes LINK elements with a REL of "social-provider-manifest" and a TYPE of "text/json". This element, if present, indicates that the current site can be a social service provider. Remember that this must be served over HTTPS.
This fact is noted and can be used to construct a user discovery UI. This could be an immediate popup notification, or a deferred list of options present in about:social or the popup panel. UX work TBD.
The Worker API
A message-oriented API is provided for communication to and from the Worker.
The messages sent by Firefox to this API are:
- social.initialize: Sent when the worker is created; sent before any other messages.
- social.cookie-changed: Sent when the cookie state for the service provider's origin changes. A one-second timer is used to catch multiple cookie edits so that only message is sent.
- social.notification-click: See social.notification-create below
XXX other events in response to UX interactions
The messages received by Firefox through this API are:
- social.notification-create(icon, title, body, id): If the service permits notifications (see Registry prefs, above), a new Notification is created. When the notification is clicked, a social.notification-click message with an "id" argument matching the given id is sent.
- social.ambient-notification-area(background, portrait): Provides a background color (as a string) and a user portrait (as a URL) that can be used to style an "ambient notification" area for the service provider.
- social.ambient-notification-update(background, counter, contentPanel): Indicates that Firefox should render an "ambient notification" for the provider. If the UX allows it, the "background" property should be used as the CSS "background" property of the notification element, and the "counter" property may be used as a numerical indicator of the number of pending notifications. When the user indicates focus on the notification, the "contentPanel" argument should be used as the URL of a browser element to display more detail.
A UI for managing the list of installed providers is provided. This must include a top-level switch to activate/deactivate the entire feature, and a list of providers with the ability to activate/deactivate each of them. Per-provider preferences can be managed in this UI as well; currently the only preference is the ability to present a popup notification.
This UI should be made available as about:social or as a preference pane (UX call?)