Bug 637840 - after closing a group in panorama, focus should go to the last used tab in the last used group r=tim

This commit is contained in:
Raymond Lee 2011-09-06 13:04:38 +08:00
Родитель f03e0c8c47
Коммит 8906b70eb1
4 изменённых файлов: 185 добавлений и 6 удалений

Просмотреть файл

@ -711,8 +711,8 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
this._createUndoButton();
} else
this.close();
this._makeClosestTabActive();
this._makeLastActiveGroupItemActive();
},
// ----------
@ -727,6 +727,17 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
UI.setActive(closestTabItem);
},
// ----------
// Function: _makeLastActiveGroupItemActive
// Makes the last active group item active.
_makeLastActiveGroupItemActive: function GroupItem__makeLastActiveGroupItemActive() {
let groupItem = GroupItems.getLastActiveGroupItem();
if (groupItem)
UI.setActive(groupItem);
else
this._makeClosestTabActive();
},
// ----------
// Function: closeIfEmpty
// Closes the group if it's empty, is closable, and autoclose is enabled
@ -1149,9 +1160,9 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
options.dontClose = true;
let closed = options.dontClose ? false : this.closeIfEmpty();
if (closed)
this._makeClosestTabActive();
else if (!options.dontArrange) {
if (closed) {
this._makeLastActiveGroupItemActive();
} else if (!options.dontArrange) {
this.arrange({animate: !options.immediately});
this._unfreezeItemSize({dontArrange: true});
}
@ -1944,6 +1955,7 @@ let GroupItems = {
_autoclosePaused: false,
minGroupHeight: 110,
minGroupWidth: 125,
_lastActiveList: null,
// ----------
// Function: toString
@ -1969,6 +1981,8 @@ let GroupItems = {
self._delayedModUpdates.splice(idx, 1);
}
this._lastActiveList = new MRUList();
AllTabs.register("attrModified", handleAttrModified);
AllTabs.register("close", handleClose);
this._cleanupFunctions.push(function() {
@ -2312,6 +2326,7 @@ let GroupItems = {
return groupItem != pending.groupItem;
});
this._lastActiveList.remove(groupItem);
UI.updateTabButton();
},
@ -2423,10 +2438,21 @@ let GroupItems = {
iQ(groupItem.container).addClass('activeGroupItem');
this._lastActiveList.update(groupItem);
this._activeGroupItem = groupItem;
this._save();
},
// ----------
// Function: getLastActiveGroupItem
// Gets last active group item.
// Returns the <groupItem>. If nothing is found, return null.
getLastActiveGroupItem: function GroupItem_getLastActiveGroupItem() {
return this._lastActiveList.peek(function(groupItem) {
return (groupItem && !groupItem.hidden && groupItem.getChildren().length > 0)
});
},
// ----------
// Function: _updateTabBar
// Hides and shows tabs in the tab bar based on the active groupItem

Просмотреть файл

@ -50,7 +50,7 @@
// **********
// Title: utils.js
let EXPORTED_SYMBOLS = ["Point", "Rect", "Range", "Subscribable", "Utils"];
let EXPORTED_SYMBOLS = ["Point", "Rect", "Range", "Subscribable", "Utils", "MRUList"];
// #########
const Ci = Components.interfaces;
@ -795,3 +795,63 @@ let Utils = {
return null;
}
};
// ##########
// Class: MRUList
// A most recently used list.
//
// Constructor: MRUList
// If a is an array of entries, creates a copy of it.
function MRUList(a) {
if (Array.isArray(a))
this._list = a.concat();
else
this._list = [];
};
MRUList.prototype = {
// ----------
// Function: toString
// Prints [List (entry1, entry2, ...)] for debug use
toString: function MRUList_toString() {
return "[List (" + this._list.join(", ") + ")]";
},
// ----------
// Function: update
// Updates/inserts the given entry as the most recently used one in the list.
update: function MRUList_update(entry) {
this.remove(entry);
this._list.unshift(entry);
},
// ----------
// Function: remove
// Removes the given entry from the list.
remove: function MRUList_remove(entry) {
let index = this._list.indexOf(entry);
if (index > -1)
this._list.splice(index, 1);
},
// ----------
// Function: peek
// Returns the most recently used entry. If a filter exists, gets the most
// recently used entry which matches the filter.
peek: function MRUList_peek(filter) {
let match = null;
if (filter && typeof filter == "function")
this._list.some(function MRUList_peek_getEntry(entry) {
if (filter(entry)) {
match = entry
return true;
}
return false;
});
else
match = this._list.length > 0 ? this._list[0] : null;
return match;
},
};

Просмотреть файл

@ -130,6 +130,7 @@ _BROWSER_FILES = \
browser_tabview_bug634085.js \
browser_tabview_bug634672.js \
browser_tabview_bug635696.js \
browser_tabview_bug637840.js \
browser_tabview_bug640765.js \
browser_tabview_bug641802.js \
browser_tabview_bug642793.js \

Просмотреть файл

@ -0,0 +1,92 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
let cw;
function test() {
waitForExplicitFinish();
newWindowWithTabView(function(win) {
registerCleanupFunction(function() {
win.close();
});
cw = win.TabView.getContentWindow();
let groupItemOne = cw.GroupItems.groupItems[0];
is(groupItemOne.getChildren().length, 1, "Group one has 1 tab item");
let groupItemTwo = createGroupItemWithBlankTabs(win, 300, 300, 40, 2);
is(groupItemTwo.getChildren().length, 2, "Group two has 2 tab items");
let groupItemThree = createGroupItemWithBlankTabs(win, 300, 300, 40, 2);
is(groupItemThree.getChildren().length, 2, "Group three has 2 tab items");
testMoreRecentlyUsedGroup(groupItemOne, groupItemTwo, function() {
testMoreRecentlyUsedGroup(groupItemOne, groupItemThree, function() {
testRemoveGroupAndCheckMoreRecentlyUsedGroup(groupItemOne, groupItemTwo);
});
});
});
}
function testMoreRecentlyUsedGroup(groupItemOne, otherGroupItem, callback) {
let tabItem = otherGroupItem.getChild(1);
cw.UI.setActive(tabItem);
is(otherGroupItem.getActiveTab(), tabItem, "The second item in the other group is active");
is(cw.GroupItems.getActiveGroupItem(), otherGroupItem, "The other group is active");
let tabItemInGroupItemOne = groupItemOne.getChild(0);
cw.UI.setActive(tabItemInGroupItemOne);
is(groupItemOne.getActiveTab(), tabItemInGroupItemOne, "The first item in group one is active");
is(cw.GroupItems.getActiveGroupItem(), groupItemOne, "The group one is active");
groupItemOne.addSubscriber("groupHidden", function onHide() {
groupItemOne.removeSubscriber("groupHidden", onHide);
// group item three should have the focus
is(otherGroupItem.getActiveTab(), tabItem, "The second item in the other group is active after group one is hidden");
is(cw.GroupItems.getActiveGroupItem(), otherGroupItem, "The other group is active active after group one is hidden");
groupItemOne.addSubscriber("groupShown", function onShown() {
groupItemOne.removeSubscriber("groupShown", onShown);
is(groupItemOne.getActiveTab(), tabItemInGroupItemOne, "The first item in group one is active after it is shown");
is(cw.GroupItems.getActiveGroupItem(), groupItemOne, "The group one is active after it is shown");
callback();
});
// click on the undo button
EventUtils.sendMouseEvent(
{ type: "click" }, groupItemOne.$undoContainer[0], cw);
});
// click on the close button of group item one
let closeButton = groupItemOne.container.getElementsByClassName("close");
ok(closeButton[0], "Group item one close button exists");
EventUtils.sendMouseEvent({ type: "click" }, closeButton[0], cw);
}
function testRemoveGroupAndCheckMoreRecentlyUsedGroup(groupItemOne, groupItemTwo) {
let tabItem = groupItemTwo.getChild(0);
cw.UI.setActive(tabItem);
is(groupItemTwo.getActiveTab(), tabItem, "The first item in the group two is active");
is(cw.GroupItems.getActiveGroupItem(), groupItemTwo, "The group two is active");
let tabItemInGroupItemOne = groupItemOne.getChild(0);
tabItemInGroupItemOne.addSubscriber("close", function onClose() {
tabItemInGroupItemOne.removeSubscriber("close", onClose);
is(groupItemTwo.getActiveTab(), tabItem, "The first item in the group two is still active after group one is closed");
is(cw.GroupItems.getActiveGroupItem(), groupItemTwo, "The group two is still active after group one is closed");
finish();
});
// close the tab item and the group item
let closeButton = tabItemInGroupItemOne.container.getElementsByClassName("close");
ok(closeButton[0], "Tab item close button exists");
EventUtils.sendMouseEvent({ type: "mousedown" }, closeButton[0], cw);
EventUtils.sendMouseEvent({ type: "mouseup" }, closeButton[0], cw);
}