view random-stuff/random-stuff.js @ 21:e82bff1ef296

Changed code to be more html-like than JS-ish.
author Atul Varma <varmaa@toolness.com>
date Thu, 07 May 2009 15:26:40 -0700
parents a07982ba7259
children ecd868a32247
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 logError(element) {
  var window = element.ownerDocument.defaultView;
  var console = window.wrappedJSObject.console;
  console.error.apply(console, arguments);
}

function absolutifyUrl(document, url) {
  var anchor = document.createElement("a");
  anchor.setAttribute("href", url);
  document.body.appendChild(anchor);
  var absolute = anchor.href;
  document.body.removeChild(anchor);
  return absolute;
}

function pageLoad_inject_sidebar_functions(document) {
  if (document.body &&
      document.body.firstChild &&
      document.body.firstChild.nodeName == "FEATURE") {
    var window = document.defaultView;
    var chromeWindow = window.QueryInterface(Ci.nsIInterfaceRequestor)
                       .getInterface(Ci.nsIWebNavigation)
                       .QueryInterface(Ci.nsIDocShellTreeItem)
                       .rootTreeItem
                       .QueryInterface(Ci.nsIInterfaceRequestor)
                       .getInterface(Ci.nsIDOMWindow);
    var widgets = document.getElementsByTagName("widget");
    for (var i = 0; i < widgets.length; i++) {
      var widget = widgets[i];
      var location = widget.getAttribute("location");
      if (location == "status-bar") {
        var href = widget.getAttribute("href");
        if (typeof(href) == "string") {
          href = absolutifyUrl(document, href);
          var width = widget.getAttribute("width");
          if (width && width.match(/^[0-9]+$/)) {
            var panelIframe = addStatusBarPanel(chromeWindow, href, width);
            window.addEventListener(
              "unload",
              function() { panelIframe.parentNode.removeChild(panelIframe); },
              true
            );
          } else
            logError(widget, "must specify width as integer");
        } else
          logError(widget, "must specify href");
      } else
        logError(widget, "has unknown location", location);
    }
  }
}