Bug 633190 - Inconsistent animation behavior for creating new tab in Panorama r=ian

This commit is contained in:
Raymond Lee 2011-06-09 04:21:20 +08:00
parent dbae20fd37
commit 29cc63cb2a
6 changed files with 164 additions and 59 deletions

View File

@ -786,7 +786,7 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
return (groupItem != self && !groupItem.getChildren().length);
});
let group = (emptyGroups.length ? emptyGroups[0] : GroupItems.newGroup());
group.newTab();
group.newTab(null, { closedLastTab: true });
}
this.destroy();
@ -1791,14 +1791,16 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
// ----------
// Function: newTab
// Creates a new tab within this groupItem.
newTab: function GroupItem_newTab(url) {
UI.setActive(this, { dontSetActiveTabInGroup: true });
let newTab = gBrowser.loadOneTab(url || "about:blank", {inBackground: true});
// Parameters:
// url - the new tab should open this url as well
// options - the options object
// closedLastTab - boolean indicates the last tab has just been closed
newTab: function GroupItem_newTab(url, options) {
if (options && options.closedLastTab)
UI.closedLastTabInTabView = true;
// TabItems will have handled the new tab and added the tabItem property.
// We don't have to check if it's an app tab (and therefore wouldn't have a
// TabItem), since we've just created it.
newTab._tabViewTabItem.zoomIn(!url);
UI.setActive(this, { dontSetActiveTabInGroup: true });
gBrowser.loadOneTab(url || "about:blank", { inBackground: false });
},
// ----------

View File

@ -379,7 +379,7 @@ TabItem.prototype = Utils.extend(new Item(), new Subscribable(), {
}
} else {
// create tab by double click is handled in UI_init().
if (!TabItems.creatingNewOrphanTab)
if (!UI.creatingNewOrphanTab)
GroupItems.newTab(self, {immediately: true});
}
@ -563,7 +563,7 @@ TabItem.prototype = Utils.extend(new Item(), new Subscribable(), {
});
group = (emptyGroups.length ? emptyGroups[0] : GroupItems.newGroup());
}
group.newTab();
group.newTab(null, { closedLastTab: true });
}
// when "TabClose" event is fired, the browser tab is about to close and our
// item "close" is fired before the browser tab actually get closed.
@ -665,6 +665,8 @@ TabItem.prototype = Utils.extend(new Item(), new Subscribable(), {
}
if (self.parent && self.parent.expanded)
self.parent.collapse();
self._sendToSubscribers("zoomedIn");
}
let animateZoom = gPrefBranch.getBoolPref("animate_zoom");
@ -803,7 +805,6 @@ let TabItems = {
_lastUpdateTime: Date.now(),
_eventListeners: [],
_pauseUpdateForTest: false,
creatingNewOrphanTab: false,
tempCanvas: null,
_reconnectingPaused: false,
tabItemPadding: {},

View File

@ -139,6 +139,14 @@ let UI = {
// Used to prevent keypress being handled after quitting search mode.
ignoreKeypressForSearch: false,
// Variable: creatingNewOrphanTab
// Used to keep track of whether we are creating a new oprhan tab or not.
creatingNewOrphanTab: false,
// Variable: _lastOpenedTab
// Used to keep track of the last opened tab.
_lastOpenedTab: null,
// ----------
// Function: toString
// Prints [UI] for debug use
@ -196,20 +204,21 @@ let UI = {
(self._lastClickPositions.y - self.DBLCLICK_OFFSET) <= e.clientY &&
(self._lastClickPositions.y + self.DBLCLICK_OFFSET) >= e.clientY) {
self.setActive(null);
TabItems.creatingNewOrphanTab = true;
let newTab =
gBrowser.loadOneTab("about:blank", { inBackground: true });
self.creatingNewOrphanTab = true;
let box =
new Rect(e.clientX - Math.floor(TabItems.tabWidth/2),
e.clientY - Math.floor(TabItems.tabHeight/2),
TabItems.tabWidth, TabItems.tabHeight);
let newTab =
gBrowser.loadOneTab("about:blank", { inBackground: false });
newTab._tabViewTabItem.setBounds(box, true);
newTab._tabViewTabItem.pushAway(true);
self.setActive(newTab._tabViewTabItem);
TabItems.creatingNewOrphanTab = false;
self.creatingNewOrphanTab = false;
// the bounds of tab item is set and we can zoom in now.
newTab._tabViewTabItem.zoomIn(true);
self._lastClick = 0;
@ -727,6 +736,8 @@ let UI = {
// if it's an app tab, add it to all the group items
if (tab.pinned)
GroupItems.addAppTab(tab);
else if (self.isTabViewVisible())
self._lastOpenedTab = tab;
};
// TabClose
@ -861,30 +872,40 @@ let UI = {
// Function: onTabSelect
// Called when the user switches from one tab to another outside of the TabView UI.
onTabSelect: function UI_onTabSelect(tab) {
let currentTab = this._currentTab;
this._currentTab = tab;
// if the last visible tab has just been closed, don't show the chrome UI.
if (this.isTabViewVisible() &&
(this._closedLastVisibleTab || this._closedSelectedTabInTabView ||
this.restoredClosedTab)) {
if (this.restoredClosedTab) {
// when the tab view UI is being displayed, update the thumb for the
// restored closed tab after the page load
tab.linkedBrowser.addEventListener("load", function (event) {
tab.linkedBrowser.removeEventListener("load", arguments.callee, true);
TabItems._update(tab);
}, true);
if (this.isTabViewVisible()) {
if (!this.restoredClosedTab && this._lastOpenedTab == tab &&
tab._tabViewTabItem) {
if (!this.creatingNewOrphanTab)
tab._tabViewTabItem.zoomIn(true);
this._lastOpenedTab = null;
return;
}
if (this._closedLastVisibleTab ||
(this._closedSelectedTabInTabView && !this.closedLastTabInTabView) ||
this.restoredClosedTab) {
if (this.restoredClosedTab) {
// when the tab view UI is being displayed, update the thumb for the
// restored closed tab after the page load
tab.linkedBrowser.addEventListener("load", function (event) {
tab.linkedBrowser.removeEventListener("load", arguments.callee, true);
TabItems._update(tab);
}, true);
}
this._closedLastVisibleTab = false;
this._closedSelectedTabInTabView = false;
this.closedLastTabInTabView = false;
this.restoredClosedTab = false;
return;
}
this._closedLastVisibleTab = false;
this._closedSelectedTabInTabView = false;
this.restoredClosedTab = false;
return;
}
// reset these vars, just in case.
this._closedLastVisibleTab = false;
this._closedSelectedTabInTabView = false;
this.closedLastTabInTabView = false;
this.restoredClosedTab = false;
this._lastOpenedTab = null;
// if TabView is visible but we didn't just close the last tab or
// selected tab, show chrome.
@ -896,12 +917,7 @@ let UI = {
if (this._currentTab != tab)
return;
let oldItem = null;
let newItem = null;
if (currentTab && currentTab._tabViewTabItem)
oldItem = currentTab._tabViewTabItem;
// update the tab bar for the new tab's group
if (tab && tab._tabViewTabItem) {
if (!TabItems.reconnectingPaused()) {
@ -1499,14 +1515,14 @@ let UI = {
return (!groupItem.hidden && groupItem.getChildren().length > 0);
});
// no pinned tabs, no visible groups and no orphaned tabs: open a new
// group. open a blank tab and return
// group, a blank tab and return
if (!unhiddenGroups.length && !GroupItems.getOrphanedTabs().length) {
let emptyGroups = GroupItems.groupItems.filter(function (groupItem) {
return (!groupItem.hidden && !groupItem.getChildren().length);
});
let group = (emptyGroups.length ? emptyGroups[0] : GroupItems.newGroup());
if (!gBrowser._numPinnedTabs) {
group.newTab();
group.newTab(null, { closedLastTab: true });
return;
}
}

View File

@ -36,20 +36,23 @@ function test3() {
ok(!contentWindow.isSearchEnabled(), "The search is disabled")
is(gBrowser.tabs.length, 1, "There is one tab before cmd/ctrl + t is pressed");
EventUtils.synthesizeKey("t", { accelKey: true }, contentWindow);
is(gBrowser.tabs.length, 2, "There are two tabs after cmd/ctrl + t is pressed");
gBrowser.tabs[0].linkedBrowser.loadURI("about:robots");
gBrowser.tabs[1].linkedBrowser.loadURI("http://example.com/");
whenTabViewIsHidden(function() {
is(gBrowser.tabs.length, 2, "There are two tabs after cmd/ctrl + t is pressed");
afterAllTabsLoaded(function () {
showTabView(test4);
gBrowser.tabs[0].linkedBrowser.loadURI("about:robots");
gBrowser.tabs[1].linkedBrowser.loadURI("http://example.com/");
afterAllTabsLoaded(function () {
showTabView(test4);
});
});
EventUtils.synthesizeKey("t", { accelKey: true }, contentWindow);
}
function test4() {
is(gBrowser.tabs.length, 2, "There are two tabs");
let onTabClose = function() {
gBrowser.tabContainer.removeEventListener("TabClose", onTabClose, true);
executeSoon(function() {
@ -59,7 +62,7 @@ function test4() {
is(gBrowser.tabs.length, 2, "There are two tabs after restoring one");
gBrowser.tabs[0].linkedBrowser.loadURI("about:blank");
gBrowser.removeTab(gBrowser.tabs[1]);
gBrowser.selectedTab = gBrowser.tabs[0];
test8();
});
};
@ -69,14 +72,14 @@ function test4() {
// below key combination shouldn't trigger actions in tabview UI
function test8() {
let newTab = gBrowser.loadOneTab("about:blank", { inBackground: true });
showTabView(function() {
is(gBrowser.tabs.length, 2, "There are two tabs before cmd/ctrl + w is pressed");
EventUtils.synthesizeKey("w", { accelKey: true }, contentWindow);
is(gBrowser.tabs.length, 2, "There are two tabs after cmd/ctrl + w is pressed");
is(gBrowser.tabs.length, 2, "There are two tabs before cmd/ctrl + w is pressed");
EventUtils.synthesizeKey("w", { accelKey: true }, contentWindow);
is(gBrowser.tabs.length, 2, "There are two tabs after cmd/ctrl + w is pressed");
gBrowser.removeTab(newTab);
test9();
gBrowser.removeTab(gBrowser.tabs[1]);
test9();
});
}
function test9() {

View File

@ -64,11 +64,8 @@ function part1(win) {
ok(!contentWindow.UI.getActiveOrphanTab(), "There is no active orphan tab.");
ok(win.TabView.isVisible(), "Tab View is visible.");
win.gBrowser.tabContainer.addEventListener("TabSelect", function() {
win.gBrowser.tabContainer.removeEventListener("TabSelect", arguments.callee, false);
executeSoon(part4);
}, false);
whenTabViewIsHidden(part4, win);
win.document.getElementById("cmd_newNavigatorTab").doCommand();
}

View File

@ -0,0 +1,86 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
let origTab = gBrowser.visibleTabs[0];
let contentWindow;
function test() {
waitForExplicitFinish();
test1();
}
// Open a new tab when the active tab item belongs to a group item.
function test1() {
registerCleanupFunction(function () TabView.hide());
showTabView(function() {
ok(origTab._tabViewTabItem.parent, "The original tab belongs to a group");
contentWindow = TabView.getContentWindow();
contentWindow.UI.setActive(origTab._tabViewTabItem);
testCreateTabAndThen(test2);
});
}
// Open a new tab when the active tab item is nothing.
function test2() {
showTabView(function() {
contentWindow.UI.setActive(null, { onlyRemoveActiveTab: true });
testCreateTabAndThen(test3);
});
}
// Open a new tab when the active tab item is an orphan tab.
function test3() {
showTabView(function() {
let groupItem = origTab._tabViewTabItem.parent;
let tabItems = groupItem.getChildren();
is(tabItems.length, 3, "There are 3 tab items in the group");
let lastTabItem = tabItems[tabItems.length - 1];
groupItem.remove(lastTabItem);
let orphanedTabs = contentWindow.GroupItems.getOrphanedTabs();
is(orphanedTabs.length, 1, "There should be 1 orphan tab");
is(orphanedTabs[0], lastTabItem, "The tab item is the same as the orphan tab");
contentWindow.UI.setActive(lastTabItem);
testCreateTabAndThen(function() {
hideTabView(finish);
});
});
}
function testCreateTabAndThen(callback) {
ok(TabView.isVisible(), "Tab View is visible");
// detect tab open and zoomed in event.
let onTabOpen = function(event) {
gBrowser.tabContainer.removeEventListener("TabOpen", onTabOpen, false);
// ensure that the default tabview listener is called before so the
// tab._tabViewTabItem exists
executeSoon(function() {
let tab = event.target;
tabItem = tab._tabViewTabItem;
ok(tabItem, "Tab item is available after tab open");
registerCleanupFunction(function () gBrowser.removeTab(tab))
tabItem.addSubscriber(tabItem, "zoomedIn", function() {
tabItem.removeSubscriber(tabItem, "zoomedIn");
is(gBrowser.selectedTab, tab,
"The selected tab is the same as the newly opened tab");
executeSoon(callback);
});
});
}
gBrowser.tabContainer.addEventListener("TabOpen", onTabOpen, false);
// use the menu item (the same as pressing cmd/ctrl + t)
document.getElementById("menu_newNavigatorTab").doCommand();
}