Merge mozilla-central to mozilla-inbound
authorMatt Brubeck <mbrubeck@mozilla.com>
Thu, 29 Sep 2011 17:36:40 -0700
changeset 77896 9ef649a80d93
parent 77869 dbb129f069b1 (current diff)
parent 77895 637bac44ba15 (diff)
child 77897 06a077444292
push id3
push userfelipc@gmail.com
push dateFri, 30 Sep 2011 20:09:13 +0000
milestone10.0a1
Merge mozilla-central to mozilla-inbound
dom/tests/browser/browser_popup_blocker_multiple_popups.js
toolkit/mozapps/extensions/test/xpinstall/browser_bug638292.js
--- a/accessible/src/base/Statistics.h
+++ b/accessible/src/base/Statistics.h
@@ -44,14 +44,26 @@
 
 namespace mozilla {
 namespace a11y {
 namespace statistics {
 
   inline void A11yInitialized()
     { Telemetry::Accumulate(Telemetry::A11Y_INSTANTIATED, true); }
 
+  /**
+   * Report that ISimpleDOM* has been used.
+   */
+  inline void ISimpleDOMUsed()
+    { Telemetry::Accumulate(Telemetry::ISIMPLE_DOM_USAGE, 1); }
+
+  /**
+   * Report that IAccessibleTable has been used.
+   */
+  inline void IAccessibleTableUsed()
+    { Telemetry::Accumulate(Telemetry::IACCESSIBLE_TABLE_USAGE, 1); }
+
 } // namespace statistics
 } // namespace a11y
 } // namespace mozilla
 
 #endif
 
--- a/accessible/src/msaa/CAccessibleTable.cpp
+++ b/accessible/src/msaa/CAccessibleTable.cpp
@@ -44,31 +44,35 @@
 #include "AccessibleTable_i.c"
 #include "AccessibleTable2_i.c"
 
 #include "nsIAccessible.h"
 #include "nsIAccessibleTable.h"
 #include "nsIWinAccessNode.h"
 #include "nsAccessNodeWrap.h"
 #include "nsWinUtils.h"
+#include "Statistics.h"
 
 #include "nsCOMPtr.h"
 #include "nsString.h"
 
+using namespace mozilla::a11y;
+
 #define CANT_QUERY_ASSERTION_MSG \
 "Subclass of CAccessibleTable doesn't implement nsIAccessibleTable"\
 
 // IUnknown
 
 STDMETHODIMP
 CAccessibleTable::QueryInterface(REFIID iid, void** ppv)
 {
   *ppv = NULL;
 
   if (IID_IAccessibleTable == iid) {
+    statistics::IAccessibleTableUsed();
     *ppv = static_cast<IAccessibleTable*>(this);
     (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
     return S_OK;
   }
 
   if (IID_IAccessibleTable2 == iid) {
     *ppv = static_cast<IAccessibleTable2*>(this);
     (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
--- a/accessible/src/msaa/nsAccessNodeWrap.cpp
+++ b/accessible/src/msaa/nsAccessNodeWrap.cpp
@@ -41,29 +41,31 @@
 #include "AccessibleApplication.h"
 #include "ISimpleDOMNode_i.c"
 
 #include "nsAccessibilityService.h"
 #include "nsApplicationAccessibleWrap.h"
 #include "nsCoreUtils.h"
 #include "nsRootAccessible.h"
 #include "nsWinUtils.h"
+#include "Statistics.h"
 
 #include "nsAttrName.h"
 #include "nsIDocument.h"
 #include "nsIDOMNodeList.h"
 #include "nsIDOMNSHTMLElement.h"
 #include "nsIFrame.h"
 #include "nsINameSpaceManager.h"
 #include "nsPIDOMWindow.h"
 #include "nsIServiceManager.h"
 
 #include "mozilla/Preferences.h"
 
 using namespace mozilla;
+using namespace mozilla::a11y;
 
 /// the accessible library and cached methods
 HINSTANCE nsAccessNodeWrap::gmAccLib = nsnull;
 HINSTANCE nsAccessNodeWrap::gmUserLib = nsnull;
 LPFNACCESSIBLEOBJECTFROMWINDOW nsAccessNodeWrap::gmAccessibleObjectFromWindow = nsnull;
 LPFNLRESULTFROMOBJECT nsAccessNodeWrap::gmLresultFromObject = NULL;
 LPFNNOTIFYWINEVENT nsAccessNodeWrap::gmNotifyWinEvent = nsnull;
 LPFNGETGUITHREADINFO nsAccessNodeWrap::gmGetGUIThreadInfo = nsnull;
@@ -115,21 +117,24 @@ nsAccessNodeWrap::QueryNativeInterface(R
 //-----------------------------------------------------
 // IUnknown interface methods - see iunknown.h for documentation
 //-----------------------------------------------------
 
 STDMETHODIMP nsAccessNodeWrap::QueryInterface(REFIID iid, void** ppv)
 {
   *ppv = nsnull;
 
-  if (IID_IUnknown == iid || IID_ISimpleDOMNode == iid)
+  if (IID_IUnknown == iid) {
     *ppv = static_cast<ISimpleDOMNode*>(this);
-
-  if (nsnull == *ppv)
+  } else if (IID_ISimpleDOMNode == iid) {
+    statistics::ISimpleDOMUsed();
+    *ppv = static_cast<ISimpleDOMNode*>(this);
+  } else {
     return E_NOINTERFACE;      //iid not supported.
+  }
    
   (reinterpret_cast<IUnknown*>(*ppv))->AddRef(); 
   return S_OK;
 }
 
 STDMETHODIMP
 nsAccessNodeWrap::QueryService(REFGUID guidService, REFIID iid, void** ppv)
 {
--- a/accessible/src/msaa/nsDocAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsDocAccessibleWrap.cpp
@@ -38,27 +38,30 @@
 
 #include "mozilla/dom/TabChild.h"
 
 #include "nsDocAccessibleWrap.h"
 #include "ISimpleDOMDocument_i.c"
 #include "nsIAccessibilityService.h"
 #include "nsRootAccessible.h"
 #include "nsWinUtils.h"
+#include "Statistics.h"
 
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeNode.h"
 #include "nsIFrame.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsISelectionController.h"
 #include "nsIServiceManager.h"
 #include "nsIURI.h"
 #include "nsIViewManager.h"
 #include "nsIWebNavigation.h"
 
+using namespace mozilla::a11y;
+
 /* For documentation of the accessibility architecture, 
  * see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html
  */
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsDocAccessibleWrap
 ////////////////////////////////////////////////////////////////////////////////
 
@@ -86,22 +89,21 @@ STDMETHODIMP_(ULONG) nsDocAccessibleWrap
   return nsAccessNode::Release();
 }
 
 // Microsoft COM QueryInterface
 STDMETHODIMP nsDocAccessibleWrap::QueryInterface(REFIID iid, void** ppv)
 {
   *ppv = NULL;
 
-  if (IID_ISimpleDOMDocument == iid)
-    *ppv = static_cast<ISimpleDOMDocument*>(this);
+  if (IID_ISimpleDOMDocument != iid)
+    return nsHyperTextAccessibleWrap::QueryInterface(iid, ppv);
 
-  if (NULL == *ppv)
-    return nsHyperTextAccessibleWrap::QueryInterface(iid, ppv);
-    
+  statistics::ISimpleDOMUsed();
+  *ppv = static_cast<ISimpleDOMDocument*>(this);
   (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
   return S_OK;
 }
 
 STDMETHODIMP nsDocAccessibleWrap::get_URL(/* [out] */ BSTR __RPC_FAR *aURL)
 {
 __try {
   *aURL = NULL;
--- a/accessible/src/msaa/nsTextAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsTextAccessibleWrap.cpp
@@ -36,23 +36,26 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsTextAccessibleWrap.h"
 #include "ISimpleDOMText_i.c"
 
 #include "nsCoreUtils.h"
 #include "nsDocAccessible.h"
+#include "Statistics.h"
 #include "nsIFrame.h"
 #include "nsFontMetrics.h"
 #include "nsPresContext.h"
 #include "nsLayoutUtils.h"
 
 #include "gfxFont.h"
 
+using namespace mozilla::a11y;
+
 ////////////////////////////////////////////////////////////////////////////////
 // nsTextAccessibleWrap Accessible
 ////////////////////////////////////////////////////////////////////////////////
 
 nsTextAccessibleWrap::
   nsTextAccessibleWrap(nsIContent *aContent, nsIWeakReference *aShell) :
   nsTextAccessible(aContent, aShell)
 {
@@ -67,21 +70,24 @@ STDMETHODIMP_(ULONG) nsTextAccessibleWra
 {
   return nsAccessNode::Release();
 }
 
 STDMETHODIMP nsTextAccessibleWrap::QueryInterface(REFIID iid, void** ppv)
 {
   *ppv = nsnull;
 
-  if (IID_IUnknown == iid || IID_ISimpleDOMText == iid)
+  if (IID_IUnknown == iid) {
     *ppv = static_cast<ISimpleDOMText*>(this);
-
-  if (nsnull == *ppv)
+  } else if (IID_ISimpleDOMText == iid) {
+    statistics::ISimpleDOMUsed();
+    *ppv = static_cast<ISimpleDOMText*>(this);
+  } else {
     return nsAccessibleWrap::QueryInterface(iid, ppv);
+  }
    
   (reinterpret_cast<IUnknown*>(*ppv))->AddRef(); 
   return S_OK;
 }
 
 STDMETHODIMP nsTextAccessibleWrap::get_domText( 
     /* [retval][out] */ BSTR __RPC_FAR *aDomText)
 {
--- a/configure.in
+++ b/configure.in
@@ -5925,22 +5925,16 @@ if test -n "$MOZ_TREE_FREETYPE"; then
    AC_DEFINE(HAVE_FT_GLYPHSLOT_EMBOLDEN)
    AC_DEFINE(HAVE_FT_LOAD_SFNT_TABLE)
    AC_SUBST(CAIRO_FT_CFLAGS)
 fi
 
 dnl ========================================================
 dnl Installer
 dnl ========================================================
-case "$target_os" in
-    aix*|solaris*|linux*|mingw*|os2*)
-        MOZ_INSTALLER=1
-        ;;
-esac
-
 MOZ_ARG_DISABLE_BOOL(installer,
 [  --disable-installer     Disable building of installer],
     MOZ_INSTALLER=,
     MOZ_INSTALLER=1)
 if test -n "$MOZ_INSTALLER" -a "$OS_ARCH" = "WINNT"; then
     # Disable installer for Windows builds that use the new toolkit if the
     # required major version and minimum minor version of Unicode NSIS isn't in
     # the path.
--- a/docshell/test/navigation/test_bug13871.html
+++ b/docshell/test/navigation/test_bug13871.html
@@ -22,24 +22,20 @@ window.onload = function () {
     isInaccessible(window3.frames[0], "Should not be able to navigate off-domain frame by targeted hyperlink.");
 
     window0.close();
     window1.close();
     window2.close();
     window3.close();
 
     xpcCleanupWindows();
-    SpecialPowers.setBoolPref("dom.block_multiple_popups", gBlockMultiplePopups);
     SimpleTest.finish();
   }, 4);
 }
 
-var gBlockMultiplePopups = SpecialPowers.getBoolPref("dom.block_multiple_popups");
-SpecialPowers.setBoolPref("dom.block_multiple_popups", false);
-
 var window0 = window.open("http://test1.example.org:80/tests/docshell/test/navigation/parent.html", "window0", "width=10,height=10");
 var window1 = window.open("http://test1.example.org:80/tests/docshell/test/navigation/parent.html", "window1", "width=10,height=10");
 var window2 = window.open("http://test1.example.org:80/tests/docshell/test/navigation/parent.html", "window2", "width=10,height=10");
 var window3 = window.open("http://test1.example.org:80/tests/docshell/test/navigation/parent.html", "window3", "width=10,height=10");
 </script>
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=13871">Mozilla Bug 13871</a>
--- a/docshell/test/navigation/test_bug270414.html
+++ b/docshell/test/navigation/test_bug270414.html
@@ -4,19 +4,16 @@
     <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>        
     <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
     <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
     <script type="text/javascript" src="NavigationUtils.js"></script>        
     <style type="text/css">
       iframe { width: 90%; height: 50px; }
     </style>
 <script>
-var gBlockMultiplePopups = SpecialPowers.getBoolPref("dom.block_multiple_popups");
-SpecialPowers.setBoolPref("dom.block_multiple_popups", false);
-
 var headerHTML = "<html><head>" +
                  "<script src='/tests/SimpleTest/EventUtils.js'></scr" + "ipt>" + 
                  "<script src='NavigationUtils.js'></scr" + "ipt>" +
                  "</head><body>";
 var footerHTML = "</body></html>";
 
 function testChild0() {
   if (!window.window0) {
@@ -69,17 +66,16 @@ xpcWaitForFinishedFrames(function() {
   isNavigated(frames[3], "Should be able to navigate on-domain opener's children by targeted hyperlink.");
 
   window0.close();
   window1.close();
   window2.close();
   window3.close();
 
   xpcCleanupWindows();
-  SpecialPowers.setBoolPref("dom.block_multiple_popups", gBlockMultiplePopups);
   SimpleTest.finish();
 }, 4);
 
 </script>
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=270414">Mozilla Bug 270414</a>
 <div id="frames">
--- a/docshell/test/navigation/test_not-opener.html
+++ b/docshell/test/navigation/test_not-opener.html
@@ -21,24 +21,20 @@ window.onload = function () {
     is(xpcGetFramesByName("window3").length, 2, "Should not be able to navigate popup's popup by targeted hyperlink.");
 
     //opener0.close();
     opener1.close();
     opener2.close();
     opener3.close();
 
     xpcCleanupWindows();
-    SpecialPowers.setBoolPref("dom.block_multiple_popups", gBlockMultiplePopups);
     SimpleTest.finish();
   }, 6);
 }
 
-var gBlockMultiplePopups = SpecialPowers.getBoolPref("dom.block_multiple_popups");
-SpecialPowers.setBoolPref("dom.block_multiple_popups", false);
-
 //opener0 = window.open("http://test1.example.org:80/tests/docshell/test/navigation/open.html#window0", "_blank", "width=10,height=10");
 opener1 = window.open("http://test1.example.org:80/tests/docshell/test/navigation/open.html#window1", "_blank", "width=10,height=10");
 opener2 = window.open("http://test1.example.org:80/tests/docshell/test/navigation/open.html#window2", "_blank", "width=10,height=10");
 opener3 = window.open("http://test1.example.org:80/tests/docshell/test/navigation/open.html#window3", "_blank", "width=10,height=10");
 </script>
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=408052">Mozilla Bug 408052</a>
--- a/docshell/test/navigation/test_popup-navigates-children.html
+++ b/docshell/test/navigation/test_popup-navigates-children.html
@@ -4,19 +4,16 @@
     <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>        
     <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
     <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
     <script type="text/javascript" src="NavigationUtils.js"></script>        
     <style type="text/css">
       iframe { width: 90%; height: 50px; }
     </style>
 <script>
-var gBlockMultiplePopups = SpecialPowers.getBoolPref("dom.block_multiple_popups");
-SpecialPowers.setBoolPref("dom.block_multiple_popups", false);
-
 function testChild0() {
   if (!window.window0)
     window0 = window.open("navigate.html#opener.frames[0],location", "window0", "width=10,height=10");
 }
 
 function testChild1() {
   if (!window.window1)
     window1 = window.open("navigate.html#child1,open", "window1", "width=10,height=10");
@@ -39,17 +36,16 @@ xpcWaitForFinishedFrames(function() {
   isNavigated(frames[3], "Should be able to navigate on-domain opener's children by targeted hyperlink.");
 
   window0.close();
   window1.close();
   window2.close();
   window3.close();
 
   xpcCleanupWindows();
-  SpecialPowers.setBoolPref("dom.block_multiple_popups", gBlockMultiplePopups);
   SimpleTest.finish();
 }, 4);
 
 </script>
 </head>
 <body>
 <div id="frames">
 <iframe onload="testChild0()" name="child0" src="http://test1.example.org:80/tests/docshell/test/navigation/blank.html"></iframe>
--- a/docshell/test/navigation/test_sibling-off-domain.html
+++ b/docshell/test/navigation/test_sibling-off-domain.html
@@ -4,34 +4,30 @@
     <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>        
     <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
     <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
     <script type="text/javascript" src="NavigationUtils.js"></script>        
     <style type="text/css">
       iframe { width: 90%; height: 50px; }
     </style>
 <script>
-var gBlockMultiplePopups = SpecialPowers.getBoolPref("dom.block_multiple_popups");
-SpecialPowers.setBoolPref("dom.block_multiple_popups", false);
-
 window.onload = function () {
   document.getElementById('active').innerHTML =
       '<iframe src="http://test1.example.org:80/tests/docshell/test/navigation/navigate.html#parent.frames[0],location"></iframe>' +
       '<iframe src="http://test1.example.org:80/tests/docshell/test/navigation/navigate.html#child1,open"></iframe>' +
       '<iframe src="http://test1.example.org:80/tests/docshell/test/navigation/navigate.html#child2,form"></iframe>' +
       '<iframe src="http://test1.example.org:80/tests/docshell/test/navigation/navigate.html#child3,hyperlink"></iframe>';
 
   xpcWaitForFinishedFrames(function() {
     isBlank(frames[0], "Should not be able to navigate off-domain sibling by setting location.");
     isBlank(frames[1], "Should not be able to navigate off-domain sibling by calling window.open.");
     isBlank(frames[2], "Should not be able to navigate off-domain sibling by submitting form.");
     isBlank(frames[3], "Should not be able to navigate off-domain sibling by targeted hyperlink.");
 
     xpcCleanupWindows();
-    SpecialPowers.setBoolPref("dom.block_multiple_popups", gBlockMultiplePopups);
     SimpleTest.finish();
   }, 4);
 }
 </script>
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=408052">Mozilla Bug 408052</a>
 <div id="frames">
--- a/docshell/test/test_bug598895.html
+++ b/docshell/test/test_bug598895.html
@@ -34,24 +34,20 @@ window.onmessage = function (ev) {
     var two = snapshotWindow(win2);
     var three = snapshotWindow(win3);
     win1.close();
     win2.close();
     win3.close();
     ok(compareSnapshots(one, two, true)[0], "Popups should look identical");
     ok(compareSnapshots(one, three, false)[0], "Popups should not look identical");
 
-    SpecialPowers.setBoolPref("dom.block_multiple_popups", gBlockMultiplePopups);
     SimpleTest.finish();
   }
 }
 
-var gBlockMultiplePopups = SpecialPowers.getBoolPref("dom.block_multiple_popups");
-SpecialPowers.setBoolPref("dom.block_multiple_popups", false);
-
 var win2 = window.open("data:text/html,<script>window.onload = function() { opener.postMessage('loaded', '*'); }</" + "script><body>Should show</body>");
 
 var win3 = window.open("data:text/html,<script>window.onload = function() { opener.postMessage('loaded', '*'); }</" + "script><body></body>");
 });
 </script>
 </pre>
 </body>
 </html>
--- a/docshell/test/test_bug637644.html
+++ b/docshell/test/test_bug637644.html
@@ -34,24 +34,20 @@ window.onmessage = function (ev) {
     var two = snapshotWindow(win2);
     var three = snapshotWindow(win3);
     win1.close();
     win2.close();
     win3.close();
     ok(compareSnapshots(one, two, true)[0], "Popups should look identical");
     ok(compareSnapshots(one, three, false)[0], "Popups should not look identical");
 
-    SpecialPowers.setBoolPref("dom.block_multiple_popups", gBlockMultiplePopups);
     SimpleTest.finish();
   }
 }
 
-var gBlockMultiplePopups = SpecialPowers.getBoolPref("dom.block_multiple_popups");
-SpecialPowers.setBoolPref("dom.block_multiple_popups", false);
-
 var win2 = window.open("data:text/html,<script>window.onload = function() { opener.postMessage('loaded', '*'); }</" + "script><body>Should show</body>", "", "height=500,width=500");
 
 var win3 = window.open("data:text/html,<script>window.onload = function() { opener.postMessage('loaded', '*'); }</" + "script><body></body>", "", "height=500,width=500");
 });
 </script>
 </pre>
 </body>
 </html>
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -263,17 +263,16 @@ using mozilla::TimeDuration;
 nsIDOMStorageList *nsGlobalWindow::sGlobalStorageList  = nsnull;
 nsGlobalWindow::WindowByIdTable *nsGlobalWindow::sWindowsById = nsnull;
 bool nsGlobalWindow::sWarnedAboutWindowInternal = false;
 
 static nsIEntropyCollector *gEntropyCollector          = nsnull;
 static PRInt32              gRefCnt                    = 0;
 static PRInt32              gOpenPopupSpamCount        = 0;
 static PopupControlState    gPopupControlState         = openAbused;
-static PopupOpenedState     gPopupOpenedState          = noTrack;
 static PRInt32              gRunningTimeoutDepth       = 0;
 static bool                 gMouseDown                 = false;
 static bool                 gDragServiceDisabled       = false;
 static FILE                *gDumpFile                  = nsnull;
 static PRUint64             gNextWindowID              = 0;
 static PRUint32             gSerialCounter             = 0;
 static bool                 gDoNotTrackEnabled         = false;
 
@@ -1709,40 +1708,16 @@ nsGlobalWindow::PopPopupControlState(Pop
 }
 
 PopupControlState
 nsGlobalWindow::GetPopupControlState() const
 {
   return gPopupControlState;
 }
 
-PopupOpenedState
-GetPopupOpenedState()
-{
-  return gPopupOpenedState;
-}
-
-PopupOpenedState
-nsGlobalWindow::GetPopupOpenedState() const
-{
-  return ::GetPopupOpenedState();
-}
-
-void
-SetPopupOpenedState(PopupOpenedState aValue)
-{
-  gPopupOpenedState = aValue;
-}
-
-void
-nsGlobalWindow::SetPopupOpenedState(PopupOpenedState aValue) const
-{
-  ::SetPopupOpenedState(aValue);
-}
-
 #define WINDOWSTATEHOLDER_IID \
 {0x0b917c3e, 0xbd50, 0x4683, {0xaf, 0xc9, 0xc7, 0x81, 0x07, 0xae, 0x33, 0x26}}
 
 class WindowStateHolder : public nsISupports
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(WINDOWSTATEHOLDER_IID)
   NS_DECL_ISUPPORTS
@@ -5734,31 +5709,16 @@ nsGlobalWindow::RevisePopupAbuseLevel(Po
 
   // limit the number of simultaneously open popups
   if (abuse == openAbused || abuse == openControlled) {
     PRInt32 popupMax = Preferences::GetInt("dom.popup_maximum", -1);
     if (popupMax >= 0 && gOpenPopupSpamCount >= popupMax)
       abuse = openOverridden;
   }
 
-  if (Preferences::GetBool("dom.block_multiple_popups", true)) {
-    // Do not allow opening more than one popup per event.
-    switch (GetPopupOpenedState()) {
-      case noOpenedPopup:
-        SetPopupOpenedState(openedPopup);
-        break;
-      case openedPopup:
-        abuse = openOverridden;
-        break;
-      case noTrack:
-      default:
-        break;
-    }
-  }
-
   return abuse;
 }
 
 /* If a window open is blocked, fire the appropriate DOM events.
    aBlocked signifies we just blocked a popup.
    aWindow signifies we just opened what is probably a popup.
 */
 void
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -348,18 +348,16 @@ public:
   virtual NS_HIDDEN_(void) SetChromeEventHandler(nsIDOMEventTarget* aChromeEventHandler);
 
   virtual NS_HIDDEN_(void) SetOpenerScriptPrincipal(nsIPrincipal* aPrincipal);
   virtual NS_HIDDEN_(nsIPrincipal*) GetOpenerScriptPrincipal();
 
   virtual NS_HIDDEN_(PopupControlState) PushPopupControlState(PopupControlState state, bool aForce) const;
   virtual NS_HIDDEN_(void) PopPopupControlState(PopupControlState state) const;
   virtual NS_HIDDEN_(PopupControlState) GetPopupControlState() const;
-  virtual NS_HIDDEN_(PopupOpenedState) GetPopupOpenedState() const;
-  virtual NS_HIDDEN_(void) SetPopupOpenedState(PopupOpenedState aValue) const;
 
   virtual NS_HIDDEN_(nsresult) SaveWindowState(nsISupports **aState);
   virtual NS_HIDDEN_(nsresult) RestoreWindowState(nsISupports *aState);
   virtual NS_HIDDEN_(void) SuspendTimeouts(PRUint32 aIncrease = 1,
                                            bool aFreezeChildren = true);
   virtual NS_HIDDEN_(nsresult) ResumeTimeouts(bool aThawChildren = true);
   virtual NS_HIDDEN_(PRUint32) TimeoutSuspendCount();
   virtual NS_HIDDEN_(nsresult) FireDelayedDOMEvents();
--- a/dom/base/nsPIDOMWindow.h
+++ b/dom/base/nsPIDOMWindow.h
@@ -64,24 +64,16 @@ class nsIPrincipal;
 // nsGlobalWindow::PushPopupControlState()).
 enum PopupControlState {
   openAllowed = 0,  // open that window without worries
   openControlled,   // it's a popup, but allow it
   openAbused,       // it's a popup. disallow it, but allow domain override.
   openOverridden    // disallow window open
 };
 
-// PopupOpenedState helps track abuse of opened popups while the privilege has
-// been given.
-enum PopupOpenedState {
-  noTrack = -1,      // Don't track opened popups.
-  noOpenedPopup = 0, // Tracking opened popups but none opened yet.
-  openedPopup = 1    // Tracking opened popups and one has been opened.
-};
-
 class nsIDocShell;
 class nsIContent;
 class nsIDocument;
 class nsIScriptTimeoutHandler;
 struct nsTimeout;
 class nsScriptObjectHolder;
 class nsXBLPrototypeHandler;
 class nsIArray;
@@ -299,18 +291,16 @@ public:
   virtual void SetOpenerScriptPrincipal(nsIPrincipal* aPrincipal) = 0;
   // Ask this window who opened it.
   virtual nsIPrincipal* GetOpenerScriptPrincipal() = 0;
 
   virtual PopupControlState PushPopupControlState(PopupControlState aState,
                                                   bool aForce) const = 0;
   virtual void PopPopupControlState(PopupControlState state) const = 0;
   virtual PopupControlState GetPopupControlState() const = 0;
-  virtual void SetPopupOpenedState(PopupOpenedState aValue) const = 0;
-  virtual PopupOpenedState GetPopupOpenedState() const = 0;
 
   // Returns an object containing the window's state.  This also suspends
   // all running timeouts in the window.
   virtual nsresult SaveWindowState(nsISupports **aState) = 0;
 
   // Restore the window state from aState.
   virtual nsresult RestoreWindowState(nsISupports *aState) = 0;
 
@@ -692,22 +682,16 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsPIDOMWin
 
 #ifdef _IMPL_NS_LAYOUT
 PopupControlState
 PushPopupControlState(PopupControlState aState, bool aForce);
 
 void
 PopPopupControlState(PopupControlState aState);
 
-PopupOpenedState
-GetPopupOpenedState();
-
-void
-SetPopupOpenedState(PopupOpenedState aState);
-
 #define NS_AUTO_POPUP_STATE_PUSHER nsAutoPopupStatePusherInternal
 #else
 #define NS_AUTO_POPUP_STATE_PUSHER nsAutoPopupStatePusherExternal
 #endif
 
 // Helper class that helps with pushing and popping popup control
 // state. Note that this class looks different from within code that's
 // part of the layout library than it does in code outside the layout
@@ -715,56 +699,45 @@ SetPopupOpenedState(PopupOpenedState aSt
 // don't conflict, but code should always use the name
 // |nsAutoPopupStatePusher|.
 class NS_AUTO_POPUP_STATE_PUSHER
 {
 public:
 #ifdef _IMPL_NS_LAYOUT
   NS_AUTO_POPUP_STATE_PUSHER(PopupControlState aState, bool aForce = false)
     : mOldState(::PushPopupControlState(aState, aForce))
-    , mPreviousOpenState(::GetPopupOpenedState())
   {
-    SetPopupOpenedState(mPreviousOpenState == openedPopup ? openedPopup
-                                                          : noOpenedPopup);
   }
 
   ~NS_AUTO_POPUP_STATE_PUSHER()
   {
     PopPopupControlState(mOldState);
-    SetPopupOpenedState(mPreviousOpenState);
   }
 #else
   NS_AUTO_POPUP_STATE_PUSHER(nsPIDOMWindow *aWindow, PopupControlState aState)
-    : mWindow(aWindow)
-    , mOldState(openAbused)
-    , mPreviousOpenState(noTrack)
+    : mWindow(aWindow), mOldState(openAbused)
   {
     if (aWindow) {
       mOldState = aWindow->PushPopupControlState(aState, PR_FALSE);
-      mPreviousOpenState = aWindow->GetPopupOpenedState();
-      aWindow->SetPopupOpenedState(mPreviousOpenState == openedPopup ? openedPopup
-                                                                     : noOpenedPopup);
     }
   }
 
   ~NS_AUTO_POPUP_STATE_PUSHER()
   {
     if (mWindow) {
       mWindow->PopPopupControlState(mOldState);
-      mWindow->SetPopupOpenedState(mPreviousOpenState);
     }
   }
 #endif
 
 protected:
 #ifndef _IMPL_NS_LAYOUT
   nsCOMPtr<nsPIDOMWindow> mWindow;
 #endif
   PopupControlState mOldState;
-  PopupOpenedState mPreviousOpenState;
 
 private:
   // Hide so that this class can only be stack-allocated
   static void* operator new(size_t /*size*/) CPP_THROW_NEW { return nsnull; }
   static void operator delete(void* /*memory*/) {}
 };
 
 #define nsAutoPopupStatePusher NS_AUTO_POPUP_STATE_PUSHER
--- a/dom/tests/browser/Makefile.in
+++ b/dom/tests/browser/Makefile.in
@@ -50,13 +50,12 @@ include $(topsrcdir)/config/rules.mk
 		browser_autofocus_background.js \
 		browser_ConsoleAPITests.js \
 		test-console-api.html \
 		browser_ConsoleStorageAPITests.js \
 		browser_ConsoleStoragePBTest.js \
 		browser_autofocus_preference.js \
 		browser_popup_blocker_save_open_panel.js \
 		browser_bug396843.js \
-		browser_popup_blocker_multiple_popups.js \
 		$(NULL)
 
 libs::	$(_BROWSER_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
deleted file mode 100644
--- a/dom/tests/browser/browser_popup_blocker_multiple_popups.js
+++ /dev/null
@@ -1,300 +0,0 @@
-/**
- * In this test, we check that the content can't open more than one popup at a
- * time (depending on "dom.allow_mulitple_popups" preference value).
- */
-
-let wm = Cc["@mozilla.org/appshell/window-mediator;1"]
-           .getService(Ci.nsIWindowMediator);
-let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"]
-           .getService(Ci.nsIWindowWatcher);
-let prefs = Cc["@mozilla.org/preferences-service;1"]
-              .getService(Components.interfaces.nsIPrefBranch);
-let gMultiplePopupsPref;
-
-let gCurrentTest = -1;
-let gTests = [
-  test1,
-  test2,
-  test3,
-  test4,
-  test5,
-  test6,
-];
-
-function cleanUpPopups()
-{
-  let windowEnumerator = wm.getEnumerator(null);
-
-  while (windowEnumerator.hasMoreElements()) {
-    let win = windowEnumerator.getNext();
-
-    // Close all windows except ourself and the browser test harness window.
-    if (win != window && !win.closed &&
-        win.document.documentElement.getAttribute("id") != "browserTestHarness") {
-      win.close();
-    }
-  }
-}
-
-function cleanUp()
-{
-  prefs.setBoolPref("dom.block_multiple_popups", gMultiplePopupsPref);
-  cleanUpPopups(window);
-}
-
-function nextOrFinish()
-{
-  gCurrentTest++;
-
-  if (gCurrentTest >= gTests.length) {
-    finish();
-    return;
-  }
-
-  gTests[gCurrentTest]();
-}
-
-function test()
-{
-  waitForExplicitFinish();
-
-  gMultiplePopupsPref = prefs.getBoolPref("dom.block_multiple_popups");
-
-  nextOrFinish();
-}
-
-/**
- * Two window.open();
- */
-function test1()
-{
-  prefs.setBoolPref("dom.block_multiple_popups", true);
-
-  gBrowser.selectedTab.linkedBrowser.addEventListener("load", function () {
-    gBrowser.selectedTab.linkedBrowser.removeEventListener("load", arguments.callee, true);
-
-    gBrowser.addEventListener("DOMPopupBlocked", function() {
-      gBrowser.removeEventListener("DOMPopupBlocked", arguments.callee, true);
-
-      ok(true, "The popup has been blocked");
-
-      cleanUp();
-      nextOrFinish();
-    }, true);
-
-    waitForFocus(function() {
-      var button = gBrowser.selectedTab.linkedBrowser.contentDocument.getElementsByTagName('button')[0];
-      EventUtils.synthesizeMouseAtCenter(button, {}, gBrowser.selectedTab.linkedBrowser.contentWindow);
-    });
-  }, true);
-
-  gBrowser.selectedTab.linkedBrowser.loadURI("data:text/html,<!DOCTYPE html><html><body><script>function openPopups() { window.open('data:text/html,foo', '', 'foo'); window.open('data:text/html,bar', '', 'foo'); }</script><button onclick='openPopups();'>click</button></body></html>");
-}
-
-/**
- * window.open followed by w.open with w being the first popup.
- */
-function test2()
-{
-  prefs.setBoolPref("dom.block_multiple_popups", true);
-
-  let gPopupsCount = 0;
-
-  gBrowser.selectedTab.linkedBrowser.addEventListener("load", function () {
-    gBrowser.selectedTab.linkedBrowser.removeEventListener("load", arguments.callee, true);
-
-    ww.registerNotification(function(aSubject, aTopic, aData) {
-      if (aTopic != "domwindowopened") {
-        return;
-      }
-
-      gPopupsCount++;
-
-      if (gPopupsCount > 1) {
-        return;
-      }
-
-      executeSoon(function() {
-      executeSoon(function() {
-      executeSoon(function() {
-      executeSoon(function() {
-        ww.unregisterNotification(arguments.callee);
-
-        is(gPopupsCount, 1, "Only one popup appeared");
-        cleanUp();
-        nextOrFinish();
-      });
-      });
-      });
-      });
-    });
-
-    waitForFocus(function() {
-      var button = gBrowser.selectedTab.linkedBrowser.contentDocument.getElementsByTagName('button')[0];
-      EventUtils.synthesizeMouseAtCenter(button, {}, gBrowser.selectedTab.linkedBrowser.contentWindow);
-    });
-  }, true);
-
-  gBrowser.selectedTab.linkedBrowser.loadURI("data:text/html,<!DOCTYPE html><html><body><script>function openPopups() { var w = window.open('data:text/html,foo', '', 'foo'); w.open('data:text/html,bar', '', 'foo'); }</script><button onclick='openPopups();'>click</button></body></html>");
-}
-
-/**
- * window.open followed by w.open with w being the first popup and the second popup being actually a tab.
- */
-function test3()
-{
-  prefs.setBoolPref("dom.block_multiple_popups", true);
-
-  let gPopupsCount = 0;
-
-  gBrowser.selectedTab.linkedBrowser.addEventListener("load", function () {
-    gBrowser.selectedTab.linkedBrowser.removeEventListener("load", arguments.callee, true);
-
-    ww.registerNotification(function(aSubject, aTopic, aData) {
-      if (aTopic != "domwindowopened") {
-        return;
-      }
-
-      gPopupsCount++;
-
-      if (gPopupsCount > 1) {
-        return;
-      }
-
-      executeSoon(function() {
-      executeSoon(function() {
-      executeSoon(function() {
-      executeSoon(function() {
-        ww.unregisterNotification(arguments.callee);
-
-        is(gPopupsCount, 1, "Only one popup appeared");
-        cleanUp();
-        nextOrFinish();
-      });
-      });
-      });
-      });
-    });
-
-    waitForFocus(function() {
-      var button = gBrowser.selectedTab.linkedBrowser.contentDocument.getElementsByTagName('button')[0];
-      EventUtils.synthesizeMouseAtCenter(button, {}, gBrowser.selectedTab.linkedBrowser.contentWindow);
-    });
-  }, true);
-
-  gBrowser.selectedTab.linkedBrowser.loadURI("data:text/html,<!DOCTYPE html><html><body><script>function openPopups() { var w = window.open('data:text/html,foo', '', 'foo'); w.open('data:text/html,bar', '', ''); }</script><button onclick='openPopups();'>click</button></body></html>");
-}
-
-/**
- * window.open and .click() on the element opening the window.
- */
-function test4()
-{
-  prefs.setBoolPref("dom.block_multiple_popups", true);
-
-  gBrowser.selectedTab.linkedBrowser.addEventListener("load", function () {
-    gBrowser.selectedTab.linkedBrowser.removeEventListener("load", arguments.callee, true);
-
-    gBrowser.addEventListener("DOMPopupBlocked", function() {
-      gBrowser.removeEventListener("DOMPopupBlocked", arguments.callee, true);
-
-      ok(true, "The popup has been blocked");
-
-      cleanUp();
-      nextOrFinish();
-    }, true);
-
-    waitForFocus(function() {
-      var button = gBrowser.selectedTab.linkedBrowser.contentDocument.getElementsByTagName('button')[0];
-      EventUtils.synthesizeMouseAtCenter(button, {}, gBrowser.selectedTab.linkedBrowser.contentWindow);
-    });
-  }, true);
-
-  gBrowser.selectedTab.linkedBrowser.loadURI("data:text/html,<!DOCTYPE html><html><body><script>var r = false; function openPopups() { window.open('data:text/html,foo', '', 'foo'); if (!r) { document.getElementsByTagName('button')[0].click(); r=true; } }</script><button onclick='openPopups();'>click</button></body></html>");
-}
-
-/**
- * Two window.open from the chrome.
- */
-function test5()
-{
-  prefs.setBoolPref("dom.block_multiple_popups", true);
-
-  let gPopupsCount = 0;
-
-  ww.registerNotification(function(aSubject, aTopic, aData) {
-    if (aTopic != "domwindowopened") {
-      return;
-    }
-
-    gPopupsCount++;
-
-    if (gPopupsCount != 2) {
-      return;
-    }
-
-    executeSoon(function() {
-    executeSoon(function() {
-    executeSoon(function() {
-    executeSoon(function() {
-      ww.unregisterNotification(arguments.callee);
-
-      is(gPopupsCount, 2, "Both window appeared");
-      cleanUp();
-      nextOrFinish();
-    });
-    });
-    });
-    });
-  });
-
-  window.open("data:text/html,foo", '', 'foo');
-  window.open("data:text/html,foo", '', 'foo');
-}
-
-/**
- * Two window.open with the pref being disabled.
- */
-function test6()
-{
-  prefs.setBoolPref("dom.block_multiple_popups", false);
-
-  let gPopupsCount = 0;
-
-  gBrowser.selectedTab.linkedBrowser.addEventListener("load", function () {
-    gBrowser.selectedTab.linkedBrowser.removeEventListener("load", arguments.callee, true);
-
-    ww.registerNotification(function(aSubject, aTopic, aData) {
-      if (aTopic != "domwindowopened") {
-        return;
-      }
-
-      gPopupsCount++;
-
-      if (gPopupsCount != 2) {
-        return;
-      }
-
-      executeSoon(function() {
-      executeSoon(function() {
-      executeSoon(function() {
-      executeSoon(function() {
-        ww.unregisterNotification(arguments.callee);
-
-        is(gPopupsCount, 2, "Both window appeared");
-        cleanUp();
-        nextOrFinish();
-      });
-      });
-      });
-      });
-    });
-
-    waitForFocus(function() {
-      var button = gBrowser.selectedTab.linkedBrowser.contentDocument.getElementsByTagName('button')[0];
-      EventUtils.synthesizeMouseAtCenter(button, {}, gBrowser.selectedTab.linkedBrowser.contentWindow);
-    });
-  }, true);
-
-  gBrowser.selectedTab.linkedBrowser.loadURI("data:text/html,<!DOCTYPE html><html><body><script>function openPopups() { window.open('data:text/html,foo', '', 'foo'); window.open('data:text/html,bar', '', 'foo'); }</script><button onclick='openPopups();'>click</button></body></html>");
-}
--- a/dom/tests/mochitest/bugs/test_bug346659.html
+++ b/dom/tests/mochitest/bugs/test_bug346659.html
@@ -23,19 +23,16 @@ https://bugzilla.mozilla.org/show_bug.cg
 var numTestsSet1 = 6;
 var numTestsSet2 = 4;
 var numTestsSet3 = 2;
 var complete = 0;
 SimpleTest.waitForExplicitFinish();
 
 var wins = [];
 
-var gBlockMultiplePopups = SpecialPowers.getBoolPref("dom.block_multiple_popups");
-SpecialPowers.setBoolPref("dom.block_multiple_popups", false);
-
 function r(base, tail) {
   return base.replace(/\/[^\/]*$/, "/" + tail);
 }
 
 function handleCmd(evt) {
   var cmd;
   try {
     cmd = JSON.parse(evt.data);
@@ -151,17 +148,16 @@ function handleTestEnd() {
     }
   } else if (numTestsSet2) {
     if (!--numTestsSet2) {
       // gc to get rid of all the old windows
       gc(); gc(); gc();
       setTimeout(startThirdBatch, 0);
     }
   } else if (!--numTestsSet3) {
-    SpecialPowers.setBoolPref("dom.block_multiple_popups", gBlockMultiplePopups);
     SimpleTest.finish();
   }
 }
 window.addEventListener("message", messageReceiver, false);
 
 var win = window.open("");
 win.x = 1;
 win.location.href = "bug346659-echoer.html";
--- a/dom/tests/mochitest/bugs/test_bug406375.html
+++ b/dom/tests/mochitest/bugs/test_bug406375.html
@@ -18,22 +18,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 <script type="application/javascript">
 
 /** Test for Bug 406375 **/
 
 
 SimpleTest.waitForExplicitFinish();
 
 function runTest() {
-  var blockMultiplePopups = SpecialPowers.getBoolPref("dom.block_multiple_popups");
-  SpecialPowers.setBoolPref("dom.block_multiple_popups", false);
-
   window.showModalDialog("file_bug406375.html");
   ok(true, "This test should not hang");
-
-  SpecialPowers.setBoolPref("dom.block_multiple_popups", blockMultiplePopups);
   SimpleTest.finish();
 }
 
 </script>
 </pre>
 </body>
 </html>
--- a/dom/tests/mochitest/bugs/test_bug61098.html
+++ b/dom/tests/mochitest/bugs/test_bug61098.html
@@ -237,19 +237,16 @@ function resetDialogLoopBlocking()
 
   prefs.setIntPref("dom.successive_dialog_time_limit", 0);
 }
 
 var expectedState;
 
 function runtests()
 {
-  var blockMultiplePopups = SpecialPowers.getBoolPref("dom.block_multiple_popups");
-  SpecialPowers.setBoolPref("dom.block_multiple_popups", false);
-
   registerMockPromptService();
   enableDialogLoopBlocking();
 
   // Test that alert() works normally and then gets blocked on the
   // second call.
   w = window.open();
   w.alert("alert message 1");
   is (promptState.method, "alert", "Wrong prompt method called");
@@ -346,16 +343,14 @@ function runtests()
 
   w.close();
 
   resetDialogLoopBlocking();
 
   mockPromptFactoryRegisterer.unregister();
   mockPromptServiceRegisterer.unregister();
 
-  SpecialPowers.setBoolPref("dom.block_multiple_popups", blockMultiplePopups);
-
   SimpleTest.finish();
 }
 
 </script>
 </body>
 </html>
--- a/dom/tests/mochitest/chrome/test_popup_blocker_chrome.xul
+++ b/dom/tests/mochitest/chrome/test_popup_blocker_chrome.xul
@@ -1,115 +1,54 @@
 <?xml version="1.0"?>
 <?xml-stylesheet type="text/css" href="chrome://global/skin"?>
 <?xml-stylesheet type="text/css" href="/tests/SimpleTest/test.css"?>
 <!--
 https://bugzilla.mozilla.org/show_bug.cgi?id=662519
 -->
-<window title="Mozilla Bug 662519 and Bug 675574"
+<window title="Mozilla Bug 662519"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
   <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
 
   <!-- test results are displayed in the html:body -->
   <body xmlns="http://www.w3.org/1999/xhtml">
   <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=662519"
      target="_blank">Mozilla Bug 662519</a>
-  <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=675574"
-     target="_blank">Mozilla Bug 675574</a>
-  <button onclick="window.open('data:text/html,foo', '', 'foo'); window.open('data:text/html,bar', '', 'bar');">click</button>
   </body>
 
   <!-- test code goes here -->
   <script type="application/javascript">
   <![CDATA[
 
   /** Test for Bug 662519 **/
 
-  let Cc = Components.classes;
-  let Ci = Components.interfaces;
-
   SimpleTest.waitForExplicitFinish();
 
   // We have to enable dom.disable_open_during_load which is disabled
   // by the test harness.
-  let prefs = Cc["@mozilla.org/preferences-service;1"]
-                .getService(Ci.nsIPrefBranch);
-  let gLastDomLoadValue = prefs.getBoolPref("dom.disable_open_during_load");
-  let gMultiplePopupsPref = prefs.getBoolPref("dom.block_multiple_popups");
-
+  let prefs = Components.classes["@mozilla.org/preferences-service;1"]
+                .getService(Components.interfaces.nsIPrefBranch);
+  var gLastDomLoadValue = prefs.getBoolPref("dom.disable_open_during_load");
   prefs.setBoolPref("dom.disable_open_during_load", true);
-  prefs.setBoolPref("dom.block_multiple_popups", true);
+
+  let w = window.open("data:text/html,foobar", "", "width=200,height=200");
+  ok(w, "The window object shouldn't be null");
 
-  function test1() {
-    let w = window.open("data:text/html,foobar", "", "width=200,height=200");
-    ok(w, "The window object shouldn't be null");
+  SimpleTest.waitForFocus(function() {
+    w.close();
+    ok(true, "The popup appeared");
 
     SimpleTest.waitForFocus(function() {
-      w.close();
-      ok(true, "The popup appeared");
+      let w = window.open("data:text/html,foobar", "", "width=200,height=200");
+      ok(w, "The window object shouldn't be null");
 
       SimpleTest.waitForFocus(function() {
-        let w = window.open("data:text/html,foobar", "", "width=200,height=200");
-        ok(w, "The window object shouldn't be null");
-
-        SimpleTest.waitForFocus(function() {
-          w.close();
-
-          ok(true, "The popup appeared");
-          test2();
-        }, w, false);
-      });
-    }, w, false);
-  }
-
-  function test2() {
-    let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"]
-               .getService(Ci.nsIWindowWatcher);
-
-    let gPopupsCount = 0;
-
-    ww.registerNotification(function(aSubject, aTopic, aData) {
-      if (aTopic != "domwindowopened") {
-        return;
-      }
-
-      gPopupsCount++;
+        w.close();
 
-      if (gPopupsCount != 2) {
-        return;
-      }
-
-      SimpleTest.executeSoon(function() {
-      SimpleTest.executeSoon(function() {
-      SimpleTest.executeSoon(function() {
-      SimpleTest.executeSoon(function() {
-        ww.unregisterNotification(arguments.callee);
-
-        is(gPopupsCount, 2, "Both window appeared");
-
-        // Clean-up and finish.
-        let windowEnumerator = wm.getEnumerator(null);
-
-        while (windowEnumerator.hasMoreElements()) {
-          let win = windowEnumerator.getNext();
-
-          // Close all windows except ourself.
-          if (win != window && !win.closed) {
-            win.close();
-          }
-        }
-
-        prefs.setBoolPref("dom.block_multiple_popups", gMultiplePopupsPref);
+        ok(true, "The popup appeared");
         prefs.setBoolPref("dom.disable_open_during_load", gLastDomLoadValue);
         SimpleTest.finish();
-      });
-      });
-      });
-      });
+      }, w, false);
     });
-
-    EventUtils.synthesizeMouseAtCenter(document.getElementsByTagName('button')[0], {});
-  }
-
-  SimpleTest.waitForFocus(test1);
+  }, w, false);
   ]]>
   </script>
 </window>
--- a/gfx/2d/Logging.h
+++ b/gfx/2d/Logging.h
@@ -82,17 +82,17 @@ static void OutputMessage(const std::str
     ::OutputDebugStringA(aString.c_str());
   }
 #elif defined(PR_LOGGING)
   if (PR_LOG_TEST(sGFX2DLog, PRLogLevelForLevel(aLevel))) {
     PR_LogPrint(aString.c_str());
   }
 #else
   if (aLevel >= sGfxLogLevel) {
-    printf(aString.c_str());
+    printf("%s", aString.c_str());
   }
 #endif
 }
 
 class NoLog
 {
 public:
   NoLog() {}
--- a/js/src/ds/LifoAlloc.cpp
+++ b/js/src/ds/LifoAlloc.cpp
@@ -1,8 +1,48 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sw=4 et tw=99 ft=cpp:
+ *
+ * ***** 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 SpiderMonkey JavaScript code.
+ *
+ * The Initial Developer of the Original Code is
+ * the Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Chris Leary <cdleary@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
+ * 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 "LifoAlloc.h"
 
 #include <new>
 
 using namespace js;
 
 namespace js {
 namespace detail {
--- a/js/src/ds/LifoAlloc.h
+++ b/js/src/ds/LifoAlloc.h
@@ -9,28 +9,29 @@
  * 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 SpiderMonkey JavaScript 1.9 code, released
- * June 12, 2009.
+ * The Original Code is Mozilla SpiderMonkey JavaScript code.
  *
  * The Initial Developer of the Original Code is
- *   the Mozilla Corporation.
+ * the Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
- *   Chris Leary <cdleary@mozilla.com>
+ *  Chris Leary <cdleary@mozilla.com>
  *
  * Alternatively, the contents of this file may be used under the terms of
- * either of 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"),
+ * 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.
--- a/js/src/jsapi-tests/testDebugger.cpp
+++ b/js/src/jsapi-tests/testDebugger.cpp
@@ -287,8 +287,37 @@ BEGIN_TEST(testDebugger_singleStepThrow)
     }
 
     static JSTrapStatus
     onStep(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval, void *closure)
     {
         return JSTRAP_CONTINUE;
     }
 END_TEST(testDebugger_singleStepThrow)
+
+BEGIN_TEST(testDebugger_emptyObjectPropertyIterator)
+{
+    JSObject *obj = JS_NewObject(cx, NULL, NULL, NULL);
+    JSScopeProperty *prop = NULL;
+    CHECK(!JS_PropertyIterator(obj, &prop));
+    CHECK(!prop);
+
+    return true;
+}
+END_TEST(testDebugger_emptyObjectPropertyIterator)
+
+BEGIN_TEST(testDebugger_nonEmptyObjectPropertyIterator)
+{
+    jsval v;
+    EVAL("({a: 15})", &v);
+    JSObject *obj = JSVAL_TO_OBJECT(v);
+    JSScopeProperty *prop = NULL;
+    CHECK(JS_PropertyIterator(obj, &prop));
+    JSPropertyDesc desc;
+    CHECK(JS_GetPropertyDesc(cx, obj, prop, &desc));
+    CHECK_EQUAL(JSVAL_IS_INT(desc.value), true);
+    CHECK_EQUAL(JSVAL_TO_INT(desc.value), 15);
+    CHECK(!JS_PropertyIterator(obj, &prop));
+    CHECK(!prop);
+
+    return true;
+}
+END_TEST(testDebugger_nonEmptyObjectPropertyIterator)
--- a/js/src/jsdbgapi.cpp
+++ b/js/src/jsdbgapi.cpp
@@ -842,24 +842,24 @@ JS_EvaluateInStackFrame(JSContext *cx, J
 
 JS_PUBLIC_API(JSScopeProperty *)
 JS_PropertyIterator(JSObject *obj, JSScopeProperty **iteratorp)
 {
     const Shape *shape;
 
     /* The caller passes null in *iteratorp to get things started. */
     shape = (Shape *) *iteratorp;
-    if (!shape) {
+    if (!shape)
         shape = obj->lastProperty();
-    } else {
+    else
         shape = shape->previous();
-        if (!shape->previous()) {
-            JS_ASSERT(JSID_IS_EMPTY(shape->propid));
-            shape = NULL;
-        }
+
+    if (!shape->previous()) {
+        JS_ASSERT(JSID_IS_EMPTY(shape->propid));
+        shape = NULL;
     }
 
     return *iteratorp = reinterpret_cast<JSScopeProperty *>(const_cast<Shape *>(shape));
 }
 
 JS_PUBLIC_API(JSBool)
 JS_GetPropertyDesc(JSContext *cx, JSObject *obj, JSScopeProperty *sprop,
                    JSPropertyDesc *pd)
--- a/layout/xul/base/src/nsResizerFrame.cpp
+++ b/layout/xul/base/src/nsResizerFrame.cpp
@@ -118,44 +118,46 @@ nsResizerFrame::HandleEvent(nsPresContex
               rect.Deflate(frameToResize->GetUsedPadding());
             case NS_STYLE_BOX_SIZING_PADDING:
               rect.Deflate(frameToResize->GetUsedBorder());
             default:
               break;
           }
 
           mMouseDownRect = rect.ToNearestPixels(aPresContext->AppUnitsPerDevPixel());
+          doDefault = PR_FALSE;
         }
         else {
+          // If there is no window, then resizing isn't allowed.
+          if (!window)
+            break;
+
+          doDefault = PR_FALSE;
+            
           // ask the widget implementation to begin a resize drag if it can
           Direction direction = GetDirection();
           nsresult rv = aEvent->widget->BeginResizeDrag(aEvent,
                         direction.mHorizontal, direction.mVertical);
-          if (rv == NS_ERROR_NOT_IMPLEMENTED && window) {
-            // if there's no native resize support, we need to do window
-            // resizing ourselves
-            window->GetPositionAndSize(&mMouseDownRect.x, &mMouseDownRect.y,
-                                       &mMouseDownRect.width, &mMouseDownRect.height);
-          }
-          else {
-            // for native drags, don't set the fields below
-            doDefault = PR_FALSE;
-            break;
-          }
+          // for native drags, don't set the fields below
+          if (rv != NS_ERROR_NOT_IMPLEMENTED)
+             break;
+             
+          // if there's no native resize support, we need to do window
+          // resizing ourselves
+          window->GetPositionAndSize(&mMouseDownRect.x, &mMouseDownRect.y,
+                                     &mMouseDownRect.width, &mMouseDownRect.height);
         }
 
         // we're tracking
         mTrackingMouseMove = PR_TRUE;
 
         // remember current mouse coordinates
         mMouseDownPoint = aEvent->refPoint + aEvent->widget->WidgetToScreenOffset();
 
         nsIPresShell::SetCapturingContent(GetContent(), CAPTURE_IGNOREALLOWED);
-
-        doDefault = PR_FALSE;
       }
     }
     break;
 
   case NS_MOUSE_BUTTON_UP: {
 
     if (mTrackingMouseMove && aEvent->eventStructType == NS_MOUSE_EVENT &&
         static_cast<nsMouseEvent*>(aEvent)->button == nsMouseEvent::eLeftButton)
@@ -353,17 +355,17 @@ nsResizerFrame::GetContentToResize(nsIPr
       isChromeShell = (NS_SUCCEEDED(dsti->GetItemType(&type)) &&
                        type == nsIDocShellTreeItem::typeChrome);
     }
 
     if (!isChromeShell) {
       // don't allow resizers in content shells, except for the viewport
       // scrollbar which doesn't have a parent
       nsIContent* nonNativeAnon = mContent->FindFirstNonNativeAnonymous();
-      if (nonNativeAnon && !nonNativeAnon->GetParent()) {
+      if (!nonNativeAnon || nonNativeAnon->GetParent()) {
         return nsnull;
       }
     }
 
     // get the document and the window - should this be cached?
     nsPIDOMWindow *domWindow = aPresShell->GetDocument()->GetWindow();
     if (domWindow) {
       nsCOMPtr<nsIDocShellTreeItem> docShellAsItem =
--- a/layout/xul/base/test/Makefile.in
+++ b/layout/xul/base/test/Makefile.in
@@ -50,17 +50,19 @@ include $(topsrcdir)/config/rules.mk
 
 _CHROME_FILES =	test_bug381167.xhtml \
 		test_bug393970.xul \
 		test_bug477754.xul \
 		test_stack.xul \
 		$(NULL)
 
 ifneq (mobile,$(MOZ_BUILD_APP))
-_TEST_FILES +=	test_resizer.xul \
+_TEST_FILES = 	test_resizer_incontent.xul
+
+_CHROME_FILES +=	test_resizer.xul \
 		window_resizer.xul \
 		window_resizer_element.xul \
 		$(NULL)
 endif
 
 libs:: $(_CHROME_FILES)
 	$(INSTALL) $^ $(DEPTH)/_tests/testing/mochitest/chrome/$(relativesrcdir)
 
--- a/layout/xul/base/test/test_bug511075.html
+++ b/layout/xul/base/test/test_bug511075.html
@@ -63,16 +63,17 @@ var tests = [
     nextTest();
     // Click the scrollbar.
     var x = scroller.getBoundingClientRect().width - 5;
     var y = scroller.getBoundingClientRect().height - 50;
     synthesizeMouse(scroller, x, y, { type : "mousedown" }, window);
     synthesizeMouse(scroller, x, y, { type: "mouseup" }, window);
   },
   function() {
+    scroller.onscroll = null;
     ok(true, "Clicking the scrollbar should scroll");
     finish();
   }
 ];
 
 document.onmousedown = function () { return false; };
 document.onmouseup = function () { return true; };
 
--- a/layout/xul/base/test/test_resizer.xul
+++ b/layout/xul/base/test/test_resizer.xul
@@ -1,19 +1,18 @@
 <?xml version="1.0"?>
 <?xml-stylesheet href="chrome://global/skin" type="text/css"?>
-<?xml-stylesheet href="/tests/SimpleTest/test.css" type="text/css"?>
-<?xml-stylesheet href="data:text/css,description {min-width: 1px; padding: 2px;}" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
 <!--
 XUL <resizer> tests
 -->
 <window title="XUL resizer tests"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"/>
-  <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"/>
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
 
   <!-- test results are displayed in the html:body -->
   <body xmlns="http://www.w3.org/1999/xhtml">
   </body>
 
   <!-- test code goes here -->
   <script type="application/javascript"><![CDATA[
     SimpleTest.waitForExplicitFinish();
@@ -63,39 +62,28 @@ XUL <resizer> tests
     function doResizerWindowTests() {
       step++;
       if (step == 1) {
         openPopup();
         return;
       }
 
       if (/Mac/.test(navigator.platform)) {
-        netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserWrite");
         window.open("window_resizer.xul", "_blank", "left=200,top=200,outerWidth=300,outerHeight=300,chrome");
       }
       else {
         // Skip window_resizer.xul tests.
         todo(false, "We can't test GTK and Windows native drag resizing implementations.");
         // Run window_resizer_element.xul test only.
         lastResizerTest();
       }
     }
 
-    function nextResizerTest()
-    {
-      // try opening the test again as a chrome window
-      if (step++ == 2)
-        window.open("window_resizer.xul", "_blank", "left=200,top=200,outerWidth=300,outerHeight=300");
-      else
-        lastResizerTest();
-    }
-
     function lastResizerTest()
     {
-      netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserWrite");
       window.open("window_resizer_element.xul", "_blank", "left=200,top=200,outerWidth=300,outerHeight=300,chrome");
     }
 
     SimpleTest.waitForFocus(openPopup);
    ]]></script>
 
 <panel id="panel" onpopupshown="popupShown(event)" onpopuphidden="doResizerWindowTests()">
   <resizer id="resizer" dir="bottomend" width="16" height="16"/>
new file mode 100644
--- /dev/null
+++ b/layout/xul/base/test/test_resizer_incontent.xul
@@ -0,0 +1,42 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="/tests/SimpleTest/test.css" type="text/css"?>
+<!--
+This test ensures that a resizer in content doesn't resize the window.
+-->
+<window title="XUL resizer in content test"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"/>
+  <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"/>
+
+  <!-- test results are displayed in the html:body -->
+  <body xmlns="http://www.w3.org/1999/xhtml">
+  </body>
+
+  <!-- test code goes here -->
+  <script type="application/javascript"><![CDATA[
+    SimpleTest.waitForExplicitFinish();
+
+    function testResizer()
+    { 
+      var oldScreenX = window.screenX;
+      var oldScreenY = window.screenY;
+      var oldWidth = window.outerWidth;
+      var oldHeight = window.outerHeight;
+      var resizer = document.getElementById("resizer");
+      synthesizeMouseAtCenter(resizer, { type:"mousedown" });
+      synthesizeMouse(resizer, 32, 32, { type:"mousemove" });
+      synthesizeMouse(resizer, 32, 32, { type:"mouseup" });
+      is(window.screenX, oldScreenX, "window not moved for non-chrome window screenX");
+      is(window.screenY, oldScreenY, "window not moved for non-chrome window screenY");
+      is(window.outerWidth, oldWidth, "window not moved for non-chrome window outerWidth");
+      is(window.outerHeight, oldHeight, "window not moved for non-chrome window outerHeight");
+      SimpleTest.finish();
+    }
+
+    SimpleTest.waitForFocus(testResizer);
+   ]]></script>
+
+  <resizer id="resizer" dir="bottomend" width="16" height="16"/>
+
+</window>
--- a/layout/xul/base/test/window_resizer.xul
+++ b/layout/xul/base/test/window_resizer.xul
@@ -1,13 +1,13 @@
 <?xml-stylesheet href="chrome://global/skin" type="text/css"?>
 <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
     screenX="200" screenY="200" width="300" height="300"
 	onload="setTimeout(doTest, 0)">
-<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
 <script><![CDATA[
 var is = window.opener.SimpleTest.is;
 
 function doTest() {
   // from test_resizer.xul
   var expectX = 200;
   var expectY = 200;
   var expectXMost = 500;
@@ -41,32 +41,24 @@ function doTest() {
         if (dy < 0) {
           newExpectY += mouseY*scale;
         } else if (dy > 0) {
           newExpectYMost += mouseY*scale;
         }
 
         synthesizeMouse(root, offsetX, offsetY, { type:"mousedown" });
         synthesizeMouse(root, offsetX + mouseX*scale, offsetY + mouseY*scale, { type:"mousemove" });
-        if (window instanceof Components.interfaces.nsIDOMChromeWindow) {
-          is(window.screenX*screenScale, newExpectX,
-             "Bad x for " + dx + "," + dy + " moving " + mouseX + "," + mouseY);
-          is(window.screenY*screenScale, newExpectY,
-             "Bad y for " + dx + "," + dy + " moving " + mouseX + "," + mouseY);
-          is(window.outerWidth, newExpectXMost - newExpectX,
-             "Bad width for " + dx + "," + dy + " moving " + mouseX + "," + mouseY);
-          is(window.outerHeight, newExpectYMost - newExpectY,
-             "Bad height for " + dx + "," + dy + " moving " + mouseX + "," + mouseY);
-        }
-        else {
-          is(window.screenX, oldScreenX, "window not moved for non-chrome window screenX");
-          is(window.screenY, oldScreenY, "window not moved for non-chrome window screenY");
-          is(window.outerWidth, oldWidth, "window not moved for non-chrome window outerWidth");
-          is(window.outerHeight, oldHeight, "window not moved for non-chrome window outerHeight");
-        }
+        is(window.screenX*screenScale, newExpectX,
+           "Bad x for " + dx + "," + dy + " moving " + mouseX + "," + mouseY);
+        is(window.screenY*screenScale, newExpectY,
+           "Bad y for " + dx + "," + dy + " moving " + mouseX + "," + mouseY);
+        is(window.outerWidth, newExpectXMost - newExpectX,
+           "Bad width for " + dx + "," + dy + " moving " + mouseX + "," + mouseY);
+        is(window.outerHeight, newExpectYMost - newExpectY,
+           "Bad height for " + dx + "," + dy + " moving " + mouseX + "," + mouseY);
 
         // move it back before we release! Adjust for any window movement
         synthesizeMouse(root, offsetX - (newExpectX - expectX),
                               offsetY - (newExpectY - expectY), { type:"mousemove" });
         synthesizeMouse(root, offsetX, offsetY, { type:"mouseup" });
       }
     }
   }
@@ -93,17 +85,17 @@ function doTest() {
   Array.forEach(resizers, function (element) {
     is(getComputedStyle(element, "").cursor,
        element.dir == "bottomend" ? "sw-resize" :
          element.getAttribute("expectedcursor"),
        "cursor for " + element.dir);
   });
 
   window.close();
-  window.opener.nextResizerTest();
+  window.opener.lastResizerTest();
 }
 ]]></script>
 	<hbox id="container" flex="1">
 		<vbox flex="1">
 			<resizer dir="topleft" expectedcursor="nw-resize" flex="1"/>
 			<resizer dir="left" expectedcursor="ew-resize" flex="1"/>
 			<resizer dir="bottomleft" expectedcursor="sw-resize" flex="1"/>
 		</vbox>
--- a/layout/xul/base/test/window_resizer_element.xul
+++ b/layout/xul/base/test/window_resizer_element.xul
@@ -1,12 +1,12 @@
 <?xml-stylesheet href="chrome://global/skin" type="text/css"?>
 <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         align="start">
-<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
 <script><![CDATA[
 var is = window.opener.SimpleTest.is;
 
 const anchorPositions =
   [ "before_start", "before_end", "after_start", "after_end",
     "start_before", "start_after", "end_before", "end_after", "overlap", "screen"];
 var currentPosition;
 
@@ -38,25 +38,26 @@ function testResizer(resizerid, noShrink
 
       var newrect = document.getElementById(resizerid + "-container").getBoundingClientRect();
       is(Math.round(newrect.width), Math.round(expectedWidth), "resize element " + resizerid +
          " " + testid + " width moving " + mouseX + "," + mouseY + ",,," + hResize);
       is(Math.round(newrect.height), Math.round(expectedHeight), "resize element " + resizerid +
          " " + testid + " height moving " + mouseX + "," + mouseY);
       // release
       synthesizeMouse(document.documentElement, originalX + 5 + mouseX * scale,
-                      originalY + 5 + mouseY * scale, { type:"mouseup" });    }
+                      originalY + 5 + mouseY * scale, { type:"mouseup" });
       // return to the original size
       synthesizeMouse(document.documentElement, originalX + 5 + mouseX * scale,
-                      originalY + 5 + mouseY * scale, { type:"dblclick" });    }
+                      originalY + 5 + mouseY * scale, { type:"dblclick" });
       var newrect = document.getElementById(resizerid + "-container").getBoundingClientRect();
       is(Math.round(newrect.width), Math.round(rect.width), "resize element " + resizerid +
          " " + testid + " doubleclicking to restore original size");
       is(Math.round(newrect.height), Math.round(rect.height), "resize element " + resizerid +
          " " + testid + " doubleclicking to restore original size");
+    }
   }
 }
 
 function doTest() {
   // first, check if a resizer with a element attribute set to an element that
   // does not exist does not cause a problem
   var resizer = document.getElementById("notfound");
   synthesizeMouse(resizer, 5, 5, { type:"mousedown" });
--- a/mobile/chrome/tests/Makefile.in
+++ b/mobile/chrome/tests/Makefile.in
@@ -92,16 +92,20 @@ include $(topsrcdir)/config/rules.mk
   browser_vkb.js \
   $(warning browser_viewport.js disabled due to failures) \
   browser_viewport.sjs \
   browser_scrollbar.sjs \
   browser_title.sjs \
   browser_thumbnails.js \
   browser_install.xml \
   browser_upgrade.rdf\
+  browser_localerepository.js \
+  browser_localerepository_pref.js \
+  browser_localerepository_buildid.js \
+  locales_list.sjs \
   mock_autocomplete.json\
   $(NULL)
 
 ifneq ($(OS_TARGET),Android)
 _BROWSER_FILES += \
   browser_autocomplete.html \
   browser_autocomplete.js \
   browser_bookmarks_star.js \
new file mode 100644
--- /dev/null
+++ b/mobile/chrome/tests/browser_localerepository.js
@@ -0,0 +1,39 @@
+var localeList = serverRoot + "locales_list.sjs";
+var PREF_LOCALE_LIST = "extensions.getLocales.get.url";
+
+Components.utils.import("resource://gre/modules/Services.jsm");
+Components.utils.import("resource://gre/modules/LocaleRepository.jsm");
+
+function test() {
+  waitForExplicitFinish();
+  runNextTest();
+}
+
+function end_test() {
+  Services.prefs.clearUserPref(PREF_LOCALE_LIST);
+}
+
+registerCleanupFunction(end_test);
+
+gTests.push({
+  desc: "Test getting a list of compatable locales",
+  run: function() {
+    Services.prefs.setCharPref(PREF_LOCALE_LIST, localeList);
+    LocaleRepository.getLocales(this.listLoaded);
+  },
+
+  listLoaded: function(aLocales) {
+    is(aLocales.length, 1, "Correct number of locales were found");
+    isnot(aLocales[0].addon, null, "Locale has an addon");
+    is(aLocales[0].xpiURL, "http://www.example.com/mylocale.xpi", "Locale has correct xpi url");
+    is(aLocales[0].xpiHash, null, "Locale has correct hash");
+
+    is(aLocales[0].addon.id, "langpack-test-1@firefox-mobile.mozilla.org", "Locale has correct id");
+    is(aLocales[0].addon.name, "Test Locale", "Locale has correct name");
+    is(aLocales[0].addon.type, "language", "Locale has correct type");
+
+    is(aLocales[0].addon.targetLocale, "test", "Locale has correct target locale");
+    is(aLocales[0].addon.version, "1.0", "Locale has correct version");
+    runNextTest();
+  }
+});
new file mode 100644
--- /dev/null
+++ b/mobile/chrome/tests/browser_localerepository_buildid.js
@@ -0,0 +1,41 @@
+var localeList = serverRoot + "locales_list.sjs";
+var PREF_LOCALE_LIST = "extensions.getLocales.get.url";
+
+Components.utils.import("resource://gre/modules/Services.jsm");
+Components.utils.import("resource://gre/modules/LocaleRepository.jsm");
+
+function test() {
+  waitForExplicitFinish();
+  runNextTest();
+}
+
+function end_test() {
+  Services.prefs.clearUserPref(PREF_LOCALE_LIST);
+}
+
+registerCleanupFunction(end_test);
+
+gTests.push({
+  desc: "Test dynamically changing extensions.getLocales.get.url",
+  run: function() {
+    Services.prefs.setCharPref(PREF_LOCALE_LIST, localeList + "?buildid=%BUILDID_EXPANDED%");
+    LocaleRepository.getLocales(this.listLoaded.bind(this), {buildID: "00001122334455"});
+  },
+
+  listLoaded: function(aLocales) {
+    is(aLocales.length, 1, "Correct number of locales were found");
+    is(aLocales[0].addon.name, "0000-11-22-33-44-55", "Buildid was correctly replaced");
+
+    Services.prefs.setCharPref(PREF_LOCALE_LIST, localeList + "?buildid=%BUILDID_EXPANDED%");
+    LocaleRepository.getLocales(this.secondListLoaded.bind(this));
+  },
+
+  secondListLoaded: function(aLocales) {
+    is(aLocales.length, 1, "Correct number of locales were found");
+
+    let buildID = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo).QueryInterface(Ci.nsIXULRuntime).appBuildID;
+    is(aLocales[0].addon.name.replace(/-/g, ""), buildID, "Buildid was correctly replaced");
+
+    runNextTest();
+  }
+});
new file mode 100644
--- /dev/null
+++ b/mobile/chrome/tests/browser_localerepository_pref.js
@@ -0,0 +1,35 @@
+var localeList = serverRoot + "locales_list.sjs";
+var PREF_LOCALE_LIST = "extensions.getLocales.get.url";
+
+Components.utils.import("resource://gre/modules/Services.jsm");
+Components.utils.import("resource://gre/modules/LocaleRepository.jsm");
+
+function test() {
+  waitForExplicitFinish();
+  runNextTest();
+}
+
+function end_test() {
+  Services.prefs.clearUserPref(PREF_LOCALE_LIST);
+}
+
+registerCleanupFunction(end_test);
+
+gTests.push({
+  desc: "Test dynamically changing extensions.getLocales.get.url",
+  run: function() {
+    Services.prefs.setCharPref(PREF_LOCALE_LIST, localeList);
+    LocaleRepository.getLocales(this.listLoaded.bind(this));
+  },
+
+  listLoaded: function(aLocales) {
+    is(aLocales.length, 1, "Correct number of locales were found");
+    Services.prefs.setCharPref(PREF_LOCALE_LIST, localeList + "?numvalid=2");
+    LocaleRepository.getLocales(this.secondListLoaded.bind(this));
+  },
+
+  secondListLoaded: function(aLocales) {
+    is(aLocales.length, 2, "Correct number of locales were found");
+    runNextTest();
+  }
+});
new file mode 100644
--- /dev/null
+++ b/mobile/chrome/tests/locales_list.sjs
@@ -0,0 +1,121 @@
+let fennecID = "{a23983c0-fd0e-11dc-95ff-0800200c9a66}";
+Components.utils.import("resource://gre/modules/Services.jsm");
+
+function getLocale(aLocaleParams, aAppParams) {
+ let l = {
+  TARGETLOCALE: "test",
+  NAME: "Test Locale",
+  VERSION: "1.0",
+  INSTALL: "http://www.example.com/mylocale.xpi",
+  TYPENUMBER: 5,
+  TYPENAME: "Language Pack (Application)",
+  IDNUMBER: "",
+ };
+ let a = {
+  APPNAME: "Fennec",
+  MINVERSION: "4.0", MAXVERSION: "*",
+  APPID: fennecID
+ };
+
+ if (aLocaleParams) {
+  for (var entry in aLocaleParams) {
+   l[entry] = aLocaleParams[entry];
+  }
+ }
+
+ if (aAppParams) {
+  for (var entry in aAppParams) {
+   a[entry] = aAppParams[entry];
+  }
+ }
+
+ l.app = a;
+ return l;
+}
+
+let appTemplate = "<application>" +
+"<name>{APPNAME}</name>" +
+ "<min_version>{MINVERSION}</min_version>" +
+ "<max_version>{MAXVERSION}</max_version>" +
+ "<appID>{APPID}</appID>" +
+"</application>";
+
+let template = "<addon>"+
+ "<target_locale>{TARGETLOCALE}</target_locale>" +
+ "<name>{NAME}</name>"+
+ "<type id=\"{TYPENUMBER}\">{TYPENAME}</type>"+
+ "<guid>langpack-{TARGETLOCALE}-{IDNUMBER}@firefox-mobile.mozilla.org</guid>"+
+ "<version>{VERSION}</version>"+
+ "<status id=\"4\">Public</status>"+
+ "<compatible_applications>{APPS}</compatible_applications>"+
+ "<all_compatible_os><os>ALL</os></all_compatible_os>"+
+ "<install os=\"ALL\">{INSTALL}</install><strings>\n" +
+  "title=TITLE\n" +
+  "continueIn=CONTINUEIN\n" +
+  "name=NAME\n" +
+  "choose=CHOOSE\n" +
+  "chooseLanguage=CHOOSELANGUAGE\n" +
+  "cancel=CANCEL\n" +
+  "continue=CONTINUE\n" +
+  "installing=INSTALLING\n" +
+  "installerror=INSTALLERROR\n" +
+  "loading=LOADING" +
+ "</strings>"+
+"</addon>";
+
+function handleRequest(request, response) {
+
+  response.setStatusLine(request.httpVersion, 200, "OK");
+  response.setHeader("Content-Type", "text/xml", false);
+
+  response.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+  response.write("<addons>");
+
+  let locales = [];
+  let query = decodeURIComponent(request.queryString || "").split("=");
+  switch(query[0]) {
+   case "numvalid":
+    let numValid = parseInt(query[1]);
+    for (let i = 0; i < numValid; i++) {
+     locales.push( getLocale({IDNUMBER: i}) );
+    }
+    break;
+   case "buildid":
+    locales.push( getLocale({IDNUMBER: 1, NAME: query[1]}) );
+    break;
+   default :
+    locales.push( getLocale({IDNUMBER: 1}) );
+    /* These locales should fail in the LocaleRepository */
+    locales.push( getLocale({IDNUMBER: 1}) ); // no duplicate ids
+    locales.push( getLocale({IDNUMBER: 2, INSTALL: "INVALID_URL"}) );
+    locales.push( getLocale({IDNUMBER: 3}, {APPID: "INVALID_ID"}) );
+    locales.push( getLocale({IDNUMBER: 3}, {MAXVERSION: "0"}) );
+    locales.push( getLocale({IDNUMBER: 4, TARGETLOCALE: ""}) );
+    locales.push( getLocale({IDNUMBER: 5, NAME: ""}) );
+    locales.push( getLocale({IDNUMBER: 6, VERSION: ""}) );
+    locales.push( getLocale({IDNUMBER: 7, TYPENUMBER: ""}) );
+    break;
+  }
+
+  for(var i = 0; i < locales.length; i++) {
+   let t = template;
+   t = t.replace(/{TARGETLOCALE}/g, locales[i].TARGETLOCALE);
+   t = t.replace(/{NAME}/, locales[i].NAME);
+   t = t.replace(/{VERSION}/, locales[i].VERSION);
+   t = t.replace(/{INSTALL}/, locales[i].INSTALL);
+   t = t.replace(/{TYPENUMBER}/, locales[i].TYPENUMBER);
+   t = t.replace(/{TYPENAME}/, locales[i].TYPENAME);
+   t = t.replace(/{IDNUMBER}/, locales[i].IDNUMBER)
+
+   let a = appTemplate;
+   a = a.replace(/{APPNAME}/, locales[i].app.APPNAME);
+   a = a.replace(/{MINVERSION}/, locales[i].app.MINVERSION);
+   a = a.replace(/{MAXVERSION}/, locales[i].app.MAXVERSION);
+   a = a.replace(/{APPID}/, locales[i].app.APPID);
+
+   t = t.replace(/{APPS}/, a);
+   response.write(t);
+  }
+
+  response.write("</addons>");
+}
--- a/mobile/modules/LocaleRepository.jsm
+++ b/mobile/modules/LocaleRepository.jsm
@@ -40,18 +40,16 @@ let EXPORTED_SYMBOLS = ["LocaleRepositor
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/AddonManager.jsm");
 Cu.import("resource://gre/modules/NetUtil.jsm");
 
-var gServiceURL = Services.prefs.getCharPref("extensions.getLocales.get.url");
-
 // A map between XML keys to LocaleSearchResult keys for string values
 // that require no extra parsing from XML
 const STRING_KEY_MAP = {
   name:               "name",
   target_locale:      "targetLocale",
   version:            "version",
   icon:               "iconURL",
   homepage:           "homepageURL",
@@ -78,27 +76,27 @@ var LocaleRepository = {
   },
   
   _getDescendantTextContent: function _getDescendantTextContent(aElement, aTagName) {
     let descendant = this._getUniqueDescendant(aElement, aTagName);
     return (descendant != null) ? this._getTextContent(descendant) : null;
   },
 
   getLocales: function getLocales(aCallback, aFilters) {
-    let url = gServiceURL;
+    let url = Services.prefs.getCharPref("extensions.getLocales.get.url");
 
     if (!url) {
       aCallback([]);
       return;
     }
 
     let buildID = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo).QueryInterface(Ci.nsIXULRuntime).appBuildID;
     if (aFilters) {
       if (aFilters.buildID)
-        buildid = aFilters.buildID;
+        buildID = aFilters.buildID;
     }
     buildID = buildID.substring(0,4) + "-" + buildID.substring(4).replace(/\d{2}(?=\d)/g, "$&-");
     url = url.replace(/%BUILDID_EXPANDED%/g, buildID);
     url = Services.urlFormatter.formatURL(url);
 
     let request = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest);
     request.mozBackgroundRequest = true;
     request.open("GET", url, true);
@@ -161,17 +159,17 @@ var LocaleRepository = {
         case "type":
           // Map AMO's type id to corresponding string
           let id = parseInt(node.getAttribute("id"));
           switch (id) {
             case 5:
               addon.type = "language";
               break;
             default:
-              WARN("Unknown type id when parsing addon: " + id);
+              this.log("Unknown type id when parsing addon: " + id);
           }
           break;
         case "authors":
           let authorNodes = node.getElementsByTagName("author");
           Array.forEach(authorNodes, function(aAuthorNode) {
             let name = self._getDescendantTextContent(aAuthorNode, "name");
             if (name == null)
               name = self._getTextContent(aAuthorNode);
@@ -214,17 +212,22 @@ var LocaleRepository = {
           let xpiURL = this._getTextContent(node);
           if (xpiURL == null)
             break;
   
           if (skipSourceURIs.indexOf(xpiURL) != -1)
             return null;
   
           result.xpiURL = xpiURL;
-          addon.sourceURI = NetUtil.newURI(xpiURL);
+          try {
+            addon.sourceURI = NetUtil.newURI(xpiURL);
+          } catch(ex) {
+            this.log("Addon has invalid uri: " + addon.sourceURI);
+            addon.sourceURI = null;
+          }
   
           let size = parseInt(node.getAttribute("size"));
           addon.size = (size >= 0) ? size : null;
   
           let xpiHash = node.getAttribute("hash");
           if (xpiHash != null)
             xpiHash = xpiHash.trim();
           result.xpiHash = xpiHash ? xpiHash : null;
@@ -265,17 +268,17 @@ var LocaleRepository = {
         continue;
 
       // Add-on meets all requirements, so parse out data
       let result = this._parseLocale(element, aSkip);
       if (result == null)
         continue;
 
       // Ignore add-on missing a required attribute
-      let requiredAttributes = ["id", "name", "version", "type", "targetLocale"];
+      let requiredAttributes = ["id", "name", "version", "type", "targetLocale", "sourceURI"];
       if (requiredAttributes.some(function(aAttribute) !result.addon[aAttribute]))
         continue;
 
       // Add only if the add-on is compatible with the platform
       if (!result.addon.isPlatformCompatible)
         continue;
 
       // Add only if there was an xpi compatible with this OS
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -557,18 +557,16 @@ pref("capability.policy.default.XMLHttpR
 pref("capability.policy.default.XMLHttpRequest.open-uri", "allAccess");
 pref("capability.policy.default.DOMParser.parseFromStream", "noAccess");
 
 // Clipboard
 pref("capability.policy.default.Clipboard.cutcopy", "noAccess");
 pref("capability.policy.default.Clipboard.paste", "noAccess");
 
 // Scripts & Windows prefs
-pref("dom.block_multiple_popups",           true);
-
 pref("dom.disable_image_src_set",           false);
 pref("dom.disable_window_flip",             false);
 pref("dom.disable_window_move_resize",      false);
 pref("dom.disable_window_status_change",    false);
 
 pref("dom.disable_window_open_feature.titlebar",    false);
 pref("dom.disable_window_open_feature.close",       false);
 pref("dom.disable_window_open_feature.toolbar",     false);
--- a/security/manager/ssl/tests/mochitest/mixedcontent/mixedContentTest.js
+++ b/security/manager/ssl/tests/mochitest/mixedcontent/mixedContentTest.js
@@ -19,18 +19,16 @@ var navigateToInsecure = false;
 var openTwoWindows = false;
 // Override the name of the test page to load, useful e.g. to prevent load
 // of images or other content before the test starts; this is actually
 // a 'redirect' to a different test page.
 var testPage = "";
 // Assign a function to this variable to have a clean up at the end
 var testCleanUp = null;
 
-// Backup the dom.block_multiple_popups pref value to re-set it on finish.
-var blockMultiplePopupsPref;
 
 // Internal variables
 var _windowCount = 0;
 
 window.onload = function onLoad()
 {
   if (location.search == "?runtest")
   {
@@ -64,18 +62,16 @@ window.onload = function onLoad()
       array.push(testPage);
       secureTestLocation = array.join("/");
     }
     secureTestLocation += "?runtest";
 
     if (openTwoWindows)
     {
       _windowCount = 2;
-      blockMultiplePopupsPref = SpecialPowers.getBoolPref("dom.block_multiple_popups");
-      SpecialPowers.setBoolPref("dom.block_multiple_popups", false);
       window.open(secureTestLocation, "_new1", "");
       window.open(secureTestLocation, "_new2", "");
     }
     else
     {
       _windowCount = 1;
       window.open(secureTestLocation);
     }
@@ -87,20 +83,17 @@ function onMessageReceived(event)
   switch (event.data)
   {
     // Indication of all test parts finish (from any of the frames)
     case "done":
       if (--_windowCount == 0)
       {
         if (testCleanUp)
           testCleanUp();
-
-        if (openTwoWindows) {
-          SpecialPowers.setBoolPref("dom.block_multiple_popups", blockMultiplePopupsPref);
-        }
+          
         SimpleTest.finish();
       }
       break;
 
     // Any other message indicates error or succes message of a test
     default:
       var failureRegExp = new RegExp("^FAILURE");
       var todoRegExp = new RegExp("^TODO");
--- a/toolkit/components/telemetry/TelemetryHistograms.h
+++ b/toolkit/components/telemetry/TelemetryHistograms.h
@@ -48,16 +48,18 @@
  * Please note that only BOOLEAN histograms are allowed to have a minimum value
  * of zero, and that bucket counts should be >= 3.
  */
 
 /**
  * a11y telemetry
  */
 HISTOGRAM(A11Y_INSTANTIATED, 0, 1, 2, BOOLEAN, "has accessibility support been instantiated")
+HISTOGRAM(ISIMPLE_DOM_USAGE, 0, 1, 2, BOOLEAN, "have the ISimpleDOM* accessibility interfaces been used")
+HISTOGRAM(IACCESSIBLE_TABLE_USAGE, 0, 1, 2, BOOLEAN, "has the IAccessibleTable accessibility interface been used")
 
 HISTOGRAM(CYCLE_COLLECTOR, 1, 10000, 50, EXPONENTIAL, "Time spent on one cycle collection (ms)")
 HISTOGRAM(CYCLE_COLLECTOR_VISITED_REF_COUNTED, 1, 300000, 50, EXPONENTIAL, "Number of ref counted objects visited by the cycle collector")
 HISTOGRAM(CYCLE_COLLECTOR_VISITED_GCED, 1, 300000, 50, EXPONENTIAL, "Number of JS objects visited by the cycle collector")
 HISTOGRAM(CYCLE_COLLECTOR_COLLECTED, 1, 100000, 50, EXPONENTIAL, "Number of objects collected by the cycle collector")
 HISTOGRAM(TELEMETRY_PING, 1, 3000, 10, EXPONENTIAL, "Time taken to submit telemetry info (ms)")
 HISTOGRAM(TELEMETRY_SUCCESS, 0, 1, 2, BOOLEAN,  "Successful telemetry submission")
 HISTOGRAM(MEMORY_JS_COMPARTMENTS_SYSTEM, 1, 1000, 10, EXPONENTIAL, "Total JavaScript compartments used for add-ons and internals.")
--- a/toolkit/content/tests/chrome/test_tabbox.xul
+++ b/toolkit/content/tests/chrome/test_tabbox.xul
@@ -1,21 +1,23 @@
 <?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"?>
 <!--
-  XUL Widget Test for radio buttons
+  XUL Widget Test for tabboxes
   -->
-<window title="Radio Buttons" width="500" height="600"
+<window title="Tabbox Test" width="500" height="600"
         onload="setTimeout(test_tabbox, 0);"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
   <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>  
   <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>  
   <script type="application/javascript" src="xul_selectcontrol.js"/>
 
+<vbox id="tabboxes">
+
 <tabbox id="tabbox">
   <tabs id="tabs">
     <tab id="tab1" label="Tab 1"/>
     <tab id="tab2" label="Tab 2"/>
   </tabs>
   <tabpanels id="tabpanels">
     <button id="panel1" label="Panel 1"/>
     <button id="panel2" label="Panel 2"/>
@@ -43,16 +45,34 @@
   </tabs>
   <tabpanels id="tabpanels-initwithselected">
     <button label="Panel 1"/>
     <button label="Panel 2"/>
     <button label="Panel 3"/>
   </tabpanels>
 </tabbox>
 
+</vbox>
+
+<tabbox id="tabbox-nofocus">
+  <textbox id="textbox-extra" hidden="true"/>
+  <tabs>
+    <tab label="Tab 1" value="one"/>
+    <tab id="tab-nofocus" label="Tab 2" value="two"/>
+  </tabs>
+  <tabpanels>
+    <tabpanel>
+      <button id="tab-nofocus-button" label="Label"/>
+    </tabpanel>
+    <tabpanel id="tabpanel-nofocusinpaneltab">
+      <label id="tablabel" value="Label"/>
+    </tabpanel>
+  </tabpanels>
+</tabbox>
+
   <!-- test results are displayed in the html:body -->
   <body xmlns="http://www.w3.org/1999/xhtml" style="height: 300px; overflow: auto;"/>
 
   <!-- test code goes here -->
   <script type="application/javascript"><![CDATA[
 
 SimpleTest.waitForExplicitFinish();
 
@@ -94,17 +114,17 @@ function test_tabbox()
   tabbox.selectedIndex = 0;
   test_tabpanels(tabpanels, tabbox);
 
   tabs.removeChild(tabs.firstChild);
   tabs.removeChild(tabs.firstChild);
 
   test_tabs(tabs);
 
-  SimpleTest.finish();
+  test_tabbox_focus();
 }
 
 function test_tabpanels(tabpanels, tabbox)
 {
   var tab = tabbox.selectedTab;
 
   // changing the selection on the tabpanels should not affect the tabbox
   // or tabs within
@@ -150,12 +170,50 @@ function test_tabbox_State(tabbox, testi
 }
 
 function test_tabpanels_State(tabpanels, testid, index, panel)
 {
   is(tabpanels.selectedIndex, index, testid + " selectedIndex");
   is(tabpanels.selectedPanel, panel, testid + " selectedPanel");
 }
 
+function test_tabbox_focus()
+{
+  $("tabboxes").hidden = true;
+  $(document.activeElement).blur();
+
+  var tabbox = $("tabbox-nofocus");
+  var tab = $("tab-nofocus");
+
+  tab.addEventListener("focus", function () {
+    tab.removeEventListener("focus", arguments.callee, true);
+    ok(document.activeElement, tab, "focus in tab with no focusable elements");
+
+    tabbox.selectedIndex = 0;
+    $("tab-nofocus-button").focus();
+
+    tab.addEventListener("focus", function () {
+      tab.removeEventListener("focus", arguments.callee, true);
+      ok(document.activeElement, tab, "focus in tab with no focusable elements, but with something in another tab focused");
+
+      var textboxExtra = $("textbox-extra");
+      textboxExtra.addEventListener("focus", function () {
+        textboxExtra.removeEventListener("focus", arguments.callee, true);
+        ok(document.activeElement, textboxExtra, "focus in tab with focus currently in textbox that is sibling of tabs");
+
+        SimpleTest.finish();
+      }, true);
+
+      tabbox.selectedIndex = 0;
+      textboxExtra.hidden = false;
+      synthesizeMouseAtCenter(tab, { });
+    }, true);
+
+    synthesizeMouseAtCenter(tab, { });
+  }, true);
+
+  synthesizeMouseAtCenter(tab, { });
+}
+
 ]]>
 </script>
 
 </window>
--- a/toolkit/content/widgets/tabbox.xml
+++ b/toolkit/content/widgets/tabbox.xml
@@ -472,26 +472,29 @@
             isTabFocused =
               (document.commandDispatcher.focusedElement == this.selectedItem);
           } catch (e) {}
           this.selectedItem = aNewTab;
           if (isTabFocused) {
             aNewTab.focus();
           }
           else if (this.getAttribute("setfocus") != "false") {
-            document.commandDispatcher.advanceFocusIntoSubtree(this.tabbox.selectedPanel);
-            
+            let selectedPanel = this.tabbox.selectedPanel;
+            document.commandDispatcher.advanceFocusIntoSubtree(selectedPanel);
+
             // Make sure that the focus doesn't move outside the tabbox
             if (this.tabbox) {
               try {
                 let el = document.commandDispatcher.focusedElement;
-                while (el && el != this.tabbox)
+                while (el && el != this.tabbox.tabpanels) {
+                  if (el == this.tabbox || el == selectedPanel)
+                    return;
                   el = el.parentNode;
-                if (el != this.tabbox)
-                  aNewTab.focus();
+                }
+                aNewTab.focus();
               } catch(e) {
               }
             }
           }
         ]]>
         </body>
       </method>