Merge inbound to m-c.
authorRyan VanderMeulen <ryanvm@gmail.com>
Thu, 21 Mar 2013 16:45:23 -0400
changeset 125843 0e9badd3cf39090e03f4527244521ee0dac14664
parent 125842 d6a51ac10751547e646b71a33d388e19bcd054e1 (current diff)
parent 125758 cb0aff9c912986587cd9676b4d9bc0a49c93b0cd (diff)
child 125844 cc4fd344ac41d06cf1d695c645c13b11c330e4f6
child 126111 0bc53c8467091db1d26c5d6fecabff8f9da3e0a1
child 126348 477539720e76867c3fbaa18aec3d85e6db4a9e0b
child 127457 872c29501019d020a444538a3c234e0adc63a1ed
push id25120
push userryanvm@gmail.com
push dateThu, 21 Mar 2013 20:48:10 +0000
treeherdermozilla-inbound@cc4fd344ac41 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone22.0a1
first release with
nightly linux32
0e9badd3cf39 / 22.0a1 / 20130322031028 / files
nightly linux64
0e9badd3cf39 / 22.0a1 / 20130322031028 / files
nightly mac
0e9badd3cf39 / 22.0a1 / 20130322031028 / files
nightly win32
0e9badd3cf39 / 22.0a1 / 20130322031028 / files
nightly win64
0e9badd3cf39 / 22.0a1 / 20130322031028 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge inbound to m-c.
browser/metro/base/content/helperui/CaptureDialog.js
browser/metro/base/content/helperui/CapturePickerUI.js
browser/metro/base/content/prompt/CaptureDialog.xul
dom/tests/mochitest/dom-level2-core/test_hasAttributes01.html
dom/tests/mochitest/dom-level2-core/test_hasAttributes02.html
dom/tests/mochitest/dom-level2-core/test_nodehasattributes01.html
dom/tests/mochitest/dom-level2-core/test_nodehasattributes02.html
dom/tests/mochitest/dom-level2-core/test_nodehasattributes03.html
dom/tests/mochitest/dom-level2-core/test_nodehasattributes04.html
js/src/jit-test/tests/basic/bug787283.js
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -234,17 +234,16 @@
 @BINPATH@/components/html5.xpt
 @BINPATH@/components/htmlparser.xpt
 @BINPATH@/components/identity.xpt
 @BINPATH@/components/imglib2.xpt
 @BINPATH@/components/imgicon.xpt
 @BINPATH@/components/inspector.xpt
 @BINPATH@/components/intl.xpt
 @BINPATH@/components/jar.xpt
-@BINPATH@/components/jetpack.xpt
 @BINPATH@/components/jsdebugger.xpt
 @BINPATH@/components/jsdservice.xpt
 @BINPATH@/components/jsinspector.xpt
 @BINPATH@/components/layout_base.xpt
 @BINPATH@/components/layout_forms.xpt
 #ifdef NS_PRINTING
 @BINPATH@/components/layout_printing.xpt
 #endif
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -1265,29 +1265,43 @@ var gBrowserInit = {
     }
 
     // Certain kinds of automigration rely on this notification to complete their
     // tasks BEFORE the browser window is shown.
     Services.obs.notifyObservers(null, "browser-window-before-show", "");
 
     // Set a sane starting width/height for all resolutions on new profiles.
     if (!document.documentElement.hasAttribute("width")) {
-      let defaultWidth = 994;
+      let defaultWidth;
       let defaultHeight;
+
+      // Very small: maximize the window
+      // Portrait  : use about full width and 3/4 height, to view entire pages
+      //             at once (without being obnoxiously tall)
+      // Widescreen: use about half width, to suggest side-by-side page view
+      // Otherwise : use 3/4 height and width
       if (screen.availHeight <= 600) {
         document.documentElement.setAttribute("sizemode", "maximized");
         defaultWidth = 610;
         defaultHeight = 450;
       }
       else {
-        // Create a narrower window for large or wide-aspect displays, to suggest
-        // side-by-side page view.
-        if (screen.availWidth >= 1600)
+        if (screen.availWidth <= screen.availHeight) {
+          defaultWidth = screen.availWidth * .9;
+          defaultHeight = screen.availHeight * .75;
+        }
+        else if (screen.availWidth >= 2048) {
           defaultWidth = (screen.availWidth / 2) - 20;
-        defaultHeight = screen.availHeight - 10;
+          defaultHeight = screen.availHeight - 10;
+        }
+        else {
+          defaultWidth = screen.availWidth * .75;
+          defaultHeight = screen.availHeight * .75;
+        }
+
 #ifdef MOZ_WIDGET_GTK2
         // On X, we're not currently able to account for the size of the window
         // border.  Use 28px as a guess (titlebar + bottom window border)
         defaultHeight -= 28;
 #endif
       }
       document.documentElement.setAttribute("width", defaultWidth);
       document.documentElement.setAttribute("height", defaultHeight);
@@ -3046,106 +3060,20 @@ var PrintPreviewListener = {
   }
 }
 
 function getMarkupDocumentViewer()
 {
   return gBrowser.markupDocumentViewer;
 }
 
-/**
- * Content area tooltip.
- * XXX - this must move into XBL binding/equiv! Do not want to pollute
- *       browser.js with functionality that can be encapsulated into
- *       browser widget. TEMPORARY!
- *
- * NOTE: Any changes to this routine need to be mirrored in DefaultTooltipTextProvider::GetNodeText()
- *       (located in mozilla/embedding/browser/webBrowser/nsDocShellTreeOwner.cpp)
- *       which performs the same function, but for embedded clients that
- *       don't use a XUL/JS layer. It is important that the logic of
- *       these two routines be kept more or less in sync.
- *       (pinkerton)
- **/
+// This function is obsolete. Newer code should use <tooltip page="true"/> instead.
 function FillInHTMLTooltip(tipElement)
 {
-  var retVal = false;
-  // Don't show the tooltip if the tooltip node is a document or disconnected.
-  if (!tipElement.ownerDocument ||
-      (tipElement.ownerDocument.compareDocumentPosition(tipElement) & document.DOCUMENT_POSITION_DISCONNECTED))
-    return retVal;
-
-  const XLinkNS = "http://www.w3.org/1999/xlink";
-  const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
-
-  var titleText = null;
-  var XLinkTitleText = null;
-  var SVGTitleText = null;
-  var lookingForSVGTitle = true;
-  var direction = tipElement.ownerDocument.dir;
-
-  // If the element is invalid per HTML5 Forms specifications and has no title,
-  // show the constraint validation error message.
-  if ((tipElement instanceof HTMLInputElement ||
-       tipElement instanceof HTMLTextAreaElement ||
-       tipElement instanceof HTMLSelectElement ||
-       tipElement instanceof HTMLButtonElement) &&
-      !tipElement.hasAttribute('title') &&
-      (!tipElement.form || !tipElement.form.noValidate)) {
-    // If the element is barred from constraint validation or valid,
-    // the validation message will be the empty string.
-    titleText = tipElement.validationMessage;
-  }
-
-  while (!titleText && !XLinkTitleText && !SVGTitleText && tipElement) {
-    if (tipElement.nodeType == Node.ELEMENT_NODE &&
-        tipElement.namespaceURI != XULNS) {
-      titleText = tipElement.getAttribute("title");
-      if ((tipElement instanceof HTMLAnchorElement ||
-           tipElement instanceof HTMLAreaElement ||
-           tipElement instanceof HTMLLinkElement ||
-           tipElement instanceof SVGAElement) && tipElement.href) {
-        XLinkTitleText = tipElement.getAttributeNS(XLinkNS, "title");
-      }
-      if (lookingForSVGTitle &&
-          (!(tipElement instanceof SVGElement) ||
-           tipElement.parentNode.nodeType == Node.DOCUMENT_NODE)) {
-        lookingForSVGTitle = false;
-      }
-      if (lookingForSVGTitle) {
-        for (let childNode of tipElement.childNodes) {
-          if (childNode instanceof SVGTitleElement) {
-            SVGTitleText = childNode.textContent;
-            break;
-          }
-        }
-      }
-      var defView = tipElement.ownerDocument.defaultView;
-      // XXX Work around bug 350679:
-      // "Tooltips can be fired in documents with no view".
-      if (!defView)
-        return retVal;
-      direction = defView.getComputedStyle(tipElement, "")
-        .getPropertyValue("direction");
-    }
-    tipElement = tipElement.parentNode;
-  }
-
-  var tipNode = document.getElementById("aHTMLTooltip");
-  tipNode.style.direction = direction;
-
-  [titleText, XLinkTitleText, SVGTitleText].forEach(function (t) {
-    if (t && /\S/.test(t)) {
-      // Make CRLF and CR render one line break each.
-      t = t.replace(/\r\n?/g, '\n');
-
-      tipNode.setAttribute("label", t);
-      retVal = true;
-    }
-  });
-  return retVal;
+  document.getElementById("aHTMLTooltip").fillInPageTooltip(tipElement);
 }
 
 var browserDragAndDrop = {
   canDropLink: function (aEvent) Services.droppedLinkHandler.canDropLink(aEvent, true),
 
   dragOver: function (aEvent)
   {
     if (this.canDropLink(aEvent)) {
@@ -4258,30 +4186,29 @@ var XULBrowserWindow = {
     var location = aLocationURI ? aLocationURI.spec : "";
     this._hostChanged = true;
 
     // Hide the form invalid popup.
     if (gFormSubmitObserver.panel) {
       gFormSubmitObserver.panel.hidePopup();
     }
 
-    if (document.tooltipNode) {
+    let pageTooltip = document.getElementById("aHTMLTooltip");
+    let tooltipNode = pageTooltip.triggerNode;
+    if (tooltipNode) {
       // Optimise for the common case
       if (aWebProgress.DOMWindow == content) {
-        document.getElementById("aHTMLTooltip").hidePopup();
-        document.tooltipNode = null;
+        pageTooltip.hidePopup();
       }
       else {
-        for (let tooltipWindow =
-               document.tooltipNode.ownerDocument.defaultView;
+        for (let tooltipWindow = tooltipNode.ownerDocument.defaultView;
              tooltipWindow != tooltipWindow.parent;
              tooltipWindow = tooltipWindow.parent) {
           if (tooltipWindow == aWebProgress.DOMWindow) {
-            document.getElementById("aHTMLTooltip").hidePopup();
-            document.tooltipNode = null;
+            pageTooltip.hidePopup();
             break;
           }
         }
       }
     }
 
     // This code here does not compare uris exactly when determining
     // whether or not the message should be hidden since the message
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -109,17 +109,17 @@
     </menupopup>
 
     <!-- bug 415444/582485: event.stopPropagation is here for the cloned version
          of this menupopup -->
     <menupopup id="backForwardMenu"
                onpopupshowing="return FillHistoryMenu(event.target);"
                oncommand="gotoHistoryIndex(event); event.stopPropagation();"
                onclick="checkForMiddleClick(this, event);"/>
-    <tooltip id="aHTMLTooltip" onpopupshowing="return FillInHTMLTooltip(document.tooltipNode);"/>
+    <tooltip id="aHTMLTooltip" page="true"/>
 
     <!-- for search and content formfill/pw manager -->
     <panel type="autocomplete" id="PopupAutoComplete" noautofocus="true" hidden="true"/>
 
     <!-- for url bar autocomplete -->
     <panel type="autocomplete-richlistbox" id="PopupAutoCompleteRichResult" noautofocus="true" hidden="true"/>
 
     <!-- for invalid form error message -->
--- a/browser/base/content/test/browser_bug329212.js
+++ b/browser/base/content/test/browser_bug329212.js
@@ -1,41 +1,42 @@
 function test () {
+
   waitForExplicitFinish();
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.selectedBrowser.addEventListener("load", function () {
     gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
 
     let doc = gBrowser.contentDocument;
     let tooltip = document.getElementById("aHTMLTooltip");
 
-    ok(FillInHTMLTooltip(doc.getElementById("svg1")), "should get title");
+    ok(tooltip.fillInPageTooltip(doc.getElementById("svg1")), "should get title");
     is(tooltip.getAttribute("label"), "This is a non-root SVG element title");
 
-    ok(FillInHTMLTooltip(doc.getElementById("text1")), "should get title");
+    ok(tooltip.fillInPageTooltip(doc.getElementById("text1")), "should get title");
     is(tooltip.getAttribute("label"), "\n\n\n    This            is a title\n\n    ");
 
-    ok(!FillInHTMLTooltip(doc.getElementById("text2")), "should not get title");
+    ok(!tooltip.fillInPageTooltip(doc.getElementById("text2")), "should not get title");
 
-    ok(!FillInHTMLTooltip(doc.getElementById("text3")), "should not get title");
+    ok(!tooltip.fillInPageTooltip(doc.getElementById("text3")), "should not get title");
 
-    ok(FillInHTMLTooltip(doc.getElementById("link1")), "should get title");
+    ok(tooltip.fillInPageTooltip(doc.getElementById("link1")), "should get title");
     is(tooltip.getAttribute("label"), "\n      This is a title\n    ");
-    ok(FillInHTMLTooltip(doc.getElementById("text4")), "should get title");
+    ok(tooltip.fillInPageTooltip(doc.getElementById("text4")), "should get title");
     is(tooltip.getAttribute("label"), "\n      This is a title\n    ");
 
-    ok(!FillInHTMLTooltip(doc.getElementById("link2")), "should not get title");
+    ok(!tooltip.fillInPageTooltip(doc.getElementById("link2")), "should not get title");
 
-    ok(FillInHTMLTooltip(doc.getElementById("link3")), "should get title");
+    ok(tooltip.fillInPageTooltip(doc.getElementById("link3")), "should get title");
     isnot(tooltip.getAttribute("label"), "");
 
-    ok(FillInHTMLTooltip(doc.getElementById("link4")), "should get title");
+    ok(tooltip.fillInPageTooltip(doc.getElementById("link4")), "should get title");
     is(tooltip.getAttribute("label"), "This is an xlink:title attribute");
 
-    ok(!FillInHTMLTooltip(doc.getElementById("text5")), "should not get title");
+    ok(!tooltip.fillInPageTooltip(doc.getElementById("text5")), "should not get title");
 
     gBrowser.removeCurrentTab();
     finish();
   }, true);
 
   content.location = 
     "http://mochi.test:8888/browser/browser/base/content/test/title_test.svg";
 }
--- a/browser/base/content/test/browser_bug561623.js
+++ b/browser/base/content/test/browser_bug561623.js
@@ -3,25 +3,25 @@ function test() {
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.selectedBrowser.addEventListener("load", function () {
     gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
 
     let doc = gBrowser.contentDocument;
     let tooltip = document.getElementById("aHTMLTooltip");
     let i = doc.getElementById("i");
 
-    ok(!FillInHTMLTooltip(i),
+    ok(!tooltip.fillInPageTooltip(i),
        "No tooltip should be shown when @title is null");
 
     i.title = "foo";
-    ok(FillInHTMLTooltip(i),
+    ok(tooltip.fillInPageTooltip(i),
        "A tooltip should be shown when @title is not the empty string");
 
     i.pattern = "bar";
-    ok(FillInHTMLTooltip(i),
+    ok(tooltip.fillInPageTooltip(i),
        "A tooltip should be shown when @title is not the empty string");
 
     gBrowser.removeCurrentTab();
     finish();
   }, true);
 
   content.location = 
     "data:text/html,<!DOCTYPE html><html><body><input id='i'></body></html>";
--- a/browser/base/content/test/browser_bug581947.js
+++ b/browser/base/content/test/browser_bug581947.js
@@ -1,35 +1,35 @@
 function check(aElementName, aBarred) {
   let doc = gBrowser.contentDocument;
   let tooltip = document.getElementById("aHTMLTooltip");
   let content = doc.getElementById('content');
 
   let e = doc.createElement(aElementName);
   content.appendChild(e);
 
-  ok(!FillInHTMLTooltip(e),
+  ok(!tooltip.fillInPageTooltip(e),
      "No tooltip should be shown when the element is valid");
 
   e.setCustomValidity('foo');
   if (aBarred) {
-    ok(!FillInHTMLTooltip(e),
+    ok(!tooltip.fillInPageTooltip(e),
        "No tooltip should be shown when the element is barred from constraint validation");
   } else {
-    ok(FillInHTMLTooltip(e),
+    ok(tooltip.fillInPageTooltip(e),
        e.tagName + " " +"A tooltip should be shown when the element isn't valid");
   }
 
   e.setAttribute('title', '');
-  ok (!FillInHTMLTooltip(e),
+  ok (!tooltip.fillInPageTooltip(e),
       "No tooltip should be shown if the title attribute is set");
 
   e.removeAttribute('title');
   content.setAttribute('novalidate', '');
-  ok (!FillInHTMLTooltip(e),
+  ok (!tooltip.fillInPageTooltip(e),
       "No tooltip should be shown if the novalidate attribute is set on the form owner");
   content.removeAttribute('novalidate');
 
   content.removeChild(e);
 }
 
 function todo_check(aElementName, aBarred) {
   let doc = gBrowser.contentDocument;
--- a/browser/base/content/web-panels.xul
+++ b/browser/base/content/web-panels.xul
@@ -41,17 +41,17 @@
     <command id="Browser:Forward"
              oncommand="getPanelBrowser().webNavigation.goForward();"
              disabled="true"/>
     <command id="Browser:Stop" oncommand="PanelBrowserStop();"/>
     <command id="Browser:Reload" oncommand="PanelBrowserReload();"/>
   </commandset>
 
   <popupset id="mainPopupSet">
-    <tooltip id="aHTMLTooltip" onpopupshowing="return FillInHTMLTooltip(document.tooltipNode);"/>
+    <tooltip id="aHTMLTooltip" page="true"/>
     <menupopup id="contentAreaContextMenu" pagemenu="start"
                onpopupshowing="if (event.target != this)
                                  return true;
                                gContextMenu = new nsContextMenu(this, event.shiftKey);
                                if (gContextMenu.shouldDisplay)
                                  document.popupNode = this.triggerNode;
                                return gContextMenu.shouldDisplay;"
                onpopuphiding="if (event.target != this)
--- a/browser/components/certerror/test/Makefile.in
+++ b/browser/components/certerror/test/Makefile.in
@@ -8,13 +8,14 @@ topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir  = @relativesrcdir@
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 _BROWSER_FILES = browser_bug431826.js \
+                 browser_bug633691.js \
     $(NULL)
 
 libs::	$(_BROWSER_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
 
new file mode 100644
--- /dev/null
+++ b/browser/components/certerror/test/browser_bug633691.js
@@ -0,0 +1,25 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+function test() {
+  waitForExplicitFinish();
+  gBrowser.selectedTab = gBrowser.addTab();
+  // Open a html page with about:certerror in an iframe
+  window.content.addEventListener("load", testIframeCert, true);
+  content.location = "data:text/html,<iframe width='700' height='700' src='about:certerror'></iframe>";
+}
+
+function testIframeCert() {
+  window.content.removeEventListener("load", testIframeCert, true);
+  // Confirm that the expert section is hidden
+  var doc = gBrowser.contentDocument.getElementsByTagName('iframe')[0].contentDocument;
+  var eC = doc.getElementById("expertContent");
+  ok(eC, "Expert content should exist")
+  ok(eC.hasAttribute("hidden"), "Expert content should be hidded by default");
+
+  // Clean up
+  gBrowser.removeCurrentTab();
+  
+  finish();
+}
--- a/browser/components/search/content/search.xml
+++ b/browser/components/search/content/search.xml
@@ -491,26 +491,26 @@
 
       <handler event="focus">
       <![CDATA[
         // Speculatively connect to the current engine's search URI (and
         // suggest URI, if different) to reduce request latency
 
         const SUGGEST_TYPE = "application/x-suggestions+json";
         var engine = this.currentEngine;
-	var connector =
+        var connector =
             Services.io.QueryInterface(Components.interfaces.nsISpeculativeConnect);
         var searchURI = engine.getSubmission("dummy").uri;
         let callbacks = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
                               .getInterface(Components.interfaces.nsIWebNavigation)
                               .QueryInterface(Components.interfaces.nsILoadContext);
         connector.speculativeConnect(searchURI, callbacks);
 
         if (engine.supportsResponseType(SUGGEST_TYPE)) {
-	  var suggestURI = engine.getSubmission("dummy", SUGGEST_TYPE).uri;
+          var suggestURI = engine.getSubmission("dummy", SUGGEST_TYPE).uri;
           if (suggestURI.prePath != searchURI.prePath)
             connector.speculativeConnect(suggestURI, callbacks);
         }
       ]]></handler>
     </handlers>
   </binding>
 
   <binding id="searchbar-textbox"
--- a/browser/devtools/framework/Sidebar.jsm
+++ b/browser/devtools/framework/Sidebar.jsm
@@ -49,16 +49,17 @@ ToolSidebar.prototype = {
    * @param {string} tab uniq id
    * @param {string} url
    */
   addTab: function ToolSidebar_addTab(id, url, selected=false) {
     let iframe = this._panelDoc.createElementNS(XULNS, "iframe");
     iframe.className = "iframe-" + id;
     iframe.setAttribute("flex", "1");
     iframe.setAttribute("src", url);
+    iframe.tooltip = "aHTMLTooltip";
 
     let tab = this._tabbox.tabs.appendItem();
     tab.setAttribute("label", ""); // Avoid showing "undefined" while the tab is loading
 
     let onIFrameLoaded = function() {
       tab.setAttribute("label", iframe.contentDocument.title);
       iframe.removeEventListener("DOMContentLoaded", onIFrameLoaded, true);
       if ("setPanel" in iframe.contentWindow) {
@@ -69,16 +70,21 @@ ToolSidebar.prototype = {
 
     iframe.addEventListener("DOMContentLoaded", onIFrameLoaded, true);
 
     let tabpanel = this._panelDoc.createElementNS(XULNS, "tabpanel");
     tabpanel.setAttribute("id", "sidebar-panel-" + id);
     tabpanel.appendChild(iframe);
     this._tabbox.tabpanels.appendChild(tabpanel);
 
+    this._tooltip = this._panelDoc.createElementNS(XULNS, "tooltip");
+    this._tooltip.id = "aHTMLTooltip";
+    tabpanel.appendChild(this._tooltip);
+    this._tooltip.page = true;
+
     tab.linkedPanel = "sidebar-panel-" + id;
 
     // We store the index of this tab.
     this._tabs.set(id, tab);
 
     if (selected) {
       // For some reason I don't understand, if we call this.select in this
       // event loop (after inserting the tab), the tab will never get the
--- a/browser/devtools/framework/Toolbox.jsm
+++ b/browser/devtools/framework/Toolbox.jsm
@@ -487,16 +487,17 @@ Toolbox.prototype = {
 
     let iframe = this.doc.getElementById("toolbox-panel-iframe-" + id);
     if (!iframe) {
       iframe = this.doc.createElement("iframe");
       iframe.className = "toolbox-panel-iframe";
       iframe.id = "toolbox-panel-iframe-" + id;
       iframe.setAttribute("flex", 1);
       iframe.setAttribute("forceOwnRefreshDriver", "");
+      iframe.tooltip = "aHTMLTooltip";
 
       let vbox = this.doc.getElementById("toolbox-panel-" + id);
       vbox.appendChild(iframe);
 
       let boundLoad = function() {
         iframe.removeEventListener("DOMContentLoaded", boundLoad, true);
 
         definition.build(iframe.contentWindow, this).then(function(panel) {
--- a/browser/devtools/framework/ToolboxHosts.jsm
+++ b/browser/devtools/framework/ToolboxHosts.jsm
@@ -63,16 +63,17 @@ BottomHost.prototype = {
 
     let frameLoad = function() {
       this.frame.removeEventListener("DOMContentLoaded", frameLoad, true);
       this.emit("ready", this.frame);
 
       deferred.resolve(this.frame);
     }.bind(this);
 
+    this.frame.tooltip = "aHTMLTooltip";
     this.frame.addEventListener("DOMContentLoaded", frameLoad, true);
 
     // we have to load something so we can switch documents if we have to
     this.frame.setAttribute("src", "about:blank");
 
     focusTab(this.hostTab);
 
     return deferred.promise;
@@ -146,16 +147,17 @@ SidebarHost.prototype = {
     let frameLoad = function() {
       this.frame.removeEventListener("DOMContentLoaded", frameLoad, true);
       this.emit("ready", this.frame);
 
       deferred.resolve(this.frame);
     }.bind(this);
 
     this.frame.addEventListener("DOMContentLoaded", frameLoad, true);
+    this.frame.tooltip = "aHTMLTooltip";
     this.frame.setAttribute("src", "about:blank");
 
     focusTab(this.hostTab);
 
     return deferred.promise;
   },
 
   /**
--- a/browser/metro/base/content/Util.js
+++ b/browser/metro/base/content/Util.js
@@ -174,16 +174,22 @@ let Util = {
             aElement instanceof Ci.nsIDOMHTMLTableCellElement ||
             aElement instanceof Ci.nsIDOMHTMLBodyElement);
   },
 
   /*
    * Rect and nsIDOMRect utilities
    */
 
+  getCleanRect: function getCleanRect() {
+    return {
+      left: 0, top: 0, right: 0, bottom: 0
+    };
+  },
+
   pointWithinRect: function pointWithinRect(aX, aY, aRect) {
     return (aRect.left < aX && aRect.top < aY &&
             aRect.right > aX && aRect.bottom > aY);
   },
 
   pointWithinDOMRect: function pointWithinDOMRect(aX, aY, aRect) {
     if (!aRect.width || !aRect.height)
       return false;
--- a/browser/metro/base/content/bindings/selectionoverlay.xml
+++ b/browser/metro/base/content/bindings/selectionoverlay.xml
@@ -5,19 +5,19 @@
     xmlns:xbl="http://www.mozilla.org/xbl"
     xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
     xmlns:html="http://www.w3.org/1999/xhtml">
   <binding id="selection-binding">  
     <content>
       <html:div flex="1" class="selection-overlay-inner window-width window-height" anonid="selection-overlay-inner">
         <xul:stack>
           <html:div anonid="selection-overlay-debug" class="window-width window-height"/>
-          <xul:toolbarbutton id="selectionhandle-start" label="^" left="10" top="10" hidden="true"/>
-          <xul:toolbarbutton id="selectionhandle-end"   label="^" left="10" top="10" hidden="true"/>
-          <xul:toolbarbutton id="selectionhandle-caret" label="^" left="10" top="10" hidden="true"/>
+          <xul:toolbarbutton id="selectionhandle-mark1" label="^" left="10" top="10" hidden="true"/>
+          <xul:toolbarbutton id="selectionhandle-mark2" label="^" left="10" top="10" hidden="true"/>
+          <xul:toolbarbutton id="selectionhandle-mark3" label="^" left="10" top="10" hidden="true"/>
         </xul:stack>
       </html:div>
     </content>
 
     <implementation implements="nsIDOMEventListener">
       <constructor>
         <![CDATA[
           this._selectionOverlay.addEventListener('contextmenu', this);
--- a/browser/metro/base/content/browser-scripts.js
+++ b/browser/metro/base/content/browser-scripts.js
@@ -84,17 +84,16 @@ Cu.import("resource://gre/modules/Geomet
  */
 let ScriptContexts = {};
 [
   ["WebProgress", "chrome://browser/content/WebProgress.js"],
   ["FindHelperUI", "chrome://browser/content/helperui/FindHelperUI.js"],
   ["FormHelperUI", "chrome://browser/content/helperui/FormHelperUI.js"],
   ["BrowserTouchHandler", "chrome://browser/content/BrowserTouchHandler.js"],
   ["AlertsHelper", "chrome://browser/content/helperui/AlertsHelper.js"],
-  ["CapturePickerUI", "chrome://browser/content/helperui/CapturePickerUI.js"],
   ["AutofillMenuUI", "chrome://browser/content/helperui/MenuUI.js"],
   ["ContextMenuUI", "chrome://browser/content/helperui/MenuUI.js"],
   ["MenuControlUI", "chrome://browser/content/helperui/MenuUI.js"],
   ["MenuPopup", "chrome://browser/content/helperui/MenuUI.js"],
   ["IndexedDB", "chrome://browser/content/helperui/IndexedDB.js"],
   ["MasterPasswordUI", "chrome://browser/content/helperui/MasterPasswordUI.js"],
   ["OfflineApps", "chrome://browser/content/helperui/OfflineApps.js"],
   ["SelectHelperUI", "chrome://browser/content/helperui/SelectHelperUI.js"],
--- a/browser/metro/base/content/browser-ui.js
+++ b/browser/metro/base/content/browser-ui.js
@@ -149,23 +149,16 @@ var BrowserUI = {
         PdfJs.init();
 #ifdef MOZ_SERVICES_SYNC
         WeaveGlue.init();
 #endif
       } catch(ex) {
         Util.dumpLn("Exception in delay load module:", ex.message);
       }
 
-      try {
-        // XXX This is currently failing
-        CapturePickerUI.init();
-      } catch(ex) {
-        Util.dumpLn("Exception in CapturePickerUI:", ex.message);
-      }
-
 #ifdef MOZ_UPDATER
       // Check for updates in progress
       let updatePrompt = Cc["@mozilla.org/updates/update-prompt;1"].createInstance(Ci.nsIUpdatePrompt);
       updatePrompt.checkForUpdates();
 #endif
 
       // check for left over crash reports and submit them if found.
       if (BrowserUI.startupCrashCheck()) {
--- a/browser/metro/base/content/contenthandlers/SelectionHandler.js
+++ b/browser/metro/base/content/contenthandlers/SelectionHandler.js
@@ -27,16 +27,20 @@ dump("### SelectionHandler.js loaded\n")
   http://mxr.mozilla.org/mozilla-central/source/dom/interfaces/core/nsIDOMElement.idl
     getClientRect
   http://mxr.mozilla.org/mozilla-central/source/layout/generic/nsFrameSelection.h
   http://mxr.mozilla.org/mozilla-central/source/editor/idl/nsIEditor.idl
   http://mxr.mozilla.org/mozilla-central/source/dom/interfaces/base/nsIFocusManager.idl
 
 */
 
+// selection node parameters for various apis
+const kSelectionNodeAnchor = 1;
+const kSelectionNodeFocus = 2;
+
 var SelectionHandler = {
   _debugEvents: false,
   _cache: {},
   _targetElement: null,
   _targetIsEditable: false,
   _contentWindow: null,
   _contentOffset: { x:0, y:0 },
   _domWinUtils: null,
@@ -53,37 +57,35 @@ var SelectionHandler = {
     addMessageListener("Browser:SelectionMove", this);
     addMessageListener("Browser:SelectionMoveEnd", this);
     addMessageListener("Browser:SelectionUpdate", this);
     addMessageListener("Browser:SelectionClose", this);
     addMessageListener("Browser:SelectionClear", this);
     addMessageListener("Browser:SelectionCopy", this);
     addMessageListener("Browser:SelectionDebug", this);
     addMessageListener("Browser:CaretAttach", this);
+    addMessageListener("Browser:CaretMove", this);
     addMessageListener("Browser:CaretUpdate", this);
-    addMessageListener("Browser:CaretPosition", this);
-    addMessageListener("Browser:CaretPositionEnd", this);
   },
 
   shutdown: function shutdown() {
     removeMessageListener("Browser:SelectionStart", this);
     removeMessageListener("Browser:SelectionAttach", this);
     removeMessageListener("Browser:SelectionEnd", this);
     removeMessageListener("Browser:SelectionMoveStart", this);
     removeMessageListener("Browser:SelectionMove", this);
     removeMessageListener("Browser:SelectionMoveEnd", this);
     removeMessageListener("Browser:SelectionUpdate", this);
     removeMessageListener("Browser:SelectionClose", this);
     removeMessageListener("Browser:SelectionClear", this);
     removeMessageListener("Browser:SelectionCopy", this);
     removeMessageListener("Browser:SelectionDebug", this);
     removeMessageListener("Browser:CaretAttach", this);
+    removeMessageListener("Browser:CaretMove", this);
     removeMessageListener("Browser:CaretUpdate", this);
-    removeMessageListener("Browser:CaretPosition", this);
-    removeMessageListener("Browser:CaretPositionEnd", this);
   },
 
   /*************************************************
    * Properties
    */
 
   /*
    * snap - enable or disable word snap for the active marker when a
@@ -202,17 +204,17 @@ var SelectionHandler = {
       pos = aMsg.end;
     }
 
     this._handleSelectionPoint(aMsg.change, pos, true);
     this._selectionMoveActive = false;
     
     // _handleSelectionPoint may set a scroll timer, so this must
     // be reset after the last call.
-    this.clearTimers();
+    this._clearTimers();
 
     // Update the position of our selection monocles
     this._updateSelectionUI(true, true);
   },
 
    /*
     * _onCaretAttach - called by SelectionHelperUI when the user taps in a
     * form input. Initializes SelectionHandler, updates the location of the
@@ -310,20 +312,25 @@ var SelectionHandler = {
   /*
    * Selection close event handler
    */
   _onSelectionClose: function _onSelectionClose() {
     this._closeSelection();
   },
 
   /*
-   * Selection clear event handler
+   * Selection clear message handler
+   *
+   * @param aClearFocus requests that the focus also be cleared.
    */
-  _onSelectionClear: function _onSelectionClear() {
+  _onSelectionClear: function _onSelectionClear(aClearFocus) {
     this._clearSelection();
+    if (aClearFocus && this._targetElement) {
+      this._targetElement.blur();
+    }
   },
 
   /*
    * Called any time SelectionHelperUI would like us to
    * recalculate the selection bounds.
    */
   _onSelectionUpdate: function _onSelectionUpdate() {
     if (!this._contentWindow) {
@@ -360,17 +367,17 @@ var SelectionHandler = {
    */
 
   /*
    * _clearSelection
    *
    * Clear existing selection if it exists and reset our internla state.
    */
   _clearSelection: function _clearSelection() {
-    this.clearTimers();
+    this._clearTimers();
     if (this._contentWindow) {
       let selection = this._getSelection();
       if (selection)
         selection.removeAllRanges();
     } else {
       let selection = content.getSelection();
       if (selection)
         selection.removeAllRanges();
@@ -379,17 +386,17 @@ var SelectionHandler = {
   },
 
   /*
    * _closeSelection
    *
    * Shuts SelectionHandler down.
    */
   _closeSelection: function _closeSelection() {
-    this.clearTimers();
+    this._clearTimers();
     this._cache = null;
     this._contentWindow = null;
     this.selectedText = "";
     this._selectionMoveActive = false;
   },
 
   /*
    * _updateSelectionUI
@@ -408,22 +415,30 @@ var SelectionHandler = {
 
     // If the range didn't have any text, let's bail
     if (!selection) {
       this._onFail("no selection was present");
       return;
     }
 
     // Updates this._cache content selection position data which we send over
-    // to SelectionHelperUI.
-    this._updateUIMarkerRects(selection);
+    // to SelectionHelperUI. Note updateUIMarkerRects will fail if there isn't
+    // any selection in the page. This can happen when we start a monocle drag
+    // but haven't dragged enough to create selection. Just return. 
+    try {
+      this._updateUIMarkerRects(selection);
+    } catch (ex) {
+      Util.dumpLn(ex.message);
+      return;
+    }
 
     this._cache.updateStart = aUpdateStart;
     this._cache.updateEnd = aUpdateEnd;
     this._cache.updateCaret = aUpdateCaret || false;
+    this._cache.targetIsEditable = this._targetIsEditable;
 
     // Get monocles positioned correctly
     sendAsyncMessage("Content:SelectionRange", this._cache);
   },
 
   /*
    * Find content within frames - cache the target nsIDOMWindow,
    * client coordinate offset, target element, and dom utils interface.
@@ -580,17 +595,17 @@ var SelectionHandler = {
 
         return;
       }
     }
 
     this._lastMarker = aMarker;
 
     // If we aren't out-of-bounds, clear the scroll timer if it exists.
-    this.clearTimers();
+    this._clearTimers();
 
     // Adjusts the selection based on monocle movement
     this._adjustSelection(aMarker, clientPoint, aEndOfSelection);
 
     // Update the other monocle's position. We do this because the dragging
     // monocle may reset the static monocle to a new position if the dragging
     // monocle drags ahead or behind the other.
     if (aMarker == "start") {
@@ -741,22 +756,22 @@ var SelectionHandler = {
       aClientPoint = this._rawSelectionPoint;
     }
     this._rawSelectionPoint = aClientPoint;
 
     let orientation = this._pointOrientationToRect(aClientPoint);
     let result = { speed: 1, trigger: false, start: false, end: false };
 
     if (orientation.left || orientation.top) {
-      this._addEditStartSelection();
+      this._addEditSelection(kSelectionNodeAnchor);
       result.speed = orientation.left + orientation.top;
       result.trigger = true;
       result.end = true;
     } else if (orientation.right || orientation.bottom) {
-      this._addEditEndSelection();
+      this._addEditSelection(kSelectionNodeFocus);
       result.speed = orientation.right + orientation.bottom;
       result.trigger = true;
       result.start = true;
     }
 
     // 'speed' is just total pixels offset, so clamp it to something
     // reasonable callers can work with.
     if (result.speed > 100)
@@ -767,53 +782,44 @@ var SelectionHandler = {
     return result;
   },
 
   _setTextEditUpdateInterval: function _setTextEditUpdateInterval(aSpeedValue) {
     let timeout = (75 - (aSpeedValue * 75));
     this._scrollTimer.interval(timeout, this.scrollTimerCallback);
   },
 
-  /*
-   * Selection control call wrapper
-   */
-  _addEditStartSelection: function _addEditStartSelection() {
-    let selCtrl = this._getSelectController();
-    let selection = this._getSelection();
-    try {
-      this._backupRangeList();
-      selection.collapseToStart();
-      // State: focus = anchor
-      // Only step back if we can, otherwise selCtrl will exception:
-      if (selection.getRangeAt(0).startOffset > 0) {
-        selCtrl.characterMove(false, true);
-      }
-      // State: focus = (anchor - 1)
-      selection.collapseToStart();
-      // State: focus = anchor and both are -1 from the original offset
-      selCtrl.characterMove(true, true);
-      // State: focus = anchor + 1, both have been moved back one char
-      // Restore the rest of the selection:
-      this._restoreRangeList();
-      selCtrl.scrollSelectionIntoView(Ci.nsISelectionController.SELECTION_NORMAL,
-                                      Ci.nsISelectionController.SELECTION_ANCHOR_REGION,
-                                      Ci.nsISelectionController.SCROLL_SYNCHRONOUS);
-    } catch (ex) { Util.dumpLn(ex.message);}
+  _clearTimers: function _clearTimers() {
+    if (this._scrollTimer) {
+      this._scrollTimer.clear();
+    }
   },
 
   /*
-   * Selection control call wrapper
+   * _addEditSelection - selection control call wrapper for text inputs.
+   * Adds selection on the anchor or focus side of selection in a text
+   * input. Scrolls the location into view as well.
+   * (TBD: anchor side scrolling is currently broken, see bug 848594)
+   *
+   * @param const selection node identifier
    */
-  _addEditEndSelection: function _addEditEndSelection() {
+  _addEditSelection: function _addEditSelection(aLocation) {
+    let selCtrl = this._getSelectController();
     try {
-      let selCtrl = this._getSelectController();
-      selCtrl.characterMove(true, true);
-      selCtrl.scrollSelectionIntoView(Ci.nsISelectionController.SELECTION_NORMAL,
-                                      Ci.nsISelectionController.SELECTION_FOCUS_REGION,
-                                      Ci.nsISelectionController.SCROLL_SYNCHRONOUS);
+      if (aLocation == kSelectionNodeAnchor) {
+        this._targetElement.selectionStart = this._targetElement.selectionStart - 1;
+        selCtrl.scrollSelectionIntoView(Ci.nsISelectionController.SELECTION_NORMAL,
+                                        Ci.nsISelectionController.SELECTION_ANCHOR_REGION,
+                                        Ci.nsISelectionController.SCROLL_SYNCHRONOUS);
+      } else {
+        this._targetElement.selectionEnd = this._targetElement.selectionEnd + 1;
+        selCtrl.scrollSelectionIntoView(Ci.nsISelectionController.SELECTION_NORMAL,
+                                        Ci.nsISelectionController.SELECTION_FOCUS_REGION,
+                                        Ci.nsISelectionController.SCROLL_SYNCHRONOUS);
+      }
     } catch (ex) {}
   },
 
   /*
    * _queryHalfLineHeight(aMarker, aSelection)
    *
    * Y offset applied to the coordinates of the selection position we send
    * to dom utils. The selection marker sits below text, but we want the
@@ -836,25 +842,16 @@ var SelectionHandler = {
     } else {
       // height of the last rect corresponding to the end marker:
       let len = rects.length - 1;
       height = rects[len].bottom - rects[len].top;
     }
     return height / 2;
   },
 
-  _findBetterLowerTextRangePoint: function _findBetterLowerTextRangePoint(aClientPoint, aHalfLineHeight) {
-    let range = this._getSelection().getRangeAt(0);
-    let clientRect = range.getBoundingClientRect();
-    if (aClientPoint.y > clientRect.bottom && clientRect.right < aClientPoint.x) {
-      aClientPoint.y = (clientRect.bottom - aHalfLineHeight);
-      this._setDebugPoint(aClientPoint, "red");
-    }
-  },
-
   /*
    * _setContinuousSelection()
    *
    * Smooths a selection with multiple ranges into a single
    * continuous range.
    */
   _setContinuousSelection: function _setContinuousSelection() {
     let selection = this._getSelection();
@@ -968,40 +965,34 @@ var SelectionHandler = {
       }
     } catch (ex) {
       Util.dumpLn("error shrinking selection:", ex.message);
     }
     return result;
   },
 
   /*
+   * Events
+   */
+
+  /*
    * Scroll + selection advancement timer when the monocle is
    * outside the bounds of an input control.
    */
   scrollTimerCallback: function scrollTimerCallback() {
     let result = SelectionHandler.updateTextEditSelection();
     // Update monocle position and speed if we've dragged off to one side
     if (result.trigger) {
       if (result.start)
         SelectionHandler._updateSelectionUI(true, false);
       if (result.end)
         SelectionHandler._updateSelectionUI(false, true);
     }
   },
 
-  clearTimers: function clearTimers() {
-    if (this._scrollTimer) {
-      this._scrollTimer.clear();
-    }
-  },
-
-  /*
-   * Events
-   */
-
   receiveMessage: function sh_receiveMessage(aMessage) {
     if (this._debugEvents && aMessage.name != "Browser:SelectionMove") {
       Util.dumpLn("SelectionHandler:", aMessage.name);
     }
     let json = aMessage.json;
     switch (aMessage.name) {
       case "Browser:SelectionStart":
         this._onSelectionStart(json.xPos, json.yPos);
@@ -1039,17 +1030,17 @@ var SelectionHandler = {
         this._onSelectionMoveEnd(json);
         break;
 
       case "Browser:SelectionCopy":
         this._onSelectionCopy(json);
         break;
 
       case "Browser:SelectionClear":
-        this._onSelectionClear();
+        this._onSelectionClear(json.clearFocus);
         break;
 
       case "Browser:SelectionDebug":
         this._onSelectionDebug(json);
         break;
 
       case "Browser:SelectionUpdate":
         this._onSelectionUpdate();
deleted file mode 100644
--- a/browser/metro/base/content/helperui/CaptureDialog.js
+++ /dev/null
@@ -1,145 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-var CaptureDialog = {
-  _video: null,
-  _container: null,
-  _lastOrientationEvent: null,
-  
-  init: function() {
-    document.getElementsByAttribute('command', 'cmd_ok')[0].focus();
-    this._video = document.getElementById("capturepicker-video");
-    this._container = document.getElementById("capturepicker-container");
-    window.addEventListener("resize", this, false);
-    window.addEventListener("deviceorientation", this, false);
-    this.handleEvent({ type: "resize" });
-  },
-  
-  setPreviewOrientation: function(aEvent) {
-    if (window.innerWidth < window.innerHeight) {
-      if (aEvent.beta > 0)
-        this._video.style.MozTransform = "rotate(90deg)";
-      else
-        this._video.style.MozTransform = "rotate(-90deg)";
-      this._container.classList.add("vertical");
-    }
-    else {
-      if (aEvent.gamma > 0)
-        this._video.style.MozTransform = "rotate(180deg)";
-      else
-        this._video.style.MozTransform = "";
-      this._container.classList.remove("vertical");
-    }
-  },
-  
-  handleEvent: function(aEvent) {
-    if (aEvent.type == "deviceorientation") {
-      if (!this._lastOrientationEvent)
-        this.setPreviewOrientation(aEvent);
-      this._lastOrientationEvent = aEvent;
-    }
-    else if (aEvent.type == "resize") {
-      if (this._lastOrientationEvent)
-        this.setPreviewOrientation(this._lastOrientationEvent);
-    }
-  },
-  
-  cancel: function() {
-    this.doClose(false);
-  },
-  
-  capture: function() {
-    this.doClose(true);
-  },
-  
-  doClose: function(aResult) {
-    window.removeEventListener("resize", this, false);
-    window.removeEventListener("deviceorientation", this, false);
-    let dialog = document.getElementById("capturepicker-dialog");
-    dialog.arguments.result = aResult;
-    if (aResult)
-      dialog.arguments.path = this.saveFrame();
-    document.getElementById("capturepicker-video").setAttribute("src", "");
-    dialog.close();
-  },
-  
-  saveFrame: function() {
-    let Cc = Components.classes;
-    let Ci = Components.interfaces;
-    Components.utils.import("resource://gre/modules/Services.jsm");
-
-    let width = 320;
-    let height = 240;
-    let rotation = 0;
-
-    if (window.innerWidth < window.innerHeight) {
-      width = 240;
-      height = 320;
-      if (this._lastOrientationEvent.beta > 0)
-        rotation = Math.PI / 2;
-      else
-        rotation = -Math.PI / 2;
-    }
-    else {
-      if (this._lastOrientationEvent.gamma > 0)
-        rotation = Math.PI;
-    }
-
-    let canvas = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
-    canvas.width = width;
-    canvas.height = height;
-    let ctx = canvas.getContext("2d");
-    ctx.clearRect(0, 0, canvas.width, canvas.height);
-    //ctx.save();
-    if (rotation != 0) {
-      if (rotation == Math.PI / 2)
-        ctx.translate(width, 0);
-      else if (rotation == -Math.PI / 2)
-        ctx.translate(-width, 0);
-      else
-        ctx.translate(width, height);
-      ctx.rotate(rotation);
-    }
-    ctx.drawImage(document.getElementById("capturepicker-video"), 0, 0, 320, 240);
-    //ctx.restore();
-    let url = canvas.toDataURL("image/png");
-    
-    let tmpDir = Services.dirsvc.get("TmpD", Ci.nsIFile);
-    let file = tmpDir.clone();
-    file.append("capture.png");
-    file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0600);
-    let persist = Cc["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"].createInstance(Ci.nsIWebBrowserPersist);
-  
-    persist.persistFlags = Ci.nsIWebBrowserPersist.PERSIST_FLAGS_REPLACE_EXISTING_FILES | Ci.nsIWebBrowserPersist.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION;
-
-    let mDone = false;
-    let mFailed = false;
-
-    let progressListener = {
-      onProgressChange: function() {
-          /* Ignore progress callback */
-      },
-      onStateChange: function(aProgress, aRequest, aStateFlag, aStatus) {
-        if (aStateFlag & Ci.nsIWebProgressListener.STATE_STOP) {
-          mDone = true;
-        }
-      }
-    }
-    persist.progressListener = progressListener;
-
-    let source = Services.io.newURI(url, "UTF8", null);;
-    persist.saveURI(source, null, null, null, null, file);
-    
-    // don't wait more than 3 seconds for a successful save
-    window.setTimeout(function() {
-      mDone = true;
-      mFailed = true;
-    }, 3000);
-    
-    while (!mDone)
-      Services.tm.currentThread.processNextEvent(true);
-    
-    return (mFailed ? null : file.path);
-  }
-}
deleted file mode 100644
--- a/browser/metro/base/content/helperui/CapturePickerUI.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* appears to have something to do with capturing a camera image. tries to
- * create a dialog, which will fail. TBD. */
-var CapturePickerUI = {
-  init: function() {
-    this.messageManager = Cc["@mozilla.org/parentprocessmessagemanager;1"].getService(Ci.nsIFrameMessageManager);
-    this.messageManager.addMessageListener("CapturePicker:Show", this);
-  },
-  
-  receiveMessage: function(aMessage) {
-    switch (aMessage.name) {
-      case "CapturePicker:Show":
-        let params = { result: true };
-        let dialog = DialogUI.importModal(null, "chrome://browser/content/prompt/CaptureDialog.xul", params);
-        document.getElementById("capturepicker-title").appendChild(document.createTextNode(aMessage.json.title));
-        dialog.waitForClose();
-        return { value: params.result, path: params.path };
-        break;
-    }
-    // prevents warning from the script loader
-    return null;
-  }
-};
--- a/browser/metro/base/content/helperui/SelectionHelperUI.js
+++ b/browser/metro/base/content/helperui/SelectionHelperUI.js
@@ -71,23 +71,25 @@ MarkerDragger.prototype = {
   }
 }
 
 function Marker(aParent, aTag, aElementId, xPos, yPos) {
   this._xPos = xPos;
   this._yPos = yPos;
   this._selectionHelperUI = aParent;
   this._element = document.getElementById(aElementId);
+  this._elementId = aElementId;
   // These get picked in input.js and receives drag input
   this._element.customDragger = new MarkerDragger(this);
   this.tag = aTag;
 }
 
 Marker.prototype = {
   _element: null,
+  _elementId: "",
   _selectionHelperUI: null,
   _xPos: 0,
   _yPos: 0,
   _tag: "",
   _hPlane: 0,
   _vPlane: 0,
 
   // Tweak me if the monocle graphics change in any way
@@ -166,90 +168,127 @@ Marker.prototype = {
 
   dragStop: function dragStop(aDx, aDy) {
     this._selectionHelperUI.markerDragStop(this);
   },
 
   moveBy: function moveBy(aDx, aDy, aClientX, aClientY) {
     this._xPos -= aDx;
     this._yPos -= aDy;
-    this._selectionHelperUI.markerDragMove(this);
-    this._setPosition();
+    let direction = (aDx < 0 || aDy < 0 ? "end" : "start");
+    // We may swap markers in markerDragMove. If markerDragMove
+    // returns true keep processing, otherwise get out of here.
+    if (this._selectionHelperUI.markerDragMove(this, direction)) {
+      this._setPosition();
+    }
   },
 
   hitTest: function hitTest(aX, aY) {
     // Gets the pointer of the arrow right in the middle of the
     // monocle.
     aY += this._monocleYHitTextAdjust;
     aX += this._monocleXHitTextAdjust;
     if (aX >= (this._xPos - this._monocleRadius) &&
         aX <= (this._xPos + this._monocleRadius) &&
         aY >= (this._yPos - this._monocleRadius) &&
         aY <= (this._yPos + this._monocleRadius))
       return true;
     return false;
   },
+
+  swapMonocle: function swapMonocle(aCaret) {
+    let targetElement = aCaret._element;
+    let targetElementId = aCaret._elementId;
+
+    aCaret._element = this._element;
+    aCaret._element.customDragger._marker = aCaret;
+    aCaret._elementId = this._elementId;
+
+    this._xPos = aCaret._xPos;
+    this._yPos = aCaret._yPos;
+    this._element = targetElement;
+    this._element.customDragger._marker = this;
+    this._elementId = targetElementId;
+    this._element.visible = true;
+  },
+
 };
 
 /*
  * SelectionHelperUI
  */
 
 var SelectionHelperUI = {
   _debugEvents: false,
   _msgTarget: null,
   _startMark: null,
   _endMark: null,
   _caretMark: null,
   _target: null,
   _movement: { active: false, x:0, y: 0 },
   _activeSelectionRect: null,
   _selectionHandlerActive: false,
+  _selectionMarkIds: [],
+  _targetIsEditable: false,
+
+  /*
+   * Properties
+   */
 
   get startMark() {
     if (this._startMark == null) {
-      this._startMark = new Marker(this, "start", "selectionhandle-start", 0, 0);
+      this._startMark = new Marker(this, "start", this._selectionMarkIds.pop(), 0, 0);
     }
     return this._startMark;
   },
 
   get endMark() {
     if (this._endMark == null) {
-      this._endMark = new Marker(this, "end", "selectionhandle-end", 0, 0);
+      this._endMark = new Marker(this, "end", this._selectionMarkIds.pop(), 0, 0);
     }
     return this._endMark;
   },
 
   get caretMark() {
     if (this._caretMark == null) {
-      this._caretMark = new Marker(this, "caret", "selectionhandle-caret", 0, 0);
+      this._caretMark = new Marker(this, "caret", this._selectionMarkIds.pop(), 0, 0);
     }
     return this._caretMark;
   },
 
   get overlay() {
     return document.getElementById("selection-overlay");
   },
 
   /*
+   * isActive (prop)
+   *
+   * Determines if an edit session is currently active.
+   */
+  get isActive() {
+    return (this._msgTarget &&
+            this._selectionHandlerActive);
+  },
+
+  /*
+   * Public apis
+   */
+
+  /*
    * openEditSession
    * 
    * Attempts to select underlying text at a point and begins editing
    * the section.
    */
   openEditSession: function openEditSession(aContent, aClientX, aClientY) {
     if (!aContent || this.isActive)
       return;
     this._init(aContent);
     this._setupDebugOptions();
 
-    // Set the track bounds for each marker NIY
-    this.startMark.setTrackBounds(aClientX, aClientY);
-    this.endMark.setTrackBounds(aClientX, aClientY);
-
     // Send this over to SelectionHandler in content, they'll message us
     // back with information on the current selection. SelectionStart
     // takes client coordinates.
     this._selectionHandlerActive = false;
     this._sendAsyncMessage("Browser:SelectionStart", {
       xPos: aClientX,
       yPos: aClientY
     });
@@ -261,20 +300,16 @@ var SelectionHelperUI = {
    * Attaches to existing selection and begins editing.
    */
   attachEditSession: function attachEditSession(aContent, aClientX, aClientY) {
     if (!aContent || this.isActive)
       return;
     this._init(aContent);
     this._setupDebugOptions();
 
-    // Set the track bounds for each marker NIY
-    this.startMark.setTrackBounds(aClientX, aClientY);
-    this.endMark.setTrackBounds(aClientX, aClientY);
-
     // Send this over to SelectionHandler in content, they'll message us
     // back with information on the current selection. SelectionAttach
     // takes client coordinates.
     this._selectionHandlerActive = false;
     this._sendAsyncMessage("Browser:SelectionAttach", {
       xPos: aClientX,
       yPos: aClientY
     });
@@ -284,17 +319,17 @@ var SelectionHelperUI = {
    * attachToCaret
    * 
    * Initiates a touch caret selection session for a text input.
    * Can be called multiple times to move the caret marker around.
    *
    * Note the caret marker is pretty limited in functionality. The
    * only thing is can do is be displayed at the caret position.
    * Once the user starts a drag, the caret marker is hidden, and
-   * the start and end markers take over. (TBD)
+   * the start and end markers take over.
    *
    * @param aClientX, aClientY client coordiates of the tap that
    * initiated the session.
    */
   attachToCaret: function attachToCaret(aContent, aClientX, aClientY) {
     if (!aContent)
       return;
     if (!this.isActive)
@@ -315,55 +350,58 @@ var SelectionHelperUI = {
    */
   canHandleContextMenuMsg: function canHandleContextMenuMsg(aMessage) {
     if (aMessage.json.types.indexOf("content-text") != -1)
       return true;
     return false;
   },
 
   /*
-   * isActive (prop)
-   *
-   * Determines if an edit session is currently active.
-   */
-  get isActive() {
-    return (this._msgTarget &&
-            this._selectionHandlerActive);
-  },
-
-  /*
    * closeEditSession
    *
    * Closes an active edit session and shuts down. Does not clear existing
    * selection regions if they exist.
    */
   closeEditSession: function closeEditSession() {
     this._sendAsyncMessage("Browser:SelectionClose");
     this._shutdown();
   },
 
   /*
    * closeEditSessionAndClear
-   * 
+   *
    * Closes an active edit session and shuts down. Clears any selection region
    * associated with the edit session.
+   *
+   * @param aClearFocus bool indicating if the selection handler should also
+   * clear the focus element. optional, the default is false.
    */
-  closeEditSessionAndClear: function closeEditSessionAndClear() {
-    this._sendAsyncMessage("Browser:SelectionClear");
+  closeEditSessionAndClear: function closeEditSessionAndClear(aClearFocus) {
+    let clearFocus = aClearFocus || false;
+    this._sendAsyncMessage("Browser:SelectionClear", { clearFocus: clearFocus });
     this.closeEditSession();
   },
 
   /*
    * Init and shutdown
    */
 
   _init: function _init(aMsgTarget) {
     // store the target message manager
     this._msgTarget = aMsgTarget;
 
+    // Init our list of available monocle ids
+    this._selectionMarkIds = ["selectionhandle-mark1",
+                              "selectionhandle-mark2",
+                              "selectionhandle-mark3"];
+
+    // Init selection rect info
+    this._activeSelectionRect = Util.getCleanRect();
+    this._targetElementRect = Util.getCleanRect();
+
     // SelectionHandler messages
     messageManager.addMessageListener("Content:SelectionRange", this);
     messageManager.addMessageListener("Content:SelectionCopied", this);
     messageManager.addMessageListener("Content:SelectionFail", this);
     messageManager.addMessageListener("Content:SelectionDebugRect", this);
 
     // selection related events
     window.addEventListener("click", this, false);
@@ -414,33 +452,82 @@ var SelectionHelperUI = {
 
     if (this.startMark != null)
       this.startMark.shutdown();
     if (this.endMark != null)
       this.endMark.shutdown();
     if (this._caretMark != null)
       this._caretMark.shutdown();
 
-    delete this._startMark;
-    delete this._endMark;
-    delete this._caretMark;
+    this._startMark = null;
+    this._endMark = null;
+    this._caretMark = null;
 
+    this._selectionMarkIds = [];
     this._msgTarget = null;
     this._activeSelectionRect = null;
     this._selectionHandlerActive = false;
 
     this.overlay.displayDebugLayer = false;
     this.overlay.enabled = false;
   },
 
   /*
    * Utilities
    */
 
   /*
+   * _swapCaretMarker
+   *
+   * Swap two drag markers - used when transitioning from caret mode
+   * to selection mode. We take the current caret marker (which is in a
+   * drag state) and swap it out with one of the selection markers.
+   */
+  _swapCaretMarker: function _swapCaretMarker(aDirection) {
+    let targetMark = null;
+    if (aDirection == "start")
+      targetMark = this.startMark;
+    else
+      targetMark = this.endMark;
+    let caret = this.caretMark;
+    targetMark.swapMonocle(caret);
+    let id = caret._elementId;
+    caret.shutdown();
+    this._caretMark = null;
+    this._selectionMarkIds.push(id);
+  },
+
+  /*
+   * _transitionFromCaretToSelection
+   *
+   * Transitions from caret mode to text selection mode.
+   */
+  _transitionFromCaretToSelection: function _transitionFromCaretToSelection(aDirection) {
+    // Get selection markers initialized if they aren't already
+    { let mark = this.startMark; mark = this.endMark; }
+
+    // Swap the caret marker out for the start or end marker depending
+    // on direction.
+    this._swapCaretMarker(aDirection);
+
+    let targetMark = null;
+    if (aDirection == "start")
+      targetMark = this.startMark;
+    else
+      targetMark = this.endMark;
+    // Start the selection monocle drag. SelectionHandler relies on this
+    // for getting initialized. This will also trigger a message back for
+    // monocle positioning. Note, markerDragMove is still on the stack in
+    // this call!
+    targetMark._setPosition();
+    this.markerDragStart(targetMark);
+    this.markerDragMove(targetMark, aDirection);
+  },
+
+  /*
    * _setupDebugOptions
    *
    * Sends a message over to content instructing it to
    * turn on various debug features.
    */
   _setupDebugOptions: function _setupDebugOptions() {
     // Debug options for selection
     let debugOpts = { dumpRanges: false, displayRanges: false, dumpEvents: false };
@@ -504,44 +591,63 @@ var SelectionHelperUI = {
 
   /*
    * Event handlers for document events
    */
 
   /*
    * _onTap
    * 
-   * Handles taps that move the current caret around text text
-   * edits. Also will clear active selection if it is present.
-   * Future: changing slection modes by tapping on a monocle.
+   * Handles taps that move the current caret around in text edits,
+   * clear active selection and focus when neccessary, or change
+   * modes.
+   * Future: changing selection modes by tapping on a monocle.
    */
   _onTap: function _onTap(aEvent) {
+    // Check for a tap on a monocle
     if (this.startMark.hitTest(aEvent.clientX, aEvent.clientY) ||
         this.endMark.hitTest(aEvent.clientX, aEvent.clientY)) {
+      aEvent.stopPropagation();
+      aEvent.preventDefault();
       return;
     }
 
-    // If the tap is within the target element and the caret monocle is
+    // Is the tap point within the bound of the target element? This
+    // is useful if we are dealing with some sort of input control.
+    // Not so much if the target is a page or div.
+    let pointInTargetElement =
+      Util.pointWithinRect(aEvent.clientX, aEvent.clientY,
+                           this._targetElementRect);
+
+    // If the tap is within an editable element and the caret monocle is
     // active, update the caret.
-    if (this.caretMark.visible &&
-        Util.pointWithinRect(aEvent.clientX, aEvent.clientY,
-                             this._targetElementRect)) {
+    if (this.caretMark.visible && pointInTargetElement) {
       // Move the caret
       this._setCaretPositionAtPoint(aEvent.clientX, aEvent.clientY);
       return;
     }
 
+    // if the target is editable and the user clicks off the target
+    // clear selection and remove focus from the input.
     if (this.caretMark.visible) {
-      // shutdown selection
-      this.closeEditSessionAndClear();
+      // shutdown and clear selection and remove focus
+      this.closeEditSessionAndClear(true);
       return;
     }
 
-    // If we have active selection w/monocles, don't let random taps
-    // kill selection.
+    // If the target is editable, we have active selection, and
+    // the user taps off the input, clear selection and shutdown.
+    if (this.startMark.visible && !pointInTargetElement &&
+        this._targetIsEditable) {
+      this.closeEditSessionAndClear(true);
+      return;
+    }
+
+    // If we have active selection in anything else don't let the event get
+    // to content. Prevents random taps from killing active selection.
     aEvent.stopPropagation();
     aEvent.preventDefault();
   },
 
   /*
    * Checks to see if the tap event was on our selection rect.
    * If it is, we select the underlying text and shutdown.
    */
@@ -577,16 +683,17 @@ var SelectionHelperUI = {
       this.endMark.show();
     }
     if (json.updateCaret) {
       this.caretMark.position(json.caret.xPos, json.caret.yPos);
       this.caretMark.show();
     }
     this._activeSelectionRect = json.selection;
     this._targetElementRect = json.element;
+    this._targetIsEditable = json.targetIsEditable;
   },
 
   _onSelectionFail: function _onSelectionFail() {
     Util.dumpLn("failed to get a selection.");
     this.closeEditSession();
   },
 
   _onKeypress: function _onKeypress() {
@@ -726,18 +833,22 @@ var SelectionHelperUI = {
     json.change = aMarker.tag;
     if (aMarker.tag == "caret") {
       this._sendAsyncMessage("Browser:CaretUpdate", json);
       return;
     }
     this._sendAsyncMessage("Browser:SelectionMoveEnd", json);
   },
 
-  markerDragMove: function markerDragMove(aMarker) {
+  markerDragMove: function markerDragMove(aMarker, aDirection) {
     let json = this._getMarkerBaseMessage();
     json.change = aMarker.tag;
     if (aMarker.tag == "caret") {
-      this._sendAsyncMessage("Browser:CaretMove", json);
-      return;
+      // We are going to transition from caret browsing mode to selection mode
+      // on a drag. So swap the caret monocle for a start or end monocle
+      // depending on the direction of the drag, and start selecting text.
+      this._transitionFromCaretToSelection(aDirection);
+      return false;
     }
     this._sendAsyncMessage("Browser:SelectionMove", json);
+    return true;
   },
 };
--- a/browser/metro/base/content/input.js
+++ b/browser/metro/base/content/input.js
@@ -141,20 +141,22 @@ var TouchModule = {
           case "touchend":
             this._onTouchEnd(aEvent);
             break;
           case "dblclick":
             // XXX This will get picked up somewhere below us for "double tap to zoom"
             // once we get omtc and the apzc. Currently though dblclick is delivered to
             // content and triggers selection of text, so fire up the SelectionHelperUI
             // once selection is present.
-            setTimeout(function () {
-              SelectionHelperUI.attachEditSession(Browser.selectedTab.browser,
-                                                  aEvent.clientX, aEvent.clientY);
-            }, 50);
+            if (!SelectionHelperUI.isActive) {
+              setTimeout(function () {
+                SelectionHelperUI.attachEditSession(Browser.selectedTab.browser,
+                                                    aEvent.clientX, aEvent.clientY);
+              }, 50);
+            }
             break;
         }
       }
     }
   },
 
   sample: function sample(aTimeStamp) {
     this._waitingForPaint = false;
deleted file mode 100644
--- a/browser/metro/base/content/prompt/CaptureDialog.xul
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0"?>
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
-   - License, v. 2.0. If a copy of the MPL was not distributed with this
-   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<!DOCTYPE dialog SYSTEM "chrome://browser/locale/prompt.dtd">
-<dialog id="capturepicker-dialog"
-        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-        onload="document.getElementById('capturepicker-dialog').CaptureDialog.init()"
-        script="chrome://browser/content/CaptureDialog.js">
-
-  <keyset>
-    <key keycode="VK_RETURN" command="cmd_ok"/>
-    <key keycode="VK_ESCAPE" command="cmd_cancel"/>
-  </keyset>
-
-  <commandset>
-    <command id="cmd_ok" oncommand="document.getElementById('capturepicker-dialog').CaptureDialog.capture();"/>
-    <command id="cmd_cancel" oncommand="document.getElementById('capturepicker-dialog').CaptureDialog.cancel();"/>
-  </commandset>
-
-  <vbox class="prompt-inner">
-    <vbox class="prompt-header" flex="1">
-      <description id="capturepicker-title" class="prompt-title" crop="center" flex="1"/>
-      <hbox flex="1" pack="center">
-        <vbox id="capturepicker-container" pack="center">
-          <video xmlns="http://www.w3.org/1999/xhtml" id="capturepicker-video"
-                 width="320" height="240"
-                 src="moz-device:?width=320&amp;height=240&amp;type=video/x-raw-yuv"
-                 autoplay="true"> </video>
-        </vbox>
-      </hbox>
-    </vbox>
-  
-    <hbox id="capturepicker-buttons-box" class="prompt-buttons">
-      <button class="prompt-button" label="&ok.label;" command="cmd_ok"/>
-      <button class="prompt-button" label="&cancel.label;" command="cmd_cancel"/>
-    </hbox>
-  </vbox>
-</dialog>
--- a/browser/metro/base/jar.mn
+++ b/browser/metro/base/jar.mn
@@ -25,29 +25,26 @@ chrome.jar:
   content/bindings/pageaction.xml              (content/bindings/pageaction.xml)
   content/bindings/arrowbox.xml                (content/bindings/arrowbox.xml)
   content/bindings/grid.xml                    (content/bindings/grid.xml)
   content/bindings/autocomplete.xml            (content/bindings/autocomplete.xml)
   content/bindings/appbar.xml                  (content/bindings/appbar.xml)
   content/bindings/flyoutpanel.xml             (content/bindings/flyoutpanel.xml)
   content/bindings/selectionoverlay.xml        (content/bindings/selectionoverlay.xml)
 
-  content/prompt/CaptureDialog.xul             (content/prompt/CaptureDialog.xul)
   content/prompt/alert.xul                     (content/prompt/alert.xul)
   content/prompt/confirm.xul                   (content/prompt/confirm.xul)
   content/prompt/prompt.xul                    (content/prompt/prompt.xul)
   content/prompt/promptPassword.xul            (content/prompt/promptPassword.xul)
   content/prompt/select.xul                    (content/prompt/select.xul)
   content/prompt/prompt.js                     (content/prompt/prompt.js)
   content/prompt/masterPassword.xul            (content/prompt/masterPassword.xul)
   content/prompt/removeMasterPassword.xul      (content/prompt/removeMasterPassword.xul)
 
   content/helperui/AlertsHelper.js             (content/helperui/AlertsHelper.js)
-  content/helperui/CaptureDialog.js            (content/helperui/CaptureDialog.js)
-  content/helperui/CapturePickerUI.js          (content/helperui/CapturePickerUI.js)
   content/helperui/IndexedDB.js                (content/helperui/IndexedDB.js)
   content/helperui/MasterPasswordUI.js         (content/helperui/MasterPasswordUI.js)
   content/helperui/MenuUI.js                   (content/helperui/MenuUI.js)
   content/helperui/OfflineApps.js              (content/helperui/OfflineApps.js)
   content/helperui/SelectHelperUI.js           (content/helperui/SelectHelperUI.js)
   content/helperui/SelectionHelperUI.js        (content/helperui/SelectionHelperUI.js)
   content/helperui/FormHelperUI.js             (content/helperui/FormHelperUI.js)
   content/helperui/FindHelperUI.js             (content/helperui/FindHelperUI.js)
--- a/browser/metro/components/components.manifest
+++ b/browser/metro/components/components.manifest
@@ -88,13 +88,8 @@ contract @mozilla.org/safebrowsing/appli
 category app-startup SafeBrowsing service,@mozilla.org/safebrowsing/application;1
 #endif
 
 #ifdef MOZ_UPDATER
 # UpdatePrompt.js
 component {88b3eb21-d072-4e3b-886d-f89d8c49fe59} UpdatePrompt.js
 contract @mozilla.org/updates/update-prompt;1 {88b3eb21-d072-4e3b-886d-f89d8c49fe59}
 #endif
-
-# CapturePicker.js
-component {cb5a47f0-b58c-4fc3-b61a-358ee95f8238} CapturePicker.js
-contract @mozilla.org/capturepicker;1 {cb5a47f0-b58c-4fc3-b61a-358ee95f8238}
-
--- a/browser/metro/theme/browser.css
+++ b/browser/metro/theme/browser.css
@@ -929,28 +929,28 @@ setting[type="directory"] > .preferences
 .scroller[orient="horizontal"] {
   min-height: @scroller_thickness@;
   height: @scroller_thickness@;
   min-width: @scroller_minimum@;
 }
 
 /* Text selection handles */
 
-#selectionhandle-start,
-#selectionhandle-end,
-#selectionhandle-caret {
+#selectionhandle-mark1,
+#selectionhandle-mark2,
+#selectionhandle-mark3 {
   border: 0px solid gray;
   padding: 0px;
   margin-top: -30px;
   margin-left: -18px;
 }
 
-#selectionhandle-start,
-#selectionhandle-end,
-#selectionhandle-caret {
+#selectionhandle-mark1,
+#selectionhandle-mark2,
+#selectionhandle-mark3 {
   list-style-image: url("chrome://browser/skin/images/selection-monocle.png");
 }
 
 /* Capture picker ------------------------------------------------------------- */
 
 #capturepicker-video {
   border: @border_width_tiny@ solid white;
 }
--- a/build/Makefile.in
+++ b/build/Makefile.in
@@ -84,17 +84,16 @@ PYTHON_UNIT_TESTS := \
 
 include $(topsrcdir)/config/rules.mk
 
 # we install to _leaktest/
 TARGET_DEPTH = ..
 include $(srcdir)/automation-build.mk
 
 _LEAKTEST_DIR = $(DEPTH)/_leaktest
-GARBAGE_DIRS += $(_LEAKTEST_DIR)
 
 _LEAKTEST_FILES =    \
 		automation.py \
 		automationutils.py \
 		leaktest.py \
 		bloatcycle.html \
 		$(topsrcdir)/build/pgo/server-locations.txt \
 		$(topsrcdir)/build/pgo/favicon.ico \
--- a/build/automation.py.in
+++ b/build/automation.py.in
@@ -19,16 +19,34 @@ import threading
 import tempfile
 import sqlite3
 from string import Template
 
 SCRIPT_DIR = os.path.abspath(os.path.realpath(os.path.dirname(sys.argv[0])))
 sys.path.insert(0, SCRIPT_DIR)
 import automationutils
 
+# --------------------------------------------------------------
+# TODO: this is a hack for mozbase without virtualenv, remove with bug 849900
+#
+here = os.path.dirname(__file__)
+mozbase = os.path.realpath(os.path.join(os.path.dirname(here), 'mozbase'))
+
+try:
+    import mozcrash
+except:
+    deps = ['mozcrash',
+            'mozlog']
+    for dep in deps:
+        module = os.path.join(mozbase, dep)
+        if module not in sys.path:
+            sys.path.append(module)
+    import mozcrash
+# ---------------------------------------------------------------
+
 _DEFAULT_WEB_SERVER = "127.0.0.1"
 _DEFAULT_HTTP_PORT = 8888
 _DEFAULT_SSL_PORT = 4443
 _DEFAULT_WEBSOCKET_PORT = 9988
 
 # from nsIPrincipal.idl
 _APP_STATUS_NOT_INSTALLED = 0
 _APP_STATUS_INSTALLED     = 1
@@ -1127,17 +1145,17 @@ user_pref("camino.use_system_proxy_setti
       self.log.info("INFO | automation.py | Checking for orphan process with PID: %d", processPID)
       if self.isPidAlive(processPID):
         foundZombie = True
         self.log.info("TEST-UNEXPECTED-FAIL | automation.py | child process %d still alive after shutdown", processPID)
         self.killPid(processPID)
     return foundZombie
 
   def checkForCrashes(self, profileDir, symbolsPath):
-    return automationutils.checkForCrashes(os.path.join(profileDir, "minidumps"), symbolsPath, self.lastTestSeen)
+    return mozcrash.check_for_crashes(os.path.join(profileDir, "minidumps"), symbolsPath, test_name=self.lastTestSeen)
 
   def runApp(self, testURL, env, app, profileDir, extraArgs,
              runSSLTunnel = False, utilityPath = None,
              xrePath = None, certPath = None,
              debuggerInfo = None, symbolsPath = None,
              timeout = -1, maxTime = None, onLaunch = None):
     """
     Run the app, log the duration it took to execute, return the status code.
--- a/build/automationutils.py
+++ b/build/automationutils.py
@@ -6,17 +6,16 @@
 from __future__ import with_statement
 import glob, logging, os, platform, shutil, subprocess, sys, tempfile, urllib2, zipfile
 import re
 from urlparse import urlparse
 
 __all__ = [
   "ZipFileReader",
   "addCommonOptions",
-  "checkForCrashes",
   "dumpLeakLog",
   "isURL",
   "processLeakLog",
   "getDebuggerInfo",
   "DEBUGGER_INFO",
   "replaceBackSlashes",
   "wrapCommand",
   ]
@@ -127,105 +126,16 @@ def addCommonOptions(parser, defaults={}
                     action = "store", dest = "debuggerArgs",
                     help = "pass the given args to the debugger _before_ "
                            "the application on the command line")
   parser.add_option("--debugger-interactive",
                     action = "store_true", dest = "debuggerInteractive",
                     help = "prevents the test harness from redirecting "
                         "stdout and stderr for interactive debuggers")
 
-def checkForCrashes(dumpDir, symbolsPath, testName=None):
-  stackwalkPath = os.environ.get('MINIDUMP_STACKWALK', None)
-  # try to get the caller's filename if no test name is given
-  if testName is None:
-    try:
-      testName = os.path.basename(sys._getframe(1).f_code.co_filename)
-    except:
-      testName = "unknown"
-
-  # Check preconditions
-  dumps = glob.glob(os.path.join(dumpDir, '*.dmp'))
-  if len(dumps) == 0:
-    return False
-
-  try:
-    removeSymbolsPath = False
-
-    # If our symbols are at a remote URL, download them now
-    if symbolsPath and isURL(symbolsPath):
-      print "Downloading symbols from: " + symbolsPath
-      removeSymbolsPath = True
-      # Get the symbols and write them to a temporary zipfile
-      data = urllib2.urlopen(symbolsPath)
-      symbolsFile = tempfile.TemporaryFile()
-      symbolsFile.write(data.read())
-      # extract symbols to a temporary directory (which we'll delete after
-      # processing all crashes)
-      symbolsPath = tempfile.mkdtemp()
-      zfile = ZipFileReader(symbolsFile)
-      zfile.extractall(symbolsPath)
-
-    for d in dumps:
-      stackwalkOutput = []
-      stackwalkOutput.append("Crash dump filename: " + d)
-      topFrame = None
-      if symbolsPath and stackwalkPath and os.path.exists(stackwalkPath):
-        # run minidump stackwalk
-        p = subprocess.Popen([stackwalkPath, d, symbolsPath],
-                             stdout=subprocess.PIPE,
-                             stderr=subprocess.PIPE)
-        (out, err) = p.communicate()
-        if len(out) > 3:
-          # minidump_stackwalk is chatty, so ignore stderr when it succeeds.
-          stackwalkOutput.append(out)
-          # The top frame of the crash is always the line after "Thread N (crashed)"
-          # Examples:
-          #  0  libc.so + 0xa888
-          #  0  libnss3.so!nssCertificate_Destroy [certificate.c : 102 + 0x0]
-          #  0  mozjs.dll!js::GlobalObject::getDebuggers() [GlobalObject.cpp:89df18f9b6da : 580 + 0x0]
-          #  0  libxul.so!void js::gc::MarkInternal<JSObject>(JSTracer*, JSObject**) [Marking.cpp : 92 + 0x28]
-          lines = out.splitlines()
-          for i, line in enumerate(lines):
-            if "(crashed)" in line:
-              match = re.search(r"^ 0  (?:.*!)?(?:void )?([^\[]+)", lines[i+1])
-              if match:
-                topFrame = "@ %s" % match.group(1).strip()
-              break
-        else:
-          stackwalkOutput.append("stderr from minidump_stackwalk:")
-          stackwalkOutput.append(err)
-        if p.returncode != 0:
-          stackwalkOutput.append("minidump_stackwalk exited with return code %d" % p.returncode)
-      else:
-        if not symbolsPath:
-          stackwalkOutput.append("No symbols path given, can't process dump.")
-        if not stackwalkPath:
-          stackwalkOutput.append("MINIDUMP_STACKWALK not set, can't process dump.")
-        elif stackwalkPath and not os.path.exists(stackwalkPath):
-          stackwalkOutput.append("MINIDUMP_STACKWALK binary not found: %s" % stackwalkPath)
-      if not topFrame:
-        topFrame = "Unknown top frame"
-      log.info("PROCESS-CRASH | %s | application crashed [%s]", testName, topFrame)
-      print '\n'.join(stackwalkOutput)
-      dumpSavePath = os.environ.get('MINIDUMP_SAVE_PATH', None)
-      if dumpSavePath:
-        shutil.move(d, dumpSavePath)
-        print "Saved dump as %s" % os.path.join(dumpSavePath,
-                                                os.path.basename(d))
-      else:
-        os.remove(d)
-      extra = os.path.splitext(d)[0] + ".extra"
-      if os.path.exists(extra):
-        os.remove(extra)
-  finally:
-    if removeSymbolsPath:
-      shutil.rmtree(symbolsPath)
-
-  return True
-
 def getFullPath(directory, path):
   "Get an absolute path relative to 'directory'."
   return os.path.normpath(os.path.join(directory, os.path.expanduser(path)))
 
 def searchPath(directory, path):
   "Go one step beyond getFullPath and try the various folders in PATH"
   # Try looking in the current working directory first.
   newpath = getFullPath(directory, path)
--- a/build/mobile/remoteautomation.py
+++ b/build/mobile/remoteautomation.py
@@ -1,16 +1,15 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 import time
 import re
 import os
-import automationutils
 import tempfile
 import shutil
 import subprocess
 
 from automation import Automation
 from devicemanager import NetworkTools, DMError
 
 # signatures for logcat messages that we don't care about much
@@ -128,18 +127,18 @@ class RemoteAutomation(Automation):
             if not self._devicemanager.dirExists(remoteCrashDir):
                 # As of this writing, the minidumps directory is automatically
                 # created when fennec (first) starts, so its lack of presence
                 # is a hint that something went wrong.
                 print "Automation Error: No crash directory (%s) found on remote device" % remoteCrashDir
                 # Whilst no crash was found, the run should still display as a failure
                 return True
             self._devicemanager.getDirectory(remoteCrashDir, dumpDir)
-            crashed = automationutils.checkForCrashes(dumpDir, symbolsPath,
-                                            self.lastTestSeen)
+            crashed = Automation.checkForCrashes(self, dumpDir, symbolsPath)
+
         finally:
             try:
                 shutil.rmtree(dumpDir)
             except:
                 print "WARNING: unable to remove directory: %s" % dumpDir
         return crashed
 
     def buildCommandLine(self, app, debuggerInfo, profileDir, testURL, extraArgs):
new file mode 100644
--- /dev/null
+++ b/content/base/crashtests/849601.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8">
+<script>
+
+function addEmptyMutationObserver()
+{
+  var m = new MutationObserver(function () {});
+  var e = document.createElement('i');
+  m.observe(e, { childList: true });
+}
+
+function addPointlessMutationListener()
+{
+  var a = document.createElementNS("http://www.w3.org/1999/xhtml", "div");
+  a.appendChild(document.createTextNode("1"));
+
+  function f() {
+    window.removeEventListener("DOMSubtreeModified", f, false);
+    a.insertAdjacentHTML("afterBegin", "<span></span>");
+  };
+
+  window.addEventListener("DOMSubtreeModified", f, false);
+}
+
+function boom()
+{
+  addEmptyMutationObserver();
+  addPointlessMutationListener();
+  document.body.outerHTML = "";
+}
+
+</script>
+</head>
+
+<body onload="boom();"></body>
+</html>
--- a/content/base/crashtests/crashtests.list
+++ b/content/base/crashtests/crashtests.list
@@ -127,8 +127,9 @@ load 822723.html
 load 824719.html
 load 827190.html
 load 828054.html
 load 829428.html
 load 836890.html
 load 841205.html
 load 844404.html
 load 847127.html
+load 849601.html
--- a/content/base/public/Element.h
+++ b/content/base/public/Element.h
@@ -1202,21 +1202,16 @@ inline mozilla::dom::Element* nsINode::A
 }
 
 inline const mozilla::dom::Element* nsINode::AsElement() const
 {
   MOZ_ASSERT(IsElement());
   return static_cast<const mozilla::dom::Element*>(this);
 }
 
-inline bool nsINode::HasAttributes() const
-{
-  return IsElement() && AsElement()->GetAttrCount() > 0;
-}
-
 /**
  * Macros to implement Clone(). _elementName is the class for which to implement
  * Clone.
  */
 #define NS_IMPL_ELEMENT_CLONE(_elementName)                                 \
 nsresult                                                                    \
 _elementName::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const        \
 {                                                                           \
--- a/content/base/public/nsINode.h
+++ b/content/base/public/nsINode.h
@@ -1567,18 +1567,16 @@ public:
   {
     mNodeInfo->GetPrefix(aPrefix);
   }
 #endif
   void GetLocalName(nsAString& aLocalName)
   {
     aLocalName = mNodeInfo->LocalName();
   }
-  // HasAttributes is defined inline in Element.h.
-  bool HasAttributes() const;
   nsDOMAttributeMap* GetAttributes();
   JS::Value SetUserData(JSContext* aCx, const nsAString& aKey, JS::Value aData,
                         nsIDOMUserDataHandler* aHandler,
                         mozilla::ErrorResult& aError);
   JS::Value GetUserData(JSContext* aCx, const nsAString& aKey,
                         mozilla::ErrorResult& aError);
 
   // Helper method to remove this node from its parent. This is not exposed
@@ -2006,22 +2004,16 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsINode, N
     nsINode::GetPrefix(aPrefix); \
     return NS_OK; \
   } \
   NS_IMETHOD GetLocalName(nsAString& aLocalName) __VA_ARGS__ \
   { \
     nsINode::GetLocalName(aLocalName); \
     return NS_OK; \
   } \
-  using nsINode::HasAttributes; \
-  NS_IMETHOD HasAttributes(bool* aResult) __VA_ARGS__ \
-  { \
-    *aResult = nsINode::HasAttributes(); \
-    return NS_OK; \
-  } \
   NS_IMETHOD GetDOMBaseURI(nsAString& aBaseURI) __VA_ARGS__ \
   { \
     nsINode::GetBaseURI(aBaseURI); \
     return NS_OK; \
   } \
   NS_IMETHOD CompareDocumentPosition(nsIDOMNode* aOther, uint16_t* aResult) __VA_ARGS__ \
   { \
     return nsINode::CompareDocumentPosition(aOther, aResult); \
--- a/content/base/src/Element.cpp
+++ b/content/base/src/Element.cpp
@@ -3382,17 +3382,16 @@ Element::SetOuterHTML(const nsAString& a
     nsCOMPtr<nsIContent> fragment = do_QueryInterface(df);
     nsContentUtils::ParseFragmentHTML(aOuterHTML,
                                       fragment,
                                       localName,
                                       namespaceID,
                                       OwnerDoc()->GetCompatibilityMode() ==
                                         eCompatibility_NavQuirks,
                                       true);
-    nsAutoMutationBatch mb(parent, true, false);
     parent->ReplaceChild(*fragment, *this, aError);
     return;
   }
 
   nsCOMPtr<nsINode> context;
   if (parent->IsElement()) {
     context = parent;
   } else {
@@ -3410,17 +3409,16 @@ Element::SetOuterHTML(const nsAString& a
   aError = nsContentUtils::CreateContextualFragment(context,
                                                     aOuterHTML,
                                                     true,
                                                     getter_AddRefs(df));
   if (aError.Failed()) {
     return;
   }
   nsCOMPtr<nsINode> fragment = do_QueryInterface(df);
-  nsAutoMutationBatch mb(parent, true, false);
   parent->ReplaceChild(*fragment, *this, aError);
 }
 
 enum nsAdjacentPosition {
   eBeforeBegin,
   eAfterBegin,
   eBeforeEnd,
   eAfterEnd
--- a/content/media/webaudio/AudioDestinationNode.h
+++ b/content/media/webaudio/AudioDestinationNode.h
@@ -30,15 +30,21 @@ public:
 
   virtual JSObject* WrapObject(JSContext* aCx, JSObject* aScope) MOZ_OVERRIDE;
 
   virtual uint32_t NumberOfOutputs() const MOZ_FINAL MOZ_OVERRIDE
   {
     return 0;
   }
 
+  void JSBindingFinalized()
+  {
+    // Don't do anything special for destination nodes, as they will always
+    // remain accessible through the AudioContext.
+  }
+
 };
 
 }
 }
 
 #endif
 
--- a/dom/imptests/failures/webapps/DOMCore/tests/submissions/Ms2ger/test_historical.html.json
+++ b/dom/imptests/failures/webapps/DOMCore/tests/submissions/Ms2ger/test_historical.html.json
@@ -5,12 +5,11 @@
   "Historical DOM features must be removed: createAttribute": true,
   "Historical DOM features must be removed: createAttributeNS": true,
   "Historical DOM features must be removed: inputEncoding": true,
   "Historical DOM features must be removed: getAttributeNode": true,
   "Historical DOM features must be removed: getAttributeNodeNS": true,
   "Historical DOM features must be removed: setAttributeNode": true,
   "Historical DOM features must be removed: removeAttributeNode": true,
   "DocumentType member must be nuked: internalSubset": true,
-  "Node member must be nuked: hasAttributes": true,
   "Node member must be nuked: getUserData": true,
   "Node member must be nuked: setUserData": true
 }
--- a/dom/interfaces/core/nsIDOMAttr.idl
+++ b/dom/interfaces/core/nsIDOMAttr.idl
@@ -9,17 +9,17 @@
  * The nsIDOMAttr interface represents an attribute in an "Element" object. 
  * Typically the allowable values for the attribute are defined in a document 
  * type definition.
  * 
  * For more information on this interface please see 
  * http://www.w3.org/TR/DOM-Level-2-Core/
  */
 
-[scriptable, builtinclass, uuid(a974a4d3-2ff1-445b-8b8e-0aada5d4eedc)]
+[scriptable, builtinclass, uuid(05568261-182f-4911-8b1e-8c8d7ffe79f9)]
 interface nsIDOMAttr : nsIDOMNode
 {
   readonly attribute DOMString            name;
   readonly attribute boolean              specified;
            attribute DOMString            value;
                                             // raises(DOMException) on setting
 
   // Introduced in DOM Level 2:
--- a/dom/interfaces/core/nsIDOMCDATASection.idl
+++ b/dom/interfaces/core/nsIDOMCDATASection.idl
@@ -10,12 +10,12 @@
  * that would otherwise be regarded as markup.
  * Their primary purpose is for including material such as XML fragments, 
  * without needing to escape all the delimiters.
  * 
  * For more information on this interface please see 
  * http://www.w3.org/TR/DOM-Level-2-Core/
  */
 
-[scriptable, uuid(cfad94e0-92d6-4b32-ab18-c61f9b8cb313)]
+[scriptable, uuid(3f73b88e-d158-416d-990f-740baabf262e)]
 interface nsIDOMCDATASection : nsIDOMText
 {
 };
--- a/dom/interfaces/core/nsIDOMCharacterData.idl
+++ b/dom/interfaces/core/nsIDOMCharacterData.idl
@@ -8,17 +8,17 @@
 /**
  * The nsIDOMCharacterData interface extends nsIDOMNode with a set of 
  * attributes and methods for accessing character data in the DOM.
  * 
  * For more information on this interface please see 
  * http://www.w3.org/TR/DOM-Level-2-Core/
  */
 
-[scriptable, uuid(05c29ae6-5533-42b6-9085-257f60445d5a)]
+[scriptable, uuid(e934716a-f7ee-46a4-9b6c-d084163d6b48)]
 interface nsIDOMCharacterData : nsIDOMNode
 {
            attribute DOMString            data;
                                   // raises(DOMException) on setting
                                   // raises(DOMException) on retrieval
 
   readonly attribute unsigned long        length;
   DOMString                 substringData(in unsigned long offset, 
--- a/dom/interfaces/core/nsIDOMComment.idl
+++ b/dom/interfaces/core/nsIDOMComment.idl
@@ -9,12 +9,12 @@
  * The nsIDOMComment interface inherits from nsIDOMCharacterData and represents 
  * the content of a comment, i.e., all the characters between the starting 
  * '<!--' and ending '-->'.
  * 
  * For more information on this interface please see 
  * http://www.w3.org/TR/DOM-Level-2-Core/
  */
 
-[scriptable, uuid(cf5493dc-ba25-423a-81e7-b417494f103a)]
+[scriptable, uuid(3bc4c503-bce5-44c5-9554-aba72502a468)]
 interface nsIDOMComment : nsIDOMCharacterData
 {
 };
--- a/dom/interfaces/core/nsIDOMDocument.idl
+++ b/dom/interfaces/core/nsIDOMDocument.idl
@@ -22,17 +22,17 @@ interface nsIDOMLocation;
  * cannot exist outside the context of a Document, the nsIDOMDocument 
  * interface also contains the factory methods needed to create these 
  * objects.
  *
  * For more information on this interface please see 
  * http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html
  */
 
-[scriptable, uuid(75996de6-6b0f-43e5-ae79-c98fa669da9a)]
+[scriptable, uuid(49592e41-a3a6-406c-a3d4-b5cf491f4e73)]
 interface nsIDOMDocument : nsIDOMNode
 {
   readonly attribute nsIDOMDocumentType         doctype;
   readonly attribute nsIDOMDOMImplementation    implementation;
   readonly attribute nsIDOMElement              documentElement;
   nsIDOMElement                 createElement([Null(Stringify)] in DOMString tagName)
                                   raises(DOMException);
   nsIDOMDocumentFragment        createDocumentFragment();
--- a/dom/interfaces/core/nsIDOMDocumentFragment.idl
+++ b/dom/interfaces/core/nsIDOMDocumentFragment.idl
@@ -9,12 +9,12 @@
  * DocumentFragment is a "lightweight" or "minimal" Document object.
  * nsIDOMDocumentFragment is used in situations where the Document
  * interface can potentially be a heavyweight interface.
  *
  * For more information on this interface please see 
  * http://www.w3.org/TR/DOM-Level-2-Core/
  */
 
-[scriptable, builtinclass, uuid(33127aed-9d6a-4b0d-95aa-0529f51bcb9c)]
+[scriptable, builtinclass, uuid(e9ba0a30-1fb4-4823-870c-650afbbc9b87)]
 interface nsIDOMDocumentFragment : nsIDOMNode
 {
 };
--- a/dom/interfaces/core/nsIDOMDocumentType.idl
+++ b/dom/interfaces/core/nsIDOMDocumentType.idl
@@ -10,16 +10,16 @@
  * or a DocumentType object. 
  * The nsIDOMDocumentType interface in the DOM Core provides an 
  * interface to the list of entities that are defined for the document.
  *
  * For more information on this interface please see 
  * http://www.w3.org/TR/DOM-Level-2-Core/
  */
 
-[scriptable, uuid(7568365e-240f-4818-b2fc-0680bfb50942)]
+[scriptable, uuid(4caa34a7-27f6-42d3-9d7f-f631334d849d)]
 interface nsIDOMDocumentType : nsIDOMNode
 {
   readonly attribute  DOMString            name;
   readonly attribute  DOMString            publicId;
   readonly attribute  DOMString            systemId;
   readonly attribute  DOMString            internalSubset;
 };
--- a/dom/interfaces/core/nsIDOMElement.idl
+++ b/dom/interfaces/core/nsIDOMElement.idl
@@ -10,17 +10,17 @@ interface nsIDOMMozNamedAttrMap;
 /**
  * The nsIDOMElement interface represents an element in an HTML or 
  * XML document. 
  *
  * For more information on this interface please see 
  * http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#interface-element
  */
 
-[scriptable, uuid(ccc2bbbc-5b44-4b01-b718-dd51f339fef8)]
+[scriptable, uuid(adea0ac9-f399-4537-bed5-58ba5d608a1b)]
 interface nsIDOMElement : nsIDOMNode
 {
   readonly attribute DOMString        tagName;
 
   /**
    * Returns a DOMTokenList object reflecting the class attribute.
    */
   readonly attribute nsISupports classList;
--- a/dom/interfaces/core/nsIDOMNode.idl
+++ b/dom/interfaces/core/nsIDOMNode.idl
@@ -12,17 +12,17 @@ interface nsIDOMUserDataHandler;
  * The nsIDOMNode interface is the primary datatype for the entire 
  * Document Object Model.
  * It represents a single node in the document tree.
  *
  * For more information on this interface please see 
  * http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html
  */
 
-[scriptable, uuid(56545150-a001-484e-9ed4-cb319eebd7b3)]
+[scriptable, uuid(e0fda4a1-b4fd-404f-85b0-3167b79ae87f)]
 interface nsIDOMNode : nsISupports
 {
   const unsigned short      ELEMENT_NODE       = 1;
   const unsigned short      ATTRIBUTE_NODE     = 2;
   const unsigned short      TEXT_NODE          = 3;
   const unsigned short      CDATA_SECTION_NODE = 4;
   const unsigned short      ENTITY_REFERENCE_NODE = 5;
   const unsigned short      ENTITY_NODE        = 6;
@@ -64,18 +64,16 @@ interface nsIDOMNode : nsISupports
   void                      normalize();
   // Introduced in DOM Level 2:
   readonly attribute DOMString        namespaceURI;
   // Modified in DOM Core
   readonly attribute DOMString        prefix;
 
   // Introduced in DOM Level 2:
   readonly attribute DOMString        localName;
-  // Introduced in DOM Level 2:
-  boolean            hasAttributes();
 
   // Introduced in DOM Level 3:
   // This uses a binaryname to avoid warnings due to name collision with
   // nsINode::GetBaseURI
   [binaryname(DOMBaseURI)] readonly attribute DOMString baseURI;
 
   // DocumentPosition
   const unsigned short      DOCUMENT_POSITION_DISCONNECTED = 0x01;
--- a/dom/interfaces/core/nsIDOMProcessingInstruction.idl
+++ b/dom/interfaces/core/nsIDOMProcessingInstruction.idl
@@ -10,13 +10,13 @@
  * "processing instruction", used in XML as a way to keep processor-specific 
  * information in the text of the document.
  *
  * For more information on this interface please see 
  * http://www.w3.org/TR/DOM-Level-2-Core/ and
  * http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html
  */
 
-[scriptable, uuid(9ee8b1c3-2b0d-49e2-b2d6-f6bb8bf21b9e)]
+[scriptable, uuid(62af8276-947f-4ad1-a303-f076a3b05ca8)]
 interface nsIDOMProcessingInstruction : nsIDOMCharacterData
 {
   readonly attribute DOMString        target;
 };
--- a/dom/interfaces/core/nsIDOMText.idl
+++ b/dom/interfaces/core/nsIDOMText.idl
@@ -8,17 +8,17 @@
 /**
  * The nsIDOMText interface inherits from nsIDOMCharacterData and represents 
  * the textual content (termed character data in XML) of an Element or Attr.
  *
  * For more information on this interface please see 
  * http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html
  */
 
-[scriptable, uuid(3de88cc9-1462-4bb8-a2fc-845b132547ac)]
+[scriptable, uuid(50a838c2-f421-4496-a63e-0d58dbc480d9)]
 interface nsIDOMText : nsIDOMCharacterData
 {
   nsIDOMText                      splitText(in unsigned long offset)
                                        raises(DOMException);
 
   /**
    * The concatenation of all logically adjacent text nodes with this text
    * node, where "logically adjacent" consists of all text nodes which can be
--- a/dom/interfaces/core/nsIDOMXMLDocument.idl
+++ b/dom/interfaces/core/nsIDOMXMLDocument.idl
@@ -1,16 +1,16 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIDOMDocument.idl"
 
-[scriptable, uuid(79547ba5-291e-4775-b71e-2440a4621b54)]
+[scriptable, uuid(94ed1513-b191-4375-b898-bde6e7352f54)]
 interface nsIDOMXMLDocument : nsIDOMDocument
 {
   // DOM Level 3 Load & Save, DocumentLS
   // http://www.w3.org/TR/DOM-Level-3-LS/load-save.html#LS-DocumentLS
   /**
    * Whether to load synchronously or asynchronously.
    * The default is async==true.
    */
--- a/dom/interfaces/html/nsIDOMHTMLAnchorElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLAnchorElement.idl
@@ -11,17 +11,17 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(c75e7bb1-cc7a-4169-9467-9513a95e3b94)]
+[scriptable, uuid(15399819-7bf8-4378-b49d-af77740f1365)]
 interface nsIDOMHTMLAnchorElement : nsIDOMHTMLElement
 {
            attribute DOMString        href;
            attribute DOMString        target;
 
            attribute DOMString        ping;
            attribute DOMString        download;
 
--- a/dom/interfaces/html/nsIDOMHTMLAppletElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLAppletElement.idl
@@ -11,17 +11,17 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(351dd451-0077-4298-b569-a41529baca32)]
+[scriptable, uuid(fffb81fc-a950-4814-bec1-9fba3c88bccf)]
 interface nsIDOMHTMLAppletElement : nsIDOMHTMLElement
 {
            attribute DOMString        align;
            attribute DOMString        alt;
            attribute DOMString        archive;
            attribute DOMString        code;
            attribute DOMString        codeBase;
            attribute DOMString        height;
--- a/dom/interfaces/html/nsIDOMHTMLAreaElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLAreaElement.idl
@@ -11,17 +11,17 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(6ab5b382-c19d-4a4e-98b7-2f4e14dbecdf)]
+[scriptable, uuid(6acf0592-60f7-4046-a95e-84a9e13ab75e)]
 interface nsIDOMHTMLAreaElement : nsIDOMHTMLElement
 {
            attribute DOMString        alt;
            attribute DOMString        coords;
            attribute DOMString        shape;
            attribute DOMString        href;
            attribute DOMString        target;
 
--- a/dom/interfaces/html/nsIDOMHTMLAudioElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLAudioElement.idl
@@ -15,17 +15,17 @@
  * <audio> element.
  *
  * For more information on this interface, please see
  * http://www.whatwg.org/specs/web-apps/current-work/#audio
  *
  * @status UNDER_DEVELOPMENT
  */
 
-[scriptable, uuid(8e3fb6a1-490d-4772-90fd-3e3763958b74)]
+[scriptable, uuid(15a3360c-278c-4667-a9b5-ec6c57120ddf)]
 interface nsIDOMHTMLAudioElement : nsIDOMHTMLMediaElement
 {
   // Setup the audio stream for writing
   void mozSetup(in uint32_t channels, in uint32_t rate);
 
   // Write audio to the audio stream
   [implicit_jscontext]
   unsigned long mozWriteAudio(in jsval data);
--- a/dom/interfaces/html/nsIDOMHTMLBRElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLBRElement.idl
@@ -11,13 +11,13 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(8e69e7c2-2c32-4176-aec7-3ec9b518f4d7)]
+[scriptable, uuid(04b2f8b6-d5d0-4023-804c-f560d9b6d97e)]
 interface nsIDOMHTMLBRElement : nsIDOMHTMLElement
 {
            attribute DOMString        clear;
 };
--- a/dom/interfaces/html/nsIDOMHTMLBaseElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLBaseElement.idl
@@ -11,14 +11,14 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(a07d89f2-c923-4632-901c-47b61c2b5f72)]
+[scriptable, uuid(ba49dfab-9361-4b73-b024-3e8ad810a71e)]
 interface nsIDOMHTMLBaseElement : nsIDOMHTMLElement
 {
            attribute DOMString        href;
            attribute DOMString        target;
 };
--- a/dom/interfaces/html/nsIDOMHTMLBodyElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLBodyElement.idl
@@ -15,17 +15,17 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(4df676f2-7da1-4b88-843c-67d6c3f151df)]
+[scriptable, uuid(385b5f03-a450-4154-931f-032ba50b6ad6)]
 interface nsIDOMHTMLBodyElement : nsIDOMHTMLElement
 {
            attribute DOMString        aLink;
            attribute DOMString        background;
            attribute DOMString        bgColor;
            attribute DOMString        link;
            attribute DOMString        text;
            attribute DOMString        vLink;
--- a/dom/interfaces/html/nsIDOMHTMLButtonElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLButtonElement.idl
@@ -13,17 +13,17 @@
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
 interface nsIDOMValidityState;
 
-[scriptable, uuid(1b5905c5-cc98-4446-9700-a90b96e4e2f4)]
+[scriptable, uuid(ef1a1782-5ea9-430f-b0ee-55f26a229512)]
 interface nsIDOMHTMLButtonElement : nsIDOMHTMLElement
 {
            attribute boolean               autofocus;
            attribute boolean               disabled;
   readonly attribute nsIDOMHTMLFormElement form;
            attribute DOMString             formAction;
            attribute DOMString             formEnctype;
            attribute DOMString             formMethod;
--- a/dom/interfaces/html/nsIDOMHTMLCanvasElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLCanvasElement.idl
@@ -41,17 +41,17 @@ interface nsIPrintCallback : nsISupports
   void render(in nsIDOMMozCanvasPrintState ctx);
 };
 
 [scriptable, function, uuid(6e9ffb59-2067-4aef-a51c-65e65a3e0d81)]
 interface nsIFileCallback : nsISupports {
   void receive(in nsIDOMBlob file);
 };
 
-[scriptable, uuid(1cfacc53-ab73-4ceb-9f5f-22387dcd1aae)]
+[scriptable, uuid(7a65eb33-0441-456f-9d58-575ce4421a3f)]
 interface nsIDOMHTMLCanvasElement : nsIDOMHTMLElement
 {
   attribute unsigned long width;
   attribute unsigned long height;
   attribute boolean mozOpaque;
 
   nsISupports getContext(in DOMString contextId,
                          [optional] in jsval contextOptions);
--- a/dom/interfaces/html/nsIDOMHTMLCommandElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLCommandElement.idl
@@ -10,17 +10,17 @@
  * <command> element.
  *
  * For more information on this interface, please see
  * http://www.whatwg.org/specs/web-apps/current-work/#the-command-element
  *
  * @status UNDER_DEVELOPMENT
  */
 
-[scriptable, uuid(97efa08f-8b7f-41bd-8be6-b806eb48b08c)]
+[scriptable, uuid(2b10cb0d-79c1-4543-aac1-0d3582593c61)]
 interface nsIDOMHTMLCommandElement : nsIDOMHTMLElement
 {
            attribute DOMString        type;
            attribute DOMString        label;
            attribute DOMString        icon;
            attribute boolean          disabled;
            attribute boolean          defaultChecked;
            attribute boolean          checked;
--- a/dom/interfaces/html/nsIDOMHTMLDListElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLDListElement.idl
@@ -11,13 +11,13 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(e611c0c1-d5ea-4d25-b9e5-08d4cafd0151)]
+[scriptable, uuid(3571547c-9293-437f-a6bb-c96d4b5ce2d3)]
 interface nsIDOMHTMLDListElement : nsIDOMHTMLElement
 {
            attribute boolean          compact;
 };
--- a/dom/interfaces/html/nsIDOMHTMLDataListElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLDataListElement.idl
@@ -12,14 +12,14 @@
  * For more information on this interface, please see
  * http://www.whatwg.org/specs/web-apps/current-work/#the-datalist-element
  *
  * @status UNDER_DEVELOPMENT
  */
 
 interface nsIDOMHTMLCollection;
 
-[scriptable, uuid(87ea361b-fe0f-486b-a891-7686dadd6372)]
+[scriptable, uuid(cdab1755-37ed-46c6-bcb8-520dfd64952a)]
 interface nsIDOMHTMLDataListElement : nsIDOMHTMLElement
 {
   readonly attribute nsIDOMHTMLCollection options;
 };
 
--- a/dom/interfaces/html/nsIDOMHTMLDirectoryElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLDirectoryElement.idl
@@ -11,13 +11,13 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(15b161c4-f471-4681-9368-1114f5d7a129)]
+[scriptable, uuid(f762b720-e03b-471e-bf3e-5d0de482c87f)]
 interface nsIDOMHTMLDirectoryElement : nsIDOMHTMLElement
 {
            attribute boolean          compact;
 };
--- a/dom/interfaces/html/nsIDOMHTMLDivElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLDivElement.idl
@@ -11,13 +11,13 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(a4f021dd-9e3b-4a78-a9a0-bae60f9a4cc4)]
+[scriptable, uuid(9fbe9793-c92b-485c-b856-b87b0399574e)]
 interface nsIDOMHTMLDivElement : nsIDOMHTMLElement
 {
            attribute DOMString        align;
 };
--- a/dom/interfaces/html/nsIDOMHTMLDocument.idl
+++ b/dom/interfaces/html/nsIDOMHTMLDocument.idl
@@ -8,17 +8,17 @@
 /**
  * The nsIDOMHTMLDocument interface is the interface to a [X]HTML
  * document object.
  *
  * @see <http://www.whatwg.org/html/>
  */
 interface nsISelection;
 
-[scriptable, uuid(fd76e045-8d97-4a97-ad75-eac5ae2f3ea4)]
+[scriptable, uuid(a6603d58-3cbe-4cf3-baec-cac7aba498b6)]
 interface nsIDOMHTMLDocument : nsIDOMDocument
 {
            attribute DOMString            domain;
            attribute DOMString            cookie;
 
   readonly attribute nsIDOMHTMLHeadElement head;
            attribute nsIDOMHTMLElement    body;
 
--- a/dom/interfaces/html/nsIDOMHTMLElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLElement.idl
@@ -14,17 +14,17 @@ interface nsIDOMHTMLMenuElement;
  * tree.
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
-[scriptable, uuid(56d50046-31af-4cdc-af51-217fb2fd0a4d)]
+[scriptable, uuid(6decb41e-44e6-40ca-b3cb-9ded9c1fc382)]
 interface nsIDOMHTMLElement : nsIDOMElement
 {
   // metadata attributes
            attribute DOMString        id;
            attribute DOMString        title;
            attribute DOMString        lang;
            attribute DOMString        dir;
            attribute DOMString        className;
--- a/dom/interfaces/html/nsIDOMHTMLEmbedElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLEmbedElement.idl
@@ -8,17 +8,17 @@
 /**
  * The nsIDOMHTMLEmbedElement interface is the interface to a [X]HTML
  * embed element.
  *
  * For more information on this interface, please see
  * http://www.whatwg.org/specs/web-apps/current-work/#the-embed-element
  */
 
-[scriptable, uuid(ca0de9c2-e230-4acb-aa6d-65fc0283bf06)]
+[scriptable, uuid(2989533c-72d1-480c-9870-b6b831b53ea8)]
 interface nsIDOMHTMLEmbedElement : nsIDOMHTMLElement
 {
            attribute DOMString        align;
            attribute DOMString        height;
            attribute DOMString        name;
            attribute DOMString        src;
            attribute DOMString        type;
            attribute DOMString        width;
--- a/dom/interfaces/html/nsIDOMHTMLFieldSetElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLFieldSetElement.idl
@@ -13,17 +13,17 @@
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
 interface nsIDOMValidityState;
 
-[scriptable, uuid(a3e19d5b-aa7c-46bd-8bca-7135b250260a)]
+[scriptable, uuid(e36fdef0-1c7f-4c1d-8917-28466ea70df8)]
 interface nsIDOMHTMLFieldSetElement : nsIDOMHTMLElement
 {
            attribute boolean                disabled;
   readonly attribute nsIDOMHTMLFormElement  form;
            attribute DOMString              name;
 
   readonly attribute DOMString              type;
 
--- a/dom/interfaces/html/nsIDOMHTMLFontElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLFontElement.idl
@@ -11,15 +11,15 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(3ab61e70-7aac-4d9b-99fd-1c5ec5228463)]
+[scriptable, uuid(447032ca-1a2c-4e4b-b160-67b1738e5629)]
 interface nsIDOMHTMLFontElement : nsIDOMHTMLElement
 {
            attribute DOMString        color;
            attribute DOMString        face;
            attribute DOMString        size;
 };
--- a/dom/interfaces/html/nsIDOMHTMLFormElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLFormElement.idl
@@ -11,17 +11,17 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(6c79f4b0-3d55-45ca-8bf3-68a236e90e97)]
+[scriptable, uuid(a71d7de5-eae8-42fe-9770-cc28dd040b16)]
 interface nsIDOMHTMLFormElement : nsIDOMHTMLElement
 {
            attribute DOMString            acceptCharset;
            attribute DOMString            action;
            attribute DOMString            autocomplete;
            attribute DOMString            enctype;
            attribute DOMString            encoding;
            attribute DOMString            method;
--- a/dom/interfaces/html/nsIDOMHTMLFrameElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLFrameElement.idl
@@ -11,17 +11,17 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(912423ad-00c2-4948-8f8e-4950169e516d)]
+[scriptable, uuid(ee026cb0-7f3d-464d-84b8-02c97ecad7f9)]
 interface nsIDOMHTMLFrameElement : nsIDOMHTMLElement
 {
            attribute DOMString        frameBorder;
            attribute DOMString        longDesc;
            attribute DOMString        marginHeight;
            attribute DOMString        marginWidth;
            attribute DOMString        name;
            attribute boolean          noResize;
--- a/dom/interfaces/html/nsIDOMHTMLFrameSetElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLFrameSetElement.idl
@@ -15,17 +15,17 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(e62b41c0-eaec-49bc-bf0c-be3a50b175d1)]
+[scriptable, uuid(d165dc56-ca5f-4d6d-a96c-252ca246b2a9)]
 interface nsIDOMHTMLFrameSetElement : nsIDOMHTMLElement
 {
            attribute DOMString        cols;
            attribute DOMString        rows;
 
            [implicit_jscontext] attribute jsval            onafterprint;
            [implicit_jscontext] attribute jsval            onbeforeprint;
            [implicit_jscontext] attribute jsval            onbeforeunload;
--- a/dom/interfaces/html/nsIDOMHTMLHRElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLHRElement.idl
@@ -11,17 +11,17 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(adf811c1-eece-4cd2-9632-ea39bc0e20e7)]
+[scriptable, uuid(1d72b9fe-f100-4800-9669-7442d7f2b326)]
 interface nsIDOMHTMLHRElement : nsIDOMHTMLElement
 {
            attribute DOMString        align;
            attribute boolean          noShade;
            attribute DOMString        size;
            attribute DOMString        width;
            attribute DOMString        color;
 };
--- a/dom/interfaces/html/nsIDOMHTMLHeadElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLHeadElement.idl
@@ -11,12 +11,12 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(2baa2206-1ce6-4208-aead-d1f6b18e97fb)]
+[scriptable, uuid(3d69a421-ff1e-49e1-9208-541e417de298)]
 interface nsIDOMHTMLHeadElement : nsIDOMHTMLElement
 {
 };
--- a/dom/interfaces/html/nsIDOMHTMLHeadingElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLHeadingElement.idl
@@ -11,13 +11,13 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(39a59521-2e03-436b-b87b-6405396e1a24)]
+[scriptable, uuid(431846a5-243b-4e0a-abd0-098a0fb5320b)]
 interface nsIDOMHTMLHeadingElement : nsIDOMHTMLElement
 {
            attribute DOMString        align;
 };
--- a/dom/interfaces/html/nsIDOMHTMLHtmlElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLHtmlElement.idl
@@ -11,13 +11,13 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(e7720912-1fb4-4c00-ae78-faddba690b45)]
+[scriptable, uuid(f4249435-cf81-4806-a5db-a53c8f8731c5)]
 interface nsIDOMHTMLHtmlElement : nsIDOMHTMLElement
 {
            attribute DOMString        version;
 };
--- a/dom/interfaces/html/nsIDOMHTMLIFrameElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLIFrameElement.idl
@@ -11,17 +11,17 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(87d6e8db-4ae2-4a9d-a546-510836611038)]
+[scriptable, uuid(3cdaedb6-5029-4852-a66e-b0d3c295b972)]
 interface nsIDOMHTMLIFrameElement : nsIDOMHTMLElement
 {
            attribute DOMString        align;
            attribute DOMString        frameBorder;
            attribute DOMString        height;
            attribute DOMString        longDesc;
            attribute DOMString        marginHeight;
            attribute DOMString        marginWidth;
--- a/dom/interfaces/html/nsIDOMHTMLImageElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLImageElement.idl
@@ -11,17 +11,17 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(0e2ffdcb-b881-436b-a450-4790f47b60fe)]
+[scriptable, uuid(fc7490d1-234b-4d0a-910d-5fb859c99fc1)]
 interface nsIDOMHTMLImageElement : nsIDOMHTMLElement
 {
            attribute DOMString        alt;
            attribute DOMString        src;
            attribute DOMString        crossOrigin;
            attribute DOMString        useMap;
            attribute boolean          isMap;
            attribute unsigned long    width;
--- a/dom/interfaces/html/nsIDOMHTMLInputElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLInputElement.idl
@@ -15,17 +15,17 @@ interface nsIDOMValidityState;
   *
   * This interface is trying to follow the DOM Level 2 HTML specification:
   * http://www.w3.org/TR/DOM-Level-2-HTML/
   *
   * with changes from the work-in-progress WHATWG HTML specification:
   * http://www.whatwg.org/specs/web-apps/current-work/
   */
 
-[scriptable, uuid(3f51d301-be0e-4e19-b056-ea98c03eedfd)]
+[scriptable, uuid(858dfd88-491b-4276-8acb-8e0f4d4fff54)]
 interface nsIDOMHTMLInputElement : nsIDOMHTMLElement
 {
            attribute DOMString             accept;
            attribute DOMString             alt;
 
            attribute DOMString             autocomplete;
            attribute boolean               autofocus;
            attribute boolean               defaultChecked;
--- a/dom/interfaces/html/nsIDOMHTMLLIElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLLIElement.idl
@@ -11,14 +11,14 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(8be7060b-66fe-47f4-99f0-44fe65cf9cd6)]
+[scriptable, uuid(090b4519-3636-4ea3-be6f-83d4917456a9)]
 interface nsIDOMHTMLLIElement : nsIDOMHTMLElement
 {
            attribute DOMString           type;
            attribute long                value;
 };
--- a/dom/interfaces/html/nsIDOMHTMLLabelElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLLabelElement.idl
@@ -11,15 +11,15 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(02024255-6b9e-445f-971e-ac71ed091a64)]
+[scriptable, uuid(b59fe47f-c4e7-47c4-b9c8-6960495fe7e3)]
 interface nsIDOMHTMLLabelElement : nsIDOMHTMLElement
 {
   readonly attribute nsIDOMHTMLFormElement form;
            attribute DOMString             htmlFor;
   readonly attribute nsIDOMHTMLElement     control;
 };
--- a/dom/interfaces/html/nsIDOMHTMLLegendElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLLegendElement.idl
@@ -11,14 +11,14 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(42f1c264-d2b1-4f50-95cf-929ae2ea4c52)]
+[scriptable, uuid(27b837cb-c825-4248-9c7c-99e2a7ddaebc)]
 interface nsIDOMHTMLLegendElement : nsIDOMHTMLElement
 {
   readonly attribute nsIDOMHTMLFormElement form;
            attribute DOMString             align;
 };
--- a/dom/interfaces/html/nsIDOMHTMLLinkElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLLinkElement.idl
@@ -11,17 +11,17 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(ca856a0b-6786-4123-90fe-dc9c7600274e)]
+[scriptable, uuid(1e63390c-4263-4578-a584-d2f2bbf37141)]
 interface nsIDOMHTMLLinkElement : nsIDOMHTMLElement
 {
            [binaryname(MozDisabled)]
            attribute boolean          disabled;
            attribute DOMString        charset;
            attribute DOMString        href;
            attribute DOMString        hreflang;
            attribute DOMString        media;
--- a/dom/interfaces/html/nsIDOMHTMLMapElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLMapElement.idl
@@ -11,14 +11,14 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(4b2136a3-f296-479a-88dc-ed4421eb3a22)]
+[scriptable, uuid(ea67d322-96be-4941-8e78-35cce42b411c)]
 interface nsIDOMHTMLMapElement : nsIDOMHTMLElement
 {
   readonly attribute nsIDOMHTMLCollection areas;
            attribute DOMString            name;
 };
--- a/dom/interfaces/html/nsIDOMHTMLMediaElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLMediaElement.idl
@@ -22,17 +22,17 @@ interface nsIDOMMediaStream;
 
 // undef the GetCurrentTime macro defined in WinBase.h from the MS Platform SDK
 %{C++
 #ifdef GetCurrentTime
 #undef GetCurrentTime
 #endif
 %}
 
-[scriptable, uuid(585a5edd-0a64-4edb-a7d7-d0304e3b8e55)]
+[scriptable, uuid(488eb1d7-fa08-425e-bac4-f7dd59805352)]
 interface nsIDOMHTMLMediaElement : nsIDOMHTMLElement
 {
   // error state
   readonly attribute nsIDOMMediaError error;
 
   // network state
            attribute DOMString src;
            attribute nsIDOMMediaStream mozSrcObject;
--- a/dom/interfaces/html/nsIDOMHTMLMenuElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLMenuElement.idl
@@ -11,16 +11,16 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(6790c2f5-01ac-43ba-9145-dd2052e3b0c7)]
+[scriptable, uuid(7d2b6008-9554-403d-8f21-e1bedba4d057)]
 interface nsIDOMHTMLMenuElement : nsIDOMHTMLElement
 {
            attribute boolean          compact;
 
            attribute DOMString        type;
            attribute DOMString        label;
 };
--- a/dom/interfaces/html/nsIDOMHTMLMenuItemElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLMenuItemElement.idl
@@ -7,12 +7,12 @@
 
 /**
  * The nsIDOMHTMLMenuItemElement interface is the interface to a HTML
  * <menuitem> element.
  *
  * @status UNDER_DEVELOPMENT
  */
 
-[scriptable, uuid(79a4ca67-bca8-4044-bc69-629e8961137a)]
+[scriptable, uuid(dacbe36c-5e6e-4949-99af-6644baf8118a)]
 interface nsIDOMHTMLMenuItemElement : nsIDOMHTMLCommandElement
 {
 };
--- a/dom/interfaces/html/nsIDOMHTMLMetaElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLMetaElement.idl
@@ -11,16 +11,16 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(1aeebf8a-577e-433a-ae40-339426b52e96)]
+[scriptable, uuid(26482444-c807-4268-96cf-c07f54fd9fa4)]
 interface nsIDOMHTMLMetaElement : nsIDOMHTMLElement
 {
            attribute DOMString        content;
            attribute DOMString        httpEquiv;
            attribute DOMString        name;
            attribute DOMString        scheme;
 };
--- a/dom/interfaces/html/nsIDOMHTMLMeterElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLMeterElement.idl
@@ -8,17 +8,17 @@
 /**
  * The nsIDOMHTMLMeterElement interface is the interface to a HTML
  * <meter> element.
  *
  * For more information on this interface, please see
  * http://www.whatwg.org/specs/web-apps/current-work/multipage/the-button-element.html#the-meter-element
  */
 
-[scriptable, uuid(53b55f04-fd1a-47e5-8181-d059114a3bc9)]
+[scriptable, uuid(4ac29593-8756-4060-a960-478082b82c48)]
 interface nsIDOMHTMLMeterElement : nsIDOMHTMLElement
 {
            attribute double value;
            attribute double min;
            attribute double max;
            attribute double low;
            attribute double high;
            attribute double optimum;
--- a/dom/interfaces/html/nsIDOMHTMLModElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLModElement.idl
@@ -11,14 +11,14 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(c8ce2f75-2bbf-4c30-8627-0ea1a7b2ebf7)]
+[scriptable, uuid(860f2f1b-3d75-4b11-b3e3-c4aa7e6007b7)]
 interface nsIDOMHTMLModElement : nsIDOMHTMLElement
 {
            attribute DOMString        cite;
            attribute DOMString        dateTime;
 };
--- a/dom/interfaces/html/nsIDOMHTMLOListElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLOListElement.idl
@@ -11,16 +11,16 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(d94ba4eb-a154-4abf-9868-105905e995e4)]
+[scriptable, uuid(56dc0564-41a5-4a49-b8ca-7ede3766c084)]
 interface nsIDOMHTMLOListElement : nsIDOMHTMLElement
 {
            attribute boolean          compact;
            attribute boolean          reversed;
            attribute long             start;
            attribute DOMString        type;
 };
--- a/dom/interfaces/html/nsIDOMHTMLObjectElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLObjectElement.idl
@@ -13,17 +13,17 @@
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
 interface nsIDOMValidityState;
 
-[scriptable, uuid(2481afa7-9ca3-448b-80d7-0138c47b5b33)]
+[scriptable, uuid(0d8341fb-1d07-41e3-98ad-2782aedf7224)]
 interface nsIDOMHTMLObjectElement : nsIDOMHTMLElement
 {
   readonly attribute nsIDOMHTMLFormElement form;
            attribute DOMString             code;
            attribute DOMString             align;
            attribute DOMString             archive;
            attribute DOMString             border;
            attribute DOMString             codeBase;
--- a/dom/interfaces/html/nsIDOMHTMLOptGroupElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLOptGroupElement.idl
@@ -11,14 +11,14 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(cc9fe8ad-908b-40c4-b007-254e15d783bb)]
+[scriptable, uuid(4d103638-5db1-4426-ba16-df773d6ad61c)]
 interface nsIDOMHTMLOptGroupElement : nsIDOMHTMLElement
 {
            attribute boolean          disabled;
            attribute DOMString        label;
 };
--- a/dom/interfaces/html/nsIDOMHTMLOptionElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLOptionElement.idl
@@ -11,17 +11,17 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(d4c53417-e746-451a-8b8a-0fa3fcda95b3)]
+[scriptable, uuid(a6fbb1d0-5342-47cd-94a3-1e50cae98648)]
 interface nsIDOMHTMLOptionElement : nsIDOMHTMLElement
 {
            attribute boolean               disabled;
   readonly attribute nsIDOMHTMLFormElement form;
            attribute DOMString             label;
            attribute boolean               defaultSelected;
            attribute boolean               selected;
            attribute DOMString             value;
--- a/dom/interfaces/html/nsIDOMHTMLOutputElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLOutputElement.idl
@@ -12,17 +12,17 @@
  * For more information on this interface, please see
  * http://www.whatwg.org/specs/web-apps/current-work/#the-output-element
  *
  * @status UNDER_DEVELOPMENT
  */
 
 interface nsIDOMValidityState;
 
-[scriptable, uuid(6d6bf653-3eb4-420f-b1b0-6ad919a06926)]
+[scriptable, uuid(de830a0f-0722-4258-8ec4-5cb75c4fd0fe)]
 interface nsIDOMHTMLOutputElement : nsIDOMHTMLElement
 {
   // DOMSettableTokenList
   readonly attribute nsISupports                htmlFor;
   readonly attribute nsIDOMHTMLFormElement      form;
            attribute DOMString                  name;
 
   readonly attribute DOMString                  type;
--- a/dom/interfaces/html/nsIDOMHTMLParagraphElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLParagraphElement.idl
@@ -11,13 +11,13 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(ccc50b61-8e2e-4e0a-be5e-0b30923051b0)]
+[scriptable, uuid(6bed192b-064f-4c62-922d-22820f822933)]
 interface nsIDOMHTMLParagraphElement : nsIDOMHTMLElement
 {
            attribute DOMString        align;
 };
--- a/dom/interfaces/html/nsIDOMHTMLParamElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLParamElement.idl
@@ -11,16 +11,16 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(9cb0d681-1d1c-4c5d-b165-579cafcdf897)]
+[scriptable, uuid(fa065fd2-daa5-4695-bb5e-67f7148e310d)]
 interface nsIDOMHTMLParamElement : nsIDOMHTMLElement
 {
            attribute DOMString        name;
            attribute DOMString        type;
            attribute DOMString        value;
            attribute DOMString        valueType;
 };
--- a/dom/interfaces/html/nsIDOMHTMLPreElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLPreElement.idl
@@ -11,13 +11,13 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(128840c4-0973-4c7a-b71a-81e23071f1f6)]
+[scriptable, uuid(b7924741-8a28-469b-85a8-3880133f2fac)]
 interface nsIDOMHTMLPreElement : nsIDOMHTMLElement
 {
            attribute long             width;
 };
--- a/dom/interfaces/html/nsIDOMHTMLProgressElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLProgressElement.idl
@@ -10,17 +10,17 @@
  * <progress> element.
  *
  * For more information on this interface, please see
  * http://www.whatwg.org/specs/web-apps/current-work/#the-progress-element
  *
  * @status UNDER_DEVELOPMENT
  */
 
-[scriptable, uuid(e5ba151c-0772-4849-8021-fb30f341fff9)]
+[scriptable, uuid(67a5c7ec-40bb-49ac-a38d-59f3b31e1af1)]
 interface nsIDOMHTMLProgressElement : nsIDOMHTMLElement
 {
            attribute double value;
            attribute double max;
   readonly attribute double position;
   /**
    * The labels attribute will be done with bug 567740.
    */
--- a/dom/interfaces/html/nsIDOMHTMLQuoteElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLQuoteElement.idl
@@ -11,13 +11,13 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(fa9731da-fa8a-48a4-95a3-cba2623bcc59)]
+[scriptable, uuid(5f07a07a-8f10-4af6-919f-2c6c2c01cedf)]
 interface nsIDOMHTMLQuoteElement : nsIDOMHTMLElement
 {
            attribute DOMString        cite;
 };
--- a/dom/interfaces/html/nsIDOMHTMLScriptElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLScriptElement.idl
@@ -11,17 +11,17 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(e445db32-0116-4cf5-b73e-7073ccf3d259)]
+[scriptable, uuid(09b9dd56-e330-4556-93ca-7557cfcf4233)]
 interface nsIDOMHTMLScriptElement : nsIDOMHTMLElement
 {
            attribute DOMString        src;
            attribute boolean          async;
            attribute boolean          defer;
            attribute DOMString        type;
            attribute DOMString        charset;
            attribute DOMString        text;
--- a/dom/interfaces/html/nsIDOMHTMLSelectElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLSelectElement.idl
@@ -14,17 +14,17 @@
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
 interface nsIDOMValidityState;
 
-[scriptable, uuid(d959feb0-a7e8-44d6-9346-b48253ad8ba4)]
+[scriptable, uuid(a26d6b65-3b24-4937-866c-6c55360789a6)]
 interface nsIDOMHTMLSelectElement : nsIDOMHTMLElement
 {
            attribute boolean                     autofocus;
            attribute boolean                     disabled;
   readonly attribute nsIDOMHTMLFormElement       form;
            attribute boolean                     multiple;
            attribute DOMString                   name;
            attribute unsigned long               size;
--- a/dom/interfaces/html/nsIDOMHTMLSourceElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLSourceElement.idl
@@ -11,15 +11,15 @@
  * <source> element.
  *
  * For more information on this interface, please see
  * http://www.whatwg.org/specs/web-apps/current-work/#source
  *
  * @status UNDER_DEVELOPMENT
  */
 
-[scriptable, uuid(333faeb7-93dc-439e-a50e-a9df705b8ba6)]
+[scriptable, uuid(3ccb1f98-1fa7-4a7e-9fd7-8d76f65603e6)]
 interface nsIDOMHTMLSourceElement : nsIDOMHTMLElement
 {
            attribute DOMString src;
            attribute DOMString type;
            attribute DOMString media;
 };
--- a/dom/interfaces/html/nsIDOMHTMLStyleElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLStyleElement.idl
@@ -11,17 +11,17 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(5e6c9cac-5594-4006-ae3f-ad82fb28cee9)]
+[scriptable, uuid(2bda99f1-8bcc-49b9-8dd0-58038b88b0d5)]
 interface nsIDOMHTMLStyleElement : nsIDOMHTMLElement
 {
            [binaryname(MozDisabled)]
            attribute boolean          disabled;
            attribute DOMString        media;
            attribute DOMString        type;
            attribute boolean          scoped;
 };
--- a/dom/interfaces/html/nsIDOMHTMLTableCaptionElem.idl
+++ b/dom/interfaces/html/nsIDOMHTMLTableCaptionElem.idl
@@ -11,13 +11,13 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, builtinclass, uuid(310ebe52-7377-4fc4-9546-a6f4dcaafa1f)]
+[scriptable, builtinclass, uuid(bdc0d664-38f5-4641-a239-8df467df7adb)]
 interface nsIDOMHTMLTableCaptionElement : nsIDOMHTMLElement
 {
            attribute DOMString        align;
 };
--- a/dom/interfaces/html/nsIDOMHTMLTableCellElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLTableCellElement.idl
@@ -11,17 +11,17 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(2c008303-f082-434b-b47e-4c8dea659ea0)]
+[scriptable, uuid(10c52e00-cbc4-4be6-b8c6-cf2cda572fce)]
 interface nsIDOMHTMLTableCellElement : nsIDOMHTMLElement
 {
   readonly attribute long             cellIndex;
            attribute DOMString        abbr;
            attribute DOMString        align;
            attribute DOMString        axis;
            attribute DOMString        bgColor;
            attribute DOMString        ch;
--- a/dom/interfaces/html/nsIDOMHTMLTableColElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLTableColElement.idl
@@ -11,17 +11,17 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(f38fe6c8-9dfd-4c24-aeab-352459383d67)]
+[scriptable, uuid(d46da739-40fd-49b2-971f-00023b486a78)]
 interface nsIDOMHTMLTableColElement : nsIDOMHTMLElement
 {
            attribute DOMString        align;
            attribute DOMString        ch;
            attribute DOMString        chOff;
            attribute long             span;
            attribute DOMString        vAlign;
            attribute DOMString        width;
--- a/dom/interfaces/html/nsIDOMHTMLTableElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLTableElement.idl
@@ -11,17 +11,17 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(cee6898b-621f-4e94-b9d1-53e7f42dbd3a)]
+[scriptable, uuid(e8d19646-c92d-4240-8bfd-f68a365b0d28)]
 interface nsIDOMHTMLTableElement : nsIDOMHTMLElement
 {
   // Modified in DOM Level 2:
            attribute nsIDOMHTMLTableCaptionElement caption;
                                              // raises(DOMException) on setting
 
   // Modified in DOM Level 2:
            attribute nsIDOMHTMLTableSectionElement tHead;
--- a/dom/interfaces/html/nsIDOMHTMLTableRowElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLTableRowElement.idl
@@ -11,17 +11,17 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(ccbaf4d5-1c2d-4edb-9faf-094e357da044)]
+[scriptable, uuid(901e174b-40ae-411e-8acd-dda2a852419c)]
 interface nsIDOMHTMLTableRowElement : nsIDOMHTMLElement
 {
   // Modified in DOM Level 2:
   readonly attribute long                 rowIndex;
   // Modified in DOM Level 2:
   readonly attribute long                 sectionRowIndex;
   // Modified in DOM Level 2:
   readonly attribute nsIDOMHTMLCollection cells;
--- a/dom/interfaces/html/nsIDOMHTMLTableSectionElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLTableSectionElement.idl
@@ -11,17 +11,17 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, builtinclass, uuid(233c3242-5379-4977-81c5-58bf90743a09)]
+[scriptable, builtinclass, uuid(3dada615-87fb-411f-8fbf-237d3580ba9d)]
 interface nsIDOMHTMLTableSectionElement : nsIDOMHTMLElement
 {
            attribute DOMString            align;
            attribute DOMString            ch;
            attribute DOMString            chOff;
            attribute DOMString            vAlign;
   readonly attribute nsIDOMHTMLCollection rows;
   // Modified in DOM Level 2:
--- a/dom/interfaces/html/nsIDOMHTMLTextAreaElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLTextAreaElement.idl
@@ -14,17 +14,17 @@ interface nsIDOMValidityState;
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(c888f597-b77e-4ba6-b7bc-09cfc7d58f4a)]
+[scriptable, uuid(6ca97089-e788-4f13-8f79-da3188969bb0)]
 interface nsIDOMHTMLTextAreaElement : nsIDOMHTMLElement
 {
            attribute boolean               autofocus;
            attribute unsigned long         cols;
            attribute boolean               disabled;
   readonly attribute nsIDOMHTMLFormElement form;
            attribute long                  maxLength;
            attribute DOMString             name;
--- a/dom/interfaces/html/nsIDOMHTMLTitleElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLTitleElement.idl
@@ -11,13 +11,13 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(5da56fa3-1a87-4931-8411-3f6be1a43178)]
+[scriptable, uuid(3eef2f10-8a28-4e8a-853f-110782105f04)]
 interface nsIDOMHTMLTitleElement : nsIDOMHTMLElement
 {
            attribute DOMString        text;
 };
--- a/dom/interfaces/html/nsIDOMHTMLUListElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLUListElement.idl
@@ -11,14 +11,14 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(edb972d4-82b0-4be6-9145-caeb5d99a4ae)]
+[scriptable, uuid(05e6f393-ac1d-47fe-b7ad-a9000ba3889c)]
 interface nsIDOMHTMLUListElement : nsIDOMHTMLElement
 {
            attribute boolean          compact;
            attribute DOMString        type;
 };
--- a/dom/interfaces/html/nsIDOMHTMLUnknownElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLUnknownElement.idl
@@ -6,12 +6,12 @@
 #include "nsIDOMHTMLElement.idl"
 
 /**
  * The nsIDOMHTMLUnknownElement interface is the interface to an unknown HTML
  * element.
  *
  * @see <http://www.whatwg.org/html/#htmlunknownelement>
  */
-[scriptable, uuid(3f4be98b-c6e5-41b4-bc0d-f659f7d109e0)]
+[scriptable, uuid(1b9f16f6-c56c-4b2a-ada7-93604eaf8075)]
 interface nsIDOMHTMLUnknownElement : nsIDOMHTMLElement
 {
 };
--- a/dom/interfaces/html/nsIDOMHTMLVideoElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLVideoElement.idl
@@ -11,17 +11,17 @@
  * <video> element.
  *
  * For more information on this interface, please see
  * http://www.whatwg.org/specs/web-apps/current-work/#video
  *
  * @status UNDER_DEVELOPMENT
  */
 
-[scriptable, uuid(4582aec0-8627-4a45-9aa4-22ec64ae9309)]
+[scriptable, uuid(f750a6c7-641a-412e-81bc-d3d681f28002)]
 interface nsIDOMHTMLVideoElement : nsIDOMHTMLMediaElement
 {
            attribute long width; 
            attribute long height;
   readonly attribute unsigned long videoWidth;
   readonly attribute unsigned long videoHeight;
            attribute DOMString poster;
            
--- a/dom/interfaces/svg/nsIDOMSVGDocument.idl
+++ b/dom/interfaces/svg/nsIDOMSVGDocument.idl
@@ -2,14 +2,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIDOMDocument.idl"
 
 interface nsIDOMSVGElement;
 
-[scriptable, uuid(72d201c7-159c-4b64-886f-ed3920dd9462)]
+[scriptable, uuid(5ed36863-ab97-4f39-b8f7-350ddd1c940f)]
 interface nsIDOMSVGDocument : nsIDOMDocument
 {
   readonly attribute DOMString domain;
   readonly attribute nsIDOMSVGElement rootElement;
 };
--- a/dom/interfaces/svg/nsIDOMSVGElement.idl
+++ b/dom/interfaces/svg/nsIDOMSVGElement.idl
@@ -5,17 +5,17 @@
 
 #include "nsIDOMElement.idl"
 
 interface nsIDOMSVGAnimatedString;
 interface nsIDOMCSSStyleDeclaration;
 interface nsIDOMCSSValue;
 
 
-[scriptable, uuid(b0d2bcfa-9aac-4c23-9a8b-b88f7c4b93a5)]
+[scriptable, uuid(dd62ac57-a9ad-46d4-80a9-6cf179970c66)]
 interface nsIDOMSVGElement : nsIDOMElement
 {
   attribute DOMString id;
             // raises DOMException on setting
   readonly attribute nsIDOMSVGElement    ownerSVGElement;
   readonly attribute nsIDOMSVGElement    viewportElement;
 
   readonly attribute nsIDOMSVGAnimatedString   className;
--- a/dom/interfaces/svg/nsIDOMSVGFilters.idl
+++ b/dom/interfaces/svg/nsIDOMSVGFilters.idl
@@ -6,34 +6,34 @@
 #include "nsIDOMSVGElement.idl"
 
 interface nsIDOMSVGAnimatedLength;
 interface nsIDOMSVGAnimatedString;
 interface nsIDOMSVGAnimatedNumber;
 interface nsIDOMSVGAnimatedEnumeration;
 interface nsIDOMSVGAnimatedInteger;
 
-[scriptable, uuid(4db427db-bbe2-4c22-875e-ed62c93cd759)]
+[scriptable, uuid(d53cce38-2b96-4803-9ca0-0310becd6873)]
 interface nsIDOMSVGFilterPrimitiveStandardAttributes : nsIDOMSVGElement
 { 
     readonly attribute nsIDOMSVGAnimatedLength      x;
     readonly attribute nsIDOMSVGAnimatedLength      y;
     readonly attribute nsIDOMSVGAnimatedLength      width;
     readonly attribute nsIDOMSVGAnimatedLength      height;
     readonly attribute nsIDOMSVGAnimatedString      result;
 };
 
-[scriptable, uuid(4fa9fbbe-482c-418a-afd1-d51b003f5a04)]
+[scriptable, uuid(89dca8ae-68bf-4259-a52d-b1040dc7f410)]
 interface nsIDOMSVGFEOffsetElement : nsIDOMSVGFilterPrimitiveStandardAttributes { 
     readonly attribute nsIDOMSVGAnimatedString in1;
     readonly attribute nsIDOMSVGAnimatedNumber dx;
     readonly attribute nsIDOMSVGAnimatedNumber dy;
 };
 
-[scriptable, uuid(b0f8b61c-7825-4149-a295-c85604ec50fa)]
+[scriptable, uuid(14eb581d-0e54-42b5-a595-5db6c9490277)]
 interface nsIDOMSVGFETurbulenceElement : nsIDOMSVGFilterPrimitiveStandardAttributes
 { 
     // Turbulence Types
     const unsigned short SVG_TURBULENCE_TYPE_UNKNOWN      = 0;
     const unsigned short SVG_TURBULENCE_TYPE_FRACTALNOISE = 1;
     const unsigned short SVG_TURBULENCE_TYPE_TURBULENCE   = 2;
     // Stitch Options
     const unsigned short SVG_STITCHTYPE_UNKNOWN  = 0;
@@ -43,33 +43,33 @@ interface nsIDOMSVGFETurbulenceElement :
     readonly attribute nsIDOMSVGAnimatedNumber      baseFrequencyX;
     readonly attribute nsIDOMSVGAnimatedNumber      baseFrequencyY;
     readonly attribute nsIDOMSVGAnimatedInteger     numOctaves;
     readonly attribute nsIDOMSVGAnimatedNumber      seed;
     readonly attribute nsIDOMSVGAnimatedEnumeration stitchTiles;
     readonly attribute nsIDOMSVGAnimatedEnumeration type;
 };
 
-[scriptable, uuid(655154fa-ad26-45b5-81b1-988986707ee4)]
+[scriptable, uuid(053c0aec-30df-48e9-9059-53f43b5261bb)]
 interface nsIDOMSVGFEMorphologyElement : nsIDOMSVGFilterPrimitiveStandardAttributes
 { 
     // Operator Types
     const unsigned short SVG_OPERATOR_UNKNOWN  = 0;
     const unsigned short SVG_OPERATOR_ERODE    = 1;
     const unsigned short SVG_OPERATOR_DILATE   = 2;
 
     readonly attribute nsIDOMSVGAnimatedString      in1;
     readonly attribute nsIDOMSVGAnimatedNumber      radiusX;
     readonly attribute nsIDOMSVGAnimatedNumber      radiusY;
     readonly attribute nsIDOMSVGAnimatedEnumeration operator;
     
     void setRadius ( in float rx, in float ry );
 };
 
-[scriptable, uuid(658c2d9c-01aa-4896-a35a-c42147fcf004)]
+[scriptable, uuid(7d49f132-5145-4b47-896a-ac5f9e6b6941)]
 interface nsIDOMSVGFEConvolveMatrixElement : nsIDOMSVGFilterPrimitiveStandardAttributes
 { 
     // Edge Mode Values
     const unsigned short SVG_EDGEMODE_UNKNOWN   = 0;
     const unsigned short SVG_EDGEMODE_DUPLICATE = 1;
     const unsigned short SVG_EDGEMODE_WRAP      = 2;
     const unsigned short SVG_EDGEMODE_NONE      = 3;
 
@@ -83,50 +83,50 @@ interface nsIDOMSVGFEConvolveMatrixEleme
     readonly attribute nsIDOMSVGAnimatedInteger     targetX;
     readonly attribute nsIDOMSVGAnimatedInteger     targetY;
     readonly attribute nsIDOMSVGAnimatedEnumeration edgeMode;
     readonly attribute nsIDOMSVGAnimatedNumber      kernelUnitLengthX;
     readonly attribute nsIDOMSVGAnimatedNumber      kernelUnitLengthY;
     readonly attribute nsISupports                  preserveAlpha;
 };
 
-[scriptable, uuid(44b5d9f8-87ec-46e7-9d55-115edbeebdd6)]
+[scriptable, uuid(309be736-d55a-40fe-a2f2-088aea14f0fa)]
 interface nsIDOMSVGFEDiffuseLightingElement :  nsIDOMSVGFilterPrimitiveStandardAttributes
 { 
   readonly attribute nsIDOMSVGAnimatedString in1;
   readonly attribute nsIDOMSVGAnimatedNumber surfaceScale;
   readonly attribute nsIDOMSVGAnimatedNumber diffuseConstant;
   readonly attribute nsIDOMSVGAnimatedNumber kernelUnitLengthX;
   readonly attribute nsIDOMSVGAnimatedNumber kernelUnitLengthY;
 };
 
-[scriptable, uuid(2426a9ec-d891-47a8-bab6-d32b10fc5e81)]
+[scriptable, uuid(bb2bac9f-dfab-4ce3-926a-9cfc11ab7922)]
 interface nsIDOMSVGFESpecularLightingElement : nsIDOMSVGFilterPrimitiveStandardAttributes
 { 
   readonly attribute nsIDOMSVGAnimatedString in1;
   readonly attribute nsIDOMSVGAnimatedNumber surfaceScale;
   readonly attribute nsIDOMSVGAnimatedNumber specularConstant;
   readonly attribute nsIDOMSVGAnimatedNumber specularExponent;
   readonly attribute nsIDOMSVGAnimatedNumber kernelUnitLengthX;
   readonly attribute nsIDOMSVGAnimatedNumber kernelUnitLengthY;
 };
 
-[scriptable, uuid(91cc30ef-4b48-4a11-8d29-13f8ffe28821)]
+[scriptable, uuid(99068af4-1156-46b6-afcc-4b9f37621d10)]
 interface nsIDOMSVGFESpotLightElement : nsIDOMSVGElement { 
   readonly attribute nsIDOMSVGAnimatedNumber x;
   readonly attribute nsIDOMSVGAnimatedNumber y;
   readonly attribute nsIDOMSVGAnimatedNumber z;
   readonly attribute nsIDOMSVGAnimatedNumber pointsAtX;
   readonly attribute nsIDOMSVGAnimatedNumber pointsAtY;
   readonly attribute nsIDOMSVGAnimatedNumber pointsAtZ;
   readonly attribute nsIDOMSVGAnimatedNumber specularExponent;
   readonly attribute nsIDOMSVGAnimatedNumber limitingConeAngle;
 };
 
-[scriptable, uuid(64bd5e60-5961-4db5-a7ab-718354491fcb)]
+[scriptable, uuid(5ab43048-d59a-4e3c-ad2f-6a5d8593f6d0)]
 interface nsIDOMSVGFEDisplacementMapElement : nsIDOMSVGFilterPrimitiveStandardAttributes
 {
   // Channel Selectors
   const unsigned short SVG_CHANNEL_UNKNOWN = 0;
   const unsigned short SVG_CHANNEL_R       = 1;
   const unsigned short SVG_CHANNEL_G       = 2;
   const unsigned short SVG_CHANNEL_B       = 3;
   const unsigned short SVG_CHANNEL_A       = 4;
--- a/dom/interfaces/xpath/nsIDOMXPathNamespace.idl
+++ b/dom/interfaces/xpath/nsIDOMXPathNamespace.idl
@@ -4,16 +4,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /**
  * Corresponds to http://www.w3.org/TR/2002/WD-DOM-Level-3-XPath-20020208
  */
 
 #include "nsIDOMNode.idl"
 
-[scriptable, uuid(558c2ab9-513e-43c2-afea-4930024b15b3)]
+[scriptable, uuid(b42c46c4-cd95-49c7-bdfe-14f51a379618)]
 interface nsIDOMXPathNamespace : nsIDOMNode
 {
   // XPathNodeType
   const unsigned short      XPATH_NAMESPACE_NODE           = 13;
 
   readonly attribute nsIDOMElement          ownerElement;
 };
--- a/dom/interfaces/xul/nsIDOMXULButtonElement.idl
+++ b/dom/interfaces/xul/nsIDOMXULButtonElement.idl
@@ -1,16 +1,16 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIDOMXULLabeledControlEl.idl"
 
-[scriptable, uuid(8eec22e8-91f4-44fc-9142-b4cd0f623076)]
+[scriptable, uuid(db51259e-4d2f-4b86-a686-6831e77b58b3)]
 interface nsIDOMXULButtonElement : nsIDOMXULLabeledControlElement {
   const short CHECKSTATE_UNCHECKED = 0;
   const short CHECKSTATE_CHECKED = 1;
   const short CHECKSTATE_MIXED = 2;
 
   attribute DOMString type;
   attribute DOMString dlgType;
 
--- a/dom/interfaces/xul/nsIDOMXULCheckboxElement.idl
+++ b/dom/interfaces/xul/nsIDOMXULCheckboxElement.idl
@@ -1,17 +1,17 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIDOMElement.idl"
 #include "nsIDOMXULLabeledControlEl.idl"
 
-[scriptable, uuid(b0539219-67c8-47c1-934c-08040701b33b)]
+[scriptable, uuid(de8d1776-92a4-4776-92bc-dd31c3a8d6bf)]
 interface nsIDOMXULCheckboxElement : nsIDOMXULLabeledControlElement {
   const short CHECKSTATE_UNCHECKED = 0;
   const short CHECKSTATE_CHECKED = 1;
   const short CHECKSTATE_MIXED = 2;
 
   attribute boolean checked;
   attribute long checkState;
   attribute boolean autoCheck;
--- a/dom/interfaces/xul/nsIDOMXULContainerElement.idl
+++ b/dom/interfaces/xul/nsIDOMXULContainerElement.idl
@@ -1,26 +1,26 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIDOMXULElement.idl"
 interface nsIDOMXULContainerElement;
 
-[scriptable, uuid(0cedc92f-a0ab-4c4c-83e9-582607b8d7e2)]
+[scriptable, uuid(149c9fbd-3939-4bd9-91d6-6238ae956a56)]
 interface nsIDOMXULContainerItemElement : nsIDOMXULElement
 {
   /**
    * Returns the parent container if any.
    */
   readonly attribute nsIDOMXULContainerElement parentContainer;
 };
 
-[scriptable, uuid(c0b1bfdd-6199-412d-af79-8d6524865a5b)]
+[scriptable, uuid(02d5a022-f2da-48d5-9cfd-68d515861240)]
 interface nsIDOMXULContainerElement : nsIDOMXULContainerItemElement
 {
   /**
    * Creates an item for the given label and value and appends it to the
    * container.
    *
    * @param aLabel - the label for the new item
    * @param aValue - the value of the new item
--- a/dom/interfaces/xul/nsIDOMXULControlElement.idl
+++ b/dom/interfaces/xul/nsIDOMXULControlElement.idl
@@ -3,17 +3,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIDOMElement.idl"
 #include "nsIDOMXULElement.idl"
 
 interface nsIControllers;
 
-[scriptable, uuid(3b1bce24-c3ad-4568-8e10-85922b521e8b)]
+[scriptable, uuid(caeccd1a-7559-4888-ade2-5879d24315c0)]
 interface nsIDOMXULControlElement : nsIDOMXULElement {
   attribute boolean disabled;
   attribute long tabIndex;
   
 // XXX defined in XULElement, but should be defined here
 //  readonly attribute nsIControllers controllers;
   
 //  void focus();
--- a/dom/interfaces/xul/nsIDOMXULDescriptionElement.idl
+++ b/dom/interfaces/xul/nsIDOMXULDescriptionElement.idl
@@ -1,15 +1,15 @@
 
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIDOMXULElement.idl"
 
-[scriptable, uuid(c5e2a24f-3c35-40c0-baf1-c92ecd09d232)]
+[scriptable, uuid(34712e25-babb-456b-afa3-fdc7e78cd778)]
 interface nsIDOMXULDescriptionElement : nsIDOMXULElement {
   attribute boolean disabled;
   attribute boolean crop;
   attribute DOMString value;
 };
 
--- a/dom/interfaces/xul/nsIDOMXULDocument.idl
+++ b/dom/interfaces/xul/nsIDOMXULDocument.idl
@@ -5,17 +5,17 @@
 
 #include "domstubs.idl"
 #include "nsIDOMDocument.idl"
 
 interface nsIDOMXULCommandDispatcher;
 interface nsIObserver;
 interface nsIBoxObject;
 
-[scriptable, uuid(7b188822-f3fc-42f2-93a9-7eee445e0108)]
+[scriptable, uuid(321957b3-0c30-4d8c-acbf-c18b3c93724d)]
 interface nsIDOMXULDocument : nsIDOMDocument
 {
   attribute nsIDOMNode                          popupNode;
 
   /**
    * These attributes correspond to trustedGetPopupNode().rangeOffset and
    * rangeParent. They will help you find where in the DOM the popup is
    * happening. Can be accessed from chrome only, and only during a popup
--- a/dom/interfaces/xul/nsIDOMXULElement.idl
+++ b/dom/interfaces/xul/nsIDOMXULElement.idl
@@ -7,17 +7,17 @@
 
 interface nsIRDFCompositeDataSource;
 interface nsIXULTemplateBuilder;
 interface nsIRDFResource;
 interface nsIControllers;
 interface nsIBoxObject;
 
 
-[scriptable, uuid(5d9d2e4f-a748-44f0-99d1-406384efdc5c)]
+[scriptable, uuid(d766ac03-e437-4923-9c38-001dc433be75)]
 interface nsIDOMXULElement : nsIDOMElement
 {
   attribute DOMString                 className;
 
   // Layout properties
   attribute DOMString align;
   attribute DOMString dir;
   attribute DOMString flex;
--- a/dom/interfaces/xul/nsIDOMXULImageElement.idl
+++ b/dom/interfaces/xul/nsIDOMXULImageElement.idl
@@ -1,12 +1,12 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIDOMElement.idl"
 #include "nsIDOMXULElement.idl"
 
-[scriptable, uuid(d7967c4e-60e1-486d-a730-c25b285f0ffa)]
+[scriptable, uuid(4088e81d-c1dc-40d5-9016-cef0adc836b6)]
 interface nsIDOMXULImageElement : nsIDOMXULElement {
   attribute DOMString src;
 };
 
--- a/dom/interfaces/xul/nsIDOMXULLabelElement.idl
+++ b/dom/interfaces/xul/nsIDOMXULLabelElement.idl
@@ -1,13 +1,13 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIDOMXULDescriptionElement.idl"
 
-[scriptable, uuid(6fe7161c-bab0-4232-9145-76d82480c1b0)]
+[scriptable, uuid(dc79cd5b-923b-42a2-8efc-ff00cb7f9e8e)]
 interface nsIDOMXULLabelElement : nsIDOMXULDescriptionElement {
   attribute DOMString accessKey;
   attribute DOMString control;
 };
 
--- a/dom/interfaces/xul/nsIDOMXULLabeledControlEl.idl
+++ b/dom/interfaces/xul/nsIDOMXULLabeledControlEl.idl
@@ -1,17 +1,17 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIDOMElement.idl"
 #include "nsIDOMXULControlElement.idl"
 
-[scriptable, uuid(eecd5462-3ead-4caa-9651-0c2b88b39a65)]
+[scriptable, uuid(61be0478-d99d-4828-a7bf-c4979ef690ae)]
 interface nsIDOMXULLabeledControlElement : nsIDOMXULControlElement {
   attribute DOMString crop;
   attribute DOMString image;
   attribute DOMString label;
   attribute DOMString accessKey;
   attribute DOMString command;
 
 //  void doCommand();
--- a/dom/interfaces/xul/nsIDOMXULMenuListElement.idl
+++ b/dom/interfaces/xul/nsIDOMXULMenuListElement.idl
@@ -1,17 +1,17 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIDOMXULSelectCntrlEl.idl"
 interface nsIDOMXULTextBoxElement;
 
-[scriptable, uuid(df76f885-717a-484b-81f9-76700a04b51d)]
+[scriptable, uuid(3ff9d357-ce7f-49f7-9c84-efa7d87d497f)]
 interface nsIDOMXULMenuListElement : nsIDOMXULSelectControlElement {
   attribute boolean editable;
   attribute boolean open;
   
   // label of selected option or value of textfield for editable menu lists
   readonly attribute DOMString label;
 
   attribute DOMString crop;
--- a/dom/interfaces/xul/nsIDOMXULMultSelectCntrlEl.idl
+++ b/dom/interfaces/xul/nsIDOMXULMultSelectCntrlEl.idl
@@ -1,16 +1,16 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIDOMXULSelectCntrlEl.idl"
 
-[scriptable, uuid(16a38e07-405b-42a3-b45d-c78037757c01)]
+[scriptable, uuid(878a7ece-8a79-493d-97dd-e89b86f75ce9)]
 interface nsIDOMXULMultiSelectControlElement : nsIDOMXULSelectControlElement
 {
   attribute DOMString selType;
 
   attribute nsIDOMXULSelectControlItemElement currentItem;
   attribute long currentIndex;
 
   readonly attribute nsIDOMNodeList selectedItems;
--- a/dom/interfaces/xul/nsIDOMXULPopupElement.idl
+++ b/dom/interfaces/xul/nsIDOMXULPopupElement.idl
@@ -1,17 +1,17 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIDOMElement.idl"
 #include "nsIDOMXULElement.idl"
 
-[scriptable, uuid(0037e541-09f8-475d-8274-ceff62332e6b)]
+[scriptable, uuid(d930acb8-c74f-44bd-ac84-ebe5fd1ea98c)]
 interface nsIDOMXULPopupElement : nsIDOMXULElement {
   const unsigned short      BEFORE_START                   = 1;
   const unsigned short      BEFORE_END                     = 2;
   const unsigned short      AFTER_START                    = 3;
   const unsigned short      AFTER_END                      = 4;
   const unsigned short      START_BEFORE                   = 5;
   const unsigned short      START_AFTER                    = 6;
   const unsigned short      END_BEFORE                     = 7;
--- a/dom/interfaces/xul/nsIDOMXULSelectCntrlEl.idl
+++ b/dom/interfaces/xul/nsIDOMXULSelectCntrlEl.idl
@@ -1,17 +1,17 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIDOMXULControlElement.idl"
 interface nsIDOMXULSelectControlItemElement;
 
-[scriptable, uuid(f9cbf59c-0cdd-416e-a809-40da4a7a8cb5)]
+[scriptable, uuid(ef83c335-b71d-4b86-9519-451ee78db033)]
 interface nsIDOMXULSelectControlElement : nsIDOMXULControlElement {
   attribute nsIDOMXULSelectControlItemElement selectedItem;
   attribute long selectedIndex;
 
   attribute DOMString value;
   
   nsIDOMXULSelectControlItemElement appendItem(in DOMString label, in DOMString value);
   nsIDOMXULSelectControlItemElement insertItemAt(in long index, in DOMString label, in DOMString value);
--- a/dom/interfaces/xul/nsIDOMXULSelectCntrlItemEl.idl
+++ b/dom/interfaces/xul/nsIDOMXULSelectCntrlItemEl.idl
@@ -1,17 +1,17 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIDOMXULElement.idl"
 interface nsIDOMXULSelectControlElement;
 
-[scriptable, uuid(85fa64de-91d9-4b2f-b9fb-28eb718ea436)]
+[scriptable, uuid(281d86b5-4448-410b-8eeb-9f4834678ab3)]
 interface nsIDOMXULSelectControlItemElement : nsIDOMXULElement {
   attribute boolean disabled;
   attribute DOMString crop;
   attribute DOMString image;
   attribute DOMString label;
   attribute DOMString accessKey;
   attribute DOMString command;
   
--- a/dom/interfaces/xul/nsIDOMXULTextboxElement.idl
+++ b/dom/interfaces/xul/nsIDOMXULTextboxElement.idl
@@ -1,17 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIDOMXULLabeledControlEl.idl"
 interface nsIDOMHTMLInputElement;
 
-[scriptable, uuid(5bab7935-6219-45f8-9f7c-54ac8e9b023b)]
+[scriptable, uuid(254e8f5a-4476-4bd4-aee8-1eb0fba454ab)]
 interface nsIDOMXULTextBoxElement : nsIDOMXULControlElement
 {
   // inputField may be any type of editable field, such as an
   // HTML <input type="text"> or <textarea>
   readonly attribute nsIDOMNode inputField;
 
   readonly attribute long textLength;
   attribute long maxLength;
--- a/dom/interfaces/xul/nsIDOMXULTreeElement.idl
+++ b/dom/interfaces/xul/nsIDOMXULTreeElement.idl
@@ -9,17 +9,17 @@
 interface nsITreeColumns;
 interface nsITreeView;
 interface nsIDOMXULTextBoxElement;
 
 /**
  * @status UNDER_DEVELOPMENT
  */
 
-[scriptable, uuid(a3c573b8-8fb8-4cde-a47a-dca921eee94c)]
+[scriptable, uuid(77504c1f-93c7-4fd3-b004-f401ffad0a09)]
 interface nsIDOMXULTreeElement : nsIDOMXULElement
 {
 
   readonly attribute nsITreeColumns columns;
 
   attribute nsITreeView view;
 
   readonly attribute nsIDOMElement body;
--- a/dom/plugins/base/nsPluginHost.cpp
+++ b/dom/plugins/base/nsPluginHost.cpp
@@ -167,18 +167,19 @@ static const char *kPrefDisableFullPage 
 // 0.08 mime entry point on MachO, bug 137535
 // 0.09 the file encoding is changed to UTF-8, bug 420285
 // 0.10 added plugin versions on appropriate platforms, bug 427743
 // 0.11 file name and full path fields now store expected values on all platforms, bug 488181
 // 0.12 force refresh due to quicktime pdf claim fix, bug 611197
 // 0.13 add architecture and list of invalid plugins, bug 616271
 // 0.14 force refresh due to locale comparison fix, bug 611296
 // 0.15 force refresh due to bug in reading Java plist MIME data, bug 638171
+// 0.16 version bump to avoid importing the plugin flags in newer versions
 // The current plugin registry version (and the maximum version we know how to read)
-static const char *kPluginRegistryVersion = "0.15";
+static const char *kPluginRegistryVersion = "0.16";
 // The minimum registry version we know how to read
 static const char *kMinimumRegistryVersion = "0.9";
 
 static NS_DEFINE_IID(kIPluginTagInfoIID, NS_IPLUGINTAGINFO_IID);
 static const char kDirectoryServiceContractID[] = "@mozilla.org/file/directory_service;1";
 
 // Registry keys for caching plugin info
 static const char kPluginsRootKey[] = "software/plugins";
@@ -1115,18 +1116,18 @@ nsPluginHost::IsPluginEnabledForType(con
     return NS_OK;
 
   // Pass false as the second arg so we can return NS_ERROR_PLUGIN_DISABLED
   // for disabled plug-ins.
   plugin = FindPluginForType(aMimeType, false);
   if (!plugin)
     return NS_ERROR_FAILURE;
 
-  if (!plugin->IsEnabled()) {
-    if (plugin->HasFlag(NS_PLUGIN_FLAG_BLOCKLISTED))
+  if (!plugin->IsActive()) {
+    if (plugin->IsBlocklisted())
       return NS_ERROR_PLUGIN_BLOCKLISTED;
     else
       return NS_ERROR_PLUGIN_DISABLED;
   }
 
   return NS_OK;
 }
 
@@ -1186,23 +1187,17 @@ nsPluginHost::GetPermissionStringForType
   if (blocklistState == nsIBlocklistService::STATE_VULNERABLE_UPDATE_AVAILABLE ||
       blocklistState == nsIBlocklistService::STATE_VULNERABLE_NO_UPDATE) {
     aPermissionString.AssignLiteral("plugin-vulnerable:");
   }
   else {
     aPermissionString.AssignLiteral("plugin:");
   }
 
-  if (tag->mIsJavaPlugin) {
-    aPermissionString.Append("java");
-  } else if (tag->mIsFlashPlugin) {
-    aPermissionString.Append("flash");
-  } else {
-    aPermissionString.Append(tag->GetNiceFileName());
-  }
+  aPermissionString.Append(tag->GetNiceFileName());
 
   return NS_OK;
 }
 
 // check comma delimitered extensions
 static int CompareExtensions(const char *aExtensionList, const char *aExtension)
 {
   if (!aExtensionList || !aExtension)
@@ -1311,17 +1306,17 @@ nsresult
 nsPluginHost::GetPluginCount(uint32_t* aPluginCount)
 {
   LoadPlugins();
 
   uint32_t count = 0;
 
   nsPluginTag* plugin = mPlugins;
   while (plugin != nullptr) {
-    if (plugin->IsEnabled()) {
+    if (plugin->IsActive()) {
       ++count;
     }
     plugin = plugin->mNext;
   }
 
   *aPluginCount = count;
 
   return NS_OK;
@@ -1329,17 +1324,17 @@ nsPluginHost::GetPluginCount(uint32_t* a
 
 nsresult
 nsPluginHost::GetPlugins(uint32_t aPluginCount, nsIDOMPlugin** aPluginArray)
 {
   LoadPlugins();
 
   nsPluginTag* plugin = mPlugins;
   for (uint32_t i = 0; i < aPluginCount && plugin; plugin = plugin->mNext) {
-    if (plugin->IsEnabled()) {
+    if (plugin->IsActive()) {
       nsIDOMPlugin* domPlugin = new DOMPluginImpl(plugin);
       NS_IF_ADDREF(domPlugin);
       aPluginArray[i++] = domPlugin;
     }
   }
 
   return NS_OK;
 }
@@ -1406,17 +1401,17 @@ nsPluginHost::FindPluginForType(const ch
   }
 
   LoadPlugins();
 
   InfallibleTArray<nsPluginTag*> matchingPlugins;
 
   nsPluginTag *plugin = mPlugins;
   while (plugin) {
-    if (!aCheckEnabled || plugin->IsEnabled()) {
+    if (!aCheckEnabled || plugin->IsActive()) {
       int32_t mimeCount = plugin->mMimeTypes.Length();
       for (int32_t i = 0; i < mimeCount; i++) {
         if (0 == PL_strcasecmp(plugin->mMimeTypes[i].get(), aMimeType)) {
           matchingPlugins.AppendElement(plugin);
           break;
         }
       }
     }
@@ -1435,17 +1430,17 @@ nsPluginHost::FindPluginEnabledForExtens
   }
 
   LoadPlugins();
 
   InfallibleTArray<nsPluginTag*> matchingPlugins;
 
   nsPluginTag *plugin = mPlugins;
   while (plugin) {
-    if (plugin->IsEnabled()) {
+    if (plugin->IsActive()) {
       int32_t variants = plugin->mExtensions.Length();
       for (int32_t i = 0; i < variants; i++) {
         // mExtensionsArray[cnt] is a list of extensions separated by commas
         if (0 == CompareExtensions(plugin->mExtensions[i].get(), aExtension)) {
           matchingPlugins.AppendElement(plugin);
           break;
         }
       }
@@ -1943,24 +1938,23 @@ nsresult nsPluginHost::ScanPluginsDirect
 
     int64_t fileModTime = GetPluginLastModifiedTime(localfile);
 
     // Look for it in our cache
     NS_ConvertUTF16toUTF8 filePath(utf16FilePath);
     nsRefPtr<nsPluginTag> pluginTag;
     RemoveCachedPluginsInfo(filePath.get(), getter_AddRefs(pluginTag));
 
-    bool enabled = true;
     bool seenBefore = false;
+
     if (pluginTag) {
       seenBefore = true;
       // If plugin changed, delete cachedPluginTag and don't use cache
       if (fileModTime != pluginTag->mLastModifiedTime) {
         // Plugins has changed. Don't use cached plugin info.
-        enabled = (pluginTag->Flags() & NS_PLUGIN_FLAG_ENABLED) != 0;
         pluginTag = nullptr;
 
         // plugin file changed, flag this fact
         *aPluginsChanged = true;
       }
 
       // If we're not creating a list and we already know something changed then
       // we're done.
@@ -2036,31 +2030,27 @@ nsresult nsPluginHost::ScanPluginsDirect
           // If the blocklist says so, block the plugin.
           // If the blocklist says it is risky and we have never seen this
           // plugin before, then disable it.
           // If the blocklist says this is an outdated plugin, warn about
           // outdated plugins.
           // If the blocklist says the plugin is one of the click-to-play
           // states, set the click-to-play flag.
           if (state == nsIBlocklistService::STATE_BLOCKED) {
-             pluginTag->Mark(NS_PLUGIN_FLAG_BLOCKLISTED);
+             pluginTag->SetBlocklisted(true);
           }
           if (state == nsIBlocklistService::STATE_SOFTBLOCKED && !seenBefore) {
-             enabled = false;
+             pluginTag->SetDisabled(true);
           }
           if (state == nsIBlocklistService::STATE_OUTDATED && !seenBefore) {
              warnOutdated = true;
           }
         }
       }
 
-      if (!enabled) {
-        pluginTag->UnMark(NS_PLUGIN_FLAG_ENABLED);
-      }
-
       // Plugin unloading is tag-based. If we created a new tag and loaded
       // the library in the process then we want to attempt to unload it here.
       // Only do this if the pref is set for aggressive unloading.
       if (UnloadPluginsASAP()) {
         pluginTag->TryUnloadPlugin(false);
       }
     }
 
@@ -2114,17 +2104,17 @@ nsresult nsPluginHost::ScanPluginsDirect
         if (!next) {
           prev->mNext = pluginTag;
         }
       }
     } else {
       mPlugins = pluginTag;
     }
 
-    if (pluginTag->IsEnabled()) {
+    if (pluginTag->IsActive()) {
       nsAdoptingCString disableFullPage =
         Preferences::GetCString(kPrefDisableFullPage);
       for (uint32_t i = 0; i < pluginTag->mMimeTypes.Length(); i++) {
         if (!IsTypeInList(pluginTag->mMimeTypes[i], disableFullPage)) {
           RegisterWithCategoryManager(pluginTag->mMimeTypes[i],
                                       ePluginRegister);
         }
       }
@@ -2395,17 +2385,17 @@ nsPluginHost::UpdatePluginInfo(nsPluginT
   }
 
   nsCOMPtr<nsIObserverService> obsService =
     mozilla::services::GetObserverService();
   if (obsService)
     obsService->NotifyObservers(nullptr, "plugin-info-updated", nullptr);
 
   // Reload instances if needed
-  if (aPluginTag->IsEnabled()) {
+  if (aPluginTag->IsActive()) {
     return NS_OK;
   }
 
   nsTArray<nsCOMPtr<nsIDocument> > instsToReload;
   DestroyRunningInstances(&instsToReload, aPluginTag);
   
   if (!instsToReload.IsEmpty()) {
     nsCOMPtr<nsIRunnable> ev = new nsPluginDocReframeEvent(instsToReload);
@@ -2540,17 +2530,17 @@ nsPluginHost::WritePluginInfo()
       PLUGIN_REGISTRY_END_OF_LINE_MARKER);
 
     // lastModifiedTimeStamp|canUnload|tag->mFlags
     PR_fprintf(fd, "%lld%c%d%c%lu%c%c\n",
       tag->mLastModifiedTime,
       PLUGIN_REGISTRY_FIELD_DELIMITER,
       false, // did store whether or not to unload in-process plugins
       PLUGIN_REGISTRY_FIELD_DELIMITER,
-      tag->Flags(),
+      0, // legacy field for flags
       PLUGIN_REGISTRY_FIELD_DELIMITER,
       PLUGIN_REGISTRY_END_OF_LINE_MARKER);
 
     //description, name & mtypecount are on separate line
     PR_fprintf(fd, "%s%c%c\n%s%c%c\n%d\n",
       (tag->mDescription.get()),
       PLUGIN_REGISTRY_FIELD_DELIMITER,
       PLUGIN_REGISTRY_END_OF_LINE_MARKER,
@@ -2601,16 +2591,20 @@ nsPluginHost::WritePluginInfo()
 }
 
 nsresult
 nsPluginHost::ReadPluginInfo()
 {
   const long PLUGIN_REG_MIMETYPES_ARRAY_SIZE = 12;
   const long PLUGIN_REG_MAX_MIMETYPES = 1000;
 
+  // we need to import the legacy flags from the plugin registry once
+  const bool pluginStateImported =
+    Preferences::GetDefaultBool("plugin.importedState", false);
+
   nsresult rv;
 
   nsCOMPtr<nsIProperties> directoryService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID,&rv));
   if (NS_FAILED(rv))
     return rv;
 
   directoryService->Get(NS_APP_USER_PROFILE_50_DIR, NS_GET_IID(nsIFile),
                         getter_AddRefs(mPluginRegFile));
@@ -2731,16 +2725,19 @@ nsPluginHost::ReadPluginInfo()
     if (PL_strcmp(archValues[1], arch.get())) {
       return rv;
     }
   }
 
   // Registry v0.13 and upwards includes the list of invalid plugins
   bool hasInvalidPlugins = (version >= "0.13");
 
+  // Registry v0.16 and upwards always have 0 for their plugin flags, prefs are used instead
+  const bool hasValidFlags = (version < "0.16");
+
   if (!ReadSectionHeader(reader, "PLUGINS"))
     return rv;
 
 #if defined(XP_MACOSX)
   bool hasFullPathInFileNameField = false;
 #else
   bool hasFullPathInFileNameField = (version < "0.11");
 #endif
@@ -2869,18 +2866,21 @@ nsPluginHost::ReadPluginInfo()
       (const char* const*)extensions,
       mimetypecount, lastmod, true);
     if (heapalloced)
       delete [] heapalloced;
 
     if (!tag)
       continue;
 
-    // Mark plugin as loaded from cache
-    tag->Mark(tagflag | NS_PLUGIN_FLAG_FROMCACHE);
+    // Import flags from registry into prefs for old registry versions
+    if (hasValidFlags && !pluginStateImported) {
+      tag->ImportFlagsToPrefs(tagflag);
+    }
+
     PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_BASIC,
       ("LoadCachedPluginsInfo : Loading Cached plugininfo for %s\n", tag->mFileName.get()));
     tag->mNext = mCachedPlugins;
     mCachedPlugins = tag;
   }
 
   if (hasInvalidPlugins) {
     if (!ReadSectionHeader(reader, "INVALID")) {
@@ -2900,16 +2900,20 @@ nsPluginHost::ReadPluginInfo()
 
       invalidTag->mNext = mInvalidPlugins;
       if (mInvalidPlugins) {
         mInvalidPlugins->mPrev = invalidTag;
       }
       mInvalidPlugins = invalidTag;
     }
   }
+
+  // flip the pref so we don't import the legacy flags again
+  Preferences::SetBool("plugin.importedState", true);
+
   return NS_OK;
 }
 
 void
 nsPluginHost::RemoveCachedPluginsInfo(const char *filePath, nsPluginTag **result)
 {
   nsRefPtr<nsPluginTag> prev;
   nsRefPtr<nsPluginTag> tag = mCachedPlugins;
--- a/dom/plugins/base/nsPluginHost.h
+++ b/dom/plugins/base/nsPluginHost.h
@@ -147,17 +147,17 @@ public:
   AddHeadersToChannel(const char *aHeadersData, uint32_t aHeadersDataLen, 
                       nsIChannel *aGenericChannel);
 
   static nsresult GetPluginTempDir(nsIFile **aDir);
 
   // Writes updated plugins settings to disk and unloads the plugin
   // if it is now disabled
   nsresult UpdatePluginInfo(nsPluginTag* aPluginTag);
-  
+
   // Helper that checks if a type is whitelisted in plugin.allowed_types.
   // Always returns true if plugin.allowed_types is not set
   static bool IsTypeWhitelisted(const char *aType);
 
   // checks whether aTag is a "java" plugin tag (a tag for a plugin
   // that does Java)
   static bool IsJavaMIMEType(const char *aType);
 
--- a/dom/plugins/base/nsPluginTags.cpp
+++ b/dom/plugins/base/nsPluginTags.cpp
@@ -19,27 +19,61 @@
 #include "nsNPAPIPlugin.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/Preferences.h"
 #include <cctype>
 
 using namespace mozilla;
 using mozilla::TimeStamp;
 
+// These legacy flags are used in the plugin registry. The states are now
+// stored in prefs, but we still need to be able to import them.
+#define NS_PLUGIN_FLAG_ENABLED      0x0001    // is this plugin enabled?
+// no longer used                   0x0002    // reuse only if regenerating pluginreg.dat
+#define NS_PLUGIN_FLAG_FROMCACHE    0x0004    // this plugintag info was loaded from cache
+// no longer used                   0x0008    // reuse only if regenerating pluginreg.dat
+#define NS_PLUGIN_FLAG_BLOCKLISTED  0x0010    // this is a blocklisted plugin
+#define NS_PLUGIN_FLAG_CLICKTOPLAY  0x0020    // this is a click-to-play plugin
+
 inline char* new_str(const char* str)
 {
   if (str == nullptr)
     return nullptr;
   
   char* result = new char[strlen(str) + 1];
   if (result != nullptr)
     return strcpy(result, str);
   return result;
 }
 
+static nsCString
+MakePrefNameForPlugin(const char* const subname, nsPluginTag* aTag)
+{
+  nsCString pref;
+
+  pref.AssignLiteral("plugin.");
+  pref.Append(subname);
+  pref.Append('.');
+  pref.Append(aTag->GetNiceFileName());
+
+  return pref;
+}
+
+static nsCString
+GetStatePrefNameForPlugin(nsPluginTag* aTag)
+{
+  return MakePrefNameForPlugin("state", aTag);
+}
+
+static nsCString
+GetBlocklistedPrefNameForPlugin(nsPluginTag* aTag)
+{
+  return MakePrefNameForPlugin("blocklisted", aTag);
+}
+
 NS_IMPL_ISUPPORTS1(DOMMimeTypeImpl, nsIDOMMimeType)
 
 /* nsPluginTag */
 
 nsPluginTag::nsPluginTag(nsPluginTag* aPluginTag)
 : mPluginHost(nullptr),
 mName(aPluginTag->mName),
 mDescription(aPluginTag->mDescription),
@@ -48,33 +82,31 @@ mMimeDescriptions(aPluginTag->mMimeDescr
 mExtensions(aPluginTag->mExtensions),
 mLibrary(nullptr),
 mIsJavaPlugin(aPluginTag->mIsJavaPlugin),
 mIsFlashPlugin(aPluginTag->mIsFlashPlugin),
 mFileName(aPluginTag->mFileName),
 mFullPath(aPluginTag->mFullPath),
 mVersion(aPluginTag->mVersion),
 mLastModifiedTime(0),
-mFlags(NS_PLUGIN_FLAG_ENABLED),
 mNiceFileName()
 {
 }
 
 nsPluginTag::nsPluginTag(nsPluginInfo* aPluginInfo)
 : mPluginHost(nullptr),
 mName(aPluginInfo->fName),
 mDescription(aPluginInfo->fDescription),
 mLibrary(nullptr),
 mIsJavaPlugin(false),
 mIsFlashPlugin(false),
 mFileName(aPluginInfo->fFileName),
 mFullPath(aPluginInfo->fFullPath),
 mVersion(aPluginInfo->fVersion),
 mLastModifiedTime(0),
-mFlags(NS_PLUGIN_FLAG_ENABLED),
 mNiceFileName()
 {
   InitMime(aPluginInfo->fMimeTypeArray,
            aPluginInfo->fMimeDescriptionArray,
            aPluginInfo->fExtensionArray,
            aPluginInfo->fVariantCount);
   EnsureMembersAreUTF8();
 }
@@ -95,17 +127,16 @@ mName(aName),
 mDescription(aDescription),
 mLibrary(nullptr),
 mIsJavaPlugin(false),
 mIsFlashPlugin(false),
 mFileName(aFileName),
 mFullPath(aFullPath),
 mVersion(aVersion),
 mLastModifiedTime(aLastModifiedTime),
-mFlags(0), // Caller will read in our flags from cache
 mNiceFileName()
 {
   InitMime(aMimeTypes, aMimeDescriptions, aExtensions, static_cast<uint32_t>(aVariants));
   if (!aArgsAreUTF8)
     EnsureMembersAreUTF8();
 }
 
 nsPluginTag::~nsPluginTag()
@@ -280,82 +311,135 @@ nsPluginTag::GetVersion(nsACString& aVer
 
 NS_IMETHODIMP
 nsPluginTag::GetName(nsACString& aName)
 {
   aName = mName;
   return NS_OK;
 }
 
+bool
+nsPluginTag::IsActive()
+{
+  return IsEnabled() && !IsBlocklisted();
+}
+
+bool
+nsPluginTag::IsEnabled()
+{
+  const PluginState state = GetPluginState();
+  return (state == ePluginState_Enabled) || (state == ePluginState_Clicktoplay);
+}
+
+void
+nsPluginTag::SetEnabled(bool enabled)
+{
+  if (enabled == IsEnabled()) {
+    return;
+  }
+
+  PluginState state = GetPluginState();
+
+  if (!enabled) {
+    SetPluginState(ePluginState_Disabled);
+  } else if (state != ePluginState_Clicktoplay) {
+    SetPluginState(ePluginState_Enabled);
+  }
+
+  mPluginHost->UpdatePluginInfo(this);
+}
+
 NS_IMETHODIMP
 nsPluginTag::GetDisabled(bool* aDisabled)
 {
-  *aDisabled = !HasFlag(NS_PLUGIN_FLAG_ENABLED);
+  *aDisabled = !IsEnabled();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsPluginTag::SetDisabled(bool aDisabled)
 {
-  if (HasFlag(NS_PLUGIN_FLAG_ENABLED) == !aDisabled)
-    return NS_OK;
-  
-  if (aDisabled)
-    UnMark(NS_PLUGIN_FLAG_ENABLED);
-  else
-    Mark(NS_PLUGIN_FLAG_ENABLED);
+  SetEnabled(!aDisabled);
+  return NS_OK;
+}
 
-  return NS_OK;
+bool
+nsPluginTag::IsBlocklisted()
+{
+  return Preferences::GetBool(GetBlocklistedPrefNameForPlugin(this).get(), false);
 }
 
 NS_IMETHODIMP
 nsPluginTag::GetBlocklisted(bool* aBlocklisted)
 {
-  *aBlocklisted = HasFlag(NS_PLUGIN_FLAG_BLOCKLISTED);
+  *aBlocklisted = IsBlocklisted();
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsPluginTag::SetBlocklisted(bool aBlocklisted)
+nsPluginTag::SetBlocklisted(bool blocklisted)
 {
-  if (HasFlag(NS_PLUGIN_FLAG_BLOCKLISTED) == aBlocklisted)
+  if (blocklisted == IsBlocklisted()) {
     return NS_OK;
-  
-  if (aBlocklisted)
-    Mark(NS_PLUGIN_FLAG_BLOCKLISTED);
-  else
-    UnMark(NS_PLUGIN_FLAG_BLOCKLISTED);
+  }
+
+  const nsCString pref = GetBlocklistedPrefNameForPlugin(this);
+  if (blocklisted) {
+    Preferences::SetBool(pref.get(), true);
+  } else {
+    Preferences::ClearUser(pref.get());
+  }
 
+  mPluginHost->UpdatePluginInfo(this);
   return NS_OK;
 }
 
+bool
+nsPluginTag::IsClicktoplay()
+{
+  const PluginState state = GetPluginState();
+  return (state == ePluginState_Clicktoplay);
+}
+
 NS_IMETHODIMP
 nsPluginTag::GetClicktoplay(bool *aClicktoplay)
 {
-  *aClicktoplay = HasFlag(NS_PLUGIN_FLAG_CLICKTOPLAY);
+  *aClicktoplay = IsClicktoplay();
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsPluginTag::SetClicktoplay(bool aClicktoplay)
+nsPluginTag::SetClicktoplay(bool clicktoplay)
 {
-  if (HasFlag(NS_PLUGIN_FLAG_CLICKTOPLAY) == aClicktoplay) {
+  if (clicktoplay == IsClicktoplay()) {
     return NS_OK;
   }
-  
-  if (aClicktoplay) {
-    Mark(NS_PLUGIN_FLAG_CLICKTOPLAY);
-  } else {
-    UnMark(NS_PLUGIN_FLAG_CLICKTOPLAY);
+
+  const PluginState state = GetPluginState();
+  if (state != ePluginState_Disabled) {
+    SetPluginState(ePluginState_Clicktoplay);
   }
-  
-  mPluginHost->UpdatePluginInfo(nullptr);
+
+  mPluginHost->UpdatePluginInfo(this);
   return NS_OK;
 }
 
+nsPluginTag::PluginState
+nsPluginTag::GetPluginState()
+{
+  return (PluginState)Preferences::GetInt(GetStatePrefNameForPlugin(this).get(),
+                                          ePluginState_Enabled);
+}
+
+void
+nsPluginTag::SetPluginState(PluginState state)
+{
+  Preferences::SetInt(GetStatePrefNameForPlugin(this).get(), state);
+}
+
 NS_IMETHODIMP
 nsPluginTag::GetMimeTypes(uint32_t* aCount, nsIDOMMimeType*** aResults)
 {
   uint32_t count = mMimeTypes.Length();
   *aResults = static_cast<nsIDOMMimeType**>
                          (nsMemory::Alloc(count * sizeof(**aResults)));
   if (!*aResults)
     return NS_ERROR_OUT_OF_MEMORY;
@@ -365,51 +449,16 @@ nsPluginTag::GetMimeTypes(uint32_t* aCou
     nsIDOMMimeType* mimeType = new DOMMimeTypeImpl(this, i);
     (*aResults)[i] = mimeType;
     NS_ADDREF((*aResults)[i]);
   }
 
   return NS_OK;
 }
 
-void nsPluginTag::Mark(uint32_t mask)
-{
-  bool wasEnabled = IsEnabled();
-  mFlags |= mask;
-
-  if (mPluginHost && wasEnabled != IsEnabled()) {
-    mPluginHost->UpdatePluginInfo(this);
-  }
-}
-
-void nsPluginTag::UnMark(uint32_t mask)
-{
-  bool wasEnabled = IsEnabled();
-  mFlags &= ~mask;
-
-  if (mPluginHost && wasEnabled != IsEnabled()) {
-    mPluginHost->UpdatePluginInfo(this);
-  }
-}
-
-bool nsPluginTag::HasFlag(uint32_t flag)
-{
-  return (mFlags & flag) != 0;
-}
-
-uint32_t nsPluginTag::Flags()
-{
-  return mFlags;
-}
-
-bool nsPluginTag::IsEnabled()
-{
-  return HasFlag(NS_PLUGIN_FLAG_ENABLED) && !HasFlag(NS_PLUGIN_FLAG_BLOCKLISTED);
-}
-
 bool
 nsPluginTag::HasSameNameAndMimes(const nsPluginTag *aPluginTag) const
 {
   NS_ENSURE_TRUE(aPluginTag, false);
 
   if ((!mName.Equals(aPluginTag->mName)) ||
       (mMimeTypes.Length() != aPluginTag->mMimeTypes.Length())) {
     return false;
@@ -438,16 +487,26 @@ void nsPluginTag::TryUnloadPlugin(bool i
   }
 }
 
 nsCString nsPluginTag::GetNiceFileName() {
   if (!mNiceFileName.IsEmpty()) {
     return mNiceFileName;
   }
 
+  if (mIsFlashPlugin) {
+    mNiceFileName.Assign(NS_LITERAL_CSTRING("flash"));
+    return mNiceFileName;
+  }
+
+  if (mIsJavaPlugin) {
+    mNiceFileName.Assign(NS_LITERAL_CSTRING("java"));
+    return mNiceFileName;
+  }
+
   mNiceFileName.Assign(mFileName);
   int32_t niceNameLength = mFileName.RFind(".");
   NS_ASSERTION(niceNameLength != kNotFound, "mFileName doesn't have a '.'?");
   while (niceNameLength > 0) {
     char chr = mFileName[niceNameLength - 1];
     if (!std::isalpha(chr))
       niceNameLength--;
     else
@@ -455,10 +514,22 @@ nsCString nsPluginTag::GetNiceFileName()
   }
 
   // If it turns out that niceNameLength <= 0, we'll fall back and use the
   // entire mFileName (which we've already taken care of, a few lines back)
   if (niceNameLength > 0) {
     mNiceFileName.Truncate(niceNameLength);
   }
 
+  ToLowerCase(mNiceFileName);
   return mNiceFileName;
 }
+
+void nsPluginTag::ImportFlagsToPrefs(uint32_t flags)
+{
+  if (!(flags & NS_PLUGIN_FLAG_ENABLED)) {
+    SetPluginState(ePluginState_Disabled);
+  }
+
+  if (flags & NS_PLUGIN_FLAG_BLOCKLISTED) {
+    Preferences::SetBool(GetBlocklistedPrefNameForPlugin(this).get(), true);
+  }
+}
--- a/dom/plugins/base/nsPluginTags.h
+++ b/dom/plugins/base/nsPluginTags.h
@@ -14,58 +14,65 @@
 #include "nsNPAPIPluginInstance.h"
 #include "nsITimer.h"
 #include "nsIDOMMimeType.h"
 
 class nsPluginHost;
 struct PRLibrary;
 struct nsPluginInfo;
 
-// Remember that flags are written out to pluginreg.dat, be careful
-// changing their meaning.
-#define NS_PLUGIN_FLAG_ENABLED      0x0001    // is this plugin enabled?
-// no longer used                   0x0002    // reuse only if regenerating pluginreg.dat
-#define NS_PLUGIN_FLAG_FROMCACHE    0x0004    // this plugintag info was loaded from cache
-// no longer used                   0x0008    // reuse only if regenerating pluginreg.dat
-#define NS_PLUGIN_FLAG_BLOCKLISTED  0x0010    // this is a blocklisted plugin
-#define NS_PLUGIN_FLAG_CLICKTOPLAY  0x0020    // this is a click-to-play plugin
-
 // A linked-list of plugin information that is used for instantiating plugins
 // and reflecting plugin information into JavaScript.
 class nsPluginTag : public nsIPluginTag
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIPLUGINTAG
-  
+
+  enum PluginState {
+    ePluginState_Disabled = 0,
+    ePluginState_Clicktoplay = 1,
+    ePluginState_Enabled = 2,
+  };
+
   nsPluginTag(nsPluginTag* aPluginTag);
   nsPluginTag(nsPluginInfo* aPluginInfo);
   nsPluginTag(const char* aName,
               const char* aDescription,
               const char* aFileName,
               const char* aFullPath,
               const char* aVersion,
               const char* const* aMimeTypes,
               const char* const* aMimeDescriptions,
               const char* const* aExtensions,
               int32_t aVariants,
               int64_t aLastModifiedTime = 0,
               bool aArgsAreUTF8 = false);
   virtual ~nsPluginTag();
-  
+
   void SetHost(nsPluginHost * aHost);
   void TryUnloadPlugin(bool inShutdown);
-  void Mark(uint32_t mask);
-  void UnMark(uint32_t mask);
-  bool HasFlag(uint32_t flag);
-  uint32_t Flags();
+
+  // plugin is enabled and not blocklisted
+  bool IsActive();
+
+  bool IsEnabled();
+  void SetEnabled(bool enabled);
+  bool IsClicktoplay();
+  bool IsBlocklisted();
+
+  PluginState GetPluginState();
+  void SetPluginState(PluginState state);
+
+  // import legacy flags from plugin registry into the preferences
+  void ImportFlagsToPrefs(uint32_t flag);
+
   bool HasSameNameAndMimes(const nsPluginTag *aPluginTag) const;
-  bool IsEnabled();
   nsCString GetNiceFileName();
-  
+
   nsRefPtr<nsPluginTag> mNext;
   nsPluginHost *mPluginHost;
   nsCString     mName; // UTF-8
   nsCString     mDescription; // UTF-8
   nsTArray<nsCString> mMimeTypes; // UTF-8
   nsTArray<nsCString> mMimeDescriptions; // UTF-8
   nsTArray<nsCString> mExtensions; // UTF-8
   PRLibrary     *mLibrary;
@@ -73,17 +80,16 @@ public:
   bool          mIsJavaPlugin;
   bool          mIsFlashPlugin;
   nsCString     mFileName; // UTF-8
   nsCString     mFullPath; // UTF-8
   nsCString     mVersion;  // UTF-8
   int64_t       mLastModifiedTime;
   nsCOMPtr<nsITimer> mUnloadTimer;
 private:
-  uint32_t      mFlags;
   nsCString     mNiceFileName; // UTF-8
 
   void InitMime(const char* const* aMimeTypes,
                 const char* const* aMimeDescriptions,
                 const char* const* aExtensions,
                 uint32_t aVariantCount);
   nsresult EnsureMembersAreUTF8();
 };
--- a/dom/plugins/test/mochitest/test_refresh_navigator_plugins.html
+++ b/dom/plugins/test/mochitest/test_refresh_navigator_plugins.html
@@ -33,16 +33,17 @@
           tagTestPlugin = plugin;
           break;
         }
       }
       ok(tagTestPlugin, "plugin tags should have Test Plug-in");
       var mimeType = tagTestPlugin.getMimeTypes()[0];
       ok(mimeType, "should have a MIME type for Test Plug-in");
       ok(navigator.mimeTypes[mimeType.type], "navigator.mimeTypes should have an entry for '" + mimeType.type + "'");
+      ok(!tagTestPlugin.disabled, "test plugin should not be disabled");
 
       nextTest = testPart2;
       tagTestPlugin.disabled = true;
 
       function testPart2() {
         var navTestPlugin = navigator.plugins.namedItem("Test Plug-in");
         ok(!navTestPlugin, "now navigator.plugins should not have Test Plug-in");
         ok(!navigator.mimeTypes[mimeType.type], "now navigator.mimeTypes should not have an entry for '" + mimeType.type + "'");
--- a/dom/plugins/test/unit/head_plugins.js
+++ b/dom/plugins/test/unit/head_plugins.js
@@ -1,13 +1,20 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+const gIsWindows = ("@mozilla.org/windows-registry-key;1" in Cc);
+const gIsOSX = ("nsILocalFileMac" in Ci);
+const gIsLinux = ("@mozilla.org/gnome-gconf-service;1" in Cc);
+
 // Finds the test plugin library
 function get_test_plugin() {
   var pluginEnum = gDirSvc.get("APluginsDL", Ci.nsISimpleEnumerator);
   while (pluginEnum.hasMoreElements()) {
     let dir = pluginEnum.getNext().QueryInterface(Ci.nsILocalFile);
     let plugin = dir.clone();
     // OSX plugin
     plugin.append("Test.plugin");
@@ -36,16 +43,17 @@ function get_test_plugin() {
 // Finds the test nsIPluginTag
 function get_test_plugintag() {
   const Cc = Components.classes;
   const Ci = Components.interfaces;
 
   var host = Cc["@mozilla.org/plugin/host;1"].
              getService(Ci.nsIPluginHost);
   var tags = host.getPluginTags();
+
   for (var i = 0; i < tags.length; i++) {
     if (tags[i].name == "Test Plug-in")
       return tags[i];
   }
   return null;
 }
 
 // Creates a fake ProfDS directory key, copied from do_get_profile
@@ -75,8 +83,37 @@ function do_get_profile_startup() {
       }
       throw Components.results.NS_ERROR_NO_INTERFACE;
     }
   };
   dirSvc.QueryInterface(Components.interfaces.nsIDirectoryService)
         .registerProvider(provider);
   return file.clone();
 }
+
+function get_platform_specific_plugin_name() {
+  if (gIsWindows) return "nptest.dll";
+  else if (gIsOSX) return "Test.plugin";
+  else if (gIsLinux) return "libnptest.so";
+  else return null;
+}
+
+function get_platform_specific_plugin_suffix() {
+  if (gIsWindows) return ".dll";
+  else if (gIsOSX) return ".plugin";
+  else if (gIsLinux) return ".so";
+  else return null;
+}
+
+function get_test_plugin_no_symlink() {
+  let dirSvc = Cc["@mozilla.org/file/directory_service;1"]
+                .getService(Ci.nsIProperties);
+  let pluginEnum = dirSvc.get("APluginsDL", Ci.nsISimpleEnumerator);
+  while (pluginEnum.hasMoreElements()) {
+    let dir = pluginEnum.getNext().QueryInterface(Ci.nsILocalFile);
+    let plugin = dir.clone();
+    plugin.append(get_platform_specific_plugin_name());
+    if (plugin.exists()) {
+      return plugin;
+    }
+  }
+  return null;
+}
--- a/dom/plugins/test/unit/test_bug455213.js
+++ b/dom/plugins/test/unit/test_bug455213.js
@@ -1,31 +1,21 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-
-// v0.9 registry field meanings are different on Mac OS X
-const CWD = do_get_cwd();
-function checkOS(os) {
-  const nsILocalFile_ = "nsILocalFile" + os;
-  return nsILocalFile_ in Components.interfaces &&
-         CWD instanceof Components.interfaces[nsILocalFile_];
-}
-const isMac = checkOS("Mac");
+Components.utils.import("resource://gre/modules/Services.jsm");
 
 // Plugin registry uses different field delimeters on different platforms
 var DELIM = ":";
 if ("@mozilla.org/windows-registry-key;1" in Components.classes)
   DELIM = "|";
 
-var gProfD = do_get_profile();
+var gProfD = do_get_profile_startup();
 var gDirSvc = Cc["@mozilla.org/file/directory_service;1"].
              getService(Ci.nsIProperties);
 
 // Writes out some plugin registry to the profile
 function write_registry(version, info) {
   var header = "Generated File. Do not edit.\n\n";
   header += "[HEADER]\n";
   header += "Version" + DELIM + version + DELIM + "$\n\n";
@@ -44,23 +34,26 @@ function write_registry(version, info) {
   os.init(foStream, charset, 0, 0x0000);
 
   os.writeString(header);
   os.writeString(info);
   os.close();
 }
 
 function run_test() {
+  var plugin = get_test_plugintag();
+  do_check_true(plugin == null);
+
   var file = get_test_plugin();
   if (!file)
     do_throw("Plugin library not found");
 
   // Write out a 0.9 version registry that marks the test plugin as disabled
   var registry = "";
-  if (isMac) {
+  if (gIsOSX) {
     registry += file.leafName + DELIM + "$\n";
     registry += file.path + DELIM + "$\n";
   } else {
     registry += file.path + DELIM + "$\n";
     registry += DELIM + "$\n";
   }
   registry += file.lastModifiedTime + DELIM + "0" + DELIM + "0" + DELIM + "$\n";
   registry += "Plug-in for testing purposes.\u2122 " + 
@@ -69,23 +62,29 @@ function run_test() {
                 "\u0627\u0644\u0639\u0631\u0628\u064a\u0629)" +
                 DELIM + "$\n";
   registry += "Test Plug-in" + DELIM + "$\n";
   registry += "1\n";
   registry += "0" + DELIM + "application/x-test" + DELIM + "Test mimetype" +
               DELIM + "tst" + DELIM + "$\n";
   write_registry("0.9", registry);
 
-  var plugin = get_test_plugintag();
+  // Initialise profile folder
+  do_get_profile();
+
+  plugin = get_test_plugintag();
   if (!plugin)
     do_throw("Plugin tag not found");
 
   // If the plugin was not rescanned then this version will not be correct
   do_check_eq(plugin.version, "1.0.0.0");
   do_check_eq(plugin.description,
               "Plug-in for testing purposes.\u2122 " + 
                 "(\u0939\u093f\u0928\u094d\u0926\u0940 " + 
                 "\u4e2d\u6587 " +
                 "\u0627\u0644\u0639\u0631\u0628\u064a\u0629)");
   // If the plugin registry was not read then the plugin will not be disabled
   do_check_true(plugin.disabled);
   do_check_false(plugin.blocklisted);
+
+  // Clean up
+  Services.prefs.clearUserPref("plugin.importedState");
 }
--- a/dom/plugins/test/unit/test_bug471245.js
+++ b/dom/plugins/test/unit/test_bug471245.js
@@ -1,20 +1,22 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
+Components.utils.import("resource://gre/modules/Services.jsm");
 
 function run_test() {
   do_get_profile_startup();
 
   var plugin = get_test_plugintag();
   do_check_true(plugin == null);
 
   // Initialises a profile folder
   do_get_profile();
 
   var plugin = get_test_plugintag();
   do_check_false(plugin == null);
+
+  // Clean up
+  Services.prefs.clearUserPref("plugin.importedState");
 }
--- a/dom/plugins/test/unit/test_bug813245.js
+++ b/dom/plugins/test/unit/test_bug813245.js
@@ -1,24 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-
-// v0.9+ registry field meanings are different on Mac OS X
-const CWD = do_get_cwd();
-function checkOS(os) {
-  const nsILocalFile_ = "nsILocalFile" + os;
-  return nsILocalFile_ in Components.interfaces &&
-         CWD instanceof Components.interfaces[nsILocalFile_];
-}
-const isMac = checkOS("Mac");
+Components.utils.import("resource://gre/modules/Services.jsm");
 
 // Plugin registry uses different field delimeters on different platforms
 var DELIM = ":";
 if ("@mozilla.org/windows-registry-key;1" in Components.classes)
   DELIM = "|";
 
 var gProfD = do_get_profile_startup();
 var gDirSvc = Cc["@mozilla.org/file/directory_service;1"].
@@ -59,17 +49,17 @@ function run_test() {
   var file = get_test_plugin();
   if (!file) {
     do_throw("Plugin library not found");
   }
 
   // write plugin registry data
   let registry = "";
 
-  if (isMac) {
+  if (gIsOSX) {
     registry += file.leafName + DELIM + "$\n";
     registry += file.path + DELIM + "$\n";
   } else {
     registry += file.path + DELIM + "$\n";
     registry += DELIM + "$\n";
   }
   registry += "0.0.0.0" + DELIM + "$\n";
   registry += "16725225600" + DELIM + "0" + DELIM + "5" + DELIM + "$\n";
@@ -89,9 +79,12 @@ function run_test() {
 
   var plugin = get_test_plugintag();
   if (!plugin)
     do_throw("Plugin tag not found");
 
   // The plugin registry should have been rejected.
   // If not, the test plugin version would be 0.0.0.0
   do_check_eq(plugin.version, "1.0.0.0");
+
+  // Clean up
+  Services.prefs.clearUserPref("plugin.importedState");
 }
--- a/dom/plugins/test/unit/test_nice_plugin_name.js
+++ b/dom/plugins/test/unit/test_nice_plugin_name.js
@@ -1,19 +1,18 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
 const XULAPPINFO_CONTRACTID = "@mozilla.org/xre/app-info;1";
 const XULAPPINFO_CID = Components.ID("{c763b610-9d49-455a-bbd2-ede71682a1ac}");
 
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+Components.utils.import("resource://gre/modules/Services.jsm");
 
 let gAppInfo = null;
 
 function createAppInfo(id, name, version, platformVersion) {
   gAppInfo = {
     // nsIXULAppInfo
     vendor: "Mozilla",
     name: name,
@@ -55,70 +54,40 @@ function createAppInfo(id, name, version
   let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
   registrar.registerFactory(XULAPPINFO_CID, "XULAppInfo",
                             XULAPPINFO_CONTRACTID, XULAppInfoFactory);
 }
 
 let gDirSvc = Cc["@mozilla.org/file/directory_service;1"]
                 .getService(Ci.nsIProperties);
 
-function get_test_plugin_no_symlink() {
-  let pluginEnum = gDirSvc.get("APluginsDL", Ci.nsISimpleEnumerator);
-  while (pluginEnum.hasMoreElements()) {
-    let dir = pluginEnum.getNext().QueryInterface(Ci.nsILocalFile);
-    let plugin = dir.clone();
-    plugin.append(get_platform_specific_plugin_name());
-    if (plugin.exists()) {
-      return plugin;
-    }
-  }
-  return null;
-}
-
 let gPluginHost = null;
 let gIsWindows = null;
 let gIsOSX = null;
 let gIsLinux = null;
 
-function get_platform_specific_plugin_name() {
-  if (gIsWindows) return "nptest.dll";
-  else if (gIsOSX) return "Test.plugin";
-  else if (gIsLinux) return "libnptest.so";
-  else return null;
-}
-
-function get_platform_specific_plugin_suffix() {
-  if (gIsWindows) return ".dll";
-  else if (gIsOSX) return ".plugin";
-  else if (gIsLinux) return ".so";
-  else return null;
-}
-
 function test_expected_permission_string(aPermString) {
   gPluginHost.reloadPlugins(false);
   let plugin = get_test_plugintag();
   do_check_false(plugin == null);
   do_check_eq(gPluginHost.getPermissionStringForType("application/x-test"),
               aPermString);
 }
 
 function run_test() {
-  gIsWindows = ("@mozilla.org/windows-registry-key;1" in Cc);
-  gIsOSX = ("nsILocalFileMac" in Ci);
-  gIsLinux = ("@mozilla.org/gnome-gconf-service;1" in Cc);
   do_check_true(gIsWindows || gIsOSX || gIsLinux);
   do_check_true(!(gIsWindows && gIsOSX) && !(gIsWindows && gIsLinux) &&
                 !(gIsOSX && gIsLinux));
 
   createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9");
   gPluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
 
   let expectedDefaultPermissionString = null;
   if (gIsWindows) expectedDefaultPermissionString = "plugin:nptest";
-  if (gIsOSX) expectedDefaultPermissionString = "plugin:Test";
+  if (gIsOSX) expectedDefaultPermissionString = "plugin:test";
   if (gIsLinux) expectedDefaultPermissionString = "plugin:libnptest";
   test_expected_permission_string(expectedDefaultPermissionString);
 
   let suffix = get_platform_specific_plugin_suffix();
   let pluginFile = get_test_plugin_no_symlink();
   let pluginDir = pluginFile.parent;
   pluginFile.copyTo(null, "npblah235" + suffix);
   let pluginCopy = pluginDir.clone();
@@ -130,18 +99,21 @@ function run_test() {
   test_expected_permission_string("plugin:npasdf");
 
   pluginCopy.moveTo(null, "npasdf_##29387!{}{[][" + suffix);
   test_expected_permission_string("plugin:npasdf");
 
   pluginCopy.moveTo(null, "npqtplugin7" + suffix);
   test_expected_permission_string("plugin:npqtplugin");
 
-  pluginCopy.moveTo(null, "npfoo3d" + suffix);
+  pluginCopy.moveTo(null, "npFoo3d" + suffix);
   test_expected_permission_string("plugin:npfoo3d");
 
   pluginCopy.moveTo(null, "NPSWF32_11_5_502_146" + suffix);
-  test_expected_permission_string("plugin:NPSWF");
+  test_expected_permission_string("plugin:npswf");
 
   pluginCopy.remove(true);
   pluginFile.moveTo(pluginDir, null);
   test_expected_permission_string(expectedDefaultPermissionString);
+
+  // Clean up
+  Services.prefs.clearUserPref("plugin.importedState");
 }
new file mode 100644
--- /dev/null
+++ b/dom/plugins/test/unit/test_persist_in_prefs.js
@@ -0,0 +1,129 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+Components.utils.import("resource://gre/modules/Services.jsm");
+
+// Plugin registry uses different field delimeters on different platforms
+let DELIM = ":";
+if ("@mozilla.org/windows-registry-key;1" in Components.classes)
+  DELIM = "|";
+
+let gProfD = do_get_profile_startup();
+let gDirSvc = Cc["@mozilla.org/file/directory_service;1"].
+             getService(Ci.nsIProperties);
+
+// Writes out some plugin registry to the profile
+function write_registry(version, info) {
+  let runtime = Cc["@mozilla.org/xre/runtime;1"].getService(Ci.nsIXULRuntime);
+
+  let header = "Generated File. Do not edit.\n\n";
+  header += "[HEADER]\n";
+  header += "Version" + DELIM + version + DELIM + "$\n";
+  header += "Arch" + DELIM + runtime.XPCOMABI + DELIM + "$\n";
+  header += "\n";
+  header += "[PLUGINS]\n";
+
+  let registry = gProfD.clone();
+  registry.append("pluginreg.dat");
+  let foStream = Components.classes["@mozilla.org/network/file-output-stream;1"]
+                           .createInstance(Components.interfaces.nsIFileOutputStream);
+  // write, create, truncate
+  foStream.init(registry, 0x02 | 0x08 | 0x20, 0666, 0);
+
+  let charset = "UTF-8"; // Can be any character encoding name that Mozilla supports
+  let os = Cc["@mozilla.org/intl/converter-output-stream;1"].
+           createInstance(Ci.nsIConverterOutputStream);
+  os.init(foStream, charset, 0, 0x0000);
+
+  os.writeString(header);
+  os.writeString(info);
+  os.close();
+}
+
+function run_test() {
+  do_check_true(gIsWindows || gIsOSX || gIsLinux);
+
+  let file = get_test_plugin_no_symlink();
+  if (!file)
+    do_throw("Plugin library not found");
+
+  const pluginDir = file.parent;
+  const parentDir = pluginDir.parent;
+  const suffix = get_platform_specific_plugin_suffix();
+  const pluginName = file.leafName.substring(0, file.leafName.length - suffix.length).toLowerCase();
+  const pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
+  const statePref = "plugin.state." + pluginName;
+  const blocklistedPref = "plugin.blocklisted." + pluginName;
+
+  // write plugin registry data
+  let registry = "";
+
+  registry += file.leafName + DELIM + "$\n";
+  registry += file.path + DELIM + "$\n";
+  registry += "1.0.0.0" + DELIM + "$\n";
+  registry += file.lastModifiedTime + DELIM + "0" + DELIM + "0" + DELIM + "$\n";
+  registry += "Plug-in for testing purposes." + DELIM + "$\n";
+  registry += "Test Plug-in" + DELIM + "$\n";
+  registry += "1\n";
+  registry += "0" + DELIM + "application/x-test" + DELIM + "Test mimetype" + DELIM + "tst" + DELIM + "$\n";
+
+  registry += "\n";
+  registry += "[INVALID]\n";
+  registry += "\n";
+  write_registry("0.15", registry);
+
+  // Initialise profile folder
+  do_get_profile();
+
+  let plugin = get_test_plugintag();
+  if (!plugin)
+    do_throw("Plugin tag not found");
+
+  // check that the expected plugin state was loaded correctly from the registry
+  do_check_true(plugin.disabled);
+  do_check_false(plugin.blocklisted);
+  do_check_false(plugin.clicktoplay);
+  // ... and imported into prefs, with 0 being the disabled state
+  do_check_eq(0, Services.prefs.getIntPref(statePref));
+
+  // prepare a copy of the plugin and backup the original
+  file.copyTo(null, "nptestcopy" + suffix);
+  let copy = pluginDir.clone();
+  copy.append("nptestcopy" + suffix);
+  file.moveTo(parentDir, null);
+
+  // test that the settings persist through a few variations of test-plugin names
+  let testNames = [
+    pluginName + "2",
+    pluginName.toUpperCase() + "_11_5_42_2323",
+    pluginName + "-5.2.7"
+  ];
+  testNames.forEach(function(leafName) {
+    dump("Checking " + leafName + ".\n");
+    copy.moveTo(null, leafName + suffix);
+    pluginHost.reloadPlugins(false);
+    plugin = get_test_plugintag();
+    do_check_false(plugin == null);
+    do_check_true(plugin.disabled);
+    do_check_false(plugin.clicktoplay);
+  });
+
+  // check that the state persists even if the plugin is not always present
+  copy.moveTo(parentDir, null);
+  pluginHost.reloadPlugins(false);
+  copy.moveTo(pluginDir, null);
+  pluginHost.reloadPlugins(false);
+
+  plugin = get_test_plugintag();
+  do_check_false(plugin == null);
+  do_check_true(plugin.disabled);
+  do_check_false(plugin.clicktoplay);
+
+  // clean up
+  Services.prefs.clearUserPref(statePref);
+  Services.prefs.clearUserPref("plugin.importedState");
+  copy.remove(true);
+  file.moveTo(pluginDir, null);
+}
--- a/dom/plugins/test/unit/xpcshell.ini
+++ b/dom/plugins/test/unit/xpcshell.ini
@@ -7,8 +7,11 @@ tail =
 fail-if = os == "android"
 [test_bug471245.js]
 # Bug 676953: test fails consistently on Android
 fail-if = os == "android"
 [test_bug813245.js]
 # Bug 676953: test fails consistently on Android
 fail-if = os == "android"
 [test_nice_plugin_name.js]
+# Bug 676953: test fails consistently on Android
+fail-if = os == "android"
+[test_persist_in_prefs.js]
--- a/dom/tests/mochitest/dom-level0/innerWidthHeight_script.html
+++ b/dom/tests/mochitest/dom-level0/innerWidthHeight_script.html
@@ -1,20 +1,21 @@
 <!DOCTYPE html>
 <html>
 <head>
+  <meta name="viewport" content="width=320,height=320" />
   <title>Bug 602580 - Test getting and setting innerWidth and Height after using setCSSViewport</title>
   <script class="testbody" type="text/javascript">
   function runSubTest()
   {
     // get ability to set innerWidth and height without setting a pref
     netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
 
-    // Firefox doesn't support the metaviewport tag, so we force a css viewport
-    // here using nsIDomWindowUtils
+    // Firefox doesn't support the metaviewport tag on desktop, so we force
+    // css viewport here using nsIDomWindowUtils
     var cwu = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
                      getInterface(Components.interfaces.nsIDOMWindowUtils);
     cwu.setCSSViewport(320, 320);
 
     var oldWidth = window.innerWidth;
     var oldHeight = window.innerHeight;
 
     /* Test that return values are now from viewport */
--- a/dom/tests/mochitest/dom-level2-core/Makefile.in
+++ b/dom/tests/mochitest/dom-level2-core/Makefile.in
@@ -160,18 +160,16 @@ MOCHITEST_FILES_D	= \
 		test_hasAttribute02.html \
 		test_hasAttribute03.html \
 		test_hasAttribute04.html \
 		test_hasAttributeNS01.html \
 		test_hasAttributeNS02.html \
 		test_hasAttributeNS03.html \
 		test_hasAttributeNS04.html \
 		test_hasAttributeNS05.html \
-		test_hasAttributes01.html \
-		test_hasAttributes02.html \
 		test_hc_namednodemapinvalidtype1.html \
 		test_hc_nodedocumentfragmentnormalize1.html \
 		test_hc_nodedocumentfragmentnormalize2.html \
 		test_importNode01.html \
 		test_importNode02.html \
 		test_importNode03.html \
 		test_importNode04.html \
 		test_importNode05.html \
@@ -225,20 +223,16 @@ MOCHITEST_FILES_E	= \
 		test_namespaceURI02.html \
 		test_namespaceURI03.html \
 		test_namespaceURI04.html \
 		test_nodegetlocalname03.html \
 		test_nodegetnamespaceuri03.html \
 		test_nodegetownerdocument01.html \
 		test_nodegetownerdocument02.html \
 		test_nodegetprefix03.html \
-		test_nodehasattributes01.html \
-		test_nodehasattributes02.html \
-		test_nodehasattributes03.html \
-		test_nodehasattributes04.html \
 		$(NULL)
 
 MOCHITEST_FILES_F	= \
 		test_nodenormalize01.html \
 		test_normalize01.html \
 		test_ownerDocument01.html \
 		test_ownerElement01.html \
 		test_ownerElement02.html \
deleted file mode 100644
--- a/dom/tests/mochitest/dom-level2-core/test_hasAttributes01.html
+++ /dev/null
@@ -1,120 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-<title>http://www.w3.org/2001/DOM-Test-Suite/level2/core/hasAttributes01</title>
-<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
-<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-<script type="text/javascript" src="DOMTestCase.js"></script>
-<script type="text/javascript" src="exclusions.js"></script>
-<script type="text/javascript">
-// expose test function names
-function exposeTestFunctionNames()
-{
-return ['hasAttributes01'];
-}
-
-var docsLoaded = -1000000;
-var builder = null;
-
-//
-//   This function is called by the testing framework before
-//      running the test suite.
-//
-//   If there are no configuration exceptions, asynchronous
-//        document loading is started.  Otherwise, the status
-//        is set to complete and the exception is immediately
-//        raised when entering the body of the test.
-//
-function setUpPage() {
-   setUpPageStatus = 'running';
-   try {
-     //
-     //   creates test document builder, may throw exception
-     //
-     builder = createConfiguredBuilder();
-
-      docsLoaded = 0;
-      
-      var docRef = null;
-      if (typeof(this.doc) != 'undefined') {
-        docRef = this.doc;
-      }
-      docsLoaded += preload(docRef, "doc", "staff");
-        
-       if (docsLoaded == 1) {
-          setUpPage = 'complete';
-       }
-    } catch(ex) {
-    	catchInitializationError(builder, ex);
-        setUpPage = 'complete';
-    }
-}
-
-//
-//   This method is called on the completion of 
-//      each asychronous load started in setUpTests.
-//
-//   When every synchronous loaded document has completed,
-//      the page status is changed which allows the
-//      body of the test to be executed.
-function loadComplete() {
-  if (++docsLoaded == 1) {
-    setUpPageStatus = 'complete';
-    runJSUnitTests();
-    markTodos();
-    SimpleTest.finish();
-  }
-}
-
-var docName = 'hasAttributes01';
-
-
-/**
-* 
-    The "hasAttributes()" method for a node should 
-    return false if the node does not have an attribute. 
-
-    Retrieve the first "name" node and invoke the "hasAttributes()" method.
-    The method should return false since the node does not have an attribute.
-
-* @author NIST
-* @author Mary Brady
-* @see http://www.w3.org/TR/DOM-Level-2-Core/core#ID-NodeHasAttrs
-*/
-function hasAttributes01() {
-   var success;
-    if(checkInitialization(builder, "hasAttributes01") != null) return;
-    var doc;
-      var addrList;
-      var addrNode;
-      var state;
-      
-      var docRef = null;
-      if (typeof(this.doc) != 'undefined') {
-        docRef = this.doc;
-      }
-      doc = load(docRef, "doc", "staff");
-      addrList = doc.getElementsByTagName("name");
-      addrNode = addrList.item(0);
-      state = addrNode.hasAttributes();
-      assertFalse("throw_False",state);
-
-}
-
-</script>
-</head>
-<body>
-<h2>Test http://www.w3.org/2001/DOM-Test-Suite/level2/core/hasAttributes01</h2>
-<p></p>
-<p>
-Copyright (c) 2001-2004 World Wide Web Consortium, 
-(Massachusetts Institute of Technology, European Research Consortium 
-for Informatics and Mathematics, Keio University). All 
-Rights Reserved. This work is distributed under the <a href="http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231">W3C(r) Software License</a> in the 
-hope that it will be useful, but WITHOUT ANY WARRANTY; without even 
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
-</p>
-</body>
-</html>
deleted file mode 100644
--- a/dom/tests/mochitest/dom-level2-core/test_hasAttributes02.html
+++ /dev/null
@@ -1,120 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-<title>http://www.w3.org/2001/DOM-Test-Suite/level2/core/hasAttributes02</title>
-<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
-<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-<script type="text/javascript" src="DOMTestCase.js"></script>
-<script type="text/javascript" src="exclusions.js"></script>
-<script type="text/javascript">
-// expose test function names
-function exposeTestFunctionNames()
-{
-return ['hasAttributes02'];
-}
-
-var docsLoaded = -1000000;
-var builder = null;
-
-//
-//   This function is called by the testing framework before
-//      running the test suite.
-//
-//   If there are no configuration exceptions, asynchronous
-//        document loading is started.  Otherwise, the status
-//        is set to complete and the exception is immediately
-//        raised when entering the body of the test.
-//
-function setUpPage() {
-   setUpPageStatus = 'running';
-   try {
-     //
-     //   creates test document builder, may throw exception
-     //
-     builder = createConfiguredBuilder();
-
-      docsLoaded = 0;
-      
-      var docRef = null;
-      if (typeof(this.doc) != 'undefined') {
-        docRef = this.doc;
-      }
-      docsLoaded += preload(docRef, "doc", "staff");
-        
-       if (docsLoaded == 1) {
-          setUpPage = 'complete';
-       }
-    } catch(ex) {
-    	catchInitializationError(builder, ex);
-        setUpPage = 'complete';
-    }
-}
-
-//
-//   This method is called on the completion of 
-//      each asychronous load started in setUpTests.
-//
-//   When every synchronous loaded document has completed,
-//      the page status is changed which allows the
-//      body of the test to be executed.
-function loadComplete() {
-  if (++docsLoaded == 1) {
-    setUpPageStatus = 'complete';
-    runJSUnitTests();
-    markTodos();
-    SimpleTest.finish();
-  }
-}
-
-var docName = 'hasAttributes02';
-
-
-/**
-* 
-    The "hasAttributes()" method for a node should 
-    return true if the node has attributes. 
-
-    Retrieve the first address node and the "hasAttributes()" method
-    should return true since the node has "domestic" as an attribute.
-
-* @author NIST
-* @author Mary Brady
-* @see http://www.w3.org/TR/DOM-Level-2-Core/core#ID-NodeHasAttrs
-*/
-function hasAttributes02() {
-   var success;
-    if(checkInitialization(builder, "hasAttributes02") != null) return;
-    var doc;
-      var addrList;
-      var addrNode;
-      var state;
-      
-      var docRef = null;
-      if (typeof(this.doc) != 'undefined') {
-        docRef = this.doc;
-      }
-      doc = load(docRef, "doc", "staff");
-      addrList = doc.getElementsByTagName("address");
-      addrNode = addrList.item(0);
-      state = addrNode.hasAttributes();
-      assertTrue("throw_True",state);
-
-}
-
-</script>
-</head>
-<body>
-<h2>Test http://www.w3.org/2001/DOM-Test-Suite/level2/core/hasAttributes02</h2>
-<p></p>
-<p>
-Copyright (c) 2001-2004 World Wide Web Consortium, 
-(Massachusetts Institute of Technology, European Research Consortium 
-for Informatics and Mathematics, Keio University). All 
-Rights Reserved. This work is distributed under the <a href="http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231">W3C(r) Software License</a> in the 
-hope that it will be useful, but WITHOUT ANY WARRANTY; without even 
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
-</p>
-</body>
-</html>
deleted file mode 100644
--- a/dom/tests/mochitest/dom-level2-core/test_nodehasattributes01.html
+++ /dev/null
@@ -1,123 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-<title>http://www.w3.org/2001/DOM-Test-Suite/level2/core/nodehasattributes01</title>
-<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
-<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-<script type="text/javascript" src="DOMTestCase.js"></script>
-<script type="text/javascript" src="exclusions.js"></script>
-<script type="text/javascript">
-// expose test function names
-function exposeTestFunctionNames()
-{
-return ['nodehasattributes01'];
-}
-
-var docsLoaded = -1000000;
-var builder = null;
-
-//
-//   This function is called by the testing framework before
-//      running the test suite.
-//
-//   If there are no configuration exceptions, asynchronous
-//        document loading is started.  Otherwise, the status
-//        is set to complete and the exception is immediately
-//        raised when entering the body of the test.
-//
-function setUpPage() {
-   setUpPageStatus = 'running';
-   try {
-     //
-     //   creates test document builder, may throw exception
-     //
-     builder = createConfiguredBuilder();
-
-      docsLoaded = 0;
-      
-      var docRef = null;
-      if (typeof(this.doc) != 'undefined') {
-        docRef = this.doc;
-      }
-      docsLoaded += preload(docRef, "doc", "staff");
-        
-       if (docsLoaded == 1) {
-          setUpPage = 'complete';
-       }
-    } catch(ex) {
-    	catchInitializationError(builder, ex);
-        setUpPage = 'complete';
-    }
-}
-
-//
-//   This method is called on the completion of 
-//      each asychronous load started in setUpTests.
-//
-//   When every synchronous loaded document has completed,
-//      the page status is changed which allows the
-//      body of the test to be executed.
-function loadComplete() {
-  if (++docsLoaded == 1) {
-    setUpPageStatus = 'complete';
-    runJSUnitTests();
-    markTodos();
-    SimpleTest.finish();
-  }
-}
-
-var docName = 'nodehasattributes01';
-
-
-/**
-* 
-	The method hasAttributes returns whether this node (if it is an element) has any attributes.
-
-	Retreive an element node without attributes.  Verify if hasAttributes returns false.
-	Retreive another element node with attributes.  Verify if hasAttributes returns true.	
-
-* @author IBM
-* @author Neil Delima
-* @see http://www.w3.org/TR/DOM-Level-2-Core/core#ID-NodeHasAttrs
-*/
-function nodehasattributes01() {
-   var success;
-    if(checkInitialization(builder, "nodehasattributes01") != null) return;
-    var doc;
-      var element;
-      var elementList;
-      var hasAttributes;
-      
-      var docRef = null;
-      if (typeof(this.doc) != 'undefined') {
-        docRef = this.doc;
-      }
-      doc = load(docRef, "doc", "staff");
-      elementList = doc.getElementsByTagName("employeeId");
-      element = elementList.item(0);
-      hasAttributes = element.hasAttributes();
-      assertFalse("employeeIdHasAttributesFalse",hasAttributes);
-elementList = doc.getElementsByTagName("address");
-      element = elementList.item(0);
-      hasAttributes = element.hasAttributes();
-      assertTrue("addressHasAttributesTrue",hasAttributes);
-
-}
-
-</script>
-</head>
-<body>
-<h2>Test http://www.w3.org/2001/DOM-Test-Suite/level2/core/nodehasattributes01</h2>
-<p></p>
-<p>
-Copyright (c) 2001-2004 World Wide Web Consortium, 
-(Massachusetts Institute of Technology, European Research Consortium 
-for Informatics and Mathematics, Keio University). All 
-Rights Reserved. This work is distributed under the <a href="http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231">W3C(r) Software License</a> in the 
-hope that it will be useful, but WITHOUT ANY WARRANTY; without even 
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
-</p>
-</body>
-</html>
deleted file mode 100644
--- a/dom/tests/mochitest/dom-level2-core/test_nodehasattributes02.html
+++ /dev/null
@@ -1,118 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-<title>http://www.w3.org/2001/DOM-Test-Suite/level2/core/nodehasattributes02</title>
-<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
-<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-<script type="text/javascript" src="DOMTestCase.js"></script>
-<script type="text/javascript" src="exclusions.js"></script>
-<script type="text/javascript">
-// expose test function names
-function exposeTestFunctionNames()
-{
-return ['nodehasattributes02'];
-}
-
-var docsLoaded = -1000000;
-var builder = null;
-
-//
-//   This function is called by the testing framework before
-//      running the test suite.
-//
-//   If there are no configuration exceptions, asynchronous
-//        document loading is started.  Otherwise, the status
-//        is set to complete and the exception is immediately
-//        raised when entering the body of the test.
-//
-function setUpPage() {
-   setUpPageStatus = 'running';
-   try {
-     //
-     //   creates test document builder, may throw exception
-     //
-     builder = createConfiguredBuilder();
-
-      docsLoaded = 0;
-      
-      var docRef = null;
-      if (typeof(this.doc) != 'undefined') {
-        docRef = this.doc;
-      }
-      docsLoaded += preload(docRef, "doc", "staffNS");
-        
-       if (docsLoaded == 1) {
-          setUpPage = 'complete';
-       }
-    } catch(ex) {
-    	catchInitializationError(builder, ex);
-        setUpPage = 'complete';
-    }
-}
-
-//
-//   This method is called on the completion of 
-//      each asychronous load started in setUpTests.
-//
-//   When every synchronous loaded document has completed,
-//      the page status is changed which allows the
-//      body of the test to be executed.
-function loadComplete() {
-  if (++docsLoaded == 1) {
-    setUpPageStatus = 'complete';
-    runJSUnitTests();
-    markTodos();
-    SimpleTest.finish();
-  }
-}
-
-var docName = 'nodehasattributes02';
-
-
-/**
-* 
-	The method hasAttributes returns whether this node (if it is an element) has any attributes.
-
-	Retrieve the docType node.	 Since this is not an element node check if hasAttributes returns
-	null.
-
-* @author IBM
-* @author Neil Delima
-* @see http://www.w3.org/TR/DOM-Level-2-Core/core#ID-NodeHasAttrs
-*/
-function nodehasattributes02() {
-   var success;
-    if(checkInitialization(builder, "nodehasattributes02") != null) return;
-    var doc;
-      var docType;
-      var hasAttributes;
-      
-      var docRef = null;
-      if (typeof(this.doc) != 'undefined') {
-        docRef = this.doc;
-      }
-      doc = load(docRef, "doc", "staffNS");
-      docType = doc.doctype;
-
-      hasAttributes = docType.hasAttributes();
-      assertFalse("nodehasattributes02",hasAttributes);
-
-}
-
-</script>
-</head>
-<body>
-<h2>Test http://www.w3.org/2001/DOM-Test-Suite/level2/core/nodehasattributes02</h2>
-<p></p>
-<p>
-Copyright (c) 2001-2004 World Wide Web Consortium, 
-(Massachusetts Institute of Technology, European Research Consortium 
-for Informatics and Mathematics, Keio University). All 
-Rights Reserved. This work is distributed under the <a href="http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231">W3C(r) Software License</a> in the 
-hope that it will be useful, but WITHOUT ANY WARRANTY; without even 
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
-</p>
-</body>
-</html>
deleted file mode 100644
--- a/dom/tests/mochitest/dom-level2-core/test_nodehasattributes03.html
+++ /dev/null
@@ -1,119 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-<title>http://www.w3.org/2001/DOM-Test-Suite/level2/core/nodehasattributes03</title>
-<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
-<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-<script type="text/javascript" src="DOMTestCase.js"></script>
-<script type="text/javascript" src="exclusions.js"></script>
-<script type="text/javascript">
-// expose test function names
-function exposeTestFunctionNames()
-{
-return ['nodehasattributes03'];
-}
-
-var docsLoaded = -1000000;
-var builder = null;
-
-//
-//   This function is called by the testing framework before
-//      running the test suite.
-//
-//   If there are no configuration exceptions, asynchronous
-//        document loading is started.  Otherwise, the status
-//        is set to complete and the exception is immediately
-//        raised when entering the body of the test.
-//
-function setUpPage() {
-   setUpPageStatus = 'running';
-   try {
-     //
-     //   creates test document builder, may throw exception
-     //
-     builder = createConfiguredBuilder();
-
-      docsLoaded = 0;
-      
-      var docRef = null;
-      if (typeof(this.doc) != 'undefined') {
-        docRef = this.doc;
-      }
-      docsLoaded += preload(docRef, "doc", "staffNS");
-        
-       if (docsLoaded == 1) {
-          setUpPage = 'complete';
-       }
-    } catch(ex) {
-    	catchInitializationError(builder, ex);
-        setUpPage = 'complete';
-    }
-}
-
-//
-//   This method is called on the completion of 
-//      each asychronous load started in setUpTests.
-//
-//   When every synchronous loaded document has completed,
-//      the page status is changed which allows the
-//      body of the test to be executed.
-function loadComplete() {
-  if (++docsLoaded == 1) {
-    setUpPageStatus = 'complete';
-    runJSUnitTests();
-    markTodos();
-    SimpleTest.finish();
-  }
-}
-
-var docName = 'nodehasattributes03';
-
-
-/**
-* 
-	The method hasAttributes returns whether this node (if it is an element) has any attributes.
-
-	Retreive an element node with a default attributes.  Verify if hasAttributes returns true.
-
-* @author IBM
-* @author Neil Delima
-* @see http://www.w3.org/TR/DOM-Level-2-Core/core#ID-NodeHasAttrs
-*/
-function nodehasattributes03() {
-   var success;
-    if(checkInitialization(builder, "nodehasattributes03") != null) return;
-    var doc;
-      var element;
-      var elementList;
-      var hasAttributes;
-      
-      var docRef = null;
-      if (typeof(this.doc) != 'undefined') {
-        docRef = this.doc;
-      }
-      doc = load(docRef, "doc", "staffNS");
-      elementList = doc.getElementsByTagName("emp:employee");
-      element = elementList.item(0);
-      assertNotNull("empEmployeeNotNull",element);
-hasAttributes = element.hasAttributes();
-      assertTrue("hasAttributes",hasAttributes);
-
-}
-
-</script>
-</head>
-<body>
-<h2>Test http://www.w3.org/2001/DOM-Test-Suite/level2/core/nodehasattributes03</h2>
-<p></p>
-<p>
-Copyright (c) 2001-2004 World Wide Web Consortium, 
-(Massachusetts Institute of Technology, European Research Consortium 
-for Informatics and Mathematics, Keio University). All 
-Rights Reserved. This work is distributed under the <a href="http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231">W3C(r) Software License</a> in the 
-hope that it will be useful, but WITHOUT ANY WARRANTY; without even 
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
-</p>
-</body>
-</html>
deleted file mode 100644
--- a/dom/tests/mochitest/dom-level2-core/test_nodehasattributes04.html
+++ /dev/null
@@ -1,138 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-<title>http://www.w3.org/2001/DOM-Test-Suite/level2/core/nodehasattributes04</title>
-<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
-<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-<script type="text/javascript" src="DOMTestCase.js"></script>
-<script type="text/javascript" src="exclusions.js"></script>
-<script type="text/javascript">
-// expose test function names
-function exposeTestFunctionNames()
-{
-return ['nodehasattributes04'];
-}
-
-var docsLoaded = -1000000;
-var builder = null;
-
-//
-//   This function is called by the testing framework before
-//      running the test suite.
-//
-//   If there are no configuration exceptions, asynchronous
-//        document loading is started.  Otherwise, the status
-//        is set to complete and the exception is immediately
-//        raised when entering the body of the test.
-//
-function setUpPage() {
-   setUpPageStatus = 'running';
-   try {
-     //
-     //   creates test document builder, may throw exception
-     //
-     builder = createConfiguredBuilder();
-       setImplementationAttribute("namespaceAware", true);
-
-      docsLoaded = 0;
-      
-      var docRef = null;
-      if (typeof(this.doc) != 'undefined') {
-        docRef = this.doc;
-      }
-      docsLoaded += preload(docRef, "doc", "staffNS");
-        
-       if (docsLoaded == 1) {
-          setUpPage = 'complete';
-       }
-    } catch(ex) {
-    	catchInitializationError(builder, ex);
-        setUpPage = 'complete';
-    }
-}
-
-//
-//   This method is called on the completion of 
-//      each asychronous load started in setUpTests.
-//
-//   When every synchronous loaded document has completed,
-//      the page status is changed which allows the
-//      body of the test to be executed.
-function loadComplete() {
-  if (++docsLoaded == 1) {
-    setUpPageStatus = 'complete';
-    runJSUnitTests();
-    markTodos();
-    SimpleTest.finish();
-  }
-}
-
-var docName = 'nodehasattributes04';
-
-
-/**
-* 
-	The method hasAttributes returns whether this node (if it is an element) has any attributes.
-
-	Create a new Document, Element and Attr node.  Add the Attr to the Element and append the 
-	Element to the Document.  Retreive the newly created element node from the document and check
-	if it has attributes using hasAttributes.
-
-* @author IBM
-* @author Neil Delima
-* @see http://www.w3.org/TR/DOM-Level-2-Core/core#ID-NodeHasAttrs
-*/
-function nodehasattributes04() {
-   var success;
-    if(checkInitialization(builder, "nodehasattributes04") != null) return;
-    var doc;
-      var newDoc;
-      var docType = null;
-
-      var domImpl;
-      var element;
-      var elementTest;
-      var elementDoc;
-      var attribute;
-      var setNode;
-      var appendedChild;
-      var elementList;
-      var hasAttributes;
-      
-      var docRef = null;
-      if (typeof(this.doc) != 'undefined') {
-        docRef = this.doc;
-      }
-      doc = load(docRef, "doc", "staffNS");
-      domImpl = doc.implementation;
-newDoc = domImpl.createDocument("http://www.w3.org/DOM/Test","test",docType);
-      element = newDoc.createElementNS("http://www.w3.org/DOM/Test","dom:elem");
-      attribute = newDoc.createAttribute("attr");
-      setNode = element.setAttributeNode(attribute);
-      elementDoc = newDoc.documentElement;
-
-      appendedChild = elementDoc.appendChild(element);
-      elementList = newDoc.getElementsByTagNameNS("http://www.w3.org/DOM/Test","elem");
-      elementTest = elementList.item(0);
-      hasAttributes = elementTest.hasAttributes();
-      assertTrue("nodehasattributes04",hasAttributes);
-
-}
-
-</script>
-</head>
-<body>
-<h2>Test http://www.w3.org/2001/DOM-Test-Suite/level2/core/nodehasattributes04</h2>
-<p></p>
-<p>
-Copyright (c) 2001-2004 World Wide Web Consortium, 
-(Massachusetts Institute of Technology, European Research Consortium 
-for Informatics and Mathematics, Keio University). All 
-Rights Reserved. This work is distributed under the <a href="http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231">W3C(r) Software License</a> in the 
-hope that it will be useful, but WITHOUT ANY WARRANTY; without even 
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
-</p>
-</body>
-</html>
--- a/dom/webidl/Node.webidl
+++ b/dom/webidl/Node.webidl
@@ -90,17 +90,16 @@ interface Node : EventTarget {
   // a non-nullable type.
   [Constant]
   readonly attribute DOMString? namespaceURI;
   [Constant]
   readonly attribute DOMString? prefix;
   [Constant]
   readonly attribute DOMString? localName;
 
-  boolean hasAttributes();
   [Throws, Func="nsINode::ShouldExposeUserData"]
   any setUserData(DOMString key, any data, UserDataHandler? handler);
   [Throws, Func="nsINode::ShouldExposeUserData"]
   any getUserData(DOMString key);
   [ChromeOnly]
   readonly attribute Principal nodePrincipal;
   [ChromeOnly]
   readonly attribute URI? baseURIObject;
--- a/js/src/builtin/Eval.cpp
+++ b/js/src/builtin/Eval.cpp
@@ -45,17 +45,17 @@ IsEvalCacheCandidate(RawScript script)
            script->objects()->length == 1 &&
            !script->hasRegexps();
 }
 
 /* static */ HashNumber
 EvalCacheHashPolicy::hash(const EvalCacheLookup &l)
 {
     return AddToHash(HashString(l.str->chars(), l.str->length()),
-                     l.caller,
+                     l.caller.get(),
                      l.staticLevel,
                      l.version,
                      l.compartment);
 }
 
 /* static */ bool
 EvalCacheHashPolicy::match(RawScript script, const EvalCacheLookup &l)
 {
@@ -88,20 +88,17 @@ class EvalScriptGuard
     /* These fields are only valid if lookup_.str is non-NULL. */
     EvalCacheLookup lookup_;
     EvalCache::AddPtr p_;
 
     Rooted<JSLinearString*> lookupStr_;
 
   public:
     EvalScriptGuard(JSContext *cx)
-      : cx_(cx), script_(cx), lookupStr_(cx)
-    {
-        lookup_.str = NULL;
-    }
+        : cx_(cx), script_(cx), lookup_(cx), lookupStr_(cx) {}
 
     ~EvalScriptGuard() {
         if (script_) {
             CallDestroyScriptHook(cx_->runtime->defaultFreeOp(), script_);
             script_->isActiveEval = false;
             script_->isCachedEval = true;
             lookup_.str = lookupStr_;
             if (lookup_.str && IsEvalCacheCandidate(script_))
--- a/js/src/builtin/MapObject.cpp
+++ b/js/src/builtin/MapObject.cpp
@@ -1101,22 +1101,22 @@ MapObject::construct(JSContext *cx, unsi
         while (iter.next()) {
             RootedObject pairobj(cx, js_ValueToNonNullObject(cx, iter.value()));
             if (!pairobj)
                 return false;
 
             RootedValue key(cx);
             if (!JSObject::getElement(cx, pairobj, pairobj, 0, &key))
                 return false;
+
             HashableValue hkey;
+            HashableValue::AutoRooter hkeyRoot(cx, &hkey);
             if (!hkey.setValue(cx, key))
                 return false;
 
-            HashableValue::AutoRooter hkeyRoot(cx, &hkey);
-
             RootedValue val(cx);
             if (!JSObject::getElement(cx, pairobj, pairobj, 1, &val))
                 return false;
 
             RelocatableValue rval(val);
             if (!map->put(hkey, rval)) {
                 js_ReportOutOfMemory(cx);
                 return false;
@@ -1133,16 +1133,17 @@ MapObject::construct(JSContext *cx, unsi
 bool
 MapObject::is(const Value &v)
 {
     return v.isObject() && v.toObject().hasClass(&class_) && v.toObject().getPrivate();
 }
 
 #define ARG0_KEY(cx, args, key)                                               \
     HashableValue key;                                                        \
+    HashableValue::AutoRooter keyRoot(cx, &key);                              \
     if (args.length() > 0 && !key.setValue(cx, args[0]))                      \
         return false
 
 ValueMap &
 MapObject::extract(CallReceiver call)
 {
     JS_ASSERT(call.thisv().isObject());
     JS_ASSERT(call.thisv().toObject().hasClass(&MapObject::class_));
@@ -1549,16 +1550,17 @@ SetObject::construct(JSContext *cx, unsi
     }
     obj->setPrivate(set);
 
     CallArgs args = CallArgsFromVp(argc, vp);
     if (args.hasDefined(0)) {
         ForOfIterator iter(cx, args[0]);
         while (iter.next()) {
             HashableValue key;
+            HashableValue::AutoRooter hkeyRoot(cx, &key);
             if (!key.setValue(cx, iter.value()))
                 return false;
             if (!set->put(key)) {
                 js_ReportOutOfMemory(cx);
                 return false;
             }
         }
         if (!iter.close())
--- a/js/src/builtin/TestingFunctions.cpp
+++ b/js/src/builtin/TestingFunctions.cpp
@@ -570,18 +570,18 @@ NondeterminsticGetWeakMapKeys(JSContext 
         return false;
     }
     if (!args[0].isObject()) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NOT_EXPECTED_TYPE,
                              "nondeterministicGetWeakMapKeys", "WeakMap",
                              InformalValueTypeName(args[0]));
         return false;
     }
-    JSObject *arr;
-    if (!JS_NondeterministicGetWeakMapKeys(cx, &args[0].toObject(), &arr))
+    RootedObject arr(cx);
+    if (!JS_NondeterministicGetWeakMapKeys(cx, &args[0].toObject(), arr.address()))
         return false;
     if (!arr) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NOT_EXPECTED_TYPE,
                              "nondeterministicGetWeakMapKeys", "WeakMap",
                              args[0].toObject().getClass()->name);
         return false;
     }
     args.rval().setObject(*arr);
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -6390,18 +6390,18 @@ Parser<ParseHandler>::primaryExpr(TokenK
             SET     = 0x2,
             VALUE   = 0x4 | GET | SET
         };
 
         pn = handler.newList(PNK_OBJECT, null(), JSOP_NEWINIT);
         if (!pn)
             return null();
 
+        RootedAtom atom(context);
         for (;;) {
-            JSAtom *atom;
             TokenKind ltok = tokenStream.getToken(TSF_KEYWORD_IS_NAME);
             switch (ltok) {
               case TOK_NUMBER:
                 atom = ToAtom<CanGC>(context, DoubleValue(tokenStream.currentToken().number()));
                 if (!atom)
                     return null();
                 pn3 = handler.newNumber(tokenStream.currentToken());
                 break;
deleted file mode 100644
--- a/js/src/jit-test/tests/basic/bug787283.js
+++ /dev/null
@@ -1,8 +0,0 @@
-// |jit-test| error:TypeError
-
-Object.prototype.apply = Function.prototype.apply;
-function testApplyCallHelper(f) {
-    var i = 0;
-    i.apply(this,[,,2])
-}
-testApplyCallHelper()
--- a/js/src/jsapi-tests/testGetPropertyDefault.cpp
+++ b/js/src/jsapi-tests/testGetPropertyDefault.cpp
@@ -42,21 +42,21 @@ BEGIN_TEST(testGetPropertyDefault_bug594
     }
 
     {
         // Check JS_GetPropertyByIdDefault
 
         JS::RootedObject obj(cx, JS_NewObject(cx, NULL, NULL, NULL));
         CHECK(obj);
 
-        jsid hereid;
-        CHECK(stringToId(cx, "here", &hereid));
+        JS::RootedId hereid(cx);
+        CHECK(stringToId(cx, "here", hereid.address()));
 
-        jsid nothereid;
-        CHECK(stringToId(cx, "nothere", &nothereid));
+        JS::RootedId nothereid(cx);
+        CHECK(stringToId(cx, "nothere", nothereid.address()));
 
         JS::RootedValue v0(cx, JSVAL_TRUE);
         CHECK(JS_SetPropertyById(cx, obj, hereid, v0.address()));
 
         JS::RootedValue v1(cx);
         CHECK(JS_GetPropertyByIdDefault(cx, obj, hereid, JSVAL_FALSE, v1.address()));
         CHECK(JSVAL_IS_TRUE(v1));
 
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -172,16 +172,21 @@ jsid JSID_EMPTY = { size_t(JSID_TYPE_OBJ
 
 const jsval JSVAL_NULL  = IMPL_TO_JSVAL(BUILD_JSVAL(JSVAL_TAG_NULL,      0));
 const jsval JSVAL_ZERO  = IMPL_TO_JSVAL(BUILD_JSVAL(JSVAL_TAG_INT32,     0));
 const jsval JSVAL_ONE   = IMPL_TO_JSVAL(BUILD_JSVAL(JSVAL_TAG_INT32,     1));
 const jsval JSVAL_FALSE = IMPL_TO_JSVAL(BUILD_JSVAL(JSVAL_TAG_BOOLEAN,   JS_FALSE));
 const jsval JSVAL_TRUE  = IMPL_TO_JSVAL(BUILD_JSVAL(JSVAL_TAG_BOOLEAN,   JS_TRUE));
 const jsval JSVAL_VOID  = IMPL_TO_JSVAL(BUILD_JSVAL(JSVAL_TAG_UNDEFINED, 0));
 
+const jsid voidIdValue = JSID_VOID;
+const jsid emptyIdValue = JSID_EMPTY;
+const HandleId JS::JSID_VOIDHANDLE = HandleId::fromMarkedLocation(&voidIdValue);
+const HandleId JS::JSID_EMPTYHANDLE = HandleId::fromMarkedLocation(&emptyIdValue);
+
 /* Make sure that jschar is two bytes unsigned integer */
 JS_STATIC_ASSERT((jschar)-1 > 0);
 JS_STATIC_ASSERT(sizeof(jschar) == 2);
 
 JS_PUBLIC_API(int64_t)
 JS_Now()
 {
     return PRMJ_Now();
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -4948,16 +4948,23 @@ JS_EncodeInterpretedFunction(JSContext *
 extern JS_PUBLIC_API(JSScript *)
 JS_DecodeScript(JSContext *cx, const void *data, uint32_t length,
                 JSPrincipals *principals, JSPrincipals *originPrincipals);
 
 extern JS_PUBLIC_API(JSObject *)
 JS_DecodeInterpretedFunction(JSContext *cx, const void *data, uint32_t length,
                              JSPrincipals *principals, JSPrincipals *originPrincipals);
 
+namespace JS {
+
+extern JS_PUBLIC_DATA(const HandleId) JSID_VOIDHANDLE;
+extern JS_PUBLIC_DATA(const HandleId) JSID_EMPTYHANDLE;
+
+};
+
 namespace js {
 
 /*
  * Import some JS:: names into the js namespace so we can make unqualified
  * references to them.
  */
 
 using JS::Value;
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -490,18 +490,18 @@ array_length_setter(JSContext *cx, Handl
          * bug 322135.
          */
         RootedObject iter(cx, JS_NewPropertyIterator(cx, obj));
         if (!iter)
             return false;
 
         uint32_t gap = oldlen - newlen;
         for (;;) {
-            jsid nid;
-            if (!JS_CHECK_OPERATION_LIMIT(cx) || !JS_NextProperty(cx, iter, &nid))
+            RootedId nid(cx);
+            if (!JS_CHECK_OPERATION_LIMIT(cx) || !JS_NextProperty(cx, iter, nid.address()))
                 return false;
             if (JSID_IS_VOID(nid))
                 break;
             uint32_t index;
             RootedValue junk(cx);
             if (js_IdIsIndex(nid, &index) && index - newlen < gap &&
                 !JSObject::deleteElement(cx, obj, index, &junk, false)) {
                 return false;
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -53,16 +53,18 @@ struct DtoaState;
 extern void
 js_ReportOutOfMemory(JSContext *cx);
 
 extern void
 js_ReportAllocationOverflow(JSContext *cx);
 
 namespace js {
 
+typedef Rooted<JSLinearString*> RootedLinearString;
+
 struct CallsiteCloneKey {
     /* The original function that we are cloning. */
     JSFunction *original;
 
     /* The script of the call. */
     JSScript *script;
 
     /* The offset of the call. */
@@ -221,18 +223,19 @@ class SourceDataCache
     SourceDataCache() : map_(NULL) {}
     JSStableString *lookup(ScriptSource *ss);
     void put(ScriptSource *ss, JSStableString *);
     void purge();
 };
 
 struct EvalCacheLookup
 {
-    JSLinearString *str;
-    JSFunction *caller;
+    EvalCacheLookup(JSContext *cx) : str(cx), caller(cx) {}
+    RootedLinearString str;
+    RootedFunction caller;
     unsigned staticLevel;
     JSVersion version;
     JSCompartment *compartment;
 };
 
 struct EvalCacheHashPolicy
 {
     typedef EvalCacheLookup Lookup;
--- a/js/src/jsdbgapi.cpp
+++ b/js/src/jsdbgapi.cpp
@@ -288,21 +288,22 @@ JS_ClearInterrupt(JSRuntime *rt, JSInter
     rt->debugHooks.interruptHook = 0;
     rt->debugHooks.interruptHookData = 0;
     return JS_TRUE;
 }
 
 /************************************************************************/
 
 JS_PUBLIC_API(JSBool)
-JS_SetWatchPoint(JSContext *cx, JSObject *obj_, jsid id,
+JS_SetWatchPoint(JSContext *cx, JSObject *obj_, jsid id_,
                  JSWatchPointHandler handler, JSObject *closure_)
 {
     assertSameCompartment(cx, obj_);
 
+    RootedId id(cx, id_);
     RootedObject origobj(cx, obj_), closure(cx, closure_);
     RootedObject obj(cx, GetInnerObject(cx, origobj));
     if (!obj)
         return false;
 
     RootedValue v(cx);
     unsigned attrs;
 
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -1055,21 +1055,21 @@ JSFunction::getBoundFunctionArgumentCoun
     return getSlot(JSSLOT_BOUND_FUNCTION_ARGS_COUNT).toPrivateUint32();
 }
 
 bool
 JSFunction::initializeLazyScript(JSContext *cx)
 {
     JS_ASSERT(isInterpretedLazy());
     JSFunctionSpec *fs = static_cast<JSFunctionSpec *>(getExtendedSlot(0).toPrivate());
+    Rooted<JSFunction*> self(cx, this);
     RootedAtom funAtom(cx, Atomize(cx, fs->selfHostedName, strlen(fs->selfHostedName)));
     if (!funAtom)
         return false;
     Rooted<PropertyName *> funName(cx, funAtom->asPropertyName());
-    Rooted<JSFunction*> self(cx, this);
     return cx->runtime->cloneSelfHostedFunctionScript(cx, funName, self);
 }
 
 /* ES5 15.3.4.5.1 and 15.3.4.5.2. */
 JSBool
 js::CallOrConstructBoundFunction(JSContext *cx, unsigned argc, Value *vp)
 {
     RootedFunction fun(cx, vp[0].toObject().toFunction());
--- a/js/src/jsproxy.cpp
+++ b/js/src/jsproxy.cpp
@@ -60,22 +60,22 @@ js::AutoEnterPolicy::reportError(JSConte
         const jschar *prop = str ? str->getCharsZ(cx) : NULL;
         JS_ReportErrorNumberUC(cx, js_GetErrorMessage, NULL,
                                JSMSG_PROPERTY_ACCESS_DENIED, prop);
     }
 }
 
 #ifdef DEBUG
 void
-js::AutoEnterPolicy::recordEnter(JSContext *cx, JSObject *proxy, jsid id)
+js::AutoEnterPolicy::recordEnter(JSContext *cx, HandleObject proxy, HandleId id)
 {
     if (allowed()) {
         context = cx;
-        enteredProxy.construct(cx, proxy);
-        enteredId.construct(cx, id);
+        enteredProxy.construct(proxy);
+        enteredId.construct(id);
         prev = cx->runtime->enteredPolicy;
         cx->runtime->enteredPolicy = this;
     }
 }
 
 void
 js::AutoEnterPolicy::recordLeave()
 {
@@ -287,17 +287,17 @@ BaseProxyHandler::keys(JSContext *cx, JS
     if (!getOwnPropertyNames(cx, proxy, props))
         return false;
 
     /* Select only the enumerable properties through in-place iteration. */
     AutoPropertyDescriptorRooter desc(cx);
     size_t i = 0;
     for (size_t j = 0, len = props.length(); j < len; j++) {
         JS_ASSERT(i <= j);
-        jsid id = props[j];
+        RootedId id(cx, props[j]);
         AutoWaivePolicy policy(cx, proxy, id);
         if (!getOwnPropertyDescriptor(cx, proxy, id, &desc, 0))
             return false;
         if (desc.obj && (desc.attrs & JSPROP_ENUMERATE))
             props[i++] = id;
     }
 
     JS_ASSERT(i <= props.length());
@@ -2297,21 +2297,22 @@ Proxy::getPropertyDescriptor(JSContext *
     RootedValue value(cx);
     if (!NewPropertyDescriptorObject(cx, &desc, &value))
         return false;
     *vp = value;
     return true;
 }
 
 bool
-Proxy::getOwnPropertyDescriptor(JSContext *cx, JSObject *proxy_, jsid id, PropertyDescriptor *desc,
+Proxy::getOwnPropertyDescriptor(JSContext *cx, JSObject *proxy_, jsid id_, PropertyDescriptor *desc,
                                 unsigned flags)
 {
     JS_CHECK_RECURSION(cx, return false);
     RootedObject proxy(cx, proxy_);
+    RootedId id(cx, id_);
     BaseProxyHandler *handler = GetProxyHandler(proxy);
     desc->obj = NULL; // default result if we refuse to perform this action
     AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::GET, true);
     if (!policy.allowed())
         return policy.returnValue();
     return handler->getOwnPropertyDescriptor(cx, proxy, id, desc, flags);
 }
 
@@ -2328,21 +2329,22 @@ Proxy::getOwnPropertyDescriptor(JSContex
     RootedValue value(cx);
     if (!NewPropertyDescriptorObject(cx, &desc, &value))
         return false;
     *vp = value;
     return true;
 }
 
 bool
-Proxy::defineProperty(JSContext *cx, JSObject *proxy_, jsid id, PropertyDescriptor *desc)
+Proxy::defineProperty(JSContext *cx, JSObject *proxy_, jsid id_, PropertyDescriptor *desc)
 {
     JS_CHECK_RECURSION(cx, return false);
     BaseProxyHandler *handler = GetProxyHandler(proxy_);
     RootedObject proxy(cx, proxy_);
+    RootedId id(cx, id_);
     AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::SET, true);
     if (!policy.allowed())
         return policy.returnValue();
     return GetProxyHandler(proxy)->defineProperty(cx, proxy, id, desc);
 }
 
 bool
 Proxy::defineProperty(JSContext *cx, JSObject *proxy_, jsid id_, const Value &v)
@@ -2356,28 +2358,29 @@ Proxy::defineProperty(JSContext *cx, JSO
 }
 
 bool
 Proxy::getOwnPropertyNames(JSContext *cx, JSObject *proxy_, AutoIdVector &props)
 {
     JS_CHECK_RECURSION(cx, return false);
     BaseProxyHandler *handler = GetProxyHandler(proxy_);
     RootedObject proxy(cx, proxy_);
-    AutoEnterPolicy policy(cx, handler, proxy, JSID_VOID, BaseProxyHandler::GET, true);
+    AutoEnterPolicy policy(cx, handler, proxy, JS::JSID_VOIDHANDLE, BaseProxyHandler::GET, true);
     if (!policy.allowed())
         return policy.returnValue();
     return GetProxyHandler(proxy)->getOwnPropertyNames(cx, proxy, props);
 }
 
 bool
-Proxy::delete_(JSContext *cx, JSObject *proxy_, jsid id, bool *bp)
+Proxy::delete_(JSContext *cx, JSObject *proxy_, jsid id_, bool *bp)
 {
     JS_CHECK_RECURSION(cx, return false);
     BaseProxyHandler *handler = GetProxyHandler(proxy_);
     RootedObject proxy(cx, proxy_);
+    RootedId id(cx, id_);
     *bp = true; // default result if we refuse to perform this action
     AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::SET, true);
     if (!policy.allowed())
         return policy.returnValue();
     return GetProxyHandler(proxy)->delete_(cx, proxy, id, bp);
 }
 
 JS_FRIEND_API(bool)
@@ -2401,17 +2404,17 @@ js::AppendUnique(JSContext *cx, AutoIdVe
 }
 
 bool
 Proxy::enumerate(JSContext *cx, JSObject *proxy_, AutoIdVector &props)
 {
     JS_CHECK_RECURSION(cx, return false);
     RootedObject proxy(cx, proxy_);
     BaseProxyHandler *handler = GetProxyHandler(proxy);
-    AutoEnterPolicy policy(cx, handler, proxy, JSID_VOID, BaseProxyHandler::GET, true);
+    AutoEnterPolicy policy(cx, handler, proxy, JS::JSID_VOIDHANDLE, BaseProxyHandler::GET, true);
     if (!policy.allowed())
         return policy.returnValue();
     if (!handler->hasPrototype())
         return GetProxyHandler(proxy)->enumerate(cx, proxy, props);
     if (!handler->keys(cx, proxy, props))
         return false;
     AutoIdVector protoProps(cx);
     INVOKE_ON_PROTOTYPE(cx, handler, proxy,
@@ -2438,20 +2441,21 @@ Proxy::has(JSContext *cx, JSObject *prox
         return true;
     JSBool Bp;
     INVOKE_ON_PROTOTYPE(cx, handler, proxy,
                         JS_HasPropertyById(cx, proto, id, &Bp) &&
                         ((*bp = Bp) || true));
 }
 
 bool
-Proxy::hasOwn(JSContext *cx, JSObject *proxy_, jsid id, bool *bp)
+Proxy::hasOwn(JSContext *cx, JSObject *proxy_, jsid id_, bool *bp)
 {
     JS_CHECK_RECURSION(cx, return false);
     RootedObject proxy(cx, proxy_);
+    RootedId id(cx, id_);
     BaseProxyHandler *handler = GetProxyHandler(proxy);
     *bp = false; // default result if we refuse to perform this action
     AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::GET, true);
     if (!policy.allowed())
         return policy.returnValue();
     return handler->hasOwn(cx, proxy, id, bp);
 }
 
@@ -2543,30 +2547,30 @@ Proxy::set(JSContext *cx, HandleObject p
 }
 
 bool
 Proxy::keys(JSContext *cx, JSObject *proxy_, AutoIdVector &props)
 {
     JS_CHECK_RECURSION(cx, return false);
     RootedObject proxy(cx, proxy_);
     BaseProxyHandler *handler = GetProxyHandler(proxy);
-    AutoEnterPolicy policy(cx, handler, proxy, JSID_VOID, BaseProxyHandler::GET, true);
+    AutoEnterPolicy policy(cx, handler, proxy, JS::JSID_VOIDHANDLE, BaseProxyHandler::GET, true);
     if (!policy.allowed())
         return policy.returnValue();
     return handler->keys(cx, proxy, props);
 }
 
 bool
 Proxy::iterate(JSContext *cx, HandleObject proxy, unsigned flags, MutableHandleValue vp)
 {
     JS_CHECK_RECURSION(cx, return false);
     BaseProxyHandler *handler = GetProxyHandler(proxy);
     vp.setUndefined(); // default result if we refuse to perform this action
     if (!handler->hasPrototype()) {
-        AutoEnterPolicy policy(cx, handler, proxy, JSID_VOID,
+        AutoEnterPolicy policy(cx, handler, proxy, JS::JSID_VOIDHANDLE,
                                BaseProxyHandler::GET, true);
         // If the policy denies access but wants us to return true, we need
         // to hand a valid (empty) iterator object to the caller.
         if (!policy.allowed()) {
             AutoIdVector props(cx);
             return policy.returnValue() &&
                    EnumeratedIdVectorToIterator(cx, proxy, flags, props, vp);
         }
@@ -2587,17 +2591,17 @@ Proxy::call(JSContext *cx, JSObject *pro
 {
     JS_CHECK_RECURSION(cx, return false);
     RootedObject proxy(cx, proxy_);
     BaseProxyHandler *handler = GetProxyHandler(proxy);
 
     // Because vp[0] is JS_CALLEE on the way in and JS_RVAL on the way out, we
     // can only set our default value once we're sure that we're not calling the
     // trap.
-    AutoEnterPolicy policy(cx, handler, proxy, JSID_VOID,
+    AutoEnterPolicy policy(cx, handler, proxy, JS::JSID_VOIDHANDLE,
                            BaseProxyHandler::CALL, true);
     if (!policy.allowed()) {
         vp->setUndefined();
         return policy.returnValue();
     }
 
     return handler->call(cx, proxy, argc, vp);
 }
@@ -2607,17 +2611,17 @@ Proxy::construct(JSContext *cx, JSObject
 {
     JS_CHECK_RECURSION(cx, return false);
     RootedObject proxy(cx, proxy_);
     BaseProxyHandler *handler = GetProxyHandler(proxy);
 
     // Because vp[0] is JS_CALLEE on the way in and JS_RVAL on the way out, we
     // can only set our default value once we're sure that we're not calling the
     // trap.
-    AutoEnterPolicy policy(cx, handler, proxy, JSID_VOID,
+    AutoEnterPolicy policy(cx, handler, proxy, JS::JSID_VOIDHANDLE,
                            BaseProxyHandler::CALL, true);
     if (!policy.allowed()) {
         rval->setUndefined();
         return policy.returnValue();
     }
 
     return handler->construct(cx, proxy, argc, argv, rval);
 }
@@ -2634,17 +2638,17 @@ Proxy::nativeCall(JSContext *cx, IsAccep
 }
 
 bool
 Proxy::hasInstance(JSContext *cx, HandleObject proxy, MutableHandleValue v, bool *bp)
 {
     JS_CHECK_RECURSION(cx, return false);
     BaseProxyHandler *handler = GetProxyHandler(proxy);
     *bp = false; // default result if we refuse to perform this action
-    AutoEnterPolicy policy(cx, handler, proxy, JSID_VOID, BaseProxyHandler::GET, true);
+    AutoEnterPolicy policy(cx, handler, proxy, JS::JSID_VOIDHANDLE, BaseProxyHandler::GET, true);
     if (!policy.allowed())
         return policy.returnValue();
     return GetProxyHandler(proxy)->hasInstance(cx, proxy, v, bp);
 }
 
 bool
 Proxy::objectClassIs(JSObject *proxy_, ESClassValue classValue, JSContext *cx)
 {
@@ -2653,32 +2657,32 @@ Proxy::objectClassIs(JSObject *proxy_, E
 }
 
 JSString *
 Proxy::obj_toString(JSContext *cx, JSObject *proxy_)
 {
     JS_CHECK_RECURSION(cx, return NULL);
     RootedObject proxy(cx, proxy_);
     BaseProxyHandler *handler = GetProxyHandler(proxy);
-    AutoEnterPolicy policy(cx, handler, proxy, JSID_VOID,
+    AutoEnterPolicy policy(cx, handler, proxy, JS::JSID_VOIDHANDLE,
                            BaseProxyHandler::GET, /* mayThrow = */ false);
     // Do the safe thing if the policy rejects.
     if (!policy.allowed()) {
         return handler->BaseProxyHandler::obj_toString(cx, proxy);
     }
     return handler->obj_toString(cx, proxy);
 }
 
 JSString *
 Proxy::fun_toString(JSContext *cx, JSObject *proxy_, unsigned indent)
 {
     JS_CHECK_RECURSION(cx, return NULL);
     RootedObject proxy(cx, proxy_);
     BaseProxyHandler *handler = GetProxyHandler(proxy);
-    AutoEnterPolicy policy(cx, handler, proxy, JSID_VOID,
+    AutoEnterPolicy policy(cx, handler, proxy, JS::JSID_VOIDHANDLE,
                            BaseProxyHandler::GET, /* mayThrow = */ false);
     // Do the safe thing if the policy rejects.
     if (!policy.allowed()) {
         if (proxy->isCallable())
             return JS_NewStringCopyZ(cx, "function () {\n    [native code]\n}");
         ReportIsNotFunction(cx, ObjectValue(*proxy));
         return NULL;
     }
--- a/js/src/jsproxy.h
+++ b/js/src/jsproxy.h
@@ -344,17 +344,17 @@ NewProxyObject(JSContext *cx, BaseProxyH
 JSObject *
 RenewProxyObject(JSContext *cx, JSObject *obj, BaseProxyHandler *handler, Value priv);
 
 class JS_FRIEND_API(AutoEnterPolicy)
 {
   public:
     typedef BaseProxyHandler::Action Action;
     AutoEnterPolicy(JSContext *cx, BaseProxyHandler *handler,
-                    JSObject *wrapper, jsid id, Action act, bool mayThrow)
+                    HandleObject wrapper, HandleId id, Action act, bool mayThrow)
 #ifdef DEBUG
         : context(NULL)
 #endif
     {
         allow = handler->hasPolicy() ? handler->enter(cx, wrapper, id, act, &rv)
                                      : true;
         recordEnter(cx, wrapper, id);
         // We want to throw an exception if all of the following are true:
@@ -378,45 +378,45 @@ class JS_FRIEND_API(AutoEnterPolicy)
 #endif
         {};
     void reportError(JSContext *cx, jsid id);
     bool allow;
     bool rv;
 
 #ifdef DEBUG
     JSContext *context;
-    mozilla::Maybe<RootedObject> enteredProxy;
-    mozilla::Maybe<RootedId> enteredId;
+    mozilla::Maybe<HandleObject> enteredProxy;
+    mozilla::Maybe<HandleId> enteredId;
     // NB: We explicitly don't track the entered action here, because sometimes
     // SET traps do an implicit GET during their implementation, leading to
     // spurious assertions.
     AutoEnterPolicy *prev;
-    void recordEnter(JSContext *cx, JSObject *proxy, jsid id);
+    void recordEnter(JSContext *cx, HandleObject proxy, HandleId id);
     void recordLeave();
 
     friend JS_FRIEND_API(void) assertEnteredPolicy(JSContext *cx, JSObject *proxy, jsid id);
 #else
     inline void recordEnter(JSContext *cx, JSObject *proxy, jsid id) {}
     inline void recordLeave() {}
 #endif
 
 };
 
 #ifdef DEBUG
 class JS_FRIEND_API(AutoWaivePolicy) : public AutoEnterPolicy {
 public:
-    AutoWaivePolicy(JSContext *cx, JSObject *proxy, jsid id)
+    AutoWaivePolicy(JSContext *cx, HandleObject proxy, HandleId id)
     {
         allow = true;
         recordEnter(cx, proxy, id);
     }
 };
 #else
 class JS_FRIEND_API(AutoWaivePolicy) {
-    public: AutoWaivePolicy(JSContext *cx, JSObject *proxy, jsid id) {};
+    public: AutoWaivePolicy(JSContext *cx, HandleObject proxy, HandleId id) {};
 };
 #endif
 
 } /* namespace js */
 
 extern JS_FRIEND_API(JSObject *)
 js_InitProxyClass(JSContext *cx, JSHandleObject obj);
 
--- a/js/src/jsstr.cpp
+++ b/js/src/jsstr.cpp
@@ -61,17 +61,16 @@
 
 using namespace js;
 using namespace js::gc;
 using namespace js::types;
 using namespace js::unicode;
 
 using mozilla::CheckedInt;
 
-typedef Rooted<JSLinearString*> RootedLinearString;
 typedef Handle<JSLinearString*> HandleLinearString;
 
 static JSLinearString *
 ArgToRootedString(JSContext *cx, CallArgs &args, unsigned argno)
 {
     if (argno >= args.length())
         return cx->names().undefined;
 
--- a/js/xpconnect/wrappers/ChromeObjectWrapper.cpp
+++ b/js/xpconnect/wrappers/ChromeObjectWrapper.cpp
@@ -170,13 +170,15 @@ ChromeObjectWrapper::enter(JSContext *cx
     // COWs fail silently for GETs, and that also happens to be the only case
     // where we might want to redirect the lookup to the home prototype chain.
     *bp = (act == Wrapper::GET);
     if (!*bp || id == JSID_VOID)
         return false;
 
     // Note that PropIsFromStandardPrototype needs to invoke getPropertyDescriptor
     // before we've fully entered the policy. Waive our policy.
-    js::AutoWaivePolicy policy(cx, wrapper, id);
+    JS::RootedObject rootedWrapper(cx, wrapper);
+    JS::RootedId rootedId(cx, id);
+    js::AutoWaivePolicy policy(cx, rootedWrapper, rootedId);
     return PropIsFromStandardPrototype(cx, wrapper, id);
 }
 
 }
--- a/mobile/android/base/BrowserApp.java
+++ b/mobile/android/base/BrowserApp.java
@@ -217,16 +217,24 @@ abstract public class BrowserApp extends
     }
 
     @Override
     public boolean onInterceptTouchEvent(View view, MotionEvent event) {
         if (!mDynamicToolbarEnabled || mToolbarPinned) {
             return super.onInterceptTouchEvent(view, event);
         }
 
+        // Don't let the toolbar scroll at all if the page is shorter than
+        // the screen height.
+        ImmutableViewportMetrics metrics =
+            mLayerView.getLayerClient().getViewportMetrics();
+        if (metrics.getPageHeight() < metrics.getHeight()) {
+            return super.onInterceptTouchEvent(view, event);
+        }
+
         int action = event.getActionMasked();
         int pointerCount = event.getPointerCount();
 
         // Whenever there are no pointers left on the screen, tell the page
         // to clamp the viewport on fixed layer margin changes. This lets the
         // toolbar scrolling off the top of the page make the page scroll up
         // if it'd cause the page to go into overscroll, but only when there
         // are no pointers held down.
@@ -299,18 +307,16 @@ abstract public class BrowserApp extends
             // Cancel any ongoing animation before we start moving the toolbar.
             mBrowserToolbar.cancelVisibilityAnimation();
 
             // Move the toolbar by the amount the touch event has moved,
             // clamping to fully visible or fully hidden.
 
             // Don't let the toolbar scroll off the top if it's just exposing
             // overscroll area.
-            ImmutableViewportMetrics metrics =
-                mLayerView.getLayerClient().getViewportMetrics();
             float toolbarMaxY = Math.min(toolbarHeight,
                 Math.max(0, toolbarHeight - (metrics.pageRectTop -
                                              metrics.viewportRectTop)));
 
             float newToolbarYf = Math.max(0, Math.min(toolbarMaxY,
                 toolbarY + deltaY + mToolbarSubpixelAccumulation));
             int newToolbarY = Math.round(newToolbarYf);
             mToolbarSubpixelAccumulation = (newToolbarYf - newToolbarY);
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -3496,23 +3496,29 @@ Tab.prototype = {
   sendViewportUpdate: function(aPageSizeUpdate) {
     let viewport = this.getViewport();
     let displayPort = getBridge().getDisplayPort(aPageSizeUpdate, BrowserApp.isBrowserContentDocumentDisplayed(), this.id, viewport);
     if (displayPort != null)
       this.setDisplayPort(displayPort);
 
     // If the page size has changed so that it might or might not fit on the
     // screen with the margins included, run updateViewportSize to resize the
-    // browser accordingly. The -1 is to account for rounding errors.
+    // browser accordingly.
+    // A page will receive the smaller viewport when its page size fits
+    // within the screen size, so remeasure when the page size remains within
+    // the threshold of screen + margins, in case it's sizing itself relative
+    // to the viewport.
     if (!this.updatingViewportForPageSizeChange) {
       this.updatingViewportForPageSizeChange = true;
-      if (((viewport.pageBottom - viewport.pageTop <= gScreenHeight - 1) !=
-           this.viewportExcludesVerticalMargins) ||
-          ((viewport.pageRight - viewport.pageLeft <= gScreenWidth - 1) !=
-           this.viewportExcludesHorizontalMargins)) {
+      if (((viewport.pageBottom - viewport.pageTop
+              < gScreenHeight + gViewportMargins.top + gViewportMargins.bottom)
+             != this.viewportExcludesVerticalMargins) ||
+          ((viewport.pageRight - viewport.pageLeft
+              < gScreenWidth + gViewportMargins.left + gViewportMargins.right)
+             != this.viewportExcludesHorizontalMargins)) {
         this.updateViewportSize(gScreenWidth);
       }
       this.updatingViewportForPageSizeChange = false;
     }
   },
 
   handleEvent: function(aEvent) {
     switch (aEvent.type) {
@@ -3995,25 +4001,24 @@ Tab.prototype = {
     let minScale = 1.0;
     if (this.browser.contentDocument) {
       // this may get run during a Viewport:Change message while the document
       // has not yet loaded, so need to guard against a null document.
       let [pageWidth, pageHeight] = this.getPageSize(this.browser.contentDocument, viewportW, viewportH);
 
       minScale = screenW / pageWidth;
 
-      // In the situation the page size exceeds the screen size minus the
-      // viewport margins on either axis, lengthen the viewport on the
-      // corresponding axis to include the margins.
-      // The +1 is to account for rounding errors.
-      if (pageWidth * this._zoom >= screenW + 1) {
+      // In the situation the page size equals or exceeds the screen size,
+      // lengthen the viewport on the corresponding axis to include the margins.
+      // The -1 is to account for rounding errors.
+      if (pageWidth * this._zoom > gScreenWidth - 1) {
         screenW = gScreenWidth;
         this.viewportExcludesHorizontalMargins = false;
       }
-      if (pageHeight * this._zoom >= screenH + 1) {
+      if (pageHeight * this._zoom > gScreenHeight - 1) {
         screenH = gScreenHeight;
         this.viewportExcludesVerticalMargins = false;
       }
     }
     minScale = this.clampZoom(minScale);
     viewportH = Math.max(viewportH, screenH / minScale);
     this.setBrowserSize(viewportW, viewportH);
 
--- a/mobile/android/installer/package-manifest.in
+++ b/mobile/android/installer/package-manifest.in
@@ -159,17 +159,16 @@
 @BINPATH@/components/gfx.xpt
 @BINPATH@/components/html5.xpt
 @BINPATH@/components/htmlparser.xpt
 @BINPATH@/components/imglib2.xpt
 @BINPATH@/components/imgicon.xpt
 @BINPATH@/components/inspector.xpt
 @BINPATH@/components/intl.xpt
 @BINPATH@/components/jar.xpt
-@BINPATH@/components/jetpack.xpt
 @BINPATH@/components/jsdservice.xpt
 @BINPATH@/components/jsdebugger.xpt
 @BINPATH@/components/jsinspector.xpt
 @BINPATH@/components/layout_base.xpt
 @BINPATH@/components/layout_forms.xpt
 #ifdef NS_PRINTING
 @BINPATH@/components/layout_printing.xpt
 #endif
--- a/modules/libjar/nsZipArchive.cpp
+++ b/modules/libjar/nsZipArchive.cpp
@@ -25,16 +25,17 @@
 #include <windows.h>
 #endif
 
 // For placement new used for arena allocations of zip file list
 #include NEW_H
 #define ZIP_ARENABLOCKSIZE (1*1024)
 
 #ifdef XP_UNIX
+    #include <sys/mman.h>
     #include <sys/types.h>
     #include <sys/stat.h>
     #include <limits.h>
     #include <unistd.h>
 #elif defined(XP_WIN) || defined(XP_OS2)
     #include <io.h>
 #endif
 
@@ -160,20 +161,24 @@ nsZipHandle::nsZipHandle()
   , mRefCnt(0)
 {
   MOZ_COUNT_CTOR(nsZipHandle);
 }
 
 NS_IMPL_THREADSAFE_ADDREF(nsZipHandle)
 NS_IMPL_THREADSAFE_RELEASE(nsZipHandle)
 
-nsresult nsZipHandle::Init(nsIFile *file, nsZipHandle **ret)
+nsresult nsZipHandle::Init(nsIFile *file, nsZipHandle **ret, PRFileDesc **aFd)
 {
   mozilla::AutoFDClose fd;
-  nsresult rv = file->OpenNSPRFileDesc(PR_RDONLY, 0000, &fd.rwget());
+  int32_t flags = PR_RDONLY;
+#if defined(XP_WIN)
+  flags |= nsIFile::OS_READAHEAD;
+#endif
+  nsresult rv = file->OpenNSPRFileDesc(flags, 0000, &fd.rwget());
   if (NS_FAILED(rv))
     return rv;
 
   int64_t size = PR_Available64(fd);
   if (size >= INT32_MAX)
     return NS_ERROR_FILE_TOO_BIG;
 
   PRFileMap *map = PR_CreateFileMap(fd, size, PR_PROT_READONLY);
@@ -189,16 +194,21 @@ nsresult nsZipHandle::Init(nsIFile *file
 
   nsRefPtr<nsZipHandle> handle = new nsZipHandle();
   if (!handle) {
     PR_MemUnmap(buf, (uint32_t) size);
     PR_CloseFileMap(map);
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
+#if defined(XP_WIN)
+  if (aFd) {
+    *aFd = fd.forget();
+  }
+#endif
   handle->mMap = map;
   handle->mFile.Init(file);
   handle->mLen = (uint32_t) size;
   handle->mFileData = buf;
   *ret = handle.forget().get();
   return NS_OK;
 }
 
@@ -243,40 +253,49 @@ nsZipHandle::~nsZipHandle()
 
 //***********************************************************
 //      nsZipArchive  --  public methods
 //***********************************************************
 
 //---------------------------------------------
 //  nsZipArchive::OpenArchive
 //---------------------------------------------
-nsresult nsZipArchive::OpenArchive(nsZipHandle *aZipHandle)
+nsresult nsZipArchive::OpenArchive(nsZipHandle *aZipHandle, PRFileDesc *aFd)
 {
   mFd = aZipHandle;
 
   // Initialize our arena
   PL_INIT_ARENA_POOL(&mArena, "ZipArena", ZIP_ARENABLOCKSIZE);
 
   //-- get table of contents for archive
-  nsresult rv = BuildFileList();
+  nsresult rv = BuildFileList(aFd);
   if (NS_SUCCEEDED(rv)) {
     if (aZipHandle->mFile)
       aZipHandle->mFile.GetURIString(mURI);
   }
   return rv;
 }
 
 nsresult nsZipArchive::OpenArchive(nsIFile *aFile)
 {
   nsRefPtr<nsZipHandle> handle;
+#if defined(XP_WIN)
+  mozilla::AutoFDClose fd;
+  nsresult rv = nsZipHandle::Init(aFile, getter_AddRefs(handle), &fd.rwget());
+#else
   nsresult rv = nsZipHandle::Init(aFile, getter_AddRefs(handle));
+#endif
   if (NS_FAILED(rv))
     return rv;
 
+#if defined(XP_WIN)
+  return OpenArchive(handle, fd.get());
+#else
   return OpenArchive(handle);
+#endif
 }
 
 //---------------------------------------------
 //  nsZipArchive::Test
 //---------------------------------------------
 nsresult nsZipArchive::Test(const char *aEntryName)
 {
   nsZipItem* currItem;
@@ -554,26 +573,37 @@ nsZipItem* nsZipArchive::CreateZipItem()
   void *mem;
   PL_ARENA_ALLOCATE(mem, &mArena, sizeof(nsZipItem));
   return (nsZipItem*)mem;
 }
 
 //---------------------------------------------
 //  nsZipArchive::BuildFileList
 //---------------------------------------------
-nsresult nsZipArchive::BuildFileList()
+nsresult nsZipArchive::BuildFileList(PRFileDesc *aFd)
 {
   // Get archive size using end pos
   const uint8_t* buf;
   const uint8_t* startp = mFd->mFileData;
   const uint8_t* endp = startp + mFd->mLen;
 MOZ_WIN_MEM_TRY_BEGIN
   uint32_t centralOffset = 4;
   if (mFd->mLen > ZIPCENTRAL_SIZE && xtolong(startp + centralOffset) == CENTRALSIG) {
     // Success means optimized jar layout from bug 559961 is in effect
+    uint32_t readaheadLength = xtolong(startp);
+    if (readaheadLength) {
+#if defined(XP_UNIX)
+      madvise(const_cast<uint8_t*>(startp), readaheadLength, MADV_WILLNEED);
+#elif defined(XP_WIN)
+      if (aFd) {
+        HANDLE hFile = (HANDLE) PR_FileDesc2NativeHandle(aFd);
+        mozilla::ReadAhead(hFile, 0, readaheadLength);
+      }
+#endif
+    }
   } else {
     for (buf = endp - ZIPEND_SIZE; buf > startp; buf--)
       {
         if (xtolong(buf) == ENDSIG) {
           centralOffset = xtolong(((ZipEnd *)buf)->offset_central_dir);
           break;
         }
       }
--- a/modules/libjar/nsZipArchive.h
+++ b/modules/libjar/nsZipArchive.h
@@ -108,19 +108,20 @@ public:
   /** 
    * OpenArchive 
    * 
    * It's an error to call this more than once on the same nsZipArchive
    * object. If we were allowed to use exceptions this would have been 
    * part of the constructor 
    *
    * @param   aZipHandle  The nsZipHandle used to access the zip
+   * @param   aFd         Optional PRFileDesc for Windows readahead optimization
    * @return  status code
    */
-  nsresult OpenArchive(nsZipHandle *aZipHandle);
+  nsresult OpenArchive(nsZipHandle *aZipHandle, PRFileDesc *aFd = nullptr);
 
   /** 
    * OpenArchive 
    * 
    * Convenience function that generates nsZipHandle
    *
    * @param   aFile  The file used to access the zip
    * @return  status code
@@ -218,17 +219,17 @@ private:
   nsRefPtr<nsZipHandle> mFd;
 
   // file URI, for logging
   nsCString mURI;
 
 private:
   //--- private methods ---
   nsZipItem*        CreateZipItem();
-  nsresult          BuildFileList();
+  nsresult          BuildFileList(PRFileDesc *aFd = nullptr);
   nsresult          BuildSynthetics();
 
   nsZipArchive& operator=(const nsZipArchive& rhs) MOZ_DELETE;
   nsZipArchive(const nsZipArchive& rhs) MOZ_DELETE;
 };
 
 /** 
  * nsZipFind 
@@ -369,17 +370,18 @@ public:
     return ret;
   }
 };
 
 class nsZipHandle {
 friend class nsZipArchive;
 friend class mozilla::FileLocation;
 public:
-  static nsresult Init(nsIFile *file, nsZipHandle **ret);
+  static nsresult Init(nsIFile *file, nsZipHandle **ret,
+                       PRFileDesc **aFd = nullptr);
   static nsresult Init(nsZipArchive *zip, const char *entry,
                        nsZipHandle **ret);
 
   NS_METHOD_(nsrefcnt) AddRef(void);
   NS_METHOD_(nsrefcnt) Release(void);
 
   int64_t SizeOfMapping();
 
--- a/parser/htmlparser/tests/mochitest/parser_datreader.js
+++ b/parser/htmlparser/tests/mochitest/parser_datreader.js
@@ -129,17 +129,18 @@ function addLevels(walker, buf, indent) 
           if ("http://www.w3.org/1998/Math/MathML" == ns) {
             buf += "math ";
           } else if ("http://www.w3.org/2000/svg" == ns) {
             buf += "svg ";
           } else if ("http://www.w3.org/1999/xhtml" != ns) {
             buf += "otherns ";
           }
           buf += walker.currentNode.localName + ">";
-          if (walker.currentNode.hasAttributes()) {
+          if (walker.currentNode.attributes &&
+              walker.currentNode.attributes.length) {
             var valuesByName = {};
             var attrs = walker.currentNode.attributes;
             for (var i = 0; i < attrs.length; ++i) {
               var localName = attrs[i].localName;
               if (localName.indexOf("_moz-") == 0) {
                 // Skip bogus attributes added by the MathML implementation
                 continue;
               }
--- a/testing/mozbase/Makefile.in
+++ b/testing/mozbase/Makefile.in
@@ -11,16 +11,17 @@ include $(DEPTH)/config/autoconf.mk
 
 include $(topsrcdir)/config/rules.mk
 
 # Harness packages from the srcdir;
 # python packages to be installed IN INSTALLATION ORDER.
 # Packages later in the list can depend only on packages earlier in the list.
 MOZBASE_PACKAGES = \
   manifestdestiny \
+  mozcrash \
   mozfile \
   mozhttpd \
   mozinfo \
   mozinstall \
   mozlog \
   mozprocess \
   mozprofile \
   mozrunner \
--- a/testing/xpcshell/runxpcshelltests.py
+++ b/testing/xpcshell/runxpcshelltests.py
@@ -13,16 +13,34 @@ from tempfile import mkdtemp, gettempdir
 import manifestparser
 import mozinfo
 import random
 import socket
 import time
 
 from automationutils import *
 
+# --------------------------------------------------------------
+# TODO: this is a hack for mozbase without virtualenv, remove with bug 849900
+#
+here = os.path.dirname(__file__)
+mozbase = os.path.realpath(os.path.join(os.path.dirname(here), 'mozbase'))
+
+try:
+    import mozcrash
+except:
+    deps = ['mozcrash',
+            'mozlog']
+    for dep in deps:
+        module = os.path.join(mozbase, dep)
+        if module not in sys.path:
+            sys.path.append(module)
+    import mozcrash
+# ---------------------------------------------------------------
+
 #TODO: replace this with json.loads when Python 2.6 is required.
 def parse_json(j):
     """
     Awful hack to parse a restricted subset of JSON strings into Python dicts.
     """
     return eval(j, {'true':True,'false':False,'null':None})
 
 """ Control-C handling """
@@ -889,17 +907,17 @@ class XPCShellTests(object):
                     xunitResult["passed"] = True
 
                     if expected:
                         self.passCount += 1
                     else:
                         self.todoCount += 1
                         xunitResult["todo"] = True
 
-                if checkForCrashes(testdir, self.symbolsPath, testName=name):
+                if mozcrash.check_for_crashes(testdir, self.symbolsPath, test_name=name):
                     message = "PROCESS-CRASH | %s | application crashed" % name
                     self.failCount += 1
                     xunitResult["passed"] = False
                     xunitResult["failure"] = {
                       "type": "PROCESS-CRASH",
                       "message": message,
                       "text": stdout
                     }
--- a/toolkit/components/viewsource/content/viewSource.js
+++ b/toolkit/components/viewsource/content/viewSource.js
@@ -695,51 +695,16 @@ function UpdateBackForwardCommands() {
     backBroadcaster.setAttribute("disabled", "true");
 
   if (getWebNavigation().canGoForward)
     forwardBroadcaster.removeAttribute("disabled");
   else
     forwardBroadcaster.setAttribute("disabled", "true");
 }
 
-// FIXME copied and modified from browser.js.
-// Deduplication is part of bug 480356.
-function FillInHTMLTooltip(tipElement)
-{
-  var retVal = false;
-  var titleText = null;
-  var direction = tipElement.ownerDocument.dir;
-
-  while (!titleText && tipElement) {
-    if (tipElement.nodeType == Node.ELEMENT_NODE) {
-      titleText = tipElement.getAttribute("title");
-      var defView = tipElement.ownerDocument.defaultView;
-      // XXX Work around bug 350679:
-      // "Tooltips can be fired in documents with no view".
-      if (!defView)
-        return retVal;
-      direction = defView.getComputedStyle(tipElement, "")
-        .getPropertyValue("direction");
-    }
-    tipElement = tipElement.parentNode;
-  }
-
-  var tipNode = document.getElementById("aHTMLTooltip");
-  tipNode.style.direction = direction;
-
-  if (titleText && /\S/.test(titleText)) {
-    // Make CRLF and CR render one line break each.  
-    titleText = titleText.replace(/\r\n/g, '\n');
-    titleText = titleText.replace(/\r/g, '\n');
-    tipNode.setAttribute("label", titleText);
-    retVal = true;
-  }
-  return retVal;
-}
-
 function contextMenuShowing() {
   var isLink = false;
   var isEmail = false;
   if (gContextMenu.triggerNode && gContextMenu.triggerNode.localName == 'a') {
     if (gContextMenu.triggerNode.href.indexOf('view-source:') == 0)
       isLink = true;
     if (gContextMenu.triggerNode.href.indexOf('mailto:') == 0)
       isEmail = true;
--- a/toolkit/components/viewsource/content/viewSource.xul
+++ b/toolkit/components/viewsource/content/viewSource.xul
@@ -99,17 +99,17 @@
 #endif
 #ifdef XP_UNIX
     <key id="goBackKb2" key="&goBackCmd.commandKey;" command="Browser:Back" modifiers="accel"/>
     <key id="goForwardKb2" key="&goForwardCmd.commandKey;" command="Browser:Forward" modifiers="accel"/>
 #endif
 
   </keyset>
   
-  <tooltip id="aHTMLTooltip" onpopupshowing="return FillInHTMLTooltip(document.tooltipNode);"/>
+  <tooltip id="aHTMLTooltip" page="true"/>
 
   <menupopup id="viewSourceContextMenu"
              onpopupshowing="contextMenuShowing();">
     <menuitem id="context-back"
               label="&backCmd.label;"
               accesskey="&backCmd.accesskey;"
               command="Browser:Back"
               observes="viewSourceNavigation"/>
--- a/toolkit/content/widgets/popup.xml
+++ b/toolkit/content/widgets/popup.xml
@@ -506,16 +506,117 @@
       </property>
 
       <field name="_mouseOutCount">0</field>
       <field name="_isMouseOver">false</field>
       
       <property name="label"
                 onget="return this.getAttribute('label');"
                 onset="this.setAttribute('label', val); return val;"/>
+
+      <property name="page" onset="if (val) this.setAttribute('page', 'true');
+                                   else this.removeAttribute('page');
+                                   return val;"
+                            onget="return this.getAttribute('page') == 'true';"/>
+
+      <!-- Given the supplied element within a page, set the tooltip's text to the text
+           for that element. Returns true if text was assigned, and false if the no text
+           is set, which normally would be used to cancel tooltip display.
+
+           Note that DefaultTooltipTextProvider::GetNodeText() from nsDocShellTreeOwner.cpp
+           also performs the same function, but for embedded clients that don't use a XUL/JS
+           layer. These two should be kept synchronized.
+        --> 
+      <method name="fillInPageTooltip">
+        <parameter name="tipElement"/>
+        <body>
+        <![CDATA[
+          // Don't show the tooltip if the tooltip node is a document or disconnected.
+          if (!tipElement || !tipElement.ownerDocument ||
+              (tipElement.ownerDocument.compareDocumentPosition(tipElement) & document.DOCUMENT_POSITION_DISCONNECTED)) {
+            return false;
+          }
+
+          var defView = tipElement.ownerDocument.defaultView;
+          // XXX Work around bug 350679:
+          // "Tooltips can be fired in documents with no view".
+          if (!defView)
+            return false;
+
+          const XLinkNS = "http://www.w3.org/1999/xlink";
+          const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+
+          var titleText = null;
+          var XLinkTitleText = null;
+          var SVGTitleText = null;
+          var lookingForSVGTitle = true;
+          var direction = tipElement.ownerDocument.dir;
+
+          // If the element is invalid per HTML5 Forms specifications and has no title,
+          // show the constraint validation error message.
+          if ((tipElement instanceof HTMLInputElement ||
+               tipElement instanceof HTMLTextAreaElement ||
+               tipElement instanceof HTMLSelectElement ||
+               tipElement instanceof HTMLButtonElement) &&
+              !tipElement.hasAttribute('title') &&
+              (!tipElement.form || !tipElement.form.noValidate)) {
+            // If the element is barred from constraint validation or valid,
+            // the validation message will be the empty string.
+            titleText = tipElement.validationMessage || null;
+          }
+
+          while ((titleText == null) && (XLinkTitleText == null) &&
+                 (SVGTitleText == null) && tipElement) {
+            if (tipElement.nodeType == Node.ELEMENT_NODE &&
+                tipElement.namespaceURI != XULNS) {
+              titleText = tipElement.getAttribute("title");
+
+              if ((tipElement instanceof HTMLAnchorElement ||
+                   tipElement instanceof HTMLAreaElement ||
+                   tipElement instanceof HTMLLinkElement ||
+                   tipElement instanceof SVGAElement) && tipElement.href) {
+                XLinkTitleText = tipElement.getAttributeNS(XLinkNS, "title");
+              }
+              if (lookingForSVGTitle &&
+                  (!(tipElement instanceof SVGElement) ||
+                   tipElement.parentNode.nodeType == Node.DOCUMENT_NODE)) {
+                lookingForSVGTitle = false;
+              }
+              if (lookingForSVGTitle) {
+                for (let childNode of tipElement.childNodes) {
+                  if (childNode instanceof SVGTitleElement) {
+                    SVGTitleText = childNode.textContent;
+                    break;
+                  }
+                }
+              }
+
+              direction = defView.getComputedStyle(tipElement, "")
+                                 .getPropertyValue("direction");
+            }
+
+            tipElement = tipElement.parentNode;
+          }
+
+          this.style.direction = direction;
+
+          return [titleText, XLinkTitleText, SVGTitleText].some(function (t) {
+            if (t && /\S/.test(t)) {
+              // Make CRLF and CR render one line break each.
+              this.label = t.replace(/\r\n?/g, '\n');
+              return true;
+            }
+
+            return false;
+          }, this);
+
+          return false;
+        ]]>
+        </body>
+      </method>
     </implementation>
 
     <handlers>
       <handler event="mouseover"><![CDATA[
         var rel = event.relatedTarget;
         //dump("ENTERING " + (rel ? rel.localName : "null") + "\n");
         if (!rel)
           return;
@@ -556,16 +657,22 @@
         }
         
         // if the entered node is not a descendant of ours, hide the tooltip
         if (rel != this && this._isMouseOver) {
           this.hidePopup();
         }        
       ]]></handler>
 
+      <handler event="popupshowing"><![CDATA[
+        if (this.page && !this.fillInPageTooltip(this.triggerNode)) {
+          event.preventDefault();
+        }
+      ]]></handler>
+
       <handler event="popuphiding"><![CDATA[
         this._isMouseOver = false;
         this._mouseOutCount = 0;
       ]]></handler>
     </handlers>
   </binding>
 
   <binding id="popup-scrollbars" extends="chrome://global/content/bindings/popup.xml#popup">
--- a/toolkit/themes/windows/global/menu.css
+++ b/toolkit/themes/windows/global/menu.css
@@ -160,17 +160,21 @@ menubar > menu:-moz-window-inactive {
 /* ::::: menu/menuitems in popups ::::: */
 
 menupopup > menu,
 menupopup > menuitem {
   max-width: 42em;
 }
 
 menu[_moz-menuactive="true"],
+.menulist-menupopup > menu[_moz-menuactive="true"],
+menulist > menupopup > menu[_moz-menuactive="true"],
 menuitem[_moz-menuactive="true"],
+.menulist-menupopup > menuitem[_moz-menuactive="true"],
+menulist > menupopup > menuitem[_moz-menuactive="true"],
 .splitmenu-menuitem[_moz-menuactive="true"] {
   background-color: -moz-menuhover;
   color: -moz-menuhovertext;
 }
 
 /* ::::: menu/menuitems in menulist popups ::::: */
 
 .menulist-menupopup > menuitem,
@@ -211,17 +215,17 @@ menulist > menupopup > menuitem[_moz-men
   color: GrayText;
 }
 
 menulist > menupopup > menuitem[disabled="true"]:not([_moz-menuactive="true"]):-moz-system-metric(windows-classic) {
   color: GrayText;
   text-shadow: none;
 }
 
-menulist > menupopup > menuitem > .menu-iconic-text {
+menulist > menupopup > menuitem:not(.menuitem-iconic) > .menu-iconic-text {
   margin: 0 !important;
 }
 
 /* ::::: checkbox and radio menuitems ::::: */
 
 menuitem[type="checkbox"],
 menuitem[checked="true"] {
   -moz-appearance: checkmenuitem;
--- a/uriloader/exthandler/unix/nsGNOMERegistry.cpp
+++ b/uriloader/exthandler/unix/nsGNOMERegistry.cpp
@@ -125,17 +125,22 @@ nsGNOMERegistry::GetFromExtension(const 
     if (!gnomevfs)
       return nullptr;
 
     if (NS_FAILED(gnomevfs->GetMimeTypeFromExtension(aFileExt, mimeType)) ||
         mimeType.EqualsLiteral("application/octet-stream"))
       return nullptr;
   }
 
-  return GetFromType(mimeType);
+  nsRefPtr<nsMIMEInfoBase> mi = GetFromType(mimeType);
+  if (mi) {
+    mi->AppendExtension(aFileExt);
+  }
+
+  return mi.forget();
 }
 
 /* static */ already_AddRefed<nsMIMEInfoBase>
 nsGNOMERegistry::GetFromType(const nsACString& aMIMEType)
 {
   nsRefPtr<nsMIMEInfoUnix> mimeInfo = new nsMIMEInfoUnix(aMIMEType);
   NS_ENSURE_TRUE(mimeInfo, nullptr);
 
--- a/widget/android/AndroidJavaWrappers.h
+++ b/widget/android/AndroidJavaWrappers.h
@@ -762,18 +762,16 @@ public:
         LOCATION_EVENT = 5,
         IME_EVENT = 6,
         DRAW = 7,
         SIZE_CHANGED = 8,
         ACTIVITY_STOPPING = 9,
         ACTIVITY_PAUSING = 10,
         ACTIVITY_SHUTDOWN = 11,
         LOAD_URI = 12,
-        SURFACE_CREATED = 13,   // used by XUL fennec only
-        SURFACE_DESTROYED = 14, // used by XUL fennec only
         NOOP = 15,
         FORCED_RESIZE = 16, // used internally in nsAppShell/nsWindow
         ACTIVITY_START = 17,
         BROADCAST = 19,
         VIEWPORT = 20,
         VISITED = 21,
         NETWORK_CHANGED = 22,
         ACTIVITY_RESUMING = 24,
--- a/widget/android/nsAppShell.cpp
+++ b/widget/android/nsAppShell.cpp
@@ -621,31 +621,16 @@ nsAppShell::PostEvent(AndroidGeckoEvent 
         // set this to true when inserting events that we can coalesce
         // viewport events across. this is effectively maintaining a whitelist
         // of events that are unaffected by viewport changes.
         bool allowCoalescingNextViewport = false;
 
         MutexAutoLock lock(mQueueLock);
         EVLOG("nsAppShell::PostEvent %p %d", ae, ae->Type());
         switch (ae->Type()) {
-        case AndroidGeckoEvent::SURFACE_DESTROYED:
-            // Give priority to this event, and discard any pending
-            // SURFACE_CREATED events.
-            mEventQueue.InsertElementAt(0, ae);
-            AndroidGeckoEvent *event;
-            for (int i = mEventQueue.Length() - 1; i >= 1; i--) {
-                event = mEventQueue[i];
-                if (event->Type() == AndroidGeckoEvent::SURFACE_CREATED) {
-                    EVLOG("nsAppShell: Dropping old SURFACE_CREATED event at %p %d", event, i);
-                    mEventQueue.RemoveElementAt(i);
-                    delete event;
-                }
-            }
-            break;
-
         case AndroidGeckoEvent::COMPOSITOR_CREATE:
         case AndroidGeckoEvent::COMPOSITOR_PAUSE:
         case AndroidGeckoEvent::COMPOSITOR_RESUME:
             // Give priority to these events, but maintain their order wrt each other.
             {
                 uint32_t i = 0;
                 while (i < mEventQueue.Length() &&
                        (mEventQueue[i]->Type() == AndroidGeckoEvent::COMPOSITOR_CREATE ||