From Browser to Browser. (1)

- - posted in gaia | Comments

Firefox OS

System app

Exactly, Firefox OS, also known for boot 2 gecko, is having only one app/one page. It’s the system app, which controls all web app’s life cycle. When FirefoxOS is booted, it would load the system app from system/index.html. Then system app would take care of the remaing stuff.

  • Load modules
  • Init homescreen app
  • Etc.

Window Manager

Window Manager is the core of Firefox OS, the core of system app, which is in charge of creating/maintaining/killing apps. An app, indeed, is a web page.

We use a magic, calling browser API, to make a web page act like an app.

Browser API

See https://developer.mozilla.org/en-US/docs/DOM/Using_the_Browser_API

A browser here means that the web page acts like it is living in a browser frame. We are replacing nearly every XUL-based UI with HTML to port the WEB to the phone.

Module Pattern

Module pattern is the way Window Manager being imeplemented. A module pattern looks like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var WindowManager = (function() {
  var _id = 0;
  var _running = {};
  function createApp() {
     var app = new App();
     _running[_id] = app;
     _id++;
     return app;
  }

  function killApp(id) {
    delete _running[id];
  }

  return {
    create: createApp,
    kill: killApp
  }
})();

Thus the Window Manager object only has 2 public attributes. This looks fine, but it would be a nightmare if this pattern grows to over 2000 lines. And it’s having countless private functions now.

This module now is not unit testable nor maintainable.

Break it!

From the browser to the browser

Let’s define a new object to contain and manage itself in its own scope.

It’s called browserFrame.

The responsibility of browserFrame

It would create an iframe with all attributes needed for BrowserAPI.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
'use strict';

/* Define a basic mozbrowser iframe class.
 * It creates a mozbrowser iframe,
 * and finally returns the DOM element it just created.
 */

var BrowserFrame = (function invocation() {
  function BrowserFrame() { // This constructor function is a local variable.
    this.element = null;
    this.id = nextId++;
    this.callbacks = {};
    createFrame.apply(this, arguments); // All arguments are values to createFrame
  }

  BrowserFrame.className = 'browser';

  // These are helper functions and variables used by the methods above
  // They're not part of the public API of the module, but they're hidden
  // within this function scope so we don't have to define them as a
  // property of Browser or prefix them with underscores.
  function createFrame(url, origin, name, manifestURL, oop) {
    var browser = document.createElement('iframe');
    browser.setAttribute('mozallowfullscreen', 'true');

    // Most apps currently need to be hosted in a special 'mozbrowser' iframe.
    // They also need to be marked as 'mozapp' to be recognized as apps by the
    // platform.
    browser.setAttribute('mozbrowser', 'true');

    if (oop)
      browser.setAttribute('remote', 'true');

    if (manifestURL)
      browser.setAttribute('mozapp', manifestURL);

    if (origin)
      this.origin = origin;

    if (name)
      this.name = name;

    browser.src = url;

    browser.id = this.className + this.id;

    browser.classList.add(BrowserFrame.className);

    // Store the element
    this.element = browser;
  };

  var nextId = 0;
  // The public API for this module is the Browser() constructor function.
  // We need to export that function from this private namespace so that
  // it can be used on the outside. In this case, we export the constructor
  // by returning it. It becomes the value of the assignment expression
  // on the first line above.
  return BrowserFrame;
}()); // Invoke the function immediately after defining it.

Comments