Bug 758212 - Allow swapping of docShells from standalone and tabbrowser <browser> elements; r=neil
authorTim Taubert <tim.taubert@gmx.de>
Sat, 07 Jul 2012 11:55:11 +0200
changeset 98463 d103f74ecd5cb911403d5529af2555a7ee02f662
parent 98462 eb12d458e0fbc90e286472d287341461ec004674
child 98519 afbb478ed7a169bfdb8f34054c9a0ad49c5de178
push id901
push usertim.taubert@gmx.de
push dateSat, 07 Jul 2012 09:55:39 +0000
treeherderfx-team@d103f74ecd5c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersneil
bugs758212
milestone16.0a1
Bug 758212 - Allow swapping of docShells from standalone and tabbrowser <browser> elements; r=neil
browser/base/content/test/browser_bug477014.js
toolkit/content/widgets/browser.xml
--- a/browser/base/content/test/browser_bug477014.js
+++ b/browser/base/content/test/browser_bug477014.js
@@ -6,22 +6,22 @@
 const iconURLSpec = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==";
 var testPage="data:text/plain,test bug 477014";
 
 function test() {
   waitForExplicitFinish();
 
   var newWindow;
   var tabToDetach;
+  var documentToDetach;
 
   function onPageShow(event) {
     // we get here if the test is executed before the pageshow
     // event for the window's first tab
-    if (!tabToDetach ||
-        tabToDetach.linkedBrowser.contentDocument != event.target)
+    if (!tabToDetach || documentToDetach != event.target)
       return;
 
     event.currentTarget.removeEventListener("pageshow", onPageShow, false);
 
     if (!newWindow) {
       // prepare the tab (set icon and busy state)
       // we have to set these only after onState* notification, otherwise
       // they're overriden
@@ -41,11 +41,15 @@ function test() {
     }
 
     is(newWindow.gBrowser.selectedTab.hasAttribute("busy"), true);
     is(newWindow.gBrowser.getIcon(), iconURLSpec);
     newWindow.close();
     finish();
   }
 
-  gBrowser.addEventListener("pageshow", onPageShow, false);
   tabToDetach = gBrowser.addTab(testPage);
+  tabToDetach.linkedBrowser.addEventListener("load", function onLoad() {
+    tabToDetach.linkedBrowser.removeEventListener("load", onLoad, true);
+    documentToDetach = tabToDetach.linkedBrowser.contentDocument;
+    gBrowser.addEventListener("pageshow", onPageShow, false);
+  }, true);
 }
--- a/toolkit/content/widgets/browser.xml
+++ b/toolkit/content/widgets/browser.xml
@@ -1136,38 +1136,43 @@
           // We need to swap fields that are tied to our docshell or related to
           // the loaded page
           // Fields which are built as a result of notifactions (pageshow/hide,
           // DOMLinkAdded/Removed, onStateChange) should not be swapped here,
           // because these notifications are dispatched again once the docshells
           // are swapped.
           var fieldsToSwap = [ "_docShell", "_webBrowserFind", "_contentWindow", "_webNavigation"];
 
-          var ourTabBrowser = this.getTabBrowser();
-
-          // _fastFind is tied to the docshell if we don't have a tabbrowser
-          if ((ourTabBrowser != null) !=
-              (aOtherBrowser.getTabBrowser() != null))
-            throw "Unable to perform swap on <browsers> if one is in a <tabbrowser> and one is not";
-
-          if (!ourTabBrowser)
-            fieldsToSwap.push("_fastFind");
-
           var ourFieldValues = {};
           var otherFieldValues = {};
           for each (var field in fieldsToSwap) {
             ourFieldValues[field] = this[field];
             otherFieldValues[field] = aOtherBrowser[field];
           }
           this.QueryInterface(Components.interfaces.nsIFrameLoaderOwner)
               .swapFrameLoaders(aOtherBrowser);
+
+          // Before we swap the actual docShell property we need to detach the
+          // form fill controller from those docShells.
+          this.detachFormFill();
+          aOtherBrowser.detachFormFill();
+
           for each (var field in fieldsToSwap) {
             this[field] = otherFieldValues[field];
             aOtherBrowser[field] = ourFieldValues[field];
           }
+
+          // Re-attach the docShells to the form fill controller.
+          this.attachFormFill();
+          aOtherBrowser.attachFormFill();
+
+          // Null the current nsITypeAheadFind instances so that they're
+          // lazily re-created on access. We need to do this because they
+          // might have attached the wrong docShell.
+          this._fastFind = aOtherBrowser._fastFind = null;
         ]]>
         </body>
       </method>
     </implementation>
 
     <handlers>
       <handler event="keypress" keycode="VK_F7" group="system">
         <![CDATA[