changeset 6:cb390cc6efa2

Switched to injecting code into iframes asynchronously via script tags rather than synchronously via window.eval(), b/c the latter didn't always result in proper evaluation (e.g., when "foo = 1" was eval'd, 'foo' was attached to the global object of the caller rather than the window object). Also added fake Observers and Preferences JS modules.
author Atul Varma <varmaa@toolness.com>
date Wed, 08 Apr 2009 22:42:13 -0700
parents f08437f96401
children c1f1d5ffd6f2
files fake_Observers.js fake_Preferences.js jsm-in-web.js
diffstat 3 files changed, 60 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/fake_Observers.js	Wed Apr 08 22:42:13 2009 -0700
@@ -0,0 +1,4 @@
+let EXPORTED_SYMBOLS = ["Observers"];
+
+function Observers() {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/fake_Preferences.js	Wed Apr 08 22:42:13 2009 -0700
@@ -0,0 +1,6 @@
+let EXPORTED_SYMBOLS = ["Preferences"];
+
+function Preferences() {
+  this.get = function() {
+  };
+}
--- a/jsm-in-web.js	Wed Apr 08 18:09:16 2009 -0700
+++ b/jsm-in-web.js	Wed Apr 08 22:42:13 2009 -0700
@@ -27,6 +27,8 @@
       realUri,
       function(code) {
         code = code.replace(/Components/g, "FakeComponents");
+        code = ("/* " + url + " (modified for use in content space) */" +
+                code);
         cb(code);
       }
     );
@@ -42,6 +44,23 @@
     return dependencies;
   }
 
+  function injectCodeIntoWindow(code, window, cb) {
+    var doc = window.document;
+    var script = doc.createElement("script");
+    var dataUrl = "data:application/javascript,";
+    dataUrl += encodeURI(code);
+    script.setAttribute("type", "application/javascript;version=1.7");
+    script.setAttribute("src", dataUrl);
+    script.addEventListener(
+      "load",
+      function onLoad() {
+        script.removeEventListener("load", onLoad, false);
+        cb();
+      },
+      false);
+    doc.body.appendChild(script);
+  }
+
   self.import = function JSMR_import(url, obj) {
     //console.log("Importing " + url);
     var module = modules[url];
@@ -49,12 +68,6 @@
     if (!module)
       throw new Error("Module at url not fetched: " + url);
 
-    if (!module.hasBeenImported) {
-      //console.log("Evaluating code for " + url);
-      module.window.eval(module.code);
-      module.hasBeenImported = true;
-    }
-
     var exported = module.window.EXPORTED_SYMBOLS;
 
     if (!exported)
@@ -84,12 +97,19 @@
     function onMaybeDone() {
       if (jsModule.code && jsModule.window) {
         jsModule.isBeingFetched = false;
-        jsModule.fetchCallbacks.forEach(
-          function(fetchCb) {
-            fetchCb();
+
+        //console.log("Evaluating code for " + url);
+        injectCodeIntoWindow(
+          jsModule.code,
+          jsModule.window,
+          function() {
+            jsModule.fetchCallbacks.forEach(
+              function(fetchCb) {
+                fetchCb();
+              });
+            jsModule.fetchCallbacks = null;
+            cb(jsModule);
           });
-        jsModule.fetchCallbacks = null;
-        cb(jsModule);
       }
     }
 
@@ -130,11 +150,7 @@
         jsModule.window = window;
         window.FakeComponents = {
           interfaces: {},
-          classes: {
-            "@mozilla.org/observer-service;1": {
-              getService: function() {}
-            }
-          },
+          classes: {},
           utils: {
             "import": function FCU_import(url, obj) {
               if (!obj)
@@ -155,21 +171,28 @@
 $(window).ready(
   function() {
     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 if (uri == "resource://gre/modules/XPCOMUtils.jsm") {
+      switch (uri) {
+      case "resource://gre/modules/XPCOMUtils.jsm":
         return "fake_XPCOMUtils.js";
-      } else
-        throw new Error("Don't know how to map " + uri);
+      case "resource://weave/ext/Preferences.js":
+        return "fake_Preferences.js";
+      case "resource://weave/ext/Observers.js":
+        return "fake_Observers.js";
+      case "resource://weave/constants.js":
+        return "modules/constants.js.in";
+      default:
+        var match = uri.match(/resource:\/\/weave\/(.*)/);
+        if (match) {
+          var filename = match[1];
+          filename = "modules/" + filename;
+          return filename;
+        } else
+          throw new Error("Don't know how to map " + uri);
+      }
     }
     gJsmReg = new JsModuleRegistry(window, mapWeaveResourceUri);
     gJsmReg.fetch(
-      "resource://weave/util.js",
+      "resource://weave/engines.js",
       function(jsm) {
         gJsmReg.import(jsm.url, {});
         console.log("Import successful.");