Merge mozilla-central to tracemonkey.
authorRobert Sayre <sayrer@gmail.com>
Fri, 14 Aug 2009 17:49:42 -0400
changeset 31831 553ce86e72dbd430e979e5387c76ae32967cb79f
parent 31826 ae4a9225ddcf6bc3a94519751f19982f7592c99d (current diff)
parent 31566 549f8ed44c5e113f990d5a88883146786e938354 (diff)
child 31832 1fd311e52b519563bf91479ce16080db5df3bc92
push id8746
push userrsayre@mozilla.com
push dateTue, 25 Aug 2009 16:53:43 +0000
treeherdermozilla-central@189759c41621 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone1.9.3a1pre
Merge mozilla-central to tracemonkey.
js/src/xpconnect/src/XPCDispObject.cpp
--- a/.hgtags
+++ b/.hgtags
@@ -27,8 +27,9 @@ 0000000000000000000000000000000000000000
 0cd41f5990807fb6ab52cb59ba3c8e8247281045 GECKO_1_9_1_BASE
 8df5a90281cd4d75835e4b7696da200555eed15f GECKO_1_9_1_BASE
 8a601ed6bc4c7b3d1e35aa9e81f257512d984bd5 FENNEC_A2
 d7d64f68423b68a671f623f123e90057ebc49dac UPDATE_PACKAGING_R7
 fb32f6e1859c07846a01b4478a7b1678019e0b45 UPDATE_PACKAGING_R7
 f817a4378f32b1ad0a7c4b5a9949586dba816da5 FENNEC_M11
 5c1e7c779b6edc8ff912001990edc579f80597f4 FENNEC_B1
 fe9cc55b8db7f56f7e68a246acba363743854979 UPDATE_PACKAGING_R8
+376b78fc72230aaf2ca4e279a8f4ef1efd4a1d9f GECKO_1_9_2_BASE
--- a/accessible/src/atk/nsAppRootAccessible.cpp
+++ b/accessible/src/atk/nsAppRootAccessible.cpp
@@ -436,16 +436,18 @@ mai_util_remove_key_event_listener (guin
 AtkObject *
 mai_util_get_root(void)
 {
     if (nsAccessibilityService::gIsShutdown) {
         // We've shutdown, try to use gail instead
         // (to avoid assert in spi_atk_tidy_windows())
         if (gail_get_root)
             return gail_get_root();
+
+        return nsnull;
     }
 
     nsRefPtr<nsApplicationAccessibleWrap> root =
         nsAccessNode::GetApplicationAccessible();
 
     if (root)
         return root->GetAtkObject();
 
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -1179,17 +1179,17 @@
             t.className = "tabbrowser-tab";
 
             this.mTabContainer.appendChild(t);
 
             if (this.tabContainer.mTabstrip._isRTLScrollbox) {
               /* In RTL UI, the tab is visually added to the left side of the
                * tabstrip. This means the tabstip has to be scrolled back in
                * order to make sure the same set of tabs is visible before and
-               * after the new tab is added */
+               * after the new tab is added.  See bug 508816. */
 
               this.tabContainer.mTabstrip.scrollByPixels(this.mTabs[0].clientWidth);
             }
 
             // invalidate cache, because mTabContainer is about to change
             this._browsers = null; 
 
             // If this new tab is owned by another, assert that relationship
--- a/browser/base/content/test/browser_bug495058.js
+++ b/browser/base/content/test/browser_bug495058.js
@@ -24,29 +24,28 @@ function next() {
     browser.loadURI(uri);
   }
 
   function detach() {
     var win = gBrowser.replaceTabWithWindow(tab);
     win.addEventListener("load", function () {
       win.removeEventListener("load", arguments.callee, false);
 
-      win.gBrowser.addEventListener("pageshow", function() {
-        win.gBrowser.removeEventListener("pageshow", arguments.callee, false);
+      var _delayedStartup = win.delayedStartup;
+      win.delayedStartup = function delayedStartup() {
+        _delayedStartup.apply(win, arguments);
+        win.delayedStartup = _delayedStartup;
 
-        // wait for delayedStartup
-        win.setTimeout(function () {
-          is(win.gBrowser.currentURI.spec, uri, uri + ": uri loaded in detached tab");
-          is(win.document.activeElement, win.gBrowser.selectedBrowser, uri + ": browser is focused");
-          is(win.gURLBar.value, "", uri + ": urlbar is empty");
-          ok(win.gURLBar.emptyText, uri + ": emptytext is present");
-          ok(win.gURLBar.hasAttribute("isempty"), uri + ": emptytext is displayed");
+        is(win.gBrowser.currentURI.spec, uri, uri + ": uri loaded in detached tab");
+        is(win.document.activeElement, win.gBrowser.selectedBrowser, uri + ": browser is focused");
+        is(win.gURLBar.value, "", uri + ": urlbar is empty");
+        ok(win.gURLBar.emptyText, uri + ": emptytext is present");
+        ok(win.gURLBar.hasAttribute("isempty"), uri + ": emptytext is displayed");
 
-          win.close();
-          if (uris.length)
-            next();
-          else
-            executeSoon(finish);
-        }, 100);
-      }, false);
+        win.close();
+        if (uris.length)
+          next();
+        else
+          executeSoon(finish);
+      };
     }, false);
   }
 }
--- a/browser/components/places/content/places.css
+++ b/browser/components/places/content/places.css
@@ -1,25 +1,29 @@
 tree[type="places"] {
   -moz-binding: url("chrome://browser/content/places/tree.xml#places-tree");
 }
 
 hbox[type="places"] {
   -moz-binding: url("chrome://browser/content/places/toolbar.xml#places-bar");
-  overflow: hidden;
 }
 
 .bookmarks-toolbar-customize,
 toolbarpaletteitem .bookmarks-toolbar-items {
   display: none;
 }
 
 toolbarpaletteitem .bookmarks-toolbar-customize {
   display: -moz-box;
 }
 
+.toolbar-drop-indicator {
+  position: relative;
+  z-index: 1;
+}
+
 menupopup[type="places"] {
   -moz-binding: url("chrome://browser/content/places/menu.xml#places-menupopup");
 }
 
 menupopup[placespopup="true"] {
   -moz-binding: url("chrome://browser/content/places/menu.xml#places-popup-base");
 }
--- a/browser/components/places/content/toolbar.xml
+++ b/browser/components/places/content/toolbar.xml
@@ -52,132 +52,148 @@
           xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
   <binding id="places-bar">
     <resources>
       <stylesheet src="chrome://browser/skin/places/places.css"/>
     </resources>
 
     <content>
-      <xul:vbox>
-        <xul:hbox class="toolbar-drop-indicator-bar">
-          <xul:hbox class="toolbar-drop-indicator"/>
-        </xul:hbox>
+        <xul:toolbarbutton class="bookmark-item bookmarks-toolbar-customize"
+                           mousethrough="never"
+                           label="&bookmarksToolbarItem.label;"/>
         <xul:hbox flex="1">
-          <xul:hbox class="bookmarks-toolbar-items" flex="1">
-            <children/>
+          <xul:hbox align="center">
+            <xul:image class="toolbar-drop-indicator"
+                       mousethrough="always"
+                       collapsed="true"/>
           </xul:hbox>
-          <xul:toolbarbutton class="bookmark-item bookmarks-toolbar-customize"
-                             mousethrough="never"
-                             label="&bookmarksToolbarItem.label;"/>
+          <xul:scrollbox orient="horizontal"
+                         class="bookmarks-toolbar-items"
+                         flex="1">
+            <children/>
+          </xul:scrollbox>
+          <xul:hbox mousethrough="always"
+                    pack="end">
+            <xul:toolbarbutton type="menu"
+                               class="chevron"
+                               mousethrough="never"
+                               collapsed="true"
+                               tooltiptext="&bookmarksToolbarChevron.tooltip;"
+                               onpopupshowing="_onChevronPopupShowing(event);">
+              <xul:menupopup anonid="chevronPopup"
+                             xbl:inherits="tooltip"
+#ifndef XP_MACOSX
+                             context="placesContext"
+#endif
+              />
+            </xul:toolbarbutton>
+          </xul:hbox>
         </xul:hbox>
-      </xul:vbox>
-      <xul:hbox mousethrough="always"
-                flex="1"
-                pack="end">
-        <xul:toolbarbutton type="menu"
-                           class="chevron"
-                           mousethrough="never"
-                           collapsed="true"
-                           tooltiptext="&bookmarksToolbarChevron.tooltip;"
-                           onpopupshowing="chevronPopupShowing(event);">
-          <xul:menupopup anonid="chevronPopup"
-                         xbl:inherits="tooltip"
-#ifndef XP_MACOSX
-                         context="placesContext"
-#endif
-          />
-        </xul:toolbarbutton>
-      </xul:hbox>
     </content>
 
-    <implementation implements="nsIAccessibleProvider, nsITimerCallback">
+    <implementation implements="nsIAccessibleProvider, nsITimerCallback, nsIDOMEventListener">
       <constructor><![CDATA[
         this._init();
       ]]></constructor>
 
       <destructor><![CDATA[
+        this._scrollbox.removeEventListener("overflow", this, false);
+        this._scrollbox.removeEventListener("underflow", this, false);
+        window.removeEventListener("resize", this, false);
+
         if (this._result) {
           this._result.viewer = null;
           this._result = null;
         }
       ]]></destructor>
 
       <property name="controller"
                 readonly="true"
                 onget="return this._controller;"/>
 
       <method name="_init">
         <body><![CDATA[
         this._controller = new PlacesController(this);
         this.controllers.appendController(this._controller);
 
-        var t = this;
-        window.addEventListener("resize",
-                                function f(e) { t.updateChevron(e); },
-                                false);
+        this._scrollbox.addEventListener("overflow", this, false);
+        this._scrollbox.addEventListener("underflow", this, false);
+        window.addEventListener("resize", this, false);
 
         if (this.hasAttribute("place")) {
-          // Do the initial build. 
+          // Do the initial build.
           this.place = this.place;
         }
         ]]></body>
       </method>
 
-      <field name="_dropIndicatorBar">document.getAnonymousElementByAttribute(this, "class", "toolbar-drop-indicator-bar")</field>
-      <field name="_chevron">document.getAnonymousElementByAttribute(this, "class", "chevron")</field>
+      <field name="_scrollbox">
+        document.getAnonymousElementByAttribute(this, "class",
+                                                "bookmarks-toolbar-items")
+      </field>
+      <field name="_dropIndicator">
+        document.getAnonymousElementByAttribute(this, "class",
+                                                "toolbar-drop-indicator")
+      </field>
+      <field name="_chevron">
+        document.getAnonymousElementByAttribute(this, "class", "chevron")
+      </field>
+      <field name="_chevronPopup">this._chevron.lastChild</field>
 
       <field name="_openedMenuButton">null</field>
       <field name="_allowPopupShowing">true</field>
 
       <field name="_result">null</field>
       <field name="_resultNode">null</field>
 
+      <field name="_isRTL">
+        document.defaultView.getComputedStyle(this.parentNode, "")
+                            .direction == "rtl"
+      </field>
+
       <!-- nsIPlacesView -->
       <method name="getResult">
         <body><![CDATA[
           return this._result;
         ]]></body>
       </method>
 
       <!-- nsIPlacesView -->
       <method name="getResultNode">
         <body><![CDATA[
           return this._result.root;
         ]]></body>
       </method>
 
       <method name="_rebuild">
         <body><![CDATA[
-          // Clear out references to existing nodes, since we'll be deleting and re-adding.
+          // Clear out references to existing nodes, since they will be removed
+          // and re-added.
           if (this._overFolder.node)
             this._clearOverFolder();
           this._openedMenuButton = null;
 
           while (this.hasChildNodes())
             this.removeChild(this.firstChild);
 
           var rootNode = this._result.root;
           var cc = rootNode.childCount;
-          for (var i = 0; i < cc; ++i)
+          for (let i = 0; i < cc; ++i)
             this.insertNewItem(rootNode.getChild(i), null);
 
-          var chevronPopup = this._chevron.lastChild;
-          if (chevronPopup.hasAttribute("type")) {
-            // Otherwise we'll set it when the chevron is enabled (see updateChevron)
-            chevronPopup.place = this.place;
+          if (this._chevronPopup.hasAttribute("type")) {
+            // Chevron has already been initialized, but since we are forcing
+            // a rebuild of the toolbar, it has to be rebuilt.
+            // Otherwise, it will be initialized when the toolbar overflows.
+            this._chevronPopup.place = this.place;
           }
 
           while (chevronPopup.hasChildNodes())
-            chevronPopup.removeChild(chevronPopup.lastChild);
-
-          // This needs to be in a timeout to make sure our boxObject has time
-          // to get its proper size
-          var t = this;
-          setTimeout(function() { t.updateChevron(); }, 0);
+            this._chevronPopup.removeChild(this._chevronPopup.lastChild);
         ]]></body>
       </method>
 
       <method name="insertNewItem">
         <parameter name="aChild"/>
         <parameter name="aBefore"/>
         <body><![CDATA[
           var type = aChild.type;
@@ -231,103 +247,126 @@
             this.appendChild(button);
         ]]></body>
       </method>
 
       <method name="removeItem">
         <parameter name="child"/>
         <body><![CDATA[
           if (PlacesUtils.nodeIsContainer(child.node)) {
-            for (var i=0; i < this._containerNodesMap.length; i++) {
+            for (let i = 0; i < this._containerNodesMap.length; i++) {
               if (this._containerNodesMap[i].resultNode == child.node) {
                 this._containerNodesMap.splice(i, 1);
                 break;
               }
             }
           }
 
           // if document.popupNode pointed to this child, null it out,
           // otherwise controller's command-updating may rely on the removed
           // item still being "selected".
           if (document.popupNode == child)
             document.popupNode = null;
           child.parentNode.removeChild(child);
         ]]></body>
       </method>
 
-      <method name="chevronPopupShowing">
+      <method name="_updateChevronPopupNodesVisibility">
+        <body><![CDATA[
+          for (let i = 0; i < this._chevronPopup.childNodes.length; i++) {
+            this._chevronPopup.childNodes[i].hidden =
+              this.childNodes[i].style.visibility != "hidden";
+          }
+        ]]></body>
+      </method>
+
+      <method name="_onChevronPopupShowing">
         <parameter name="aEvent"/>
         <body><![CDATA[
-          var popup = aEvent.target;
-          if (popup != this._chevron.firstChild)
+          // Handle popupshowing only for the chevron popup, not for
+          // nested ones.
+          if (aEvent.target != this._chevronPopup)
             return;
 
-          for (var i = 0; i < popup.childNodes.length; i++)
-            popup.childNodes[i].hidden = !this.childNodes[i].collapsed;
+          this._updateChevronPopupNodesVisibility();
         ]]></body>
       </method>
 
-      <method name="getElementWidth">
-        <parameter name="element"/>
+      <method name="handleEvent">
+        <parameter name="aEvent"/>
         <body><![CDATA[
-          var style = document.defaultView.getComputedStyle(element, "");
-          var leftMargin = style.getPropertyValue("margin-left");
-          leftMargin = leftMargin ? Math.round(parseFloat(leftMargin)) : 0;
-          var rightMargin = style.getPropertyValue("margin-right");
-          rightMargin = rightMargin ? Math.round(parseFloat(rightMargin)) : 0;
-          return element.boxObject.width + leftMargin + rightMargin;
+          // Both overflow/underflow and resize events should not be handled
+          // for descendant nodes.
+          if (aEvent.target != aEvent.currentTarget)
+            return;
+
+          switch (aEvent.type) {
+            case "resize":
+              // This handler updates nodes visibility in both the toolbar
+              // and the chevron popup when a window resize does not change
+              // the overflow status of the toolbar.
+              break;
+
+            case "overflow":
+              // Attach the popup binding to the chevron popup if it has not yet
+              // been initialized.
+              if (!this._chevronPopup.hasAttribute("type")) {
+                this._chevronPopup.setAttribute("place", this.place);
+                this._chevronPopup.setAttribute("type", "places");
+              }
+              this._chevron.collapsed = false;
+              break;
+
+            case "underflow":
+              this._chevron.collapsed = true;
+              break;
+          }
+
+          this.updateChevron();
         ]]></body>
       </method>
 
       <method name="updateChevron">
-        <parameter name="event"/>
         <body><![CDATA[
-          // Ignore events that aren't on the document or the window
-          // (html document, tooltips, etc)
-          // Do not ignore content window resizes, because they may
-          // be the result of the toolbar being shown/hidden
-          if (event && event.target != document && event.target != window &&
-              event.target != content)
+          // If the chevron is collapsed there's nothing to update.
+          if (this._chevron.collapsed)
             return;
 
-          if (this.childNodes.length == 0) {
-            this._chevron.collapsed = true;
-            return;
-          }
+          // XXX (bug 508816) Scrollbox does not handle correctly RTL mode.
+          // This workarounds the issue scrolling the box to the right.
+          if (this._isRTL)
+            this._scrollbox.scrollLeft = this._scrollbox.scrollWidth;
+
+          // Update the chevron on a timer.  This will avoid repeated work when
+          // lot of changes happen in a small timeframe.
+          if (this._updateChevronTimer)
+            this._updateChevronTimer.cancel();
+          this._updateChevronTimer = this._setTimer(100);
+        ]]></body>
+      </method>
 
-          var spaceLeft = this.boxObject.width;
-          this._chevron.collapsed = false;
-          var chevronWidth = this._chevron.boxObject.width;
-          var overflowed = false;
-          for (var i = 0; i < this.childNodes.length; i++) {
-            var child = this.childNodes[i];
-            child.collapsed = false;
-            spaceLeft -= this.getElementWidth(child);
-            var spaceNeeded = (i == this.childNodes.length - 1) ? 0 : chevronWidth;
-            if (spaceLeft < spaceNeeded) {
-              overflowed = true;
-              child.collapsed = true;
+      <method name="_updateChevronTimerCallback">
+        <body><![CDATA[
+          var scrollRect = this._scrollbox.getBoundingClientRect();
+          var childOverflowed = false;
+          for (let i = 0; i < this.childNodes.length; i++) {
+            let child = this.childNodes[i];
+            // Once a child overflows, all the next ones will.
+            if (!childOverflowed) {
+              let childRect = child.getBoundingClientRect();
+              childOverflowed = this._isRTL ? (childRect.left < scrollRect.left)
+                                            : (childRect.right > scrollRect.right);
             }
-          }
-          if (!(this._chevron.collapsed = !overflowed)) {
-            // Attach the popup binding to the chevron popup
-            var popup = this._chevron.firstChild;
-            if (!popup.hasAttribute("type")) {
-              popup.setAttribute("place", this.place);
-              popup.setAttribute("type", "places");
-            }
+            child.style.visibility = childOverflowed ? "hidden" : "visible";
           }
 
           // We rebuild the chevron on popupShowing, so if it is open
-          // we must force a rebuild
-          if (this._chevron.open) {
-            var popup = this._chevron.firstChild;
-            for (var i = 0; i < popup.childNodes.length; i++)
-              popup.childNodes[i].hidden = !this.childNodes[i].collapsed;
-          }
+          // we must update it.
+          if (this._chevron.open)
+            this._updateChevronPopupNodesVisibility();
         ]]></body>
       </method>
 
       <!-- nsIPlacesView -->
       <property name="place">
         <getter><![CDATA[
           return this.getAttribute("place");
         ]]></getter>
@@ -454,17 +493,17 @@
       <field name="_viewer"><![CDATA[({
         _self: this,
 
         _getPopupForContainer:
         function PMV__getPopupForContainer(aNode) {
           if (this._self._resultNode == aNode)
             return this._self;
 
-          for (var i=0; i < this._self._containerNodesMap.length; i++) {
+          for (let i = 0; i < this._self._containerNodesMap.length; i++) {
             if (this._self._containerNodesMap[i].resultNode == aNode)
               return this._self._containerNodesMap[i].domNode;
           }
           throw("Container view not found");
         },
 
         get result() {
           return this._self._result;
@@ -506,31 +545,31 @@
             if (popup._emptyMenuItem)
               popup._emptyMenuItem.hidden = true;
           }
         },
 
         itemRemoved: function TV_V_itemRemoved(aParentNode, aNode, aIndex) {
           if (aParentNode == this._self.getResultNode()) {
             var children = this._self.childNodes;
-            for (var i = 0; i < children.length; i++) {
+            for (let i = 0; i < children.length; i++) {
               if (children[i].node == aNode) {
                 this._self.removeItem(children[i]);
                 this._self.updateChevron();
                 return;
               }
             }
           }
           else {
             var popup = this._getPopupForContainer(aParentNode);
             if (!popup._built)
               return;
 
             var children = popup.childNodes;
-            for (var i = popup._startMarker + 1; i < children.length; i++) {
+            for (let i = popup._startMarker + 1; i < children.length; i++) {
               if (children[i].node == aNode) {
                 this._self.removeItem(children[i]);
                 if (!popup.hasChildNodes() ||
                     (popup.childNodes.length == 1 &&
                      popup.firstChild == popup._emptyMenuItem)) {
                   this._self._showEmptyMenuItem(popup);
                 }
                 if (popup._endMarker != -1)
@@ -545,38 +584,38 @@
         function TV_V_itemMoved(aItem, aOldParent, aOldIndex, aNewParent,
                                 aNewIndex) {
           // This cannot actually happen yet (see IDL)
           if (aNewParent != aOldParent)
             return;
 
           if (aNewParent == this._self.getResultNode()) {
             var children = this._self.childNodes;
-            var chevronPopup = this._self._chevron.firstChild;
-            for (var i = 0; i < children.length; i++) {
+            for (let i = 0; i < children.length; i++) {
               var button = children[i];
               if (button.node == aItem) {
                 this._self.removeChild(button);
                 this._self.insertBefore(button, children[aNewIndex]);
-                if (chevronPopup) {
-                  // Maintain chevron in sync
+                // If the chevron popup is open, keep it in sync.
+                if (this._self._chevron.open) {
+                  var chevronPopup = this._self._chevronPopup;
                   var menuitem = chevronPopup.childNodes[i];
                   chevronPopup.removeChild(menuitem);
                   chevronPopup.insertBefore(menuitem,
                                             chevronPopup.childNodes[aNewIndex]);
                 }
                 this._self.updateChevron();
                 return;
               }
             }
           }
           else {
             var popup = this._getPopupForContainer(aNewParent);
             var children = popup.childNodes;
-            for (var i = popup._startMarker + 1; i < children.length; i++) {
+            for (let i = popup._startMarker + 1; i < children.length; i++) {
               var menuItem = children[i];
               if (menuItem.node == aItem) {
                 popup.removeChild(menuItem);
                 popup.insertBefore(menuItem, children[aNewIndex]);
                 return;
               }
             }
           }
@@ -593,32 +632,32 @@
             return;
           }
 
           var element;
           var onToolbar = false;
           if (parentNode == this._self.getResultNode()) {
             onToolbar = true;
             var children = this._self.childNodes;
-            for (var i = 0; i < children.length; i++) {
+            for (let i = 0; i < children.length; i++) {
               if (children[i].node == aNode) {
                 element = children[i];
                 break;
               }
             }
             // Don't replace title on toolbarbuttons
             var title = aNode.title;
           }
           else {
             var popup = this._getPopupForContainer(parentNode);
             if (!popup._built)
               return;
 
             var children = popup.childNodes;
-            for (var i = popup._startMarker + 1; i < children.length; i++) {
+            for (let i = popup._startMarker + 1; i < children.length; i++) {
               if (children[i].node == aNode) {
                 element = children[i];
                 break;
               }
             }
             var title = PlacesUIUtils.getBestTitle(aNode);
           }
 
@@ -648,17 +687,17 @@
             element.setAttribute("scheme", PlacesUIUtils.guessUrlSchemeForUI(aNode.uri));
           }
         },
 
         itemReplaced:
         function TV_V_itemReplaced(aParentNode, aOldNode, aNewNode, aIndex) {
           if (aParentNode == this._self.getResultNode()) {
             var children = this._self.childNodes;
-            for (var i = 0; i < children.length; i++) {
+            for (let i = 0; i < children.length; i++) {
               if (children[i].node == aOldNode) {
                 var next = children[i].nextSibling;
                 this._self.removeItem(children[i]);
                 this._self.insertNewItem(aNewNode, next);
                 this._self.updateChevron();
                 return;
               }
             }
@@ -686,17 +725,17 @@
               if (parent == container)
                 return true;
               parent = parent.parent;
             }
             return false;
           }
 
           var popupToRebuild = null;
-          for (var i=0; i < this._self._containerNodesMap.length; i++) {
+          for (let i = 0; i < this._self._containerNodesMap.length; i++) {
             var node = this._self._containerNodesMap[i].resultNode;
             
             if (node == aContainer)
               popupToRebuild = this._self._containerNodesMap[i].domNode;
             if (isChildOf(node, aContainer)) {
               this._self._containerNodesMap.splice(i,1);
               i--;
             }
@@ -766,18 +805,18 @@
 
           if (aBefore)
             aParentPopup.insertBefore(element, aBefore);
           else {
             // Add the new element to the menu.  If there is static content at
             // the end of the menu, add the element before that.  Otherwise,
             // just add to the end.
             if (aParentPopup._endMarker != -1) {
-              aParentPopup.insertBefore(element,
-                                        aParentPopup.childNodes[aParentPopup._endMarker]);
+              let lastNode = aParentPopup.childNodes[aParentPopup._endMarker];
+              aParentPopup.insertBefore(element, lastNode);
             }
             else
               aParentPopup.appendChild(element);
           }
 
           if (aParentPopup._endMarker != -1)
             aParentPopup._endMarker++;
         ]]></body>
@@ -805,17 +844,17 @@
           if (!resultNode.containerOpen)
             resultNode.containerOpen = true;
 
           var cc = resultNode.childCount;
           if (cc > 0) {
             if (aPopup._emptyMenuItem)
               aPopup._emptyMenuItem.hidden = true;
 
-            for (var i = 0; i < cc; ++i) {
+            for (let i = 0; i < cc; ++i) {
               var child = resultNode.getChild(i);
               this.insertNewItemToPopup(child, aPopup, null);
             }
           }
           else {
             // This menu is empty.  If there is no static content, add
             // an element to show it is empty.
             if (aPopup._startMarker == -1 && aPopup._endMarker == -1)
@@ -856,83 +895,96 @@
           }
         ]]></body>
       </method>
 
       <method name="_getDropPoint">
         <parameter name="aEvent"/>
         <body><![CDATA[
           // This function returns information about where to drop when
-          // dragging over this menu--insertion point, child index to drop
-          // before, and folder to drop into.
-          // Can't drop if the toolbar isn't a folder.
+          // dragging over the toolbar.
+          // The returned object has 3 properties:
+          // - ip: the insertion point for the bookmarks service.
+          // - beforeIndex: child index to drop before, for the drop indicator.
+          // - folderNode: the folder to drop into, if applicable.
           var result = this.getResult();
           if (!PlacesUtils.nodeIsFolder(result.root))
             return null;
 
-          var isRTL = document.defaultView
-                              .getComputedStyle(this.parentNode, "")
-                              .direction == "rtl";
-
           var dropPoint = { ip: null, beforeIndex: null, folderNode: null };
-          // Loop through all the nodes to see which one this should
-          // get dropped in/next to
-          for (var i = 0; i < this.childNodes.length; i++) {
-            var xulNode = this.childNodes[i];
+          var xulNode = aEvent.target;
+          if (xulNode.node) {
+            let nodeRect = xulNode.getBoundingClientRect();
+            let nodeIndex = Array.indexOf(this.childNodes, xulNode);
             if (PlacesUtils.nodeIsFolder(xulNode.node) &&
                 !PlacesUtils.nodeIsReadOnly(xulNode.node)) {
-              // This is a folder. If the mouse is in the left 25% of the
-              // node (or 25% of the right, in RTL UI), drop before the folder.
-              // If it's in the middle 50%, drop into the folder. If it's past
-              // that, drop after.
-              if ((isRTL && aEvent.clientX > xulNode.boxObject.x +
-                                             (xulNode.boxObject.width * 0.75)) ||
-                  (!isRTL && aEvent.clientX < xulNode.boxObject.x + 
-                                              (xulNode.boxObject.width * 0.25))) {
-                // Drop to the left of this folder.
+              // This is a folder.
+              // If we are in the middle of it, drop inside it.
+              // Otherwise, drop before it, with regards to RTL mode.
+              let threshold = nodeRect.width * 0.25;
+              if (this._isRTL ? (aEvent.clientX > nodeRect.right - threshold)
+                              : (aEvent.clientX < nodeRect.left + threshold)) {
+                // Drop before this folder.
                 dropPoint.ip =
                   new InsertionPoint(PlacesUtils.getConcreteItemId(result.root),
-                                     i, -1);
-                dropPoint.beforeIndex = i;
-                return dropPoint;
+                                     nodeIndex, Ci.nsITreeView.DROP_BEFORE);
+                dropPoint.beforeIndex = nodeIndex;
               }
-              else if ((isRTL && aEvent.clientX > xulNode.boxObject.x + 
-                                                  (xulNode.boxObject.width * 0.25)) ||
-                       (!isRTL && aEvent.clientX < xulNode.boxObject.x +
-                                                   (xulNode.boxObject.width * 0.75))) {
+              else if (this._isRTL ? (aEvent.clientX > nodeRect.left + threshold)
+                                   : (aEvent.clientX < nodeRect.right - threshold)) {
                 // Drop inside this folder.
                 dropPoint.ip =
                   new InsertionPoint(PlacesUtils.getConcreteItemId(xulNode.node),
-                                     -1, 1,
+                                     -1, Ci.nsITreeView.DROP_ON,
                                      PlacesUtils.nodeIsTagQuery(xulNode.node));
-                dropPoint.beforeIndex = i;
+                dropPoint.beforeIndex = nodeIndex;
                 dropPoint.folderNode = xulNode;
-                return dropPoint;
+              }
+              else {
+                // Drop after this folder.
+                let beforeIndex =
+                  (nodeIndex == this.childNodes.length - 1) ? -1 : nodeIndex + 1;
+                dropPoint.ip =
+                  new InsertionPoint(PlacesUtils.getConcreteItemId(result.root),
+                                     beforeIndex, Ci.nsITreeView.DROP_BEFORE);
+                dropPoint.beforeIndex = beforeIndex;
               }
             }
             else {
-              // This is a non-folder node. If the mouse is left (or right, in
-              // RTL UI) of the middle, drop before the folder.  Otehrwise,
-              // we'll drop after
-              if ((isRTL && aEvent.clientX > xulNode.boxObject.x + (xulNode.boxObject.width / 2)) ||
-                  (!isRTL && aEvent.clientX < xulNode.boxObject.x + (xulNode.boxObject.width / 2))) {
+              // This is a non-folder node or a read-only folder.
+              // Drop before it with regards to RTL mode.
+              let threshold = nodeRect.width * 0.5;
+              if (this._isRTL ? (aEvent.clientX > nodeRect.left + threshold)
+                              : (aEvent.clientX < nodeRect.left + threshold)) {
                 // Drop before this bookmark.
                 dropPoint.ip =
 	                new InsertionPoint(PlacesUtils.getConcreteItemId(result.root),
-	                                   i, -1);
-                dropPoint.beforeIndex = i;
-                return dropPoint;
+	                                   nodeIndex, Ci.nsITreeView.DROP_BEFORE);
+                dropPoint.beforeIndex = nodeIndex;
+              }
+              else {
+                // Drop after this bookmark.
+                let beforeIndex =
+                  nodeIndex == this.childNodes.length - 1 ? -1 : nodeIndex + 1;
+                dropPoint.ip =
+                  new InsertionPoint(PlacesUtils.getConcreteItemId(result.root),
+                                     beforeIndex, Ci.nsITreeView.DROP_BEFORE);
+                dropPoint.beforeIndex = beforeIndex;
               }
             }
           }
-          // Should drop after the last node.
-          dropPoint.ip =
-        	  new InsertionPoint(PlacesUtils.getConcreteItemId(result.root),
-	                             -1, 1);
-          dropPoint.beforeIndex = -1;
+          else {
+            // We are most likely dragging on the empty area of the
+            // toolbar, we should drop after the last node.
+            dropPoint.ip =
+              new InsertionPoint(PlacesUtils.getConcreteItemId(result.root),
+                                 -1, Ci.nsITreeView.DROP_BEFORE);
+            dropPoint.beforeIndex = -1;
+          }
+
           return dropPoint;
         ]]></body>
       </method>
 
       <method name="_setTimer">
         <parameter name="aTime"/>
         <body><![CDATA[
           var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
@@ -942,36 +994,41 @@
       </method>
 
       <!-- nsITimerCallback -->
       <method name="notify">
         <parameter name="aTimer"/>
         <body><![CDATA[
           // Function to process all timer notifications.
 
+          if (aTimer == this._updateChevronTimer) {
+            this._updateChevronTimer = null;
+            this._updateChevronTimerCallback();
+          }
+
           // * Timer to turn off indicator bar.
-          if (aTimer == this._ibTimer) {
-            this._dropIndicatorBar.removeAttribute('dragging');
+          else if (aTimer == this._ibTimer) {
+            this._dropIndicator.collapsed = true;
             this._ibTimer = null;
           }
 
           // * Timer to open a menubutton that's being dragged over.
-          if (aTimer == this._overFolder.openTimer) {
+          else if (aTimer == this._overFolder.openTimer) {
             // Set the autoopen attribute on the folder's menupopup so that
             // the menu will automatically close when the mouse drags off of it.
             this._overFolder.node.lastChild.setAttribute("autoopened", "true");
             this._overFolder.node.open = true;
             this._overFolder.openTimer = null;
           }
 
           // * Timer to close a menubutton that's been dragged off of.
-          if (aTimer == this._overFolder.closeTimer) {
-            // Only close the menubutton if the drag session isn't currently over
-            // it or one of its children.  (The autoopened attribute will let the menu
-            // know to close later if the menu is still being dragged over.)
+          else if (aTimer == this._overFolder.closeTimer) {
+            // Close the menubutton if we are not dragging over it or one of
+            // its children.  The autoopened attribute will let the menu know to
+            // close later if the menu is still being dragged over.
             var currentNode = PlacesControllerDragHelper.currentDropTarget;
             var inHierarchy = false;
             while (currentNode) {
               if (currentNode == this) {
                 inHierarchy = true;
                 break;
               }
               currentNode = currentNode.parentNode;
@@ -1038,20 +1095,19 @@
         event.stopPropagation();
       ]]></handler>
 
       <handler event="dragover"><![CDATA[
         // Cache the dataTransfer
         var dt = PlacesControllerDragHelper.currentDataTransfer =
                  event.dataTransfer;
 
-        var ib = this._dropIndicatorBar;
         var ip = this.insertionPoint;
         if (!ip || !PlacesControllerDragHelper.canDrop(ip)) {
-          ib.removeAttribute("dragging");
+          this._dropIndicator.collapsed = true;
           PlacesControllerDragHelper.currentDataTransfer = null;
           return;
         }
 
         PlacesControllerDragHelper.currentDropTarget = event.target;
         var dropPoint = this._getDropPoint(event);
 
         if (this._ibTimer) {
@@ -1067,53 +1123,51 @@
           if (this._overFolder.node != overNode) {
             this._clearOverFolder();
             this._overFolder.node = overNode;
             this._overFolder.openTimer = this._setTimer(this._overFolder.hoverTime);
           }
           if (!this._overFolder.node.hasAttribute("dragover"))
             this._overFolder.node.setAttribute("dragover", "true");
 
-          ib.removeAttribute("dragging");
+          this._dropIndicator.collapsed = true;
         }
         else {
           // Dragging over a normal toolbarbutton,
           // show indicator bar and move it to the appropriate drop point.
-          if (!ib.hasAttribute("dragging"))
-            ib.setAttribute("dragging", "true");
-          var ind = ib.firstChild;
-          var halfInd = ind.boxObject.width / 2;
-          var direction = document.defaultView.getComputedStyle(this.parentNode, "").direction;
-          if (direction == "ltr") {
+          let ind = this._dropIndicator;
+          let halfInd = ind.clientWidth / 2;
+          let translateX;
+          if (this._isRTL) {
             halfInd = Math.ceil(halfInd);
-          if (!this.childNodes.length)
-            ind.style.marginLeft = 0 - this.boxObject.x - halfInd + 'px'
-          else if (dropPoint.beforeIndex == -1)
-            ind.style.marginLeft = this.lastChild.boxObject.x + 
-                                   this.lastChild.boxObject.width - this.boxObject.x - halfInd + 'px';
-          else
-            ind.style.marginLeft = this.childNodes[dropPoint.beforeIndex].boxObject.x -
-                                   this.boxObject.x - halfInd + 'px';
+            translateX = 0 - this._scrollbox.getBoundingClientRect().right -
+                             halfInd;
+            if (dropPoint.beforeIndex == -1)
+              translateX += this.lastChild.getBoundingClientRect().left;
+            else if (this.childNodes.length) {
+              translateX += this.childNodes[dropPoint.beforeIndex]
+                                .getBoundingClientRect().right;
+            }
           }
           else {
             halfInd = Math.floor(halfInd);
-            if (this.childNodes.length == 0)
-              ind.style.marginRight = this.boxObject.width + 'px';
-            else if (dropPoint.beforeIndex == -1) {
-              ind.style.marginRight = this.boxObject.width -
-                                      (this.childNodes[this.childNodes.length - 1].boxObject.x +
-                                      halfInd) +'px';
-            }
-            else {
-              ind.style.marginRight = this.boxObject.width -
-                                      (this.childNodes[dropPoint.beforeIndex].boxObject.x +
-                                       this.childNodes[dropPoint.beforeIndex].boxObject.width -
-                                      this.boxObject.x + halfInd) + 'px';
+            translateX = 0 - this._scrollbox.getBoundingClientRect().left +
+                         halfInd;
+            if (dropPoint.beforeIndex == -1)
+              translateX += this.lastChild.getBoundingClientRect().right;
+            else if (this.childNodes.length) {
+              translateX += this.childNodes[dropPoint.beforeIndex]
+                                .getBoundingClientRect().left;
             }
           }
+
+          ind.style.MozTransform = "translate(" + Math.round(translateX) + "px)";
+          ind.style.MozMarginStart = (-ind.clientWidth) + "px";
+          ind.collapsed = false;
+
           // Clear out old folder information
           this._clearOverFolder();
         }
 
         dt.effectAllowed = "all";
         event.preventDefault();
         event.stopPropagation();
       ]]></handler>
--- a/browser/components/preferences/applications.js
+++ b/browser/components/preferences/applications.js
@@ -1870,17 +1870,17 @@ var gApplicationsPane = {
 
     // Unfortunately we can't use the favicon service to get the favicon,
     // because the service looks in the annotations table for a record with
     // the exact URL we give it, and users won't have such records for URLs
     // they don't visit, and users won't visit the web app's URL template,
     // they'll only visit URLs derived from that template (i.e. with %s
     // in the template replaced by the URL of the content being handled).
 
-    if (/^https?/.test(uri.scheme))
+    if (/^https?/.test(uri.scheme) && this._prefSvc.getBoolPref("browser.chrome.favicons"))
       return uri.prePath + "/favicon.ico";
 
     return "";
   },
 
   _getIconURLForSystemDefault: function(aHandlerInfo) {
     // Handler info objects for MIME types on some OSes implement a property bag
     // interface from which we can get an icon for the default app, so if we're
--- a/browser/components/sessionstore/nsISessionStore.idl
+++ b/browser/components/sessionstore/nsISessionStore.idl
@@ -160,16 +160,19 @@ interface nsISessionStore : nsISupports
   /**
    * @param aIndex is the index of the windows to be restored (FIFO ordered).
    * @returns the nsIDOMWindow object of the reopened window
    */
   nsIDOMWindow undoCloseWindow(in unsigned long aIndex);
 
   /**
    * @param aIndex  is the index of the closed window to be removed (FIFO ordered).
+   *
+   * @throws NS_ERROR_INVALID_ARG
+   *   when aIndex does not map to a closed window
    */
   nsIDOMNode forgetClosedWindow(in unsigned long aIndex);
 
   /**
    * @param aWindow is the window to get the value for.
    * @param aKey    is the value's name.
    * 
    * @returns A string value or an empty string if none is set.
--- a/browser/config/version.txt
+++ b/browser/config/version.txt
@@ -1,1 +1,1 @@
-3.6a2pre
+3.7a1pre
--- a/browser/installer/removed-files.in
+++ b/browser/installer/removed-files.in
@@ -1,8 +1,12 @@
+chrome/classic.jar
+chrome/classic.manifest
+chrome/reporter.jar
+chrome/reporter.manifest
 chrome/US.jar
 chrome/en-win.jar
 chrome/help.jar
 chrome/chrome.rdf
 chrome/installed-chrome.txt
 chrome/app-chrome.manifest
 chrome/overlayinfo/
 chrome/m3ffxtbr.manifest
--- a/browser/installer/unix/packages-static
+++ b/browser/installer/unix/packages-static
@@ -260,30 +260,26 @@ bin/components/nsUrlClassifierLib.js
 bin/components/url-classifier.xpt
 
 ; GNOME hooks
 bin/components/libmozgnome.so
 
 ; [Browser Chrome Files]
 bin/chrome/browser.jar
 bin/chrome/browser.manifest
-bin/chrome/classic.jar
-bin/chrome/classic.manifest
 bin/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf
 bin/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/icon.png
 bin/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/preview.png
 bin/chrome/comm.jar
 bin/chrome/comm.manifest
 bin/chrome/toolkit.jar
 bin/chrome/toolkit.manifest
 bin/chrome/icons/default/default16.png
 bin/chrome/icons/default/default32.png
 bin/chrome/icons/default/default48.png
-bin/chrome/reporter.manifest
-bin/chrome/reporter.jar
 bin/@PREF_DIR@/reporter.js
 
 ; shell icons
 bin/icons/*.xpm
 bin/icons/*.png
 
 ; [Default Preferences]
 ; All the pref files must be part of base to prevent migration bugs
--- a/browser/installer/windows/packages-static
+++ b/browser/installer/windows/packages-static
@@ -269,27 +269,23 @@ bin\modules\*
 bin\components\nsSafebrowsingApplication.js
 bin\components\nsUrlClassifierListManager.js
 bin\components\nsUrlClassifierLib.js
 bin\components\url-classifier.xpt
 
 ; [Browser Chrome Files]
 bin\chrome\browser.jar
 bin\chrome\browser.manifest
-bin\chrome\classic.jar
-bin\chrome\classic.manifest
 bin\extensions\{972ce4c6-7e08-4474-a285-3208198ce6fd}\install.rdf
 bin\extensions\{972ce4c6-7e08-4474-a285-3208198ce6fd}\icon.png
 bin\extensions\{972ce4c6-7e08-4474-a285-3208198ce6fd}\preview.png
 bin\chrome\comm.jar
 bin\chrome\comm.manifest
 bin\chrome\toolkit.jar
 bin\chrome\toolkit.manifest
-bin\chrome\reporter.manifest
-bin\chrome\reporter.jar
 bin\defaults\pref\reporter.js
 
 ; [Default Preferences]
 ; All the pref files must be part of base to prevent migration bugs
 bin\defaults\pref\firefox.js
 bin\defaults\pref\firefox-branding.js
 bin\defaults\pref\channel-prefs.js
 bin\greprefs\all.js
--- a/browser/locales/Makefile.in
+++ b/browser/locales/Makefile.in
@@ -87,16 +87,30 @@ MOZ_LANGPACK_EID=langpack-$(AB_CD)@firef
 
 ifeq (,$(filter-out pref,$(MOZ_EXTENSIONS)))
 DEFINES += -DEXTENSION_PREF
 endif
 
 PREF_JS_EXPORTS = $(firstword $(wildcard $(LOCALE_SRCDIR)/firefox-l10n.js) \
                        $(srcdir)/en-US/firefox-l10n.js )
 
+ifneq (,$(filter cocoa,$(MOZ_WIDGET_TOOLKIT)))
+MOZ_PKG_MAC_DSSTORE=$(_ABS_DIST)/branding/dsstore
+MOZ_PKG_MAC_BACKGROUND=$(_ABS_DIST)/branding/background.png
+MOZ_PKG_MAC_ICON=$(_ABS_DIST)/branding/disk.icns
+MOZ_PKG_MAC_EXTRA=--symlink "/Applications:/ "
+endif
+
+ifeq (WINNT,$(OS_ARCH))
+UNINSTALLER_PACKAGE_HOOK = $(RM) -r $(STAGEDIST)/uninstall; \
+    $(NSINSTALL) -D $(STAGEDIST)/uninstall; \
+    cp ../installer/windows/l10ngen/helper.exe $(STAGEDIST)/uninstall; \
+    $(NULL)
+endif
+
 include $(topsrcdir)/config/rules.mk
 
 include $(topsrcdir)/toolkit/locales/l10n.mk
 
 $(STAGEDIST): $(DIST)/branding
 
 $(DIST)/branding:
 	$(NSINSTALL) -D $@
@@ -180,23 +194,16 @@ libs-%:
 	$(NSINSTALL) -D $(DIST)/install
 	@$(MAKE) -C ../../toolkit/locales libs-$* BOTH_MANIFESTS=1
 	@$(MAKE) -C ../../extensions/reporter/locales libs AB_CD=$* XPI_NAME=locale-$* BOTH_MANIFESTS=1
 	@$(MAKE) -C ../../extensions/spellcheck/locales AB_CD=$* XPI_NAME=locale-$* BOTH_MANIFESTS=1
 	@$(MAKE) libs AB_CD=$* XPI_NAME=locale-$* PREF_DIR=defaults/pref BOTH_MANIFESTS=1
 	@$(MAKE) -C $(DEPTH)/$(MOZ_BRANDING_DIRECTORY)/locales AB_CD=$* XPI_NAME=locale-$* BOTH_MANIFESTS=1
 	@$(MAKE) tests AB_CD=$*
 
-ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
-MOZ_PKG_MAC_DSSTORE=$(_ABS_DIST)/branding/dsstore
-MOZ_PKG_MAC_BACKGROUND=$(_ABS_DIST)/branding/background.png
-MOZ_PKG_MAC_ICON=$(_ABS_DIST)/branding/disk.icns
-MOZ_PKG_MAC_EXTRA=--symlink "/Applications:/ "
-endif
-
 
 repackage-win32-installer: WIN32_INSTALLER_OUT="$(_ABS_DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME).exe"
 repackage-win32-installer: $(WIN32_INSTALLER_IN) $(SUBMAKEFILES)
 	@echo "Repackaging $(WIN32_INSTALLER_IN) into $(WIN32_INSTALLER_OUT)."
 	$(MAKE) -C $(DEPTH)/$(MOZ_BRANDING_DIRECTORY) export
 	if test ! -d $(_ABS_DIST)/$(PKG_INST_PATH); then \
 	  $(NSINSTALL) -D $(_ABS_DIST)/$(PKG_INST_PATH); \
 	fi
@@ -223,17 +230,17 @@ repackage-win32-installer: $(WIN32_INSTA
 
 ifeq (WINNT,$(OS_ARCH))
 repackage-win32-installer-%: $(WIN32_INSTALLER_IN) libs-%
 	@$(MAKE) repackage-win32-installer AB_CD=$* WIN32_INSTALLER_IN=$(WIN32_INSTALLER_IN)
 else
 repackage-win32-installer-%: ;
 endif
 
-ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
+ifneq (,$(filter cocoa,$(MOZ_WIDGET_TOOLKIT)))
 STAGEDIST = $(_ABS_DIST)/l10n-stage/$(MOZ_PKG_APPNAME)/$(_APPNAME)/Contents/MacOS
 else
 STAGEDIST = $(_ABS_DIST)/l10n-stage/$(MOZ_PKG_DIR)
 endif
 
 clobber-zip:
 	$(RM) $(STAGEDIST)/chrome/$(AB_CD).jar \
 	  $(STAGEDIST)/chrome/$(AB_CD).manifest \
--- a/browser/themes/gnomestripe/browser/browser.css
+++ b/browser/themes/gnomestripe/browser/browser.css
@@ -141,33 +141,19 @@ menuitem.bookmark-item {
 
 .menupopup-drop-indicator {
   list-style-image: none;
   height: 2px;
   -moz-margin-end: -4em;
   background-color: Highlight;
 }
 
+/* Bookmarks toolbar */
 .toolbar-drop-indicator {
-  width: 9px;
-  height: 18px;
-  margin-bottom: -6px;
-  position: relative;
-  background: url("chrome://browser/skin/places/toolbarDropMarker.png") 50% 50% no-repeat;
-}
-
-.toolbar-drop-indicator-bar {
-  visibility: hidden;
-  height: 18px;
-  margin-bottom: -18px;
-  position: relative;
-}
-
-.toolbar-drop-indicator-bar[dragging="true"] {
-  visibility: visible;
+  list-style-image: url(chrome://browser/skin/places/toolbarDropMarker.png);
 }
 
 /* Bookmark items */
 .bookmark-item:not([container])  {
   list-style-image: url("chrome://global/skin/icons/folder-item.png");
   -moz-image-region: rect(0px, 16px, 16px, 0px)
 }
 
--- a/browser/themes/gnomestripe/browser/jar.mn
+++ b/browser/themes/gnomestripe/browser/jar.mn
@@ -1,9 +1,9 @@
-classic.jar:
+browser.jar:
 % skin browser classic/1.0 %skin/classic/browser/
 % override chrome://global/skin/icons/warning-16.png moz-icon://stock/gtk-dialog-warning?size=menu
   skin/classic/browser/sanitizeDialog.css             (sanitizeDialog.css)
 * skin/classic/browser/aboutPrivateBrowsing.css             (aboutPrivateBrowsing.css)
 * skin/classic/browser/aboutSessionRestore.css        (aboutSessionRestore.css)
   skin/classic/browser/aboutSessionRestore-window-icon.png
   skin/classic/browser/aboutCertError.css             (aboutCertError.css)
 * skin/classic/browser/browser.css                    (browser.css)
--- a/browser/themes/gnomestripe/communicator/jar.mn
+++ b/browser/themes/gnomestripe/communicator/jar.mn
@@ -1,3 +1,3 @@
-classic.jar:
+browser.jar:
 % skin communicator classic/1.0 %skin/classic/communicator/
         skin/classic/communicator/communicator.css
index 6709e0d17ed08249ce244e8a4dda1edddc433611..9bbfe10662ee4c540666d196565e09702b06ddd1
GIT binary patch
literal 35269
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
--- a/browser/themes/pinstripe/browser/browser.css
+++ b/browser/themes/pinstripe/browser/browser.css
@@ -1706,33 +1706,19 @@ tabbrowser > tabbox > tabpanels {
 .tabs-closebutton:hover:active {
   list-style-image: url("chrome://global/skin/icons/closetab-active.png");
 }
 
 tabpanels.plain {
 	background-color: #fff !important;
 }
 
-/* Personal toolbar */
+/* Bookmarks toolbar */
 .toolbar-drop-indicator {
-  width: 7px;
-  height: 17px;
-  position: relative;
-  background: url('chrome://browser/skin/places/toolbarDropMarker.png') 40% 50% no-repeat;
-}
-
-.toolbar-drop-indicator-bar {
-  visibility: hidden;
-  height: 17px;
-  margin-bottom: -17px;
-  position: relative;
-}
-
-.toolbar-drop-indicator-bar[dragging="true"] {
-  visibility: visible;
+  list-style-image: url(chrome://browser/skin/places/toolbarDropMarker.png);
 }
 
 /* Bookmark drag and drop styles */
 
 .bookmark-item[dragover-into="true"] {
   background: Highlight !important;
   color: HighlightText !important;
 }
--- a/browser/themes/pinstripe/browser/jar.mn
+++ b/browser/themes/pinstripe/browser/jar.mn
@@ -1,9 +1,9 @@
-classic.jar:
+browser.jar:
 % skin browser classic/1.0 %skin/classic/browser/
   skin/classic/browser/sanitizeDialog.css                   (sanitizeDialog.css)
 * skin/classic/browser/aboutPrivateBrowsing.css             (aboutPrivateBrowsing.css)
 * skin/classic/browser/aboutSessionRestore.css              (aboutSessionRestore.css)
   skin/classic/browser/aboutSessionRestore-window-icon.png
   skin/classic/browser/aboutCertError.css                   (aboutCertError.css)
   skin/classic/browser/bookmark_toolbar_background.png
   skin/classic/browser/bookmark-open-left.png
--- a/browser/themes/pinstripe/communicator/jar.mn
+++ b/browser/themes/pinstripe/communicator/jar.mn
@@ -1,3 +1,3 @@
-classic.jar:
+browser.jar:
 % skin communicator classic/1.0 %skin/classic/communicator/
         skin/classic/communicator/communicator.css
--- a/browser/themes/winstripe/browser/browser.css
+++ b/browser/themes/winstripe/browser/browser.css
@@ -1627,34 +1627,19 @@ toolbar[mode="text"] > #window-controls 
 #pageReportFirstTime statusbarpanel.statusbar-resizerpanel {
   visibility: collapse;
 }
 
 #checkForUpdates[loading="true"] {
   list-style-image: url("chrome://global/skin/icons/loading_16.png");
 }
 
-/* Personal toolbar */
+/* Bookmarks toolbar */
 .toolbar-drop-indicator {
-  width: 9px;
-  height: 18px;
-  margin-bottom: -6px;
-  position: relative;
-  background: url("chrome://browser/skin/places/toolbarDropMarker.png") 50% 50% no-repeat;
-}
-
-.toolbar-drop-indicator-bar {
-  visibility: hidden;
-  height: 18px;
-  margin-bottom: -18px;
-  position: relative;
-}
-
-.toolbar-drop-indicator-bar[dragging="true"] {
-  visibility: visible;
+  list-style-image: url(chrome://browser/skin/places/toolbarDropMarker.png);
 }
 
 toolbarbutton.bookmark-item[dragover="true"][open="true"] {
   -moz-appearance: none;
   background: Highlight !important;
   color: HighlightText !important;
 }
 
--- a/browser/themes/winstripe/browser/jar.mn
+++ b/browser/themes/winstripe/browser/jar.mn
@@ -1,9 +1,9 @@
-classic.jar:
+browser.jar:
 % skin browser classic/1.0 %skin/classic/browser/ os=WINNT osversion<6
 % skin browser classic/1.0 %skin/classic/browser/ os!=WINNT
 # NOTE: If you add a new file here, you'll need to add it to the aero
 # section at the bottom of this file
         skin/classic/browser/sanitizeDialog.css                      (sanitizeDialog.css)
 *       skin/classic/browser/aboutPrivateBrowsing.css                (aboutPrivateBrowsing.css)
 *       skin/classic/browser/aboutSessionRestore.css                 (aboutSessionRestore.css)
         skin/classic/browser/aboutSessionRestore-window-icon.png     (aboutSessionRestore-window-icon.png)
@@ -87,17 +87,17 @@ classic.jar:
         skin/classic/browser/tabbrowser/tabbrowser-tabs-bkgnd.png               (tabbrowser/tabbrowser-tabs-bkgnd.png)
         skin/classic/browser/tabbrowser/tabDragIndicator.png                    (tabbrowser/tabDragIndicator.png)
         skin/classic/browser/tabbrowser/tab-bkgnd.png                           (tabbrowser/tab-bkgnd.png)
         skin/classic/browser/tabbrowser/tab-active-bkgnd.png                    (tabbrowser/tab-active-bkgnd.png)
         skin/classic/browser/tabbrowser/tab-hover-bkgnd.png                     (tabbrowser/tab-hover-bkgnd.png)
         skin/classic/browser/tabbrowser/tabstrip-bottom.png                     (tabbrowser/tabstrip-bottom.png)
 
 #ifdef XP_WIN
-classic.jar:
+browser.jar:
 % skin browser classic/1.0 %skin/classic/aero/browser/ os=WINNT osversion>=6
         skin/classic/aero/browser/sanitizeDialog.css                       (sanitizeDialog.css)
 *       skin/classic/aero/browser/aboutPrivateBrowsing.css           (aboutPrivateBrowsing.css)
 *       skin/classic/aero/browser/aboutSessionRestore.css            (aboutSessionRestore.css)
         skin/classic/aero/browser/aboutSessionRestore-window-icon.png (aboutSessionRestore-window-icon-aero.png)
         skin/classic/aero/browser/aboutCertError.css                 (aboutCertError.css)
 *       skin/classic/aero/browser/browser.css                        (browser-aero.css)
 *       skin/classic/aero/browser/engineManager.css                  (engineManager.css)
--- a/browser/themes/winstripe/communicator/jar.mn
+++ b/browser/themes/winstripe/communicator/jar.mn
@@ -1,3 +1,3 @@
-classic.jar:
+browser.jar:
 % skin communicator classic/1.0 %skin/classic/communicator/
         skin/classic/communicator/communicator.css
--- a/caps/tests/mochitest/test_bug292789.html
+++ b/caps/tests/mochitest/test_bug292789.html
@@ -50,17 +50,17 @@ function testScriptSrc(aCallback) {
       if (aCallback)
         aCallback();
     }
 }
 
 /** <img src=""> tests **/
 var img_global = "chrome://global/skin/icons/Error.png";
 var img_mozapps = "chrome://mozapps/skin/passwordmgr/key.png";
-var res_mozapps = "jar:resource://gre/chrome/classic.jar!/skin/classic/mozapps/passwordmgr/key.png";
+var res_mozapps = "jar:resource://gre/chrome/toolkit.jar!/skin/classic/mozapps/passwordmgr/key.png";
 
 var imgTests = [[img_global, "success"],
                 [img_mozapps, "fail"],
                 [res_mozapps, "success"]];
 
 var curImgTest = 0;
 
 function runImgTest() {
--- a/config/JarMaker.py
+++ b/config/JarMaker.py
@@ -229,16 +229,62 @@ class JarMaker(object):
         self.processJarSection(m.group('jarfile'), lines,
                                jardir, sourcedirs, topsourcedir,
                                localedirs)
     except StopIteration:
       # we read the file
       pass
     return
 
+  def makeJars(self, infiles, l10nbases,
+               jardir='',
+               sourcedirs=[], topsourcedir='', localedirs=None):
+    '''makeJars is the second main entry point to JarMaker.
+
+    It takes an iterable sequence of input file names, the l10nbases,
+    the output directory, the source dirs and the
+    top source dir as argument, and optionally the l10n dirs.
+
+    It iterates over all inputs, guesses srcdir and l10ndir from the
+    path and topsourcedir and calls into makeJar.
+
+    The l10ndirs are created by guessing the relativesrcdir, and resolving
+    that against the l10nbases. l10nbases can either be path strings, or 
+    callables. In the latter case, that will be called with the 
+    relativesrcdir as argument, and is expected to return a path string.
+    '''
+    topsourcedir = os.path.normpath(os.path.abspath(topsourcedir))
+    def resolveL10nBase(relpath):
+      def _resolve(base):
+        if isinstance(base, basestring):
+          return os.path.join(base, relpath)
+        if callable(base):
+          return base(relpath)
+        return base
+      return _resolve
+    for infile in infiles:
+      srcdir = os.path.normpath(os.path.abspath(os.path.dirname(infile)))
+      l10ndir = srcdir
+      if os.path.basename(srcdir) == 'locales':
+        l10ndir = os.path.dirname(l10ndir)
+      assert srcdir.startswith(topsourcedir), "src dir %s not in topsourcedir %s" % (srcdir, topsourcedir)
+      rell10ndir = l10ndir[len(topsourcedir):].lstrip(os.sep)
+      
+      l10ndirs = map(resolveL10nBase(rell10ndir), l10nbases)
+      if localedirs is not None:
+        l10ndirs += [os.path.normpath(os.path.abspath(s))
+                     for s in localedirs]
+      srcdirs = [os.path.normpath(os.path.abspath(s))
+                 for s in sourcedirs] + [srcdir]
+      self.makeJar(infile=infile,
+                   sourcedirs=srcdirs, topsourcedir=topsourcedir,
+                   localedirs=l10ndirs,
+                   jardir=jardir)
+
+
   def processJarSection(self, jarfile, lines,
                         jardir, sourcedirs, topsourcedir, localedirs):
     '''Internal method called by makeJar to actually process a section
     of a jar.mn file.
 
     jarfile is the basename of the jarfile or the directory name for 
     flat output, lines is a pushback_iterator of the lines of jar.mn,
     the remaining options are carried over from makeJar.
@@ -431,33 +477,16 @@ def main():
   logging.getLogger().setLevel(noise)
   topsrc = options.t
   topsrc = os.path.normpath(os.path.abspath(topsrc))
   if not args:
     jm.makeJar(infile=sys.stdin,
                sourcedirs=options.s, topsourcedir=topsrc,
                localedirs=options.l10n_src,
                jardir=options.j)
-    return
-  for infile in args:
-    # guess srcdir and l10n dirs from jar.mn path and topsrcdir
-    # srcdir is the dir of the jar.mn and
-    # the l10n dirs are the relative path of topsrcdir to srcdir
-    # resolved against all l10n base dirs.
-    srcdir = os.path.normpath(os.path.abspath(os.path.dirname(infile)))
-    l10ndir = srcdir
-    if os.path.basename(srcdir) == 'locales':
-      l10ndir = os.path.dirname(l10ndir)
-    assert srcdir.startswith(topsrc), "src dir %s not in topsrcdir %s" % (srcdir, topsrc)
-    rell10ndir = l10ndir[len(topsrc):].lstrip(os.sep)
-    l10ndirs = map(lambda d: os.path.join(d, rell10ndir), options.l10n_base)
-    if options.l10n_src is not None:
-      l10ndirs += map(lambda s: os.path.normpath(os.path.abspath(s)),
-                      options.l10n_src)
-    srcdirs = map(lambda s: os.path.normpath(os.path.abspath(s)), options.s) + \
-        [srcdir]
-    jm.makeJar(infile=infile,
-               sourcedirs=srcdirs, topsourcedir=topsrc,
-               localedirs=l10ndirs,
-               jardir=options.j)
+  else:
+    jm.makeJars(args, options.l10n_base,
+                jardir=options.j,
+                sourcedirs=options.s, topsourcedir=topsrc,
+                localedirs=options.l10n_src)
 
 if __name__ == "__main__":
   main()
--- a/config/milestone.txt
+++ b/config/milestone.txt
@@ -5,9 +5,9 @@
 #    x.x.x.x
 #    x.x.x+
 #
 # Referenced by milestone.pl.
 # Hopefully I'll be able to automate replacement of *all*
 # hardcoded milestones in the tree from these two files.
 #--------------------------------------------------------
 
-1.9.2a2pre
+1.9.3a1pre
--- a/configure.in
+++ b/configure.in
@@ -2129,16 +2129,19 @@ case "$target" in
         DLL_PREFIX=
         LIB_PREFIX=
         IMPORT_LIB_SUFFIX=lib
         MKSHLIB='$(LD) -NOLOGO -DLL -OUT:$@ -PDB:$(LINK_PDBFILE) $(DSO_LDOPTS)'
         MKCSHLIB='$(LD) -NOLOGO -DLL -OUT:$@ -PDB:$(LINK_PDBFILE) $(DSO_LDOPTS)'
         MKSHLIB_FORCE_ALL=
         MKSHLIB_UNFORCE_ALL=
         DSO_LDOPTS=-SUBSYSTEM:WINDOWS
+        _USE_CPP_INCLUDE_FLAG=1
+        _DEFINES_CFLAGS='-FI $(DEPTH)/dist/include/mozilla-config.h -DMOZILLA_CLIENT'
+        _DEFINES_CXXFLAGS='-FI $(DEPTH)/dist/include/mozilla-config.h -DMOZILLA_CLIENT'
         CFLAGS="$CFLAGS -W3 -Gy -Fd\$(COMPILE_PDBFILE)"
         CXXFLAGS="$CXXFLAGS -W3 -Gy -Fd\$(COMPILE_PDBFILE)"
         LIBS="$LIBS kernel32.lib user32.lib gdi32.lib winmm.lib wsock32.lib advapi32.lib"
         MOZ_DEBUG_FLAGS='-Zi'
         MOZ_DEBUG_LDFLAGS='-DEBUG -DEBUGTYPE:CV'
         WARNINGS_AS_ERRORS='-WX'
     	MOZ_OPTIMIZE_FLAGS='-O1'
         MOZ_JS_LIBS='$(LIBXUL_DIST)/lib/js$(MOZ_BITS)$(VERSION_NUMBER).lib'
@@ -7358,19 +7361,22 @@ if test "$_cpp_md_flag"; then
     _DEPEND_CFLAGS='$(filter-out %/.pp,-Wp,-MD,$(MDDEPDIR)/$(basename $(@F)).pp)'
   fi
   dnl Sun Studio on Solaris use -xM instead of -MD, see config/rules.mk
   if test "$SOLARIS_SUNPRO_CC"; then
     _DEPEND_CFLAGS=
   fi
 else
   COMPILER_DEPEND=
-  _USE_CPP_INCLUDE_FLAG=
-  _DEFINES_CFLAGS='$(ACDEFINES) -D_MOZILLA_CONFIG_H_ -DMOZILLA_CLIENT'
-  _DEFINES_CXXFLAGS='$(ACDEFINES) -D_MOZILLA_CONFIG_H_ -DMOZILLA_CLIENT'
+  dnl Don't override this for MSVC
+  if test -z "$_WIN32_MSVC"; then
+    _USE_CPP_INCLUDE_FLAG=
+    _DEFINES_CFLAGS='$(ACDEFINES) -D_MOZILLA_CONFIG_H_ -DMOZILLA_CLIENT'
+    _DEFINES_CXXFLAGS='$(ACDEFINES) -D_MOZILLA_CONFIG_H_ -DMOZILLA_CLIENT'
+  fi
 fi
 fi # MOZ_AUTO_DEPS
 MDDEPDIR='.deps'
 AC_SUBST(MOZ_AUTO_DEPS)
 AC_SUBST(COMPILER_DEPEND)
 AC_SUBST(MDDEPDIR)
 
 
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -3545,33 +3545,35 @@ nsDocument::SetScriptGlobalObject(nsIScr
   if (aScriptGlobalObject) {
     mScriptObject = nsnull;
     mHasHadScriptHandlingObject = PR_TRUE;
     // Go back to using the docshell for the layout history state
     mLayoutHistoryState = nsnull;
     mScopeObject = do_GetWeakReference(aScriptGlobalObject);
 
 #ifdef DEBUG
-    // We really shouldn't have a wrapper here but if we do we need to make sure
-    // it has the correct parent.
-    JSObject *obj = GetWrapper();
-    if (obj) {
-      JSObject *newScope = aScriptGlobalObject->GetGlobalJSObject();
-      nsIScriptContext *scx = aScriptGlobalObject->GetContext();
-      JSContext *cx = scx ? (JSContext *)scx->GetNativeContext() : nsnull;
-      if (!cx) {
-        nsContentUtils::ThreadJSContextStack()->Peek(&cx);
+    if (!mWillReparent) {
+      // We really shouldn't have a wrapper here but if we do we need to make sure
+      // it has the correct parent.
+      JSObject *obj = GetWrapper();
+      if (obj) {
+        JSObject *newScope = aScriptGlobalObject->GetGlobalJSObject();
+        nsIScriptContext *scx = aScriptGlobalObject->GetContext();
+        JSContext *cx = scx ? (JSContext *)scx->GetNativeContext() : nsnull;
         if (!cx) {
-          nsContentUtils::ThreadJSContextStack()->GetSafeJSContext(&cx);
-          NS_ASSERTION(cx, "Uhoh, no context, this is bad!");
+          nsContentUtils::ThreadJSContextStack()->Peek(&cx);
+          if (!cx) {
+            nsContentUtils::ThreadJSContextStack()->GetSafeJSContext(&cx);
+            NS_ASSERTION(cx, "Uhoh, no context, this is bad!");
+          }
         }
-      }
-      if (cx) {
-        NS_ASSERTION(JS_GetGlobalForObject(cx, obj) == newScope,
-                     "Wrong scope, this is really bad!");
+        if (cx) {
+          NS_ASSERTION(JS_GetGlobalForObject(cx, obj) == newScope,
+                       "Wrong scope, this is really bad!");
+        }
       }
     }
 #endif
 
     if (mAllowDNSPrefetch) {
       nsCOMPtr<nsIDocShell> docShell = do_QueryReferent(mDocumentContainer);
       if (docShell) {
 #ifdef DEBUG
--- a/content/base/src/nsDocument.h
+++ b/content/base/src/nsDocument.h
@@ -1268,16 +1268,21 @@ private:
   nsExternalResourceMap mExternalResourceMap;
 
   // All images in process of being preloaded
   nsCOMArray<imgIRequest> mPreloadingImages;
 
 #ifdef MOZ_SMIL
   nsAutoPtr<nsSMILAnimationController> mAnimationController;
 #endif // MOZ_SMIL
+
+#ifdef DEBUG
+protected:
+  PRBool mWillReparent;
+#endif
 };
 
 #define NS_DOCUMENT_INTERFACE_TABLE_BEGIN(_class)                             \
   NS_NODE_OFFSET_AND_INTERFACE_TABLE_BEGIN(_class)                            \
   NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(_class, nsIDOMDocument, nsDocument)      \
   NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(_class, nsIDOMNSDocument, nsDocument)    \
   NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(_class, nsIDOMDocumentEvent, nsDocument) \
   NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(_class, nsIDOMDocumentView, nsDocument)  \
--- a/content/base/test/Makefile.in
+++ b/content/base/test/Makefile.in
@@ -46,16 +46,17 @@ include $(DEPTH)/config/autoconf.mk
 DIRS += \
   chrome \
   $(NULL)
 
 MODULE = content
 
 CPP_UNIT_TESTS = \
                  TestNativeXMLHttpRequest.cpp \
+                 TestGetURL.cpp \
                  TestPlainTextSerializer.cpp \
                  $(NULL)
 
 REQUIRES += \
   caps \
   content \
   dom \
   js \
new file mode 100644
--- /dev/null
+++ b/content/base/test/TestGetURL.cpp
@@ -0,0 +1,116 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla XMLHttpRequest Tests.
+ *
+ * The Initial Developer of the Original Code is
+ * Adam Barth
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "TestHarness.h"
+
+#include "nsIDOMDocument.h"
+#include "nsIPrincipal.h"
+#include "nsIScriptSecurityManager.h"
+#include "nsIXMLHttpRequest.h"
+
+
+#define TEST_ENSURE_BASE(_test, _msg)       \
+  PR_BEGIN_MACRO                            \
+    if (_test) {                            \
+      fail(_msg);                           \
+      return NS_ERROR_FAILURE;              \
+    }                                       \
+  PR_END_MACRO
+
+#define TEST_ENSURE_SUCCESS(_rv, _msg)      \
+  TEST_ENSURE_BASE(NS_FAILED(_rv), _msg)
+
+#define TEST_ENSURE_FAILED(_rv, _msg)       \
+  TEST_ENSURE_BASE(NS_SUCCEEDED(_rv), _msg)
+
+nsresult TestGetURL(const nsCString& aURL)
+{
+  nsresult rv;
+
+  nsCOMPtr<nsIXMLHttpRequest> xhr =
+    do_CreateInstance(NS_XMLHTTPREQUEST_CONTRACTID, &rv);
+  TEST_ENSURE_SUCCESS(rv, "Couldn't create nsIXMLHttpRequest instance!");
+
+  NS_NAMED_LITERAL_CSTRING(getString, "GET");
+  const nsAString& empty = EmptyString();
+  
+  nsCOMPtr<nsIScriptSecurityManager> secman =
+    do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
+  TEST_ENSURE_SUCCESS(rv, "Couldn't get script security manager!");
+
+  nsCOMPtr<nsIPrincipal> systemPrincipal;
+  rv = secman->GetSystemPrincipal(getter_AddRefs(systemPrincipal));
+  TEST_ENSURE_SUCCESS(rv, "Couldn't get system principal!");
+
+  rv = xhr->Init(systemPrincipal, nsnull, nsnull, nsnull);
+  TEST_ENSURE_SUCCESS(rv, "Couldn't initialize the XHR!");
+
+  rv = xhr->OpenRequest(getString, aURL, PR_FALSE, empty, empty);
+  TEST_ENSURE_SUCCESS(rv, "OpenRequest failed!");
+
+  rv = xhr->Send(nsnull);
+  TEST_ENSURE_SUCCESS(rv, "Send failed!");
+
+  nsAutoString response;
+  rv = xhr->GetResponseText(response);
+  TEST_ENSURE_SUCCESS(rv, "GetResponse failed!");
+
+  nsCAutoString responseUTF8 = NS_ConvertUTF16toUTF8(response);
+  printf("#BEGIN\n");
+  printf("%s", responseUTF8.get());
+  printf("\n#EOF\n");
+
+  return NS_OK;
+}
+
+int main(int argc, char** argv)
+{
+  if (argc <  2) {
+    printf("Usage: TestGetURL <url>\n");
+    exit(0);
+  }
+
+  ScopedXPCOM xpcom("XMLHttpRequest");
+  if (xpcom.failed())
+    return 1;
+
+  nsCAutoString targetURL(argv[1]);
+
+  int retval = 0;
+  if (NS_FAILED(TestGetURL(targetURL))) {
+    retval = 1;
+  }
+
+  return retval;
+}
--- a/content/canvas/src/nsCanvasRenderingContext2D.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2D.cpp
@@ -2028,17 +2028,17 @@ nsCanvasRenderingContext2D::GetTextAlign
         break;
     case TEXT_ALIGN_RIGHT:
         ta.AssignLiteral("right");
         break;
     case TEXT_ALIGN_CENTER:
         ta.AssignLiteral("center");
         break;
     default:
-        NS_ASSERTION(0, "textAlign holds invalid value");
+        NS_ERROR("textAlign holds invalid value");
         return NS_ERROR_FAILURE;
     }
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::SetTextBaseline(const nsAString& tb)
@@ -2081,17 +2081,17 @@ nsCanvasRenderingContext2D::GetTextBasel
         break;
     case TEXT_BASELINE_IDEOGRAPHIC:
         tb.AssignLiteral("ideographic");
         break;
     case TEXT_BASELINE_BOTTOM:
         tb.AssignLiteral("bottom");
         break;
     default:
-        NS_ASSERTION(0, "textBaseline holds invalid value");
+        NS_ERROR("textBaseline holds invalid value");
         return NS_ERROR_FAILURE;
     }
 
     return NS_OK;
 }
 
 /*
  * Helper function that replaces the whitespace characters in a string
@@ -2360,17 +2360,17 @@ nsCanvasRenderingContext2D::DrawOrMeasur
         break;
     case TEXT_BASELINE_IDEOGRAPHIC:
         anchorY = 0; // currently unvailable
         break;
     case TEXT_BASELINE_BOTTOM:
         anchorY = -fontMetrics.emDescent;
         break;
     default:
-        NS_ASSERTION(0, "mTextBaseline holds invalid value");
+        NS_ERROR("mTextBaseline holds invalid value");
         return NS_ERROR_FAILURE;
     }
 
     processor.mPt.y += anchorY;
 
     // correct bounding box to get it to be the correct size/position
     processor.mBoundingBox.size.width = totalWidth;
     processor.mBoundingBox.MoveBy(processor.mPt);
--- a/content/events/src/nsEventStateManager.cpp
+++ b/content/events/src/nsEventStateManager.cpp
@@ -56,16 +56,17 @@
 #include "nsIWidget.h"
 #include "nsPresContext.h"
 #include "nsIPresShell.h"
 #include "nsDOMEvent.h"
 #include "nsGkAtoms.h"
 #include "nsIEditorDocShell.h"
 #include "nsIFormControl.h"
 #include "nsIComboboxControlFrame.h"
+#include "nsIScrollableFrame.h"
 #include "nsIDOMNSHTMLElement.h"
 #include "nsIDOMHTMLAnchorElement.h"
 #include "nsIDOMHTMLInputElement.h"
 #include "nsIDOMNSHTMLInputElement.h"
 #include "nsIDOMHTMLSelectElement.h"
 #include "nsIDOMHTMLTextAreaElement.h"
 #include "nsIDOMHTMLAreaElement.h"
 #include "nsIDOMHTMLButtonElement.h"
@@ -2487,16 +2488,125 @@ nsEventStateManager::DoScrollText(nsPres
       return DoScrollText(newPresContext, newFrame, aMouseEvent, aScrollQuantity);
   }
 
   aMouseEvent->scrollOverflow = numLines;
 
   return NS_OK;
 }
 
+void
+nsEventStateManager::DecideGestureEvent(nsGestureNotifyEvent* aEvent,
+                                        nsIFrame* targetFrame)
+{
+
+  NS_ASSERTION(aEvent->message == NS_GESTURENOTIFY_EVENT_START,
+               "DecideGestureEvent called with a non-gesture event");
+
+  /* Check the ancestor tree to decide if any frame is willing* to receive
+   * a MozPixelScroll event. If that's the case, the current touch gesture
+   * will be used as a pan gesture; otherwise it will be a regular
+   * mousedown/mousemove/click event.
+   *
+   * *willing: determine if it makes sense to pan the element using scroll events:
+   *  - For web content: if there are any visible scrollbars on the touch point
+   *  - For XUL: if it's an scrollable element that can currently scroll in some
+    *    direction.
+   *
+   * Note: we'll have to one-off various cases to ensure a good usable behavior
+   */
+  nsGestureNotifyEvent::ePanDirection panDirection = nsGestureNotifyEvent::ePanNone;
+  PRBool displayPanFeedback = PR_FALSE;
+  for (nsIFrame* current = targetFrame; current;
+       current = nsLayoutUtils::GetCrossDocParentFrame(current)) {
+
+    nsIAtom* currentFrameType = current->GetType();
+
+    // Scrollbars should always be draggable
+    if (currentFrameType == nsGkAtoms::scrollbarFrame) {
+      panDirection = nsGestureNotifyEvent::ePanNone;
+      break;
+    }
+
+#ifdef MOZ_XUL
+    // Special check for trees
+    nsTreeBodyFrame* treeFrame = do_QueryFrame(current);
+    if (treeFrame) {
+      if (treeFrame->GetHorizontalOverflow()) {
+        panDirection = nsGestureNotifyEvent::ePanHorizontal;
+      }
+      if (treeFrame->GetVerticalOverflow()) {
+        panDirection = nsGestureNotifyEvent::ePanVertical;
+      }
+      break;
+    }
+#endif
+
+    nsIScrollableFrame* scrollableFrame = do_QueryFrame(current);
+    if (scrollableFrame) {
+      if (current->IsFrameOfType(nsIFrame::eXULBox)) {
+
+        nsIScrollableView* scrollableView = scrollableFrame->GetScrollableView();
+        if (scrollableView) {
+
+          displayPanFeedback = PR_TRUE;
+
+          PRBool canScrollUp, canScrollDown, canScrollLeft, canScrollRight;
+          scrollableView->CanScroll(PR_FALSE, PR_TRUE,  canScrollDown);
+          scrollableView->CanScroll(PR_FALSE, PR_FALSE, canScrollUp);
+          scrollableView->CanScroll(PR_TRUE,  PR_TRUE,  canScrollRight);
+          scrollableView->CanScroll(PR_TRUE,  PR_FALSE, canScrollLeft);
+
+          if (targetFrame->GetType() == nsGkAtoms::menuFrame) {
+            // menu frames report horizontal scroll when they have submenus
+            // and we don't want that
+            canScrollRight = PR_FALSE;
+            canScrollLeft  = PR_FALSE;
+            displayPanFeedback = PR_FALSE;
+          }
+
+          //Vertical panning has priority over horizontal panning, so
+          //when a vertical movement is detected we can just finish the loop.
+          if (canScrollUp || canScrollDown) {
+            panDirection = nsGestureNotifyEvent::ePanVertical;
+            break;
+          }
+
+          if (canScrollLeft || canScrollRight) {
+            panDirection = nsGestureNotifyEvent::ePanHorizontal;
+            displayPanFeedback = PR_FALSE;
+          }
+        }
+
+      } else { //Not a XUL box
+
+        nsMargin scrollbarSizes = scrollableFrame->GetActualScrollbarSizes();
+
+        //Check if we have visible scrollbars
+        if (scrollbarSizes.LeftRight()) {
+          panDirection = nsGestureNotifyEvent::ePanVertical;
+          displayPanFeedback = PR_TRUE;
+          break;
+        }
+
+        if (scrollbarSizes.TopBottom()) {
+          panDirection = nsGestureNotifyEvent::ePanHorizontal;
+          displayPanFeedback = PR_TRUE;
+        }
+
+      }
+
+    } //scrollableFrame
+  } //ancestor chain
+
+  aEvent->displayPanFeedback = displayPanFeedback;
+  aEvent->panDirection = panDirection;
+
+}
+
 nsresult
 nsEventStateManager::GetParentScrollingView(nsInputEvent *aEvent,
                                             nsPresContext* aPresContext,
                                             nsIFrame* &targetOuterFrame,
                                             nsPresContext* &presCtxOuter)
 {
   targetOuterFrame = nsnull;
 
@@ -2793,16 +2903,23 @@ nsEventStateManager::PostHandleEvent(nsP
         default:  // Including -1 (do nothing)
           break;
         }
         *aStatus = nsEventStatus_eConsumeNoDefault;
       }
     }
     break;
 
+  case NS_GESTURENOTIFY_EVENT_START:
+    {
+      if (nsEventStatus_eConsumeNoDefault != *aStatus)
+        DecideGestureEvent(static_cast<nsGestureNotifyEvent*>(aEvent), mCurrentTarget);
+    }
+    break;
+
   case NS_DRAGDROP_ENTER:
   case NS_DRAGDROP_OVER:
     {
       NS_ASSERTION(aEvent->eventStructType == NS_DRAG_EVENT, "Expected a drag event");
 
       nsCOMPtr<nsIDragSession> dragSession = nsContentUtils::GetDragSession();
       if (!dragSession)
         break;
@@ -3805,25 +3922,19 @@ nsEventStateManager::GetContentState(nsI
   for (nsIContent* hoverContent = mHoverContent; hoverContent;
        hoverContent = hoverContent->GetParent()) {
     if (aContent == hoverContent) {
       aState |= NS_EVENT_STATE_HOVER;
       break;
     }
   }
 
-  nsIFocusManager* fm = nsFocusManager::GetFocusManager();
-  if (fm) {
-    nsCOMPtr<nsIDOMElement> focusedElement;
-    fm->GetFocusedElement(getter_AddRefs(focusedElement));
-
-    nsCOMPtr<nsIContent> focusedContent = do_QueryInterface(focusedElement);
-    if (aContent == focusedContent) {
-      aState |= NS_EVENT_STATE_FOCUS;
-    }
+  nsFocusManager* fm = nsFocusManager::GetFocusManager();
+  if (fm && aContent == fm->GetFocusedContent()) {
+    aState |= NS_EVENT_STATE_FOCUS;
   }
   if (aContent == mDragOverContent) {
     aState |= NS_EVENT_STATE_DRAGOVER;
   }
   if (aContent == mURLTargetContent) {
     aState |= NS_EVENT_STATE_URLTARGET;
   }
   return NS_OK;
--- a/content/events/src/nsEventStateManager.h
+++ b/content/events/src/nsEventStateManager.h
@@ -36,16 +36,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsEventStateManager_h__
 #define nsEventStateManager_h__
 
 #include "nsIEventStateManager.h"
 #include "nsEvent.h"
+#include "nsGUIEvent.h"
 #include "nsIContent.h"
 #include "nsIObserver.h"
 #include "nsWeakReference.h"
 #include "nsHashtable.h"
 #include "nsITimer.h"
 #include "nsCOMPtr.h"
 #include "nsIDocument.h"
 #include "nsCOMArray.h"
@@ -273,16 +274,26 @@ protected:
                         ScrollQuantity aScrollQuantity);
   void DoScrollHistory(PRInt32 direction);
   void DoScrollZoom(nsIFrame *aTargetFrame, PRInt32 adjustment);
   nsresult GetMarkupDocumentViewer(nsIMarkupDocumentViewer** aMv);
   nsresult ChangeTextSize(PRInt32 change);
   nsresult ChangeFullZoom(PRInt32 change);
   // end mousewheel functions
 
+  /*
+   * When a touch gesture is about to start, this function determines what
+   * kind of gesture interaction we will want to use, based on what is
+   * underneath the initial touch point.
+   * Currently it decides between panning (finger scrolling) or dragging
+   * the target element, as well as the orientation to trigger panning and
+   * display visual boundary feedback. The decision is stored back in aEvent.
+   */
+  void DecideGestureEvent(nsGestureNotifyEvent* aEvent, nsIFrame* targetFrame);
+
   // routines for the d&d gesture tracking state machine
   void BeginTrackingDragGesture ( nsPresContext* aPresContext, nsMouseEvent* inDownEvent,
                                   nsIFrame* inDownFrame ) ;
   void StopTrackingDragGesture ( ) ;
   void GenerateDragGesture ( nsPresContext* aPresContext, nsMouseEvent *aEvent ) ;
 
   /**
    * Determine which node the drag should be targeted at.
new file mode 100644
--- /dev/null
+++ b/content/html/document/reftests/bug502168-1_malformed.html
@@ -0,0 +1,10 @@
+<html><head>
+<title> Bug 502168 -  Particular images are displayed multiple times in a formated way - only FF 3.5</title>
+</head><body>
+
+<table><tbody><tr><td >You should see this text only once</td>
+<embed type="*" style="display: none;"/>
+</td></tr></tbody></table>
+
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/document/reftests/bug502168-1_well-formed.html
@@ -0,0 +1,9 @@
+<html><head>
+<title> Bug 502168 -  Particular images are displayed multiple times in a formated way - only FF 3.5</title>
+</head><body>
+
+<embed type="*" style="display: none;">
+<table><tbody><tr><td>You should see this text only once</td>
+</tr></tbody></table>
+
+</body></html>
--- a/content/html/document/reftests/reftests.list
+++ b/content/html/document/reftests/reftests.list
@@ -1,4 +1,5 @@
 == bug448564-1_malformed.html bug448564-1_well-formed.html
 == bug448564-1_malformed.html bug448564-1_ideal.html
 
 == bug448564-4a.html          bug448564-4b.html
+== bug502168-1_malformed.html bug502168-1_well-formed.html
--- a/content/html/document/src/nsHTMLContentSink.cpp
+++ b/content/html/document/src/nsHTMLContentSink.cpp
@@ -1358,21 +1358,26 @@ SinkContext::FlushTags()
           mStack[stackPos].mContent->Tag()->GetUTF8String(&tagStr);
 
           SINK_TRACE(gSinkLogModuleInfo, SINK_TRACE_REFLOW,
                      ("SinkContext::FlushTags: tag=%s from newindex=%d at "
                       "stackPos=%d", tagStr,
                       mStack[stackPos].mNumFlushed, stackPos));
         }
 #endif
-        if ((mStack[stackPos].mInsertionPoint != -1) &&
-            (mStackPos > (stackPos + 1))) {
+        if (mStack[stackPos].mInsertionPoint != -1) {
+          // We might have popped the child off our stack already
+          // but not notified on it yet, which is why we have to get it
+          // directly from its parent node.
+
           PRInt32 childIndex = mStack[stackPos].mInsertionPoint - 1;
-          nsIContent* child = mStack[stackPos + 1].mContent;
-          NS_ASSERTION(content->GetChildAt(childIndex) == child,
+          nsIContent* child = content->GetChildAt(childIndex);
+          // Child not on stack anymore; can't assert it's correct
+          NS_ASSERTION(!(mStackPos > (stackPos + 1)) ||
+                       (child == mStack[stackPos + 1].mContent),
                        "Flushing the wrong child.");
           mSink->NotifyInsert(content, child, childIndex);
         } else {
           mSink->NotifyAppend(content, mStack[stackPos].mNumFlushed);
         }
 
         flushed = PR_TRUE;
       }
--- a/content/html/document/src/nsHTMLDocument.cpp
+++ b/content/html/document/src/nsHTMLDocument.cpp
@@ -1919,19 +1919,28 @@ nsHTMLDocument::OpenCommon(const nsACStr
   nsCOMPtr<nsIDOMDocument> kungFuDeathGrip =
     do_QueryInterface((nsIHTMLDocument*)this);
 
   nsPIDOMWindow *window = GetInnerWindow();
   if (window) {
     // Remember the old scope in case the call to SetNewDocument changes it.
     nsCOMPtr<nsIScriptGlobalObject> oldScope(do_QueryReferent(mScopeObject));
 
+#ifdef DEBUG
+    PRBool willReparent = mWillReparent;
+    mWillReparent = PR_TRUE;
+#endif
+
     rv = window->SetNewDocument(this, nsnull, PR_FALSE);
     NS_ENSURE_SUCCESS(rv, rv);
 
+#ifdef DEBUG
+    mWillReparent = willReparent;
+#endif
+
     // Now make sure we're not flagged as the initial document anymore, now
     // that we've had stuff done to us.  From now on, if anyone tries to
     // document.open() us, they get a new inner window.
     SetIsInitialDocument(PR_FALSE);
 
     nsCOMPtr<nsIScriptGlobalObject> newScope(do_QueryReferent(mScopeObject));
     if (oldScope && newScope != oldScope) {
       nsContentUtils::ReparentContentWrappersInScope(oldScope, newScope);
--- a/content/xslt/src/xml/txAttr.cpp
+++ b/content/xslt/src/xml/txAttr.cpp
@@ -55,17 +55,17 @@ Attr::Attr(nsIAtom *aPrefix, nsIAtom *aL
 {
 }
 
 //
 //Not implemented anymore, return null as an error.
 //
 Node* Attr::appendChild(Node* newChild)
 {
-  NS_ASSERTION(0, "not implemented");
+  NS_ERROR("not implemented");
   return nsnull;
 }
 
 nsresult
 Attr::getNodeName(nsAString& aName) const
 {
   if (mPrefix) {
     mPrefix->ToString(aName);
--- a/content/xslt/src/xml/txDOM.h
+++ b/content/xslt/src/xml/txDOM.h
@@ -390,17 +390,17 @@ public:
             return kNameSpaceID_Unknown;
 
         PRInt32 id = mNamespaces->IndexOf(aURI);
         if (id != -1) {
             return id + 1;
         }
 
         if (!mNamespaces->AppendString(aURI)) {
-            NS_ASSERTION(0, "Out of memory, namespaces are getting lost");
+            NS_ERROR("Out of memory, namespaces are getting lost");
             return kNameSpaceID_Unknown;
         }
 
         return mNamespaces->Count();
     }
 
     static nsresult getNamespaceURI(const PRInt32 aID, nsAString& aNSURI)
     {
--- a/content/xslt/src/xml/txNodeDefinition.cpp
+++ b/content/xslt/src/xml/txNodeDefinition.cpp
@@ -359,17 +359,17 @@ NodeDefinition::OrderInfo* NodeDefinitio
         }
         ++i;
         child = child->getNextSibling();
       }
       break;
     }
   }
 
-  NS_ASSERTION(0, "unable to get childnumber");
+  NS_ERROR("unable to get childnumber");
   mOrderInfo->mOrder[lastElem] = 0;
   return mOrderInfo;
 }
 
 /*
  * OrderInfo destructor
  */
 NodeDefinition::OrderInfo::~OrderInfo()
--- a/content/xslt/src/xpath/txFunctionCall.cpp
+++ b/content/xslt/src/xpath/txFunctionCall.cpp
@@ -140,17 +140,17 @@ FunctionCall::argsSensitiveTo(ContextSen
 #ifdef TX_TO_STRING
 void
 FunctionCall::toString(nsAString& aDest)
 {
     nsCOMPtr<nsIAtom> functionNameAtom;
     nsAutoString functionName;
     if (NS_FAILED(getNameAtom(getter_AddRefs(functionNameAtom))) ||
         NS_FAILED(functionNameAtom->ToString(functionName))) {
-        NS_ASSERTION(0, "Can't get function name.");
+        NS_ERROR("Can't get function name.");
         return;
     }
 
     aDest.Append(functionName);
     aDest.Append(PRUnichar('('));
     for (PRUint32 i = 0; i < mParams.Length(); ++i) {
         if (i != 0) {
             aDest.Append(PRUnichar(','));
--- a/content/xslt/src/xslt/txCurrentFunctionCall.cpp
+++ b/content/xslt/src/xslt/txCurrentFunctionCall.cpp
@@ -25,17 +25,17 @@ CurrentFunctionCall::evaluate(txIEvalCon
     *aResult = nsnull;
 
     if (!requireParams(0, 0, aContext))
         return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT;
 
     txExecutionState* es = 
         static_cast<txExecutionState*>(aContext->getPrivateContext());
     if (!es) {
-        NS_ASSERTION(0,
+        NS_ERROR(
             "called xslt extension function \"current\" with wrong context");
         return NS_ERROR_UNEXPECTED;
     }
     return aContext->recycler()->getNodeSet(
            es->getEvalContext()->getContextNode(), aResult);
 }
 
 Expr::ResultType
--- a/content/xslt/src/xslt/txXSLTPatterns.cpp
+++ b/content/xslt/src/xslt/txXSLTPatterns.cpp
@@ -50,17 +50,17 @@
 
 /*
  * Returns the default priority of this Pattern.
  * UnionPatterns don't like this.
  * This should be called on the simple patterns.
  */
 double txUnionPattern::getDefaultPriority()
 {
-    NS_ASSERTION(0, "Don't call getDefaultPriority on txUnionPattern");
+    NS_ERROR("Don't call getDefaultPriority on txUnionPattern");
     return Double::NaN;
 }
 
 /*
  * Determines whether this Pattern matches the given node within
  * the given context
  * This should be called on the simple patterns for xsl:template,
  * but is fine for xsl:key and xsl:number
--- a/content/xul/content/src/nsXULElement.cpp
+++ b/content/xul/content/src/nsXULElement.cpp
@@ -1561,17 +1561,17 @@ nsXULElement::DestroyContent()
 
     nsGenericElement::DestroyContent();
 }
 
 #ifdef DEBUG
 void
 nsXULElement::List(FILE* out, PRInt32 aIndent) const
 {
-    nsCString prefix("<XUL");
+    nsCString prefix("XUL");
     if (HasSlots()) {
       prefix.Append('*');
     }
     prefix.Append(' ');
 
     nsGenericElement::List(out, aIndent, prefix);
 }
 #endif
--- a/db/mork/src/morkConfig.cpp
+++ b/db/mork/src/morkConfig.cpp
@@ -48,17 +48,17 @@
 #endif
 
 //3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
 
 void mork_assertion_signal(const char* inMessage)
 {
 #if defined(MORK_WIN) || defined(MORK_MAC)
   // asm { int 3 }
-  NS_ASSERTION(0, inMessage);
+  NS_ERROR(inMessage);
 #endif /*MORK_WIN*/
 }
 
 #if defined(MORK_OS2)
 #include <fcntl.h>
 #include <sys/stat.h>
 #include <share.h>
 #include <io.h>
--- a/docshell/test/chrome/Makefile.in
+++ b/docshell/test/chrome/Makefile.in
@@ -68,16 +68,22 @@ include $(topsrcdir)/config/rules.mk
 		bug293235_window.xul \
 		bug293235.html \
 		bug293235_p2.html \
 		test_bug294258.xul \
 		bug294258_window.xul \
 		bug294258_testcase.html \
 		test_bug298622.xul \
 		bug298622_window.xul \
+		test_bug301397.xul \
+		bug301397_window.xul \
+		bug301397_1.html \
+		bug301397_2.html \
+		bug301397_3.html \
+		bug301397_4.html \
 		test_bug303267.xul \
 		bug303267.html \
 		bug303267_window.xul \
 		test_bug321671.xul \
 		bug321671_window.xul \
 		test_bug360511.xul \
 		bug360511_window.xul \
 		bug360511_case1.html \
new file mode 100644
--- /dev/null
+++ b/docshell/test/chrome/bug301397_1.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>iframe parent</title>
+  </head>
+<body>
+  <iframe id="iframe" src="bug301397_2.html"/>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/docshell/test/chrome/bug301397_2.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>iframe content #1</title>
+  </head>
+<body>
+  iframe page 1<br/>
+  <a id="link" href="bug301397_3.html">go to next page</a>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/docshell/test/chrome/bug301397_3.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>iframe content #2</title>
+  </head>
+<body>
+  iframe page 2<br/>
+  You made it!
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/docshell/test/chrome/bug301397_4.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>dummy page, no iframe</title>
+  </head>
+<body>
+  Just a boring test page, nothing special.
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/docshell/test/chrome/bug301397_window.xul
@@ -0,0 +1,253 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+
+<window id="301397Test"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        width="600"
+        height="600"
+        onload="setTimeout(nextTest,0);"
+        title="bug 301397 test">
+
+  <script type="application/javascript"
+    src=
+  "chrome://mochikit/content/chrome/docshell/test/chrome/docshell_helpers.js">
+  </script>
+
+  <script type="application/javascript"><![CDATA[
+  
+    // Define the generator-iterator for the tests.
+    var tests = testIterator();
+
+    ////
+    // Execute the next test in the generator function.
+    //
+    function nextTest() {
+      tests.next();
+    }
+    
+    ////
+    // Return the document element with the specified id.
+    //
+    function $(id) { return TestWindow.getDocument().getElementById(id); }
+
+    ////
+    // Verifies that the given string exists in the innerHTML of the iframe
+    // content.
+    //
+    function verifyIframeInnerHtml(string) {
+      var iframeInnerHtml = $("iframe").contentDocument.body.innerHTML;
+      ok(iframeInnerHtml.indexOf(string) != -1,
+        "iframe contains wrong document: " + iframeInnerHtml);    
+    }
+    
+    ////
+    // Generator function for test steps for bug 301397:  
+    // The correct page should be displayed in an iframe when
+    // navigating back and forwards, when the parent page
+    // occupies multiple spots in the session history.
+    //
+    function testIterator()
+    {
+      // Make sure the bfcache is enabled.
+      enableBFCache(8);
+
+      // Load a dummy page.
+      doPageNavigation({
+        uri: getHttpUrl("generic.html"),
+        onNavComplete: nextTest
+      });
+      yield;
+      
+      // Load a page containing an iframe.
+      doPageNavigation({
+        uri: getHttpUrl("bug301397_1.html"),
+        eventsToListenFor: ["pageshow", "pagehide"],
+        expectedEvents: [ { type: "pagehide",
+                            title: "generic page",
+                            persisted: true },
+                          { type: "pageshow",
+                            title: "iframe content #1",
+                            persisted: false },   // false on initial load
+                          { type: "pageshow",
+                            title: "iframe parent",
+                            persisted: false } ], // false on initial load
+        onNavComplete: nextTest
+      });
+      yield;
+      
+      // Click a link in the iframe to cause the iframe to navigate
+      // to a new page, and wait until the related pagehide/pageshow
+      // events have occurred.
+      waitForPageEvents({
+        eventsToListenFor: ["pageshow", "pagehide"],
+        expectedEvents: [ { type: "pagehide",
+                            title: "iframe content #1",
+                            persisted: false },   // false, subframe nav
+                          { type: "pageshow",
+                            title: "iframe content #2",
+                            persisted: false } ], // false on initial load
+        onNavComplete: nextTest
+      });
+      var link = $("iframe").contentDocument.getElementById("link");
+      var event = $("iframe").contentDocument.createEvent("MouseEvents");
+      event.initMouseEvent("click", true, true, $("iframe").contentWindow,
+          0, 0, 0, 0, 0,
+          false, false, false, false,
+          0, null);
+      link.dispatchEvent(event);
+      yield;
+       
+      // Load another dummy page.  Verify that both the outgoing parent and
+      // iframe pages are stored in the bfcache.
+      doPageNavigation({
+        uri: getHttpUrl("bug301397_4.html"),
+        eventsToListenFor: ["pageshow", "pagehide"],
+        expectedEvents: [ { type: "pagehide",
+                            title: "iframe parent",
+                            persisted: true },
+                          { type: "pagehide",
+                            title: "iframe content #2",
+                            persisted: true },
+                          { type: "pageshow",
+                            title: "dummy page, no iframe",
+                            persisted: false } ],  // false on initial load
+        onNavComplete: nextTest
+      });
+      yield;
+      
+      // Go back.  The iframe should show the second page loaded in it. 
+      // Both the parent and the iframe pages should be loaded from
+      // the bfcache.
+      doPageNavigation({
+        back: true,
+        eventsToListenFor: ["pageshow", "pagehide"],
+        expectedEvents: [ { type: "pagehide",
+                            title: "dummy page, no iframe",
+                            persisted: true },
+                          { type: "pageshow",
+                            persisted: true,
+                            title: "iframe content #2" },
+                          { type: "pageshow",
+                            persisted: true,
+                            title: "iframe parent" } ],
+        onNavComplete: nextTest
+      });
+      yield;
+      
+      verifyIframeInnerHtml("You made it");
+      
+      // Go gack again.  The iframe should show the first page loaded in it.
+      doPageNavigation({
+        back: true,
+        eventsToListenFor: ["pageshow", "pagehide"],
+        expectedEvents: [ { type: "pagehide",
+                            title: "iframe content #2",
+                            persisted: false },  // false, subframe nav
+                          { type: "pageshow",
+                            title: "iframe content #1",
+                            // false since this page was never stored
+                            // in the bfcache in the first place
+                            persisted: false } ], 
+        onNavComplete: nextTest
+      });
+      yield;
+      
+      verifyIframeInnerHtml("go to next page");
+      
+      // Go back to the generic page.  Now go forward to the last page,
+      // again verifying that the iframe shows the first and second
+      // pages in order.
+      doPageNavigation({
+        back: true,
+        eventsToListenFor: ["pageshow", "pagehide"],
+        expectedEvents: [ { type: "pagehide",
+                            title: "iframe parent",
+                            persisted: true },
+                          { type: "pagehide",
+                            title: "iframe content #1",
+                            persisted: true },
+                          { type: "pageshow",
+                            title: "generic page",
+                            persisted: true } ], 
+        onNavComplete: nextTest
+      });
+      yield;
+
+      doPageNavigation({
+        forward: true,
+        eventsToListenFor: ["pageshow"],
+        expectedEvents: [ {type: "pageshow",
+                           title: "iframe content #1",
+                           persisted: true},
+                          {type: "pageshow",
+                           title: "iframe parent",
+                           persisted: true} ],
+        onNavComplete: nextTest
+      });
+      yield;
+
+      verifyIframeInnerHtml("go to next page");
+      
+      doPageNavigation({
+        forward: true,
+        eventsToListenFor: ["pageshow", "pagehide"],
+        expectedEvents: [ { type: "pagehide",
+                            title: "iframe content #1",
+                            persisted: false },   // false, subframe nav
+                          { type: "pageshow",
+                            title: "iframe content #2",
+                            // false because the page wasn't stored in 
+                            // bfcache last time it was unloaded
+                            persisted: false } ], 
+        onNavComplete: nextTest
+      });
+      yield;
+
+      verifyIframeInnerHtml("You made it");
+      
+      doPageNavigation({
+        forward: true,
+        eventsToListenFor: ["pageshow", "pagehide"],
+        expectedEvents: [ { type: "pagehide",
+                            title: "iframe parent",
+                            persisted: true },
+                          { type: "pagehide",
+                            title: "iframe content #2",
+                            persisted: true },
+                          { type: "pageshow",
+                            title: "dummy page, no iframe",
+                            persisted: true } ],
+        onNavComplete: nextTest
+      });
+      yield;
+
+      // Go back once more, and again verify that the iframe shows the
+      // second page loaded in it.
+      doPageNavigation({
+        back: true,
+        eventsToListenFor: ["pageshow", "pagehide"],
+        expectedEvents: [ { type: "pagehide",
+                            title: "dummy page, no iframe",
+                            persisted: true },
+                          { type: "pageshow",
+                            persisted: true,
+                            title: "iframe content #2" },
+                          { type: "pageshow",
+                            persisted: true,
+                            title: "iframe parent" } ],
+        onNavComplete: nextTest
+      });
+      yield;
+      
+      verifyIframeInnerHtml("You made it");
+      
+      // Tell the framework the test is finished.  Include the final 'yield' 
+      // statement to prevent a StopIteration exception from being thrown.
+      finish();
+      yield;
+    }
+    
+  ]]></script>
+
+  <browser type="content-primary" flex="1" id="content" src="about:blank"/>
+</window>
--- a/docshell/test/chrome/docshell_helpers.js
+++ b/docshell/test/chrome/docshell_helpers.js
@@ -11,24 +11,25 @@ for each (var import in imports) {
  * Define global constants and variables.
  */
 const NAV_NONE = 0;
 const NAV_BACK = 1;
 const NAV_FORWARD = 2;
 const NAV_URI = 3;
 const NAV_RELOAD = 4;
 
-var gExpectedEvents;         // an array of events which are expected to be 
-                             // triggered by this navigation
-var gFinalEvent;             // true if the last expected event has occurred
-var gUrisNotInBFCache = [];  // an array of uri's which shouldn't be stored
-                             // in the bfcache
-var gNavType = NAV_NONE;     // defines the most recent navigation type
-                             // executed by doPageNavigation
-
+var gExpectedEvents;          // an array of events which are expected to
+                              // be triggered by this navigation
+var gFinalEvent;              // true if the last expected event has fired
+var gUrisNotInBFCache = [];   // an array of uri's which shouldn't be stored
+                              // in the bfcache
+var gNavType = NAV_NONE;      // defines the most recent navigation type
+                              // executed by doPageNavigation
+var gOrigMaxTotalViewers =    // original value of max_total_viewers,
+  undefined;                  // to be restored at end of test
 
 /**
  * The doPageNavigation() function performs page navigations asynchronously, 
  * listens for specified events, and compares actual events with a list of 
  * expected events.  When all expected events have occurred, an optional 
  * callback can be notified. The parameter passed to this function is an 
  * object with the following properties:
  * 
@@ -87,32 +88,40 @@ function doPageNavigation(params) {
   let reload = params.reload ? params.reload : false;
   let uri = params.uri ? params.uri : false;
   let eventsToListenFor = typeof(params.eventsToListenFor) != "undefined" ?
     params.eventsToListenFor : ["pageshow"];
   gExpectedEvents = typeof(params.eventsToListenFor) == "undefined" || 
     eventsToListenFor.length == 0 ? undefined : params.expectedEvents; 
   let preventBFCache = (typeof[params.preventBFCache] == "undefined") ? 
     false : params.preventBFCache;
-    
+  let waitOnly = (typeof(params.waitForEventsOnly) == "boolean" 
+    && params.waitForEventsOnly);
+  
   // Do some sanity checking on arguments.  
   if (back && forward)
     throw "Can't specify both back and forward";
   if (back && uri)
     throw "Can't specify both back and a uri";
   if (forward && uri)
     throw "Can't specify both forward and a uri";
   if (reload && (forward || back || uri))
     throw "Can't specify reload and another navigation type";
-  if (!back && !forward && !uri && !reload)
+  if (!back && !forward && !uri && !reload && !waitOnly)
     throw "Must specify back or foward or reload or uri";
   if (params.onNavComplete && eventsToListenFor.length == 0)
     throw "Can't use onNavComplete when eventsToListenFor == []";
   if (params.preventBFCache && eventsToListenFor.length == 0)
     throw "Can't use preventBFCache when eventsToListenFor == []";
+  if (params.preventBFCache && waitOnly)
+    throw "Can't prevent bfcaching when only waiting for events";
+  if (waitOnly && typeof(params.onNavComplete) == "undefined")
+    throw "Must specify onNavComplete when specifying waitForEventsOnly";
+  if (waitOnly && (back || forward || reload || uri))
+    throw "Can't specify a navigation type when using waitForEventsOnly";
   for each (let anEventType in eventsToListenFor) {
     let eventFound = false;
     if ( (anEventType == "pageshow") && (!gExpectedEvents) )
       eventFound = true;
     for each (let anExpectedEvent in gExpectedEvents) {
       if (anExpectedEvent.type == anEventType)
         eventFound = true;
     }
@@ -145,16 +154,19 @@ function doPageNavigation(params) {
   else if (uri) {
     gNavType = NAV_URI;
     TestWindow.getBrowser().loadURI(uri);
   }
   else if (reload) {
     gNavType = NAV_RELOAD;
     TestWindow.getBrowser().reload();
   }
+  else if (waitOnly) {
+    gNavType = NAV_NONE;
+  }
   else {
     throw "No valid navigation type passed to doPageNavigation!";
   }
   
   // If we're listening for events and there is an .onNavComplete callback, 
   // wait for all events to occur, and then call doPageNavigation_complete().
   if (eventsToListenFor.length > 0 && params.onNavComplete)
   {
@@ -207,16 +219,26 @@ function doPageNavigation_complete(event
       }, this);
   }
   
   // Notify the callback now that we're done.
   onNavComplete.call();
 }
 
 /**
+ * Allows a test to wait for page navigation events, and notify a 
+ * callback when they've all been received.  This works exactly the
+ * same as doPageNavigation(), except that no navigation is initiated.
+ */
+function waitForPageEvents(params) {
+  params.waitForEventsOnly = true;
+  doPageNavigation(params);
+}
+
+/**
  * The event listener which listens for expectedEvents.
  */
 function pageEventListener(event) {
   try {
     dump("TEST: eventListener received a " + event.type + " event for page " +
       event.originalTarget.title + ", persisted=" + event.persisted + "\n");
   }catch(e) {
     // Ignore any exception.
@@ -282,16 +304,26 @@ function pageEventListener(event) {
 
 /**
  * End a test.  
  */
 function finish() {
   // Work around bug 467960.
   var history = TestWindow.getBrowser().webNavigation.sessionHistory;
   history.PurgeHistory(history.count);
+  
+  // If the test changed the value of max_total_viewers via a call to
+  // enableBFCache(), then restore it now.
+  if (typeof(gOrigMaxTotalViewers) != "undefined") {
+    netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+    var prefs = Components.classes["@mozilla.org/preferences-service;1"]
+                .getService(Components.interfaces.nsIPrefBranch);
+    prefs.setIntPref("browser.sessionhistory.max_total_viewers",
+      gOrigMaxTotalViewers);
+  }
 
   // Close the test window and signal the framework that the test is done.
   window.close();
   window.opener.wrappedJSObject.SimpleTest.finish();
 }
 
 /**
  * Helper function which waits until another function returns true, or until a 
@@ -348,16 +380,25 @@ function waitForTrue(fn, onWaitComplete,
  *
  *   enable: if true, set max_total_viewers to -1 (the default); if false, set 
  *           to 0 (disabled), if a number, set it to that specific number
  */
 function enableBFCache(enable) {
   netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
   var prefs = Components.classes["@mozilla.org/preferences-service;1"]
               .getService(Components.interfaces.nsIPrefBranch);
+  
+  // If this is the first time the test called enableBFCache(),
+  // store the original value of max_total_viewers, so it can
+  // be restored at the end of the test.
+  if (typeof(gOrigMaxTotalViewers) == "undefined") {
+    gOrigMaxTotalViewers =
+      prefs.getIntPref("browser.sessionhistory.max_total_viewers");
+  }
+  
   if (typeof(enable) == "boolean") {
     if (enable)
       prefs.setIntPref("browser.sessionhistory.max_total_viewers", -1);
     else
       prefs.setIntPref("browser.sessionhistory.max_total_viewers", 0);    
   }
   else if (typeof(enable) == "number") {
     prefs.setIntPref("browser.sessionhistory.max_total_viewers", enable);    
new file mode 100644
--- /dev/null
+++ b/docshell/test/chrome/test_bug301397.xul
@@ -0,0 +1,43 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet
+  href="chrome://mochikit/content/tests/SimpleTest/test.css"
+  type="text/css"?>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=301397.xul
+-->
+<window title="Mozilla Bug 301397"
+  xmlns:html="http://www.w3.org/1999/xhtml"
+  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+  <title>Test for Bug 301397</title>
+  <script type="application/javascript"
+    src="chrome://mochikit/content/MochiKit/packed.js"></script>
+  <script type="application/javascript"
+    src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+
+<body  xmlns="http://www.w3.org/1999/xhtml">
+<a target="_blank"
+   href="https://bugzilla.mozilla.org/show_bug.cgi?id=301397">
+   Mozilla Bug 301397</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+
+<script class="testbody" type="application/javascript">
+<![CDATA[
+
+/** Test for Bug 301397 **/
+
+SimpleTest.waitForExplicitFinish();
+window.open("bug301397_window.xul", "bug301397",
+            "chrome,width=600,height=600");
+
+]]>
+</script>
+
+</window>
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -144,17 +144,17 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mFocusedContent)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mFirstBlurEvent)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mFirstFocusEvent)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mWindowBeingLowered)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 static NS_DEFINE_CID(kLookAndFeelCID, NS_LOOKANDFEEL_CID);
 
-nsIFocusManager* nsFocusManager::sInstance = nsnull;
+nsFocusManager* nsFocusManager::sInstance = nsnull;
 
 nsFocusManager::nsFocusManager()
 { }
 
 nsFocusManager::~nsFocusManager()
 {
   nsCOMPtr<nsIPrefBranch2> prefBranch =
     do_QueryInterface(nsContentUtils::GetPrefBranch());
--- a/dom/base/nsFocusManager.h
+++ b/dom/base/nsFocusManager.h
@@ -68,17 +68,24 @@ public:
 
   // called to initialize and stop the focus manager at startup and shutdown
   static nsresult Init();
   static void Shutdown();
 
   /**
    * Retrieve the single focus manager.
    */
-  static nsIFocusManager* GetFocusManager() { return sInstance; }
+  static nsFocusManager* GetFocusManager() { return sInstance; }
+
+  /**
+   * A faster version of nsIFocusManager::GetFocusedElement, returning a
+   * raw nsIContent pointer (instead of having AddRef-ed nsIDOMElement
+   * pointer filled in to an out-parameter).
+   */
+  nsIContent* GetFocusedContent() { return mFocusedContent; }
 
   /**
    * Returns the content node that would be focused if aWindow was in an
    * active window. This will traverse down the frame hierarchy, starting at
    * the given window aWindow. Sets aFocusedWindow to the window with the
    * document containing aFocusedContent. If no element is focused,
    * aFocusedWindow may be still be set -- this means that the document is
    * focused but no element within it is focused.
@@ -432,15 +439,15 @@ protected:
   // keep track of a window while it is being lowered
   nsCOMPtr<nsPIDOMWindow> mWindowBeingLowered;
 
   // synchronized actions cannot be interrupted with events, so queue these up
   // and fire them later.
   nsTArray<nsDelayedBlurOrFocusEvent> mDelayedBlurFocusEvents;
 
   // the single focus manager
-  static nsIFocusManager* sInstance;
+  static nsFocusManager* sInstance;
 };
 
 nsresult
 NS_NewFocusManager(nsIFocusManager** aResult);
 
 #endif
--- a/dom/interfaces/threads/nsIDOMWorkers.idl
+++ b/dom/interfaces/threads/nsIDOMWorkers.idl
@@ -78,30 +78,46 @@ interface nsIWorkerErrorEvent : nsIDOMEv
   void initErrorEvent(in DOMString aTypeArg,
                       in boolean aCanBubbleArg,
                       in boolean aCancelableArg,
                       in DOMString aMessageArg,
                       in DOMString aFilenameArg,
                       in unsigned long aLinenoArg);
 };
 
+[scriptable, uuid(17a005c3-4f2f-4bb6-b169-c181fa6873de)]
+interface nsIWorkerLocation : nsISupports
+{
+  readonly attribute AUTF8String href;
+  readonly attribute AUTF8String protocol;
+  readonly attribute AUTF8String host;
+  readonly attribute AUTF8String hostname;
+  readonly attribute AUTF8String port;
+  readonly attribute AUTF8String pathname;
+  readonly attribute AUTF8String search;
+  readonly attribute AUTF8String hash;
+
+  AUTF8String toString();
+};
+
 [scriptable, uuid(74fb665a-e477-4ce2-b3c6-c58b1b28b6c3)]
 interface nsIWorkerNavigator : nsISupports
 {
   readonly attribute DOMString appName;
   readonly attribute DOMString appVersion;
   readonly attribute DOMString platform;
   readonly attribute DOMString userAgent;
 };
 
-[scriptable, uuid(d7d7cf59-6c8a-4598-8753-630953ae7409)]
+[scriptable, uuid(c111e7d3-8044-4458-aa7b-637696ffb841)]
 interface nsIWorkerGlobalScope : nsISupports
 {
   readonly attribute nsIWorkerGlobalScope self;
   readonly attribute nsIWorkerNavigator navigator;
+  readonly attribute nsIWorkerLocation location;
 
   attribute nsIDOMEventListener onerror;
 };
 
 [scriptable, uuid(5c55ea4b-e4ac-4ceb-bfeb-46bd5e521b8a)]
 interface nsIWorkerScope : nsIWorkerGlobalScope
 {
   void postMessage(/* in JSObject aMessage */);
--- a/dom/src/threads/Makefile.in
+++ b/dom/src/threads/Makefile.in
@@ -66,16 +66,17 @@ REQUIRES = \
   xpcom \
   xpconnect \
   $(NULL)
 
 CPPSRCS = \
   nsDOMThreadService.cpp \
   nsDOMWorker.cpp \
   nsDOMWorkerEvents.cpp \
+  nsDOMWorkerLocation.cpp \
   nsDOMWorkerMessageHandler.cpp \
   nsDOMWorkerNavigator.cpp \
   nsDOMWorkerPool.cpp \
   nsDOMWorkerScriptLoader.cpp \
   nsDOMWorkerSecurityManager.cpp \
   nsDOMWorkerTimeout.cpp \
   nsDOMWorkerXHR.cpp \
   nsDOMWorkerXHRProxy.cpp \
--- a/dom/src/threads/nsDOMThreadService.cpp
+++ b/dom/src/threads/nsDOMThreadService.cpp
@@ -533,40 +533,43 @@ DOMWorkerOperationCallback(JSContext* aC
           gDOMThreadService->ChangeThreadPoolMaxThreads(-1);
         }
         JS_ResumeRequest(aCx, suspendDepth);
       }
       return JS_TRUE;
     }
 
     if (!wasSuspended) {
-      // It's possible that the worker was canceled since we checked above.
-      if (worker->IsCanceled()) {
-        NS_WARNING("Tried to suspend on a pool that has gone away");
-        JS_ClearPendingException(aCx);
-        return JS_FALSE;
-      }
-
       // Make sure to suspend our request while we block like this, otherwise we
       // prevent GC for everyone.
       suspendDepth = JS_SuspendRequest(aCx);
 
       // Since we're going to block this thread we should open up a new thread
       // in the thread pool for other workers. Must check the return value to
       // make sure we don't decrement when we failed.
       extraThreadAllowed =
         NS_SUCCEEDED(gDOMThreadService->ChangeThreadPoolMaxThreads(1));
 
       // Only do all this setup once.
       wasSuspended = PR_TRUE;
     }
 
     nsAutoMonitor mon(worker->Pool()->Monitor());
-    mon.Wait();
+
+    // There's a small chance that the worker was canceled after our check
+    // above in which case we shouldn't wait here. We're guaranteed not to race
+    // here because the pool reenters its monitor after canceling each worker
+    // in order to notify its condition variable.
+    if (!worker->IsCanceled()) {
+      mon.Wait();
+    }
   }
+
+  NS_NOTREACHED("Should never get here!");
+  return JS_FALSE;
 }
 
 void
 DOMWorkerErrorReporter(JSContext* aCx,
                        const char* aMessage,
                        JSErrorReport* aReport)
 {
   NS_ASSERTION(!NS_IsMainThread(), "Huh?!");
--- a/dom/src/threads/nsDOMWorker.cpp
+++ b/dom/src/threads/nsDOMWorker.cpp
@@ -53,16 +53,17 @@
 #include "nsGlobalWindow.h"
 #include "nsJSON.h"
 #include "nsJSUtils.h"
 #include "nsProxyRelease.h"
 #include "nsThreadUtils.h"
 
 #include "nsDOMThreadService.h"
 #include "nsDOMWorkerEvents.h"
+#include "nsDOMWorkerLocation.h"
 #include "nsDOMWorkerNavigator.h"
 #include "nsDOMWorkerPool.h"
 #include "nsDOMWorkerScriptLoader.h"
 #include "nsDOMWorkerTimeout.h"
 #include "nsDOMWorkerXHR.h"
 
 class nsDOMWorkerFunctions
 {
@@ -694,16 +695,28 @@ nsDOMWorkerScope::GetNavigator(nsIWorker
     NS_ENSURE_TRUE(mNavigator, NS_ERROR_OUT_OF_MEMORY);
   }
 
   NS_ADDREF(*_retval = mNavigator);
   return NS_OK;
 }
 
 NS_IMETHODIMP
+nsDOMWorkerScope::GetLocation(nsIWorkerLocation** _retval)
+{
+  NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
+
+  nsCOMPtr<nsIWorkerLocation> location = mWorker->GetLocation();
+  NS_ASSERTION(location, "This should never be null!");
+
+  location.forget(_retval);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 nsDOMWorkerScope::GetOnerror(nsIDOMEventListener** aOnerror)
 {
   NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
   NS_ENSURE_ARG_POINTER(aOnerror);
 
   if (mWorker->IsCanceled()) {
     return NS_ERROR_ABORT;
   }
@@ -1740,16 +1753,34 @@ nsDOMWorker::ResumeFeatures()
 
   PRUint32 count = features.Length();
   for (PRUint32 i = 0; i < count; i++) {
     features[i]->Resume();
   }
 }
 
 nsresult
+nsDOMWorker::SetURI(nsIURI* aURI)
+{
+  NS_ASSERTION(aURI, "Don't hand me a null pointer!");
+  NS_ASSERTION(!mURI && !mLocation, "Called more than once?!");
+  NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+
+  mURI = aURI;
+
+  nsCOMPtr<nsIURL> url(do_QueryInterface(aURI));
+  NS_ENSURE_TRUE(url, NS_ERROR_NO_INTERFACE);
+
+  mLocation = nsDOMWorkerLocation::NewLocation(url);
+  NS_ENSURE_TRUE(mLocation, NS_ERROR_FAILURE);
+
+  return NS_OK;
+}
+
+nsresult
 nsDOMWorker::FireCloseRunnable(PRIntervalTime aTimeoutInterval,
                                PRBool aClearQueue,
                                PRBool aFromFinalize)
 {
   // Resume the worker (but not its features) if we're currently suspended. This
   // should only ever happen if we are being called from Cancel (page falling
   // out of bfcache or quitting) or Finalize, in which case all we really want
   // to do is unblock the waiting thread.
--- a/dom/src/threads/nsDOMWorker.h
+++ b/dom/src/threads/nsDOMWorker.h
@@ -261,27 +261,29 @@ private:
   void SetPrincipal(nsIPrincipal* aPrincipal) {
     mPrincipal = aPrincipal;
   }
 
   nsIURI* GetURI() {
     return mURI;
   }
 
-  void SetURI(nsIURI* aURI) {
-    mURI = aURI;
-  }
+  nsresult SetURI(nsIURI* aURI);
 
   nsresult FireCloseRunnable(PRIntervalTime aTimeoutInterval,
                              PRBool aClearQueue,
                              PRBool aFromFinalize);
   nsresult Close();
 
   nsresult TerminateInternal(PRBool aFromFinalize);
 
+  nsIWorkerLocation* GetLocation() {
+    return mLocation;
+  }
+
 private:
 
   // mParent will live as long as mParentWN but only mParentWN will keep the JS
   // reflection alive, so we only hold one strong reference to mParentWN.
   nsDOMWorker* mParent;
   nsCOMPtr<nsIXPConnectWrappedNative> mParentWN;
 
   PRLock* mLock;
@@ -309,16 +311,18 @@ private:
   // Always protected by mLock
   DOMWorkerStatus mStatus;
 
   // Always protected by mLock
   PRIntervalTime mExpirationTime;
 
   nsCOMPtr<nsITimer> mKillTimer;
 
+  nsCOMPtr<nsIWorkerLocation> mLocation;
+
   PRPackedBool mSuspended;
   PRPackedBool mCompileAttempted;
 };
 
 /**
  * A worker "feature" holds the worker alive yet can be canceled, paused, and
  * resumed by the worker. It is up to each derived class to implement these
  * methods. This class uses a custom implementation of Release in order to
new file mode 100644
--- /dev/null
+++ b/dom/src/threads/nsDOMWorkerLocation.cpp
@@ -0,0 +1,223 @@
+/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is worker threads.
+ *
+ * The Initial Developer of the Original Code is
+ *   Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Ben Turner <bent.mozilla@gmail.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsDOMWorkerLocation.h"
+
+#include "nsIClassInfoImpl.h"
+#include "nsITextToSubURI.h"
+#include "nsIURL.h"
+
+#include "nsDOMWorkerMacros.h"
+
+#include "nsAutoPtr.h"
+#include "nsEscape.h"
+#include "nsNetUtil.h"
+
+#define XPC_MAP_CLASSNAME nsDOMWorkerLocation
+#define XPC_MAP_QUOTED_CLASSNAME "WorkerLocation"
+
+#define XPC_MAP_FLAGS                                      \
+  nsIXPCScriptable::USE_JSSTUB_FOR_ADDPROPERTY           | \
+  nsIXPCScriptable::USE_JSSTUB_FOR_DELPROPERTY           | \
+  nsIXPCScriptable::USE_JSSTUB_FOR_SETPROPERTY           | \
+  nsIXPCScriptable::DONT_ENUM_QUERY_INTERFACE            | \
+  nsIXPCScriptable::CLASSINFO_INTERFACES_ONLY            | \
+  nsIXPCScriptable::DONT_REFLECT_INTERFACE_NAMES
+
+#include "xpc_map_end.h"
+
+NS_IMPL_THREADSAFE_ISUPPORTS3(nsDOMWorkerLocation, nsIWorkerLocation,
+                                                   nsIClassInfo,
+                                                   nsIXPCScriptable)
+
+NS_IMPL_CI_INTERFACE_GETTER1(nsDOMWorkerLocation, nsIWorkerLocation)
+
+NS_IMPL_THREADSAFE_DOM_CI_GETINTERFACES(nsDOMWorkerLocation)
+NS_IMPL_THREADSAFE_DOM_CI_ALL_THE_REST(nsDOMWorkerLocation)
+
+NS_IMETHODIMP
+nsDOMWorkerLocation::GetHelperForLanguage(PRUint32 aLanguage,
+                                          nsISupports** _retval)
+{
+  if (aLanguage == nsIProgrammingLanguage::JAVASCRIPT) {
+    NS_ADDREF(*_retval = NS_ISUPPORTS_CAST(nsIWorkerLocation*, this));
+  }
+  else {
+    *_retval = nsnull;
+  }
+  return NS_OK;
+}
+
+// static
+already_AddRefed<nsIWorkerLocation>
+nsDOMWorkerLocation::NewLocation(nsIURL* aURL)
+{
+  NS_ASSERTION(aURL, "Don't hand me a null pointer!");
+
+  nsAutoPtr<nsDOMWorkerLocation> location(new nsDOMWorkerLocation());
+  NS_ENSURE_TRUE(location, nsnull);
+
+  nsresult rv = aURL->GetSpec(location->mHref);
+  NS_ENSURE_SUCCESS(rv, nsnull);
+
+  rv = aURL->GetHost(location->mHostname);
+  NS_ENSURE_SUCCESS(rv, nsnull);
+
+  rv = aURL->GetPath(location->mPathname);
+  NS_ENSURE_SUCCESS(rv, nsnull);
+
+  nsCString temp;
+
+  rv = aURL->GetQuery(temp);
+  NS_ENSURE_SUCCESS(rv, nsnull);
+  if (!temp.IsEmpty()) {
+    location->mSearch.AssignLiteral("?");
+    location->mSearch.Append(temp);
+  }
+
+  rv = aURL->GetRef(temp);
+  NS_ENSURE_SUCCESS(rv, nsnull);
+
+  if (!temp.IsEmpty()) {
+    nsAutoString unicodeRef;
+
+    nsCOMPtr<nsITextToSubURI> converter =
+      do_GetService(NS_ITEXTTOSUBURI_CONTRACTID, &rv);
+    if (NS_SUCCEEDED(rv)) {
+      nsCString charset;
+      rv = aURL->GetOriginCharset(charset);
+      if (NS_SUCCEEDED(rv)) {
+        rv = converter->UnEscapeURIForUI(charset, temp, unicodeRef);
+        if (NS_SUCCEEDED(rv)) {
+          location->mHash.AssignLiteral("#");
+          location->mHash.Append(NS_ConvertUTF16toUTF8(unicodeRef));
+        }
+      }
+    }
+
+    if (NS_FAILED(rv)) {
+      location->mHash.AssignLiteral("#");
+      location->mHash.Append(temp);
+    }
+  }
+
+  rv = aURL->GetScheme(location->mProtocol);
+  NS_ENSURE_SUCCESS(rv, nsnull);
+
+  location->mProtocol.AppendLiteral(":");
+
+  PRInt32 port;
+  rv = aURL->GetPort(&port);
+  if (NS_SUCCEEDED(rv) && port != -1) {
+    location->mPort.AppendInt(port);
+
+    nsCAutoString host(location->mHostname);
+    host.AppendLiteral(":");
+    host.Append(location->mPort);
+
+    location->mHost.Assign(host);
+  }
+  else {
+    location->mHost.Assign(location->mHostname);
+  }
+
+  NS_ADDREF(location);
+  return location.forget();
+}
+
+NS_IMETHODIMP
+nsDOMWorkerLocation::GetHref(nsACString& aHref)
+{
+  aHref.Assign(mHref);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDOMWorkerLocation::GetProtocol(nsACString& aProtocol)
+{
+  aProtocol.Assign(mProtocol);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDOMWorkerLocation::GetHost(nsACString& aHost)
+{
+  aHost.Assign(mHost);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDOMWorkerLocation::GetHostname(nsACString& aHostname)
+{
+  aHostname.Assign(mHostname);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDOMWorkerLocation::GetPort(nsACString& aPort)
+{
+  aPort.Assign(mPort);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDOMWorkerLocation::GetPathname(nsACString& aPathname)
+{
+  aPathname.Assign(mPathname);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDOMWorkerLocation::GetSearch(nsACString& aSearch)
+{
+  aSearch.Assign(mSearch);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDOMWorkerLocation::GetHash(nsACString& aHash)
+{
+  aHash.Assign(mHash);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDOMWorkerLocation::ToString(nsACString& _retval)
+{
+  return GetHref(_retval);
+}
new file mode 100644
--- /dev/null
+++ b/dom/src/threads/nsDOMWorkerLocation.h
@@ -0,0 +1,77 @@
+/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is worker threads.
+ *
+ * The Initial Developer of the Original Code is
+ *   Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Ben Turner <bent.mozilla@gmail.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef __NSDOMWORKERLOCATION_H__
+#define __NSDOMWORKERLOCATION_H__
+
+#include "nsIClassInfo.h"
+#include "nsIDOMWorkers.h"
+#include "nsIXPCScriptable.h"
+
+#include "nsCOMPtr.h"
+#include "nsStringGlue.h"
+
+class nsIURL;
+
+class nsDOMWorkerLocation : public nsIWorkerLocation,
+                            public nsIClassInfo,
+                            public nsIXPCScriptable
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIWORKERLOCATION
+  NS_DECL_NSICLASSINFO
+  NS_DECL_NSIXPCSCRIPTABLE
+
+  static already_AddRefed<nsIWorkerLocation> NewLocation(nsIURL* aURL);
+
+protected:
+  nsDOMWorkerLocation() { }
+
+private:
+  nsCString mHref;
+  nsCString mProtocol;
+  nsCString mHost;
+  nsCString mHostname;
+  nsCString mPort;
+  nsCString mPathname;
+  nsCString mSearch;
+  nsCString mHash;
+};
+
+#endif /* __NSDOMWORKERLOCATION_H__ */
--- a/dom/src/threads/nsDOMWorkerScriptLoader.cpp
+++ b/dom/src/threads/nsDOMWorkerScriptLoader.cpp
@@ -478,17 +478,19 @@ nsDOMWorkerScriptLoader::RunInternal()
     // do a same-origin check. Otherwise we need to clear the load with the
     // security manager.
     if (mForWorker) {
       rv = principal->CheckMayLoad(uri, PR_FALSE);
       NS_ENSURE_SUCCESS(rv, rv);
 
       // Set the principal and URI on the new worker.
       mWorker->SetPrincipal(principal);
-      mWorker->SetURI(uri);
+
+      rv = mWorker->SetURI(uri);
+      NS_ENSURE_SUCCESS(rv, rv);
     }
     else {
       rv = secMan->CheckLoadURIWithPrincipal(principal, uri, 0);
       NS_ENSURE_SUCCESS(rv, rv);
     }
 
     // We need to know which index we're on in OnStreamComplete so we know where
     // to put the result.
--- a/dom/src/threads/nsDOMWorkerTimeout.cpp
+++ b/dom/src/threads/nsDOMWorkerTimeout.cpp
@@ -302,25 +302,18 @@ nsDOMWorkerTimeout::Init(JSContext* aCx,
 nsresult
 nsDOMWorkerTimeout::Start()
 {
   if (IsSuspended()) {
     NS_ASSERTION(mSuspendedBeforeStart, "Bad state!");
     return NS_OK;
   }
 
-  PRInt32 type;
-  if (mIsInterval) {
-    type = nsITimer::TYPE_REPEATING_SLACK;
-  }
-  else {
-    type = nsITimer::TYPE_ONE_SHOT;
-  }
-
-  nsresult rv = mTimer->InitWithCallback(this, mInterval, type);
+  nsresult rv = mTimer->InitWithCallback(this, mInterval,
+                                         nsITimer::TYPE_ONE_SHOT);
   NS_ENSURE_SUCCESS(rv, rv);
 
   mStarted = PR_TRUE;
   return NS_OK;
 }
 
 nsresult
 nsDOMWorkerTimeout::Run()
@@ -338,16 +331,19 @@ nsDOMWorkerTimeout::Run()
 
   rv = mCallback->Run(this, cx);
 
   // Make sure any pending exceptions are converted to errors for the pool.
   JS_ReportPendingException(cx);
 
   if (mIsInterval) {
     mTargetTime = PR_Now() + mInterval * (PRTime)PR_USEC_PER_MSEC;
+    nsresult rv2 = mTimer->InitWithCallback(this, mInterval,
+                                            nsITimer::TYPE_ONE_SHOT);
+    NS_ENSURE_SUCCESS(rv2, rv2);
   }
 
   return rv;
 }
 
 void
 nsDOMWorkerTimeout::Cancel()
 {
--- a/dom/src/threads/test/Makefile.in
+++ b/dom/src/threads/test/Makefile.in
@@ -61,16 +61,18 @@ include $(topsrcdir)/config/rules.mk
   test_importScripts.html \
   importScripts_worker.js \
   importScripts_worker_imported1.js \
   importScripts_worker_imported2.js \
   importScripts_worker_imported3.js \
   importScripts_worker_imported4.js \
   test_json.html \
   json_worker.js \
+  test_location.html \
+  location_worker.js \
   test_longThread.html \
   longThread_worker.js \
   test_navigator.html \
   navigator_worker.js \
   test_recursion.html \
   recursion_worker.js \
   test_regExpStatics.html \
   regExpStatics_worker.js \
new file mode 100644
--- /dev/null
+++ b/dom/src/threads/test/location_worker.js
@@ -0,0 +1,4 @@
+for (var string in self.location) {
+  postMessage({ "string": string, "value": self.location[string] });
+}
+postMessage({"string": "testfinished", "value": self.location.toString()});
new file mode 100644
--- /dev/null
+++ b/dom/src/threads/test/test_location.html
@@ -0,0 +1,64 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+Tests of DOM Worker Location
+-->
+<head>
+  <title>Test for DOM Worker Location</title>
+  <script type="text/javascript" src="/MochiKit/packed.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script class="testbody" language="javascript">
+
+  var thisFilename = "test_location.html";
+  var workerFilename = "location_worker.js";
+
+  var href = window.location.href
+  var baseHref = href.substr(0, href.lastIndexOf("/") + 1);
+
+  var path = window.location.pathname;
+  var basePath = path.substr(0, path.lastIndexOf("/") + 1);
+
+  var strings = {
+    "href": baseHref + workerFilename,
+    "protocol": window.location.protocol,
+    "host": window.location.host,
+    "hostname": window.location.hostname,
+    "port": window.location.port,
+    "pathname": basePath + workerFilename,
+    "search": "",
+    "hash": ""
+  };
+
+  is(thisFilename, href.substr(href.lastIndexOf("/") + 1));
+
+  var worker = new Worker(workerFilename);
+
+  worker.onmessage = function(event) {
+    if (event.data.string == "testfinished") {
+      is(event.data.value, strings["href"]);
+      SimpleTest.finish();
+      return;
+    }
+    ok(event.data.string in strings);
+    is(event.data.value, strings[event.data.string]);
+  };
+
+  worker.onerror = function(event) {
+    ok(false, "Worker had an error: " + event.data);
+    SimpleTest.finish();
+  }
+
+  SimpleTest.waitForExplicitFinish();
+
+</script>
+</pre>
+</body>
+</html>
--- a/editor/libeditor/html/nsHTMLDataTransfer.cpp
+++ b/editor/libeditor/html/nsHTMLDataTransfer.cpp
@@ -1219,17 +1219,17 @@ nsHTMLEditor::ParseCFHTML(nsCString & aC
       }
       else if (aCfhtml[curPos] == '<') 
       {
           // if we are at the start, then we want to see the '<'
           if (curPos != startFragment) 
           {
               // working backwards, the first thing we see is the start of a tag
               // so StartFragment is bad, so we need to update it.
-              NS_ASSERTION(0, "StartFragment byte count in the clipboard looks bad, see bug #228879");
+              NS_ERROR("StartFragment byte count in the clipboard looks bad, see bug #228879");
               startFragment = curPos - 1;
           }
           break;
       }
       else 
       {
           curPos--;
       }
--- a/editor/txtsvc/src/nsTextServicesDocument.cpp
+++ b/editor/txtsvc/src/nsTextServicesDocument.cpp
@@ -1864,17 +1864,17 @@ nsTextServicesDocument::DeleteNode(nsIDO
       mIteratorStatus != nsTextServicesDocument::eIsDone)
   {
     // XXX: This should never really happen because
     // AdjustContentIterator() should have been called prior
     // to the delete to try and position the iterator on the
     // next valid text node in the offset table, and if there
     // wasn't a next, it would've set mIteratorStatus to eIsDone.
 
-    NS_ASSERTION(0, "DeleteNode called for current iterator node."); 
+    NS_ERROR("DeleteNode called for current iterator node."); 
   }
 
   tcount = mOffsetTable.Length();
 
   while (nodeIndex < tcount)
   {
     entry = mOffsetTable[nodeIndex];
 
@@ -1927,28 +1927,28 @@ nsTextServicesDocument::JoinNodes(nsIDOM
 
   result = aLeftNode->GetNodeType(&type);
 
   if (NS_FAILED(result))
     return PR_FALSE;
 
   if (nsIDOMNode::TEXT_NODE != type)
   {
-    NS_ASSERTION(0, "JoinNode called with a non-text left node!");
+    NS_ERROR("JoinNode called with a non-text left node!");
     return NS_ERROR_FAILURE;
   }
 
   result = aRightNode->GetNodeType(&type);
 
   if (NS_FAILED(result))
     return PR_FALSE;
 
   if (nsIDOMNode::TEXT_NODE != type)
   {
-    NS_ASSERTION(0, "JoinNode called with a non-text right node!");
+    NS_ERROR("JoinNode called with a non-text right node!");
     return NS_ERROR_FAILURE;
   }
 
   // Note: The editor merges the contents of the left node into the
   //       contents of the right.
 
   PRInt32 leftIndex, rightIndex;
   PRBool leftHasEntry, rightHasEntry;
--- a/embedding/browser/activex/src/common/ControlSite.cpp
+++ b/embedding/browser/activex/src/common/ControlSite.cpp
@@ -390,17 +390,17 @@ HRESULT CControlSite::Create(REFCLSID cl
 
 // Attach the created control to a window and activate it
 HRESULT CControlSite::Attach(HWND hwndParent, const RECT &rcPos, IUnknown *pInitStream)
 {
     TRACE_METHOD(CControlSite::Attach);
 
     if (hwndParent == NULL)
     {
-        NS_ASSERTION(0, "No parent hwnd");
+        NS_ERROR("No parent hwnd");
         return E_INVALIDARG;
     }
 
     m_hWndParent = hwndParent;
     m_rcObjectPos = rcPos;
 
     // Object must have been created
     if (m_spObject == NULL)
--- a/embedding/browser/activex/src/common/IEHtmlElementCollection.cpp
+++ b/embedding/browser/activex/src/common/IEHtmlElementCollection.cpp
@@ -100,17 +100,17 @@ HRESULT CIEHtmlElementCollection::Popula
     for (PRUint32 i = 0; i < length; i++)
     {
         // Get the next item from the list
         nsCOMPtr<nsIDOMNode> childNode;
         pNodeList->Item(i, getter_AddRefs(childNode));
         if (!childNode)
         {
             // Empty node (unexpected, but try and carry on anyway)
-            NS_ASSERTION(0, "Empty node");
+            NS_ERROR("Empty node");
             continue;
         }
 
         // Skip nodes representing, text, attributes etc.
         PRUint16 nodeType;
         childNode->GetNodeType(&nodeType);
         if (nodeType != nsIDOMNode::ELEMENT_NODE)
         {
@@ -126,17 +126,17 @@ HRESULT CIEHtmlElementCollection::Popula
     }
     return S_OK;
 }
 
 HRESULT CIEHtmlElementCollection::PopulateFromDOMNode(nsIDOMNode *aDOMNode, BOOL bRecurseChildren)
 {
     if (aDOMNode == nsnull)
     {
-        NS_ASSERTION(0, "No dom node");
+        NS_ERROR("No dom node");
         return E_INVALIDARG;
     }
 
     PRBool hasChildNodes = PR_FALSE;
     aDOMNode->HasChildNodes(&hasChildNodes);
     if (hasChildNodes)
     {
         if (bRecurseChildren)
@@ -191,70 +191,70 @@ HRESULT CIEHtmlElementCollection::Popula
     return S_OK;
 }
 
 
 HRESULT CIEHtmlElementCollection::CreateFromDOMHTMLCollection(CNode *pParentNode, nsIDOMHTMLCollection *pNodeList, CIEHtmlElementCollection **pInstance)
 {
     if (pInstance == NULL || pParentNode == NULL)
     {
-        NS_ASSERTION(0, "No instance or parent node");
+        NS_ERROR("No instance or parent node");
         return E_INVALIDARG;
     }
 
     // Get the DOM node from the parent node
     if (!pParentNode->mDOMNode)
     {
-        NS_ASSERTION(0, "Parent has no DOM node");
+        NS_ERROR("Parent has no DOM node");
         return E_INVALIDARG;
     }
 
     *pInstance = NULL;
 
     // Create a collection object
     CIEHtmlElementCollectionInstance *pCollection = NULL;
     CIEHtmlElementCollectionInstance::CreateInstance(&pCollection);
     if (pCollection == NULL)
     {
-        NS_ASSERTION(0, "Could not create collection");
+        NS_ERROR("Could not create collection");
         return E_OUTOFMEMORY;
     }
 
     // Initialise and populate the collection
     pCollection->SetParent(pParentNode);
     pCollection->PopulateFromDOMHTMLCollection(pNodeList);
 
     *pInstance = pCollection;
 
     return S_OK;
 }
 
 HRESULT CIEHtmlElementCollection::CreateFromParentNode(CNode *pParentNode, BOOL bRecurseChildren, CIEHtmlElementCollection **pInstance)
 {
     if (pInstance == NULL || pParentNode == NULL)
     {
-        NS_ASSERTION(0, "No instance or parent node");
+        NS_ERROR("No instance or parent node");
         return E_INVALIDARG;
     }
 
     // Get the DOM node from the parent node
     if (!pParentNode->mDOMNode)
     {
-        NS_ASSERTION(0, "Parent has no DOM node");
+        NS_ERROR("Parent has no DOM node");
         return E_INVALIDARG;
     }
 
     *pInstance = NULL;
 
     // Create a collection object
     CIEHtmlElementCollectionInstance *pCollection = NULL;
     CIEHtmlElementCollectionInstance::CreateInstance(&pCollection);
     if (pCollection == NULL)
     {
-        NS_ASSERTION(0, "Could not create collection");
+        NS_ERROR("Could not create collection");
         return E_OUTOFMEMORY;
     }
 
     // Initialise and populate the collection
     pCollection->SetParent(pParentNode);
     pCollection->PopulateFromDOMNode(pParentNode->mDOMNode, bRecurseChildren);
 
     *pInstance = pCollection;
@@ -262,17 +262,17 @@ HRESULT CIEHtmlElementCollection::Create
     return S_OK;
 }
 
 
 HRESULT CIEHtmlElementCollection::AddNode(IDispatch *pNode)
 {
     if (pNode == NULL)
     {
-        NS_ASSERTION(0, "No node");
+        NS_ERROR("No node");
         return E_INVALIDARG;
     }
 
     const PRUint32 c_NodeListResizeBy = 100;
 
     if (mNodeList == NULL)
     {
         mNodeListCapacity = c_NodeListResizeBy;
@@ -282,17 +282,17 @@ HRESULT CIEHtmlElementCollection::AddNod
     else if (mNodeListCount == mNodeListCapacity)
     {
         mNodeListCapacity += c_NodeListResizeBy;
         mNodeList = (IDispatch **) realloc(mNodeList, sizeof(IDispatch *) * mNodeListCapacity);
     }
 
     if (mNodeList == NULL)
     {
-        NS_ASSERTION(0, "Could not realloc node list");
+        NS_ERROR("Could not realloc node list");
         return E_OUTOFMEMORY;
     }
 
     pNode->AddRef();
     mNodeList[mNodeListCount++] = pNode;
 
     return S_OK;
 }
@@ -337,17 +337,17 @@ HRESULT STDMETHODCALLTYPE CIEHtmlElement
         for (PRUint32 i = 0; i < length; i++)
         {
             // Get the next item from the list
             nsCOMPtr<nsIDOMNode> childNode;
             mDOMNodeList->Item(i, getter_AddRefs(childNode));
             if (!childNode)
             {
                 // Empty node (unexpected, but try and carry on anyway)
-                NS_ASSERTION(0, "Empty node");
+                NS_ERROR("Empty node");
                 continue;
             }
 
             // Only count elements
             PRUint16 nodeType;
             childNode->GetNodeType(&nodeType);
             if (nodeType == nsIDOMNode::ELEMENT_NODE)
             {
@@ -376,46 +376,46 @@ HRESULT STDMETHODCALLTYPE CIEHtmlElement
 
     *p = NULL;
 
     // Create a new IEnumVARIANT object
     CComEnumVARIANT *pEnumVARIANT = NULL;
     CComEnumVARIANT::CreateInstance(&pEnumVARIANT);
     if (pEnumVARIANT == NULL)
     {
-        NS_ASSERTION(0, "Could not creat Enum");
+        NS_ERROR("Could not creat Enum");
         return E_OUTOFMEMORY;
     }
 
     int nObject = 0;
     long nObjects = 0;
     get_length(&nObjects);
 
     // Create an array of VARIANTs
     VARIANT *avObjects = new VARIANT[nObjects];
     if (avObjects == NULL)
     {
-        NS_ASSERTION(0, "Could not create variant array");
+        NS_ERROR("Could not create variant array");
         return E_OUTOFMEMORY;
     }
 
     if (mDOMNodeList)
     {
         // Fill the variant array with elements from the DOM node list
         PRUint32 length = 0;
         mDOMNodeList->GetLength(&length);
         for (PRUint32 i = 0; i < length; i++)
         {
             // Get the next item from the list
             nsCOMPtr<nsIDOMNode> childNode;
             mDOMNodeList->Item(i, getter_AddRefs(childNode));
             if (!childNode)
             {
                 // Empty node (unexpected, but try and carry on anyway)
-                NS_ASSERTION(0, "Could not get node");
+                NS_ERROR("Could not get node");
                 continue;
             }
 
             // Skip nodes representing, text, attributes etc.
             PRUint16 nodeType;
             childNode->GetNodeType(&nodeType);
             if (nodeType != nsIDOMNode::ELEMENT_NODE)
             {
@@ -523,17 +523,17 @@ HRESULT STDMETHODCALLTYPE CIEHtmlElement
         for (PRUint32 i = 0; i < length; i++)
         {
             // Get the next item from the list
             nsCOMPtr<nsIDOMNode> childNode;
             mDOMNodeList->Item(i, getter_AddRefs(childNode));
             if (!childNode)
             {
                 // Empty node (unexpected, but try and carry on anyway)
-                NS_ASSERTION(0, "Could not get node");
+                NS_ERROR("Could not get node");
                 continue;
             }
 
             // Skip nodes representing, text, attributes etc.
             nsCOMPtr<nsIDOMElement> nodeAsElement = do_QueryInterface(childNode);
             if (!nodeAsElement)
             {
                 continue;
@@ -633,17 +633,17 @@ HRESULT STDMETHODCALLTYPE CIEHtmlElement
             {
                 return E_INVALIDARG;
             }
 
             *pdisp = NULL;
             IDispatch *pNode = mNodeList[idxForSearch];
             if (pNode == NULL)
             {
-                NS_ASSERTION(0, "No node");
+                NS_ERROR("No node");
                 return E_UNEXPECTED;
             }
             pNode->QueryInterface(IID_IDispatch, (void **) pdisp);
         }
     }
 
     // Note: As per docs S_OK is fine even if no node is returned
     return S_OK;
@@ -683,17 +683,17 @@ HRESULT STDMETHODCALLTYPE CIEHtmlElement
         for (PRUint32 i = 0; i < length; i++)
         {
             // Get the next item from the list
             nsCOMPtr<nsIDOMNode> childNode;
             mDOMNodeList->Item(i, getter_AddRefs(childNode));
             if (!childNode)
             {
                 // Empty node (unexpected, but try and carry on anyway)
-                NS_ASSERTION(0, "Could not get node");
+                NS_ERROR("Could not get node");
                 continue;
             }
 
             // Skip nodes representing, text, attributes etc.
             nsCOMPtr<nsIDOMElement> nodeAsElement = do_QueryInterface(childNode);
             if (!nodeAsElement)
             {
                 continue;
--- a/embedding/browser/activex/src/common/IEHtmlNode.cpp
+++ b/embedding/browser/activex/src/common/IEHtmlNode.cpp
@@ -143,17 +143,17 @@ CIEHtmlDomNode::~CIEHtmlDomNode()
 #define CREATE_FROM_DOMNODE(nsInterface, WrapperType, errorMsg) \
     nsCOMPtr<nsInterface> domNode_##nsInterface = do_QueryInterface(pIDOMNode); \
     if (domNode_##nsInterface) \
     { \
         WrapperType *pWrapper = NULL; \
         WrapperType::CreateInstance(&pWrapper); \
         if (!pWrapper) \
         { \
-            NS_ASSERTION(0, errorMsg); \
+            NS_ERROR(errorMsg); \
             return E_OUTOFMEMORY; \
         } \
         if (FAILED(pWrapper->QueryInterface(IID_IUnknown, (void**)pNode))) \
             return E_UNEXPECTED; \
         pWrapper->SetDOMNode(pIDOMNode); \
         return S_OK; \
     }
 
--- a/embedding/browser/activex/src/common/IWebBrowserImpl.h
+++ b/embedding/browser/activex/src/common/IWebBrowserImpl.h
@@ -59,26 +59,26 @@ typedef long SHANDLE_PTR;
 #include "PropertyList.h"
 
 // CPMozillaControl.h was autogenerated by the ATL proxy wizard so don't edit it!
 #include "CPMozillaControl.h"
 
 #define ENSURE_BROWSER_IS_VALID() \
     if (!BrowserIsValid()) \
     { \
-        NS_ASSERTION(0, "Browser is not valid"); \
+        NS_ERROR("Browser is not valid"); \
         return SetErrorInfo(E_UNEXPECTED, L"Browser is not in a valid state"); \
     }
 
 #define ENSURE_GET_WEBNAV() \
     nsCOMPtr<nsIWebNavigation> webNav; \
     nsresult rv = GetWebNavigation(getter_AddRefs(webNav)); \
     if (NS_FAILED(rv)) \
     { \
-        NS_ASSERTION(0, "Cannot get nsIWebNavigation"); \
+        NS_ERROR("Cannot get nsIWebNavigation"); \
         return SetErrorInfo(E_UNEXPECTED, L"Could not obtain nsIWebNavigation interface"); \
     }
 
 template<class T, const CLSID *pclsid, const GUID* plibid = &LIBID_MSHTML>
 class IWebBrowserImpl :
     public CStockPropImpl<T, IWebBrowser2, &IID_IWebBrowser2, plibid>,
     public CProxyDWebBrowserEvents<T>,
     public CProxyDWebBrowserEvents2<T>
@@ -231,34 +231,34 @@ public:
         ATLTRACE(_T("IWebBrowserImpl::Navigate()\n"));
         ENSURE_BROWSER_IS_VALID();
 
         nsresult rv;
 
         // Extract the URL parameter
         if (URL == NULL)
         {
-            NS_ASSERTION(0, "No URL supplied");
+            NS_ERROR("No URL supplied");
             return SetErrorInfo(E_INVALIDARG);
         }
 
         PRBool openInNewWindow = PR_FALSE;
         PRUint32 loadFlags = nsIWebNavigation::LOAD_FLAGS_NONE;
 
         // Extract the navigate flags parameter
         LONG lFlags = 0;
         if (Flags &&
             Flags->vt != VT_ERROR &&
             Flags->vt != VT_EMPTY &&
             Flags->vt != VT_NULL)
         {
             CComVariant vFlags;
             if ( vFlags.ChangeType(VT_I4, Flags) != S_OK )
             {
-                NS_ASSERTION(0, "Flags param is invalid");
+                NS_ERROR("Flags param is invalid");
                 return SetErrorInfo(E_INVALIDARG);
             }
             lFlags = vFlags.lVal;
         }
         if (lFlags & navOpenInNewWindow) 
         {
             openInNewWindow = PR_TRUE;
         }
@@ -375,17 +375,17 @@ public:
                     SafeArrayUnlock(PostData->parray);
 
                     // Create a byte array input stream object.
                     nsCOMPtr<nsIStringInputStream> stream
                         (do_CreateInstance("@mozilla.org/io/string-input-stream;1"));
                     rv = stream->AdoptData(tmp, nSize);
                     if (NS_FAILED(rv) || !stream)
                     {
-                        NS_ASSERTION(0, "cannot create byte stream");
+                        NS_ERROR("cannot create byte stream");
                         nsMemory::Free(tmp);
                         return SetErrorInfo(E_UNEXPECTED);
                     }
 
                     postDataStream = stream;
                 }
             }
         }
@@ -411,17 +411,17 @@ public:
 
                     // Create a byte array input stream object which will own the buffer
                     headersStream = do_CreateInstance("@mozilla.org/io/string-input-stream;1");
                     if (headersStream)
                         rv = headersStream->AdoptData(tmp, nSize);
 
                     if (NS_FAILED(rv) || !headersStream)
                     {
-                        NS_ASSERTION(0, "cannot create byte stream");
+                        NS_ERROR("cannot create byte stream");
                         nsMemory::Free(tmp);
                     }
                 }
             }
         }
 
         // Use the specified target or the top level web navigation
         nsCOMPtr<nsIWebNavigation> webNavToUse;
@@ -462,17 +462,17 @@ public:
         if (Level == NULL)
             return E_INVALIDARG;
 
         // Check the requested refresh type
         OLECMDID_REFRESHFLAG iRefreshLevel = OLECMDIDF_REFRESH_NORMAL;
         CComVariant vLevelAsInt;
         if ( vLevelAsInt.ChangeType(VT_I4, Level) != S_OK )
         {
-            NS_ASSERTION(0, "Cannot change refresh type to int");
+            NS_ERROR("Cannot change refresh type to int");
             return SetErrorInfo(E_UNEXPECTED);
         }
         iRefreshLevel = (OLECMDID_REFRESHFLAG) vLevelAsInt.iVal;
 
         // Turn the IE refresh type into the nearest NG equivalent
         PRUint32 flags = nsIWebNavigation::LOAD_FLAGS_NONE;
         switch (iRefreshLevel & OLECMDIDF_REFRESH_LEVELMASK)
         {
@@ -483,17 +483,17 @@ public:
         case OLECMDIDF_REFRESH_RELOAD:
             flags = nsIWebNavigation::LOAD_FLAGS_NONE;
             break;
         case OLECMDIDF_REFRESH_COMPLETELY:
             flags = nsIWebNavigation::LOAD_FLAGS_BYPASS_CACHE | nsIWebNavigation::LOAD_FLAGS_BYPASS_PROXY;
             break;
         default:
             // No idea what refresh type this is supposed to be
-            NS_ASSERTION(0, "Unknown refresh type");
+            NS_ERROR("Unknown refresh type");
             return SetErrorInfo(E_UNEXPECTED);
         }
 
         webNav->Reload(flags);
 
         return S_OK;
     }
     virtual HRESULT STDMETHODCALLTYPE Stop(void)
--- a/embedding/components/commandhandler/src/nsCommandParams.h
+++ b/embedding/components/commandhandler/src/nsCommandParams.h
@@ -105,17 +105,17 @@ protected:
         case eStringType:
           NS_ASSERTION(inRHS.mData.mCString, "Source entry has no string");
           mData.mCString = new nsCString(*inRHS.mData.mCString);
           break;      
         case eISupportsType:
           mISupports = inRHS.mISupports.get();    // additional addref
           break;
         default:
-          NS_ASSERTION(0, "Unknown type");
+          NS_ERROR("Unknown type");
       }
     }
     
     ~HashEntry()
     {
       if (mEntryType == eWStringType)
         delete mData.mString;
       else if (mEntryType == eStringType)
@@ -129,17 +129,17 @@ protected:
         case eNoType:                                       break;
         case eBooleanType:      mData.mBoolean = PR_FALSE;  break;
         case eLongType:         mData.mLong = 0;            break;
         case eDoubleType:       mData.mDouble = 0.0;        break;
         case eWStringType:      delete mData.mString; mData.mString = nsnull;     break;
         case eISupportsType:    mISupports = nsnull;        break;    // clear the nsCOMPtr
         case eStringType:       delete mData.mCString; mData.mCString = nsnull;   break;
         default:
-          NS_ASSERTION(0, "Unknown type");
+          NS_ERROR("Unknown type");
       }
       
       mEntryType = inNewType;
     }
     
   };
 
 
--- a/extensions/reporter/jar.mn
+++ b/extensions/reporter/jar.mn
@@ -1,9 +1,9 @@
-reporter.jar:
+browser.jar:
 % content reporter %content/reporter/ xpcnativewrappers=yes
 % overlay chrome://browser/content/browser.xul         chrome://reporter/content/reporterOverlay.xul
 % overlay chrome://navigator/content/navigator.xul     chrome://reporter/content/reporterOverlay.xul
 % overlay chrome://global/content/customizeToolbar.xul chrome://reporter/content/reporterOverlay.xul
 % skin reporter classic/1.0 %skin/classic/reporter/
  content/reporter/reportWizard.xul                       (resources/content/reporter/reportWizard.xul)
  content/reporter/reportWizard.js                        (resources/content/reporter/reportWizard.js)
  content/reporter/reporterOverlay.xul                    (resources/content/reporter/reporterOverlay.xul)
--- a/gfx/cairo/cairo/src/cairo-quartz-surface.c
+++ b/gfx/cairo/cairo/src/cairo-quartz-surface.c
@@ -1033,38 +1033,29 @@ typedef enum {
     DO_TILED_IMAGE
 } cairo_quartz_action_t;
 
 static cairo_quartz_action_t
 _cairo_quartz_setup_fallback_source (cairo_quartz_surface_t *surface,
 				     const cairo_pattern_t *source)
 {
     CGRect clipBox = CGContextGetClipBoundingBox (surface->cgContext);
-    CGAffineTransform ctm;
     double x0, y0, w, h;
 
     cairo_surface_t *fallback;
     cairo_t *fallback_cr;
     CGImageRef img;
     cairo_pattern_t *source_copy;
 
     cairo_status_t status;
 
     if (clipBox.size.width == 0.0f ||
 	clipBox.size.height == 0.0f)
 	return DO_NOTHING;
 
-    // the clipBox is in userspace, so:
-    ctm = CGContextGetCTM (surface->cgContext);
-    ctm = CGAffineTransformInvert (ctm);
-    clipBox = CGRectApplyAffineTransform (clipBox, ctm);
-
-    // get the Y flip right -- the CTM will always have a Y flip in place
-    clipBox.origin.y = surface->extents.height - (clipBox.origin.y + clipBox.size.height);
-
     x0 = floor(clipBox.origin.x);
     y0 = floor(clipBox.origin.y);
     w = ceil(clipBox.origin.x + clipBox.size.width) - x0;
     h = ceil(clipBox.origin.y + clipBox.size.height) - y0;
 
     /* Create a temporary the size of the clip surface, and position
      * it so that the device origin coincides with the original surface */
     fallback = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, (int) w, (int) h);
@@ -1717,18 +1708,20 @@ static cairo_int_status_t
     action = _cairo_quartz_setup_source (surface, source);
 
     if (action == DO_SOLID || action == DO_PATTERN) {
 	CGContextFillRect (surface->cgContext, CGRectMake(surface->extents.x,
 							  surface->extents.y,
 							  surface->extents.width,
 							  surface->extents.height));
     } else if (action == DO_SHADING) {
+	CGContextSaveGState (surface->cgContext);
 	CGContextConcatCTM (surface->cgContext, surface->sourceTransform);
 	CGContextDrawShading (surface->cgContext, surface->sourceShading);
+	CGContextRestoreGState (surface->cgContext);
     } else if (action == DO_IMAGE || action == DO_TILED_IMAGE) {
 	CGContextSaveGState (surface->cgContext);
 
 	CGContextConcatCTM (surface->cgContext, surface->sourceTransform);
 	CGContextTranslateCTM (surface->cgContext, 0, surface->sourceImageRect.size.height);
 	CGContextScaleCTM (surface->cgContext, 1, -1);
 
 	if (action == DO_IMAGE)
--- a/gfx/public/nsCoord.h
+++ b/gfx/public/nsCoord.h
@@ -92,18 +92,18 @@ inline void VERIFY_COORD(nscoord aCoord)
  * Returns aCoord * aVal, capping the product to nscoord_MAX.
  *
  * Note: If/when we start using floats for nscoords, this function won't be
  * necessary.  Normal float multiplication correctly handles overflowing
  * multiplications, automatically saturating to infinity.
  */
 inline nscoord NSCoordSaturatingMultiply(nscoord aCoord, float aVal) {
   VERIFY_COORD(aCoord);
-  NS_ABORT_IF_FALSE(aVal >= 0.0f,
-                    "negative scaling factors must be handled manually");
+  NS_ASSERTION(aVal >= 0.0f,
+               "negative scaling factors must be handled manually");
 #ifdef NS_COORD_IS_FLOAT
   return floorf(aCoord * aVal);
 #else
   // This one's only a warning because it's possible to trigger
   NS_WARN_IF_FALSE(aCoord > 0
                    ? floorf(aCoord * aVal) < nscoord_MAX
                    : ceilf(aCoord * aVal) > nscoord_MIN,
                    "nscoord multiplication capped");
--- a/gfx/src/thebes/nsThebesDeviceContext.cpp
+++ b/gfx/src/thebes/nsThebesDeviceContext.cpp
@@ -1251,17 +1251,17 @@ nsThebesDeviceContext::CalcPrintingSize(
         if (DevQueryCaps(dc, CAPS_COLOR_BITCOUNT, 1, &value))
             mDepth = value;
         else
             mDepth = 8; // default to 8bpp, should be enough for printers
         break;
     }
 #endif
     default:
-        NS_ASSERTION(0, "trying to print to unknown surface type");
+        NS_ERROR("trying to print to unknown surface type");
     }
 
     if (inPoints) {
         mWidth = NSToCoordRound(float(size.width) * AppUnitsPerInch() / 72);
         mHeight = NSToCoordRound(float(size.height) * AppUnitsPerInch() / 72);
     } else {
         mWidth = NSToIntRound(size.width);
         mHeight = NSToIntRound(size.height);
@@ -1310,16 +1310,16 @@ nsThebesDeviceContext::GetPrintHDC()
 #endif
 
 #ifdef XP_OS2
             case gfxASurface::SurfaceTypeOS2:
                 return GpiQueryDevice(reinterpret_cast<gfxOS2Surface*>(mPrintingSurface.get())->GetPS());
 #endif
 
             default:
-                NS_ASSERTION(0, "invalid surface type in GetPrintHDC");
+                NS_ERROR("invalid surface type in GetPrintHDC");
                 break;
         }
     }
 
     return nsnull;
 }
 #endif
--- a/gfx/thebes/src/gfxFT2Fonts.cpp
+++ b/gfx/thebes/src/gfxFT2Fonts.cpp
@@ -703,17 +703,17 @@ gfxFT2Font::GetMetrics()
     gid = FT_Get_Char_Index(face, ' ');
     if (gid) {
         FT_Load_Glyph(face, gid, FT_LOAD_DEFAULT);
         // face->glyph->metrics.width doesn't work for spaces, use advance.x instead
         mMetrics.spaceWidth = face->glyph->advance.x >> 6;
         // save the space glyph
         mSpaceGlyph = gid;
     } else {
-        NS_ASSERTION(0, "blah");
+        NS_ERROR("blah");
     }
             
     // properties of 'x', also use its width as average width
     gid = FT_Get_Char_Index(face, 'x'); // select the glyph
     if (gid) {
         // Load glyph into glyph slot. Here, use no_scale to get font units.
         FT_Load_Glyph(face, gid, FT_LOAD_NO_SCALE);
         mMetrics.xHeight = face->glyph->metrics.height * yScale;
--- a/intl/locale/src/os2/nsCollationOS2.cpp
+++ b/intl/locale/src/os2/nsCollationOS2.cpp
@@ -78,17 +78,17 @@ nsCollationOS2::~nsCollationOS2()
 nsresult nsCollationOS2::Initialize(nsILocale *locale)
 {
   NS_ASSERTION(mCollation == NULL, "Should only be initialized once");
 
   nsresult res;
 
   mCollation = new nsCollation;
   if (mCollation == NULL) {
-    NS_ASSERTION(0, "mCollation creation failed");
+    NS_ERROR("mCollation creation failed");
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   return NS_OK;
 }
 
 
 nsresult nsCollationOS2::CompareString(PRInt32 strength, 
--- a/intl/locale/src/unix/nsCollationUnix.cpp
+++ b/intl/locale/src/unix/nsCollationUnix.cpp
@@ -86,17 +86,17 @@ nsresult nsCollationUnix::Initialize(nsI
 {
 #define kPlatformLocaleLength 64
   NS_ASSERTION(mCollation == NULL, "Should only be initialized once");
 
   nsresult res;
 
   mCollation = new nsCollation;
   if (mCollation == NULL) {
-    NS_ASSERTION(0, "mCollation creation failed");
+    NS_ERROR("mCollation creation failed");
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   // default platform locale
   mLocale.Assign('C');
 
   nsAutoString localeStr;
   NS_NAMED_LITERAL_STRING(aCategory, "NSILOCALE_COLLATE##PLATFORM");
--- a/intl/strres/src/nsStringBundleTextOverride.cpp
+++ b/intl/strres/src/nsStringBundleTextOverride.cpp
@@ -91,17 +91,17 @@ URLPropertyElement::GetValue(nsAString& 
 // setters are kind of strange, hopefully we'll never be called
 NS_IMETHODIMP
 URLPropertyElement::SetKey(const nsACString& aKey)
 {
     // this is just wrong - ideally you'd take the key, append it to
     // the url, and set that as the key. However, that would require
     // us to hold onto a copy of the string, and that's a waste,
     // considering nobody should ever be calling this.
-    NS_ASSERTION(0, "This makes no sense!");
+    NS_ERROR("This makes no sense!");
     return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 URLPropertyElement::SetValue(const nsAString& aValue)
 {
     return mRealElement->SetValue(aValue);
 }
--- a/intl/uconv/src/nsUNIXCharset.cpp
+++ b/intl/uconv/src/nsUNIXCharset.cpp
@@ -121,17 +121,17 @@ nsPlatformCharset::ConvertLocaleToCharse
     localeKey.AssignLiteral("locale.all.");
     localeKey.Append(locale);
     res = gInfo_deprecated->Get(localeKey, charset);
     if (NS_SUCCEEDED(res))  {
       LossyCopyUTF16toASCII(charset, oResult);
       return NS_OK;
     }
    }
-   NS_ASSERTION(0, "unable to convert locale to charset using deprecated config");
+   NS_ERROR("unable to convert locale to charset using deprecated config");
    mCharset.AssignLiteral("ISO-8859-1");
    oResult.AssignLiteral("ISO-8859-1");
    return NS_SUCCESS_USING_FALLBACK_LOCALE;
 }
 
 nsPlatformCharset::~nsPlatformCharset()
 {
   PR_AtomicDecrement(&gCnt);
@@ -200,17 +200,17 @@ nsPlatformCharset::GetDefaultCharsetForL
   // convert from locale to charset
   // using the deprecated locale to charset mapping 
   //
   nsAutoString localeStr(localeName);
   nsresult res = ConvertLocaleToCharsetUsingDeprecatedConfig(localeStr, oResult);
   if (NS_SUCCEEDED(res))
     return res;
 
-  NS_ASSERTION(0, "unable to convert locale to charset using deprecated config");
+  NS_ERROR("unable to convert locale to charset using deprecated config");
   oResult.AssignLiteral("ISO-8859-1");
   return NS_SUCCESS_USING_FALLBACK_LOCALE;
 }
 
 nsresult
 nsPlatformCharset::InitGetCharset(nsACString &oString)
 {
   char* nl_langinfo_codeset = nsnull;
@@ -297,17 +297,17 @@ nsPlatformCharset::InitGetCharset(nsACSt
       res = VerifyCharset(aCharset);
       if (NS_SUCCEEDED(res)) {
         oString = aCharset;
         return res;
       }
     }
   }
 
-  NS_ASSERTION(0, "unable to use nl_langinfo(CODESET)");
+  NS_ERROR("unable to use nl_langinfo(CODESET)");
 #endif
 
   //
   // try falling back on a deprecated (locale based) name
   //
   char* locale = setlocale(LC_CTYPE, nsnull);
   nsAutoString localeStr;
   localeStr.AssignWithConversion(locale);
@@ -340,17 +340,17 @@ nsPlatformCharset::Init()
 
   res = InitGetCharset(charset);
   if (NS_SUCCEEDED(res)) {
     mCharset = charset;
     return res; // succeeded
   }
 
   // last resort fallback
-  NS_ASSERTION(0, "unable to convert locale to charset using deprecated config");
+  NS_ERROR("unable to convert locale to charset using deprecated config");
   mCharset.AssignLiteral("ISO-8859-1");
   return NS_SUCCESS_USING_FALLBACK_LOCALE;
 }
 
 nsresult
 nsPlatformCharset::VerifyCharset(nsCString &aCharset)
 {
   nsresult res;
@@ -363,27 +363,27 @@ nsPlatformCharset::VerifyCharset(nsCStri
     return res;
 
   //
   // check if we can get an input converter
   //
   nsCOMPtr <nsIUnicodeEncoder> enc;
   res = charsetConverterManager->GetUnicodeEncoder(aCharset.get(), getter_AddRefs(enc));
   if (NS_FAILED(res)) {
-    NS_ASSERTION(0, "failed to create encoder");
+    NS_ERROR("failed to create encoder");
     return res;
   }
 
   //
   // check if we can get an output converter
   //
   nsCOMPtr <nsIUnicodeDecoder> dec;
   res = charsetConverterManager->GetUnicodeDecoder(aCharset.get(), getter_AddRefs(dec));
   if (NS_FAILED(res)) {
-    NS_ASSERTION(0, "failed to create decoder");
+    NS_ERROR("failed to create decoder");
     return res;
   }
 
   //
   // check if we recognize the charset string
   //
 
   nsCAutoString result;
--- a/intl/uconv/util/nsUCSupport.cpp
+++ b/intl/uconv/util/nsUCSupport.cpp
@@ -162,26 +162,26 @@ NS_IMETHODIMP nsBufferDecoderSupport::Co
     // Detect invalid input character
     if (res == NS_ERROR_ILLEGAL_INPUT && mErrBehavior == kOnError_Signal) {
       break;
     }
 
     if ((res == NS_OK_UDEC_MOREINPUT) && (bcw == 0)) {
         res = NS_ERROR_UNEXPECTED;
 #if defined(DEBUG_yokoyama) || defined(DEBUG_ftang)
-        NS_ASSERTION(0, "This should not happen. Internal buffer may be corrupted.");
+        NS_ERROR("This should not happen. Internal buffer may be corrupted.");
 #endif
         break;
     } else {
       if (bcr < buffLen) {
         // we didn't convert that residual data - unfill the buffer
         src -= mBufferLength - buffLen;
         mBufferLength = buffLen;
 #if defined(DEBUG_yokoyama) || defined(DEBUG_ftang)
-        NS_ASSERTION(0, "This should not happen. Internal buffer may be corrupted.");
+        NS_ERROR("This should not happen. Internal buffer may be corrupted.");
 #endif
       } else {
         // the buffer and some extra data was converted - unget the rest
         src -= mBufferLength - bcr;
         mBufferLength = 0;
         res = NS_OK;
       }
       break;
--- a/js/jsd/jsd_xpc.cpp
+++ b/js/jsd/jsd_xpc.cpp
@@ -432,17 +432,17 @@ jsds_FilterHook (JSDContext *jsdc, JSDTh
                                 nsACString::const_iterator start, end;
                                 url.BeginReading(start);
                                 url.EndReading(end);
                                 if (FindInReadable(currentFilter->urlPattern, start, end))
                                     return !!(flags & jsdIFilter::FLAG_PASS);
                             }
                             break;
                         default:
-                            NS_ASSERTION(0, "Invalid pattern type");
+                            NS_ERROR("Invalid pattern type");
                     }
                 }                
             }
         }
         currentFilter = reinterpret_cast<FilterRecord *>
                                         (PR_NEXT_LINK(&currentFilter->links));
     } while (currentFilter != gFilters);
 
--- a/js/src/config/milestone.txt
+++ b/js/src/config/milestone.txt
@@ -5,9 +5,9 @@
 #    x.x.x.x
 #    x.x.x+
 #
 # Referenced by milestone.pl.
 # Hopefully I'll be able to automate replacement of *all*
 # hardcoded milestones in the tree from these two files.
 #--------------------------------------------------------
 
-1.9.2a2pre
+1.9.3a1pre
--- a/js/src/configure.in
+++ b/js/src/configure.in
@@ -1942,16 +1942,19 @@ case "$target" in
         DLL_PREFIX=
         LIB_PREFIX=
         IMPORT_LIB_SUFFIX=lib
         MKSHLIB='$(LD) -NOLOGO -DLL -OUT:$@ -PDB:$(LINK_PDBFILE) $(DSO_LDOPTS)'
         MKCSHLIB='$(LD) -NOLOGO -DLL -OUT:$@ -PDB:$(LINK_PDBFILE) $(DSO_LDOPTS)'
         MKSHLIB_FORCE_ALL=
         MKSHLIB_UNFORCE_ALL=
         DSO_LDOPTS=-SUBSYSTEM:WINDOWS
+        _USE_CPP_INCLUDE_FLAG=1
+        _DEFINES_CFLAGS='-FI $(DEPTH)/js-confdefs.h -DMOZILLA_CLIENT'
+        _DEFINES_CXXFLAGS='-FI $(DEPTH)/js-confdefs.h -DMOZILLA_CLIENT'
         CFLAGS="$CFLAGS -W3 -Gy -Fd\$(COMPILE_PDBFILE)"
         CXXFLAGS="$CXXFLAGS -W3 -Gy -Fd\$(COMPILE_PDBFILE)"
         LIBS="$LIBS kernel32.lib user32.lib gdi32.lib winmm.lib wsock32.lib advapi32.lib"
         MOZ_DEBUG_FLAGS='-Zi'
         MOZ_DEBUG_LDFLAGS='-DEBUG -DEBUGTYPE:CV'
         WARNINGS_AS_ERRORS='-WX'
     	MOZ_OPTIMIZE_FLAGS='-O1'
         MOZ_JS_LIBS='$(libdir)/js$(MOZ_BITS)$(VERSION_NUMBER).lib'
@@ -4770,19 +4773,22 @@ if test "$_cpp_md_flag"; then
     _DEPEND_CFLAGS='$(filter-out %/.pp,-Wp,-MD,$(MDDEPDIR)/$(basename $(@F)).pp)'
   fi
   dnl Sun Studio on Solaris use -xM instead of -MD, see config/rules.mk
   if test "$SOLARIS_SUNPRO_CC"; then
     _DEPEND_CFLAGS=
   fi
 else
   COMPILER_DEPEND=
-  _USE_CPP_INCLUDE_FLAG=
-  _DEFINES_CFLAGS='$(ACDEFINES) -D_JS_CONFDEFS_H_ -DMOZILLA_CLIENT'
-  _DEFINES_CXXFLAGS='$(ACDEFINES) -D_JS_CONFDEFS_H_ -DMOZILLA_CLIENT'
+  dnl Don't override this for MSVC
+  if test -z "$_WIN32_MSVC"; then
+    _USE_CPP_INCLUDE_FLAG=
+    _DEFINES_CFLAGS='$(ACDEFINES) -D_JS_CONFDEFS_H_ -DMOZILLA_CLIENT'
+    _DEFINES_CXXFLAGS='$(ACDEFINES) -D_JS_CONFDEFS_H_ -DMOZILLA_CLIENT'
+  fi
 fi
 fi # MOZ_AUTO_DEPS
 MDDEPDIR='.deps'
 AC_SUBST(MOZ_AUTO_DEPS)
 AC_SUBST(COMPILER_DEPEND)
 AC_SUBST(MDDEPDIR)
 
 
--- a/js/src/xpconnect/src/XPCDispObject.cpp
+++ b/js/src/xpconnect/src/XPCDispObject.cpp
@@ -300,17 +300,17 @@ JSBool XPCDispObject::Invoke(XPCCallCont
             secFlag   = nsIXPCSecurityManager::HOOK_GET_PROPERTY;
             secAction = nsIXPCSecurityManager::ACCESS_GET_PROPERTY;
             break;
         case CALL_SETTER:
             secFlag   = nsIXPCSecurityManager::HOOK_SET_PROPERTY;
             secAction = nsIXPCSecurityManager::ACCESS_SET_PROPERTY;
             break;
         default:
-            NS_ASSERTION(0,"bad value");
+            NS_ERROR("bad value");
             return JS_FALSE;
     }
     jsval name = member->GetName();
 
     nsIXPCSecurityManager* sm = xpcc->GetAppropriateSecurityManager(secFlag);
     XPCWrappedNative* wrapper = ccx.GetWrapper();
     if(sm && NS_FAILED(sm->CanAccess(secAction, &ccx, ccx,
                                      ccx.GetFlattenedJSObject(),
--- a/js/src/xpconnect/src/xpcconvert.cpp
+++ b/js/src/xpconnect/src/xpcconvert.cpp
@@ -476,17 +476,17 @@ XPCConvert::NativeData2JS(XPCLazyCallCon
                     if(jsobj && !STOBJ_GET_PARENT(jsobj))
                         NS_ASSERTION(STOBJ_GET_CLASS(jsobj)->flags & JSCLASS_IS_GLOBAL,
                                      "Why did we recreate this wrapper?");
 #endif
                 }
                 break;
             }
         default:
-            NS_ASSERTION(0, "bad type");
+            NS_ERROR("bad type");
             return JS_FALSE;
         }
     }
     return JS_TRUE;
 }
 
 /***************************************************************************/
 
@@ -615,25 +615,25 @@ XPCConvert::JSData2Native(XPCCallContext
                 return JS_FALSE;
             }
             *((uint16*)d)  = (uint16) chars[0];
             break;
         }
     default:
         if(!type.IsPointer())
         {
-            NS_ASSERTION(0,"unsupported type");
+            NS_ERROR("unsupported type");
             return JS_FALSE;
         }
 
         switch(type.TagPart())
         {
         case nsXPTType::T_VOID:
             XPC_LOG_ERROR(("XPCConvert::JSData2Native : void* params not supported"));
-            NS_ASSERTION(0,"void* params not supported");
+            NS_ERROR("void* params not supported");
             return JS_FALSE;
         case nsXPTType::T_IID:
         {
             NS_ASSERTION(useAllocator,"trying to convert a JSID to nsID without allocator : this would leak");
 
             JSObject* obj;
             const nsID* pid=nsnull;
 
@@ -1012,17 +1012,17 @@ XPCConvert::JSData2Native(XPCCallContext
                     *pErr = NS_ERROR_XPC_BAD_CONVERT_JS_ZERO_ISNOT_NULL;
                 return JS_FALSE;
             }
 
             return JSObject2NativeInterface(ccx, (void**)d, obj, iid,
                                             nsnull, pErr);
         }
         default:
-            NS_ASSERTION(0, "bad type");
+            NS_ERROR("bad type");
             return JS_FALSE;
         }
     }
     return JS_TRUE;
 }
 
 inline JSBool
 CreateHolderIfNeeded(XPCCallContext& ccx, JSObject* obj, jsval* d,
@@ -1592,17 +1592,17 @@ XPCConvert::JSValToXPCException(XPCCallC
 
     if(!JSVAL_IS_PRIMITIVE(s))
     {
         // we have a JSObject
         JSObject* obj = JSVAL_TO_OBJECT(s);
 
         if(!obj)
         {
-            NS_ASSERTION(0, "when is an object not an object?");
+            NS_ERROR("when is an object not an object?");
             return NS_ERROR_FAILURE;
         }
 
         // is this really a native xpcom object with a wrapper?
         XPCWrappedNative* wrapper;
         if(nsnull != (wrapper =
            XPCWrappedNative::GetWrappedNativeOfJSObject(cx,obj)))
         {
@@ -1986,27 +1986,27 @@ XPCConvert::NativeArray2JS(XPCLazyCallCo
     case nsXPTType::T_U16           : POPULATE(uint16);         break;
     case nsXPTType::T_U32           : POPULATE(uint32);         break;
     case nsXPTType::T_U64           : POPULATE(uint64);         break;
     case nsXPTType::T_FLOAT         : POPULATE(float);          break;
     case nsXPTType::T_DOUBLE        : POPULATE(double);         break;
     case nsXPTType::T_BOOL          : POPULATE(PRBool);         break;
     case nsXPTType::T_CHAR          : POPULATE(char);           break;
     case nsXPTType::T_WCHAR         : POPULATE(jschar);         break;
-    case nsXPTType::T_VOID          : NS_ASSERTION(0,"bad type"); goto failure;
+    case nsXPTType::T_VOID          : NS_ERROR("bad type"); goto failure;
     case nsXPTType::T_IID           : POPULATE(nsID*);          break;
-    case nsXPTType::T_DOMSTRING     : NS_ASSERTION(0,"bad type"); goto failure;
+    case nsXPTType::T_DOMSTRING     : NS_ERROR("bad type"); goto failure;
     case nsXPTType::T_CHAR_STR      : POPULATE(char*);          break;
     case nsXPTType::T_WCHAR_STR     : POPULATE(jschar*);        break;
     case nsXPTType::T_INTERFACE     : POPULATE(nsISupports*);   break;
     case nsXPTType::T_INTERFACE_IS  : POPULATE(nsISupports*);   break;
-    case nsXPTType::T_UTF8STRING    : NS_ASSERTION(0,"bad type"); goto failure;
-    case nsXPTType::T_CSTRING       : NS_ASSERTION(0,"bad type"); goto failure;
-    case nsXPTType::T_ASTRING       : NS_ASSERTION(0,"bad type"); goto failure;
-    default                         : NS_ASSERTION(0,"bad type"); goto failure;
+    case nsXPTType::T_UTF8STRING    : NS_ERROR("bad type"); goto failure;
+    case nsXPTType::T_CSTRING       : NS_ERROR("bad type"); goto failure;
+    case nsXPTType::T_ASTRING       : NS_ERROR("bad type"); goto failure;
+    default                         : NS_ERROR("bad type"); goto failure;
     }
 
     if(pErr)
         *pErr = NS_OK;
     return JS_TRUE;
 
 failure:
     return JS_FALSE;
@@ -2119,27 +2119,27 @@ fill_array:
     case nsXPTType::T_U16           : POPULATE(na, uint16);         break;
     case nsXPTType::T_U32           : POPULATE(na, uint32);         break;
     case nsXPTType::T_U64           : POPULATE(na, uint64);         break;
     case nsXPTType::T_FLOAT         : POPULATE(na, float);          break;
     case nsXPTType::T_DOUBLE        : POPULATE(na, double);         break;
     case nsXPTType::T_BOOL          : POPULATE(na, PRBool);         break;
     case nsXPTType::T_CHAR          : POPULATE(na, char);           break;
     case nsXPTType::T_WCHAR         : POPULATE(na, jschar);         break;
-    case nsXPTType::T_VOID          : NS_ASSERTION(0,"bad type"); goto failure;
+    case nsXPTType::T_VOID          : NS_ERROR("bad type"); goto failure;
     case nsXPTType::T_IID           : POPULATE(fr, nsID*);          break;
-    case nsXPTType::T_DOMSTRING     : NS_ASSERTION(0,"bad type"); goto failure;
+    case nsXPTType::T_DOMSTRING     : NS_ERROR("bad type"); goto failure;
     case nsXPTType::T_CHAR_STR      : POPULATE(fr, char*);          break;
     case nsXPTType::T_WCHAR_STR     : POPULATE(fr, jschar*);        break;
     case nsXPTType::T_INTERFACE     : POPULATE(re, nsISupports*);   break;
     case nsXPTType::T_INTERFACE_IS  : POPULATE(re, nsISupports*);   break;
-    case nsXPTType::T_UTF8STRING    : NS_ASSERTION(0,"bad type"); goto failure;
-    case nsXPTType::T_CSTRING       : NS_ASSERTION(0,"bad type"); goto failure;
-    case nsXPTType::T_ASTRING       : NS_ASSERTION(0,"bad type"); goto failure;
-    default                         : NS_ASSERTION(0,"bad type"); goto failure;
+    case nsXPTType::T_UTF8STRING    : NS_ERROR("bad type"); goto failure;
+    case nsXPTType::T_CSTRING       : NS_ERROR("bad type"); goto failure;
+    case nsXPTType::T_ASTRING       : NS_ERROR("bad type"); goto failure;
+    default                         : NS_ERROR("bad type"); goto failure;
     }
 
     *d = array;
     if(pErr)
         *pErr = NS_OK;
     return JS_TRUE;
 
 failure:
--- a/js/src/xpconnect/src/xpcjsid.cpp
+++ b/js/src/xpconnect/src/xpcjsid.cpp
@@ -198,17 +198,17 @@ nsJSID::GetInvalidIID() const
 }
 
 //static
 nsJSID*
 nsJSID::NewID(const char* str)
 {
     if(!str)
     {
-        NS_ASSERTION(0,"no string");
+        NS_ERROR("no string");
         return nsnull;
     }
 
     nsJSID* idObj = new nsJSID();
     if(idObj)
     {
         NS_ADDREF(idObj);
         if(NS_FAILED(idObj->Initialize(str)))
@@ -699,17 +699,17 @@ nsJSCID::ResolveName()
 }
 
 //static
 nsJSCID*
 nsJSCID::NewID(const char* str)
 {
     if(!str)
     {
-        NS_ASSERTION(0,"no string");
+        NS_ERROR("no string");
         return nsnull;
     }
 
     nsJSCID* idObj = new nsJSCID();
     if(idObj)
     {
         PRBool success = PR_FALSE;
         NS_ADDREF(idObj);
--- a/js/src/xpconnect/src/xpcthreadcontext.cpp
+++ b/js/src/xpconnect/src/xpcthreadcontext.cpp
@@ -459,37 +459,37 @@ XPCPerThreadData::GetDataImpl(JSContext 
     {
         nsAutoLock lock(gLock);
         // check again now that we have the lock...
         if(gTLSIndex == BAD_TLS_INDEX)
         {
             if(PR_FAILURE ==
                PR_NewThreadPrivateIndex(&gTLSIndex, xpc_ThreadDataDtorCB))
             {
-                NS_ASSERTION(0, "PR_NewThreadPrivateIndex failed!");
+                NS_ERROR("PR_NewThreadPrivateIndex failed!");
                 gTLSIndex = BAD_TLS_INDEX;
                 return nsnull;
             }
         }
     }
 
     data = (XPCPerThreadData*) PR_GetThreadPrivate(gTLSIndex);
     if(!data)
     {
         data = new XPCPerThreadData();
         if(!data || !data->IsValid())
         {
-            NS_ASSERTION(0, "new XPCPerThreadData() failed!");
+            NS_ERROR("new XPCPerThreadData() failed!");
             if(data)
                 delete data;
             return nsnull;
         }
         if(PR_FAILURE == PR_SetThreadPrivate(gTLSIndex, data))
         {
-            NS_ASSERTION(0, "PR_SetThreadPrivate failed!");
+            NS_ERROR("PR_SetThreadPrivate failed!");
             delete data;
             return nsnull;
         }
     }
 
     if(cx && !sMainJSThread && NS_IsMainThread())
     {
         sMainJSThread = cx->thread;
--- a/js/src/xpconnect/src/xpcwrappednative.cpp
+++ b/js/src/xpconnect/src/xpcwrappednative.cpp
@@ -2284,17 +2284,17 @@ XPCWrappedNative::CallMethod(XPCCallCont
             secFlag   = nsIXPCSecurityManager::HOOK_GET_PROPERTY;
             secAction = nsIXPCSecurityManager::ACCESS_GET_PROPERTY;
             break;
         case CALL_SETTER:
             secFlag   = nsIXPCSecurityManager::HOOK_SET_PROPERTY;
             secAction = nsIXPCSecurityManager::ACCESS_SET_PROPERTY;
             break;
         default:
-            NS_ASSERTION(0,"bad value");
+            NS_ERROR("bad value");
             return JS_FALSE;
     }
 
     sm = xpcc->GetAppropriateSecurityManager(secFlag);
     if(sm && NS_FAILED(sm->CanAccess(secAction, &ccx, ccx,
                                      ccx.GetFlattenedJSObject(),
                                      ccx.GetWrapper()->GetIdentityObject(),
                                      ccx.GetWrapper()->GetClassInfo(), name,
@@ -2847,17 +2847,17 @@ done:
                     JSUint32 array_count;
 
                     const nsXPTParamInfo& paramInfo = methodInfo->GetParam(i);
                     if(!GetArraySizeFromParam(ccx, ifaceInfo, methodInfo,
                                               paramInfo, vtblIndex,
                                               i, GET_LENGTH, dispatchParams,
                                               &array_count))
                     {
-                        NS_ASSERTION(0,"failed to get array length, we'll leak here");
+                        NS_ERROR("failed to get array length, we'll leak here");
                         continue;
                     }
                     if(dp->IsValAllocated())
                     {
                         void** a = (void**)p;
                         for(JSUint32 k = 0; k < array_count; k++)
                         {
                             void* o = a[k];
@@ -3725,17 +3725,17 @@ XPCJSObjectHolder::PrintTraceName(JSTrac
 #endif
 
 // static
 XPCJSObjectHolder*
 XPCJSObjectHolder::newHolder(XPCCallContext& ccx, JSObject* obj)
 {
     if(!obj)
     {
-        NS_ASSERTION(0, "bad param");
+        NS_ERROR("bad param");
         return nsnull;
     }
     return new XPCJSObjectHolder(ccx, obj);
 }
 
 JSBool
 MorphSlimWrapper(JSContext *cx, JSObject *obj)
 {
--- a/js/src/xpconnect/src/xpcwrappednativeinfo.cpp
+++ b/js/src/xpconnect/src/xpcwrappednativeinfo.cpp
@@ -431,17 +431,17 @@ XPCNativeInterface::NewInstance(XPCCallC
             continue;
 
         if(!XPCConvert::IsMethodReflectable(*info))
             continue;
 
         str = JS_InternString(ccx, info->GetName());
         if(!str)
         {
-            NS_ASSERTION(0,"bad method name");
+            NS_ERROR("bad method name");
             failed = JS_TRUE;
             break;
         }
         name = STRING_TO_JSVAL(str);
 
         if(info->IsSetter())
         {
             NS_ASSERTION(realTotalCount,"bad setter");
@@ -475,17 +475,17 @@ XPCNativeInterface::NewInstance(XPCCallC
             {
                 failed = JS_TRUE;
                 break;
             }
 
             str = JS_InternString(ccx, constant->GetName());
             if(!str)
             {
-                NS_ASSERTION(0,"bad constant name");
+                NS_ERROR("bad constant name");
                 failed = JS_TRUE;
                 break;
             }
             name = STRING_TO_JSVAL(str);
 
             // XXX need better way to find dups
             //NS_ASSERTION(!LookupMemberByID(name),"duplicate method/constant name");
 
--- a/js/src/xpconnect/tests/TestXPC.cpp
+++ b/js/src/xpconnect/tests/TestXPC.cpp
@@ -234,17 +234,17 @@ MySecMan::CanCreateWrapper(JSContext * a
         case OK_ALL:
             return NS_OK;
         case VETO_ALL:
             JS_SetPendingException(aJSContext,
                 STRING_TO_JSVAL(JS_NewStringCopyZ(aJSContext,
                     "security exception")));
             return NS_ERROR_FAILURE;
         default:
-            NS_ASSERTION(0,"bad case");
+            NS_ERROR("bad case");
             return NS_OK;
     }
 }
 
 NS_IMETHODIMP
 MySecMan::CanCreateInstance(JSContext * aJSContext, const nsCID & aCID)
 {
     switch(mMode)
@@ -252,17 +252,17 @@ MySecMan::CanCreateInstance(JSContext * 
         case OK_ALL:
             return NS_OK;
         case VETO_ALL:
             JS_SetPendingException(aJSContext,
                 STRING_TO_JSVAL(JS_NewStringCopyZ(aJSContext,
                     "security exception")));
             return NS_ERROR_FAILURE;
         default:
-            NS_ASSERTION(0,"bad case");
+            NS_ERROR("bad case");
             return NS_OK;
     }
 }
 
 NS_IMETHODIMP
 MySecMan::CanGetService(JSContext * aJSContext, const nsCID & aCID)
 {
     switch(mMode)
@@ -270,17 +270,17 @@ MySecMan::CanGetService(JSContext * aJSC
         case OK_ALL:
             return NS_OK;
         case VETO_ALL:
             JS_SetPendingException(aJSContext,
                 STRING_TO_JSVAL(JS_NewStringCopyZ(aJSContext,
                     "security exception")));
             return NS_ERROR_FAILURE;
         default:
-            NS_ASSERTION(0,"bad case");
+            NS_ERROR("bad case");
             return NS_OK;
     }
 }
 
 /* void CanAccess (in PRUint32 aAction, in nsIXPCNativeCallContext aCallContext, in JSContextPtr aJSContext, in JSObjectPtr aJSObject, in nsISupports aObj, in nsIClassInfo aClassInfo, in JSVal aName, inout voidPtr aPolicy); */
 NS_IMETHODIMP 
 MySecMan::CanAccess(PRUint32 aAction, nsAXPCNativeCallContext *aCallContext, JSContext * aJSContext, JSObject * aJSObject, nsISupports *aObj, nsIClassInfo *aClassInfo, jsval aName, void * *aPolicy)
 {
@@ -289,17 +289,17 @@ MySecMan::CanAccess(PRUint32 aAction, ns
         case OK_ALL:
             return NS_OK;
         case VETO_ALL:
             JS_SetPendingException(aJSContext,
                 STRING_TO_JSVAL(JS_NewStringCopyZ(aJSContext,
                     "security exception")));
             return NS_ERROR_FAILURE;
         default:
-            NS_ASSERTION(0,"bad case");
+            NS_ERROR("bad case");
             return NS_OK;
     }
 }
 
 /**********************************************/
 static void
 EvaluateScript(JSContext* jscontext, JSObject* glob, MySecMan* sm, MySecMan::Mode mode, const char* msg, const char* t, jsval &rval)
 {
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -803,16 +803,18 @@ public:
   // together.
   PRPackedBool              mFixedPosIsAbsPos;
 
   // A boolean to indicate whether we have a "pending" popupgroup.  That is, we
   // have already created the FrameConstructionItem for the root popupgroup but
   // we have not yet created the relevant frame.
   PRPackedBool              mHavePendingPopupgroup;
 
+  nsCOMArray<nsIContent>    mGeneratedTextNodesWithInitializer;
+
   // Constructor
   // Use the passed-in history state.
   nsFrameConstructorState(nsIPresShell*          aPresShell,
                           nsIFrame*              aFixedContainingBlock,
                           nsIFrame*              aAbsoluteContainingBlock,
                           nsIFrame*              aFloatContainingBlock,
                           nsILayoutHistoryState* aHistoryState);
   // Get the history state from the pres context's pres shell.
@@ -978,16 +980,20 @@ nsFrameConstructorState::~nsFrameConstru
   // items whose containing block is outside the abs-pos frames. 
   MOZ_COUNT_DTOR(nsFrameConstructorState);
   ProcessFrameInsertions(mFloatedItems, nsGkAtoms::floatList);
   ProcessFrameInsertions(mAbsoluteItems, nsGkAtoms::absoluteList);
   ProcessFrameInsertions(mFixedItems, nsGkAtoms::fixedList);
 #ifdef MOZ_XUL
   ProcessFrameInsertions(mPopupItems, nsGkAtoms::popupList);
 #endif
+  for (PRInt32 i = mGeneratedTextNodesWithInitializer.Count() - 1; i >= 0; --i) {
+    mGeneratedTextNodesWithInitializer[i]->
+      DeleteProperty(nsGkAtoms::genConInitializerProperty);
+  }
 }
 
 static nsIFrame*
 AdjustAbsoluteContainingBlock(nsIFrame* aContainingBlockIn)
 {
   if (!aContainingBlockIn) {
     return nsnull;
   }
@@ -1638,17 +1644,18 @@ DestroyGenConInitializer(void*    aFrame
                          nsIAtom* aPropertyName,
                          void*    aPropertyValue,
                          void*    aDtorData)
 {
   delete static_cast<nsGenConInitializer*>(aPropertyValue);
 }
 
 already_AddRefed<nsIContent>
-nsCSSFrameConstructor::CreateGenConTextNode(const nsString& aString,
+nsCSSFrameConstructor::CreateGenConTextNode(nsFrameConstructorState& aState,
+                                            const nsString& aString,
                                             nsCOMPtr<nsIDOMCharacterData>* aText,
                                             nsGenConInitializer* aInitializer)
 {
   nsCOMPtr<nsIContent> content;
   NS_NewTextNode(getter_AddRefs(content), mDocument->NodeInfoManager());
   if (!content) {
     // XXX The quotes/counters code doesn't like the text pointer
     // being null in case of dynamic changes!
@@ -1657,22 +1664,24 @@ nsCSSFrameConstructor::CreateGenConTextN
   }
   content->SetText(aString, PR_FALSE);
   if (aText) {
     *aText = do_QueryInterface(content);
   }
   if (aInitializer) {
     content->SetProperty(nsGkAtoms::genConInitializerProperty, aInitializer,
                          DestroyGenConInitializer);
+    aState.mGeneratedTextNodesWithInitializer.AppendObject(content);
   }
   return content.forget();
 }
 
 already_AddRefed<nsIContent>
-nsCSSFrameConstructor::CreateGeneratedContent(nsIContent*     aParentContent,
+nsCSSFrameConstructor::CreateGeneratedContent(nsFrameConstructorState& aState,
+                                              nsIContent*     aParentContent,
                                               nsStyleContext* aStyleContext,
                                               PRUint32        aContentIndex)
 {
   // Get the content value
   const nsStyleContentData &data =
     aStyleContext->GetStyleContent()->ContentAt(aContentIndex);
   nsStyleContentType type = data.mType;
 
@@ -1693,18 +1702,19 @@ nsCSSFrameConstructor::CreateGeneratedCo
     nsCOMPtr<nsIContent> content;
     NS_NewGenConImageContent(getter_AddRefs(content), nodeInfo,
                              data.mContent.mImage);
     return content.forget();
   }
 
   switch (type) {
   case eStyleContentType_String:
-    return CreateGenConTextNode(nsDependentString(data.mContent.mString), nsnull,
-                                nsnull);
+    return CreateGenConTextNode(aState,
+                                nsDependentString(data.mContent.mString),
+                                nsnull, nsnull);
 
   case eStyleContentType_Attr:
     {
       nsCOMPtr<nsIAtom> attrName;
       PRInt32 attrNameSpace = kNameSpaceID_None;
       nsAutoString contentString(data.mContent.mString);
       PRInt32 barIndex = contentString.FindChar('|'); // CSS namespace delimiter
       if (-1 != barIndex) {
@@ -1744,17 +1754,18 @@ nsCSSFrameConstructor::CreateGeneratedCo
         new nsCounterUseNode(counters, aContentIndex,
                              type == eStyleContentType_Counters);
       if (!node)
         return nsnull;
 
       nsGenConInitializer* initializer =
         new nsGenConInitializer(node, counterList,
                                 &nsCSSFrameConstructor::CountersDirty);
-      return CreateGenConTextNode(EmptyString(), &node->mText, initializer);
+      return CreateGenConTextNode(aState, EmptyString(), &node->mText,
+                                  initializer);
     }
 
   case eStyleContentType_Image:
     NS_NOTREACHED("handled by if above");
     return nsnull;
 
   case eStyleContentType_OpenQuote:
   case eStyleContentType_CloseQuote:
@@ -1764,17 +1775,18 @@ nsCSSFrameConstructor::CreateGeneratedCo
       nsQuoteNode* node =
         new nsQuoteNode(type, aContentIndex);
       if (!node)
         return nsnull;
 
       nsGenConInitializer* initializer =
         new nsGenConInitializer(node, &mQuoteList,
                                 &nsCSSFrameConstructor::QuotesDirty);
-      return CreateGenConTextNode(EmptyString(), &node->mText, initializer);
+      return CreateGenConTextNode(aState, EmptyString(), &node->mText,
+                                  initializer);
     }
   
   case eStyleContentType_AltContent:
     {
       // Use the "alt" attribute; if that fails and the node is an HTML
       // <input>, try the value attribute and then fall back to some default
       // localized text we have.
       // XXX what if the 'alt' attribute is added later, how will we
@@ -1793,17 +1805,17 @@ nsCSSFrameConstructor::CreateGeneratedCo
           NS_NewAttributeContent(mDocument->NodeInfoManager(),
                                  kNameSpaceID_None, nsGkAtoms::value, getter_AddRefs(content));
           return content.forget();
         }
 
         nsXPIDLString temp;
         nsContentUtils::GetLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
                                            "Submit", temp);
-        return CreateGenConTextNode(temp, nsnull, nsnull);
+        return CreateGenConTextNode(aState, temp, nsnull, nsnull);
       }
 
       break;
     }
   } // switch
 
   return nsnull;
 }
@@ -1861,17 +1873,18 @@ nsCSSFrameConstructor::CreateGeneratedCo
   if (NS_FAILED(rv)) {
     container->UnbindFromTree();
     return;
   }
 
   PRUint32 contentCount = pseudoStyleContext->GetStyleContent()->ContentCount();
   for (PRUint32 contentIndex = 0; contentIndex < contentCount; contentIndex++) {
     nsCOMPtr<nsIContent> content =
-      CreateGeneratedContent(aParentContent, pseudoStyleContext, contentIndex);
+      CreateGeneratedContent(aState, aParentContent, pseudoStyleContext,
+                             contentIndex);
     if (content) {
       container->AppendChildTo(content, PR_FALSE);
     }
   }
 
   AddFrameConstructionItemsInternal(aState, container, aParentFrame, elemName,
                                     kNameSpaceID_None, -1, pseudoStyleContext,
                                     ITEM_IS_GENERATED_CONTENT, aItems);
@@ -2683,16 +2696,18 @@ nsCSSFrameConstructor::ConstructRootFram
 
   // Bind the viewport frame to the root view
   nsIView*        rootView;
   mPresShell->GetViewManager()->GetRootView(rootView);
   viewportFrame->SetView(rootView);
 
   nsContainerFrame::SyncFrameViewProperties(mPresShell->GetPresContext(), viewportFrame,
                                             viewportPseudoStyle, rootView);
+  nsContainerFrame::SyncWindowProperties(mPresShell->GetPresContext(), viewportFrame,
+                                         rootView);
 
   // The viewport is the containing block for 'fixed' elements
   mFixedContainingBlock = viewportFrame;
 
   *aNewFrame = viewportFrame;
   return NS_OK;
 }
 
@@ -6211,26 +6226,27 @@ nsCSSFrameConstructor::ContentAppended(n
       // Now comes the fun part.  For each appended child, make a
       // ContentInserted call as if it had just gotten inserted at the index
       // it's at in aContainer and let ContentInserted handle the mess.  If our
       // insertion point is non-XBL that's the correct index, and otherwise
       // ContentInserted will ignore the passed-in index.
       PRUint32 containerCount = aContainer->GetChildCount();
       for (PRUint32 i = aNewIndexInContainer; i < containerCount; i++) {
         nsIContent* content = aContainer->GetChildAt(i);
-        if (mPresShell->GetPrimaryFrameFor(content)
+        if ((mPresShell->GetPrimaryFrameFor(content) ||
+             mPresShell->FrameManager()->GetUndisplayedContent(content))
 #ifdef MOZ_XUL
             //  Except listboxes suck, so do NOT skip anything here if
             //  we plan to notify a listbox.
             && !MaybeGetListBoxBodyFrame(aContainer, content)
 #endif
             ) {
-          // Already have a frame for this content; a previous ContentInserted
-          // in this loop must have reconstructed its insertion parent.  Skip
-          // it.
+          // Already have a frame or undisplayed entry for this content; a
+          // previous ContentInserted in this loop must have reconstructed
+          // its insertion parent.  Skip it.
           continue;
         }
         LAYOUT_PHASE_TEMP_EXIT();
         // Call ContentInserted with this index.
         ContentInserted(aContainer, content, i, mTempFrameTreeState);
         LAYOUT_PHASE_TEMP_REENTER();
       }
 
@@ -6474,18 +6490,18 @@ PRBool NotifyListBoxBody(nsPresContext* 
 {
   nsListBoxBodyFrame* listBoxBodyFrame =
     MaybeGetListBoxBodyFrame(aContainer, aChild);
   if (listBoxBodyFrame) {
     if (aOperation == CONTENT_REMOVED) {
       // Except if we have an aChildFrame and its parent is not the right
       // thing, then we don't do this.  Pseudo frames are so much fun....
       if (!aChildFrame || aChildFrame->GetParent() == listBoxBodyFrame) {
-        listBoxBodyFrame->OnContentRemoved(aPresContext, aChildFrame,
-                                           aIndexInContainer);
+        listBoxBodyFrame->OnContentRemoved(aPresContext, aContainer,
+                                           aChildFrame, aIndexInContainer);
         return PR_TRUE;
       }
     } else {
       // If this codepath ever starts using aIndexInContainer, need to
       // change ContentInserted to pass in something resembling a correct
       // one in the XBL cases.
       listBoxBodyFrame->OnContentInserted(aPresContext, aChild);
       return PR_TRUE;
@@ -11236,17 +11252,17 @@ nsCSSFrameConstructor::ReframeContaining
 
   // XXXbz how exactly would we get here while isReflowing anyway?  Should this
   // whole test be ifdef DEBUG?
   PRBool isReflowing;
   mPresShell->IsReflowLocked(&isReflowing);
   if(isReflowing) {
     // don't ReframeContainingBlock, this will result in a crash
     // if we remove a tree that's in reflow - see bug 121368 for testcase
-    NS_ASSERTION(0, "Atemptted to nsCSSFrameConstructor::ReframeContainingBlock during a Reflow!!!");
+    NS_ERROR("Atemptted to nsCSSFrameConstructor::ReframeContainingBlock during a Reflow!!!");
     return NS_OK;
   }
 
   // Get the first "normal" ancestor of the target frame.
   nsIFrame* containingBlock = GetIBContainingBlockFor(aFrame);
   if (containingBlock) {
     // From here we look for the containing block in case the target
     // frame is already a block (which can happen when an inline frame
--- a/layout/base/nsCSSFrameConstructor.h
+++ b/layout/base/nsCSSFrameConstructor.h
@@ -458,30 +458,32 @@ private:
                                   nsCOMArray<nsIContent>& aGeneratedContent,
                                   nsIContent** aNewContent,
                                   nsIFrame** aNewFrame);
 
   /**
    * Create a text node containing the given string. If aText is non-null
    * then we also set aText to the returned node.
    */
-  already_AddRefed<nsIContent> CreateGenConTextNode(const nsString& aString,  
+  already_AddRefed<nsIContent> CreateGenConTextNode(nsFrameConstructorState& aState,
+                                                    const nsString& aString,
                                                     nsCOMPtr<nsIDOMCharacterData>* aText,
                                                     nsGenConInitializer* aInitializer);
 
   /**
    * Create a content node for the given generated content style.
    * The caller takes care of making it SetNativeAnonymous, binding it
    * to the document, and creating frames for it.
    * @param aParentContent is the node that has the before/after style
    * @param aStyleContext is the 'before' or 'after' pseudo-element
    * style context
    * @param aContentIndex is the index of the content item to create
    */
-  already_AddRefed<nsIContent> CreateGeneratedContent(nsIContent*     aParentContent,
+  already_AddRefed<nsIContent> CreateGeneratedContent(nsFrameConstructorState& aState,
+                                                      nsIContent*     aParentContent,
                                                       nsStyleContext* aStyleContext,
                                                       PRUint32        aContentIndex);
 
   // aFrame may be null; this method doesn't use it directly in any case.
   void CreateGeneratedContentItem(nsFrameConstructorState& aState,
                                   nsIFrame*                aFrame,
                                   nsIContent*              aContent,
                                   nsStyleContext*          aStyleContext,
--- a/layout/base/nsCSSRendering.cpp
+++ b/layout/base/nsCSSRendering.cpp
@@ -1976,20 +1976,16 @@ PaintBackgroundLayer(nsPresContext* aPre
   //
   // relative to aBorderArea.TopLeft() (which is where the top-left
   // of aForFrame's border-box will be rendered)
   nsPoint imageTopLeft, anchor, offset;
   if (NS_STYLE_BG_ATTACHMENT_FIXED == aLayer.mAttachment) {
     // If it's a fixed background attachment, then the image is placed
     // relative to the viewport, which is the area of the root frame
     // in a screen context or the page content frame in a print context.
-
-    // Remember that we've drawn position-varying content in this prescontext
-    aPresContext->SetRenderedPositionVaryingContent();
-
     nsIFrame* topFrame =
       aPresContext->PresShell()->FrameManager()->GetRootFrame();
     NS_ASSERTION(topFrame, "no root frame");
     nsIFrame* pageContentFrame = nsnull;
     if (aPresContext->IsPaginated()) {
       pageContentFrame =
         nsLayoutUtils::GetClosestFrameOfType(aForFrame, nsGkAtoms::pageContentFrame);
       if (pageContentFrame) {
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -60,16 +60,17 @@
 
 #include "imgIContainer.h"
 #include "nsIInterfaceRequestorUtils.h"
 
 nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
     PRBool aIsForEvents, PRBool aBuildCaret)
     : mReferenceFrame(aReferenceFrame),
       mMovingFrame(nsnull),
+      mSaveVisibleRegionOfMovingContent(nsnull),
       mIgnoreScrollFrame(nsnull),
       mCurrentTableItem(nsnull),
       mBuildCaret(aBuildCaret),
       mEventDelivery(aIsForEvents),
       mIsAtRootOfPseudoStackingContext(PR_FALSE),
       mPaintAllFrames(PR_FALSE),
       mAccurateVisibleRegions(PR_FALSE),
       mInTransform(PR_FALSE) {
@@ -150,16 +151,26 @@ nsDisplayListBuilder::~nsDisplayListBuil
   NS_ASSERTION(mPresShellStates.Length() == 0,
                "All presshells should have been exited");
   NS_ASSERTION(!mCurrentTableItem, "No table item should be active");
 
   PL_FreeArenaPool(&mPool);
   PL_FinishArenaPool(&mPool);
 }
 
+void
+nsDisplayListBuilder::SubtractFromVisibleRegion(nsRegion* aVisibleRegion,
+                                                const nsRegion& aRegion)
+{
+  aVisibleRegion->Sub(*aVisibleRegion, aRegion);
+  if (!GetAccurateVisibleRegions()) {
+    aVisibleRegion->SimplifyOutward(15);
+  }
+}
+
 PRBool
 nsDisplayListBuilder::IsMovingFrame(nsIFrame* aFrame)
 {
   return mMovingFrame &&
      nsLayoutUtils::IsAncestorFrameCrossDoc(mMovingFrame, aFrame, mReferenceFrame);
 }
 
 nsCaret *
@@ -231,16 +242,36 @@ nsDisplayListBuilder::MarkFramesForDispl
 
 void*
 nsDisplayListBuilder::Allocate(size_t aSize) {
   void *tmp;
   PL_ARENA_ALLOCATE(tmp, &mPool, aSize);
   return tmp;
 }
 
+void
+nsDisplayListBuilder::AccumulateVisibleRegionOfMovingContent(const nsRegion& aMovingContent,
+                                                             const nsRegion& aVisibleRegion)
+{
+  if (!mSaveVisibleRegionOfMovingContent)
+    return;
+
+  // Grab the union of aMovingContent (after the move) with
+  // aMovingContent - mMoveDelta (before the move)
+  nsRegion r = aMovingContent;
+  r.MoveBy(-mMoveDelta);
+  r.Or(r, aMovingContent);
+  // Reduce to the part that's visible after the move
+  r.And(r, aVisibleRegion);
+  // Accumulate it into our result
+  mSaveVisibleRegionOfMovingContent->Or(
+      *mSaveVisibleRegionOfMovingContent, r);
+  mSaveVisibleRegionOfMovingContent->SimplifyOutward(15);
+}
+
 void nsDisplayListSet::MoveTo(const nsDisplayListSet& aDestination) const
 {
   aDestination.BorderBackground()->AppendToTop(BorderBackground());
   aDestination.BlockBorderBackgrounds()->AppendToTop(BlockBorderBackgrounds());
   aDestination.Floats()->AppendToTop(Floats());
   aDestination.Content()->AppendToTop(Content());
   aDestination.PositionedDescendants()->AppendToTop(PositionedDescendants());
   aDestination.Outlines()->AppendToTop(Outlines());
@@ -261,21 +292,17 @@ nsDisplayItem::OptimizeVisibility(nsDisp
     nsRect opaqueArea = bounds;
     if (aBuilder->IsMovingFrame(f)) {
       // The display list should include items for both the before and after
       // states (see nsLayoutUtils::ComputeRepaintRegionForCopy. So the
       // only area we want to cover is the area that was opaque in the
       // before state and in the after state.
       opaqueArea.IntersectRect(bounds - aBuilder->GetMoveDelta(), bounds);
     }
-    if (aBuilder->GetAccurateVisibleRegions()) {
-      aVisibleRegion->Sub(*aVisibleRegion, opaqueArea);
-    } else {
-      aVisibleRegion->SimpleSubtract(opaqueArea);
-    }
+    aBuilder->SubtractFromVisibleRegion(aVisibleRegion, nsRegion(opaqueArea));
   }
 
   return PR_TRUE;
 }
 
 void
 nsDisplayList::FlattenTo(nsTArray<nsDisplayItem*>* aElements) {
   nsDisplayItem* item;
@@ -299,32 +326,51 @@ nsDisplayList::GetBounds(nsDisplayListBu
 }
 
 void
 nsDisplayList::OptimizeVisibility(nsDisplayListBuilder* aBuilder,
                                   nsRegion* aVisibleRegion) {
   nsAutoTArray<nsDisplayItem*, 512> elements;
   FlattenTo(&elements);
 
+  // Accumulate the bounds of all moving content we find in this list
+  nsRect movingContentAccumulatedBounds;
+  // Store an overapproximation of the visible region for the moving
+  // content in this list
+  nsRegion movingContentVisibleRegion;
+
   for (PRInt32 i = elements.Length() - 1; i >= 0; --i) {
     nsDisplayItem* item = elements[i];
     nsDisplayItem* belowItem = i < 1 ? nsnull : elements[i - 1];
 
     if (belowItem && item->TryMerge(aBuilder, belowItem)) {
       belowItem->~nsDisplayItem();
       elements.ReplaceElementsAt(i - 1, 1, item);
       continue;
     }
-    
+
+    nsIFrame* f = item->GetUnderlyingFrame();
+    if (f && aBuilder->IsMovingFrame(f)) {
+      if (movingContentAccumulatedBounds.IsEmpty()) {
+        // *aVisibleRegion can only shrink during this loop, so storing
+        // the first one we see is a sound overapproximation
+        movingContentVisibleRegion = *aVisibleRegion;
+      }
+      movingContentAccumulatedBounds.UnionRect(movingContentAccumulatedBounds,
+                                               item->GetBounds(aBuilder));
+    }
     if (item->OptimizeVisibility(aBuilder, aVisibleRegion)) {
       AppendToBottom(item);
     } else {
       item->~nsDisplayItem();
     }
   }
+
+  aBuilder->AccumulateVisibleRegionOfMovingContent(
+      nsRegion(movingContentAccumulatedBounds), movingContentVisibleRegion);
 }
 
 void nsDisplayList::Paint(nsDisplayListBuilder* aBuilder, nsIRenderingContext* aCtx,
                           const nsRect& aDirtyRect) const {
   for (nsDisplayItem* i = GetBottom(); i != nsnull; i = i->GetAbove()) {
     i->Paint(aBuilder, aCtx, aDirtyRect);
   }
   nsCSSRendering::DidPaint();
@@ -830,17 +876,17 @@ PRBool nsDisplayWrapList::IsVaryingRelat
 void nsDisplayWrapList::Paint(nsDisplayListBuilder* aBuilder,
      nsIRenderingContext* aCtx, const nsRect& aDirtyRect) {
   mList.Paint(aBuilder, aCtx, aDirtyRect);
 }
 
 static nsresult
 WrapDisplayList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
                 nsDisplayList* aList, nsDisplayWrapper* aWrapper) {
-  if (!aList->GetTop())
+  if (!aList->GetTop() && !aBuilder->HasMovingFrames())
     return NS_OK;
   nsDisplayItem* item = aWrapper->WrapList(aBuilder, aFrame, aList);
   if (!item)
     return NS_ERROR_OUT_OF_MEMORY;
   // aList was emptied
   aList->AppendToTop(item);
   return NS_OK;
 }
@@ -1019,25 +1065,35 @@ void nsDisplayClip::Paint(nsDisplayListB
   nsDisplayWrapList::Paint(aBuilder, aCtx, dirty);
   aCtx->PopState();
 }
 
 PRBool nsDisplayClip::OptimizeVisibility(nsDisplayListBuilder* aBuilder,
                                          nsRegion* aVisibleRegion) {
   nsRegion clipped;
   clipped.And(*aVisibleRegion, mClip);
+
+  if (aBuilder->HasMovingFrames() &&
+      !aBuilder->IsMovingFrame(mClippingFrame)) {
+    // There may be some clipped moving children that were visible before
+    // but are clipped out now. Conservatively assume they were there
+    // and add their possible area to the visible region of moving
+    // content.
+    // Compute the after-move region of moving content that could have been
+    // totally clipped out.
+    nsRegion r;
+    r.Sub(mClip + aBuilder->GetMoveDelta(), mClip);
+    aBuilder->AccumulateVisibleRegionOfMovingContent(r, *aVisibleRegion);
+  }
+
   nsRegion rNew(clipped);
   PRBool anyVisible = nsDisplayWrapList::OptimizeVisibility(aBuilder, &rNew);
   nsRegion subtracted;
   subtracted.Sub(clipped, rNew);
-  if (aBuilder->GetAccurateVisibleRegions()) {
-    aVisibleRegion->Sub(*aVisibleRegion, subtracted);
-  } else {
-    aVisibleRegion->SimpleSubtract(subtracted);
-  }
+  aBuilder->SubtractFromVisibleRegion(aVisibleRegion, subtracted);
   return anyVisible;
 }
 
 PRBool nsDisplayClip::TryMerge(nsDisplayListBuilder* aBuilder,
                                nsDisplayItem* aItem) {
   if (aItem->GetType() != TYPE_CLIP)
     return PR_FALSE;
   nsDisplayClip* other = static_cast<nsDisplayClip*>(aItem);
--- a/layout/base/nsDisplayList.h
+++ b/layout/base/nsDisplayList.h
@@ -56,16 +56,17 @@
 #include <stdlib.h>
 
 class nsIPresShell;
 class nsIContent;
 class nsRegion;
 class nsIRenderingContext;
 class nsIDeviceContext;
 class nsDisplayTableItem;
+class nsDisplayItem;
 
 /*
  * An nsIFrame can have many different visual parts. For example an image frame
  * can have a background, border, and outline, the image itself, and a
  * translucent selection overlay. In general these parts can be drawn at
  * discontiguous z-levels; see CSS2.1 appendix E:
  * http://www.w3.org/TR/CSS21/zindex.html
  * 
@@ -155,36 +156,49 @@ public:
 
   /**
    * Indicate that we'll use this display list to analyze the effects
    * of aMovingFrame moving by aMoveDelta. The move has already been
    * applied to the frame tree. Moving frames are not allowed to clip or
    * cover (during OptimizeVisibility) non-moving frames. E.g. when we're
    * constructing a display list to see what should be repainted during a
    * scroll operation, we specify the scrolled frame as the moving frame.
+   * @param aSaveVisibleRegionOfMovingContent if non-null,
+   *   this receives a bounding region for the visible moving content
+   * (considering the moving content both before and after the move)
    */
-  void SetMovingFrame(nsIFrame* aMovingFrame, const nsPoint& aMoveDelta) {
+  void SetMovingFrame(nsIFrame* aMovingFrame, const nsPoint& aMoveDelta,
+                      nsRegion* aSaveVisibleRegionOfMovingContent) {
     mMovingFrame = aMovingFrame;
     mMoveDelta = aMoveDelta;
+    mSaveVisibleRegionOfMovingContent = aSaveVisibleRegionOfMovingContent;
   }
 
   /**
    * @return PR_TRUE if we are doing analysis of moving frames
    */
   PRBool HasMovingFrames() { return mMovingFrame != nsnull; }
   /**
    * @return the frame that was moved
    */
   nsIFrame* GetRootMovingFrame() { return mMovingFrame; }
   /**
    * @return the amount by which mMovingFrame was moved.
    * Only valid when GetRootMovingFrame() returns non-null.
    */
   const nsPoint& GetMoveDelta() { return mMoveDelta; }
   /**
+   * Given the bounds of some moving content, and a visible region,
+   * intersect the bounds with the visible region and add it to the
+   * recorded region of visible moving content.
+   */
+  void AccumulateVisibleRegionOfMovingContent(const nsRegion& aMovingContent,
+                                              const nsRegion& aVisibleRegion);
+
+  /**
    * @return PR_TRUE if aFrame is, or is a descendant of, the hypothetical
    * moving frame
    */
   PRBool IsMovingFrame(nsIFrame* aFrame);
   /**
    * @return the selection that painting should be restricted to (or nsnull
    * in the normal unrestricted case)
    */
@@ -272,16 +286,25 @@ public:
   PRBool IsInTransform() { return mInTransform; }
   /**
    * Indicate whether or not we're directly or indirectly under and
    * nsDisplayTransform or SVG foreignObject.
    */
   void SetInTransform(PRBool aInTransform) { mInTransform = aInTransform; }
 
   /**
+   * Subtracts aRegion from *aVisibleRegion. We avoid letting
+   * aVisibleRegion become overcomplex by simplifying it if necessary ---
+   * unless mAccurateVisibleRegions is set, in which case we let it
+   * get arbitrarily complex.
+   */
+  void SubtractFromVisibleRegion(nsRegion* aVisibleRegion,
+                                 const nsRegion& aRegion);
+
+  /**
    * Mark the frames in aFrames to be displayed if they intersect aDirtyRect
    * (which is relative to aDirtyFrame). If the frames have placeholders
    * that might not be displayed, we mark the placeholders and their ancestors
    * to ensure that display list construction descends into them
    * anyway. nsDisplayListBuilder will take care of unmarking them when it is
    * destroyed.
    */
   void MarkFramesForDisplayList(nsIFrame* aDirtyFrame,
@@ -351,16 +374,17 @@ private:
   PresShellState* CurrentPresShellState() {
     NS_ASSERTION(mPresShellStates.Length() > 0,
                  "Someone forgot to enter a presshell");
     return &mPresShellStates[mPresShellStates.Length() - 1];
   }
   
   nsIFrame*                      mReferenceFrame;
   nsIFrame*                      mMovingFrame;
+  nsRegion*                      mSaveVisibleRegionOfMovingContent;
   nsIFrame*                      mIgnoreScrollFrame;
   nsPoint                        mMoveDelta; // only valid when mMovingFrame is non-null
   PLArenaPool                    mPool;
   nsCOMPtr<nsISelection>         mBoundingSelection;
   nsAutoTArray<PresShellState,8> mPresShellStates;
   nsAutoTArray<nsIFrame*,100>    mFramesMarkedForDisplay;
   nsDisplayTableItem*            mCurrentTableItem;
   PRPackedBool                   mBuildCaret;
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -643,16 +643,17 @@ nsLayoutUtils::GetDOMEventCoordinatesRel
 
 nsPoint
 nsLayoutUtils::GetEventCoordinatesRelativeTo(const nsEvent* aEvent, nsIFrame* aFrame)
 {
   if (!aEvent || (aEvent->eventStructType != NS_MOUSE_EVENT && 
                   aEvent->eventStructType != NS_MOUSE_SCROLL_EVENT &&
                   aEvent->eventStructType != NS_DRAG_EVENT &&
                   aEvent->eventStructType != NS_SIMPLE_GESTURE_EVENT &&
+                  aEvent->eventStructType != NS_GESTURENOTIFY_EVENT &&
                   aEvent->eventStructType != NS_QUERY_CONTENT_EVENT))
     return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
 
   const nsGUIEvent* GUIEvent = static_cast<const nsGUIEvent*>(aEvent);
   if (!GUIEvent->widget)
     return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
 
   /* If we walk up the frame tree and discover that any of the frames are
@@ -1129,39 +1130,39 @@ nsLayoutUtils::PaintFrame(nsIRenderingCo
   
   list.Paint(&builder, aRenderingContext, aDirtyRegion.GetBounds());
   // Flush the list so we don't trigger the IsEmpty-on-destruction assertion
   list.DeleteAll();
   return NS_OK;
 }
 
 static void
-AccumulateItemInRegion(nsRegion* aRegion, const nsRect& aAreaRect,
+AccumulateItemInRegion(nsRegion* aRegion, const nsRect& aUpdateRect,
                        const nsRect& aItemRect, const nsRect& aExclude,
                        nsDisplayItem* aItem)
 {
   nsRect damageRect;
-  if (damageRect.IntersectRect(aAreaRect, aItemRect)) {
+  if (damageRect.IntersectRect(aUpdateRect, aItemRect)) {
     nsRegion r;
     r.Sub(damageRect, aExclude);
 #ifdef DEBUG
     if (gDumpRepaintRegionForCopy) {
       nsRect bounds = r.GetBounds();
       fprintf(stderr, "Adding rect %d,%d,%d,%d for frame %p\n",
               bounds.x, bounds.y, bounds.width, bounds.height,
               (void*)aItem->GetUnderlyingFrame());
     }
 #endif
     aRegion->Or(*aRegion, r);
   }
 }
 
 static void
 AddItemsToRegion(nsDisplayListBuilder* aBuilder, nsDisplayList* aList,
-                 const nsRect& aRect, const nsRect& aClipRect, nsPoint aDelta,
+                 const nsRect& aUpdateRect, const nsRect& aClipRect, nsPoint aDelta,
                  nsRegion* aRegion)
 {
   for (nsDisplayItem* item = aList->GetBottom(); item; item = item->GetAbove()) {
     nsDisplayList* sublist = item->GetList();
     if (sublist) {
       nsDisplayItem::Type type = item->GetType();
 #ifdef MOZ_SVG
       if (type == nsDisplayItem::TYPE_SVG_EFFECTS) {
@@ -1180,67 +1181,68 @@ AddItemsToRegion(nsDisplayListBuilder* a
         // If the clipping frame is moving, then it isn't clipping any
         // non-moving content (see ApplyAbsPosClipping), so we don't need
         // to do anything special, but we should not restrict aClipRect.
         if (!aBuilder->IsMovingFrame(clipItem->GetClippingFrame())) {
           clip.IntersectRect(clip, clipItem->GetClipRect());
 
           // Invalidate the translation of the source area that was clipped out
           nsRegion clippedOutSource;
-          clippedOutSource.Sub(aRect, clip);
+          clippedOutSource.Sub(aUpdateRect - aDelta, clip);
           clippedOutSource.MoveBy(aDelta);
           aRegion->Or(*aRegion, clippedOutSource);
 
           // Invalidate the destination area that is clipped out
           nsRegion clippedOutDestination;
-          clippedOutDestination.Sub(aRect + aDelta, clip);
+          clippedOutDestination.Sub(aUpdateRect, clip);
           aRegion->Or(*aRegion, clippedOutDestination);
         }
-        AddItemsToRegion(aBuilder, sublist, aRect, clip, aDelta, aRegion);
+        AddItemsToRegion(aBuilder, sublist, aUpdateRect, clip, aDelta, aRegion);
       } else {
         // opacity, or a generic sublist
-        AddItemsToRegion(aBuilder, sublist, aRect, aClipRect, aDelta, aRegion);
+        AddItemsToRegion(aBuilder, sublist, aUpdateRect, aClipRect, aDelta, aRegion);
       }
     } else {
       nsRect r;
       if (r.IntersectRect(aClipRect, item->GetBounds(aBuilder))) {
         nsIFrame* f = item->GetUnderlyingFrame();
         NS_ASSERTION(f, "Must have an underlying frame for leaf item");
         nsRect exclude;
         if (aBuilder->IsMovingFrame(f)) {
           if (item->IsVaryingRelativeToMovingFrame(aBuilder)) {
             // something like background-attachment:fixed that varies
             // its drawing when it moves
-            AccumulateItemInRegion(aRegion, aRect + aDelta, r, exclude, item);
+            AccumulateItemInRegion(aRegion, aUpdateRect, r, exclude, item);
           }
         } else {
           // not moving.
           if (item->IsUniform(aBuilder)) {
             // If it's uniform, we don't need to invalidate where one part
             // of the item was copied to another part.
             exclude.IntersectRect(r, r + aDelta);
           }
           // area where a non-moving element is visible must be repainted
-          AccumulateItemInRegion(aRegion, aRect + aDelta, r, exclude, item);
+          AccumulateItemInRegion(aRegion, aUpdateRect, r, exclude, item);
           // we may have bitblitted an area that was painted by a non-moving
           // element. This bitblitted data is invalid and was copied to
           // "r + aDelta".
-          AccumulateItemInRegion(aRegion, aRect + aDelta, r + aDelta,
+          AccumulateItemInRegion(aRegion, aUpdateRect, r + aDelta,
                                  exclude, item);
         }
       }
     }
   }
 }
 
 nsresult
 nsLayoutUtils::ComputeRepaintRegionForCopy(nsIFrame* aRootFrame,
                                            nsIFrame* aMovingFrame,
                                            nsPoint aDelta,
-                                           const nsRect& aCopyRect,
+                                           const nsRect& aUpdateRect,
+                                           nsRegion* aBlitRegion,
                                            nsRegion* aRepaintRegion)
 {
   NS_ASSERTION(aRootFrame != aMovingFrame,
                "The root frame shouldn't be the one that's moving, that makes no sense");
 
   nsAutoDisableGetUsedXAssertions disableAssert;
 
   // Build the 'after' display list over the whole area of interest.
@@ -1251,19 +1253,22 @@ nsLayoutUtils::ComputeRepaintRegionForCo
   // 'before' display list. So opaque moving items are only considered to
   // cover the intersection of their old and new bounds (see
   // nsDisplayItem::OptimizeVisibility). A moving clip item is not allowed
   // to clip non-moving items --- this is enforced by the code that sets
   // up nsDisplayClip items, in particular see ApplyAbsPosClipping.
   // XXX but currently a non-moving clip item can incorrectly clip
   // moving items! See bug 428156.
   nsRect rect;
-  rect.UnionRect(aCopyRect, aCopyRect + aDelta);
+  rect.UnionRect(aUpdateRect, aUpdateRect - aDelta);
   nsDisplayListBuilder builder(aRootFrame, PR_FALSE, PR_TRUE);
-  builder.SetMovingFrame(aMovingFrame, aDelta);
+  // Retrieve the area of the moving content that's visible. This is the
+  // only area that needs to be blitted or repainted.
+  nsRegion visibleRegionOfMovingContent;
+  builder.SetMovingFrame(aMovingFrame, aDelta, &visibleRegionOfMovingContent);
   nsDisplayList list;
 
   builder.EnterPresShell(aRootFrame, rect);
 
   nsresult rv =
     aRootFrame->BuildDisplayListForStackingContext(&builder, rect, &list);
 
   builder.LeavePresShell(aRootFrame, rect);
@@ -1275,40 +1280,47 @@ nsLayoutUtils::ComputeRepaintRegionForCo
             "Repaint region for copy --- before optimization (area %d,%d,%d,%d, frame %p):\n",
             rect.x, rect.y, rect.width, rect.height, (void*)aMovingFrame);
     nsIFrameDebug::PrintDisplayList(&builder, list);
   }
 #endif
 
   // Optimize for visibility, but frames under aMovingFrame will not be
   // considered opaque, so they don't cover non-moving frames.
-  nsRegion visibleRegion(aCopyRect);
-  visibleRegion.Or(visibleRegion, aCopyRect + aDelta);
+  nsRegion visibleRegion(aUpdateRect);
+  visibleRegion.Or(visibleRegion, aUpdateRect - aDelta);
   list.OptimizeVisibility(&builder, &visibleRegion);
 
 #ifdef DEBUG
   if (gDumpRepaintRegionForCopy) {
     fprintf(stderr, "Repaint region for copy --- after optimization:\n");
     nsIFrameDebug::PrintDisplayList(&builder, list);
   }
 #endif
 
   aRepaintRegion->SetEmpty();
   // Any visible non-moving display items get added to the repaint region
   // a) at their current location and b) offset by -aPt (their position in
   // the 'before' display list) (unless they're uniform and we can exclude them).
   // Also, any visible position-varying display items get added to the
-  // repaint region. All these areas are confined to aCopyRect+aDelta.
+  // repaint region. All these areas are confined to aUpdateRect.
   // We could do more work here: e.g., do another optimize-visibility pass
   // with the moving items taken into account, either on the before-list
   // or the after-list, or even both if we cloned the display lists ... but
   // it's probably not worth it.
-  AddItemsToRegion(&builder, &list, aCopyRect, rect, aDelta, aRepaintRegion);
+  AddItemsToRegion(&builder, &list, aUpdateRect, rect, aDelta, aRepaintRegion);
   // Flush the list so we don't trigger the IsEmpty-on-destruction assertion
   list.DeleteAll();
+
+  // Finalize output regions. The region of moving content that's not
+  // visible --- hidden by overlaid opaque non-moving content --- need not
+  // be blitted or repainted.
+  visibleRegionOfMovingContent.And(visibleRegionOfMovingContent, aUpdateRect);
+  aRepaintRegion->And(*aRepaintRegion, visibleRegionOfMovingContent);
+  aBlitRegion->Sub(visibleRegionOfMovingContent, *aRepaintRegion);
   return NS_OK;
 }
 
 PRInt32
 nsLayoutUtils::GetZIndex(nsIFrame* aFrame) {
   if (!aFrame->GetStyleDisplay()->IsPositioned())
     return 0;
 
@@ -3030,41 +3042,44 @@ nsLayoutUtils::HasNonZeroCornerOnSide(co
     if (NonZeroStyleCoord(aCorners.Get(corner)) &&
         IsCornerAdjacentToSide(corner/2, aSide))
       return PR_TRUE;
   }
   return PR_FALSE;
 }
 
 /* static */ nsTransparencyMode
-nsLayoutUtils::GetFrameTransparency(nsIFrame* aFrame) {
-  if (aFrame->GetStyleContext()->GetStyleDisplay()->mOpacity < 1.0f)
+nsLayoutUtils::GetFrameTransparency(nsIFrame* aBackgroundFrame,
+                                    nsIFrame* aCSSRootFrame) {
+  if (aCSSRootFrame->GetStyleContext()->GetStyleDisplay()->mOpacity < 1.0f)
     return eTransparencyTransparent;
 
-  if (HasNonZeroCorner(aFrame->GetStyleContext()->GetStyleBorder()->mBorderRadius))
+  if (HasNonZeroCorner(aCSSRootFrame->GetStyleContext()->GetStyleBorder()->mBorderRadius))
     return eTransparencyTransparent;
 
   nsTransparencyMode transparency;
-  if (aFrame->IsThemed(&transparency))
+  if (aCSSRootFrame->IsThemed(&transparency))
     return transparency;
 
-  if (aFrame->GetStyleDisplay()->mAppearance == NS_THEME_WIN_GLASS)
+  if (aCSSRootFrame->GetStyleDisplay()->mAppearance == NS_THEME_WIN_GLASS)
     return eTransparencyGlass;
 
   // We need an uninitialized window to be treated as opaque because
   // doing otherwise breaks window display effects on some platforms,
   // specifically Vista. (bug 450322)
-  if (aFrame->GetType() == nsGkAtoms::viewportFrame &&
-      !aFrame->GetFirstChild(nsnull)) {
+  if (aBackgroundFrame->GetType() == nsGkAtoms::viewportFrame &&
+      !aBackgroundFrame->GetFirstChild(nsnull)) {
     return eTransparencyOpaque;
   }
 
   const nsStyleBackground* bg;
-  if (!nsCSSRendering::FindBackground(aFrame->PresContext(), aFrame, &bg))
+  if (!nsCSSRendering::FindBackground(aBackgroundFrame->PresContext(),
+                                      aBackgroundFrame, &bg)) {
     return eTransparencyTransparent;
+  }
   if (NS_GET_A(bg->mBackgroundColor) < 255 ||
       // bottom layer's clip is used for the color
       bg->BottomLayer().mClip != NS_STYLE_BG_CLIP_BORDER)
     return eTransparencyTransparent;
   return eTransparencyOpaque;
 }
 
 static PRBool
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -492,57 +492,64 @@ public:
    */
   static nsresult PaintFrame(nsIRenderingContext* aRenderingContext, nsIFrame* aFrame,
                              const nsRegion& aDirtyRegion, nscolor aBackstop,
                              PRUint32 aFlags = 0);
 
   /**
    * @param aRootFrame the root frame of the tree to be displayed
    * @param aMovingFrame a frame that has moved
-   * @param aPt the amount by which aMovingFrame has moved and the rect will
-   * be copied
-   * @param aCopyRect a rectangle that will be copied, relative to aRootFrame
-   * @param aRepaintRegion a subregion of aCopyRect+aDelta that must be repainted
-   * after doing the bitblt
+   * @param aPt the amount by which aMovingFrame has moved
+   * @param aUpdateRect a rectangle that bounds the area to be updated,
+   * relative to aRootFrame
+   * @param aRepaintRegion output: a subregion of aUpdateRect that must be
+   * repainted after doing the blit
+   * @param aBlitRegion output: a subregion of aUpdateRect that should
+   * be repainted by blitting
    * 
-   * Ideally this function would actually have the rect-to-copy as an output
-   * rather than an input, but for now, scroll bitblitting is limited to
-   * the whole of a single widget, so we cannot choose the rect.
+   * If the caller does a bitblt copy of aBlitRegion-aPt to aBlitRegion,
+   * and then repaints aRepaintRegion, then the area aUpdateRect will be
+   * correctly up to date. aBlitRegion and aRepaintRegion do not intersect
+   * and are both contained within aUpdateRect.
    * 
-   * This function assumes that the caller will do a bitblt copy of aCopyRect
-   * to aCopyRect+aPt. It computes a region that must be repainted in order
-   * for the resulting rendering to be correct. Frame geometry must have
-   * already been adjusted for the scroll/copy operation.
+   * Frame geometry must have already been adjusted for the scroll/copy
+   * operation before this function is called.
    * 
    * Conceptually it works by computing a display list in the before-state
    * and a display list in the after-state and analyzing them to find the
    * differences. In practice it is only feasible to build a display list
    * in the after-state (plus building two display lists would be less
    * efficient), so we use some unfortunately tricky techniques to get by
    * with just the after-list.
    * 
-   * The output region consists of:
+   * We compute the "visible moving area": aUpdateRect minus any opaque
+   * areas of non-moving content that are above all moving content in
+   * z-order.
+   *
+   * The aRepaintRegion region consists of the visible moving area
+   * intersected with the union of the following areas:
    * a) any visible background-attachment:fixed areas in the after-move display
    * list
    * b) any visible areas of the before-move display list corresponding to
    * frames that will not move (translated by aDelta)
    * c) any visible areas of the after-move display list corresponding to
    * frames that did not move
-   * d) except that if the same display list element is visible in b) and c)
-   * for a frame that did not move and paints a uniform color within its
-   * bounds, then the intersection of its old and new bounds can be excluded
-   * when it is processed by b) and c).
+   * 
+   * aBlitRegion is the visible moving area minus aRepaintRegion.
    * 
-   * We may return a larger region if computing the above region precisely is
-   * too expensive.
+   * We may return a larger region for aRepaintRegion and/or aBlitRegion
+   * if computing the above regions precisely is too expensive.  (However,
+   * they will never intersect, since the regions that may be computed
+   * imprecisely are really the "visible moving area" and aRepaintRegion.)
    */
   static nsresult ComputeRepaintRegionForCopy(nsIFrame* aRootFrame,
                                               nsIFrame* aMovingFrame,
                                               nsPoint aDelta,
-                                              const nsRect& aCopyRect,
+                                              const nsRect& aUpdateRect,
+                                              nsRegion* aBlitRegion,
                                               nsRegion* aRepaintRegion);
 
   /**
    * Compute the used z-index of aFrame; returns zero for elements to which
    * z-index does not apply, and for z-index:auto
    */
   static PRInt32 GetZIndex(nsIFrame* aFrame);
 
@@ -956,20 +963,26 @@ public:
    * Determine if there is any corner radius on corners adjacent to the
    * given side.
    */
   static PRBool HasNonZeroCornerOnSide(const nsStyleCorners& aCorners,
                                        PRUint8 aSide);
 
   /**
    * Determine if a widget is likely to require transparency or translucency.
-   *   @param aFrame the frame of a <window>, <popup> or <menupopup> element.
+   *   @param aBackgroundFrame The frame that the background is set on. For
+   *                           <window>s, this will be the canvas frame.
+   *   @param aCSSRootFrame    The frame that holds CSS properties affecting
+   *                           the widget's transparency. For menupopups,
+   *                           aBackgroundFrame and aCSSRootFrame will be the
+   *                           same.
    *   @return a value suitable for passing to SetWindowTranslucency
    */
-  static nsTransparencyMode GetFrameTransparency(nsIFrame* aFrame);
+  static nsTransparencyMode GetFrameTransparency(nsIFrame* aBackgroundFrame,
+                                                 nsIFrame* aCSSRootFrame);
 
   /**
    * Get textrun construction flags determined by a given style; in particular
    * some combination of:
    * -- TEXT_DISABLE_OPTIONAL_LIGATURES if letter-spacing is in use
    * -- TEXT_OPTIMIZE_SPEED if the text-rendering CSS property and font size
    * and prefs indicate we should be optimizing for speed over quality
    */
--- a/layout/base/nsPresContext.h
+++ b/layout/base/nsPresContext.h
@@ -463,19 +463,16 @@ public:
   }
 
   /**
    * Return true if this presentation context is a paginated
    * context.
    */
   PRBool IsPaginated() const { return mPaginated; }
   
-  PRBool GetRenderedPositionVaryingContent() const { return mRenderedPositionVaryingContent; }
-  void SetRenderedPositionVaryingContent() { mRenderedPositionVaryingContent = PR_TRUE; }
-
   /**
    * Sets whether the presentation context can scroll for a paginated
    * context.
    */
   NS_HIDDEN_(void) SetPaginatedScrolling(PRBool aResult);
 
   /**
    * Return true if this presentation context can scroll for paginated
@@ -1010,17 +1007,16 @@ protected:
   unsigned              mEnableJapaneseTransform : 1;
   unsigned              mIsRootPaginatedDocument : 1;
   unsigned              mPrefBidiDirection : 1;
   unsigned              mPrefScrollbarSide : 2;
   unsigned              mPendingSysColorChanged : 1;
   unsigned              mPendingThemeChanged : 1;
   unsigned              mPendingMediaFeatureValuesChanged : 1;
   unsigned              mPrefChangePendingNeedsReflow : 1;
-  unsigned              mRenderedPositionVaryingContent : 1;
 
   // Is the current mUserFontSet valid?
   unsigned              mUserFontSetDirty : 1;
   // Has GetUserFontSet() been called?
   unsigned              mGetUserFontSetCalled : 1;
   // Do we currently have an event posted to call FlushUserFontSet?
   unsigned              mPostedFlushUserFontSet : 1;
 
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -908,17 +908,18 @@ public:
                    nsIRenderingContext* aRenderingContext,
                    const nsRegion& aDirtyRegion);
   NS_IMETHOD PaintDefaultBackground(nsIView *aView,
                                     nsIRenderingContext* aRenderingContext,
                                     const nsRect& aDirtyRect);
   NS_IMETHOD ComputeRepaintRegionForCopy(nsIView*      aRootView,
                                          nsIView*      aMovingView,
                                          nsPoint       aDelta,
-                                         const nsRect& aCopyRect,
+                                         const nsRect& aUpdateRect,
+                                         nsRegion*     aBlitRegion,
                                          nsRegion*     aRepaintRegion);
   NS_IMETHOD HandleEvent(nsIView*        aView,
                          nsGUIEvent*     aEvent,
                          nsEventStatus*  aEventStatus);
   NS_IMETHOD HandleDOMEventWithTarget(nsIContent* aTargetContent,
                                       nsEvent* aEvent,
                                       nsEventStatus* aStatus);
   NS_IMETHOD HandleDOMEventWithTarget(nsIContent* aTargetContent,
@@ -5219,23 +5220,24 @@ PresShell::GetPlaceholderFrameFor(nsIFra
 }
 
 //nsIViewObserver
 
 NS_IMETHODIMP
 PresShell::ComputeRepaintRegionForCopy(nsIView*      aRootView,
                                        nsIView*      aMovingView,
                                        nsPoint       aDelta,
-                                       const nsRect& aCopyRect,
+                                       const nsRect& aUpdateRect,
+                                       nsRegion*     aBlitRegion,
                                        nsRegion*     aRepaintRegion)
 {
   return nsLayoutUtils::ComputeRepaintRegionForCopy(
       static_cast<nsIFrame*>(aRootView->GetClientData()),
       static_cast<nsIFrame*>(aMovingView->GetClientData()),
-      aDelta, aCopyRect, aRepaintRegion);
+      aDelta, aUpdateRect, aBlitRegion, aRepaintRegion);
 }
 
 NS_IMETHODIMP
 PresShell::RenderDocument(const nsRect& aRect, PRUint32 aFlags,
                           nscolor aBackgroundColor,
                           gfxContext* aThebesContext)
 {
   NS_ENSURE_TRUE(!(aFlags & RENDER_IS_UNTRUSTED), NS_ERROR_NOT_IMPLEMENTED);
@@ -6303,16 +6305,46 @@ PresShell::HandleEventWithTarget(nsEvent
 
 inline PRBool
 IsSynthesizedMouseMove(nsEvent* aEvent)
 {
   return aEvent->eventStructType == NS_MOUSE_EVENT &&
          static_cast<nsMouseEvent*>(aEvent)->reason != nsMouseEvent::eReal;
 }
 
+static PRBool CanHandleContextMenuEvent(nsMouseEvent* aMouseEvent,
+                                        nsIFrame* aFrame)
+{
+#if defined(XP_MACOSX) && defined(MOZ_XUL)
+  nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
+  if (pm) {
+    nsIFrame* popupFrame = pm->GetTopPopup(ePopupTypeMenu);
+    if (popupFrame) {
+      // context menus should not be opened while another menu is open on Mac,
+      // so return false so that the event is not fired.
+      if (aMouseEvent->context == nsMouseEvent::eContextMenuKey) {
+        return PR_FALSE;
+      } else if (aMouseEvent->widget) {
+         nsWindowType windowType;
+         aMouseEvent->widget->GetWindowType(windowType);
+         if (windowType == eWindowType_popup) {
+           for (nsIFrame* current = aFrame; current;
+                current = nsLayoutUtils::GetCrossDocParentFrame(current)) {
+             if (current->GetType() == nsGkAtoms::menuPopupFrame) {
+               return PR_FALSE;
+             }
+           }
+         }
+      }
+    }
+  }
+#endif
+  return PR_TRUE;
+}
+
 nsresult
 PresShell::HandleEventInternal(nsEvent* aEvent, nsIView *aView,
                                nsEventStatus* aStatus)
 {
 #ifdef ACCESSIBILITY
   if (aEvent->eventStructType == NS_ACCESSIBLE_EVENT)
   {
     static_cast<nsAccessibleEvent*>(aEvent)->accessible = nsnull;
@@ -6353,21 +6385,26 @@ PresShell::HandleEventInternal(nsEvent* 
       case NS_MOUSE_BUTTON_UP:
       case NS_KEY_PRESS:
       case NS_KEY_DOWN:
       case NS_KEY_UP:
         isHandlingUserInput = PR_TRUE;
       }
     }
 
-    if (aEvent->message == NS_CONTEXTMENU &&
-        static_cast<nsMouseEvent*>(aEvent)->context == nsMouseEvent::eContextMenuKey) {
-      if (!AdjustContextMenuKeyEvent(static_cast<nsMouseEvent*>(aEvent)))
+    if (aEvent->message == NS_CONTEXTMENU) {
+      nsMouseEvent* me = static_cast<nsMouseEvent*>(aEvent);
+      if (!CanHandleContextMenuEvent(me, GetCurrentEventFrame())) {
         return NS_OK;
-    }
+      }
+      if (me->context == nsMouseEvent::eContextMenuKey &&
+          !AdjustContextMenuKeyEvent(me)) {
+        return NS_OK;
+      }
+    }                                
 
     nsAutoHandlingUserInputStatePusher userInpStatePusher(isHandlingUserInput);
 
     nsAutoPopupStatePusher popupStatePusher(nsDOMEvent::GetEventPopupControlState(aEvent));
 
     // FIXME. If the event was reused, we need to clear the old target,
     // bug 329430
     aEvent->target = nsnull;
@@ -6455,43 +6492,35 @@ PresShell::HandleDOMEventWithTarget(nsIC
   PopCurrentEventInfo();
   return NS_OK;
 }
 
 PRBool
 PresShell::AdjustContextMenuKeyEvent(nsMouseEvent* aEvent)
 {
 #ifdef MOZ_XUL
-  // if a menu is open, open the context menu relative to the active item on the menu.
-  // XXXndeakin Mac doesn't fire mouse-triggered context menus while another
-  // menu is open. Maybe we should prevent keyboard-tiggered context menu events too. 
+  // if a menu is open, open the context menu relative to the active item on the menu. 
   nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
   if (pm) {
     nsIFrame* popupFrame = pm->GetTopPopup(ePopupTypeMenu);
     if (popupFrame) {
-#ifdef XP_MACOSX
-      // context menus should not be opened while another menu is open on Mac,
-      // so return false so that the event is not fired.
-      return PR_FALSE;
-#else
       nsIFrame* itemFrame = 
         (static_cast<nsMenuPopupFrame *>(popupFrame))->GetCurrentMenuItem();
       if (!itemFrame)
         itemFrame = popupFrame;
 
       nsCOMPtr<nsIWidget> widget = popupFrame->GetWindow();
       aEvent->widget = widget;
       nsIntPoint widgetPoint = widget->WidgetToScreenOffset();
       aEvent->refPoint = itemFrame->GetScreenRect().BottomLeft() - widgetPoint;
 
       mCurrentEventContent = itemFrame->GetContent();
       mCurrentEventFrame = itemFrame;
 
       return PR_TRUE;
-#endif
     }
   }
 #endif
 
   // If we're here because of the key-equiv for showing context menus, we
   // have to twiddle with the NS event to make sure the context menu comes
   // up in the upper left of the relevant content area before we create
   // the DOM event. Since we never call InitMouseEvent() on the event, 
@@ -7185,16 +7214,18 @@ PresShell::DoReflow(nsIFrame* target, PR
   NS_ASSERTION(status == NS_FRAME_COMPLETE,
                "reflow roots should never split");
 
   target->SetSize(nsSize(desiredSize.width, desiredSize.height));
 
   nsContainerFrame::SyncFrameViewAfterReflow(mPresContext, target,
                                              target->GetView(),
                                              &desiredSize.mOverflowArea);
+  nsContainerFrame::SyncWindowProperties(mPresContext, target,
+                                         target->GetView());
 
   target->DidReflow(mPresContext, nsnull, NS_FRAME_REFLOW_FINISHED);
   if (target == rootFrame && size.height == NS_UNCONSTRAINEDSIZE) {
     mPresContext->SetVisibleArea(nsRect(0, 0, desiredSize.width,
                                         desiredSize.height));
   }
 
 #ifdef DEBUG
--- a/layout/forms/nsListControlFrame.cpp
+++ b/layout/forms/nsListControlFrame.cpp
@@ -2139,18 +2139,16 @@ nsListControlFrame::GetIndexFromDOMEvent
 
 nsresult
 nsListControlFrame::MouseDown(nsIDOMEvent* aMouseEvent)
 {
   NS_ASSERTION(aMouseEvent != nsnull, "aMouseEvent is null.");
 
   UpdateInListState(aMouseEvent);
 
-  mButtonDown = PR_TRUE;
-
   if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::disabled)) {
     return NS_OK;
   }
 
   // only allow selection with the left button
   // if a right button click is on the combobox itself
   // or on the select when in listbox mode, then let the click through
   if (!IsLeftButton(aMouseEvent)) {
@@ -2165,16 +2163,17 @@ nsListControlFrame::MouseDown(nsIDOMEven
     } else {
       return NS_OK;
     }
   }
 
   PRInt32 selectedIndex;
   if (NS_SUCCEEDED(GetIndexFromDOMEvent(aMouseEvent, selectedIndex))) {
     // Handle Like List
+    mButtonDown = PR_TRUE;
     CaptureMouseEvents(PR_TRUE);
     mChangesSinceDragStart = HandleListSelection(aMouseEvent, selectedIndex);
 #ifdef ACCESSIBILITY
     if (mChangesSinceDragStart) {
       FireMenuItemActiveEvent();
     }
 #endif
   } else {
--- a/layout/forms/nsTextControlFrame.cpp
+++ b/layout/forms/nsTextControlFrame.cpp
@@ -2281,17 +2281,17 @@ nsTextControlFrame::OffsetToDOMPoint(PRI
         NS_ADDREF(*aResult);
         return NS_OK;
       }
 
       ++textOffset;
     }
   }
 
-  NS_ASSERTION(0, "We should never get here!");
+  NS_ERROR("We should never get here!");
 
   return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsTextControlFrame::GetSelectionRange(PRInt32* aSelectionStart, PRInt32* aSelectionEnd)
 {
   // make sure we have an editor
--- a/layout/generic/nsContainerFrame.cpp
+++ b/layout/generic/nsContainerFrame.cpp
@@ -466,48 +466,51 @@ IsMenuPopup(nsIFrame *aFrame)
       return listControlFrame->IsInDropDownMode();
     }
   }
 
   // ... or if we're a XUL menupopup frame.
   return (frameType == nsGkAtoms::menuPopupFrame);
 }
 
-static PRBool
-IsTopLevelWidget(nsPresContext* aPresContext)
+static nsIWidget*
+GetPresContextContainerWidget(nsPresContext* aPresContext)
 {
   nsCOMPtr<nsISupports> container = aPresContext->Document()->GetContainer();
   nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(container);
   if (!baseWindow)
-    return PR_FALSE;
+    return nsnull;
 
   nsCOMPtr<nsIWidget> mainWidget;
   baseWindow->GetMainWidget(getter_AddRefs(mainWidget));
-  if (!mainWidget)
-    return PR_FALSE;
+  return mainWidget;
+}
 
+static PRBool
+IsTopLevelWidget(nsIWidget* aWidget)
+{
   nsWindowType windowType;
-  mainWidget->GetWindowType(windowType);
+  aWidget->GetWindowType(windowType);
   return windowType == eWindowType_toplevel ||
-         windowType == eWindowType_dialog;
+         windowType == eWindowType_dialog || 
+         windowType == eWindowType_sheet;
   // popups aren't toplevel so they're not handled here
 }
 
-static void
-SyncFrameViewGeometryDependentProperties(nsPresContext*   aPresContext,
-                                         nsIFrame*        aFrame,
-                                         nsStyleContext*  aStyleContext,
-                                         nsIView*         aView,
-                                         PRUint32         aFlags)
+void
+nsContainerFrame::SyncWindowProperties(nsPresContext*       aPresContext,
+                                       nsIFrame*            aFrame,
+                                       nsIView*             aView)
 {
 #ifdef MOZ_XUL
-  if (!nsCSSRendering::IsCanvasFrame(aFrame))
+  if (!aView || !nsCSSRendering::IsCanvasFrame(aFrame) || !aView->HasWidget())
     return;
 
-  if (!aView->HasWidget() || !IsTopLevelWidget(aPresContext))
+  nsIWidget* windowWidget = GetPresContextContainerWidget(aPresContext);
+  if (!windowWidget || !IsTopLevelWidget(windowWidget))
     return;
 
   nsIViewManager* vm = aView->GetViewManager();
   nsIView* rootView;
   vm->GetRootView(rootView);
 
   if (aView != rootView)
     return;
@@ -527,31 +530,24 @@ SyncFrameViewGeometryDependentProperties
     // (e.g. to do something like Dashboard widgets), once we
     // have broad support for translucent scrolled documents, but be
     // careful because apparently some Firefox extensions expect
     // openDialog("something.html") to produce an opaque window
     // even if the HTML doesn't have a background-color set.
     return;
   }
 
-  // The issue here is that the CSS 'background' propagates from the root
-  // element's frame (rootFrame) to the real root frame (nsViewportFrame),
-  // so we need to call GetFrameTransparency on that. But -moz-appearance
-  // does not propagate so we need to check that directly on rootFrame.
-  nsTransparencyMode mode = nsLayoutUtils::GetFrameTransparency(aFrame);
   nsIFrame *rootFrame = aPresContext->PresShell()->FrameConstructor()->GetRootElementStyleFrame();
-  if (rootFrame &&
-      NS_THEME_WIN_GLASS == rootFrame->GetStyleDisplay()->mAppearance) {
-    mode = eTransparencyGlass;
-  }
-  nsIWidget* widget = aView->GetWidget();
-  widget->SetTransparencyMode(mode);
-  if (rootFrame) {
-    widget->SetWindowShadowStyle(rootFrame->GetStyleUIReset()->mWindowShadow);
-  }
+  if (!rootFrame)
+    return;
+
+  nsTransparencyMode mode = nsLayoutUtils::GetFrameTransparency(aFrame, rootFrame);
+  nsIWidget* viewWidget = aView->GetWidget();
+  viewWidget->SetTransparencyMode(mode);
+  windowWidget->SetWindowShadowStyle(rootFrame->GetStyleUIReset()->mWindowShadow);
 #endif
 }
 
 void
 nsContainerFrame::SyncFrameViewAfterReflow(nsPresContext* aPresContext,
                                            nsIFrame*       aFrame,
                                            nsIView*        aView,
                                            const nsRect*   aCombinedArea,
@@ -567,25 +563,16 @@ nsContainerFrame::SyncFrameViewAfterRefl
   if (0 == (aFlags & NS_FRAME_NO_MOVE_VIEW)) {
     PositionFrameView(aFrame);
   }
 
   if (0 == (aFlags & NS_FRAME_NO_SIZE_VIEW)) {
     nsIViewManager* vm = aView->GetViewManager();
 
     vm->ResizeView(aView, *aCombinedArea, PR_TRUE);
-
-    // Even if the size hasn't changed, we need to sync up the
-    // geometry dependent properties, because overflow areas of
-    // children might have changed, and we can't
-    // detect whether it has or not. Likewise, whether the view size
-    // has changed or not, we may need to change the transparency
-    // state even if there is no clip.
-    nsStyleContext* savedStyleContext = aFrame->GetStyleContext();
-    SyncFrameViewGeometryDependentProperties(aPresContext, aFrame, savedStyleContext, aView, aFlags);
   }
 }
 
 void
 nsContainerFrame::SyncFrameViewProperties(nsPresContext*  aPresContext,
                                           nsIFrame*        aFrame,
                                           nsStyleContext*  aStyleContext,
                                           nsIView*         aView,
@@ -659,18 +646,16 @@ nsContainerFrame::SyncFrameViewPropertie
     if (position->mZIndex.GetUnit() == eStyleUnit_Integer) {
       zIndex = position->mZIndex.GetIntValue();
     } else if (position->mZIndex.GetUnit() == eStyleUnit_Auto) {
       autoZIndex = PR_TRUE;
     }
   }
 
   vm->SetViewZIndex(aView, autoZIndex, zIndex, isPositioned);
-
-  SyncFrameViewGeometryDependentProperties(aPresContext, aFrame, aStyleContext, aView, aFlags);
 }
 
 PRBool
 nsContainerFrame::FrameNeedsView(nsIFrame* aFrame)
 {
   // XXX Check needed because frame construction can't properly figure out when
   // a frame is the child of a scrollframe
   if (aFrame->GetStyleContext()->GetPseudoType() ==
--- a/layout/generic/nsContainerFrame.h
+++ b/layout/generic/nsContainerFrame.h
@@ -121,21 +121,25 @@ public:
   // NS_FRAME_NO_MOVE_VIEW - don't position the frame's view. Set this if you
   //    don't want to automatically sync the frame and view
   // NS_FRAME_NO_SIZE_VIEW - don't size the view
   static void SyncFrameViewAfterReflow(nsPresContext* aPresContext,
                                        nsIFrame*       aFrame,
                                        nsIView*        aView,
                                        const nsRect*   aCombinedArea,
                                        PRUint32        aFlags = 0);
-  
+
+  // Syncs properties to the top level view and window, like transparency and
+  // shadow.
+  static void SyncWindowProperties(nsPresContext*       aPresContext,
+                                   nsIFrame*            aFrame,
+                                   nsIView*             aView);
+
   // Sets the view's attributes from the frame style.
-  // - opacity
   // - visibility
-  // - content transparency
   // - clip
   // Call this when one of these styles changes or when the view has just
   // been created.
   // @param aStyleContext can be null, in which case the frame's style context is used
   static void SyncFrameViewProperties(nsPresContext*  aPresContext,
                                       nsIFrame*        aFrame,
                                       nsStyleContext*  aStyleContext,
                                       nsIView*         aView,
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -1387,44 +1387,16 @@ nsIFrame::BuildDisplayListForStackingCon
 
     resultList.AppendToTop(transform);
   }
 
   aList->AppendToTop(&resultList);
   return rv;
 }
 
-class nsDisplaySummary : public nsDisplayItem
-{
-public:
-  nsDisplaySummary(nsIFrame* aFrame) : nsDisplayItem(aFrame) {
-    MOZ_COUNT_CTOR(nsDisplaySummary);
-  }
-#ifdef NS_BUILD_REFCNT_LOGGING
-  virtual ~nsDisplaySummary() {
-    MOZ_COUNT_DTOR(nsDisplaySummary);
-  }
-#endif
-
-  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
-  NS_DISPLAY_DECL_NAME("Summary")
-};
-
-nsRect
-nsDisplaySummary::GetBounds(nsDisplayListBuilder* aBuilder) {
-  return mFrame->GetOverflowRect() + aBuilder->ToReferenceFrame(mFrame);
-}
-
-static void
-AddSummaryFrameToList(nsDisplayListBuilder* aBuilder,
-                      nsIFrame* aFrame, nsDisplayList* aList)
-{
-  aList->AppendNewToTop(new (aBuilder) nsDisplaySummary(aFrame));
-}
-
 nsresult
 nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder*   aBuilder,
                                    nsIFrame*               aChild,
                                    const nsRect&           aDirtyRect,
                                    const nsDisplayListSet& aLists,
                                    PRUint32                aFlags) {
   // If painting is restricted to just the background of the top level frame,
   // then we have nothing to do here.
@@ -1497,37 +1469,16 @@ nsIFrame::BuildDisplayListForChild(nsDis
       if (!childDirty.IntersectRect(dirty, aChild->GetOverflowRect()))
         return NS_OK;
       // Usually we could set dirty to childDirty now but there's no
       // benefit, and it can be confusing. It can especially confuse
       // situations where we're going to ignore a scrollframe's clipping;
       // we wouldn't want to clip the dirty area to the scrollframe's
       // bounds in that case.
     }
-
-    // Note that aBuilder->GetRootMovingFrame() is non-null only if we're doing
-    // ComputeRepaintRegionForCopy.
-    if (aBuilder->GetRootMovingFrame() == this &&
-        !PresContext()->GetRenderedPositionVaryingContent()) {
-      // No position-varying content has been rendered in this prescontext.
-      // Therefore there is no need to descend into analyzing the moving frame's
-      // descendants looking for such content, because any bitblit will
-      // not be copying position-varying graphics. However, to keep things
-      // sane we still need display items representing the frame subtree.
-      // We need to add these summaries to every list that the child could
-      // contribute to. This avoids display list optimizations optimizing
-      // away entire lists because they appear to be empty.
-      AddSummaryFrameToList(aBuilder, aChild, aLists.BlockBorderBackgrounds());
-      AddSummaryFrameToList(aBuilder, aChild, aLists.BorderBackground());
-      AddSummaryFrameToList(aBuilder, aChild, aLists.Content());
-      AddSummaryFrameToList(aBuilder, aChild, aLists.Floats());
-      AddSummaryFrameToList(aBuilder, aChild, aLists.PositionedDescendants());      
-      AddSummaryFrameToList(aBuilder, aChild, aLists.Outlines());
-      return NS_OK;
-    }
   }
 
   // XXX need to have inline-block and inline-table set pseudoStackingContext
   
   const nsStyleDisplay* ourDisp = GetStyleDisplay();
   // REVIEW: Taken from nsBoxFrame::Paint
   // Don't paint our children if the theme object is a leaf.
   if (IsThemed(ourDisp) &&
@@ -5449,17 +5400,17 @@ nsIFrame::GetFrameFromDirection(nsDirect
       if (aDirection == eDirPrevious) {
         nsFrame::GetFirstLeaf(presContext, &firstFrame);
         atLineEdge = firstFrame == traversedFrame;
       } else { // eDirNext
         lastFrame = firstFrame;
         for (;lineFrameCount > 1;lineFrameCount --){
           result = it->GetNextSiblingOnLine(lastFrame, thisLine);
           if (NS_FAILED(result) || !lastFrame){
-            NS_ASSERTION(0,"should not be reached nsFrame\n");
+            NS_ERROR("should not be reached nsFrame\n");
             return NS_ERROR_FAILURE;
           }
         }
         nsFrame::GetLastLeaf(presContext, &lastFrame);
         atLineEdge = lastFrame == traversedFrame;
       }
     }
 
--- a/layout/generic/nsFrameSelection.h
+++ b/layout/generic/nsFrameSelection.h
@@ -136,50 +136,50 @@ struct NS_STACK_CLASS nsPeekOffsetStruct
   // mStartOffset: Offset into the content of the current frame where the peek starts.
   //               Used with: eSelectCharacter, eSelectWord
   PRInt32 mStartOffset;
   
   // mDesiredX: The desired x coordinate for the caret.
   //            Used with: eSelectLine.
   nscoord mDesiredX;
 
-  // mJumpLines: Whether to allow jumping across line boundaries.
-  //             Used with: eSelectCharacter, eSelectWord.
-  PRBool mJumpLines;
-
-  // mScrollViewStop: Whether to stop when reaching a scroll view boundary.
-  //                  Used with: eSelectCharacter, eSelectWord, eSelectLine.
-  PRBool mScrollViewStop;
-
-  // mIsKeyboardSelect: Whether the peeking is done in response to a keyboard action.
-  //                    Used with: eSelectWord.
-  PRBool mIsKeyboardSelect;
-
-  // mVisual: Whether bidi caret behavior is visual (PR_TRUE) or logical (PR_FALSE).
-  //          Used with: eSelectCharacter, eSelectWord, eSelectBeginLine, eSelectEndLine.
-  PRBool mVisual;
-
   // mWordMovementType: An enum that determines whether to prefer the start or end of a word
   //                    or to use the default beahvior, which is a combination of 
   //                    direction and the platform-based pref
   //                    "layout.word_select.eat_space_to_next_word"
   EWordMovementType mWordMovementType;
 
+  // mJumpLines: Whether to allow jumping across line boundaries.
+  //             Used with: eSelectCharacter, eSelectWord.
+  PRPackedBool mJumpLines;
+
+  // mScrollViewStop: Whether to stop when reaching a scroll view boundary.
+  //                  Used with: eSelectCharacter, eSelectWord, eSelectLine.
+  PRPackedBool mScrollViewStop;
+
+  // mIsKeyboardSelect: Whether the peeking is done in response to a keyboard action.
+  //                    Used with: eSelectWord.
+  PRPackedBool mIsKeyboardSelect;
+
+  // mVisual: Whether bidi caret behavior is visual (PR_TRUE) or logical (PR_FALSE).
+  //          Used with: eSelectCharacter, eSelectWord, eSelectBeginLine, eSelectEndLine.
+  PRPackedBool mVisual;
+
   /*** Output arguments ***/
 
   // mResultContent: Content reached as a result of the peek.
   nsCOMPtr<nsIContent> mResultContent;
 
-  // mContentOffset: Offset into content reached as a result of the peek.
-  PRInt32 mContentOffset;
-
   // mResultFrame: Frame reached as a result of the peek.
   //               Used with: eSelectCharacter, eSelectWord.
   nsIFrame *mResultFrame;
 
+  // mContentOffset: Offset into content reached as a result of the peek.
+  PRInt32 mContentOffset;
+
   // mAttachForward: When the result position is between two frames,
   //                 indicates which of the two frames the caret should be painted in.
   //                 PR_FALSE means "the end of the frame logically before the caret", 
   //                 PR_TRUE means "the beginning of the frame logically after the caret".
   //                 Used with: eSelectLine, eSelectBeginLine, eSelectEndLine.
   PRBool mAttachForward;
 };
 
--- a/layout/generic/nsSelection.cpp
+++ b/layout/generic/nsSelection.cpp
@@ -844,17 +844,17 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
 NS_INTERFACE_MAP_END
 
 
 nsresult
 nsFrameSelection::FetchDesiredX(nscoord &aDesiredX) //the x position requested by the Key Handling for up down
 {
   if (!mShell)
   {
-    NS_ASSERTION(0,"fetch desired X failed\n");
+    NS_ERROR("fetch desired X failed\n");
     return NS_ERROR_FAILURE;
   }
   if (mDesiredXSet)
   {
     aDesiredX = mDesiredX;
     return NS_OK;
   }
 
--- a/layout/generic/test/file_IconTestServer.sjs
+++ b/layout/generic/test/file_IconTestServer.sjs
@@ -1,35 +1,63 @@
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const TIMEOUT_INTERVAL_MS = 100;
 
-// Global Context
-var ctx = {};
-
 function handleRequest(request, response) {
 
   // Allow us to asynchronously construct the response with timeouts
   // rather than forcing us to make the whole thing in one call. See
   // bug 396226.
   response.processAsync();
 
   // Figure out whether the client wants to load the image, or just
-  // to tell us that it's ready for us to finish
+  // to tell us to finish the previous load
   var query = {};
   request.queryString.split('&').forEach(function (val) {
     var [name, value] = val.split('=');
     query[name] = unescape(value);
   });
   if (query["continue"] == "true") {
-    setState("doContinue", "yes");
+
+    // Get the context structure and finish the old request
+    getObjectState("context", function(obj) {
+
+      // magic or goop, depending on how you look at it
+      savedCtx = obj.wrappedJSObject;
+
+      // Write the rest of the data
+      savedCtx.ostream.writeFrom(savedCtx.istream, savedCtx.istream.available());
+
+      // Close the streams
+      savedCtx.ostream.close();
+      savedCtx.istream.close();
+
+      // Finish off 'the old response'
+      savedCtx.response.finish();
+    });
+
+    // Finish off 'the current response'
     response.finish();
     return;
   }
 
+  // Context structure - we need to set this up properly to pass to setObjectState
+  var ctx = {
+    QueryInterface: function(iid) {
+      if (iid.equals(Components.interfaces.nsISupports))
+        return this;
+      throw Components.results.NS_ERROR_NO_INTERFACE;
+    }
+  };
+  ctx.wrappedJSObject = ctx;
+
+  // Save the response
+  ctx.response = response;
+
   // We're serving up a png
   response.setHeader("Content-Type", "image/png", false);
 
   // Get the output stream
   ctx.ostream = response.bodyOutputStream;
 
   // Ugly hack, but effective - copied from content/media/test/contentDuration1.sjs
   var pngFile = Components.classes["@mozilla.org/file/directory_service;1"].
@@ -44,40 +72,14 @@ function handleRequest(request, response
   // Get an input stream for the png data
   ctx.istream = Cc["@mozilla.org/network/file-input-stream;1"].
                       createInstance(Components.interfaces.nsIFileInputStream);
   ctx.istream.init(pngFile, -1, 0, 0);
 
   // Write the first 10 bytes, which is just boilerplate/magic bytes
   ctx.ostream.writeFrom(ctx.istream, 10);
 
-  // Mark that we haven't yet been instructed to continue
-  setState("doContinue", "no");
+  // Save the context structure for retrieval when we get pinged
+  setObjectState("context", ctx);
 
-  // Wait for the continue request, then finish
-  waitForContinueAndFinish();
+  // Now we play the waiting game...
 }
 
-function waitForContinueAndFinish() {
-
-  // If we can continue
-  if (getState("doContinue") == "yes")
-    return finishRequest();
-
-  // Wait 100 ms and check again
-  var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
-  timer.initWithCallback(waitForContinueAndFinish,
-                         TIMEOUT_INTERVAL_MS, Ci.nsITimer.TYPE_ONE_SHOT);
-}
-
-
-function finishRequest() {
-
-  // Write the rest of the data
-  ctx.ostream.writeFrom(ctx.istream, ctx.istream.available());
-
-  // Close the streams
-  ctx.ostream.close();
-  ctx.istream.close();
-
-  // Finish off the response
-  response.finish();
-}
--- a/layout/mathml/nsMathMLmpaddedFrame.cpp
+++ b/layout/mathml/nsMathMLmpaddedFrame.cpp
@@ -321,17 +321,17 @@ nsMathMLmpaddedFrame::UpdateValue(PRInt3
 
         case NS_MATHML_PSEUDO_UNIT_LSPACE:
              scaler = aLeftSpace;
              break;
 
         default:
           // if we ever reach here, it would mean something is wrong 
           // somewhere with the setup and/or the caller
-          NS_ASSERTION(0, "Unexpected Pseudo Unit");
+          NS_ERROR("Unexpected Pseudo Unit");
           return;
       }
     }
 
     if (eCSSUnit_Number == unit)
       amount = NSToCoordRound(float(scaler) * aCSSValue.GetFloatValue());
     else if (eCSSUnit_Percent == unit)
       amount = NSToCoordRound(float(scaler) * aCSSValue.GetPercentValue());
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/387227-1-ref.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<html>
+ <body>
+   <div style="display: table-cell">Table cell</div
+  ><div>New Div</div
+  ><div id="insertion">Block</div>
+ </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/387227-1.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+ <head>
+   <script>
+     function runTest() {
+       dump('aaa');
+       var div = document.createElement("div");
+       div.appendChild(document.createTextNode("New Div"));
+       document.body.insertBefore(div, document.getElementById("insertion"));
+     }
+   </script>
+ </head>
+ <body onload="runTest()">
+   <div style="display: table-cell">Table cell</div
+  ><div id="insertion">Block</div>
+ </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/387227-2-ref.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<html>
+ <body>
+   <div style="display: table-cell">Table cell</div>
+   <div>New Div</div><div id="insertion">Block</div>
+ </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/387227-2.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+ <head>
+   <script>
+     function runTest() {
+       dump('aaa');
+       var div = document.createElement("div");
+       div.appendChild(document.createTextNode("New Div"));
+       document.body.insertBefore(div, document.getElementById("insertion"));
+     }
+   </script>
+ </head>
+ <body onload="runTest()">
+   <div style="display: table-cell">Table cell</div>
+   <div id="insertion">Block</div>
+ </body>
+</html>
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -685,16 +685,18 @@ fails == 386147-1.html 386147-1-ref.html
 == 386401-3.html 386401-3-ref.html
 == 386470-1a.html 386470-1-ref.html
 == 386470-1b.html 386470-1-ref.html
 == 386470-1c.html 386470-1-ref.html
 == 386920-1.html 386920-1-ref.html
 == 387201-1.html 387201-1-ref.html
 == 387201-2.html about:blank  # Really an assertion test rather than a rendering test
 == 387201-3.html about:blank  # Really an assertion test rather than a rendering test
+== 387227-1.html 387227-1-ref.html
+== 387227-2.html 387227-2-ref.html
 == 387344-1.html 387344-1-ref.html
 == 387876-1.html 387876-1-ref.html
 random == 387876-2.html 387876-2-ref.html # bug 471630
 == 387876-3a.html 387876-3-ref.html
 == 387876-3b.html 387876-3-ref.html
 == 388026-1.html 388026-1-ref.html
 == 388367-1.html about:blank
 == 388980-1.html 388980-1-ref.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/canvas/default-size-ref.html
@@ -0,0 +1,7 @@
+<!DOCTYPE HTML>
+<html>
+<body>
+<canvas style="border: 1px solid black;" width="300" height="150">
+</canvas>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/canvas/default-size.html
@@ -0,0 +1,7 @@
+<!DOCTYPE HTML>
+<html>
+<body>
+<canvas style="border: 1px solid black;">
+</canvas>
+</body>
+</html>
--- a/layout/reftests/canvas/reftest.list
+++ b/layout/reftests/canvas/reftest.list
@@ -1,8 +1,10 @@
+== default-size.html default-size-ref.html
+
 == image-rendering-test.html image-rendering-ref.html
 
 != text-ltr-left.html text-blank.html
 != text-ltr-right.html text-blank.html
 != text-rtl-left.html text-blank.html
 != text-rtl-right.html text-blank.html
 
 == text-ltr-start.html text-ltr-left.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/first-letter/quote-1e.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <style>
+  div { color: black; }
+  div::first-letter { color: green; }
+  </style>
+</head>
+<body>
+  <div><a>"<span>This is text</span>"</a></div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/first-letter/quote-1f.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <style>
+  div { color: black; }
+  div::first-letter { color: green; }
+  span:before { content: "\"This "; }
+  </style>
+</head>
+<body>
+  <div><span>is text"</span></div>
+</body>
+</html>
--- a/layout/reftests/first-letter/reftest.list
+++ b/layout/reftests/first-letter/reftest.list
@@ -9,21 +9,24 @@
 == nested-1a.html nested-1-ref.html
 == nested-1b.html nested-1-ref.html
 == nested-1c.html nested-1-ref.html
 == nested-1d.html nested-1-ref.html
 == nested-1e.html nested-1-ref.html
 == nested-1f.html nested-1-ref.html
 == nested-1g.html nested-1-ref.html
 == quote-1a.html quote-1-ref.html
-fails == quote-1b.html quote-1-ref.html
-fails == quote-1c.html quote-1-ref.html
+fails == quote-1b.html quote-1-ref.html # bug 509685
+fails == quote-1c.html quote-1-ref.html # bug 509685
 == quote-1c.html quote-1b.html
 fails == quote-1d.html quote-1-ref.html
 random == quote-1d.html quote-1b.html
+fails == quote-1e.html quote-1-ref.html # bug 509685
+== quote-1e.html quote-1b.html
+== quote-1f.html quote-1-ref.html
 fails == dynamic-1.html dynamic-1-ref.html # bug 8253
 == dynamic-2.html dynamic-2-ref.html
 == dynamic-3a.html dynamic-3-ref.html
 random == dynamic-3b.html dynamic-3-ref.html
 == 23605-1.html 23605-1-ref.html
 == 23605-2.html 23605-2-ref.html
 == 23605-3.html 23605-3-ref.html
 == 23605-4.html 23605-4-ref.html
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -343,16 +343,18 @@ GetStyleContextForFrame(nsIFrame* aFrame
 }    
 
 /* static */
 already_AddRefed<nsStyleContext>
 nsComputedDOMStyle::GetStyleContextForContent(nsIContent* aContent,
                                               nsIAtom* aPseudo,
                                               nsIPresShell* aPresShell)
 {
+  NS_ASSERTION(aContent->IsNodeOfType(nsINode::eELEMENT),
+               "aContent must be an element");
   if (!aPseudo) {
     aPresShell->FlushPendingNotifications(Flush_Style);
     nsIFrame* frame = aPresShell->GetPrimaryFrameFor(aContent);
     if (frame) {
       nsStyleContext* result = GetStyleContextForFrame(frame);
       // Don't use the style context if it was influenced by
       // pseudo-elements, since then it's not the primary style
       // for this element.
@@ -363,30 +365,26 @@ nsComputedDOMStyle::GetStyleContextForCo
       }
     }
   }
 
   // No frame has been created or we have a pseudo, so resolve the
   // style ourselves
   nsRefPtr<nsStyleContext> parentContext;
   nsIContent* parent = aPseudo ? aContent : aContent->GetParent();
-  if (parent)
+  // Don't resolve parent context for document fragments.
+  if (parent && parent->IsNodeOfType(nsINode::eELEMENT))
     parentContext = GetStyleContextForContent(parent, nsnull, aPresShell);
 
   nsPresContext *presContext = aPresShell->GetPresContext();
   if (!presContext)
     return nsnull;
 
   nsStyleSet *styleSet = aPresShell->StyleSet();
 
-  if (!aContent->IsNodeOfType(nsINode::eELEMENT)) {
-    NS_ASSERTION(!aPseudo, "Shouldn't have a pseudo for a non-element!");
-    return styleSet->ResolveStyleForNonElement(parentContext);
-  }
-
   if (aPseudo) {
     return styleSet->ResolvePseudoStyleFor(aContent, aPseudo, parentContext);
   }
 
   return styleSet->ResolveStyleFor(aContent, parentContext);
 }
 
 NS_IMETHODIMP
new file mode 100644
--- /dev/null
+++ b/layout/xul/base/src/crashtests/508927-1.xul
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+<bindings xmlns="http://www.mozilla.org/xbl"><binding id="foo"><content><xul:listrows xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"><xul:listboxbody/><children xmlns="http://www.mozilla.org/xbl"/></xul:listrows></content></binding></bindings>
+<hbox style="-moz-binding: url(#foo);"><listitem/><listitem/></hbox>
+</window>
--- a/layout/xul/base/src/crashtests/crashtests.list
+++ b/layout/xul/base/src/crashtests/crashtests.list
@@ -51,8 +51,9 @@ load 434458-1.xul
 load 460900-1.xul
 load 464149-1.xul
 load 467481-1.xul
 load 470063-1.html
 load 472189.xul
 load 475133.html
 load 488210-1.xhtml
 load 495728-1.xul
+load 508927-1.xul
--- a/layout/xul/base/src/nsListBoxBodyFrame.cpp
+++ b/layout/xul/base/src/nsListBoxBodyFrame.cpp
@@ -66,16 +66,17 @@
 #include "nsAutoPtr.h"
 #include "nsStyleSet.h"
 #include "nsIDOMNSDocument.h"
 #include "nsPIBoxObject.h"
 #include "nsINodeInfo.h"
 #include "nsLayoutUtils.h"
 #include "nsPIListBoxObject.h"
 #include "nsContentUtils.h"
+#include "nsChildIterator.h"
 
 /////////////// nsListScrollSmoother //////////////////
 
 /* A mediator used to smooth out scrolling. It works by seeing if 
  * we have time to scroll the amount of rows requested. This is determined
  * by measuring how long it takes to scroll a row. If we can scroll the 
  * rows in time we do so. If not we start a timer and skip the request. We
  * do this until the timer finally first because the user has stopped moving
@@ -575,23 +576,21 @@ nsListBoxBodyFrame::ScrollByLines(PRInt3
 // walks the DOM to get the zero-based row index of the content
 nsresult
 nsListBoxBodyFrame::GetIndexOfItem(nsIDOMElement* aItem, PRInt32* _retval)
 {
   if (aItem) {
     *_retval = 0;
     nsCOMPtr<nsIContent> itemContent(do_QueryInterface(aItem));
 
-    nsIContent* listbox = mContent->GetBindingParent();
-    NS_ENSURE_STATE(listbox);
-
-    PRUint32 childCount = listbox->GetChildCount();
-    for (PRUint32 childIndex = 0; childIndex < childCount; childIndex++) {
-      nsIContent *child = listbox->GetChildAt(childIndex);
-
+    ChildIterator iter, last;
+    for (ChildIterator::Init(mContent, &iter, &last);
+         iter != last;
+         ++iter) {
+      nsIContent *child = (*iter);
       // we hit a list row, count it
       if (child->Tag() == nsGkAtoms::listitem) {
         // is this it?
         if (child == itemContent)
           return NS_OK;
 
         ++(*_retval);
       }
@@ -605,25 +604,22 @@ nsListBoxBodyFrame::GetIndexOfItem(nsIDO
 
 nsresult
 nsListBoxBodyFrame::GetItemAtIndex(PRInt32 aIndex, nsIDOMElement** aItem)
 {
   *aItem = nsnull;
   if (aIndex < 0)
     return NS_OK;
   
-  nsIContent* listbox = mContent->GetBindingParent();
-  NS_ENSURE_STATE(listbox);
-
-  PRUint32 childCount = listbox->GetChildCount();
-
   PRInt32 itemCount = 0;
-  for (PRUint32 childIndex = 0; childIndex < childCount; childIndex++) {
-    nsIContent *child = listbox->GetChildAt(childIndex);
-
+  ChildIterator iter, last;
+  for (ChildIterator::Init(mContent, &iter, &last);
+       iter != last;
+       ++iter) {
+    nsIContent *child = (*iter);
     // we hit a list row, check if it is the one we are looking for
     if (child->Tag() == nsGkAtoms::listitem) {
       // is this it?
       if (itemCount == aIndex) {
         return CallQueryInterface(child, aItem);
       }
       ++itemCount;
     }
@@ -730,23 +726,23 @@ nsListBoxBodyFrame::ComputeIntrinsicWidt
     nsMargin margin(0,0,0,0);
 
     if (styleContext->GetStylePadding()->GetPadding(margin))
       width += margin.LeftRight();
     width += styleContext->GetStyleBorder()->GetActualBorder().LeftRight();
     if (styleContext->GetStyleMargin()->GetMargin(margin))
       width += margin.LeftRight();
 
-    nsIContent* listbox = mContent->GetBindingParent();
-    NS_ENSURE_TRUE(listbox, largestWidth);
 
-    PRUint32 childCount = listbox->GetChildCount();
-
-    for (PRUint32 i = 0; i < childCount && i < 100; ++i) {
-      nsIContent *child = listbox->GetChildAt(i);
+    ChildIterator iter, last;
+    PRUint32 i = 0;
+    for (ChildIterator::Init(mContent, &iter, &last);
+         iter != last && i < 100;
+         ++iter, ++i) {
+      nsIContent *child = (*iter);
 
       if (child->Tag() == nsGkAtoms::listitem) {
         nsIRenderingContext* rendContext = aBoxLayoutState.GetRenderingContext();
         if (rendContext) {
           nsAutoString value;
           PRUint32 textCount = child->GetChildCount();
           for (PRUint32 j = 0; j < textCount; ++j) {
             nsIContent* text = child->GetChildAt(j);
@@ -771,22 +767,22 @@ nsListBoxBodyFrame::ComputeIntrinsicWidt
   mStringWidth = largestWidth;
   return mStringWidth;
 }
 
 void
 nsListBoxBodyFrame::ComputeTotalRowCount()
 {
   mRowCount = 0;
-  nsIContent* listbox = mContent->GetBindingParent();
-  ENSURE_TRUE(listbox);
 
-  PRUint32 childCount = listbox->GetChildCount();
-  for (PRUint32 i = 0; i < childCount; i++) {
-    if (listbox->GetChildAt(i)->Tag() == nsGkAtoms::listitem)
+  ChildIterator iter, last;
+  for (ChildIterator::Init(mContent, &iter, &last);
+       iter != last;
+       ++iter) {
+    if ((*iter)->Tag() == nsGkAtoms::listitem)
       ++mRowCount;
   }
 }
 
 void
 nsListBoxBodyFrame::PostReflowCallback()
 {
   if (!mReflowCallbackPosted) {
@@ -1380,30 +1376,32 @@ nsListBoxBodyFrame::OnContentInserted(ns
     FrameNeedsReflow(this, nsIPresShell::eTreeChange,
                      NS_FRAME_HAS_DIRTY_CHILDREN);
 }
 
 // 
 // Called by nsCSSFrameConstructor when listitem content is removed.
 //
 void
-nsListBoxBodyFrame::OnContentRemoved(nsPresContext* aPresContext, nsIFrame* aChildFrame, PRInt32 aIndex)
+nsListBoxBodyFrame::OnContentRemoved(nsPresContext* aPresContext,
+                                     nsIContent* aContainer,
+                                     nsIFrame* aChildFrame,
+                                     PRInt32 aIndex)
 {
   NS_ASSERTION(!aChildFrame || aChildFrame->GetParent() == this,
                "Removing frame that's not our child... Not good");
   
   if (mRowCount >= 0)
     --mRowCount;
 
-  nsIContent* listBoxContent = mContent->GetBindingParent();
-  if (listBoxContent) {
+  if (aContainer) {
     if (!aChildFrame) {
       // The row we are removing is out of view, so we need to try to
       // determine the index of its next sibling.
-      nsIContent *oldNextSiblingContent = listBoxContent->GetChildAt(aIndex);
+      nsIContent *oldNextSiblingContent = aContainer->GetChildAt(aIndex);
   
       PRInt32 siblingIndex = -1;
       if (oldNextSiblingContent) {
         nsCOMPtr<nsIContent> nextSiblingContent;
         GetListItemNextSibling(oldNextSiblingContent, getter_AddRefs(nextSiblingContent), siblingIndex);
       }
     
       // if the row being removed is off-screen and above the top frame, we need to
@@ -1417,19 +1415,21 @@ nsListBoxBodyFrame::OnContentRemoved(nsP
     } else if (mCurrentIndex > 0) {
       // At this point, we know we have a scrollbar, and we need to know 
       // if we are scrolled to the last row.  In this case, the behavior
       // of the scrollbar is to stay locked to the bottom.  Since we are
       // removing visible content, the first visible row will have to move
       // down by one, and we will have to insert a new frame at the top.
       
       // if the last content node has a frame, we are scrolled to the bottom
-      PRUint32 childCount = listBoxContent->GetChildCount();
-      if (childCount > 0) {
-        nsIContent *lastChild = listBoxContent->GetChildAt(childCount - 1);
+      ChildIterator iter, last;
+      ChildIterator::Init(mContent, &iter, &last);
+      if (last.position() > 0) {
+        iter.seek(last.position() - 1);
+        nsIContent *lastChild = *iter;
         nsIFrame* lastChildFrame = 
           aPresContext->PresShell()->GetPrimaryFrameFor(lastChild);
       
         if (lastChildFrame) {
           mTopFrame = nsnull;
           mRowsToPrepend = 1;
           --mCurrentIndex;
           mYPosition = mCurrentIndex*mRowHeight;
@@ -1453,57 +1453,53 @@ nsListBoxBodyFrame::OnContentRemoved(nsP
     FrameNeedsReflow(this, nsIPresShell::eTreeChange,
                      NS_FRAME_HAS_DIRTY_CHILDREN);
 }
 
 void
 nsListBoxBodyFrame::GetListItemContentAt(PRInt32 aIndex, nsIContent** aContent)
 {
   *aContent = nsnull;
-  nsIContent* listboxContent = mContent->GetBindingParent();
-  ENSURE_TRUE(listboxContent);
 
-  PRUint32 childCount = listboxContent->GetChildCount();
   PRInt32 itemsFound = 0;
-  for (PRUint32 i = 0; i < childCount; ++i) {
-    nsIContent *kid = listboxContent->GetChildAt(i);
-
+  ChildIterator iter, last;
+  for (ChildIterator::Init(mContent, &iter, &last);
+       iter != last;
+       ++iter) {
+    nsIContent *kid = (*iter);
     if (kid->Tag() == nsGkAtoms::listitem) {
       ++itemsFound;
       if (itemsFound-1 == aIndex) {
         *aContent = kid;
         NS_IF_ADDREF(*aContent);
         return;
       }
-        
     }
   }
 }
 
 void
 nsListBoxBodyFrame::GetListItemNextSibling(nsIContent* aListItem, nsIContent** aContent, PRInt32& aSiblingIndex)
 {
   *aContent = nsnull;
   aSiblingIndex = -1;
-  nsIContent* listboxContent = mContent->GetBindingParent();
-  ENSURE_TRUE(listboxContent);
-
-  PRUint32 childCount = listboxContent->GetChildCount();
   nsIContent *prevKid = nsnull;
-  for (PRUint32 i = 0; i < childCount; ++i) {
-    nsIContent *kid = listboxContent->GetChildAt(i);
+  ChildIterator iter, last;
+  for (ChildIterator::Init(mContent, &iter, &last);
+       iter != last;
+       ++iter) {
+    nsIContent *kid = (*iter);
 
     if (kid->Tag() == nsGkAtoms::listitem) {
       ++aSiblingIndex;
       if (prevKid == aListItem) {
         *aContent = kid;
         NS_IF_ADDREF(*aContent);
         return;
       }
-        
     }
     prevKid = kid;
   }
 
   aSiblingIndex = -1; // no match, so there is no next sibling
 }
 
 void
--- a/layout/xul/base/src/nsListBoxBodyFrame.h
+++ b/layout/xul/base/src/nsListBoxBodyFrame.h
@@ -134,17 +134,18 @@ public:
   void DestroyRows(PRInt32& aRowsToLose);
   void ReverseDestroyRows(PRInt32& aRowsToLose);
   nsIBox* GetFirstItemBox(PRInt32 aOffset, PRBool* aCreated);
   nsIBox* GetNextItemBox(nsIBox* aBox, PRInt32 aOffset, PRBool* aCreated);
   PRBool ContinueReflow(nscoord height);
   NS_IMETHOD ListBoxAppendFrames(nsFrameList& aFrameList);
   NS_IMETHOD ListBoxInsertFrames(nsIFrame* aPrevFrame, nsFrameList& aFrameList);
   void OnContentInserted(nsPresContext* aPresContext, nsIContent* aContent);
-  void OnContentRemoved(nsPresContext* aPresContext,  nsIFrame* aChildFrame, PRInt32 aIndex);
+  void OnContentRemoved(nsPresContext* aPresContext,  nsIContent* aContainer,
+                        nsIFrame* aChildFrame, PRInt32 aIndex);
 
   void GetListItemContentAt(PRInt32 aIndex, nsIContent** aContent);
   void GetListItemNextSibling(nsIContent* aListItem, nsIContent** aContent, PRInt32& aSiblingIndex);
 
   void PostReflowCallback();
 
   PRBool SetBoxObject(nsPIBoxObject* aBoxObject)
   {
--- a/layout/xul/base/src/nsMenuPopupFrame.cpp
+++ b/layout/xul/base/src/nsMenuPopupFrame.cpp
@@ -246,17 +246,17 @@ nsMenuPopupFrame::CreateWidgetForView(ns
 {
   // Create a widget for ourselves.
   nsWidgetInitData widgetData;
   widgetData.mWindowType = eWindowType_popup;
   widgetData.mBorderStyle = eBorderStyle_default;
   widgetData.clipSiblings = PR_TRUE;
   widgetData.mPopupHint = mPopupType;
 
-  nsTransparencyMode mode = nsLayoutUtils::GetFrameTransparency(this);
+  nsTransparencyMode mode = nsLayoutUtils::GetFrameTransparency(this, this);
   PRBool viewHasTransparentContent = !mInContentShell &&
                                      (eTransparencyTransparent ==
                                       mode);
   nsIContent* parentContent = GetContent()->GetParent();
   nsIAtom *tag = nsnull;
   if (parentContent)
     tag = parentContent->Tag();
   widgetData.mDropShadow = !(viewHasTransparentContent || tag == nsGkAtoms::menulist);
--- a/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp
+++ b/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp
@@ -4124,25 +4124,27 @@ nsTreeBodyFrame::ScrollInternal(const Sc
       PR_ABS(delta)*mRowHeight >= mRect.height) {
     Invalidate();
   } else {
     nsIWidget* widget = nsLeafBoxFrame::GetView()->GetWidget();
     if (widget) {
       nscoord rowHeightAsPixels =
         PresContext()->AppUnitsToDevPixels(mRowHeight);
       nsIntPoint deltaPt = nsIntPoint(0, -delta*rowHeightAsPixels);
+
       nsIntRect bounds;
       widget->GetBounds(bounds);
       bounds.x = bounds.y = 0;
-      nsIntRect source;
-      source.IntersectRect(bounds, bounds - deltaPt);
+      nsTArray<nsIntRect> destRects;
+      destRects.AppendElement(bounds);
+
       // No plugins have a tree widget as a parent so we don't need
       // configurations here.
       nsTArray<nsIWidget::Configuration> emptyConfigurations;
-      widget->Scroll(deltaPt, source, emptyConfigurations);
+      widget->Scroll(deltaPt, destRects, emptyConfigurations);
       nsIntRect invalid = bounds;
       if (deltaPt.y < 0) {
         invalid.y = bounds.height + deltaPt.y;
         invalid.height = -deltaPt.y;
       } else {
         invalid.height = deltaPt.y;
       }
       widget->Invalidate(invalid, PR_FALSE);
@@ -4179,25 +4181,27 @@ nsTreeBodyFrame::ScrollHorzInternal(cons
       background->mImageCount > 1 ||
       NS_GET_A(background->mBackgroundColor) < 255 ||
       PR_ABS(delta) >= mRect.width) {
     Invalidate();
   } else {
     nsIWidget* widget = nsLeafBoxFrame::GetView()->GetWidget();
     if (widget) {
       nsIntPoint deltaPt(PresContext()->AppUnitsToDevPixels(-delta), 0);
+
       nsIntRect bounds;
       widget->GetBounds(bounds);
       bounds.x = bounds.y = 0;
-      nsIntRect source;
-      source.IntersectRect(bounds, bounds - deltaPt);
+      nsTArray<nsIntRect> destRects;
+      destRects.AppendElement(bounds);
+
       // No plugins have a tree widget as a parent so we don't need
       // configurations here.
       nsTArray<nsIWidget::Configuration> emptyConfigurations;
-      widget->Scroll(deltaPt, source, emptyConfigurations);
+      widget->Scroll(deltaPt, destRects, emptyConfigurations);
       nsIntRect invalid = bounds;
       if (deltaPt.x < 0) {
         invalid.x = bounds.width + deltaPt.x;
         invalid.width = -deltaPt.x;
       } else {
         invalid.width = deltaPt.x;
       }
       widget->Invalidate(invalid, PR_FALSE);
--- a/layout/xul/base/src/tree/src/nsTreeBodyFrame.h
+++ b/layout/xul/base/src/tree/src/nsTreeBodyFrame.h
@@ -181,16 +181,19 @@ public:
     nsIScrollableView* mColumnsScrollableView;
   };
 
   void PaintTreeBody(nsIRenderingContext& aRenderingContext,
                      const nsRect& aDirtyRect, nsPoint aPt);
 
   nsITreeBoxObject* GetTreeBoxObject() const { return mTreeBoxObject; }
 
+  PRBool GetVerticalOverflow() const { return mVerticalOverflow; }
+  PRBool GetHorizontalOverflow() const {return mHorizontalOverflow; }
+
 protected:
   friend class nsOverflowChecker;
 
   // This method paints a specific column background of the tree.
   void PaintColumn(nsTreeColumn*        aColumn,
                    const nsRect&        aColumnRect,
                    nsPresContext*      aPresContext,
                    nsIRenderingContext& aRenderingContext,
--- a/modules/libjar/nsJAR.cpp
+++ b/modules/libjar/nsJAR.cpp
@@ -117,17 +117,16 @@ DeleteManifestEntry(nsHashKey* aKey, voi
 
 // The following initialization makes a guess of 10 entries per jarfile.
 nsJAR::nsJAR(): mManifestData(nsnull, nsnull, DeleteManifestEntry, nsnull, 10),
                 mParsedManifest(PR_FALSE),
                 mGlobalStatus(JAR_MANIFEST_NOT_PARSED),
                 mReleaseTime(PR_INTERVAL_NO_TIMEOUT), 
                 mCache(nsnull), 
                 mLock(nsnull),
-                mMtime(0),
                 mTotalItemsInManifest(0)
 {
 }
 
 nsJAR::~nsJAR()
 {
   Close();
 }
@@ -162,26 +161,24 @@ nsrefcnt nsJAR::Release(void)
 
 NS_IMETHODIMP
 nsJAR::Open(nsIFile* zipFile)
 {
   NS_ENSURE_ARG_POINTER(zipFile);
   if (mLock) return NS_ERROR_FAILURE; // Already open!
 
   mZipFile = zipFile;
-  nsresult rv = zipFile->GetLastModifiedTime(&mMtime);
-  if (NS_FAILED(rv)) return rv;
 
   mLock = PR_NewLock();
   NS_ENSURE_TRUE(mLock, NS_ERROR_OUT_OF_MEMORY);
 
   PRFileDesc *fd = OpenFile();
   NS_ENSURE_TRUE(fd, NS_ERROR_FAILURE);
 
-  rv = mZip.OpenArchive(fd);
+  nsresult rv = mZip.OpenArchive(fd);
   if (NS_FAILED(rv)) Close();
 
   return rv;
 }
 
 NS_IMETHODIMP
 nsJAR::GetFile(nsIFile* *result)
 {
@@ -335,29 +332,19 @@ nsJAR::GetInputStreamWithSpec(const nsAC
   }
   nsJARInputStream* jis = new nsJARInputStream();
   // addref now so we can call InitFile/InitDirectory()
   NS_ENSURE_TRUE(jis, NS_ERROR_OUT_OF_MEMORY);
   NS_ADDREF(*result = jis);
 
   nsresult rv = NS_OK;
   if (!item || item->isDirectory) {
-    rv = jis->InitDirectory(&mZip, aJarDirSpec, aEntryName);
+    rv = jis->InitDirectory(this, aJarDirSpec, aEntryName);
   } else {
-    // Open jarfile, to get its own filedescriptor for the stream
-    // XXX The file may have been overwritten, so |item| might not be
-    // valid.  We really want to work from inode rather than file name.
-    PRFileDesc *fd = nsnull;
-    fd = OpenFile();
-    if (fd) {
-      rv = jis->InitFile(&mZip, item, fd);
-      // |jis| now owns |fd|
-    } else {
-      rv = NS_ERROR_FAILURE;
-    }
+    rv = jis->InitFile(mZip.GetFD(item), item);
   }
   if (NS_FAILED(rv)) {
     NS_RELEASE(*result);
   }
   return rv;
 }
 
 //----------------------------------------------
@@ -1108,23 +1095,19 @@ nsZipReaderCache::GetZip(nsIFile* zipFil
 #ifdef ZIP_CACHE_HIT_RATE
   mZipCacheLookups++;
 #endif
 
   nsCAutoString path;
   rv = zipFile->GetNativePath(path);
   if (NS_FAILED(rv)) return rv;
 
-  PRInt64 Mtime;
-  rv = zipFile->GetLastModifiedTime(&Mtime);
-  if (NS_FAILED(rv)) return rv;
-
   nsCStringKey key(path);
   nsJAR* zip = static_cast<nsJAR*>(static_cast<nsIZipReader*>(mZips.Get(&key))); // AddRefs
-  if (zip && Mtime == zip->GetMtime()) {
+  if (zip) {
 #ifdef ZIP_CACHE_HIT_RATE
     mZipCacheHits++;
 #endif
     zip->ClearReleaseTime();
   }
   else {
     if (zip) {
       antiLockZipGrip = zip;
--- a/modules/libjar/nsJAR.h
+++ b/modules/libjar/nsJAR.h
@@ -128,20 +128,16 @@ class nsJAR : public nsIZipReader, publi
     void ClearReleaseTime() {
       mReleaseTime = PR_INTERVAL_NO_TIMEOUT;
     }
     
     void SetZipReaderCache(nsZipReaderCache* cache) {
       mCache = cache;
     }
 
-    PRInt64 GetMtime() {
-      return mMtime;
-    }
-
   protected:
     //-- Private data members
     nsCOMPtr<nsIFile>        mZipFile;        // The zip/jar file on disk
     nsZipArchive             mZip;            // The underlying zip archive
     nsObjectHashtable        mManifestData;   // Stores metadata for each entry
     PRBool                   mParsedManifest; // True if manifest has been parsed
     nsCOMPtr<nsIPrincipal>   mPrincipal;      // The entity which signed this file
     PRInt16                  mGlobalStatus;   // Global signature verification status
--- a/modules/libjar/nsJARInputStream.cpp
+++ b/modules/libjar/nsJARInputStream.cpp
@@ -18,16 +18,17 @@
  *
  * The Initial Developer of the Original Code is
  * Netscape Communications Corporation.
  * Portions created by the Initial Developer are Copyright (C) 1999
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *   Mitch Stoltz <mstoltz@netscape.com>
+ *   Taras Glek <tglek@mozilla.com>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
@@ -40,45 +41,40 @@
 
 #include "nsJARInputStream.h"
 #include "zipstruct.h"         // defines ZIP compression codes
 #include "nsZipArchive.h"
 
 #include "nsNetUtil.h"
 #include "nsEscape.h"
 #include "nsIFile.h"
+#include "nsDebug.h"
 
 /*---------------------------------------------
  *  nsISupports implementation
  *--------------------------------------------*/
 
 NS_IMPL_THREADSAFE_ISUPPORTS1(nsJARInputStream, nsIInputStream)
 
 /*----------------------------------------------------------
  * nsJARInputStream implementation
  *--------------------------------------------------------*/
 
 nsresult
-nsJARInputStream::InitFile(nsZipArchive* aZip, nsZipItem *item, PRFileDesc *fd)
+nsJARInputStream::InitFile(nsZipHandle *aFd, nsZipItem *item)
 {
     nsresult rv;
-
-    // Keep the file handle, even on failure
-    mFd = fd;
-      
-    NS_ENSURE_ARG_POINTER(aZip);
-    NS_ENSURE_ARG_POINTER(item);
-    NS_ENSURE_ARG_POINTER(fd);
+    NS_ABORT_IF_FALSE(aFd, "Argument may not be null");
+    NS_ABORT_IF_FALSE(item, "Argument may not be null");
 
     // Mark it as closed, in case something fails in initialisation
     mClosed = PR_TRUE;
-
     // Keep the important bits of nsZipItem only
     mInSize = item->size;
- 
+
     //-- prepare for the compression type
     switch (item->compression) {
        case STORED: 
            break;
 
        case DEFLATED:
            mInflate = (InflateStruct *) PR_Malloc(sizeof(InflateStruct));
            NS_ENSURE_TRUE(mInflate, NS_ERROR_OUT_OF_MEMORY);
@@ -91,39 +87,38 @@ nsJARInputStream::InitFile(nsZipArchive*
            mInflate->mOutCrc = crc32(0L, Z_NULL, 0);
            break;
 
        default:
            return NS_ERROR_NOT_IMPLEMENTED;
     }
    
     //-- Set filepointer to start of item
-    rv = aZip->SeekToItem(item, mFd);
-    NS_ENSURE_SUCCESS(rv, NS_ERROR_FILE_CORRUPTED);
+    mFd.Open(aFd, item->dataOffset, item->size);
         
     // Open for reading
     mClosed = PR_FALSE;
     mCurPos = 0;
     return NS_OK;
 }
 
 nsresult
-nsJARInputStream::InitDirectory(nsZipArchive* aZip,
+nsJARInputStream::InitDirectory(nsJAR* aJar,
                                 const nsACString& aJarDirSpec,
                                 const char* aDir)
 {
-    NS_ENSURE_ARG_POINTER(aZip);
-    NS_ENSURE_ARG_POINTER(aDir);
+    NS_ABORT_IF_FALSE(aJar, "Argument may not be null");
+    NS_ABORT_IF_FALSE(aDir, "Argument may not be null");
 
     // Mark it as closed, in case something fails in initialisation
     mClosed = PR_TRUE;
     mDirectory = PR_TRUE;
     
     // Keep the zipReader for getting the actual zipItems
-    mZip = aZip;
+    mJar = aJar;
     nsZipFind *find;
     nsresult rv;
     // We can get aDir's contents as strings via FindEntries
     // with the following pattern (see nsIZipReader.findEntries docs)
     // assuming dirName is properly escaped:
     //
     //   dirName + "?*~" + dirName + "?*/?*"
     nsDependentCString dirName(aDir);
@@ -151,17 +146,17 @@ nsJARInputStream::InitDirectory(nsZipArc
                 // fall through
             default:
                 escDirName.Append(*curr);
         }
         ++curr;
     }
     nsCAutoString pattern = escDirName + NS_LITERAL_CSTRING("?*~") +
                             escDirName + NS_LITERAL_CSTRING("?*/?*");
-    rv = aZip->FindInit(pattern.get(), &find);
+    rv = mJar->mZip.FindInit(pattern.get(), &find);
     if (NS_FAILED(rv)) return rv;
 
     const char *name;
     while ((rv = find->FindNext( &name )) == NS_OK) {
         // No need to copy string, just share the one from nsZipArchive
         mArray.AppendElement(nsDependentCString(name));
     }
     delete find;
@@ -215,37 +210,35 @@ nsJARInputStream::Read(char* aBuffer, PR
         rv = ReadDirectory(aBuffer, aCount, aBytesRead);
     } else {
         if (mInflate) {
             rv = ContinueInflate(aBuffer, aCount, aBytesRead);
         } else {
             PRInt32 bytesRead = 0;
             aCount = PR_MIN(aCount, mInSize - mCurPos);
             if (aCount) {
-                bytesRead = PR_Read(mFd, aBuffer, aCount);
+                bytesRead = mFd.Read(aBuffer, aCount);
                 if (bytesRead < 0)
                     return NS_ERROR_FILE_CORRUPTED;
                 mCurPos += bytesRead;
-                if (bytesRead != aCount) {
+                if ((PRUint32)bytesRead != aCount) {
                     // file is truncated or was lying about size, we're done
-                    PR_Close(mFd);
-                    mFd = nsnull;
+                    Close();
                     return NS_ERROR_FILE_CORRUPTED;
                 }
             }
             *aBytesRead = bytesRead;
         }
-
         // be aggressive about closing!
         // note that sometimes, we will close mFd before we've finished
         // deflating - this is because zlib buffers the input
         // So, don't free the ReadBuf/InflateStruct yet.
-        if (mCurPos >= mInSize && mFd) {
-            PR_Close(mFd);
-            mFd = nsnull;
+        // It is ok to close the fd multiple times (also in nsJARInputStream::Close())
+        if (mCurPos >= mInSize) {
+            mFd.Close();
         }
     }
     return rv;
 }
 
 NS_IMETHODIMP
 nsJARInputStream::ReadSegments(nsWriteSegmentFun writer, void * closure, PRUint32 count, PRUint32 *_retval)
 {
@@ -260,21 +253,18 @@ nsJARInputStream::IsNonBlocking(PRBool *
     *aNonBlocking = PR_FALSE;
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsJARInputStream::Close()
 {
     PR_FREEIF(mInflate);
-    if (mFd) {
-        PR_Close(mFd);
-        mFd = nsnull;
-    }
     mClosed = PR_TRUE;
+    mFd.Close();
     return NS_OK;
 }
 
 nsresult 
 nsJARInputStream::ContinueInflate(char* aBuffer, PRUint32 aCount,
                                   PRUint32* aBytesRead)
 {
     // No need to check the args, ::Read did that, but assert them at least
@@ -292,18 +282,17 @@ nsJARInputStream::ContinueInflate(char* 
     int zerr = Z_OK;
     //-- inflate loop
     while (mInflate->mZs.avail_out > 0 && zerr == Z_OK) {
 
         if (mInflate->mZs.avail_in == 0 && mCurPos < mInSize) {
             // time to fill the buffer!
             PRUint32 bytesToRead = PR_MIN(mInSize - mCurPos, ZIP_BUFLEN);
 
-            NS_ASSERTION(mFd, "File handle missing");
-            PRInt32 bytesRead = PR_Read(mFd, mInflate->mReadBuf, bytesToRead);
+            PRInt32 bytesRead = mFd.Read(mInflate->mReadBuf, bytesToRead);
             if (bytesRead < 0) {
                 zerr = Z_ERRNO;
                 break;
             }
             mCurPos += bytesRead;
 
             // now set the state for 'inflate'
             mInflate->mZs.next_in = mInflate->mReadBuf;
@@ -357,17 +346,17 @@ nsJARInputStream::ReadDirectory(char* aB
 
         for ( ;aCount > mBuffer.Length(); mArrPos++) {
             // have we consumed all the directory contents?
             if (arrayLen <= mArrPos)
                 break;
 
             const char * entryName = mArray[mArrPos].get();
             PRUint32 entryNameLen = mArray[mArrPos].Length();
-            nsZipItem* ze = mZip->GetItem(entryName);
+            nsZipItem* ze = mJar->mZip.GetItem(entryName);
             NS_ENSURE_TRUE(ze, NS_ERROR_FILE_TARGET_DOES_NOT_EXIST);
 
             // Last Modified Time
             PRExplodedTime tm;
             PR_ExplodeTime(GetModTime(ze->date, ze->time), PR_GMTParameters, &tm);
             char itemLastModTime[65];
             PR_FormatTimeUSEnglish(itemLastModTime,
                                    sizeof(itemLastModTime),
--- a/modules/libjar/nsJARInputStream.h
+++ b/modules/libjar/nsJARInputStream.h
@@ -48,54 +48,55 @@
  * Class nsJARInputStream declaration. This class defines the type of the
  * object returned by calls to nsJAR::GetInputStream(filename) for the
  * purpose of reading a file item out of a JAR file. 
  *------------------------------------------------------------------------*/
 class nsJARInputStream : public nsIInputStream
 {
   public:
     nsJARInputStream() : 
-        mFd(nsnull), mInSize(0), mCurPos(0),
-        mInflate(nsnull), mDirectory(0), mClosed(PR_FALSE) { }
-    
-    ~nsJARInputStream() { Close(); }
+        mInSize(0), mCurPos(0), mInflate(nsnull), mDirectory(0), mClosed(PR_FALSE)
+  { }
+
+  ~nsJARInputStream() {
+    Close();
+  }
 
     NS_DECL_ISUPPORTS
     NS_DECL_NSIINPUTSTREAM
    
     // takes ownership of |fd|, even on failure
-    nsresult InitFile(nsZipArchive* aZip, nsZipItem *item, PRFileDesc *fd);
+    nsresult InitFile(nsZipHandle *aFd, nsZipItem *item);
 
-    nsresult InitDirectory(nsZipArchive* aZip,
+    nsresult InitDirectory(nsJAR *aJar,
                            const nsACString& aJarDirSpec,
                            const char* aDir);
   
   private:
-    PRFileDesc*   mFd;              // My own file handle, for reading
     PRUint32      mInSize;          // Size in original file 
     PRUint32      mCurPos;          // Current position in input 
 
     struct InflateStruct {
         PRUint32      mOutSize;     // inflated size 
         PRUint32      mInCrc;       // CRC as provided by the zipentry
         PRUint32      mOutCrc;      // CRC as calculated by me
         z_stream      mZs;          // zip data structure
         unsigned char mReadBuf[ZIP_BUFLEN]; // Readbuffer to inflate from
     };
     struct InflateStruct *   mInflate;
 
     /* For directory reading */
-    nsZipArchive*           mZip;        // the zipReader
+    nsRefPtr<nsJAR>         mJar;     // string reference to zipreader
     PRUint32                mNameLen; // length of dirname
     nsCAutoString           mBuffer;  // storage for generated text of stream
     PRUint32                mArrPos;  // current position within mArray
     nsTArray<nsCString>     mArray;   // array of names in (zip) directory
-
-    PRPackedBool    mDirectory;
-    PRPackedBool    mClosed;          // Whether the stream is closed
+  PRPackedBool            mDirectory; // is this a directory?
+    PRPackedBool            mClosed;  // Whether the stream is closed
+    nsSeekableZipHandle     mFd;      // handle for reading
 
     nsresult ContinueInflate(char* aBuf, PRUint32 aCount, PRUint32* aBytesRead);
     nsresult ReadDirectory(char* aBuf, PRUint32 aCount, PRUint32* aBytesRead);
     PRUint32 CopyDataToBuffer(char* &aBuffer, PRUint32 &aCount);
 };
 
 #endif /* nsJARINPUTSTREAM_h__ */
 
--- a/modules/libjar/nsZipArchive.cpp
+++ b/modules/libjar/nsZipArchive.cpp
@@ -21,16 +21,17 @@
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *   Daniel Veditz <dveditz@netscape.com>
  *   Samir Gehani <sgehani@netscape.com>
  *   Mitch Stoltz <mstoltz@netscape.com>
  *   Jeroen Dobbelaere <jeroen.dobbelaere@acunia.com>
  *   Jeff Walden <jwalden+code@mit.edu>
+ *   Taras Glek <tglek@mozilla.com>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
@@ -44,27 +45,29 @@
 /*
  * This module implements a simple archive extractor for the PKZIP format.
  *
  * The underlying nsZipArchive is NOT thread-safe. Do not pass references
  * or pointers to it across thread boundaries.
  */
 
 
-#include "nsWildCard.h"
-#include "nscore.h"
-#include "prmem.h"
-#include "prio.h"
-#include "plstr.h"
-#include "prlog.h"
 #define ZFILE_CREATE    PR_WRONLY | PR_CREATE_FILE
 #define READTYPE  PRInt32
 #include "zlib.h"
 #include "nsISupportsUtils.h"
 #include "nsRecyclingAllocator.h"
+#include "prio.h"
+#include "plstr.h"
+#include "prlog.h"
+#include "stdlib.h"
+#include "nsWildCard.h"
+#include "zipfile.h"
+#include "zipstruct.h"
+#include "nsZipArchive.h"
 
 /**
  * Globals
  *
  * Global allocator used with zlib. Destroyed in module shutdown.
  */
 #define NBUCKETS 6
 #define BY4ALLOC_ITEMS 320
@@ -200,35 +203,90 @@ nsresult gZlibInit(z_stream *zs)
     zs->opaque = gZlibAllocator;
   }
   int zerr = inflateInit2(zs, -MAX_WBITS);
   if (zerr != Z_OK) return ZIP_ERR_MEMORY;
 
   return ZIP_OK;
 }
 
+nsZipHandle::nsZipHandle()
+  : mFd(nsnull)
+  , mFileData(nsnull)
+  , mLen(0)
+  , mMap(nsnull)
+  , mRefCnt(0)
+{
+  MOZ_COUNT_CTOR(nsZipHandle);
+}
+
+NS_IMPL_THREADSAFE_ADDREF(nsZipHandle)
+NS_IMPL_THREADSAFE_RELEASE(nsZipHandle)
+
+nsresult nsZipHandle::Init(PRFileDesc *fd, nsZipHandle **ret)
+{
+  PRInt64 size = PR_Available64(fd);
+  if (size >= PR_INT32_MAX)
+    return NS_ERROR_FILE_TOO_BIG;
+
+  PRFileMap *map = PR_CreateFileMap(fd, size, PR_PROT_READONLY);
+
+  if (!map)
+    return NS_ERROR_FAILURE;
+
+  nsZipHandle *handle = new nsZipHandle();
+  if (!handle)
+    return NS_ERROR_OUT_OF_MEMORY;
+
+  handle->mFd = fd;
+  handle->mMap = map;
+  handle->mLen = (PRUint32) size;
+  handle->mFileData = (PRUint8*) PR_MemMap(map, 0, handle->mLen);
+  handle->AddRef();
+  *ret = handle;
+  return NS_OK;
+}
+
+PRInt32 nsZipHandle::Read(PRUint32 aPosition, void *aBuffer, PRUint32 aCount)
+{
+  if (mLen < 0 || aPosition+aCount > (PRUint32) mLen)
+    return -1;
+  PRInt32 count = PR_MIN(aCount, mLen - aPosition);
+  memcpy(aBuffer, mFileData + aPosition, count);
+  return count;
+}
+
+nsZipHandle::~nsZipHandle()
+{
+  if (mFd) {
+    PR_MemUnmap(mFileData, mLen);
+    PR_CloseFileMap(mMap);
+    PR_Close(mFd);
+    mFd = 0;
+  }
+  MOZ_COUNT_DTOR(nsZipHandle);
+}
+
 //***********************************************************
 //      nsZipArchive  --  public methods
 //***********************************************************
 
 
 //---------------------------------------------
 //  nsZipArchive::OpenArchive
 //---------------------------------------------
 nsresult nsZipArchive::OpenArchive(PRFileDesc * fd)
 {
-  if (!fd)
-    return ZIP_ERR_PARAM;
+  nsresult rv = nsZipHandle::Init(fd, getter_AddRefs(mFd));
+  if (NS_FAILED(rv))
+    return rv;
 
   // Initialize our arena
   PL_INIT_ARENA_POOL(&mArena, "ZipArena", ZIP_ARENABLOCKSIZE);
 
-  //-- Keep the filedescriptor for further reading...
-  mFd = fd;
-
   //-- get table of contents for archive
   return BuildFileList();
 }
 
 //---------------------------------------------
 //  nsZipArchive::Test
 //---------------------------------------------
 nsresult nsZipArchive::Test(const char *aEntryName)
@@ -274,21 +332,18 @@ nsresult nsZipArchive::CloseArchive()
   // We don't need to delete each of the nsZipItem as the memory for
   // the zip item and the filename it holds are both allocated from the Arena.
   // Hence, destroying the Arena is like destroying all the memory
   // for all the nsZipItem in one shot. But if the ~nsZipItem is doing
   // anything more than cleaning up memory, we should start calling it.
   // Let us also cleanup the mFiles table for re-use on the next 'open' call
   for (int i = 0; i < ZIP_TABSIZE; i++) {
     mFiles[i] = 0;
-  }  
-  if (mFd) {
-    PR_Close(mFd);
-    mFd = 0;
   }
+  mFd = NULL;
   mBuiltSynthetics = PR_FALSE;
   return ZIP_OK;
 }
 
 //---------------------------------------------
 // nsZipArchive::GetItem
 //---------------------------------------------
 nsZipItem*  nsZipArchive::GetItem(const char * aEntryName)
@@ -329,30 +384,34 @@ nsresult nsZipArchive::ExtractFile(nsZip
   if (!mFd)
     return ZIP_ERR_GENERAL;
 
   // Directory extraction is handled in nsJAR::Extract,
   // so the item to be extracted should never be a directory
   PR_ASSERT(!item->isDirectory);
 
   //-- move to the start of file's data
-  if (SeekToItem(item, mFd) != ZIP_OK)
+  if (!MaybeReadItem(item))
+    return ZIP_ERR_CORRUPT;
+
+  nsSeekableZipHandle fd;
+  if (!fd.Open(mFd.get(), item->dataOffset, item->size))
     return ZIP_ERR_CORRUPT;
 
   nsresult rv;
 
   //-- extract the file using the appropriate method
   switch(item->compression)
   {
     case STORED:
-      rv = CopyItemToDisk(item->size, item->crc32, aFd);
+      rv = CopyItemToDisk(item->size, item->crc32, fd, aFd);
       break;
 
     case DEFLATED:
-      rv = InflateItem(item, aFd);
+      rv = InflateItem(item, fd, aFd);
       break;
 
     default:
       //-- unsupported compression type
       rv = ZIP_ERR_UNSUPPORTED;
   }
 
   //-- delete the file on errors, or resolve symlink if needed
@@ -504,74 +563,64 @@ nsZipItem* nsZipArchive::CreateZipItem(P
   return (nsZipItem*)mem;
 }
 
 //---------------------------------------------
 //  nsZipArchive::BuildFileList
 //---------------------------------------------
 nsresult nsZipArchive::BuildFileList()
 {
-  PRUint8   buf[4*BR_BUF_SIZE];
-
+  PRUint8   *buf;
   //-----------------------------------------------------------------------
   // locate the central directory via the End record
   //-----------------------------------------------------------------------
 
   //-- get archive size using end pos
-  PRInt32  pos = PR_Seek(mFd, 0, PR_SEEK_END);
-  if (pos <= 0)
-    return ZIP_ERR_CORRUPT;
+  PRInt32  pos = (PRInt32) mFd->mLen;
 
-  PRBool bEndsigFound = PR_FALSE;
-  while (!bEndsigFound)
+  PRInt32 central = -1;
+  while (central == -1)
   {
     //-- read backwards in 1K-sized chunks (unless file is less than 1K)
     PRInt32  bufsize = pos > BR_BUF_SIZE ? BR_BUF_SIZE : pos;
     pos -= bufsize;
 
-    if (!ZIP_Seek(mFd, pos, PR_SEEK_SET))
-      return ZIP_ERR_CORRUPT;
-
-    if (PR_Read(mFd, buf, bufsize) != (READTYPE)bufsize)
-      return ZIP_ERR_CORRUPT;
+    buf = mFd->mFileData + pos;
 
     //-- scan for ENDSIG
     PRUint8 *endp = buf + bufsize;
     for (endp -= ZIPEND_SIZE; endp >= buf; endp--)
     {
       if (xtolong(endp) == ENDSIG)
       { 
         //-- Seek to start of central directory
-        PRInt32 central = xtolong(((ZipEnd *) endp)->offset_central_dir);
-        if (!ZIP_Seek(mFd, central, PR_SEEK_SET))
-          return ZIP_ERR_CORRUPT;
-
-        bEndsigFound = PR_TRUE;
+        central = xtolong(((ZipEnd *) endp)->offset_central_dir);
         break;
       }
     }
 
-    if (bEndsigFound)
+    if (central != -1)
       break;
 
     if (pos <= 0)
       //-- We're at the beginning of the file, and still no sign
       //-- of the end signature.  File must be corrupted!
       return ZIP_ERR_CORRUPT;
 
     //-- backward read must overlap ZipEnd length
     pos += ZIPEND_SIZE;
 
   } /* while looking for end signature */
 
 
   //-------------------------------------------------------
   // read the central directory headers
   //-------------------------------------------------------
-  PRInt32 byteCount = PR_Read(mFd, &buf, sizeof(buf));
+  PRInt32 byteCount = mFd->mLen - central;
+  buf = mFd->mFileData + central;
   pos = 0;
   PRUint32 sig = xtolong(buf);
   while (sig == CENTRALSIG) {
     //-- make sure we've read enough
     if (byteCount - pos < ZIPCENTRAL_SIZE)
       return ZIP_ERR_CORRUPT;
 
     //-------------------------------------------------------
@@ -608,41 +657,21 @@ nsresult nsZipArchive::BuildFileList()
 
     item->mode = ExtractMode(central->external_attributes);
 #if defined(XP_UNIX) || defined(XP_BEOS)
     // Check if item is a symlink
     item->isSymlink = IsSymlink(central->external_attributes);
 #endif
 
     pos += ZIPCENTRAL_SIZE;
-
-    //-------------------------------------------------------
-    // Make sure that remainder of this record (name, comments, extra)
-    // and the next ZipCentral is all in the buffer
-    //-------------------------------------------------------
-    PRInt32 leftover = byteCount - pos;
-    if (leftover < (namelen + extralen + commentlen + ZIPCENTRAL_SIZE)) {
-      //-- not enough data left to process at top of loop.
-      //-- move leftover and read more
-      memcpy(buf, buf+pos, leftover);
-      byteCount = leftover + PR_Read(mFd, buf+leftover, sizeof(buf)-leftover);
-      pos = 0;
-
-      if (byteCount < (namelen + extralen + commentlen + sizeof(sig))) {
-        // truncated file
-        return ZIP_ERR_CORRUPT;
-      }
-    }
-
     //-------------------------------------------------------
     // get the item name
     //-------------------------------------------------------
     memcpy(item->name, buf+pos, namelen);
     item->name[namelen] = 0;
-
     //-- an item whose name ends with '/' is a directory
     item->isDirectory = ('/' == item->name[namelen - 1]);
 
     //-- add item to file table
     //-- note that an explicit entry for a directory will override
     //-- a fake entry created for that directory (as in the case
     //-- of processing foo/bar.txt and then foo/) -- this will
     //-- preserve an explicit directory's metadata at the cost of
@@ -753,63 +782,66 @@ nsresult nsZipArchive::BuildSynthetics()
         diritem->next = mFiles[hash];
         mFiles[hash] = diritem;
       } /* end processing of dirs in item's name */
     }
   }
   return ZIP_OK;
 }
 
+nsZipHandle* nsZipArchive::GetFD(nsZipItem* aItem)
+{
+  if (!mFd || !MaybeReadItem(aItem))
+    return NULL;
+  return mFd.get();
+}
 
 //---------------------------------------------
-// nsZipArchive::SeekToItem
+// nsZipArchive::MaybeReadItem
 //---------------------------------------------
-nsresult  nsZipArchive::SeekToItem(nsZipItem* aItem, PRFileDesc* aFd)
+bool nsZipArchive::MaybeReadItem(nsZipItem* aItem)
 {
   PR_ASSERT (aItem);
 
   //-- the first time an item is used we need to calculate its offset
   if (!aItem->hasDataOffset)
   {
     //-- read local header to get variable length values and calculate
     //-- the real data offset
     //--
     //-- NOTE: extralen is different in central header and local header
     //--       for archives created using the Unix "zip" utility. To set
     //--       the offset accurately we need the _local_ extralen.
-    if (!ZIP_Seek(aFd, aItem->headerOffset, PR_SEEK_SET))
-      return ZIP_ERR_CORRUPT;
+    if (!mFd || !mFd->mLen > aItem->headerOffset + ZIPLOCAL_SIZE)
+      return false;
 
-    ZipLocal   Local;
-    if ((PR_Read(aFd, (char*)&Local, ZIPLOCAL_SIZE) != (READTYPE) ZIPLOCAL_SIZE) || 
-        (xtolong(Local.signature) != LOCALSIG))
+    ZipLocal   *Local =     (ZipLocal*)(mFd->mFileData + aItem->headerOffset);
+    //check limits here
+    if ((xtolong(Local->signature) != LOCALSIG))
     {
       //-- read error or local header not found
-      return ZIP_ERR_CORRUPT;
+      return false;
     }
 
     aItem->dataOffset = aItem->headerOffset +
                         ZIPLOCAL_SIZE +
-                        xtoint(Local.filename_len) +
-                        xtoint(Local.extrafield_len);
+                        xtoint(Local->filename_len) +
+                        xtoint(Local->extrafield_len);
     aItem->hasDataOffset = PR_TRUE;
   }
 
-  //-- move to start of file in archive
-  if (!ZIP_Seek(aFd, aItem->dataOffset, PR_SEEK_SET))
-    return  ZIP_ERR_CORRUPT;
-
-  return ZIP_OK;
+  return true;
 }
 
 //---------------------------------------------
 // nsZipArchive::CopyItemToDisk
 //---------------------------------------------
 nsresult
-nsZipArchive::CopyItemToDisk(PRUint32 itemSize, PRUint32 itemCrc, PRFileDesc* outFD)
+nsZipArchive::CopyItemToDisk(PRUint32 itemSize, PRUint32 itemCrc, 
+                             nsSeekableZipHandle &fd, PRFileDesc* outFD)
 /*
  * This function copies an archive item to disk, to the
  * file specified by outFD. If outFD is zero, the extracted data is
  * not written, only checked for CRC, so this is in effect same as 'Test'.
  */
 {
   PRUint32    chunk, pos, crc;
   char buf[ZIP_BUFLEN];
@@ -817,17 +849,17 @@ nsZipArchive::CopyItemToDisk(PRUint32 it
   //-- initialize crc
   crc = crc32(0L, Z_NULL, 0);
 
   //-- copy chunks until file is done
   for (pos = 0; pos < itemSize; pos += chunk)
   {
     chunk = (itemSize - pos < ZIP_BUFLEN) ? (itemSize - pos) : ZIP_BUFLEN;
     
-    if (PR_Read(mFd, buf, chunk) != (READTYPE)chunk)
+    if (fd.Read(buf, chunk) != (READTYPE)chunk)
     {
       //-- unexpected end of data in archive
       return ZIP_ERR_CORRUPT;
     }
 
     //-- incrementally update crc32
     crc = crc32(crc, (const unsigned char*)buf, chunk);
 
@@ -844,17 +876,17 @@ nsZipArchive::CopyItemToDisk(PRUint32 it
 
   return ZIP_OK;
 }
 
 
 //---------------------------------------------
 // nsZipArchive::InflateItem
 //---------------------------------------------
-nsresult nsZipArchive::InflateItem(const nsZipItem* aItem, PRFileDesc* outFD)
+nsresult nsZipArchive::InflateItem(const nsZipItem* aItem, nsSeekableZipHandle &fd, PRFileDesc* outFD)
 /*
  * This function inflates an archive item to disk, to the
  * file specified by outFD. If outFD is zero, the extracted data is
  * not written, only checked for CRC, so this is in effect same as 'Test'.
  */
 {
   PR_ASSERT(aItem);
 
@@ -882,17 +914,17 @@ nsresult nsZipArchive::InflateItem(const
     PRBool      bWrote= PR_FALSE;
 
     if (zs.avail_in == 0 && zs.total_in < size)
     {
       //-- no data to inflate yet still more in file:
       //-- read another chunk of compressed data
       PRUint32 chunk = (size-zs.total_in < ZIP_BUFLEN) ? size-zs.total_in : ZIP_BUFLEN;
 
-      if (PR_Read(mFd, inbuf, chunk) != (READTYPE)chunk)
+      if (fd.Read(inbuf, chunk) != (READTYPE)chunk)
       {
         //-- unexpected end of data
         status = ZIP_ERR_CORRUPT;
         break;
       }
 
       zs.next_in  = inbuf;
       zs.avail_in = chunk;
@@ -961,18 +993,17 @@ cleanup:
   return status;
 }
 
 //------------------------------------------
 // nsZipArchive constructor and destructor
 //------------------------------------------
 
 nsZipArchive::nsZipArchive() :
-    mFd(0),
-    mBuiltSynthetics(PR_FALSE)
+  mBuiltSynthetics(PR_FALSE)
 {
   MOZ_COUNT_CTOR(nsZipArchive);
 
   // initialize the table to NULL
   memset(mFiles, 0, sizeof mFiles);
 }
 
 nsZipArchive::~nsZipArchive()
@@ -1070,9 +1101,8 @@ static PRUint16 ExtractMode(unsigned cha
  *
  */
 
 static PRBool IsSymlink(unsigned char *ll)
 {
   return ((xtoint(ll+2) & S_IFMT) == S_IFLNK);
 }
 #endif
-
--- a/modules/libjar/nsZipArchive.h
+++ b/modules/libjar/nsZipArchive.h
@@ -19,16 +19,17 @@
  * Netscape Communications Corporation.
  * Portions created by the Initial Developer are Copyright (C) 1998-1999
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *   Daniel Veditz <dveditz@netscape.com>
  *   Samir Gehani <sgehani@netscape.com>
  *   Mitch Stoltz <mstoltz@netscape.com>
+ *   Taras Glek <tglek@mozilla.com>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
@@ -48,16 +49,17 @@
 // Keep this odd. The -1 is significant.
 #define ZIP_BUFLEN    (4 * 1024 - 1)
 
 #define PL_ARENA_CONST_ALIGN_MASK 7
 #include "plarena.h"
 #define ZIP_Seek(fd,p,m) (PR_Seek((fd),((PROffset32)p),(m))==((PROffset32)p))
 
 #include "zlib.h"
+#include "nsAutoPtr.h"
 
 class nsZipFind;
 class nsZipReadState;
 class nsZipItemMetadata;
 
 struct PRFileDesc;
 
 /**
@@ -106,16 +108,18 @@ struct nsZipItem
                                     and no foo/ entry is synthetic */
 #if defined(XP_UNIX) || defined(XP_BEOS)
   PRPackedBool isSymlink : 1;
 #endif
 
   char        name[1]; // actually, bigger than 1
 };
 
+class nsZipHandle;
+class nsSeekableZipHandle;
 /** 
  * nsZipArchive -- a class for reading the PKZIP file format.
  *
  */
 class nsZipArchive 
 {
   friend class nsZipFind;
 
@@ -181,46 +185,134 @@ public:
    *                      (may be NULL to find all files in archive)
    * @param   aFind       a pointer to a pointer to a structure used
    *                      in FindNext.  In the case of an error this
    *                      will be set to NULL.
    * @return  status code
    */
   PRInt32 FindInit(const char * aPattern, nsZipFind** aFind);
 
-  /**
-   * Moves the filepointer aFd to the start of data of the aItem.
-   * @param   aItem       Pointer to nsZipItem
-   * @param   aFd         The filepointer to move
+  /* Gets an undependent handle to the jar
+   * Also ensures that aItem is fully filled
    */
-  nsresult  SeekToItem(nsZipItem* aItem, PRFileDesc* aFd);
+  nsZipHandle* GetFD(nsZipItem* aItem);
 
 private:
   //--- private members ---
 
   nsZipItem*    mFiles[ZIP_TABSIZE];
   PLArenaPool   mArena;
 
-  // Used for central directory reading, and for Test and Extract
-  PRFileDesc    *mFd;
+  /**
+   * Fills in nsZipItem fields that were not filled in by BuildFileList
+   * @param   aItem       Pointer to nsZipItem
+   * returns true if the item was filled in successfully
+   */
+  bool MaybeReadItem(nsZipItem* aItem);
 
   // Whether we synthesized the directory entries
   PRPackedBool  mBuiltSynthetics;
 
+  // file handle
+  nsRefPtr<nsZipHandle> mFd;
   //--- private methods ---
   
   nsZipArchive& operator=(const nsZipArchive& rhs); // prevent assignments
   nsZipArchive(const nsZipArchive& rhs);            // prevent copies
 
   nsZipItem*        CreateZipItem(PRUint16 namelen);
   nsresult          BuildFileList();
   nsresult          BuildSynthetics();
 
-  nsresult  CopyItemToDisk(PRUint32 size, PRUint32 crc, PRFileDesc* outFD);
-  nsresult  InflateItem(const nsZipItem* aItem, PRFileDesc* outFD);
+  nsresult  CopyItemToDisk(PRUint32 size, PRUint32 crc, nsSeekableZipHandle &fd, PRFileDesc* outFD);
+  nsresult  InflateItem(const nsZipItem* aItem, nsSeekableZipHandle &fd, PRFileDesc* outFD);
+};
+
+class nsZipHandle {
+friend class nsZipArchive;
+friend class nsSeekableZipHandle;
+public:
+  static nsresult Init(PRFileDesc *fd, nsZipHandle **ret NS_OUTPARAM);
+
+  /**
+   * Reads data at a certain point
+   * @param aPosition seek ofset
+   * @param aBuffer buffer
+   * @param aCount number of bytes to read */
+  PRInt32 Read(PRUint32 aPosition, void *aBuffer, PRUint32 aCount);
+
+  NS_METHOD_(nsrefcnt) AddRef(void);
+  NS_METHOD_(nsrefcnt) Release(void);
+
+protected:
+  PRFileDesc *mFd; // OS file-descriptor
+  PRUint8 *mFileData; // pointer to mmaped file
+  PRUint32 mLen; // length of file and memory mapped area
+
+private:
+  nsZipHandle();
+  ~nsZipHandle();
+
+  PRFileMap *mMap; // nspr datastructure for mmap
+  nsrefcnt mRefCnt; // ref count
+};
+
+
+/** nsSeekableZipHandle acts as a container for nsZipHandle,
+    emulates sequential file io */
+class nsSeekableZipHandle {
+  //   stick nsZipItem in here
+public:
+  nsSeekableZipHandle()
+    : mOffset(0)
+    , mRemaining(0)
+  {
+  }
+
+  /** Initializes nsSeekableZipHandle with
+   * @param aOffset byte offset of the file to start reading at
+   * @param length of this descriptor
+   */
+  bool Open(nsZipHandle *aHandle, PRUint32 aOffset, PRUint32 aLength) {
+    NS_ABORT_IF_FALSE (aHandle, "Argument must not be NULL");
+    if (aOffset > aHandle->mLen)
+      return false;
+    mFd = aHandle;
+    mOffset = aOffset;
+    mRemaining = aLength;
+    return true;
+  }
+
+  /** Releases the file handle. It is safe to call multiple times. */
+  void Close()
+  {
+    mFd = NULL;
+  }
+
+  /**
+   * Reads data at a certain point
+   * @param aBuffer input buffer
+   * @param aCount number of bytes to read */
+  PRInt32 Read(void *aBuffer, PRUint32 aCount)
+  {
+    if (!mFd.get())
+      return -1;
+    aCount = PR_MIN(mRemaining, aCount);
+    PRInt32 ret = mFd->Read(mOffset, aBuffer, aCount);
+    if (ret > 0) {
+      mOffset += ret;
+      mRemaining -= ret;
+    }
+    return ret;
+  }
+
+private:
+  nsRefPtr<nsZipHandle> mFd; // file handle
+  PRUint32 mOffset; // current reading offset
+  PRUint32 mRemaining; // bytes remaining
 };
 
 
 /** 
  * nsZipFind 
  *
  * a helper class for nsZipArchive, representing a search
  */
new file mode 100644
--- /dev/null
+++ b/modules/libjar/test/unit/test_jarinput_stream_zipreader_reference.js
@@ -0,0 +1,72 @@
+/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Taras Glek <tglek@mozilla.com>
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+function wrapInputStream(input)
+{
+  var nsIScriptableInputStream = Components.interfaces.nsIScriptableInputStream;
+  var factory = Components.classes["@mozilla.org/scriptableinputstream;1"];
+  var wrapper = factory.createInstance(nsIScriptableInputStream);
+  wrapper.init(input);
+  return wrapper;
+}
+
+// Check that files can be read from after closing zipreader
+function run_test() {
+  const Cc = Components.classes;
+  const Ci = Components.interfaces;
+
+  // the build script have created the zip we can test on in the current dir.
+  var file = do_get_file("data/test_bug333423.zip");
+
+  var zipreader = Cc["@mozilla.org/libjar/zip-reader;1"].
+                  createInstance(Ci.nsIZipReader);
+  zipreader.open(file);
+  // do crc stuff
+  function check_archive_crc() {
+    zipreader.test(null);
+    return true;
+  }
+  do_check_true(check_archive_crc())
+  var entries = zipreader.findEntries(null);
+  var stream = wrapInputStream(zipreader.getInputStream("modules/libjar/test/Makefile.in"))
+  var dirstream= wrapInputStream(zipreader.getInputStream("modules/libjar/test/"))
+  zipreader.close();
+  zipreader = null;
+  Components.utils.forceGC();
+  do_check_true(stream.read(1024).length > 0);
+  do_check_true(dirstream.read(100).length > 0);
+}
+
--- a/modules/libpr0n/src/imgLoader.cpp
+++ b/modules/libpr0n/src/imgLoader.cpp
@@ -44,16 +44,17 @@
 
 #include "nsNetUtil.h"
 #include "nsIHttpChannel.h"
 #include "nsICachingChannel.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIPrefBranch2.h"
 #include "nsIPrefService.h"
 #include "nsIProgressEventSink.h"
+#include "nsIChannelEventSink.h"
 #include "nsIProxyObjectManager.h"
 #include "nsIServiceManager.h"
 #include "nsIFileURL.h"
 #include "nsThreadUtils.h"
 #include "nsXPIDLString.h"
 #include "nsCRT.h"
 
 #include "netCore.h"
@@ -113,38 +114,41 @@ static void PrintImageDecoders()
 
 /**
  * A class that implements nsIProgressEventSink and forwards all calls to it to
  * the original notification callbacks of the channel. Also implements
  * nsIInterfaceRequestor and gives out itself for nsIProgressEventSink calls,
  * and forwards everything else to the channel's notification callbacks.
  */
 class nsProgressNotificationProxy : public nsIProgressEventSink
+                                  , public nsIChannelEventSink
                                   , public nsIInterfaceRequestor
 {
   public:
     nsProgressNotificationProxy(nsIChannel* channel,
                                 imgIRequest* proxy)
         : mChannel(channel), mImageRequest(proxy) {
       channel->GetNotificationCallbacks(getter_AddRefs(mOriginalCallbacks));
     }
 
     NS_DECL_ISUPPORTS
     NS_DECL_NSIPROGRESSEVENTSINK
+    NS_DECL_NSICHANNELEVENTSINK
     NS_DECL_NSIINTERFACEREQUESTOR
   private:
     ~nsProgressNotificationProxy() {}
 
     nsCOMPtr<nsIChannel> mChannel;
     nsCOMPtr<nsIInterfaceRequestor> mOriginalCallbacks;
     nsCOMPtr<nsIRequest> mImageRequest;
 };
 
-NS_IMPL_ISUPPORTS2(nsProgressNotificationProxy,
+NS_IMPL_ISUPPORTS3(nsProgressNotificationProxy,
                      nsIProgressEventSink,
+                     nsIChannelEventSink,
                      nsIInterfaceRequestor)
 
 NS_IMETHODIMP
 nsProgressNotificationProxy::OnProgress(nsIRequest* request,
                                         nsISupports* ctxt,
                                         PRUint64 progress,
                                         PRUint64 progressMax) {
   nsCOMPtr<nsILoadGroup> loadGroup;
@@ -174,23 +178,52 @@ nsProgressNotificationProxy::OnStatus(ns
                                 NS_GET_IID(nsIProgressEventSink),
                                 getter_AddRefs(target));
   if (!target)
     return NS_OK;
   return target->OnStatus(mImageRequest, ctxt, status, statusArg);
 }
 
 NS_IMETHODIMP
+nsProgressNotificationProxy::OnChannelRedirect(nsIChannel *oldChannel,
+                                               nsIChannel *newChannel,
+                                               PRUint32 flags) {
+  // The 'old' channel should match the current one
+  NS_ABORT_IF_FALSE(oldChannel == mChannel,
+                    "old channel doesn't match current!");
+
+  // Save the new channel
+  mChannel = newChannel;
+
+  // Tell the original original callbacks about it too
+  nsCOMPtr<nsILoadGroup> loadGroup;
+  mChannel->GetLoadGroup(getter_AddRefs(loadGroup));
+  nsCOMPtr<nsIChannelEventSink> target;
+  NS_QueryNotificationCallbacks(mOriginalCallbacks,
+                                loadGroup,
+                                NS_GET_IID(nsIChannelEventSink),
+                                getter_AddRefs(target));
+  if (!target)
+    return NS_OK;
+  return target->OnChannelRedirect(oldChannel, newChannel, flags);
+}
+
+NS_IMETHODIMP
 nsProgressNotificationProxy::GetInterface(const nsIID& iid,
                                           void** result) {
   if (iid.Equals(NS_GET_IID(nsIProgressEventSink))) {
     *result = static_cast<nsIProgressEventSink*>(this);
     NS_ADDREF_THIS();
     return NS_OK;
   }
+  if (iid.Equals(NS_GET_IID(nsIChannelEventSink))) {
+    *result = static_cast<nsIChannelEventSink*>(this);
+    NS_ADDREF_THIS();
+    return NS_OK;
+  }
   if (mOriginalCallbacks)
     return mOriginalCallbacks->GetInterface(iid, result);
   return NS_NOINTERFACE;
 }
 
 static PRBool NewRequestAndEntry(nsIURI *uri, imgRequest **request, imgCacheEntry **entry)
 {
   // If file, force revalidation on expiration
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..3ebefac7323ac89e167af92c1f70f35924b3bcb3
GIT binary patch
literal 3226
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
EFNbyV(f|Me
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..1d8efc687addc1baef1863205e335fc257e499df
GIT binary patch
literal 2738
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
--- a/modules/libpr0n/test/reftest/jpeg/reftest.list
+++ b/modules/libpr0n/test/reftest/jpeg/reftest.list
@@ -18,8 +18,9 @@ fails-if(MOZ_WIDGET_TOOLKIT=="windows") 
 fails-if(MOZ_WIDGET_TOOLKIT=="windows") == jpg-size-33x33.jpg jpg-size-33x33.png
 # Progressive encoding
 fails-if(MOZ_WIDGET_TOOLKIT=="windows") == jpg-progressive.jpg jpg-progressive.png
 # Grayscale colorspace
 fails-if(MOZ_WIDGET_TOOLKIT=="windows") == jpg-gray.jpg jpg-gray.png
 # CMYK colorspace
 fails-if(MOZ_WIDGET_TOOLKIT=="windows") == jpg-cmyk-1.jpg jpg-cmyk-1.png
 fails-if(MOZ_WIDGET_TOOLKIT=="windows") == jpg-cmyk-2.jpg jpg-cmyk-2.png
+== jpg-srgb-icc.jpg jpg-srgb-icc.png
--- a/modules/plugin/base/src/nsNPAPIPlugin.cpp
+++ b/modules/plugin/base/src/nsNPAPIPlugin.cpp
@@ -503,41 +503,49 @@ nsNPAPIPlugin::CreatePlugin(const char* 
   }
 
   if (!NS_SUCCEEDED(rv)) {
     return NS_ERROR_UNEXPECTED;
   }
 #endif
 
 #if defined(XP_MACOSX)
+#ifndef __LP64__
   short appRefNum = ::CurResFile();
   short pluginRefNum;
+#endif
 
   nsCOMPtr<nsILocalFile> pluginPath;
   NS_NewNativeLocalFile(nsDependentCString(aFilePath), PR_TRUE,
                         getter_AddRefs(pluginPath));
-
   nsPluginFile pluginFile(pluginPath);
+
+#ifndef __LP64__
   pluginRefNum = pluginFile.OpenPluginResource();
+#endif
 
   nsNPAPIPlugin* plugin = new nsNPAPIPlugin(nsnull, aLibrary, nsnull);
+#ifndef __LP64__
   ::UseResFile(appRefNum);
+#endif
   if (!plugin)
     return NS_ERROR_OUT_OF_MEMORY;
 
   *aResult = plugin;
 
   NS_ADDREF(*aResult);
   if (NS_FAILED((*aResult)->Initialize())) {
     NS_RELEASE(*aResult);
     return NS_ERROR_FAILURE;
   }
 
+#ifndef __LP64__
   plugin->SetPluginRefNum(pluginRefNum);
 #endif
+#endif
 
 #ifdef XP_BEOS
   // I just copied UNIX version.
   // Makoto Hamanaka <VYA04230@nifty.com>
 
   nsNPAPIPlugin *plptr;
 
   NPPluginFuncs callbacks;
@@ -694,17 +702,17 @@ MakeNewNPAPIStreamInternal(NPP npp, cons
   case eNPPStreamTypeInternal_Post:
     {
       if (NS_FAILED(pluginHost->PostURL(inst, relativeURL, len, buf, file, target,
                                 listener)))
         return NPERR_GENERIC_ERROR;
       break;
     }
   default:
-    NS_ASSERTION(0, "how'd I get here");
+    NS_ERROR("how'd I get here");
   }
 
   return NPERR_NO_ERROR;
 }
 
 //
 // Static callbacks that get routed back through the new C++ API
 //
@@ -2105,18 +2113,17 @@ NPError NP_CALLBACK
     case NPPVpluginWantsAllNetworkStreams: {
       PRBool bWantsAllNetworkStreams = (result != nsnull);
       return inst->SetWantsAllNetworkStreams(bWantsAllNetworkStreams);
     }
 
 #ifdef XP_MACOSX
     case NPPVpluginDrawingModel: {
       if (inst) {
-        int dModelValue = (int)result;
-        inst->SetDrawingModel((NPDrawingModel)dModelValue);
+        inst->SetDrawingModel((NPDrawingModel)NS_PTR_TO_INT32(result));
         return NPERR_NO_ERROR;
       }
       else {
         return NPERR_GENERIC_ERROR;
       }
     }
 #endif
 
--- a/modules/plugin/base/src/nsPluginsDirDarwin.cpp
+++ b/modules/plugin/base/src/nsPluginsDirDarwin.cpp
@@ -300,16 +300,17 @@ static char* p2cstrdup(StringPtr pstr)
 
 static char* GetNextPluginStringFromHandle(Handle h, short *index)
 {
   char *ret = p2cstrdup((unsigned char*)(*h + *index));
   *index += (ret ? PL_strlen(ret) : 0) + 1;
   return ret;
 }
 
+#ifndef __LP64__
 static char* GetPluginString(short id, short index)
 {
   Str255 str;
   ::GetIndString(str, id, index);
   return p2cstrdup(str);
 }
 
 // Opens the resource fork for the plugin
@@ -354,32 +355,36 @@ public:
   }
   PRBool ResourceOpened()
   {
     return (mRefNum > 0);
   }
 private:
   short mRefNum;
 };
+#endif
 
 /**
  * Obtains all of the information currently available for this plugin.
  */
 nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info)
 {
   nsresult rv = NS_OK;
 
   // clear out the info, except for the first field.
   memset(&info, 0, sizeof(info));
 
   // First open up resource we can use to get plugin info.
 
+#ifndef __LP64__
   // Try to open a resource fork.
   nsAutoCloseResourceObject resourceObject(mPlugin);
   bool resourceOpened = resourceObject.ResourceOpened();
+#endif
+
   // Try to get a bundle reference.
   nsCAutoString path;
   if (NS_FAILED(rv = mPlugin->GetNativePath(path)))
     return rv;
   CFBundleRef bundle = getPluginBundle(path.get());
 
   // fill in full path
   info.fFullPath = PL_strdup(path.get());
@@ -395,31 +400,35 @@ nsresult nsPluginFile::GetPluginInfo(nsP
     info.fBundle = PR_TRUE;
 
   // Get fName
   if (bundle) {
     CFTypeRef name = ::CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("WebPluginName"));
     if (name && ::CFGetTypeID(name) == ::CFStringGetTypeID())
       info.fName = CFStringRefToUTF8Buffer(static_cast<CFStringRef>(name));
   }
+#ifndef __LP64__
   if (!info.fName && resourceOpened) {
     // 'STR#', 126, 2 => plugin name.
     info.fName = GetPluginString(126, 2);
   }
+#endif
 
   // Get fDescription
   if (bundle) {
     CFTypeRef description = ::CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("WebPluginDescription"));
     if (description && ::CFGetTypeID(description) == ::CFStringGetTypeID())
       info.fDescription = CFStringRefToUTF8Buffer(static_cast<CFStringRef>(description));
   }
+#ifndef __LP64__
   if (!info.fDescription && resourceOpened) {
     // 'STR#', 126, 1 => plugin description.
     info.fDescription = GetPluginString(126, 1);
   }
+#endif
 
   // Get fVersion
   if (bundle) {
     // Look for the release version first
     CFTypeRef version = ::CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("CFBundleShortVersionString"));
     if (!version) // try the build version
       version = ::CFBundleGetValueForInfoDictionaryKey(bundle, kCFBundleVersionKey);
     if (version && ::CFGetTypeID(version) == ::CFStringGetTypeID())
@@ -460,16 +469,17 @@ nsresult nsPluginFile::GetPluginInfo(nsP
     if (pfnMime && noErr == pfnMime(&mi, 0) && mi.typeStrings) {
       info.fVariantCount = (**(short**)mi.typeStrings) / 2;
       ::HLock(mi.typeStrings);
       if (mi.infoStrings)  // it's possible some plugins have infoStrings missing
         ::HLock(mi.infoStrings);
     }
   }
 
+#ifndef __LP64__
   // Try to get data from the resource fork
   if (!info.fVariantCount && resourceObject.ResourceOpened()) {
     mi.typeStrings = ::Get1Resource('STR#', 128);
     if (mi.typeStrings) {
       info.fVariantCount = (**(short**)mi.typeStrings) / 2;
       ::DetachResource(mi.typeStrings);
       ::HLock(mi.typeStrings);
     } else {
@@ -478,16 +488,17 @@ nsresult nsPluginFile::GetPluginInfo(nsP
     }
     
     mi.infoStrings = ::Get1Resource('STR#', 127);
     if (mi.infoStrings) {
       ::DetachResource(mi.infoStrings);
       ::HLock(mi.infoStrings);
     }
   }
+#endif
 
   // Fill in the info struct based on the data in the BPSupportedMIMETypes struct
   int variantCount = info.fVariantCount;
   info.fMimeTypeArray = static_cast<char**>(NS_Alloc(variantCount * sizeof(char*)));
   if (!info.fMimeTypeArray)
     return NS_ERROR_OUT_OF_MEMORY;
   info.fExtensionArray = static_cast<char**>(NS_Alloc(variantCount * sizeof(char*)));
   if (!info.fExtensionArray)
--- a/netwerk/protocol/http/src/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/src/nsHttpChannel.cpp
@@ -1274,18 +1274,25 @@ nsHttpChannel::DoReplaceWithProxy(nsIPro
     newChannel->SetOriginalURI(mOriginalURI);
 
     // open new channel
     rv = newChannel->AsyncOpen(mListener, mListenerContext);
     if (NS_FAILED(rv))
         return rv;
 
     mStatus = NS_BINDING_REDIRECTED;
+
+    // disconnect from the old listeners...
     mListener = nsnull;
     mListenerContext = nsnull;
+
+    // ...and the old callbacks
+    mCallbacks = nsnull;
+    mProgressSink = nsnull;
+
     return rv;
 }
 
 nsresult
 nsHttpChannel::ResolveProxy()
 {
     LOG(("nsHttpChannel::ResolveProxy [this=%x]\n", this));
 
new file mode 100644
--- /dev/null
+++ b/parser/html/javasrc/README.txt
@@ -0,0 +1,6 @@
+The .java files in this directory were placed here by the Java-to-C++
+translator that lives in parser/html/java/translator.  Together they represent
+a snapshot of the Java code that was translated to produce the corresponding
+.h and .cpp files in the parent directory.  Changing these .java files is not
+worthwhile, as they will just be overwritten by the next translation.  See
+parser/html/java/README.txt for information about performing the translation.
--- a/parser/html/nsHtml5TreeOperation.cpp
+++ b/parser/html/nsHtml5TreeOperation.cpp
@@ -34,19 +34,24 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsHtml5TreeOperation.h"
+#include "nsContentUtils.h"
 #include "nsNodeUtils.h"
 #include "nsAttrName.h"
 #include "nsHtml5TreeBuilder.h"
+#include "nsIDOMMutationEvent.h"
+#include "mozAutoDocUpdate.h"
+#include "nsBindingManager.h"
+#include "nsXBLBinding.h"
 
 nsHtml5TreeOperation::nsHtml5TreeOperation()
  : mOpCode(eTreeOpAppend)
 {
   MOZ_COUNT_CTOR(nsHtml5TreeOperation);
 }
 
 nsHtml5TreeOperation::~nsHtml5TreeOperation()
@@ -112,26 +117,58 @@ nsHtml5TreeOperation::Perform(nsHtml5Tre
       PRUint32 childCount = doc->GetChildCount();
       rv = doc->AppendChildTo(mNode, PR_FALSE);
       NS_ENSURE_SUCCESS(rv, rv);
       nsNodeUtils::ContentInserted(doc, mNode, childCount);
       return rv;
     }
     case eTreeOpAddAttributes: {
       // mNode holds the new attributes and mParent is the target
+      nsIDocument* document = mParent->GetCurrentDoc();
+      
       PRUint32 len = mNode->GetAttrCount();
       for (PRUint32 i = 0; i < len; ++i) {
         const nsAttrName* attrName = mNode->GetAttrNameAt(i);
         nsIAtom* localName = attrName->LocalName();
         PRInt32 nsuri = attrName->NamespaceID();
         if (!mParent->HasAttr(nsuri, localName)) {
           nsAutoString value;
           mNode->GetAttr(nsuri, localName, value);
-          mParent->SetAttr(nsuri, localName, attrName->GetPrefix(), value, PR_TRUE);
-          // XXX should not fire mutation event here
+          
+          // the manual notification code is based on nsGenericElement
+          
+          PRUint32 stateMask = PRUint32(mParent->IntrinsicState());
+          nsNodeUtils::AttributeWillChange(mParent, 
+                                           nsuri,
+                                           localName,
+                                           static_cast<PRUint8>(nsIDOMMutationEvent::ADDITION));
+          
+          mParent->SetAttr(nsuri, localName, attrName->GetPrefix(), value, PR_FALSE);
+          
+          if (document || mParent->HasFlag(NODE_FORCE_XBL_BINDINGS)) {
+            nsIDocument* ownerDoc = mParent->GetOwnerDoc();
+            if (ownerDoc) {
+              nsRefPtr<nsXBLBinding> binding =
+                ownerDoc->BindingManager()->GetBinding(mParent);
+              if (binding) {
+                binding->AttributeChanged(localName, nsuri, PR_FALSE, PR_FALSE);
+              }
+            }
+          }
+          
+          stateMask = stateMask ^ PRUint32(mParent->IntrinsicState());
+          if (stateMask && document) {
+            MOZ_AUTO_DOC_UPDATE(document, UPDATE_CONTENT_STATE, PR_TRUE);
+            document->ContentStatesChanged(mParent, nsnull, stateMask);
+          }
+          nsNodeUtils::AttributeChanged(mParent, 
+                                        nsuri, 
+                                        localName, 
+                                        static_cast<PRUint8>(nsIDOMMutationEvent::ADDITION),
+                                        stateMask);
         }
       }
       return rv;
     }
     case eTreeOpDoneAddingChildren: {
       mNode->DoneAddingChildren(PR_FALSE);
       return rv;
     }
--- a/parser/htmlparser/src/CNavDTD.cpp
+++ b/parser/htmlparser/src/CNavDTD.cpp
@@ -75,19 +75,16 @@ static NS_DEFINE_CID(kFormProcessorCID, 
 
 #ifdef DEBUG
 static const  char kNullToken[] = "Error: Null token given";
 static const  char kInvalidTagStackPos[] = "Error: invalid tag stack position";
 #endif
 
 #include "nsElementTable.h"
 
-#define START_TIMER()
-#define STOP_TIMER()
-
 // Some flags for use by the DTD.
 #define NS_DTD_FLAG_NONE                   0x00000000
 #define NS_DTD_FLAG_HAS_OPEN_HEAD          0x00000001
 #define NS_DTD_FLAG_HAS_OPEN_BODY          0x00000002
 #define NS_DTD_FLAG_HAS_OPEN_FORM          0x00000004
 #define NS_DTD_FLAG_HAS_EXPLICIT_HEAD      0x00000008
 #define NS_DTD_FLAG_HAD_BODY               0x00000010
 #define NS_DTD_FLAG_HAD_FRAMESET           0x00000020
@@ -1080,26 +1077,20 @@ CNavDTD::WillHandleStartTag(CToken* aTok
       // the correct node.
       while (stackDepth != MAX_REFLOW_DEPTH && NS_SUCCEEDED(result)) {
         result = CloseContainersTo(mBodyContext->Last(), PR_FALSE);
         --stackDepth;
       }
     }
   }
 
-  STOP_TIMER()
-  MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::WillHandleStartTag(), this=%p\n", this));
-
   if (aTag <= NS_HTML_TAG_MAX) {
     result = mSink->NotifyTagObservers(&aNode);
   }
 
-  MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::WillHandleStartTag(), this=%p\n", this));
-  START_TIMER()
-
   return result;
 }
 
 static void
 PushMisplacedAttributes(nsIParserNode& aNode, nsDeque& aDeque)
 {
   nsCParserNode& theAttrNode = static_cast<nsCParserNode &>(aNode);
 
@@ -1331,26 +1322,21 @@ CNavDTD::HandleStartToken(CToken* aToken
       theHeadIsParent = nsHTMLElement::IsChildOfHead(theChildTag, isExclusive);
 
       switch (theChildTag) {
         case eHTMLTag_area:
           if (!mOpenMapCount) {
             isTokenHandled = PR_TRUE;
           }
 
-          STOP_TIMER();
-          MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::HandleStartToken(), this=%p\n", this));
-
           if (mOpenMapCount > 0 && mSink) {
             result = mSink->AddLeaf(*theNode);
             isTokenHandled = PR_TRUE;
           }
-
-          MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::HandleStartToken(), this=%p\n", this));
-          START_TIMER();
+	  
           break;
 
         case eHTMLTag_image:
           aToken->SetTypeID(theChildTag = eHTMLTag_img);
           break;
 
         case eHTMLTag_keygen:
           result = HandleKeyGen(theNode);
@@ -1772,23 +1758,19 @@ CNavDTD::HandleSavedTokens(PRInt32 anInd
         // Do this to synchronize dtd stack and the sink stack.
         // Note: FORM is never on the dtd stack because its always
         // considered as a leaf. However, in the sink FORM can either
         // be a container or a leaf. Therefore, we have to check
         // with the sink -- Ref: Bug 20087.
         ++anIndex;
       }
 
-      STOP_TIMER()
-      MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::HandleSavedTokensAbove(), this=%p\n", this));
       // Pause the main context and switch to the new context.
       result = mSink->BeginContext(anIndex);
-      MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::HandleSavedTokensAbove(), this=%p\n", this));
-      START_TIMER()
-
+      
       NS_ENSURE_SUCCESS(result, result);
 
       // The body context should contain contents only upto the marked position.
       mBodyContext->MoveEntries(*mTempContext, theTagCount - theTopIndex);
 
       // Now flush out all the bad contents.
       while (theBadTokenCount-- > 0){
         theToken = (CToken*)mMisplacedContent.PopFront();
@@ -1850,22 +1832,18 @@ CNavDTD::HandleSavedTokens(PRInt32 anInd
         // HandleSavedTokens, have the sink close it:
         mSink->CloseContainer(eHTMLTag_form);
       }
 
       // Bad-contents were successfully processed. Now, itz time to get
       // back to the original body context state.
       mTempContext->MoveEntries(*mBodyContext, theTagCount - theTopIndex);
 
-      STOP_TIMER()
-      MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::HandleSavedTokensAbove(), this=%p\n", this));
       // Terminate the new context and switch back to the main context
       mSink->EndContext(anIndex);
-      MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::HandleSavedTokensAbove(), this=%p\n", this));
-      START_TIMER()
 
       mFlags &= ~NS_DTD_FLAG_IN_MISPLACED_CONTENT;
     }
   }
   return result;
 }
 
 
@@ -1931,26 +1909,20 @@ CNavDTD::HandleEntityToken(CToken* aToke
 nsresult
 CNavDTD::HandleCommentToken(CToken* aToken)
 {
   NS_PRECONDITION(nsnull != aToken, kNullToken);
 
   nsCParserNode* theNode = mNodeAllocator.CreateNode(aToken, mTokenAllocator);
   NS_ENSURE_TRUE(theNode, NS_ERROR_OUT_OF_MEMORY);
 
-  STOP_TIMER();
-  MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::HandleCommentToken(), this=%p\n", this));
-
   nsresult result = mSink ? mSink->AddComment(*theNode) : NS_OK;
 
   IF_FREE(theNode, &mNodeAllocator);
 
-  MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::HandleCommentToken(), this=%p\n", this));
-  START_TIMER();
-
   return result;
 }
 
 
 /**
  *  This method gets called when an attribute token has been
  *  encountered in the parse process. This is an error, since
  *  all attributes should have been accounted for in the prior
@@ -1978,26 +1950,20 @@ CNavDTD::HandleAttributeToken(CToken* aT
 nsresult
 CNavDTD::HandleProcessingInstructionToken(CToken* aToken)
 {
   NS_PRECONDITION(nsnull != aToken, kNullToken);
 
   nsCParserNode* theNode = mNodeAllocator.CreateNode(aToken, mTokenAllocator);
   NS_ENSURE_TRUE(theNode, NS_ERROR_OUT_OF_MEMORY);
 
-  STOP_TIMER();
-  MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::HandleProcessingInstructionToken(), this=%p\n", this));
-
   nsresult result = mSink ? mSink->AddProcessingInstruction(*theNode) : NS_OK;
 
   IF_FREE(theNode, &mNodeAllocator);
 
-  MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::HandleProcessingInstructionToken(), this=%p\n", this));
-  START_TIMER();
-
   return result;
 }
 
 /**
  *  This method gets called when a DOCTYPE token has been 
  *  encountered in the parse process. 
  *  
  *  @update  harishd 09/02/99
@@ -2024,26 +1990,21 @@ CNavDTD::HandleDocTypeDeclToken(CToken* 
   }
 
   // Now remove "<!" from the begining
   docTypeStr.Cut(0, 2);
   theToken->SetStringValue(docTypeStr);
 
   nsCParserNode* theNode = mNodeAllocator.CreateNode(aToken, mTokenAllocator);
   NS_ENSURE_TRUE(theNode, NS_ERROR_OUT_OF_MEMORY);
-  STOP_TIMER();
-  MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::HandleDocTypeDeclToken(), this=%p\n", this));
 
   nsresult result = mSink ? mSink->AddDocTypeDecl(*theNode) : NS_OK;
 
   IF_FREE(theNode, &mNodeAllocator);
 
-  MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::HandleDocTypeDeclToken(), this=%p\n", this));
-  START_TIMER();
-
   return result;
 }
 
 /**
  * Retrieve the attributes for this node, and add then into
  * the node.
  *
  * @update  gess4/22/98
@@ -2489,24 +2450,18 @@ CNavDTD::PopStyle(eHTMLTags aTag)
  * @update  gess4/22/98
  * @param   aNode -- next node to be added to model
  */
 nsresult
 CNavDTD::OpenHTML(const nsCParserNode *aNode)
 {
   NS_PRECONDITION(mBodyContext->GetCount() >= 0, kInvalidTagStackPos);
 
-  STOP_TIMER();
-  MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::OpenHTML(), this=%p\n", this));
-
   nsresult result = mSink ? mSink->OpenContainer(*aNode) : NS_OK; 
 
-  MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::OpenHTML(), this=%p\n", this));
-  START_TIMER();
-
   // Don't push more than one HTML tag into the stack.
   if (mBodyContext->GetCount() == 0)  {
     mBodyContext->Push(const_cast<nsCParserNode*>(aNode), 0, PR_FALSE); 
   }
 
   return result;
 }
 
@@ -2523,28 +2478,22 @@ CNavDTD::OpenBody(const nsCParserNode *a
 {
   NS_PRECONDITION(mBodyContext->GetCount() >= 0, kInvalidTagStackPos);
 
   nsresult result = NS_OK;
   
   if (!(mFlags & NS_DTD_FLAG_HAD_FRAMESET)) {
     mFlags |= NS_DTD_FLAG_HAD_BODY;
 
-    STOP_TIMER();
-    MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::OpenBody(), this=%p\n", this));
-
     // Make sure the head is closed by the time the body is opened.
     CloseContainer(eHTMLTag_head, PR_FALSE);
 
     // Now we can open the body.
     result = mSink ? mSink->OpenContainer(*aNode) : NS_OK; 
 
-    MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::OpenBody(), this=%p\n", this));
-    START_TIMER();
-
     if (!HasOpenContainer(eHTMLTag_body)) {
       mBodyContext->Push(const_cast<nsCParserNode*>(aNode), 0, PR_FALSE);
       mTokenizer->PrependTokens(mMisplacedContent);
     }
   }
 
   return result;
 }
@@ -2657,24 +2606,19 @@ CNavDTD::OpenContainer(const nsCParserNo
       break;
 
     default:
       done = PR_FALSE;
       break;
   }
 
   if (!done) {
-    STOP_TIMER();
-    MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::OpenContainer(), this=%p\n", this));
 
     result = mSink ? mSink->OpenContainer(*aNode) : NS_OK;
 
-    MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::OpenContainer(), this=%p\n", this));
-    START_TIMER();
-
     // For residual style tags rs_tag will be true and hence
     // the body context will hold an extra reference to the node.
     mBodyContext->Push(const_cast<nsCParserNode*>(aNode), aStyleStack, rs_tag); 
   }
 
   return result;
 }
 
@@ -2748,18 +2692,16 @@ CNavDTD::CloseContainer(const eHTMLTags 
       mFlags &= ~NS_DTD_FLAG_ALTERNATE_CONTENT;
 
       // falling thro' intentionally....
     default:
       done = PR_FALSE;
   }
 
   if (!done) {
-    STOP_TIMER();
-    MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::CloseContainer(), this=%p\n", this));
 
     if (mSink) {
       result = !aMalformed
                ? mSink->CloseContainer(aTag)
                : mSink->CloseMalformedContainer(aTag);
     }
 
     // If we were dealing with a head container in the body, make sure to
@@ -2771,19 +2713,16 @@ CNavDTD::CloseContainer(const eHTMLTags 
 
       // Note: we could be assigning NS_OK into NS_OK here, but that's ok.
       // This test is to avoid a successful CloseHead result stomping over a
       // request to block the parser.
       if (NS_SUCCEEDED(result)) {
         result = headresult;
       }
     }
-
-    MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::CloseContainer(), this=%p\n", this));
-    START_TIMER();
   }
 
   return result;
 }
 
 /**
  * This method does two things: 1st, help construct
  * our own internal model of the content-stack; and
@@ -2997,23 +2936,17 @@ nsresult
 CNavDTD::AddLeaf(const nsIParserNode *aNode)
 {
   nsresult result = NS_OK;
 
   if (mSink) {
     eHTMLTags theTag = (eHTMLTags)aNode->GetNodeType();
     OpenTransientStyles(theTag);
 
-    STOP_TIMER();
-    MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this));
-
     result = mSink->AddLeaf(*aNode);
-
-    MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::AddLeaf(), this=%p\n", this));
-    START_TIMER();
   }
 
   return result;
 }
 
 /**
  * Call this method ONLY when you want to write a leaf
  * into the head container.
@@ -3036,19 +2969,16 @@ CNavDTD::AddHeadContent(nsIParserNode *a
   // SCRIPT inside NOTAGS.  Ref Bug 25880.
   if (eHTMLTag_meta == theTag || eHTMLTag_script == theTag) {
     if (HasOpenContainer(gNoXTags, NS_ARRAY_LENGTH(gNoXTags))) {
       return result;
     }
   }
 
   if (mSink) {
-    STOP_TIMER();
-    MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::AddHeadContent(), this=%p\n", this));
-
     // Make sure the head is opened.
     if (!(mFlags & NS_DTD_FLAG_HAS_OPEN_HEAD)) {
       result = mSink->OpenHead();
       mBodyContext->PushTag(eHTMLTag_head);
       mFlags |= NS_DTD_FLAG_HAS_OPEN_HEAD;
     }
 
     // Note: userdefined tags in the head are treated as leaves.
@@ -3068,19 +2998,16 @@ CNavDTD::AddHeadContent(nsIParserNode *a
       }
 
       // Note: The head context is already opened.
       result = mSink->OpenContainer(*aNode);
 
       mBodyContext->Push(static_cast<nsCParserNode*>(aNode), nsnull,
                          PR_FALSE);
     }
-
-    MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::AddHeadContent(), this=%p\n", this));
-    START_TIMER();
   }
 
   return result;
 }
 
 void
 CNavDTD::CreateContextStackFor(eHTMLTags aParent, eHTMLTags aChild)
 {
--- a/parser/htmlparser/src/nsViewSourceHTML.cpp
+++ b/parser/htmlparser/src/nsViewSourceHTML.cpp
@@ -42,20 +42,16 @@
 
 /*
  * Set NS_VIEWSOURCE_TOKENS_PER_BLOCK to 0 to disable multi-block
  * output.  Multi-block output helps reduce the amount of bidi
  * processing we have to do on the resulting content model.
  */
 #define NS_VIEWSOURCE_TOKENS_PER_BLOCK 16
 
-// TODO get rid of these unused macros
-#define STOP_TIMER()
-#define START_TIMER()
-
 #include "nsIAtom.h"
 #include "nsViewSourceHTML.h"
 #include "nsCRT.h"
 #include "nsParser.h"
 #include "nsScanner.h"
 #include "nsDTDUtils.h"
 #include "nsIContentSink.h"
 #include "nsIHTMLContentSink.h"
@@ -256,17 +252,16 @@ CViewSourceHTML::WillBuildModel(const CP
 {
   nsresult result=NS_OK;
 
 #ifdef RAPTOR_PERF_METRICS
   vsTimer.Reset();
   NS_START_STOPWATCH(vsTimer);
 #endif
 
-  STOP_TIMER();
   mSink=(nsIHTMLContentSink*)aSink;
 
   if((!aParserContext.mPrevContext) && (mSink)) {
 
     nsAString & contextFilename = aParserContext.mScanner->GetFilename();
     mFilename = Substring(contextFilename,
                           12, // The length of "view-source:"
                           contextFilename.Length() - 12);
@@ -297,18 +292,16 @@ CViewSourceHTML::WillBuildModel(const CP
 
 
   if(eViewSource!=aParserContext.mParserCommand)
     mDocType=ePlainText;
   else mDocType=aParserContext.mDocType;
 
   mLineNumber = 1;
 
-  START_TIMER();
-
   return result;
 }
 
 /**
   * The parser uses a code sandwich to wrap the parsing process. Before
   * the process begins, WillBuildModel() is called. Afterwards the parser
   * calls DidBuildModel().
   * @update gess5/18/98
@@ -535,18 +528,16 @@ void CViewSourceHTML::AddAttrToNode(nsCP
  * @return
  */
 NS_IMETHODIMP CViewSourceHTML::DidBuildModel(nsresult anErrorCode)
 {
   nsresult result= NS_OK;
 
   //ADD CODE HERE TO CLOSE OPEN CONTAINERS...
 
-  STOP_TIMER();
-
   if (mSink) {
       //now let's close automatically auto-opened containers...
 
 #ifdef DUMP_TO_FILE
     if(gDumpFile) {
       fprintf(gDumpFile, "</pre>\n");
       fprintf(gDumpFile, "</body>\n");
       fprintf(gDumpFile, "</html>\n");
@@ -556,18 +547,16 @@ NS_IMETHODIMP CViewSourceHTML::DidBuildM
 
     if(ePlainText!=mDocType) {
       mSink->CloseContainer(eHTMLTag_pre);
       mSink->CloseContainer(eHTMLTag_body);
       mSink->CloseContainer(eHTMLTag_html);
     }
   }
 
-  START_TIMER();
-
 #ifdef RAPTOR_PERF_METRICS
   NS_STOP_STOPWATCH(vsTimer);
   printf("viewsource timer: ");
   vsTimer.Print();
   printf("\n");
 #endif
 
   return result;
@@ -764,18 +753,16 @@ nsresult CViewSourceHTML::WriteTag(PRInt
     if (gDumpFile) {
       fprintf(gDumpFile, "<span class=\"");
       fprintf(gDumpFile, kElementClasses[aTagType]);
       fprintf(gDumpFile, "\">");
     }
 #endif // DUMP_TO_FILE
   }
 
-  STOP_TIMER();
-
   mITextToken.SetIndirectString(aText);  //now emit the tag name...
 
   nsCParserNode theNode(&mITextToken, 0/*stack token*/);
   mSink->AddLeaf(theNode);
 #ifdef DUMP_TO_FILE
   if (gDumpFile) {
     fputs(NS_ConvertUTF16toUTF8(aText).get(), gDumpFile);
   }
@@ -811,18 +798,16 @@ nsresult CViewSourceHTML::WriteTag(PRInt
     mErrorNode.ReleaseAll();
     mSink->CloseContainer(eHTMLTag_span);  //emit </endtag>...
 #ifdef DUMP_TO_FILE
     if (gDumpFile)
       fprintf(gDumpFile, "</span>");
 #endif //DUMP_TO_FILE
   }
 
-  START_TIMER();
-
   return result;
 }
 
 /**
  *
  *  @update  gess 3/25/98
  *  @param   aToken -- token object to be put into content model
  *  @return  0 if all is well; non-zero is an error
--- a/security/manager/ssl/src/nsCipherInfo.cpp
+++ b/security/manager/ssl/src/nsCipherInfo.cpp
@@ -81,17 +81,17 @@ nsCipherInfo::nsCipherInfo(PRUint16 aCip
   
     PRBool isGood = (
       (SECSuccess == SSL_GetCipherSuiteInfo(i_id, &mInfo, sizeof(mInfo)))
       &&
       (sizeof(mInfo) == mInfo.length));
 
     if (!isGood)
     {
-      NS_ASSERTION(0, "unable to get info for implemented cipher");
+      NS_ERROR("unable to get info for implemented cipher");
       continue;
     }
     
     mHaveInfo = PR_TRUE;
   }
 }
 
 nsCipherInfo::~nsCipherInfo()
--- a/security/manager/ssl/src/nsCrypto.cpp
+++ b/security/manager/ssl/src/nsCrypto.cpp
@@ -2103,17 +2103,17 @@ nsP12Runnable::Run()
   nssComponent->GetPIPNSSBundleString("ForcedBackup3", temp);
 
   final.Append(temp.get());
   alertUser(final.get());
 
   nsCOMPtr<nsIFilePicker> filePicker = 
                         do_CreateInstance("@mozilla.org/filepicker;1", &rv);
   if (!filePicker) {
-    NS_ASSERTION(0, "Could not create a file picker when backing up certs.");
+    NS_ERROR("Could not create a file picker when backing up certs.");
     return rv;
   }
 
   nsCOMPtr<nsIWindowWatcher> wwatch =
     (do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIDOMWindow> window;
@@ -3009,12 +3009,12 @@ nsPkcs11::AddModule(const nsAString& aMo
   switch (srv) {
   case SECSuccess:
     return NS_OK;
   case SECFailure:
     return NS_ERROR_FAILURE;
   case -2:
     return NS_ERROR_ILLEGAL_VALUE;
   }
-  NS_ASSERTION(0,"Bogus return value, this should never happen");
+  NS_ERROR("Bogus return value, this should never happen");
   return NS_ERROR_FAILURE;
 }
 
--- a/security/manager/ssl/src/nsIdentityChecking.cpp
+++ b/security/manager/ssl/src/nsIdentityChecking.cpp
@@ -888,17 +888,17 @@ static SECStatus getFirstEVPolicy(CERTCe
       if (!policies)
         continue;
     
       policyInfos = policies->policyInfos;
 
       while (*policyInfos != NULL) {
         policyInfo = *policyInfos++;
 
-        SECOidTag oid_tag = SECOID_FindOIDTag(&policyInfo->policyID);
+        SECOidTag oid_tag = policyInfo->oid;
         if (oid_tag == SEC_OID_UNKNOWN) // not in our list of OIDs accepted for EV
           continue;
 
         if (!isEVPolicy(oid_tag))
           continue;
 
         outOidTag = oid_tag;
         return SECSuccess;
@@ -999,16 +999,17 @@ nsNSSCertificate::hasValidEVOidTag(SECOi
     cert_revocation_method_ocsp
   };
 
   PRUint64 revMethodFlags = 
     CERT_REV_M_TEST_USING_THIS_METHOD
     | CERT_REV_M_ALLOW_NETWORK_FETCHING
     | CERT_REV_M_ALLOW_IMPLICIT_DEFAULT_SOURCE
     | CERT_REV_M_REQUIRE_INFO_ON_MISSING_SOURCE
+    | CERT_REV_M_IGNORE_MISSING_FRESH_INFO
     | CERT_REV_M_STOP_TESTING_ON_FRESH_INFO;
 
   PRUint64 revMethodIndependentFlags = 
     CERT_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST
     | CERT_REV_MI_REQUIRE_SOME_FRESH_INFO_AVAILABLE;
 
   PRUint64 methodFlags[2];
   methodFlags[cert_revocation_method_crl] = revMethodFlags;
--- a/security/manager/ssl/src/nsNSSASN1Object.cpp
+++ b/security/manager/ssl/src/nsNSSASN1Object.cpp
@@ -179,17 +179,17 @@ buildASN1ObjectFromDER(unsigned char *da
           break;
         case SEC_ASN1_CONTEXT_SPECIFIC:
           type = nsIASN1Object::ASN1_CONTEXT_SPECIFIC;
           break;
         case SEC_ASN1_PRIVATE:
           type = nsIASN1Object::ASN1_PRIVATE;
           break;
         default:
-          NS_ASSERTION(0,"Bad DER");
+          NS_ERROR("Bad DER");
           return NS_ERROR_FAILURE;
         }
         sequence->SetTag(tagnum);
         sequence->SetType(type);
         rv = buildASN1ObjectFromDER(data, (len == 0) ? end : data + len, 
                                     sequence);
         asn1Obj = sequence;
       }
--- a/security/manager/ssl/src/nsNSSCertHelper.cpp
+++ b/security/manager/ssl/src/nsNSSCertHelper.cpp
@@ -104,17 +104,17 @@ static const unsigned int numOids = (siz
 static nsresult
 GetIntValue(SECItem *versionItem, 
             unsigned long *version)
 {
   SECStatus srv;
 
   srv = SEC_ASN1DecodeInteger(versionItem,version);
   if (srv != SECSuccess) {
-    NS_ASSERTION(0,"Could not decode version of cert");
+    NS_ERROR("Could not decode version of cert");
     return NS_ERROR_FAILURE;
   }
   return NS_OK;
 }
 
 static nsresult
 ProcessVersion(SECItem         *versionItem,
                nsINSSComponent *nssComponent,
@@ -150,17 +150,17 @@ ProcessVersion(SECItem         *versionI
     break;
   case 1:
     rv = nssComponent->GetPIPNSSBundleString("CertDumpVersion2", text);
     break;
   case 2:
     rv = nssComponent->GetPIPNSSBundleString("CertDumpVersion3", text);
     break;
   default:
-    NS_ASSERTION(0,"Bad value for cert version");
+    NS_ERROR("Bad value for cert version");
     rv = NS_ERROR_FAILURE;
   }
     
   if (NS_FAILED(rv))
     return rv;
 
   rv = printableItem->SetDisplayValue(text);
   if (NS_FAILED(rv))
@@ -1407,18 +1407,17 @@ ProcessCertificatePolicies(SECItem  *ext
     }
 
     PRBool needColon = PR_TRUE;
     if (ev_oid_tag != SEC_OID_UNKNOWN) {
       // This is an EV cert. Let's see if this oid is the EV oid,
       // because we want to display the EV information string
       // next to the correct OID.
 
-      SECOidTag oid_tag = SECOID_FindOIDTag(&policyInfo->policyID);
-      if (oid_tag == ev_oid_tag) {
+      if (policyInfo->oid == ev_oid_tag) {
         text.Append(NS_LITERAL_STRING(":"));
         text.Append(NS_LITERAL_STRING(SEPARATOR));
         needColon = PR_FALSE;
         nssComponent->GetPIPNSSBundleString("CertDumpPolicyOidEV", local);
         text.Append(local);
       }
     }
 
--- a/security/manager/ssl/src/nsNSSCertificate.cpp
+++ b/security/manager/ssl/src/nsNSSCertificate.cpp
@@ -591,17 +591,17 @@ nsNSSCertificate::GetWindowTitle(char * 
         } else if (mCert->emailAddr) {
           *aWindowTitle = PL_strdup(mCert->emailAddr);
         } else {
           *aWindowTitle = PL_strdup("");
         }
       }
     }
   } else {
-    NS_ASSERTION(0,"Somehow got nsnull for mCertificate in nsNSSCertificate.");
+    NS_ERROR("Somehow got nsnull for mCertificate in nsNSSCertificate.");
     *aWindowTitle = nsnull;
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsNSSCertificate::GetNickname(nsAString &aNickname)
 {
@@ -1636,22 +1636,22 @@ nsNSSCertList::AddCert(nsIX509Cert *aCer
 {
   /* This should be a query interface, but currently this his how the
    * rest of PSM is working */
   nsCOMPtr<nsIX509Cert2> nssCert = do_QueryInterface(aCert);
   CERTCertificate *cert;
 
   cert = nssCert->GetCert();
   if (cert == nsnull) {
-    NS_ASSERTION(0,"Somehow got nsnull for mCertificate in nsNSSCertificate.");
+    NS_ERROR("Somehow got nsnull for mCertificate in nsNSSCertificate.");
     return NS_ERROR_FAILURE;
   }
 
   if (mCertList == nsnull) {
-    NS_ASSERTION(0,"Somehow got nsnull for mCertList in nsNSSCertList.");
+    NS_ERROR("Somehow got nsnull for mCertList in nsNSSCertList.");
     return NS_ERROR_FAILURE;
   }
   CERT_AddCertToListTail(mCertList,cert);
   return NS_OK;
 }
 
 /* void deleteCert (in nsIX509Cert cert); */
 NS_IMETHODIMP
@@ -1659,22 +1659,22 @@ nsNSSCertList::DeleteCert(nsIX509Cert *a
 {
   /* This should be a query interface, but currently this his how the
    * rest of PSM is working */
   nsCOMPtr<nsIX509Cert2> nssCert = do_QueryInterface(aCert);
   CERTCertificate *cert = nssCert->GetCert();
   CERTCertListNode *node;
 
   if (cert == nsnull) {
-    NS_ASSERTION(0,"Somehow got nsnull for mCertificate in nsNSSCertificate.");
+    NS_ERROR("Somehow got nsnull for mCertificate in nsNSSCertificate.");
     return NS_ERROR_FAILURE;
   }
 
   if (mCertList == nsnull) {
-    NS_ASSERTION(0,"Somehow got nsnull for mCertList in nsNSSCertList.");
+    NS_ERROR("Somehow got nsnull for mCertList in nsNSSCertList.");
     return NS_ERROR_FAILURE;
   }
 
   for (node = CERT_LIST_HEAD(mCertList); !CERT_LIST_END(node,mCertList);
                                              node = CERT_LIST_NEXT(node)) {
     if (node->cert == cert) {
 	CERT_RemoveCertListNode(node);
         return NS_OK;
--- a/security/manager/ssl/src/nsNSSCertificateDB.cpp
+++ b/security/manager/ssl/src/nsNSSCertificateDB.cpp
@@ -442,17 +442,17 @@ nsNSSCertificateDB::handleCACertDownload
     CERTCertificate *tmpCert2 = 
       CERT_NewTempCertificate(certdb, &der, nsnull, PR_FALSE, PR_TRUE);
 
     nsMemory::Free(der.data);
     der.data = nsnull;
     der.len = 0;
 
     if (!tmpCert2) {
-      NS_ASSERTION(0, "Couldn't create temp cert from DER blob\n");
+      NS_ERROR("Couldn't create temp cert from DER blob\n");
       continue;  // Let's try to import the rest of 'em
     }
     
     CERT_AddCertToListTail(certList, tmpCert2);
   }
 
   return ImportValidCACertsInList(certList, ctx);
 }
@@ -1689,17 +1689,17 @@ NS_IMETHODIMP nsNSSCertificateDB::AddCer
   if (!tmpCert) 
     tmpCert = CERT_NewTempCertificate(certdb, &der,
                                       nsnull, PR_FALSE, PR_TRUE);
   nsMemory::Free(der.data);
   der.data = nsnull;
   der.len = 0;
 
   if (!tmpCert) {
-    NS_ASSERTION(0,"Couldn't create cert from DER blob\n");
+    NS_ERROR("Couldn't create cert from DER blob\n");
     return NS_ERROR_FAILURE;
   }
 
   if (tmpCert->isperm) {
     CERT_DestroyCertificate(tmpCert);
     return NS_OK;
   }
 
--- a/toolkit/components/downloads/src/nsDownloadManager.cpp
+++ b/toolkit/components/downloads/src/nsDownloadManager.cpp
@@ -791,17 +791,17 @@ nsDownloadManager::InitDB()
       rv = InitMemoryDB();
       break;
 
     case DATABASE_DISK:
       rv = InitFileDB();
       break;
 
     default:
-      NS_ASSERTION(0, "Unexpected value encountered for nsDownloadManager::mDBType");
+      NS_ERROR("Unexpected value encountered for nsDownloadManager::mDBType");
       break;
   }
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
     "UPDATE moz_downloads "
     "SET tempPath = ?1, startTime = ?2, endTime = ?3, state = ?4, "
         "referrer = ?5, entityID = ?6, currBytes = ?7, maxBytes = ?8, "
--- a/toolkit/components/places/tests/bookmarks/test_395593.js
+++ b/toolkit/components/places/tests/bookmarks/test_395593.js
@@ -31,77 +31,71 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK *