diff --git a/browser/base/content/tabview/ui.js b/browser/base/content/tabview/ui.js index ed2740ac5985..d9e18083bd0a 100644 --- a/browser/base/content/tabview/ui.js +++ b/browser/base/content/tabview/ui.js @@ -433,7 +433,8 @@ let UI = { Utils.assert(item, "item must be given"); if (item.isATabItem) { - GroupItems.setActiveGroupItem(item.parent); + if (item.parent) + GroupItems.setActiveGroupItem(item.parent); this._setActiveTab(item); } else { GroupItems.setActiveGroupItem(item); diff --git a/browser/base/content/test/tabview/browser_tabview_privatebrowsing.js b/browser/base/content/test/tabview/browser_tabview_privatebrowsing.js index a6f6ae278617..4160fd1c5907 100644 --- a/browser/base/content/test/tabview/browser_tabview_privatebrowsing.js +++ b/browser/base/content/test/tabview/browser_tabview_privatebrowsing.js @@ -22,7 +22,7 @@ function onTabViewLoadedAndShown() { ok(TabView.isVisible(), "Tab View is visible"); // Establish initial state - contentWindow = document.getElementById("tab-view").contentWindow; + contentWindow = TabView.getContentWindow(); verifyCleanState("start"); // register a clean up for private browsing just in case @@ -50,40 +50,37 @@ function onTabViewLoadedAndShown() { } // Create a second tab - gBrowser.loadOneTab("about:robots", { inBackground: false }); + gBrowser.addTab("about:robots"); is(gBrowser.tabs.length, 2, "we now have 2 tabs"); registerCleanupFunction(function() { gBrowser.removeTab(gBrowser.tabs[1]); }); afterAllTabsLoaded(function() { - showTabView(function() { - // Get normal tab urls - for (let a = 0; a < gBrowser.tabs.length; a++) - normalURLs.push(gBrowser.tabs[a].linkedBrowser.currentURI.spec); + // Get normal tab urls + for (let a = 0; a < gBrowser.tabs.length; a++) + normalURLs.push(gBrowser.tabs[a].linkedBrowser.currentURI.spec); - // verify that we're all set up for our test - verifyNormal(); + // verify that we're all set up for our test + verifyNormal(); - // go into private browsing and make sure Tab View becomes hidden - togglePBAndThen(function() { - whenTabViewIsHidden(function() { - ok(!TabView.isVisible(), "Tab View is no longer visible"); + // go into private browsing and make sure Tab View becomes hidden + togglePBAndThen(function() { + whenTabViewIsHidden(function() { + ok(!TabView.isVisible(), "Tab View is no longer visible"); + verifyPB(); - verifyPB(); + // exit private browsing and make sure Tab View is shown again + togglePBAndThen(function() { + whenTabViewIsShown(function() { + ok(TabView.isVisible(), "Tab View is visible again"); + verifyNormal(); - // exit private browsing and make sure Tab View is shown again - togglePBAndThen(function() { - whenTabViewIsShown(function() { - ok(TabView.isVisible(), "Tab View is visible again"); - verifyNormal(); - - hideTabView(onTabViewHidden); - }); + hideTabView(onTabViewHidden); }); }); }); - }); + }); }); } @@ -103,6 +100,8 @@ function onTabViewHidden() { // end game ok(!TabView.isVisible(), "we finish with Tab View not visible"); registerCleanupFunction(verifyCleanState); // verify after all cleanups + + gBrowser.selectedTab = gBrowser.tabs[0]; finish(); }); }); diff --git a/browser/components/places/src/PlacesUIUtils.jsm b/browser/components/places/src/PlacesUIUtils.jsm index 544822740929..e9e34d024e4b 100644 --- a/browser/components/places/src/PlacesUIUtils.jsm +++ b/browser/components/places/src/PlacesUIUtils.jsm @@ -812,8 +812,10 @@ var PlacesUIUtils = { } var loadInBackground = where == "tabshifted" ? true : false; - var replaceCurrentTab = where == "tab" ? false : true; - browserWindow.gBrowser.loadTabs(urls, loadInBackground, replaceCurrentTab); + // For consistency, we want all the bookmarks to open in new tabs, instead + // of having one of them replace the currently focused tab. Hence we call + // loadTabs with aReplace set to false. + browserWindow.gBrowser.loadTabs(urls, loadInBackground, false); }, /** diff --git a/browser/components/preferences/aboutPermissions.js b/browser/components/preferences/aboutPermissions.js index c9a9e12aeee2..1299064655fb 100644 --- a/browser/components/preferences/aboutPermissions.js +++ b/browser/components/preferences/aboutPermissions.js @@ -92,18 +92,28 @@ Site.prototype = { * A callback function that takes a favicon image URL as a parameter. */ getFavicon: function Site_getFavicon(aCallback) { + let callbackExecuted = false; function faviconDataCallback(aURI, aDataLen, aData, aMimeType) { + // We don't need a second callback, so we can ignore it to avoid making + // a second database query for the favicon data. + if (callbackExecuted) { + return; + } try { - aCallback(aURI.spec); + // Use getFaviconLinkForIcon to get image data from the database instead + // of using the favicon URI to fetch image data over the network. + aCallback(gFaviconService.getFaviconLinkForIcon(aURI).spec); + callbackExecuted = true; } catch (e) { Cu.reportError("AboutPermissions: " + e); } } // Try to find favicion for both URIs. Callback will only be called if a - // favicon URI is found, so this means we'll always prefer the https favicon. - gFaviconService.getFaviconURLForPage(this.httpURI, faviconDataCallback); + // favicon URI is found. We'll ignore the second callback if it is called, + // so this means we'll always prefer the https favicon. gFaviconService.getFaviconURLForPage(this.httpsURI, faviconDataCallback); + gFaviconService.getFaviconURLForPage(this.httpURI, faviconDataCallback); }, /** diff --git a/browser/components/privatebrowsing/src/nsPrivateBrowsingService.js b/browser/components/privatebrowsing/src/nsPrivateBrowsingService.js index 42fdf81d1906..484482f24b13 100644 --- a/browser/components/privatebrowsing/src/nsPrivateBrowsingService.js +++ b/browser/components/privatebrowsing/src/nsPrivateBrowsingService.js @@ -503,41 +503,43 @@ PrivateBrowsingService.prototype = { if (this._currentStatus != STATE_IDLE) throw Cr.NS_ERROR_FAILURE; + if (val == this._inPrivateBrowsing) + return; + try { + if (val) { + if (!this._canEnterPrivateBrowsingMode()) + return; + } + else { + if (!this._canLeavePrivateBrowsingMode()) + return; + } + + this._ensureCanCloseWindows(); + + // start the transition now that we know that we can this._currentStatus = STATE_TRANSITION_STARTED; - if (val != this._inPrivateBrowsing) { - if (val) { - if (!this._canEnterPrivateBrowsingMode()) - return; - } - else { - if (!this._canLeavePrivateBrowsingMode()) - return; - } + this._autoStarted = this._prefs.getBoolPref("browser.privatebrowsing.autostart"); + this._inPrivateBrowsing = val != false; - this._ensureCanCloseWindows(); + let data = val ? "enter" : "exit"; - this._autoStarted = this._prefs.getBoolPref("browser.privatebrowsing.autostart"); - this._inPrivateBrowsing = val != false; + let quitting = Cc["@mozilla.org/supports-PRBool;1"]. + createInstance(Ci.nsISupportsPRBool); + quitting.data = this._quitting; - let data = val ? "enter" : "exit"; + // notify observers of the pending private browsing mode change + this._obs.notifyObservers(quitting, "private-browsing-change-granted", data); - let quitting = Cc["@mozilla.org/supports-PRBool;1"]. - createInstance(Ci.nsISupportsPRBool); - quitting.data = this._quitting; + // destroy the current session and start initial cleanup + this._onBeforePrivateBrowsingModeChange(); - // notify observers of the pending private browsing mode change - this._obs.notifyObservers(quitting, "private-browsing-change-granted", data); + this._obs.notifyObservers(quitting, "private-browsing", data); - // destroy the current session and start initial cleanup - this._onBeforePrivateBrowsingModeChange(); - - this._obs.notifyObservers(quitting, "private-browsing", data); - - // load the appropriate session - this._onAfterPrivateBrowsingModeChange(); - } + // load the appropriate session + this._onAfterPrivateBrowsingModeChange(); } catch (ex) { // We aborted the transition to/from private browsing, we must restore the // beforeunload handling on all the windows for which we switched it off. diff --git a/browser/components/sessionstore/content/aboutSessionRestore.js b/browser/components/sessionstore/content/aboutSessionRestore.js index bbbe87b08d17..dc98407a44b1 100644 --- a/browser/components/sessionstore/content/aboutSessionRestore.js +++ b/browser/components/sessionstore/content/aboutSessionRestore.js @@ -48,12 +48,8 @@ window.onload = function() { // (for when the tab is closed or the session crashes right again) var sessionData = document.getElementById("sessionData"); if (!sessionData.value) { - var ss = Cc["@mozilla.org/browser/sessionstartup;1"].getService(Ci.nsISessionStartup); - sessionData.value = ss.state; - if (!sessionData.value) { - document.getElementById("errorTryAgain").disabled = true; - return; - } + document.getElementById("errorTryAgain").disabled = true; + return; } // remove unneeded braces (added for compatibility with Firefox 2.0 and 3.0) diff --git a/browser/components/sessionstore/test/browser/browser_588426.js b/browser/components/sessionstore/test/browser/browser_588426.js index 1e414e5f2821..fc9146e72657 100644 --- a/browser/components/sessionstore/test/browser/browser_588426.js +++ b/browser/components/sessionstore/test/browser/browser_588426.js @@ -7,19 +7,35 @@ function test() { {entries: [{url: "about:robots"}], hidden: true} ] }] }; - let finalState = { windows: [{ tabs: [ - {entries: [{url: "about:blank"}]} - ] }] }; - waitForExplicitFinish(); - waitForBrowserState(state, function () { - is(gBrowser.tabs.length, 2, "two tabs were restored"); - is(gBrowser.visibleTabs.length, 1, "one tab is visible"); + newWindowWithState(state, function (win) { + registerCleanupFunction(function () win.close()); - let tab = gBrowser.visibleTabs[0]; + is(win.gBrowser.tabs.length, 2, "two tabs were restored"); + is(win.gBrowser.visibleTabs.length, 1, "one tab is visible"); + + let tab = win.gBrowser.visibleTabs[0]; is(tab.linkedBrowser.currentURI.spec, "about:mozilla", "visible tab is about:mozilla"); - waitForBrowserState(finalState, finish); + finish(); }); } + +function newWindowWithState(state, callback) { + let opts = "chrome,all,dialog=no,height=800,width=800"; + let win = window.openDialog(getBrowserURL(), "_blank", opts); + + win.addEventListener("load", function onLoad() { + win.removeEventListener("load", onLoad, false); + + executeSoon(function () { + win.addEventListener("SSWindowStateReady", function onReady() { + win.removeEventListener("SSWindowStateReady", onReady, false); + executeSoon(function () callback(win)); + }, false); + + ss.setWindowState(win, JSON.stringify(state), true); + }); + }, false); +} diff --git a/browser/components/sessionstore/test/browser/browser_590563.js b/browser/components/sessionstore/test/browser/browser_590563.js index c30c901da935..1fefc4c63d6f 100644 --- a/browser/components/sessionstore/test/browser/browser_590563.js +++ b/browser/components/sessionstore/test/browser/browser_590563.js @@ -1,11 +1,7 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ -let stateBackup = ss.getBrowserState(); - function test() { - waitForExplicitFinish(); - let oldState = { windows: [{ tabs: [ @@ -20,24 +16,26 @@ function test() { }; let state = { windows: [{ tabs: [{ entries: [pageData] }] }] }; - // The form data will be restored before SSTabRestored, so we want to listen - // for that on the currently selected tab (it will be reused) - gBrowser.selectedTab.addEventListener("SSTabRestored", onSSTabRestored, true); + waitForExplicitFinish(); - ss.setBrowserState(JSON.stringify(state)); + newWindowWithState(state, function (win) { + registerCleanupFunction(function () win.close()); + + is(gBrowser.tabs.length, 1, "The total number of tabs should be 1"); + is(gBrowser.visibleTabs.length, 1, "The total number of visible tabs should be 1"); + + executeSoon(function () { + waitForFocus(function () { + middleClickTest(win); + finish(); + }, win); + }); + }); } -function onSSTabRestored(aEvent) { - gBrowser.selectedTab.removeEventListener("SSTabRestored", onSSTabRestored, true); - - is(gBrowser.tabs.length, 1, "The total number of tabs should be 1"); - is(gBrowser.visibleTabs.length, 1, "The total number of visible tabs should be 1"); - - executeSoon(middleClickTest); -} - -function middleClickTest() { - let tree = gBrowser.selectedBrowser.contentDocument.getElementById("tabList"); +function middleClickTest(win) { + let browser = win.gBrowser.selectedBrowser; + let tree = browser.contentDocument.getElementById("tabList"); is(tree.view.rowCount, 3, "There should be three items"); let x = {}, y = {}, width = {}, height = {}; @@ -45,21 +43,36 @@ function middleClickTest() { // click on the first tab item tree.treeBoxObject.getCoordsForCellItem(1, tree.columns[1], "text", x, y, width, height); EventUtils.synthesizeMouse(tree.body, x.value, y.value, { button: 1 }, - gBrowser.selectedBrowser.contentWindow); + browser.contentWindow); // click on the second tab item tree.treeBoxObject.getCoordsForCellItem(2, tree.columns[1], "text", x, y, width, height); EventUtils.synthesizeMouse(tree.body, x.value, y.value, { button: 1 }, - gBrowser.selectedBrowser.contentWindow); + browser.contentWindow); - is(gBrowser.tabs.length, 3, + is(win.gBrowser.tabs.length, 3, "The total number of tabs should be 3 after restoring 2 tabs by middle click."); - is(gBrowser.visibleTabs.length, 3, + is(win.gBrowser.visibleTabs.length, 3, "The total number of visible tabs should be 3 after restoring 2 tabs by middle click"); - - cleanup(); } -function cleanup() { - ss.setBrowserState(stateBackup); - executeSoon(finish); +function newWindowWithState(state, callback) { + let opts = "chrome,all,dialog=no,height=800,width=800"; + let win = window.openDialog(getBrowserURL(), "_blank", opts); + + win.addEventListener("load", function onLoad() { + win.removeEventListener("load", onLoad, false); + + let tab = win.gBrowser.selectedTab; + + // The form data will be restored before SSTabRestored, so we want to listen + // for that on the currently selected tab (it will be reused) + tab.addEventListener("SSTabRestored", function onRestored() { + tab.removeEventListener("SSTabRestored", onRestored, true); + callback(win); + }, true); + + executeSoon(function () { + ss.setWindowState(win, JSON.stringify(state), true); + }); + }, false); } diff --git a/browser/devtools/scratchpad/scratchpad.xul b/browser/devtools/scratchpad/scratchpad.xul index eca6ee9de80e..8ab59a707b7e 100644 --- a/browser/devtools/scratchpad/scratchpad.xul +++ b/browser/devtools/scratchpad/scratchpad.xul @@ -186,12 +186,12 @@