diff --git a/browser/base/content/browser-tabview.js b/browser/base/content/browser-tabview.js index 35ffb01fabb..425589e68a9 100644 --- a/browser/base/content/browser-tabview.js +++ b/browser/base/content/browser-tabview.js @@ -435,7 +435,12 @@ let TabView = { this.sessionRestoreEnabledOnce = true; - // enable session restore - Services.prefs.setIntPref(this.PREF_STARTUP_PAGE, 3); + // enable session restore if necessary + if (Services.prefs.getIntPref(this.PREF_STARTUP_PAGE) != 3) { + Services.prefs.setIntPref(this.PREF_STARTUP_PAGE, 3); + + // show banner + this._window.UI.notifySessionRestoreEnabled(); + } } }; diff --git a/browser/base/content/tabview/groupitems.js b/browser/base/content/tabview/groupitems.js index 6e5c870bb28..35aa58de022 100644 --- a/browser/base/content/tabview/groupitems.js +++ b/browser/base/content/tabview/groupitems.js @@ -191,6 +191,7 @@ function GroupItem(listOfEls, options) { self.$titleShield.show(); if (self.getTitle()) gTabView.firstUseExperienced = true; + self.save(); }) .focus(function() { self._unfreezeItemSize(); @@ -825,9 +826,7 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), { } else { // child.removeSubscriber() must be called before child.close(), // therefore we call child.addSubscriber() if the tab is not removed. - child.addSubscriber(self, "close", function() { - self.remove(child); - }); + child.addSubscriber(self, "close", self._onChildClose.bind(self)); } }); @@ -1010,19 +1009,7 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), { item.droppable(false); item.groupItemData = {}; - item.addSubscriber(this, "close", function() { - let count = self._children.length; - let dontArrange = self.expanded || !self.shouldStack(count); - let dontClose = !item.closedManually && gBrowser._numPinnedTabs > 0; - self.remove(item, {dontArrange: dontArrange, dontClose: dontClose}); - - if (dontArrange) - self._freezeItemSize(count); - - if (self._children.length > 0 && self._activeTab) - UI.setActive(self); - }); - + item.addSubscriber(this, "close", this._onChildClose.bind(this)); item.setParent(this); if (typeof item.setResizable == 'function') @@ -1050,6 +1037,25 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), { } }, + // ---------- + // Function: _onChildClose + // Handles "close" events from the group's children. + // + // Parameters: + // tabItem - The tabItem that is closed. + _onChildClose: function GroupItem__onChildClose(tabItem) { + let count = this._children.length; + let dontArrange = this.expanded || !this.shouldStack(count); + let dontClose = !tabItem.closedManually && gBrowser._numPinnedTabs > 0; + this.remove(tabItem, {dontArrange: dontArrange, dontClose: dontClose}); + + if (dontArrange) + this._freezeItemSize(count); + + if (this._children.length > 0 && this._activeTab) + UI.setActive(this); + }, + // ---------- // Function: remove // Removes an item from the groupItem. diff --git a/browser/base/content/tabview/tabview.css b/browser/base/content/tabview/tabview.css index 8a0eb7dc1c3..902c3063290 100644 --- a/browser/base/content/tabview/tabview.css +++ b/browser/base/content/tabview/tabview.css @@ -178,6 +178,20 @@ body { position: absolute; } +.banner { + left: 0; + bottom: 0; + right: 0; + padding: 10px 0; + position: absolute; + z-index: 1000060; + background: #000; + color: #fff; + opacity: 0; + text-align: center; + font-weight: 700; +} + /* Resizable ----------------------------------*/ .resizer { diff --git a/browser/base/content/tabview/ui.js b/browser/base/content/tabview/ui.js index c88dc90e230..ff753d266d8 100644 --- a/browser/base/content/tabview/ui.js +++ b/browser/base/content/tabview/ui.js @@ -135,6 +135,10 @@ let UI = { // Used to keep track of allowed browser keys. _browserKeys: null, + // Variable: _browserKeysWithShift + // Used to keep track of allowed browser keys with Shift key combination. + _browserKeysWithShift: null, + // Variable: ignoreKeypressForSearch // Used to prevent keypress being handled after quitting search mode. ignoreKeypressForSearch: false, @@ -973,11 +977,15 @@ let UI = { "selectAll", "find" ].forEach(function(key) { let element = gWindow.document.getElementById("key_" + key); - keys[key] = element.getAttribute("key").toLocaleLowerCase().charCodeAt(0); + let code = element.getAttribute("key").toLocaleLowerCase().charCodeAt(0); + keys[code] = key; }); + this._browserKeys = keys; - // for key combinations with shift key, the charCode of upper case letters - // are different to the lower case ones so need to handle them differently. + keys = {}; + // The lower case letters are passed to processBrowserKeys() even with shift + // key when stimulating a key press using EventUtils.synthesizeKey() so need + // to handle both upper and lower cases here. [ #ifdef XP_UNIX "redo", @@ -986,11 +994,10 @@ let UI = { "privatebrowsing" ].forEach(function(key) { let element = gWindow.document.getElementById("key_" + key); - keys[key] = element.getAttribute("key").toLocaleUpperCase().charCodeAt(0); + let code = element.getAttribute("key").toLocaleLowerCase().charCodeAt(0); + keys[code] = key; }); - - delete this._browserKeys; - this._browserKeys = keys; + this._browserKeysWithShift = keys; }, // ---------- @@ -1022,44 +1029,25 @@ let UI = { #endif let preventDefault = true; if (evt.shiftKey) { - switch (evt.charCode) { - case self._browserKeys.tabview: + // when a user presses ctrl+shift+key, upper case letter charCode + // is passed to processBrowserKeys() so converting back to lower + // case charCode before doing the check + let lowercaseCharCode = + String.fromCharCode(evt.charCode).toLocaleLowerCase().charCodeAt(0); + if (lowercaseCharCode in self._browserKeysWithShift) { + let key = self._browserKeysWithShift[lowercaseCharCode]; + if (key == "tabview") self.exit(); - break; -#ifdef XP_UNIX - case self._browserKeys.redo: -#endif - case self._browserKeys.closeWindow: - case self._browserKeys.undoCloseTab: - case self._browserKeys.undoCloseWindow: - case self._browserKeys.privatebrowsing: + else preventDefault = false; - break; } } else { - switch (evt.charCode) { - case self._browserKeys.find: + if (evt.charCode in self._browserKeys) { + let key = self._browserKeys[evt.charCode]; + if (key == "find") self.enableSearch(); - break; -#ifdef XP_UNIX - case self._browserKeys.quitApplication: -#else - case self._browserKeys.redo: -#endif -#ifdef XP_MACOSX - case self._browserKeys.preferencesCmdMac: - case self._browserKeys.minimizeWindow: - case self._browserKeys.hideThisAppCmdMac: -#endif - case self._browserKeys.newNavigator: - case self._browserKeys.newNavigatorTab: - case self._browserKeys.undo: - case self._browserKeys.cut: - case self._browserKeys.copy: - case self._browserKeys.paste: - case self._browserKeys.selectAll: + else preventDefault = false; - break; } } if (preventDefault) { @@ -1568,6 +1556,35 @@ let UI = { url = gFavIconService.getFaviconImageForPage(tab.linkedBrowser.currentURI).spec; return url; + }, + + // ---------- + // Function: notifySessionRestoreEnabled + // Notify the user that session restore has been automatically enabled + // by showing a banner that expects no user interaction. It fades out after + // some seconds. + notifySessionRestoreEnabled: function UI_notifySessionRestoreEnabled() { + let brandBundle = gWindow.document.getElementById("bundle_brand"); + let brandShortName = brandBundle.getString("brandShortName"); + let notificationText = tabviewBundle.formatStringFromName( + "tabview.notification.sessionStore", [brandShortName], 1); + + let banner = iQ("
") + .text(notificationText) + .addClass("banner") + .appendTo("body"); + + let onFadeOut = function () { + banner.remove(); + }; + + let onFadeIn = function () { + setTimeout(function () { + banner.animate({opacity: 0}, {duration: 1500, complete: onFadeOut}); + }, 5000); + }; + + banner.animate({opacity: 0.7}, {duration: 1500, complete: onFadeIn}); } }; diff --git a/browser/base/content/test/tabview/Makefile.in b/browser/base/content/test/tabview/Makefile.in index 40cca03069a..fb3bc52b640 100644 --- a/browser/base/content/test/tabview/Makefile.in +++ b/browser/base/content/test/tabview/Makefile.in @@ -110,7 +110,6 @@ _BROWSER_FILES = \ browser_tabview_bug625195.js \ browser_tabview_bug625269.js \ browser_tabview_bug625424.js \ - browser_tabview_bug625666.js \ browser_tabview_bug626368.js \ browser_tabview_bug626525.js \ browser_tabview_bug626791.js \ diff --git a/browser/base/content/test/tabview/browser_tabview_bug580412.js b/browser/base/content/test/tabview/browser_tabview_bug580412.js index f535b8b6ecc..6405fc8e2ef 100644 --- a/browser/base/content/test/tabview/browser_tabview_bug580412.js +++ b/browser/base/content/test/tabview/browser_tabview_bug580412.js @@ -3,124 +3,78 @@ function test() { waitForExplicitFinish(); - - window.addEventListener("tabviewshown", onTabViewWindowLoaded, false); - if (TabView.isVisible()) - onTabViewWindowLoaded(); - else - TabView.show(); + showTabView(onTabViewShown); } -function onTabViewWindowLoaded() { - window.removeEventListener("tabviewshown", onTabViewWindowLoaded, false); - - let contentWindow = document.getElementById("tab-view").contentWindow; +function onTabViewShown() { + let contentWindow = TabView.getContentWindow(); let [originalTab] = gBrowser.visibleTabs; ok(TabView.isVisible(), "Tab View is visible"); is(contentWindow.GroupItems.groupItems.length, 1, "There is only one group"); let currentActiveGroup = contentWindow.GroupItems.getActiveGroupItem(); - // set double click interval to negative so quick drag and drop doesn't - // trigger the double click code. - let origDBlClickInterval = contentWindow.UI.DBLCLICK_INTERVAL; - contentWindow.UI.DBLCLICK_INTERVAL = -1; - let endGame = function() { - contentWindow.UI.reset(); - contentWindow.UI.DBLCLICK_INTERVAL = origDBlClickInterval; - - let onTabViewHidden = function() { - window.removeEventListener("tabviewhidden", onTabViewHidden, false); - ok(!TabView.isVisible(), "TabView is shown"); - finish(); - }; - window.addEventListener("tabviewhidden", onTabViewHidden, false); - ok(TabView.isVisible(), "TabView is shown"); - gBrowser.selectedTab = originalTab; - TabView.hide(); - } - let part1 = function() { - // move down 20 so we're far enough away from the top. - checkSnap(currentActiveGroup, 0, 20, contentWindow, function(snapped){ - ok(!snapped,"Move away from the edge"); - - // Just pick it up and drop it. - checkSnap(currentActiveGroup, 0, 0, contentWindow, function(snapped){ - ok(!snapped,"Just pick it up and drop it"); - - checkSnap(currentActiveGroup, 0, 1, contentWindow, function(snapped){ - ok(snapped,"Drag one pixel: should snap"); - - checkSnap(currentActiveGroup, 0, 5, contentWindow, function(snapped){ - ok(!snapped,"Moving five pixels: shouldn't snap"); - endGame(); - }); - }); - }); + hideTabView(function () { + ok(!TabView.isVisible(), "TabView is hidden"); + finish(); }); } + // we need to stop the setBounds() css animation or else the test will + // fail in single-mode because the group is newly created "ontabshown". + let $container = contentWindow.iQ(currentActiveGroup.container); + $container.css("-moz-transition-property", "none"); + currentActiveGroup.setPosition(40, 40, true); currentActiveGroup.arrange({animate: false}); - part1(); + + // move down 20 so we're far enough away from the top. + checkSnap(currentActiveGroup, 0, 20, contentWindow, function(snapped){ + is(currentActiveGroup.getBounds().top, 60, "group.top is 60px"); + ok(!snapped,"Move away from the edge"); + + // Just pick it up and drop it. + checkSnap(currentActiveGroup, 0, 0, contentWindow, function(snapped){ + is(currentActiveGroup.getBounds().top, 60, "group.top is 60px"); + ok(!snapped,"Just pick it up and drop it"); + + checkSnap(currentActiveGroup, 0, 1, contentWindow, function(snapped){ + is(currentActiveGroup.getBounds().top, 60, "group.top is 60px"); + ok(snapped,"Drag one pixel: should snap"); + + checkSnap(currentActiveGroup, 0, 5, contentWindow, function(snapped){ + is(currentActiveGroup.getBounds().top, 65, "group.top is 65px"); + ok(!snapped,"Moving five pixels: shouldn't snap"); + endGame(); + }); + }); + }); + }); } -function simulateDragDrop(tabItem, offsetX, offsetY, contentWindow) { - // enter drag mode - let dataTransfer; +function simulateDragDrop(item, offsetX, offsetY, contentWindow) { + let target = item.container; - EventUtils.synthesizeMouse( - tabItem.container, 1, 1, { type: "mousedown" }, contentWindow); - let event = contentWindow.document.createEvent("DragEvents"); - event.initDragEvent( - "dragenter", true, true, contentWindow, 0, 0, 0, 0, 0, - false, false, false, false, 1, null, dataTransfer); - tabItem.container.dispatchEvent(event); - - // drag over - if (offsetX || offsetY) { - let Ci = Components.interfaces; - let utils = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor). - getInterface(Ci.nsIDOMWindowUtils); - let rect = tabItem.getBounds(); - for (let i = 1; i <= 5; i++) { - let left = rect.left + 1 + Math.round(i * offsetX / 5); - let top = rect.top + 1 + Math.round(i * offsetY / 5); - utils.sendMouseEvent("mousemove", left, top, 0, 1, 0); - } - event = contentWindow.document.createEvent("DragEvents"); - event.initDragEvent( - "dragover", true, true, contentWindow, 0, 0, 0, 0, 0, - false, false, false, false, 0, null, dataTransfer); - tabItem.container.dispatchEvent(event); - } - - // drop - EventUtils.synthesizeMouse( - tabItem.container, 0, 0, { type: "mouseup" }, contentWindow); - event = contentWindow.document.createEvent("DragEvents"); - event.initDragEvent( - "drop", true, true, contentWindow, 0, 0, 0, 0, 0, - false, false, false, false, 0, null, dataTransfer); - tabItem.container.dispatchEvent(event); + EventUtils.synthesizeMouse(target, 1, 1, {type: "mousedown"}, contentWindow); + EventUtils.synthesizeMouse(target, 1 + offsetX, 1 + offsetY, {type: "mousemove"}, contentWindow); + EventUtils.synthesizeMouse(target, 1, 1, {type: "mouseup"}, contentWindow); } function checkSnap(item, offsetX, offsetY, contentWindow, callback) { let firstTop = item.getBounds().top; let firstLeft = item.getBounds().left; - let onDrop = function() { - let snapped = false; - item.container.removeEventListener('drop', onDrop, false); - if (item.getBounds().top != firstTop + offsetY) - snapped = true; - if (item.getBounds().left != firstLeft + offsetX) - snapped = true; - callback(snapped); - }; - item.container.addEventListener('drop', onDrop, false); + simulateDragDrop(item, offsetX, offsetY, contentWindow); + + let snapped = false; + if (item.getBounds().top != firstTop + offsetY) + snapped = true; + if (item.getBounds().left != firstLeft + offsetX) + snapped = true; + + callback(snapped); } diff --git a/browser/base/content/test/tabview/browser_tabview_bug587276.js b/browser/base/content/test/tabview/browser_tabview_bug587276.js index defed5a2e39..8a5ee937409 100644 --- a/browser/base/content/test/tabview/browser_tabview_bug587276.js +++ b/browser/base/content/test/tabview/browser_tabview_bug587276.js @@ -17,7 +17,7 @@ function test1() { ok(!TabView.isVisible(), "Tab View is not visible"); showTabView(test2); }); - EventUtils.synthesizeKey("E", { accelKey: true, shiftKey: true }, contentWindow); + EventUtils.synthesizeKey("e", { accelKey: true, shiftKey: true }, contentWindow); } function test2() { @@ -58,7 +58,7 @@ function test4() { executeSoon(function() { is(gBrowser.tabs.length, 1, "There is one tab after removing one"); - EventUtils.synthesizeKey("T", { accelKey: true, shiftKey: true }, contentWindow); + EventUtils.synthesizeKey("t", { accelKey: true, shiftKey: true }, contentWindow); is(gBrowser.tabs.length, 2, "There are two tabs after restoring one"); gBrowser.tabs[0].linkedBrowser.loadURI("about:blank"); @@ -96,7 +96,7 @@ function test9() { function test10() { is(gBrowser.tabs.length, 1, "There is one tab before cmd/ctrl + shift + a is pressed"); // it would open about:addons on a new tab if it passes through the white list. - EventUtils.synthesizeKey("A", { accelKey: true, shiftKey: true }, contentWindow); + EventUtils.synthesizeKey("a", { accelKey: true, shiftKey: true }, contentWindow); executeSoon(function() { is(gBrowser.tabs.length, 1, "There is still one tab after cmd/ctrl + shift + a is pressed"); diff --git a/browser/base/content/test/tabview/browser_tabview_bug595020.js b/browser/base/content/test/tabview/browser_tabview_bug595020.js index 102374b9a5a..c3b5d436658 100644 --- a/browser/base/content/test/tabview/browser_tabview_bug595020.js +++ b/browser/base/content/test/tabview/browser_tabview_bug595020.js @@ -11,6 +11,8 @@ function test() { let assertWindowTitle = function (win, title) { let browser = win.gBrowser.tabs[0].linkedBrowser; let winTitle = win.gBrowser.getWindowTitleForBrowser(browser); + + info('window title is: "' + winTitle + '"'); is(winTitle.indexOf(title), 0, "title starts with '" + title + "'"); }; diff --git a/browser/base/content/test/tabview/browser_tabview_bug595191.js b/browser/base/content/test/tabview/browser_tabview_bug595191.js index 660d3f29903..e216eae564d 100644 --- a/browser/base/content/test/tabview/browser_tabview_bug595191.js +++ b/browser/base/content/test/tabview/browser_tabview_bug595191.js @@ -57,5 +57,5 @@ function toggleTabViewTest(contentWindow) { } contentWindow.addEventListener("tabviewhidden", onTabViewHidden, false); // Use keyboard shortcut to toggle back to browser view - EventUtils.synthesizeKey("E", { accelKey: true, shiftKey: true }); + EventUtils.synthesizeKey("e", { accelKey: true, shiftKey: true }); } diff --git a/browser/base/content/test/tabview/browser_tabview_bug595518.js b/browser/base/content/test/tabview/browser_tabview_bug595518.js index f462f14bc42..4a2ae34bcef 100644 --- a/browser/base/content/test/tabview/browser_tabview_bug595518.js +++ b/browser/base/content/test/tabview/browser_tabview_bug595518.js @@ -28,7 +28,7 @@ function onTabViewWindowLoaded() { // verify that the keyboard combo works (this is the crux of bug 595518) // Prepare the key combo window.addEventListener("tabviewshown", onTabViewShown, false); - EventUtils.synthesizeKey("E", { accelKey: true, shiftKey: true }, contentWindow); + EventUtils.synthesizeKey("e", { accelKey: true, shiftKey: true }, contentWindow); } let onTabViewShown = function() { diff --git a/browser/base/content/test/tabview/browser_tabview_bug595930.js b/browser/base/content/test/tabview/browser_tabview_bug595930.js index a4fe90bf2bd..269d58620cc 100644 --- a/browser/base/content/test/tabview/browser_tabview_bug595930.js +++ b/browser/base/content/test/tabview/browser_tabview_bug595930.js @@ -41,7 +41,7 @@ function onTabViewWindowLoaded() { // the appropriate group would get selected when the key // combination is pressed executeSoon(function() { - EventUtils.synthesizeKey("E", {accelKey : true, shiftKey: true}, contentWindow); + EventUtils.synthesizeKey("e", {accelKey : true, shiftKey: true}, contentWindow); }); }); diff --git a/browser/base/content/test/tabview/browser_tabview_bug597980.js b/browser/base/content/test/tabview/browser_tabview_bug597980.js index 1d78502ecea..079003933e8 100644 --- a/browser/base/content/test/tabview/browser_tabview_bug597980.js +++ b/browser/base/content/test/tabview/browser_tabview_bug597980.js @@ -78,8 +78,8 @@ function part2(win) { finish(); }, false); // show tabview - EventUtils.synthesizeKey("E", { accelKey: true, shiftKey: true }, win); + EventUtils.synthesizeKey("e", { accelKey: true, shiftKey: true }, win); // hide tabview - EventUtils.synthesizeKey("E", { accelKey: true, shiftKey: true }, win); + EventUtils.synthesizeKey("e", { accelKey: true, shiftKey: true }, win); }) } diff --git a/browser/base/content/test/tabview/browser_tabview_bug625666.js b/browser/base/content/test/tabview/browser_tabview_bug625666.js deleted file mode 100644 index a1ba7b883d1..00000000000 --- a/browser/base/content/test/tabview/browser_tabview_bug625666.js +++ /dev/null @@ -1,49 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -function test() { - let cw; - - let getTabItemAspect = function (tabItem) { - let bounds = cw.iQ('.thumb', tabItem.container).bounds(); - let padding = cw.TabItems.tabItemPadding; - return (bounds.height + padding.y) / (bounds.width + padding.x); - } - - let getAspectRange = function () { - let aspect = cw.TabItems.tabAspect; - let variance = aspect / 100 * 1.5; - return new cw.Range(aspect - variance, aspect + variance); - } - - waitForExplicitFinish(); - - newWindowWithTabView(function (win) { - registerCleanupFunction(function () win.close()); - cw = win.TabView.getContentWindow(); - - // prepare orphan tab - let tabItem = win.gBrowser.tabs[0]._tabViewTabItem; - tabItem.parent.remove(tabItem, {immediately: true}); - tabItem.setBounds(new cw.Rect(20, 20, 200, 165), true); - - let bounds = tabItem.getBounds(); - - // prepare group item - let box = new cw.Rect(20, 300, 400, 200); - let groupItem = new cw.GroupItem([], {bounds: box, immediately: true}); - - groupItem.setBounds(new cw.Rect(20, 100, 400, 200)); - groupItem.pushAway(true); - - let newBounds = tabItem.getBounds(); - ok(newBounds.width < bounds.width, "The new width of item is smaller than the old one."); - ok(newBounds.height < bounds.height, "The new height of item is smaller than the old one."); - - let aspectRange = getAspectRange(); - let aspect = getTabItemAspect(tabItem); - ok(aspectRange.contains(aspect), "orphaned tabItem's aspect is correct"); - - finish(); - }); -} diff --git a/browser/base/content/test/tabview/browser_tabview_bug656778.js b/browser/base/content/test/tabview/browser_tabview_bug656778.js index a17bdf3afcb..f7417aece12 100644 --- a/browser/base/content/test/tabview/browser_tabview_bug656778.js +++ b/browser/base/content/test/tabview/browser_tabview_bug656778.js @@ -30,6 +30,16 @@ function test() { assertBoolPref(TabView.PREF_RESTORE_ENABLED_ONCE, enabledOnce); }; + let assertNotificationBannerVisible = function (win) { + let cw = win.TabView.getContentWindow(); + is(cw.iQ(".banner").length, 1, "notification banner is visible"); + }; + + let assertNotificationBannerNotVisible = function (win) { + let cw = win.TabView.getContentWindow(); + is(cw.iQ(".banner").length, 0, "notification banner is not visible"); + }; + let next = function () { if (tests.length == 0) { waitForFocus(finish); @@ -52,6 +62,7 @@ function test() { setPreferences(1, true, false); newWindowWithTabView(function (win) { + assertNotificationBannerVisible(win); assertPreferences(3, true, true); win.close(); @@ -72,10 +83,12 @@ function test() { setPreferences(1, false, false); newWindowWithTabView(function (win) { + assertNotificationBannerNotVisible(win); assertPreferences(1, false, false); win.TabView.firstUseExperienced = true; + assertNotificationBannerVisible(win); assertPreferences(3, true, true); win.close(); @@ -94,6 +107,7 @@ function test() { setPreferences(3, true, false); newWindowWithTabView(function (win) { + assertNotificationBannerNotVisible(win); assertPreferences(3, true, true); win.close(); @@ -111,6 +125,7 @@ function test() { setPreferences(3, true, true); newWindowWithTabView(function (win) { + assertNotificationBannerNotVisible(win); assertPreferences(3, true, true); win.close(); @@ -129,6 +144,7 @@ function test() { setPreferences(1, true, true); newWindowWithTabView(function (win) { + assertNotificationBannerNotVisible(win); assertPreferences(1, true, true); win.close(); diff --git a/browser/base/content/test/tabview/browser_tabview_launch.js b/browser/base/content/test/tabview/browser_tabview_launch.js index db4ff070bc9..03dddbcfcb4 100644 --- a/browser/base/content/test/tabview/browser_tabview_launch.js +++ b/browser/base/content/test/tabview/browser_tabview_launch.js @@ -28,7 +28,7 @@ function test() { newWin.document.getElementById("menu_tabview").doCommand(); }, function() { testMethodToHideAndShowTabView(function() { - EventUtils.synthesizeKey("E", { accelKey: true, shiftKey: true }, newWin); + EventUtils.synthesizeKey("e", { accelKey: true, shiftKey: true }, newWin); }, finish); }); }); diff --git a/browser/base/content/test/tabview/head.js b/browser/base/content/test/tabview/head.js index 53d25e9e511..107146b6a0a 100644 --- a/browser/base/content/test/tabview/head.js +++ b/browser/base/content/test/tabview/head.js @@ -83,9 +83,11 @@ function newWindowWithTabView(shownCallback, loadCallback, width, height) { ",width=" + winWidth); whenWindowLoaded(win, function () { - if (typeof loadCallback == "function") + if (loadCallback) loadCallback(win); + }); + whenDelayedStartupFinished(win, function () { showTabView(function () shownCallback(win), win); }); } diff --git a/browser/components/sessionstore/content/aboutSessionRestore.js b/browser/components/sessionstore/content/aboutSessionRestore.js index ae553537492..bbbe87b08d1 100644 --- a/browser/components/sessionstore/content/aboutSessionRestore.js +++ b/browser/components/sessionstore/content/aboutSessionRestore.js @@ -289,6 +289,7 @@ var treeView = { isSeparator: function(idx) { return false; }, isSorted: function() { return false; }, isEditable: function(idx, column) { return false; }, + canDrop: function(idx, orientation, dt) { return false; }, getLevel: function(idx) { return this.isContainer(idx) ? 0 : 1; }, getParentIndex: function(idx) { diff --git a/browser/components/sessionstore/src/nsSessionStore.js b/browser/components/sessionstore/src/nsSessionStore.js index 99962fa296c..3be78775b13 100644 --- a/browser/components/sessionstore/src/nsSessionStore.js +++ b/browser/components/sessionstore/src/nsSessionStore.js @@ -2222,8 +2222,14 @@ SessionStoreService.prototype = { if (!aWindow._hosts) return; for (var [host, isPinned] in Iterator(aWindow._hosts)) { - var list = CookieSvc.getCookiesFromHost(host); - while (list.hasMoreElements()) { + let list; + try { + list = CookieSvc.getCookiesFromHost(host); + } + catch (ex) { + debug("getCookiesFromHost failed. Host: " + host); + } + while (list && list.hasMoreElements()) { var cookie = list.getNext().QueryInterface(Ci.nsICookie2); // aWindow._hosts will only have hosts with the right privacy rules, // so there is no need to do anything special with this call to @@ -2952,8 +2958,11 @@ SessionStoreService.prototype = { // so we can just set the URL to null. browser.__SS_restore_data = { url: null }; browser.__SS_restore_tab = aTab; + if (didStartLoad) + browser.stop(); didStartLoad = true; - browser.loadURI(tabData.userTypedValue, null, null, true); + browser.loadURIWithFlags(tabData.userTypedValue, + Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP); } } diff --git a/browser/locales/en-US/chrome/browser/tabview.properties b/browser/locales/en-US/chrome/browser/tabview.properties index ef12273d397..534872ac849 100644 --- a/browser/locales/en-US/chrome/browser/tabview.properties +++ b/browser/locales/en-US/chrome/browser/tabview.properties @@ -2,3 +2,4 @@ tabview.groupItem.newTabButton=New tab tabview.groupItem.defaultName=Name this tab group… tabview.groupItem.undoCloseGroup=Undo Close Group tabview.search.otherWindowTabs=Tabs from other windows +tabview.notification.sessionStore=Tabs and groups will automatically be restored the next time you start %S.