diff random-stuff/random-stuff.js @ 20:a07982ba7259

Added random stuff.
author Atul Varma <varmaa@toolness.com>
date Wed, 06 May 2009 09:20:13 -0700
parents
children e82bff1ef296
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/random-stuff/random-stuff.js	Wed May 06 09:20:13 2009 -0700
@@ -0,0 +1,155 @@
+const BG_PROPS = ["backgroundImage",
+                  "backgroundPosition",
+                  "backgroundRepeat",
+                  "backgroundColor",
+                  "backgroundAttachment"];
+
+function copyBackground(fromElement, toElement) {
+  var window = fromElement.ownerDocument.defaultView;
+  var style = window.getComputedStyle(fromElement, null);
+  BG_PROPS.forEach(
+    function(name) {
+      toElement.style[name] = style[name];
+    });
+}
+
+function evalFunctionsIntoWindow(functions, window) {
+  var sandbox = Components.utils.Sandbox(window);
+  var codeLines = [];
+
+  for (name in functions)
+    if (typeof(functions[name]) == "function")
+      codeLines.push("window." + name + " = " +
+                     functions[name].toString() + ";");
+
+  sandbox.window = window.wrappedJSObject;
+
+  Components.utils.evalInSandbox(codeLines.join('\n'), sandbox);
+}
+
+function importFunctionsIntoWindow(functions, window) {
+  var sandbox = Components.utils.Sandbox(window);
+  var codeLines = [];
+
+  for (name in functions)
+    if (typeof(functions[name]) == "function") {
+      codeLines.push("window." + name + " = " + name + ";");
+      sandbox.importFunction(functions[name]);
+    }
+
+  sandbox.window = window.wrappedJSObject;
+  Components.utils.evalInSandbox(codeLines.join('\n'), sandbox);
+}
+
+function injectPanelWindowFunctions(iframe) {
+  var functions = {
+    close: function close() {
+      iframe.parentNode.removeChild(iframe);
+    }
+  };
+
+  importFunctionsIntoWindow(functions, iframe.contentWindow);
+}
+
+function onPanelLoad(evt) {
+  if (evt.originalTarget.nodeName == "#document") {
+    var iframe = this;
+
+    iframe.removeEventListener("DOMContentLoaded", onPanelLoad, true);
+    injectPanelWindowFunctions(iframe);
+    copyBackground(this.parentNode, iframe.contentDocument.body);
+  }
+}
+
+function addStatusBarPanel(window, url, width) {
+  var document = window.document;
+  var statusBar = document.getElementById("status-bar");
+  var iframe = document.createElement("iframe");
+  iframe.setAttribute("type", "content");
+  iframe.setAttribute("src", url);
+  iframe.setAttribute("width", width);
+  iframe.setAttribute("height", statusBar.boxObject.height);
+  iframe.style.overflow = "hidden";
+  iframe.addEventListener("DOMContentLoaded", onPanelLoad, true);
+  statusBar.appendChild(iframe);
+  return iframe;
+}
+
+function pageLoad_inject_sidebar_functions(document) {
+  var window = document.defaultView;
+  var chromeWindow = window.QueryInterface(Ci.nsIInterfaceRequestor)
+                     .getInterface(Ci.nsIWebNavigation)
+                     .QueryInterface(Ci.nsIDocShellTreeItem)
+                     .rootTreeItem
+                     .QueryInterface(Ci.nsIInterfaceRequestor)
+                     .getInterface(Ci.nsIDOMWindow);
+
+  document = null;
+
+  var functionsToImport = {
+    _addSidebar: function _addSidebar(url, width) {
+      if (typeof(url) != "string")
+        throw new Error("URL must be a string");
+
+      if (typeof(width) != "number")
+        throw new Error("width must be a number");
+
+      var panelIframe = addStatusBarPanel(chromeWindow, url, width);
+      chromeWindow = null;
+
+      panelIframe.addEventListener(
+        "load",
+        function(loadEvent) {
+          var panelDocument = loadEvent.originalTarget;
+          var evt = window.document.createEvent("MessageEvent");
+          var origin = (panelDocument.location.protocol + "//" +
+                        panelDocument.location.host);
+          evt.initMessageEvent("message",
+                               false,
+                               true,
+                               "sidebar created",
+                               origin,
+                               "",
+                               panelDocument.defaultView);
+          window.addEventListener(
+            "unload",
+            function() { panelIframe.parentNode.removeChild(panelIframe); },
+            true
+          );
+          window.dispatchEvent(evt);
+          window = null;
+        },
+        true);
+    }
+  };
+
+  var functionsToEval = {
+    addSidebar: function addSidebar(options) {
+      window.addEventListener(
+        "message",
+        function onMessage(event) {
+          // TODO: Make this secure by looking at the origin, etc.
+          window.console.log(event);
+          if (event.data == "sidebar created") {
+            window.removeEventListener("message", onMessage, false);
+            var panel = event.source;
+            options.callback(panel);
+          }
+        },
+        false
+      );
+
+      // Absolut-ify the URL if necessary.
+      var anchor = window.document.createElement("a");
+      anchor.setAttribute("href", options.url);
+      window.document.body.appendChild(anchor);
+      options.url = anchor.href;
+      window.document.body.removeChild(anchor);
+
+      window._addSidebar(options.url, options.width);
+    }
+  };
+
+  importFunctionsIntoWindow(functionsToImport, window);
+  evalFunctionsIntoWindow(functionsToEval, window);
+}