author | Raymond Lee <raymond@appcoast.com> |
Fri, 04 Feb 2011 10:16:23 +0100 | |
changeset 61927 | f2a6a78478dc6692fc06cb85a97d130650676018 |
parent 61926 | 847a825087f209993654ab1ff726998b9cb91a04 |
child 61928 | fa442c0d6d2939b18d5068312659c9702d2023fd |
push id | 18542 |
push user | dgottwald@mozilla.com |
push date | Fri, 04 Feb 2011 09:16:59 +0000 |
treeherder | mozilla-central@f2a6a78478dc [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | dao, b |
bugs | 626525 |
milestone | 2.0b12pre |
first release with | nightly win64
f2a6a78478dc
/
4.0b12pre
/
20110204030202
/
files
nightly linux32
nightly linux64
nightly mac
nightly win32
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
releases | nightly win64
4.0b12pre
/
20110204030202
/
pushlog to previous
|
--- a/browser/base/content/browser-tabview.js +++ b/browser/base/content/browser-tabview.js @@ -34,53 +34,89 @@ # 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 ***** let TabView = { _deck: null, _window: null, - _sessionstore: null, + _firstRunExperienced: false, + _browserKeyHandlerInitialized: false, VISIBILITY_IDENTIFIER: "tabview-visibility", // ---------- get windowTitle() { delete this.windowTitle; let brandBundle = document.getElementById("bundle_brand"); let brandShortName = brandBundle.getString("brandShortName"); let title = gNavigatorBundle.getFormattedString("tabView2.title", [brandShortName]); return this.windowTitle = title; }, + + // ---------- + get firstRunExperienced() { + return this._firstRunExperienced; + }, // ---------- init: function TabView_init() { - // ___ keys - this._setBrowserKeyHandlers(); + if (!Services.prefs.prefHasUserValue("browser.panorama.experienced_first_run") || + !Services.prefs.getBoolPref("browser.panorama.experienced_first_run")) { + Services.prefs.addObserver( + "browser.panorama.experienced_first_run", this, false); + } else { + this._firstRunExperienced = true; + + if ((gBrowser.tabs.length - gBrowser.visibleTabs.length) > 0) + this._setBrowserKeyHandlers(); - // ___ visibility - this._sessionstore = - Cc["@mozilla.org/browser/sessionstore;1"]. - getService(Ci.nsISessionStore); + // ___ visibility + let sessionstore = + Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore); + let data = sessionstore.getWindowValue(window, this.VISIBILITY_IDENTIFIER); - let data = this._sessionstore.getWindowValue(window, this.VISIBILITY_IDENTIFIER); + if (data && data == "true") { + this.show(); + } else { + let self = this; - if (data && data == "true") { - this.show(); - } else { - let self = this; - // if a tab is changed from hidden to unhidden and the iframe is not - // initialized, load the iframe and setup the tab. - this._tabShowEventListener = function (event) { - if (!self._window) - self._initFrame(function() { - self._window.UI.onTabSelect(gBrowser.selectedTab); - }); - }; - gBrowser.tabContainer.addEventListener( + // if a tab is changed from hidden to unhidden and the iframe is not + // initialized, load the iframe and setup the tab. + this._tabShowEventListener = function (event) { + if (!self._window) + self._initFrame(function() { + self._window.UI.onTabSelect(gBrowser.selectedTab); + }); + }; + gBrowser.tabContainer.addEventListener( + "TabShow", this._tabShowEventListener, true); + } + } + }, + + // ---------- + // Observes topic changes. + observe: function TabView_observe(subject, topic, data) { + if (topic == "nsPref:changed") { + Services.prefs.removeObserver( + "browser.panorama.experienced_first_run", this); + this._firstRunExperienced = true; + } + }, + + // ---------- + // Uninitializes TabView. + uninit: function TabView_uninit() { + if (!this._firstRunExperienced) { + Services.prefs.removeObserver( + "browser.panorama.experienced_first_run", this); + } + if (this._tabShowEventListener) { + gBrowser.tabContainer.removeEventListener( "TabShow", this._tabShowEventListener, true); } }, // ---------- // Creates the frame and calls the callback once it's loaded. // If the frame already exists, calls the callback immediately. _initFrame: function TabView__initFrame(callback) { @@ -102,17 +138,20 @@ let TabView = { iframe.setAttribute("src", "chrome://browser/content/tabview.html"); this._deck.appendChild(iframe); this._window = iframe.contentWindow; if (this._tabShowEventListener) { gBrowser.tabContainer.removeEventListener( "TabShow", this._tabShowEventListener, true); + this._tabShowEventListener = null; } + + this._setBrowserKeyHandlers(); } }, // ---------- getContentWindow: function TabView_getContentWindow() { return this._window; }, @@ -146,17 +185,17 @@ let TabView = { // ---------- toggle: function() { if (this.isVisible()) this.hide(); else this.show(); }, - getActiveGroupName: function Tabview_getActiveGroupName() { + getActiveGroupName: function TabView_getActiveGroupName() { // We get the active group this way, instead of querying // GroupItems.getActiveGroupItem() because the tabSelect event // will not have happened by the time the browser tries to // update the title. let activeTab = window.gBrowser.selectedTab; if (activeTab._tabViewTabItem && activeTab._tabViewTabItem.parent){ let groupName = activeTab._tabViewTabItem.parent.getTitle(); if (groupName) @@ -189,46 +228,57 @@ let TabView = { isEmpty = false; } }); separator.hidden = isEmpty; }); }, // ---------- - _createGroupMenuItem : function(groupItem) { + _createGroupMenuItem: function TabView__createGroupMenuItem(groupItem) { let menuItem = document.createElement("menuitem") menuItem.setAttribute("label", groupItem.getTitle()); menuItem.setAttribute( "oncommand", "TabView.moveTabTo(TabContextMenu.contextTab,'" + groupItem.id + "')"); return menuItem; }, // ---------- - moveTabTo: function(tab, groupItemId) { - if (this._window) + moveTabTo: function TabView_moveTabTo(tab, groupItemId) { + if (this._window) { this._window.GroupItems.moveTabToGroupItem(tab, groupItemId); + } else { + let self = this; + this._initFrame(function() { + self._window.GroupItems.moveTabToGroupItem(tab, groupItemId); + }); + } }, // ---------- - enableSearch: function Tabview_enableSearch(event) { + enableSearch: function TabView_enableSearch(event) { if (this._window) this._window.UI.enableSearch(event); }, // ---------- // Adds new key commands to the browser, for invoking the Tab Candy UI // and for switching between groups of tabs when outside of the Tab Candy UI. - _setBrowserKeyHandlers : function() { - let self = this; + _setBrowserKeyHandlers: function TabView__setBrowserKeyHandlers() { + if (this._browserKeyHandlerInitialized) + return; + this._browserKeyHandlerInitialized = true; + + let self = this; window.addEventListener("keypress", function(event) { - if (self.isVisible()) + if (self.isVisible() || + (gBrowser.tabs.length - gBrowser.visibleTabs.length) == 0) return; let charCode = event.charCode; // Control (+ Shift) + ` if (event.ctrlKey && !event.metaKey && !event.altKey && (charCode == 96 || charCode == 126)) { event.stopPropagation(); event.preventDefault(); @@ -259,10 +309,18 @@ let TabView = { } }, // ---------- // Cleans up the tab view after undo close tab. afterUndoCloseTab: function () { if (this._window) this._window.UI.restoredClosedTab = false; + }, + + // ---------- + // On move to group pop showing. + moveToGroupPopupShowing: function TabView_moveToGroupPopupShowing(event) { + // there are hidden tabs so initialize the iframe and update the context menu + if ((gBrowser.tabs.length - gBrowser.visibleTabs.length) > 0) + this.updateContextMenu(TabContextMenu.contextTab, event.target); } };
--- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -1669,16 +1669,17 @@ function BrowserShutdown() { if (Win7Features) Win7Features.onCloseWindow(); gPrefService.removeObserver(ctrlTab.prefName, ctrlTab); gPrefService.removeObserver(allTabs.prefName, allTabs); ctrlTab.uninit(); allTabs.uninit(); + TabView.uninit(); CombinedStopReload.uninit(); gGestureSupport.init(false); FullScreen.cleanup(); try { @@ -8403,17 +8404,18 @@ var TabContextMenu = { // Hide "Bookmark All Tabs" for a pinned tab. Update its state if visible. let bookmarkAllTabs = document.getElementById("context_bookmarkAllTabs"); bookmarkAllTabs.hidden = this.contextTab.pinned; if (!bookmarkAllTabs.hidden) PlacesCommandHook.updateBookmarkAllTabsCommand(); // Hide "Move to Group" if it's a pinned tab. - document.getElementById("context_tabViewMenu").hidden = this.contextTab.pinned; + document.getElementById("context_tabViewMenu").hidden = + (this.contextTab.pinned || !TabView.firstRunExperienced); } }; XPCOMUtils.defineLazyGetter(this, "HUDConsoleUI", function () { Cu.import("resource:///modules/HUDService.jsm"); try { return HUDService.consoleUI; }
--- a/browser/base/content/browser.xul +++ b/browser/base/content/browser.xul @@ -120,17 +120,17 @@ accesskey="&pinAppTab.accesskey;" oncommand="gBrowser.pinTab(TabContextMenu.contextTab);"/> <menuitem id="context_unpinTab" label="&unpinAppTab.label;" hidden="true" accesskey="&unpinAppTab.accesskey;" oncommand="gBrowser.unpinTab(TabContextMenu.contextTab);"/> <menu id="context_tabViewMenu" label="&moveToGroup.label;" accesskey="&moveToGroup.accesskey;"> <menupopup id="context_tabViewMenuPopup" - onpopupshowing="if (event.target == this) TabView.updateContextMenu(TabContextMenu.contextTab, this);"> + onpopupshowing="if (event.target == this) TabView.moveToGroupPopupShowing(event);"> <menuseparator id="context_tabViewNamedGroups" hidden="true"/> <menuitem id="context_tabViewNewGroup" label="&moveToNewGroup.label;" oncommand="TabView.moveTabTo(TabContextMenu.contextTab, null);"/> </menupopup> </menu> <menuitem id="context_openTabInWindow" label="&moveToNewWindow.label;" accesskey="&moveToNewWindow.accesskey;" tbattr="tabbrowser-multiple"
--- a/browser/base/content/test/tabview/Makefile.in +++ b/browser/base/content/test/tabview/Makefile.in @@ -94,16 +94,17 @@ include $(topsrcdir)/config/rules.mk browser_tabview_bug624265.js \ browser_tabview_bug624931.js \ browser_tabview_bug624727.js \ browser_tabview_bug624847.js \ browser_tabview_bug624953.js \ browser_tabview_bug625269.js \ browser_tabview_bug625424.js \ browser_tabview_bug626368.js \ + browser_tabview_bug626525.js \ browser_tabview_bug627288.js \ browser_tabview_bug627736.js \ browser_tabview_bug628165.js \ browser_tabview_bug628270.js \ browser_tabview_bug629195.js \ browser_tabview_bug630102.js \ browser_tabview_dragdrop.js \ browser_tabview_exit_button.js \
new file mode 100644 --- /dev/null +++ b/browser/base/content/test/tabview/browser_tabview_bug626525.js @@ -0,0 +1,160 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +let prefsBranch; +let currentActiveGroupItemId; + +function test() { + waitForExplicitFinish(); + + // disable the first run pref + prefsBranch = Services.prefs.getBranch("browser.panorama."); + prefsBranch.setBoolPref("experienced_first_run", false); + + let win = + window.openDialog(getBrowserURL(), "_blank", "all,dialog=no", "about:blank"); + + let onLoad = function() { + win.removeEventListener("load", onLoad, false); + + let theObserver = function(subject, topic, data) { + Services.obs.removeObserver( + theObserver, "browser-delayed-startup-finished"); + test1(win); + } + Services.obs.addObserver( + theObserver, "browser-delayed-startup-finished", false); + }; + + win.addEventListener("load", onLoad, false); +} + +// check whether tha menu is hidden when the "experienced_first_run" pref is +// false +function test1(win) { + is(win.gBrowser.tabs.length - win.gBrowser.visibleTabs.length, 0, + "There are no hidden tabs") + + let originalTab = win.gBrowser.visibleTabs[0]; + + openTabContextPopup(win, originalTab); + + ok(win.document.getElementById("context_tabViewMenu").hidden, + "The menu should be hidden"); + + closeTabContextPopup(win); + + executeSoon(function() { + ok(!win.TabView.getContentWindow(), "The tab view iframe is not loaded"); + test2(win); + }); +} + +// press the next group key combination and check whether the iframe has loaded or not +function test2(win) { + goToNextGroup(win); + + // give it a delay so we can ensure the iframe has not been loaded + executeSoon(function() { + ok(!win.TabView.getContentWindow(), + "The tab view iframe is not loaded after pressing the next group key combination"); + + test3(win); + }); +} + +// first run has happened, open the tab context menupopup and the tabview menu, +// move a tab to another group including iframe initialization. Then, +// use the key combination to change to the next group. +function test3(win) { + prefsBranch.setBoolPref("experienced_first_run", true); + + let newTab = win.gBrowser.addTab("about:blank"); + + // open the tab context menupopup and the tabview menupopup + openTabContextPopup(win, newTab); + win.document.getElementById("context_tabViewMenuPopup").openPopup( + win.document.getElementById("context_tabViewMenu"), "end_after", 0, 0, + true, false); + + ok(!win.document.getElementById("context_tabViewMenu").hidden, + "The menu should be visible now"); + is(win.gBrowser.tabs.length - win.gBrowser.visibleTabs.length, 0, + "There are no hidden tabs") + ok(!win.TabView.getContentWindow(), + "The tab view iframe is not loaded after opening tab context menu"); + + let onTabViewFrameInitialized = function() { + win.removeEventListener( + "tabviewframeinitialized", onTabViewFrameInitialized, false); + + let contentWindow = win.document.getElementById("tab-view").contentWindow; + + // show the tab view to ensure groups are created before checking. + let onTabViewShown = function() { + win.removeEventListener("tabviewshown", onTabViewShown, false); + + ok(win.TabView.isVisible(), "Tab View is visible"); + + is(contentWindow.GroupItems.groupItems.length, 2, + "There are two group items"); + is(contentWindow.GroupItems.groupItems[0].getChildren().length, 1, + "There should be one tab item in the first group"); + is(contentWindow.GroupItems.groupItems[1].getChildren().length, 1, + "There should be one tab item in the second group"); + + // simulate the next group key combination + currentActiveGroupItemId = + contentWindow.GroupItems.getActiveGroupItem().id; + + win.addEventListener("tabviewhidden", onTabViewHidden, false); + + win.TabView.toggle(); + }; + let onTabViewHidden = function() { + win.removeEventListener("tabviewhidden", onTabViewHidden, false); + + goToNextGroup(win); + + isnot(contentWindow.GroupItems.getActiveGroupItem().id, + currentActiveGroupItemId, "Just switched to another group"); + + // close the window and finish it + win.close(); + finish(); + }; + win.addEventListener("tabviewshown", onTabViewShown, false); + // give it a delay to ensure everything is loaded. + executeSoon(function() { win.TabView.toggle(); }); + }; + win.addEventListener( + "tabviewframeinitialized", onTabViewFrameInitialized, false); + // move the tab to another group using the menu item + win.document.getElementById("context_tabViewNewGroup").doCommand(); + + // close popups + win.document.getElementById("context_tabViewMenuPopup").hidePopup(); + closeTabContextPopup(win); +} + +function openTabContextPopup(win, tab) { + win.document.popupNode = tab; + win.document.getElementById("tabContextMenu").openPopup( + tab, "end_after", 0, 0, true, false); +} + +function closeTabContextPopup(win) { + win.document.getElementById("tabContextMenu").hidePopup(); +} + +function goToNextGroup(win) { + let utils = + win.QueryInterface(Ci.nsIInterfaceRequestor). + getInterface(Ci.nsIDOMWindowUtils); + + const masks = Ci.nsIDOMNSEvent; + let mval = 0; + mval |= masks.CONTROL_MASK; + + utils.sendKeyEvent("keypress", 0, 96, mval); +}