view 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 source

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);
}