changeset 2:e8416415be29

Added automatic dependency-finding and loading.
author Atul Varma <varmaa@toolness.com>
date Wed, 08 Apr 2009 16:16:48 -0700
parents 2062295ebae2
children 017106cf4c79
files jsm-in-web.js
diffstat 1 files changed, 122 insertions(+), 58 deletions(-) [+]
line wrap: on
line diff
--- a/jsm-in-web.js	Wed Apr 08 14:52:38 2009 -0700
+++ b/jsm-in-web.js	Wed Apr 08 16:16:48 2009 -0700
@@ -1,66 +1,130 @@
-var FILES_TO_LOAD = [];
+function JsModuleRegistry(win, resourceMapper) {
+  var self = this;
+  var modules = {};
+
+  function loadIframe(cb) {
+    var doc = win.document;
+
+    var iframe = doc.createElement("iframe");
+    iframe.setAttribute("src", "blank.html");
+    iframe.style.display = "none";
+    iframe.addEventListener(
+      "load",
+      function onLoad() {
+        iframe.removeEventListener("load",
+                                   onLoad,
+                                   true);
+        cb(iframe);
+      },
+      true
+    );
+    doc.body.appendChild(iframe);
+  }
+
+  function getCodeForJsModule(url, cb) {
+    var realUri = resourceMapper(url);
+    if (realUri)
+      jQuery.get(
+        realUri,
+        function(code) {
+          code = code.replace(/Components/g, "FakeComponents");
+          cb(code);
+        }
+      );
+    else
+      cb("/* No code for " + url + "*/");
+  }
+
+  function findDependencies(code) {
+    var dependencies = [];
+    for (var match = JsModuleRegistry.IMPORT_RE.exec(code);
+         match != null;
+         match = JsModuleRegistry.IMPORT_RE.exec(code)) {
+      dependencies.push(match[1]);
+    }
+    return dependencies;
+  }
 
-function loadJs(url, cb) {
-  jQuery.get(
-    url,
-    function(data) {
-      data = data.replace(/Components/g, "FakeComponents");
-      cb(data);
+  self.fetch = function fetch(url, cb) {
+    //console.log("Fetching " + url);
+    var jsModule = {
+      isBeingFetched: true,
+      fetchCallbacks: []
+    };
+
+    modules[url] = jsModule;
+
+    function onMaybeDone() {
+      if (jsModule.code && jsModule.iframe) {
+        jsModule.isBeingFetched = false;
+        jsModule.fetchCallbacks.forEach(
+          function(fetchCb) {
+            fetchCb();
+          });
+        jsModule.fetchCallbacks = null;
+        cb(jsModule);
+      }
     }
-  );
+
+    getCodeForJsModule(
+      url,
+      function(code) {
+        var dependencies = findDependencies(code);
+        function doneResolvingDeps() {
+          jsModule.code = code;
+          jsModule.dependencies = dependencies;
+          onMaybeDone();
+        }
+
+        if (dependencies.length) {
+          var depsLeft = dependencies.length;
+          function onDepResolved() {
+            depsLeft -= 1;
+            if (!depsLeft)
+              doneResolvingDeps();
+          }
+          dependencies.forEach(
+            function(dependency) {
+              var depMod = modules[dependency];
+              if (depMod) {
+                if (!depMod.isBeingFetched)
+                  onDepResolved();
+                else
+                  depMod.fetchCallbacks.push(onDepResolved);
+              } else
+                self.fetch(dependency, onDepResolved);
+            });
+        } else
+          doneResolvingDeps();
+      });
+    loadIframe(function(iframe) { jsModule.iframe = iframe;
+                                  onMaybeDone(); });
+  };
+
+  self.modules = modules;
 }
 
-function loadIframe(win, cb) {
-  var doc = win.document;
-
-  var iframe = doc.createElement("iframe");
-  iframe.setAttribute("src", "blank.html");
-  iframe.style.display = "none";
-  iframe.addEventListener(
-    "load",
-    function onLoad() {
-      iframe.removeEventListener("load",
-                                 onLoad,
-                                 true);
-      cb(iframe);
-    },
-    true
-  );
-  doc.body.appendChild(iframe);
-}
-
-function onEverythingLoaded(iframes, codeFiles) {
-  console.log("all done.");
-}
-
-function onFramesLoaded(iframes) {
-  var codeFiles = {};
-  var filesLeft = FILES_TO_LOAD.length;
-
-  FILES_TO_LOAD.forEach(
-    function(filename) {
-      loadJs(filename,
-             function(data) {
-               codeFiles[filename] = data;
-               filesLeft -= 1;
-               if (!filesLeft) {
-                 onEverythingLoaded(iframes, codeFiles);
-               }
-             });
-    }
-  );
-}
+var gJsmReg;
 
 $(window).ready(
   function() {
-    var numFrames = FILES_TO_LOAD.length;
-    var iframes = [];
-    for (var i = 0; i < numFrames; i++)
-      loadIframe(
-        window,
-        function(iframe) {
-          iframes.push(iframe);
-          if (iframes.length == numFrames)
-            onFramesLoaded(iframes);
-        });
+    function mapWeaveResourceUri(uri) {
+      var match = uri.match(/resource:\/\/weave\/(.*)/);
+      if (match) {
+        var filename = match[1];
+        if (filename == "constants.js")
+          filename = "constants.js.in";
+        filename = "modules/" + filename;
+        return filename;
+      } else
+        return "";
+    }
+    gJsmReg = new JsModuleRegistry(window, mapWeaveResourceUri);
+    gJsmReg.fetch(
+      "resource://weave/util.js",
+      function(jsm) {
+        console.log(jsm);
+      });
   });
+
+JsModuleRegistry.IMPORT_RE = (/\.import\(['"]([^'"]+)/g);