Skip to content
willscott edited this page Nov 12, 2014 · 6 revisions

Views & User Interaction

The Players:

  • freedom.js library
  • Website owner
  • Module developer

The Goals:

  • A module developer should be able to show UX to a user without worrying that the website owner using their module can introspect or change their content.
    • This becomes an unreasonable expectation when included in an extension or server-side app, since those environments act with full user permissions.
  • A website developer wants to integrate 3rd party UX into their website, like comments or a login screen, and have control over placement of that 3rd party UX within their page.
  • All resources needed by a freedom.js module can be found in its manifest, allowing the freedom.js runtime to support redistribution / offline / distribute use of modules.
  • A website owner who hasn't included placement for a view in a 3rd party module they include shouldn't result in loss of functionality. (e.g. a social provider that needs to show a login view which the site does not have code to handle should still work)

Proposal:

Internal (within freedom module) API:

This is the proposal for the methods and interface that module developer would have access to. In particular, they will declaratively specify the files contained in a view within a "views" section of the module manifest, and then ask to show and hide views by name through the core.view API. The difference from the 0.5/0.6 API proposed is twofold:

  1. view.open and view.show are merged into a single command. The filename is not specified in both the manifest and open method, but just in the manifest.
  2. view.isSecure is added to inform the module developer about the condition of the communication channel to the view, specifically whether there is a reasonable expectation that the website developer will be unable to intercept messages passed between the module and its view.

The argument passed to view.show represents a view key listed in the views section of the manifest, as shown in the following example:

view.show('myView').then(...)
view.isSecure('myView').then(...)
view.close('myView').then(...)

Where the view is named in the manifest:

{
  ...
  "views": {
    "myView": {
      "main": "mypage.html",
      "files": ["mypage.html", "mypage.css", ...]
    }
  }
}

Each view has two fields, "main" and "files". The resource specified in "main" will be loaded as the source of the opened frame or window, and must also be listed in the files array of all resources needed by the view. Any number of files may be specified in the files array, this declarative listing allows the freedom.js system to properly migrate files to appropriate origins when needed. Files can be referenced by standard relative paths within the view.

External (outside of module) API:

When instantiating freedom.js, a view handler can be provided:

var myViewHandler = function() {
  this.onOpen = function(id, name, page, resources, postMessage) {
    ...
  };
  this.onMessage = function(id, message) {
    ...
  };
  this.onClose = function(id) {
    ...
  };
};

freedom('manifest.json', {
  view: myViewHandler
}).then(...)

Messages posted to the handler must be relayed to the window of the page (via window.postMessage), and messages from the page must be passed to the postMessage function received in the open call.

Messages will be opaque to the page - the view library will wrap messages from the module such that actual content is not passed through this channel, but instead only signalling messages will be used to establish direct communication. If freedom.js assesses that these guarantees cannot be met, the return form of the isSecure function will be false, allowing the module to communicate to the user that it has not been loaded in a safe environment for sensitive data entry that should not be shared with the page.

If no handler is provided, freedom will use a built-in handler appropriate for the runtime.

TODO - Describe the existing external view API (<div id='name'>)