changeset 52:d5efcc6476d9

Factored out base and postMessage-server logic from index.js into two new files, added a new Ajax global that's decoupled from jQuery, and decoupled the base and postMessage-server logic from jQuery.
author Atul Varma <avarma@mozilla.com>
date Sat, 26 Jun 2010 20:42:06 -0700
parents 71686dfb845d
children 18de6b362cc5
files static-files/index.html static-files/index.js static-files/server.js static-files/summit-idp.js
diffstat 4 files changed, 240 insertions(+), 195 deletions(-) [+]
line wrap: on
line diff
--- a/static-files/index.html	Sun Jun 27 01:41:45 2010 +0000
+++ b/static-files/index.html	Sat Jun 26 20:42:06 2010 -0700
@@ -616,7 +616,7 @@
 <script src="jquery-ui-1.8.2.custom.min.js"></script>
 <script src="uni-form.jquery.js"></script>
 <script src="showdown.js"></script>
-<script src="api.js"></script>
+<script src="summit-idp.js"></script>
 <script src="index.js"></script>
 </body>
 </html>
--- a/static-files/index.js	Sun Jun 27 01:41:45 2010 +0000
+++ b/static-files/index.js	Sat Jun 26 20:42:06 2010 -0700
@@ -1,148 +1,3 @@
-// -----------------------------------------------------------------------
-// Config object
-// -----------------------------------------------------------------------
-// 
-// This manages interactions with client-side persistent storage and the
-// current login state of the app.
-
-(
-  function(window) {
-    // Amount of time, in milliseconds, that pass before we check
-    // to see if another instance of this page changed our persistent
-    // storage.
-    const REFRESH_INTERVAL = 2000;
-
-    var Config = window.Config = {
-      get value() {
-        var val = localStorage.getItem("SUMMIT_CFG");
-        if (val)
-          return JSON.parse(val);
-        return {};
-      },
-      get lastChanged() {
-        var ts = localStorage.getItem("SUMMIT_CFG_TIMESTAMP");
-        if (ts)
-          return new Date(ts);
-        return new Date(0);
-      },
-      setValue: function Config_setValue(val) {
-        localStorage.setItem("SUMMIT_CFG", JSON.stringify(val));
-        localStorage.setItem("SUMMIT_CFG_TIMESTAMP",
-                             (new Date()).toString());
-        this.observers.forEach(function(cb) { cb(); });
-      },
-      wipe: function Config_wipe() {
-        localStorage.removeItem("SUMMIT_CFG");
-        localStorage.removeItem("SUMMIT_CFG_TIMESTAMP");
-        this.observers.forEach(function(cb) { cb(); });
-      },
-      observers: []
-    };
-
-    function ensureStateIsValid() {
-      if (!('state' in Config.value))
-        Config.setValue({state: "login"});
-    }
-
-    Config.observers.push(ensureStateIsValid);
-
-    // This is useful for finding out whether our configuration has
-    // been changed by another instance of our same window.
-    function setupConfigWatcher() {
-      var lastChanged = Config.lastChanged;
-
-      function onConfigChanged() {
-        lastChanged = Config.lastChanged;
-      };
-
-      Config.observers.push(onConfigChanged);
-
-      window.setInterval(
-        function() {
-          if (Config.lastChanged > lastChanged)
-            Config.observers.forEach(function(cb) { cb(); });
-        },
-        REFRESH_INTERVAL
-      );
-    }
-
-    function initConfig() {
-      ensureStateIsValid();
-      setupConfigWatcher();
-    }
-
-    $(window).ready(initConfig);
-  }
-)(window);
-
-// -----------------------------------------------------------------------
-// Attendees object
-// -----------------------------------------------------------------------
-// 
-// This manages the list of Summit attendees and their shared metadata.
-
-(
-  function(window) {
-    var req;
-
-    var Attendees = window.Attendees = {
-      refresh: function refresh() {
-        if (req)
-          return;
-        var self = this;
-        if (Config.value.token) {
-          req = jQuery.getJSON(
-            "api/profile",
-            {token: Config.value.token},
-            function(data, textStatus) {
-              // TODO: Might need to add a failure callback too?
-              req = null;
-              if (textStatus == "success") {
-                self.value = data.contents;
-                self.observers.forEach(function(cb) { cb(); });
-              } else {
-                // TODO: Raise an error?
-              }
-            });
-        }
-      },
-      value: null,
-      observers: []
-    };
-
-    function refreshAttendees() {
-      if (Config.value.state == "logged-in" && !Attendees.users)
-        Attendees.refresh();
-    }
-
-    Config.observers.push(refreshAttendees);
-    $(window).ready(refreshAttendees);
-  }
-)(window);
-
-jQuery.postJSON = function postJSON(path, obj, cb) {
-  var options = {
-    url: path,
-    type: "POST",
-    contentType: "application/json",
-    data: JSON.stringify(obj),
-    dataType: "json",
-    success: function(data) {
-      cb(true, data);
-    },
-    error: function(req, textStatus, errorThrown) {
-      var data = null;
-      if (req.getResponseHeader("Content-Type") == "application/json") {
-        try {
-          data = JSON.parse(req.responseText);
-        } catch (e) {}
-      }
-      cb(false, data);
-    }
-  };
-  return jQuery.ajax(options);
-};
-
 // -----------------------------------------------------------------------
 // UserInterface object
 // -----------------------------------------------------------------------
@@ -275,7 +130,7 @@
         function(event) {
           event.preventDefault();
           $("#login .error").hide();
-          jQuery.postJSON(
+          Ajax.postJSON(
             "api/challenge/request",
             {email: $(this).find("#email").val() },
             function(success, data) {
@@ -309,7 +164,7 @@
                 contents.interests.push($.trim($(this.parentNode).text()));
             });
 
-          jQuery.postJSON(
+          Ajax.postJSON(
             "api/profile",
             {token: Config.value.token,
              contents: contents},
@@ -330,7 +185,7 @@
       if (verify && Config.value.state != "logged-in") {
         verify = verify[1];
         Config.setValue({state: "wait-for-verify"});
-        jQuery.postJSON(
+        Ajax.postJSON(
           "api/challenge/respond",
           {token: verify},
           function(success, data) {
@@ -352,49 +207,3 @@
     $(window).ready(initUI);
   }
 )(window);
-
-// -----------------------------------------------------------------------
-// Server object
-// -----------------------------------------------------------------------
-// 
-// This sets up an in-browser "server" that can be accessed from other
-// windows via a postMessage API.
-
-(
-  function(window) {
-    var Server = window.Server = {};
-
-    var attendeeCallbacks = [];
-
-    var myOrigin = window.location.protocol + "//" + window.location.host;
-    var handlers = {
-      getAllUsers: function(options, cb, origin) {
-        if (origin != myOrigin) {
-          cb({error: "access denied"});
-          return;
-        }
-
-        // TODO: Add support for more origins.
-
-        if (Config.value.state != "logged-in") {
-          cb({error: "not logged in"});
-          return;
-        }
-
-        if (Attendees.value) {
-          cb({users: Attendees.value});
-        } else
-          attendeeCallbacks.push(cb);
-      }
-    };
-
-    var server = new Summit.Server(handlers);
-
-    Attendees.observers.push(
-      function() {
-        var cbs = attendeeCallbacks;
-        attendeeCallbacks = [];
-        cbs.forEach(function(cb) { cb({users: Attendees.value}); });
-      });
-  }
-)(window);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/static-files/server.js	Sat Jun 26 20:42:06 2010 -0700
@@ -0,0 +1,45 @@
+// -----------------------------------------------------------------------
+// Server object
+// -----------------------------------------------------------------------
+// 
+// This sets up an in-browser "server" that can be accessed from other
+// windows via a postMessage API.
+
+(
+  function(window) {
+    var Server = window.Server = {};
+
+    var attendeeCallbacks = [];
+
+    var myOrigin = window.location.protocol + "//" + window.location.host;
+    var handlers = {
+      getAllUsers: function(options, cb, origin) {
+        if (origin != myOrigin) {
+          cb({error: "access denied"});
+          return;
+        }
+
+        // TODO: Add support for more origins.
+
+        if (Config.value.state != "logged-in") {
+          cb({error: "not logged in"});
+          return;
+        }
+
+        if (Attendees.value) {
+          cb({users: Attendees.value});
+        } else
+          attendeeCallbacks.push(cb);
+      }
+    };
+
+    var server = new Summit.Server(handlers);
+
+    Attendees.observers.push(
+      function() {
+        var cbs = attendeeCallbacks;
+        attendeeCallbacks = [];
+        cbs.forEach(function(cb) { cb({users: Attendees.value}); });
+      });
+  }
+)(window);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/static-files/summit-idp.js	Sat Jun 26 20:42:06 2010 -0700
@@ -0,0 +1,191 @@
+// -----------------------------------------------------------------------
+// Ajax object
+// -----------------------------------------------------------------------
+// 
+// This provides simple functions for making Ajax calls easily.
+
+(
+  function(window) {
+    var Ajax = window.Ajax = {
+      getJSON: function getJSON(path, obj, cb) {
+        if (obj)
+          path += "?" + queryString(obj);
+        var req = new XMLHttpRequest();
+        req.open("GET", path);
+        prepare(req, cb);
+        req.send(null);
+        return req;
+      },
+      postJSON: function postJSON(path, obj, cb) {
+        var body = JSON.stringify(obj);
+        var req = new XMLHttpRequest();
+        req.open("POST", path);
+        req.setRequestHeader("Content-Type", "application/json");
+        prepare(req, cb);
+        req.send(body);
+        return req;
+      }
+    };
+
+    function queryString(data) {
+      var parts = [];
+      for (name in data) {
+        var values = data[name];
+        if (!values.forEach)
+          values = [values];
+        values.forEach(
+          function(value) {
+            parts.push(encodeURI(name) + "=" + encodeURI(value));
+          });
+      }
+      return parts.join("&");
+    }
+
+    function prepare(req, cb) {
+      function onLoad(event) {
+        var data = null;
+        try {
+          data = JSON.parse(req.responseText);
+        } catch (e) {}
+        if (req.status >= 200 && req.status < 300)
+          cb(true, data);
+        else
+          cb(false, data);
+      }
+
+      function onError(event) {
+        var data = null;
+        try {
+          data = JSON.parse(req.responseText);
+        } catch (e) {}
+        cb(false, data);
+      }
+
+      req.addEventListener("load", onLoad, false);
+      req.addEventListener("error", onError, false);
+      req.addEventListener("abort", onError, false);
+      req.overrideMimeType("application/json");
+    }
+  }
+)(window);
+
+// -----------------------------------------------------------------------
+// Config object
+// -----------------------------------------------------------------------
+// 
+// This manages interactions with client-side persistent storage and the
+// current login state of the app.
+
+(
+  function(window) {
+    // Amount of time, in milliseconds, that pass before we check
+    // to see if another instance of this page changed our persistent
+    // storage.
+    const REFRESH_INTERVAL = 2000;
+
+    var Config = window.Config = {
+      get value() {
+        var val = localStorage.getItem("SUMMIT_CFG");
+        if (val)
+          return JSON.parse(val);
+        return {};
+      },
+      get lastChanged() {
+        var ts = localStorage.getItem("SUMMIT_CFG_TIMESTAMP");
+        if (ts)
+          return new Date(ts);
+        return new Date(0);
+      },
+      setValue: function Config_setValue(val) {
+        localStorage.setItem("SUMMIT_CFG", JSON.stringify(val));
+        localStorage.setItem("SUMMIT_CFG_TIMESTAMP",
+                             (new Date()).toString());
+        this.observers.forEach(function(cb) { cb(); });
+      },
+      wipe: function Config_wipe() {
+        localStorage.removeItem("SUMMIT_CFG");
+        localStorage.removeItem("SUMMIT_CFG_TIMESTAMP");
+        this.observers.forEach(function(cb) { cb(); });
+      },
+      observers: []
+    };
+
+    function ensureStateIsValid() {
+      if (!('state' in Config.value))
+        Config.setValue({state: "login"});
+    }
+
+    Config.observers.push(ensureStateIsValid);
+
+    // This is useful for finding out whether our configuration has
+    // been changed by another instance of our same window.
+    function setupConfigWatcher() {
+      var lastChanged = Config.lastChanged;
+
+      function onConfigChanged() {
+        lastChanged = Config.lastChanged;
+      };
+
+      Config.observers.push(onConfigChanged);
+
+      window.setInterval(
+        function() {
+          if (Config.lastChanged > lastChanged)
+            Config.observers.forEach(function(cb) { cb(); });
+        },
+        REFRESH_INTERVAL
+      );
+    }
+
+    function initConfig() {
+      ensureStateIsValid();
+      setupConfigWatcher();
+    }
+
+    window.addEventListener("DOMContentLoaded", initConfig, false);
+  }
+)(window);
+
+// -----------------------------------------------------------------------
+// Attendees object
+// -----------------------------------------------------------------------
+// 
+// This manages the list of Summit attendees and their shared metadata.
+
+(
+  function(window) {
+    var req;
+
+    var Attendees = window.Attendees = {
+      refresh: function refresh() {
+        if (req)
+          return;
+        var self = this;
+        if (Config.value.token) {
+          req = Ajax.getJSON(
+            "api/profile",
+            {token: Config.value.token},
+            function(success, data) {
+              req = null;
+              if (success) {
+                self.value = data.contents;
+                self.observers.forEach(function(cb) { cb(); });
+              } else {
+                // TODO: Raise an error?
+              }
+            });
+        }
+      },
+      value: null,
+      observers: []
+    };
+
+    function refreshAttendees() {
+      if (Config.value.state == "logged-in" && !Attendees.users)
+        Attendees.refresh();
+    }
+
+    Config.observers.push(refreshAttendees);
+    window.addEventListener("DOMContentLoaded", refreshAttendees, false);
+  }
+)(window);