зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
f03e0c8c47
Коммит
8906b70eb1
|
@ -712,7 +712,7 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
|||
} 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);
|
||||
}
|
||||
|
Загрузка…
Ссылка в новой задаче