Bug 1096534 - ContentSearch should load the search URL in the tab sending the search message, not the current tab. r=mak
authorDrew Willcoxon <adw@mozilla.com>
Mon, 08 Dec 2014 11:05:27 -0800
changeset 218821 945080e133d25b82ba04c5881ea48f93bc045c54
parent 218708 bf62346a3afbdc8abe0f47a12ddbad290ffdd51e
child 218822 dfef8b5c91e1644e399480ff97ac841016444e4a
push id27945
push usercbook@mozilla.com
push dateTue, 09 Dec 2014 12:09:06 +0000
treeherdermozilla-central@47f0671e2c65 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmak
bugs1096534
milestone37.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1096534 - ContentSearch should load the search URL in the tab sending the search message, not the current tab. r=mak
browser/modules/ContentSearch.jsm
browser/modules/test/browser_ContentSearch.js
--- a/browser/modules/ContentSearch.jsm
+++ b/browser/modules/ContentSearch.jsm
@@ -200,21 +200,33 @@ this.ContentSearch = {
   },
 
   _onMessageSearch: function (msg, data) {
     this._ensureDataHasProperties(data, [
       "engineName",
       "searchString",
       "whence",
     ]);
-    let browserWin = msg.target.ownerDocument.defaultView;
     let engine = Services.search.getEngineByName(data.engineName);
-    browserWin.BrowserSearch.recordSearchInHealthReport(engine, data.whence, data.selection);
     let submission = engine.getSubmission(data.searchString, "", data.whence);
-    browserWin.loadURI(submission.uri.spec, null, submission.postData);
+    let browser = msg.target;
+    try {
+      browser.loadURIWithFlags(submission.uri.spec,
+                               Ci.nsIWebNavigation.LOAD_FLAGS_NONE, null, null,
+                               submission.postData);
+    }
+    catch (err) {
+      // The browser may have been closed between the time its content sent the
+      // message and the time we handle it.  In that case, trying to call any
+      // method on it will throw.
+      return Promise.resolve();
+    }
+    let win = browser.ownerDocument.defaultView;
+    win.BrowserSearch.recordSearchInHealthReport(engine, data.whence,
+                                                 data.selection || null);
     return Promise.resolve();
   },
 
   _onMessageSetCurrentEngine: function (msg, data) {
     Services.search.currentEngine = Services.search.getEngineByName(data);
     return Promise.resolve();
   },
 
--- a/browser/modules/test/browser_ContentSearch.js
+++ b/browser/modules/test/browser_ContentSearch.js
@@ -97,34 +97,44 @@ add_task(function* search() {
     whence: "ContentSearchTest",
   };
   gMsgMan.sendAsyncMessage(TEST_MSG, {
     type: "Search",
     data: data,
   });
   let submissionURL =
     engine.getSubmission(data.searchString, "", data.whence).uri.spec;
-  let deferred = Promise.defer();
-  let listener = {
-    onStateChange: function (webProg, req, flags, status) {
-      let url = req.originalURI.spec;
-      info("onStateChange " + url);
-      let docStart = Ci.nsIWebProgressListener.STATE_IS_DOCUMENT |
-                     Ci.nsIWebProgressListener.STATE_START;
-      if ((flags & docStart) && webProg.isTopLevel && url == submissionURL) {
-        gBrowser.removeProgressListener(listener);
-        ok(true, "Search URL loaded");
-        req.cancel(Components.results.NS_ERROR_FAILURE);
-        deferred.resolve();
-      }
-    }
+  yield waitForLoadAndStopIt(gBrowser.selectedBrowser, submissionURL);
+});
+
+add_task(function* searchInBackgroundTab() {
+  // This test is like search(), but it opens a new tab after starting a search
+  // in another.  In other words, it performs a search in a background tab.  The
+  // search page should be loaded in the same tab that performed the search, in
+  // the background tab.
+  yield addTab();
+  let searchBrowser = gBrowser.selectedBrowser;
+  let engine = Services.search.currentEngine;
+  let data = {
+    engineName: engine.name,
+    searchString: "ContentSearchTest",
+    whence: "ContentSearchTest",
   };
-  gBrowser.addProgressListener(listener);
-  info("Waiting for search URL to load: " + submissionURL);
-  yield deferred.promise;
+  gMsgMan.sendAsyncMessage(TEST_MSG, {
+    type: "Search",
+    data: data,
+  });
+
+  let newTab = gBrowser.addTab();
+  gBrowser.selectedTab = newTab;
+  registerCleanupFunction(() => gBrowser.removeTab(newTab));
+
+  let submissionURL =
+    engine.getSubmission(data.searchString, "", data.whence).uri.spec;
+  yield waitForLoadAndStopIt(searchBrowser, submissionURL);
 });
 
 add_task(function* badImage() {
   yield addTab();
   // If the bad image URI caused an exception to be thrown within ContentSearch,
   // then we'll hang waiting for the CurrentState responses triggered by the new
   // engine.  That's what we're testing, and obviously it shouldn't happen.
   let vals = yield waitForNewEngine("contentSearchBadImage.xml", 1);
@@ -314,16 +324,43 @@ function waitForNewEngine(basename, numI
       ok(false, "addEngine failed with error code " + errCode);
       addDeferred.reject();
     },
   });
 
   return Promise.all([addDeferred.promise].concat(eventPromises));
 }
 
+function waitForLoadAndStopIt(browser, expectedURL) {
+  let deferred = Promise.defer();
+  let listener = {
+    onStateChange: function (webProg, req, flags, status) {
+      if (req instanceof Ci.nsIChannel) {
+        let url = req.originalURI.spec;
+        info("onStateChange " + url);
+        let docStart = Ci.nsIWebProgressListener.STATE_IS_DOCUMENT |
+                       Ci.nsIWebProgressListener.STATE_START;
+        if ((flags & docStart) && webProg.isTopLevel && url == expectedURL) {
+          browser.removeProgressListener(listener);
+          ok(true, "Expected URL loaded");
+          req.cancel(Components.results.NS_ERROR_FAILURE);
+          deferred.resolve();
+        }
+      }
+    },
+    QueryInterface: XPCOMUtils.generateQI([
+      Ci.nsIWebProgressListener,
+      Ci.nsISupportsWeakReference,
+    ]),
+  };
+  browser.addProgressListener(listener);
+  info("Waiting for URL to load: " + expectedURL);
+  return deferred.promise;
+}
+
 function addTab() {
   let deferred = Promise.defer();
   let tab = gBrowser.addTab();
   gBrowser.selectedTab = tab;
   tab.linkedBrowser.addEventListener("load", function load() {
     tab.linkedBrowser.removeEventListener("load", load, true);
     let url = getRootDirectory(gTestPath) + TEST_CONTENT_SCRIPT_BASENAME;
     gMsgMan = tab.linkedBrowser.messageManager;