Labs/F1/Modularity/WebMod-API
F1 defines the following javascript postMessage/jschannel based APIs.
For simplicity, the functions are described as if they are regular blocking functions (ie, they specify a return value). However, as they are implemented using jschannels, the actual implementation will be that the caller obtains the "return value" via jschannel 'success' callback.
Authentication
Note: This section is just ideas from markh. Alternative ideas can be found at http://etherpad.mozilla.com:9000/howa. Further, authentication is so fundamental that the agreed authentication spec should be formalized in the OWA specification rather than the F1 specification (ie, this section should be moved!)
The APIs used for authentication also provide the functionality for obtaining information about the user, such as their name, favicon, etc.
To be implemented by the app (ie, APIs called by F1)
getUserInfos()
Returns an object with users and optionally login attributes.
users is a list of infos for each logged in user to the service. If the list contains more than 1 item, multiple accounts against that service are being used (eg, 2 twitter accounts are configured). The user-info will include some pre-defined fields (eg, name, username, avatar, logout/revoke related links, etc) and any other values the service desires. The full user info (including the service specific "blobs") will be passed back into the service for many future operations.
Note that these user infos are not stored by F1 or the browser - but the app itself is free to manage the storage of credentials etc itself. Thus, the service specific data should not contain the credentials but instead could be used to identify the user when multiple accounts are supported (eg, it may store an internal "user id" used internally by the app to locate the specific credentials.)
Optionally, the return value will include login object, itself with a number of attributes which specify alternative login methods. Eg, a dialog entry can specify a URL which will be loaded in a popup Window created by F1. Services which only allow one user at a time will only return the login object when the list of logged-in users is zero. Services which allow multiple users/accounts will return this object even when there are returned users.
When login is required/desired and a 'dialog' method is supported, F1 will open the popup and establish a postMessage channel between the popup and the invisible iframe, so the login screen and the application itself can directly communicate. When login is complete, the app itself will be able to communicate this back to F1 (which will then re-execute this request and presumably get an extra user in the returned list, and adjust the UI accordingly)
Example
In these examples, we assume the service only uses a popup-based login technique. If no users are currently logged in, the result might be:
{users: [], login: {dialog: 'https://example.com/login'}}
If one user is logged in and the user only supports a single user, the result might be:
{users: [{name: 'Joe Blow', userid: 'joeblow', favicons: [...]]}
If one user is logged in but the service supports logging in multiple users, the result might be:
{users: [{name: 'Joe Blow', userid: 'joeblow', favicons: [...]], login: {dialog: 'https://example.com/login'}}
To be implemented by F1 (ie, APIs called by the app)
userInfosChanged()
Inform F1 that the list of logged-in users for the app has changed. F1 will refresh the service by calling getUserInfos() and adjust itself accordingly - eg, by creating a second visible iframe for the service if a new user appears, or displaying special UI if no logins exist at all.
Sharing
To be implemented by the app (ie, APIs called by F1)
Get enough metadata about the application so the necessary UI for the service can be dynamically built. This is similar to the current F1 "services" global, and allows F1 to offer "send to wall" for facebook versus "send to my contacts" for linkedin.
The result is an object with the following fields (mostly taken from the current F1 implementation)
- name
- The (localized) name of the service as displayed to the user. If 'serviceUrl' is specified, the name will be rendered as a link to that URL, otherwise it will be rendered as plain text.
- serviceUrl
- The main URL for this service.
- icon
- The favicon to be displayed for this service.
- subject
- Whether the app supports a 'subject' field.
- shareTypes
- A list of ways an item can be shared with this service. If the service supports direct messaging, then this must be reflected in shareTypes. Each element in the list may have fields type (an identifier passed back to the service if this item is selected), label (what is shown to the user) and toLabel (the label for the 'to' field - if not specified, the 'to' field is hidden)
- textLimit
- The maximum number of characters allowed. If specified, a counter will be displayed and the limit will be enforced.
- shorten
- A boolean indicating if links must be shortened. (XXX - is this necessary? Can't we determine whether to shorten links based on the specified textLimit and the amount of text currently entered?)
getAutocompleteEntries(user_info, send_to, to_prefix, callback)
Get all the autocomplete entries for the "to" field based on the current setting of the "send to" field for the specified user. For example, the facebook app might return the list of all groups you are a member of if send_to="group wall", and twitter would send a list of all your followers for send_to="direct".
send(user_info, data)
Send an item as described by "data" - ie, perform the actual share.