Bug 979880: Added basic view toggling utility in app router. r=dmose,r=ametaireau
authorNicolas Perriault <nperriault@gmail.com>
Thu, 29 May 2014 21:20:11 +0100
changeset 187690 16e055e25d64cd133e5b093d73897f481dfe9863
parent 187689 80911ee357f0c819b3cab4b8e429b73b2e868a66
child 187691 156565c17cbd049da892e6ec3ab862f85e5050a7
push id26931
push usermbanner@mozilla.com
push dateMon, 09 Jun 2014 22:07:01 +0000
treeherdermozilla-central@fc70d6d9a9b0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdmose, ametaireau
bugs979880
milestone32.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 979880: Added basic view toggling utility in app router. r=dmose,r=ametaireau
static/index.html
static/js/webapp.js
static/l10n/data.ini
test/webapp_test.js
--- a/static/index.html
+++ b/static/index.html
@@ -12,21 +12,25 @@
     <link rel="prefetch" type="application/l10n" href="l10n/data.ini">
   </head>
   <body onload="loop.webapp.init();">
 
     <header>
       <h1>Loop</h1>
     </header>
 
-    <div id="call-launcher">
-      <p><button class="btn">Call</button></p>
+    <div id="home">
+      <p data-l10n-id="welcome">Welcome to the Loop web client.</p>
     </div>
 
-    <div id="call" class="conversation">
+    <div id="call-launcher" class="hide">
+      <p><button class="btn btn-success" data-l10n-id="start_call">Start call</button></p>
+    </div>
+
+    <div id="call" class="conversation hide">
       <nav class="controls">
         <button class="btn" data-l10n-id="start">Start</button>
         <button class="btn" data-l10n-id="stop">Stop</button>
       </nav>
       <div class="media nested">
         <video class="remote" src="http://v2v.cc/~j/theora_testsuite/320x240.ogg"></video>
         <video class="local" src="http://v2v.cc/~j/theora_testsuite/320x240.ogg"></video>
       </div>
--- a/static/js/webapp.js
+++ b/static/js/webapp.js
@@ -3,16 +3,123 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /*global loop:true*/
 
 var loop = loop || {};
 loop.webapp = (function() {
   "use strict";
 
+  var router;
+
+  /**
+   * Base Backbone view.
+   */
+  var BaseView = Backbone.View.extend({
+    hide: function() {
+      this.$el.hide();
+      return this;
+    },
+
+    show: function() {
+      this.$el.show();
+      return this;
+    }
+  });
+
+  /**
+   * Homepage view.
+   */
+  var HomeView = BaseView.extend({
+    el: "#home"
+  });
+
+  /**
+   * Call launcher view.
+   */
+  var CallLauncherView = BaseView.extend({
+    el: "#call-launcher",
+
+    events: {
+      "click button": "launchCall"
+    },
+
+    initialize: function(options) {
+      options = options || {};
+      if (!options.token) {
+        throw new Error("missing required token");
+      }
+      this.token = options.token;
+    },
+
+    launchCall: function(event) {
+      event.preventDefault();
+      // XXX: request the loop server for call information using this.token
+    }
+  });
+
+  /**
+   * Call view.
+   */
+  var CallView = BaseView.extend({
+    el: "#call"
+  });
+
+  /**
+   * App Router. Allows defining a main active view and ease toggling it when
+   * the active route changes.
+   * @link http://mikeygee.com/blog/backbone.html
+   */
+  var Router = Backbone.Router.extend({
+    view: undefined,
+
+    routes: {
+        "": "home",
+        "call/:token": "call"
+    },
+
+    initialize: function() {
+      this.loadView(new HomeView());
+    },
+
+    /**
+     * Loads and render current active view.
+     *
+     * @param {BaseView} view View.
+     */
+    loadView : function(view) {
+      this.view && this.view.hide();
+      this.view = view.render().show();
+    },
+
+    /**
+     * Main entry point.
+     */
+    home: function() {
+      this.loadView(new HomeView());
+    },
+
+    /**
+     * Call setup view.
+     *
+     * @param  {String} token Call token.
+     */
+    call: function(token) {
+      this.loadView(new CallLauncherView({token: token}));
+    }
+  });
+
+  /**
+   * App initialization.
+   */
   function init() {
-    console.log("Loop app started.");
+    router = new Router();
+    Backbone.history.start();
   }
 
   return {
-    init: init
+    init: init,
+    BaseView: BaseView,
+    HomeView: HomeView,
+    Router: Router,
+    CallLauncherView: CallLauncherView
   };
 })();
--- a/static/l10n/data.ini
+++ b/static/l10n/data.ini
@@ -1,3 +1,11 @@
-[en-US]
+[en]
 start=Start
 stop=Stop
+start_call=Start the call
+welcome=Welcome to the Loop web client.
+
+[fr]
+start=Démarrer
+stop=Arrêter
+start_call=Démarrer l'appel
+welcome=Bienvenue sur Loop.
--- a/test/webapp_test.js
+++ b/test/webapp_test.js
@@ -1,13 +1,43 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+/* global loop */
+
 var expect = chai.expect;
 
-describe("test", function() {
+describe("Router", function() {
   "use strict";
 
-  it("is true", function() {
-    expect(true).eql(true);
+  var router;
+
+  beforeEach(function() {
+    router = new loop.webapp.Router();
+  });
+
+  describe("#constructor", function() {
+    it("should define a default active view", function() {
+      expect(router.view).to.be.an.instanceOf(loop.webapp.HomeView);
+    });
+  });
+
+  describe("#loadView", function() {
+    it("should set the active view", function() {
+      router.loadView(new loop.webapp.CallLauncherView({token: "fake"}));
+
+      expect(router.view).to.be.an.instanceOf(loop.webapp.CallLauncherView);
+    });
   });
 });
+
+describe("CallLauncherView", function() {
+  "use strict";
+
+  describe("#constructor", function() {
+    it("should require a token option", function() {
+      expect(function() {
+        new loop.webapp.CallLauncherView();
+      }).to.Throw(Error, /missing required token/);
+    });
+  });
+});