+ Renamed Group and Groups to GroupItem and GroupItems, respectively

+ Fixed a bug in "group sites"

--HG--
rename : browser/base/content/tabview/groups.js => browser/base/content/tabview/groupitems.js
extra : rebase_source : 06525a410c9f3a7d3a3f3023d6b1b520295a8fe6
This commit is contained in:
Ian Gilman 2010-08-06 15:46:55 -07:00
parent 0abeebc996
commit 502cc2969a
10 changed files with 362 additions and 361 deletions

View File

@ -82,7 +82,7 @@ var Drag = function(item, event, isResizing, isFauxDrag) {
if (!isFauxDrag) {
// When a tab drag starts, make it the focused tab.
if (this.item.isAGroup) {
if (this.item.isAGroupItem) {
var tab = UI.getActiveTab();
if (!tab || tab.parent != this.item) {
if (this.item._children.length)

View File

@ -11,7 +11,7 @@
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is groups.js.
* The Original Code is groupItems.js.
*
* The Initial Developer of the Original Code is
* Ian Gilman <ian@iangilman.com>.
@ -39,30 +39,30 @@
* ***** END LICENSE BLOCK ***** */
// **********
// Title: groups.js
// Title: groupItems.js
// ##########
// Class: Group
// A single group in the TabView window. Descended from <Item>.
// Class: GroupItem
// A single groupItem in the TabView window. Descended from <Item>.
// Note that it implements the <Subscribable> interface.
//
// ----------
// Constructor: Group
// Constructor: GroupItem
//
// Parameters:
// listOfEls - an array of DOM elements for tabs to be added to this group
// options - various options for this group (see below). In addition, gets passed
// listOfEls - an array of DOM elements for tabs to be added to this groupItem
// options - various options for this groupItem (see below). In addition, gets passed
// to <add> along with the elements provided.
//
// Possible options:
// id - specifies the group's id; otherwise automatically generated
// id - specifies the groupItem's id; otherwise automatically generated
// locked - see <Item.locked>; default is {}
// userSize - see <Item.userSize>; default is null
// bounds - a <Rect>; otherwise based on the locations of the provided elements
// container - a DOM element to use as the container for this group; otherwise will create
// title - the title for the group; otherwise blank
// dontPush - true if this group shouldn't push away on creation; default is false
window.Group = function Group(listOfEls, options) {
// container - a DOM element to use as the container for this groupItem; otherwise will create
// title - the title for the groupItem; otherwise blank
// dontPush - true if this groupItem shouldn't push away on creation; default is false
window.GroupItem = function GroupItem(listOfEls, options) {
try {
if (typeof(options) == 'undefined')
options = {};
@ -70,8 +70,8 @@ window.Group = function Group(listOfEls, options) {
this._inited = false;
this._children = []; // an array of Items
this.defaultSize = new Point(TabItems.tabWidth * 1.5, TabItems.tabHeight * 1.5);
this.isAGroup = true;
this.id = options.id || Groups.getNextID();
this.isAGroupItem = true;
this.id = options.id || GroupItems.getNextID();
this._isStacked = false;
this._stackAngles = [0];
this.expanded = null;
@ -81,14 +81,14 @@ window.Group = function Group(listOfEls, options) {
this.keepProportional = false;
// Variable: _activeTab
// The <TabItem> for the group's active tab.
// The <TabItem> for the groupItem's active tab.
this._activeTab = null;
// Variables: xDensity, yDensity
// "density" ranges from 0 to 1, with 0 being "not dense" = "squishable" and 1 being "dense"
// = "not squishable". For example, if there is extra space in the vertical direction,
// yDensity will be < 1. These are set by <Group.arrange>, as it is dependent on the tab items
// inside the group.
// yDensity will be < 1. These are set by <GroupItem.arrange>, as it is dependent on the tab items
// inside the groupItem.
this.xDensity = 0;
this.yDensity = 0;
@ -104,14 +104,14 @@ window.Group = function Group(listOfEls, options) {
}
if (!rectToBe) {
rectToBe = Groups.getBoundingBox(listOfEls);
rectToBe = GroupItems.getBoundingBox(listOfEls);
rectToBe.inset(-30, -30);
}
var $container = options.container;
if (!$container) {
$container = iQ('<div>')
.addClass('group')
.addClass('groupItem')
.css({position: 'absolute'})
.css(rectToBe);
}
@ -277,7 +277,7 @@ window.Group = function Group(listOfEls, options) {
if (!this.locked.bounds)
this.setResizable(true);
Groups.register(this);
GroupItems.register(this);
// ___ Position
var immediately = $container ? true : false;
@ -293,21 +293,21 @@ window.Group = function Group(listOfEls, options) {
this._inited = true;
this.save();
} catch(e) {
Utils.log("Error in Group()");
Utils.log("Error in GroupItem()");
Utils.log(e.stack);
}
};
// ----------
window.Group.prototype = Utils.extend(new Item(), new Subscribable(), {
window.GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
// ----------
// Variable: defaultName
// The prompt text for the title field.
defaultName: "name this group...",
defaultName: "name this groupItem...",
// -----------
// Function: setActiveTab
// Sets the active <TabItem> for this group
// Sets the active <TabItem> for this groupItem
setActiveTab: function(tab) {
Utils.assert('tab must be a TabItem', tab && tab.isATabItem);
this._activeTab = tab;
@ -315,14 +315,14 @@ window.Group.prototype = Utils.extend(new Item(), new Subscribable(), {
// -----------
// Function: getActiveTab
// Gets the active <TabItem> for this group
// Gets the active <TabItem> for this groupItem
getActiveTab: function() {
return this._activeTab;
},
// ----------
// Function: getStorageData
// Returns all of the info worth storing about this group.
// Returns all of the info worth storing about this groupItem.
getStorageData: function() {
var data = {
bounds: this.getBounds(),
@ -340,26 +340,26 @@ window.Group.prototype = Utils.extend(new Item(), new Subscribable(), {
// ----------
// Function: isEmpty
// Returns true if the tab group is empty and unnamed.
// Returns true if the tab groupItem is empty and unnamed.
isEmpty: function() {
return !this._children.length && !this.getTitle();
},
// ----------
// Function: save
// Saves this group to persistent storage.
// Saves this groupItem to persistent storage.
save: function() {
if (!this._inited) // too soon to save now
return;
var data = this.getStorageData();
if (Groups.groupStorageSanity(data))
Storage.saveGroup(gWindow, data);
if (GroupItems.groupItemStorageSanity(data))
Storage.saveGroupItem(gWindow, data);
},
// ----------
// Function: getTitle
// Returns the title of this group as a string.
// Returns the title of this groupItem as a string.
getTitle: function() {
var value = (this.$title ? this.$title.val() : '');
return (value == this.defaultName ? '' : value);
@ -367,7 +367,7 @@ window.Group.prototype = Utils.extend(new Item(), new Subscribable(), {
// ----------
// Function: setTitle
// Sets the title of this group with the given string
// Sets the title of this groupItem with the given string
setTitle: function(value) {
this.$title.val(value);
this.save();
@ -375,7 +375,7 @@ window.Group.prototype = Utils.extend(new Item(), new Subscribable(), {
// ----------
// Function: adjustTitleSize
// Used to adjust the width of the title box depending on group width and title size.
// Used to adjust the width of the title box depending on groupItem width and title size.
adjustTitleSize: function() {
Utils.assert('bounds needs to have been set', this.bounds);
var w = Math.min(this.bounds.width - 35, Math.max(150, this.getTitle().length * 6));
@ -386,7 +386,7 @@ window.Group.prototype = Utils.extend(new Item(), new Subscribable(), {
// ----------
// Function: getContentBounds
// Returns a <Rect> for the group's content area (which doesn't include the title, etc).
// Returns a <Rect> for the groupItem's content area (which doesn't include the title, etc).
getContentBounds: function() {
var box = this.getBounds();
var titleHeight = this.$titlebar.height();
@ -412,7 +412,7 @@ window.Group.prototype = Utils.extend(new Item(), new Subscribable(), {
// force - true to always update the DOM even if the bounds haven't changed; default false
setBounds: function(rect, immediately, options) {
if (!Utils.isRect(rect)) {
Utils.trace('Group.setBounds: rect is not a real rectangle!', rect);
Utils.trace('GroupItem.setBounds: rect is not a real rectangle!', rect);
return;
}
@ -491,7 +491,7 @@ window.Group.prototype = Utils.extend(new Item(), new Subscribable(), {
// ----------
// Function: setZ
// Set the Z order for the group's container, as well as its children.
// Set the Z order for the groupItem's container, as well as its children.
setZ: function(value) {
this.zIndex = value;
@ -518,23 +518,23 @@ window.Group.prototype = Utils.extend(new Item(), new Subscribable(), {
// ----------
// Function: close
// Closes the group, removing (but not closing) all of its children.
// Closes the groupItem, removing (but not closing) all of its children.
close: function() {
this.removeAll();
this._sendToSubscribers("close");
Groups.unregister(this);
GroupItems.unregister(this);
this.removeTrenches();
iQ(this.container).fadeOut(function() {
iQ(this).remove();
Items.unsquish();
});
Storage.deleteGroup(gWindow, this.id);
Storage.deleteGroupItem(gWindow, this.id);
},
// ----------
// Function: closeAll
// Closes the group and all of its children.
// Closes the groupItem and all of its children.
closeAll: function() {
var self = this;
if (this._children.length) {
@ -551,7 +551,7 @@ window.Group.prototype = Utils.extend(new Item(), new Subscribable(), {
// ----------
// Function: add
// Adds an item to the group.
// Adds an item to the groupItem.
// Parameters:
//
// a - The item to add. Can be an <Item>, a DOM element or a jQuery object.
@ -569,7 +569,7 @@ window.Group.prototype = Utils.extend(new Item(), new Subscribable(), {
$el = iQ(a);
item = Items.item($el);
}
Utils.assertThrow("shouldn't already be in another group", !item.parent || item.parent == this);
Utils.assertThrow("shouldn't already be in another groupItem", !item.parent || item.parent == this);
item.removeTrenches();
@ -581,11 +581,11 @@ window.Group.prototype = Utils.extend(new Item(), new Subscribable(), {
var self = this;
var wasAlreadyInThisGroup = false;
var wasAlreadyInThisGroupItem = false;
var oldIndex = this._children.indexOf(item);
if (oldIndex != -1) {
this._children.splice(oldIndex, 1);
wasAlreadyInThisGroup = true;
wasAlreadyInThisGroupItem = true;
}
// TODO: You should be allowed to drop in the white space at the bottom and have it go to the end
@ -631,11 +631,11 @@ window.Group.prototype = Utils.extend(new Item(), new Subscribable(), {
this._children.splice(index, 0, item);
item.setZ(this.getZ() + 1);
$el.addClass("tabInGroup");
$el.addClass("tabInGroupItem");
if (!wasAlreadyInThisGroup) {
if (!wasAlreadyInThisGroupItem) {
item.droppable(false);
item.groupData = {};
item.groupItemData = {};
item.addSubscriber(this, "close", function() {
self.remove($el);
@ -647,7 +647,7 @@ window.Group.prototype = Utils.extend(new Item(), new Subscribable(), {
item.setResizable(false);
if (item.tab == gBrowser.selectedTab)
Groups.setActiveGroup(this);
GroupItems.setActiveGroupItem(this);
}
if (!options.dontArrange) {
@ -660,13 +660,13 @@ window.Group.prototype = Utils.extend(new Item(), new Subscribable(), {
this._nextNewTabCallback = null;
}
} catch(e) {
Utils.log('Group.add error', e);
Utils.log('GroupItem.add error', e);
}
},
// ----------
// Function: remove
// Removes an item from the group.
// Removes an item from the groupItem.
// Parameters:
//
// a - The item to remove. Can be an <Item>, a DOM element or a jQuery object.
@ -693,7 +693,7 @@ window.Group.prototype = Utils.extend(new Item(), new Subscribable(), {
this._children.splice(index, 1);
item.setParent(null);
item.removeClass("tabInGroup");
item.removeClass("tabInGroupItem");
item.removeClass("stacked");
item.removeClass("stack-trayed");
item.setRotation(0);
@ -717,7 +717,7 @@ window.Group.prototype = Utils.extend(new Item(), new Subscribable(), {
// ----------
// Function: removeAll
// Removes all of the group's children.
// Removes all of the groupItem's children.
removeAll: function() {
var self = this;
var toRemove = this._children.concat();
@ -728,7 +728,7 @@ window.Group.prototype = Utils.extend(new Item(), new Subscribable(), {
// ----------
// Function: setNewTabButtonBounds
// Used for positioning the "new tab" button in the "new tabs" group.
// Used for positioning the "new tab" button in the "new tabs" groupItem.
setNewTabButtonBounds: function(box, immediately) {
if (!immediately)
this.$ntb.animate(box.css(), {
@ -741,14 +741,14 @@ window.Group.prototype = Utils.extend(new Item(), new Subscribable(), {
// ----------
// Function: hideExpandControl
// Hide the control which expands a stacked group into a quick-look view.
// Hide the control which expands a stacked groupItem into a quick-look view.
hideExpandControl: function() {
this.$expander.hide();
},
// ----------
// Function: showExpandControl
// Show the control which expands a stacked group into a quick-look view.
// Show the control which expands a stacked groupItem into a quick-look view.
showExpandControl: function() {
var childBB = this.getChild(0).getBounds();
var dT = childBB.top - this.getBounds().top;
@ -768,7 +768,7 @@ window.Group.prototype = Utils.extend(new Item(), new Subscribable(), {
// ----------
// Function: shouldStack
// Returns true if the group, given "count", should stack (instead of grid).
// Returns true if the groupItem, given "count", should stack (instead of grid).
shouldStack: function(count) {
if (count <= 1)
return false;
@ -901,13 +901,13 @@ window.Group.prototype = Utils.extend(new Item(), new Subscribable(), {
// compute h and w. h and w are the dimensions of each of the tabs... in other words, the
// height and width of the entire stack, modulo rotation.
if (bbAspect > itemAspect) { // Tall, thin group
if (bbAspect > itemAspect) { // Tall, thin groupItem
w = bb.width * scale;
h = w * itemAspect;
// let's say one, because, even though there's more space, we're enforcing that with scale.
this.xDensity = 1;
this.yDensity = h / (bb.height * scale);
} else { // Short, wide group
} else { // Short, wide groupItem
h = bb.height * scale;
w = h * (1 / itemAspect);
this.yDensity = 1;
@ -961,7 +961,7 @@ window.Group.prototype = Utils.extend(new Item(), new Subscribable(), {
// ----------
// Function: childHit
// Called by one of the group's children when the child is clicked on.
// Called by one of the groupItem's children when the child is clicked on.
//
// Returns an object:
// shouldZoom - true if the browser should launch into the tab represented by the child
@ -981,11 +981,11 @@ window.Group.prototype = Utils.extend(new Item(), new Subscribable(), {
// ___ we're stacked, but command isn't held down
/*if (!Keys.meta) {
Groups.setActiveGroup(self);
GroupItems.setActiveGroupItem(self);
return { shouldZoom: true };
}*/
Groups.setActiveGroup(self);
GroupItems.setActiveGroupItem(self);
return { shouldZoom: true };
/*this.expand();
@ -995,7 +995,7 @@ window.Group.prototype = Utils.extend(new Item(), new Subscribable(), {
expand: function() {
var self = this;
// ___ we're stacked, and command is held down so expand
Groups.setActiveGroup(self);
GroupItems.setActiveGroupItem(self);
var startBounds = this.getChild(0).getBounds();
var $tray = iQ("<div>").css({
top: startBounds.top,
@ -1077,7 +1077,7 @@ window.Group.prototype = Utils.extend(new Item(), new Subscribable(), {
// ----------
// Function: collapse
// Collapses the group from the expanded "tray" mode.
// Collapses the groupItem from the expanded "tray" mode.
collapse: function() {
if (this.expanded) {
var z = this.getZ();
@ -1154,8 +1154,8 @@ window.Group.prototype = Utils.extend(new Item(), new Subscribable(), {
if (location.distance(self._mouseDown.location) > 1.0)
return;
// Zoom into the last-active tab when the group
// is clicked, but only for non-stacked groups.
// Zoom into the last-active tab when the groupItem
// is clicked, but only for non-stacked groupItems.
var activeTab = self.getActiveTab();
if (!self._isStacked) {
if (activeTab)
@ -1176,7 +1176,7 @@ window.Group.prototype = Utils.extend(new Item(), new Subscribable(), {
// ----------
// Function: setResizable
// Sets whether the group is resizable and updates the UI accordingly.
// Sets whether the groupItem is resizable and updates the UI accordingly.
setResizable: function(value) {
this.resizeOptions.minWidth = 90;
this.resizeOptions.minHeight = 90;
@ -1192,9 +1192,9 @@ window.Group.prototype = Utils.extend(new Item(), new Subscribable(), {
// ----------
// Function: newTab
// Creates a new tab within this group.
// Creates a new tab within this groupItem.
newTab: function(url) {
Groups.setActiveGroup(this);
GroupItems.setActiveGroupItem(this);
let newTab = gBrowser.loadOneTab(url || "about:blank", {inBackground: true});
/* ToDo: why we need this here?
@ -1210,7 +1210,7 @@ window.Group.prototype = Utils.extend(new Item(), new Subscribable(), {
var self = this;
var doNextTab = function(tab) {
var group = Groups.getActiveGroup();
var groupItem = GroupItems.getActiveGroupItem();
iQ(tab.container).css({opacity: 0});
var $anim = iQ("<div>")
@ -1247,12 +1247,12 @@ window.Group.prototype = Utils.extend(new Item(), new Subscribable(), {
$anim.remove();
// We need a timeout here so that there is a chance for the
// new tab to get made! Otherwise it won't appear in the list
// of the group's tab.
// of the groupItem's tab.
// TODO: This is probably a terrible hack that sets up a race
// condition. We need a better solution.
Utils.timeout(function() {
self._sendToSubscribers("tabAdded", { groupId: self.id });
Groups.updateTabBarForActiveGroup();
self._sendToSubscribers("tabAdded", { groupItemId: self.id });
GroupItems.updateTabBarForActiveGroupItem();
}, 1);
}
});
@ -1269,9 +1269,9 @@ window.Group.prototype = Utils.extend(new Item(), new Subscribable(), {
// ----------
// Function: reorderTabItemsBasedOnTabOrder
// Reorders the tabs in a group based on the arrangment of the tabs
// Reorders the tabs in a groupItem based on the arrangment of the tabs
// shown in the tab bar. It does it by sorting the children
// of the group by the positions of their respective tabs in the
// of the groupItem by the positions of their respective tabs in the
// tab bar.
reorderTabItemsBasedOnTabOrder: function() {
this._children.sort(function(a,b) a.tab._tPos - b.tab._tPos);
@ -1282,7 +1282,7 @@ window.Group.prototype = Utils.extend(new Item(), new Subscribable(), {
// Function: reorderTabsBasedOnTabItemOrder
// Reorders the tabs in the tab bar based on the arrangment of the tabs
// shown in the group.
// shown in the groupItem.
reorderTabsBasedOnTabItemOrder: function() {
var tabBarTabs = Array.slice(gBrowser.tabs);
var currentIndex;
@ -1346,11 +1346,11 @@ window.Group.prototype = Utils.extend(new Item(), new Subscribable(), {
// ---------
// Function: onNextNewTab
// Sets up a one-time handler that gets called the next time a
// tab is added to the group.
// tab is added to the groupItem.
//
// Parameters:
// callback - the one-time callback that is fired when the next
// time a tab is added to a group; it gets passed the
// time a tab is added to a groupItem; it gets passed the
// new tab
onNextNewTab: function(callback) {
this._nextNewTabCallback = callback;
@ -1358,16 +1358,16 @@ window.Group.prototype = Utils.extend(new Item(), new Subscribable(), {
});
// ##########
// Class: Groups
// Singelton for managing all <Group>s.
window.Groups = {
groups: [],
// Class: GroupItems
// Singelton for managing all <GroupItem>s.
window.GroupItems = {
groupItems: [],
nextID: 1,
_inited: false,
// ----------
// Function: getNextID
// Returns the next unused group ID.
// Returns the next unused groupItem ID.
getNextID: function() {
var result = this.nextID;
this.nextID++;
@ -1377,11 +1377,11 @@ window.Groups = {
// ----------
// Function: getStorageData
// Returns an object for saving Groups state to persistent storage.
// Returns an object for saving GroupItems state to persistent storage.
getStorageData: function() {
var data = {nextID: this.nextID, groups: []};
this.groups.forEach(function(group) {
data.groups.push(group.getStorageData());
var data = {nextID: this.nextID, groupItems: []};
this.groupItems.forEach(function(groupItem) {
data.groupItems.push(groupItem.getStorageData());
});
return data;
@ -1389,28 +1389,28 @@ window.Groups = {
// ----------
// Function: saveAll
// Saves Groups state, as well as the state of all of the groups.
// Saves GroupItems state, as well as the state of all of the groupItems.
saveAll: function() {
this.save();
this.groups.forEach(function(group) {
group.save();
this.groupItems.forEach(function(groupItem) {
groupItem.save();
});
},
// ----------
// Function: save
// Saves Groups state.
// Saves GroupItems state.
save: function() {
if (!this._inited) // too soon to save now
return;
Storage.saveGroupsData(gWindow, {nextID:this.nextID});
Storage.saveGroupItemsData(gWindow, {nextID:this.nextID});
},
// ----------
// Function: getBoundingBox
// Given an array of DOM elements, returns a <Rect> with (roughly) the union of their locations.
getBoundingBox: function Groups_getBoundingBox(els) {
getBoundingBox: function GroupItems_getBoundingBox(els) {
var el, b;
var bounds = [iQ(el).bounds() for each (el in els)];
var left = Math.min.apply({},[ b.left for each (b in bounds) ]);
@ -1423,22 +1423,22 @@ window.Groups = {
// ----------
// Function: reconstitute
// Restores to stored state, creating groups as needed.
// If no data, sets up blank slate (including "new tabs" group).
reconstitute: function(groupsData, groupData) {
// Restores to stored state, creating groupItems as needed.
// If no data, sets up blank slate (including "new tabs" groupItem).
reconstitute: function(groupItemsData, groupItemData) {
try {
if (groupsData && groupsData.nextID)
this.nextID = groupsData.nextID;
if (groupItemsData && groupItemsData.nextID)
this.nextID = groupItemsData.nextID;
if (groupData) {
for (var id in groupData) {
var group = groupData[id];
if (this.groupStorageSanity(group)) {
if (groupItemData) {
for (var id in groupItemData) {
var groupItem = groupItemData[id];
if (this.groupItemStorageSanity(groupItem)) {
var options = {
dontPush: true
};
new Group([], Utils.extend({}, group, options));
new GroupItem([], Utils.extend({}, groupItem, options));
}
}
}
@ -1451,13 +1451,13 @@ window.Groups = {
},
// ----------
// Function: groupStorageSanity
// Given persistent storage data for a group, returns true if it appears to not be damaged.
groupStorageSanity: function(groupData) {
// Function: groupItemStorageSanity
// Given persistent storage data for a groupItem, returns true if it appears to not be damaged.
groupItemStorageSanity: function(groupItemData) {
// TODO: check everything
var sane = true;
if (!Utils.isRect(groupData.bounds)) {
Utils.log('Groups.groupStorageSanity: bad bounds', groupData.bounds);
if (!Utils.isRect(groupItemData.bounds)) {
Utils.log('GroupItems.groupItemStorageSanity: bad bounds', groupItemData.bounds);
sane = false;
}
@ -1465,15 +1465,15 @@ window.Groups = {
},
// ----------
// Function: getGroupWithTitle
// Returns the <Group> that has the given title, or null if none found.
// TODO: what if there are multiple groups with the same title??
// Function: getGroupItemWithTitle
// Returns the <GroupItem> that has the given title, or null if none found.
// TODO: what if there are multiple groupItems with the same title??
// Right now, looks like it'll return the last one.
getGroupWithTitle: function(title) {
getGroupItemWithTitle: function(title) {
var result = null;
this.groups.forEach(function(group) {
if (group.getTitle() == title) {
result = group;
this.groupItems.forEach(function(groupItem) {
if (groupItem.getTitle() == title) {
result = groupItem;
return false;
}
});
@ -1483,32 +1483,32 @@ window.Groups = {
// ----------
// Function: register
// Adds the given <Group> to the list of groups we're tracking.
register: function(group) {
Utils.assert('group', group);
Utils.assert('only register once per group', this.groups.indexOf(group) == -1);
this.groups.push(group);
// Adds the given <GroupItem> to the list of groupItems we're tracking.
register: function(groupItem) {
Utils.assert('groupItem', groupItem);
Utils.assert('only register once per groupItem', this.groupItems.indexOf(groupItem) == -1);
this.groupItems.push(groupItem);
},
// ----------
// Function: unregister
// Removes the given <Group> from the list of groups we're tracking.
unregister: function(group) {
var index = this.groups.indexOf(group);
// Removes the given <GroupItem> from the list of groupItems we're tracking.
unregister: function(groupItem) {
var index = this.groupItems.indexOf(groupItem);
if (index != -1)
this.groups.splice(index, 1);
this.groupItems.splice(index, 1);
if (group == this._activeGroup)
this._activeGroup = null;
if (groupItem == this._activeGroupItem)
this._activeGroupItem = null;
},
// ----------
// Function: group
// Given some sort of identifier, returns the appropriate group.
// Currently only supports group ids.
group: function(a) {
// Function: groupItem
// Given some sort of identifier, returns the appropriate groupItem.
// Currently only supports groupItem ids.
groupItem: function(a) {
var result = null;
this.groups.forEach(function(candidate) {
this.groupItems.forEach(function(candidate) {
if (candidate.id == a) {
result = candidate;
return false;
@ -1520,10 +1520,12 @@ window.Groups = {
// ----------
// Function: arrange
// Arranges all of the groups into a grid.
// Arranges all of the groupItems into a grid.
arrange: function() {
var bounds = Items.getPageBounds();
var count = this.groups.length - 1;
bounds.bottom -= 20; // for the dev menu
var count = this.groupItems.length - 1;
var columns = Math.ceil(Math.sqrt(count));
var rows = ((columns * columns) - count >= columns ? columns - 1 : columns);
var padding = 12;
@ -1534,13 +1536,13 @@ window.Groups = {
var box = new Rect(startX, startY,
(totalWidth / columns) - padding,
(totalHeight / rows) - padding);
var i = 0;
this.groups.forEach(function(group) {
if (group.locked.bounds)
this.groupItems.forEach(function(groupItem) {
if (groupItem.locked.bounds)
return;
group.setBounds(box, true);
groupItem.setBounds(box, true);
box.left += box.width + padding;
i++;
@ -1553,31 +1555,31 @@ window.Groups = {
// ----------
// Function: removeAll
// Removes all tabs from all groups (which automatically closes all unnamed groups).
// Removes all tabs from all groupItems (which automatically closes all unnamed groupItems).
removeAll: function() {
var toRemove = this.groups.concat();
toRemove.forEach(function(group) {
group.removeAll();
var toRemove = this.groupItems.concat();
toRemove.forEach(function(groupItem) {
groupItem.removeAll();
});
},
// ----------
// Function: newTab
// Given a <TabItem>, files it in the appropriate group.
// Given a <TabItem>, files it in the appropriate groupItem.
newTab: function(tabItem) {
let group = this.getActiveGroup();
let groupItem = this.getActiveGroupItem();
let orphanTab = this.getActiveOrphanTab();
// Utils.log('newTab', group, orphanTab);
if (group) {
group.add(tabItem);
// Utils.log('newTab', groupItem, orphanTab);
if (groupItem) {
groupItem.add(tabItem);
} else if ( orphanTab ) {
let newGroupBounds = orphanTab.getBoundsWithTitle();
newGroupBounds.inset(-40,-40);
let newGroupItemBounds = orphanTab.getBoundsWithTitle();
newGroupItemBounds.inset(-40,-40);
let newGroup = new Group([orphanTab, tabItem], {bounds: newGroupBounds});
newGroup.snap();
let newGroupItem = new GroupItem([orphanTab, tabItem], {bounds: newGroupItemBounds});
newGroupItem.snap();
this.setActiveGroup(newGroup);
this.setActiveGroupItem(newGroupItem);
} else {
this.positionNewTabAtBottom(tabItem);
@ -1603,63 +1605,63 @@ window.Groups = {
},
// ----------
// Function: getActiveGroup
// Returns the active group. Active means the group where a new
// Function: getActiveGroupItem
// Returns the active groupItem. Active means the groupItem where a new
// tab will live when it is created as well as what tabs are
// shown in the tab bar when not in the TabView interface.
getActiveGroup: function() {
return this._activeGroup;
getActiveGroupItem: function() {
return this._activeGroupItem;
},
// ----------
// Function: setActiveGroup
// Sets the active group, thereby showing only the relavent tabs
// to that group. The change is visible only if the tab bar is
// Function: setActiveGroupItem
// Sets the active groupItem, thereby showing only the relavent tabs
// to that groupItem. The change is visible only if the tab bar is
// visible.
//
// Paramaters:
// group - the active <Group> or <null> if no group is active
// groupItem - the active <GroupItem> or <null> if no groupItem is active
// (which means we have an orphaned tab selected)
setActiveGroup: function(group) {
this._activeGroup = group;
this.updateTabBarForActiveGroup();
// if a group is active, we surely are not in an orphaned tab.
setActiveGroupItem: function(groupItem) {
this._activeGroupItem = groupItem;
this.updateTabBarForActiveGroupItem();
// if a groupItem is active, we surely are not in an orphaned tab.
this.setActiveOrphanTab(null);
},
// ----------
// Function: getActiveOrphanTab
// Returns the active orphan tab, in cases when there is no active group.
// Returns the active orphan tab, in cases when there is no active groupItem.
getActiveOrphanTab: function() {
return this._activeOrphanTab;
},
// ----------
// Function: setActiveOrphanTab
// In cases where an orphan tab (not in a group) is active by itself,
// In cases where an orphan tab (not in a groupItem) is active by itself,
// this function is called and the "active orphan tab" is set.
//
// Paramaters:
// group - the active <TabItem> or <null>
// groupItem - the active <TabItem> or <null>
setActiveOrphanTab: function(tabItem) {
this._activeOrphanTab = tabItem;
},
// ----------
// Function: updateTabBarForActiveGroup
// Hides and shows tabs in the tab bar based on the active group.
updateTabBarForActiveGroup: function() {
// Function: updateTabBarForActiveGroupItem
// Hides and shows tabs in the tab bar based on the active groupItem.
updateTabBarForActiveGroupItem: function() {
if (!window.UI)
return; // called too soon
let tabItems = this._activeGroup == null ? this.getOrphanedTabs() :
this._activeGroup._children;
let tabItems = this._activeGroupItem == null ? this.getOrphanedTabs() :
this._activeGroupItem._children;
gBrowser.showOnlyTheseTabs(tabItems.map(function(item) item.tab));
},
// ----------
// Function: getOrphanedTabs
// Returns an array of all tabs that aren't in a group.
// Returns an array of all tabs that aren't in a groupItem.
getOrphanedTabs: function() {
var tabs = TabItems.getItems();
tabs = tabs.filter(function(tab) {
@ -1669,22 +1671,22 @@ window.Groups = {
},
// ----------
// Function: getNextGroupTab
// Function: getNextGroupItemTab
// Paramaters:
// reverse - the boolean indicates the direction to look for the next group.
// reverse - the boolean indicates the direction to look for the next groupItem.
// Returns the <tabItem>. If nothing is found, return null.
getNextGroupTab: function(reverse) {
var groups = Groups.groups.map(function(group) group);
var activeGroup = Groups.getActiveGroup();
getNextGroupItemTab: function(reverse) {
var groupItems = GroupItems.groupItems.map(function(groupItem) groupItem);
var activeGroupItem = GroupItems.getActiveGroupItem();
var tabItem = null;
if (!activeGroup) {
if (groups.length > 0) {
if (!activeGroupItem) {
if (groupItems.length > 0) {
if (reverse)
groups = groups.reverse();
groupItems = groupItems.reverse();
groups.some(function(group) {
var child = group.getChild(0);
groupItems.some(function(groupItem) {
var child = groupItem.getChild(0);
if (child) {
tabItem = child;
return true;
@ -1693,32 +1695,32 @@ window.Groups = {
}
} else {
if (reverse)
groups = groups.reverse();
groupItems = groupItems.reverse();
var currentIndex;
groups.some(function(group, index) {
if (group == activeGroup) {
groupItems.some(function(groupItem, index) {
if (groupItem == activeGroupItem) {
currentIndex = index;
return true;
}
});
var firstGroups = groups.slice(currentIndex + 1);
firstGroups.some(function(group) {
var child = group.getChild(0);
var firstGroupItems = groupItems.slice(currentIndex + 1);
firstGroupItems.some(function(groupItem) {
var child = groupItem.getChild(0);
if (child) {
tabItem = child;
return true;
}
});
if (!tabItem) {
var orphanedTabs = Groups.getOrphanedTabs();
var orphanedTabs = GroupItems.getOrphanedTabs();
if (orphanedTabs.length > 0)
tabItem = orphanedTabs[0];
}
if (!tabItem) {
var secondGroups = groups.slice(0, currentIndex);
secondGroups.some(function(group) {
var child = group.getChild(0);
var secondGroupItems = groupItems.slice(0, currentIndex);
secondGroupItems.some(function(groupItem) {
var child = groupItem.getChild(0);
if (child) {
tabItem = child;
return true;
@ -1730,14 +1732,14 @@ window.Groups = {
},
// ----------
// Function: moveTabToGroup
// Function: moveTabToGroupItem
// Paramaters:
// tab - the <xul:tab>.
// groupId - the <group>'s id. If nothing, create a new <group>.
moveTabToGroup : function(tab, groupId) {
// groupItemId - the <groupItem>'s id. If nothing, create a new <groupItem>.
moveTabToGroupItem : function(tab, groupItemId) {
Utils.log("move to tab")
let shouldUpdateTabBar = false;
let group;
let groupItem;
// switch to the appropriate tab first.
if (gBrowser.selectedTab == tab) {
@ -1755,15 +1757,15 @@ window.Groups = {
} else
shouldUpdateTabBar = true
// remove tab item from a group
// remove tab item from a groupItem
if (tab.tabItem.parent)
tab.tabItem.parent.remove(tab.tabItem);
// add tab item to a group
if (groupId) {
group = Groups.group(groupId);
group.add(tab.tabItem);
UI.setReorderTabItemsOnShow(group);
// add tab item to a groupItem
if (groupItemId) {
groupItem = GroupItems.groupItem(groupItemId);
groupItem.add(tab.tabItem);
UI.setReorderTabItemsOnShow(groupItem);
} else {
let pageBounds = Items.getPageBounds();
pageBounds.inset(20, 20);
@ -1772,11 +1774,11 @@ window.Groups = {
box.width = 250;
box.height = 200;
new Group([ tab.tabItem ], { bounds: box });
new GroupItem([ tab.tabItem ], { bounds: box });
}
if (shouldUpdateTabBar)
this.updateTabBarForActiveGroup();
this.updateTabBarForActiveGroupItem();
else {
tab.tabItem.setZoomPrep(false);
UI.showTabView();

View File

@ -52,11 +52,11 @@
//
// Parameters:
// bounds - a <Rect> for where the item should be located
// options - various options for this group (see below)
// options - various options for this infoItem (see below)
//
// Possible options:
// locked - see <Item.locked>; default is {}
// dontPush - true if this group shouldn't push away on creation; default is false
// dontPush - true if this infoItem shouldn't push away on creation; default is false
window.InfoItem = function(bounds, options) {
try {
Utils.assertThrow('bounds', Utils.isRect(bounds));
@ -150,8 +150,8 @@ window.InfoItem.prototype = Utils.extend(new Item(), new Subscribable(), {
var data = this.getStorageData();
/*
if (Groups.groupStorageSanity(data))
Storage.saveGroup(Utils.getCurrentWindow(), data);
if (GroupItems.groupItemStorageSanity(data))
Storage.saveGroupItem(Utils.getCurrentWindow(), data);
*/
} catch(e) {
Utils.log(e);
@ -163,7 +163,7 @@ window.InfoItem.prototype = Utils.extend(new Item(), new Subscribable(), {
// Sets the bounds with the given <Rect>, animating unless "immediately" is false.
setBounds: function(rect, immediately) {
try {
Utils.assertThrow('Group.setBounds: rect must be a real rectangle!', Utils.isRect(rect));
Utils.assertThrow('InfoItem.setBounds: rect must be a real rectangle!', Utils.isRect(rect));
// ___ Determine what has changed
var css = {};
@ -184,7 +184,7 @@ window.InfoItem.prototype = Utils.extend(new Item(), new Subscribable(), {
return;
this.bounds = new Rect(rect);
Utils.assertThrow('Group.setBounds: this.bounds must be a real rectangle!',
Utils.assertThrow('InfoItem.setBounds: this.bounds must be a real rectangle!',
Utils.isRect(this.bounds));
// ___ Update our representation
@ -239,7 +239,7 @@ window.InfoItem.prototype = Utils.extend(new Item(), new Subscribable(), {
Items.unsquish();
});
/* Storage.deleteGroup(Utils.getCurrentWindow(), this.id); */
/* Storage.deleteGroupItem(Utils.getCurrentWindow(), this.id); */
} catch(e) {
Utils.log(e);
}

View File

@ -41,7 +41,7 @@
// ##########
// Class: Item
// Superclass for all visible objects (<TabItem>s and <Group>s).
// Superclass for all visible objects (<TabItem>s and <GroupItem>s).
//
// If you subclass, in addition to the things Item provides, you need to also provide these methods:
// setBounds - function(rect, immediately)
@ -92,7 +92,7 @@ window.Item = function() {
this.locked = null;
// Variable: parent
// The group that this item is a child of
// The groupItem that this item is a child of
this.parent = null;
// Variable: userSize
@ -191,9 +191,9 @@ window.Item.prototype = {
this.dropOptions = {
over: function() {},
out: function() {
var group = drag.info.item.parent;
if (group)
group.remove(drag.info.$el, {dontClose: true});
var groupItem = drag.info.item.parent;
if (groupItem)
groupItem.remove(drag.info.$el, {dontClose: true});
iQ(this.container).removeClass("acceptsDrop");
},
@ -424,7 +424,7 @@ window.Item.prototype = {
bounds.left += posStep.x;
bounds.top += posStep.y;
if (!item.isAGroup) {
if (!item.isAGroupItem) {
if (sizeStep.y > sizeStep.x) {
var newWidth = bounds.height * (TabItems.tabWidth / TabItems.tabHeight);
bounds.left += (bounds.width - newWidth) / 2;
@ -549,7 +549,7 @@ window.Item.prototype = {
// ----------
// Function: snap
// The snap function used during group creation via drag-out
// The snap function used during groupItem creation via drag-out
snap: function Item_snap() {
// make the snapping work with a wider range!
var defaultRadius = Trenches.defaultRadius;
@ -835,11 +835,11 @@ window.Items = {
// ----------
// Function: getTopLevelItems
// Returns an array of all Items not grouped into groups.
// Returns an array of all Items not grouped into groupItems.
getTopLevelItems: function() {
var items = [];
iQ('.tab, .group, .info-item').each(function(elem) {
iQ('.tab, .groupItem, .info-item').each(function(elem) {
var $this = iQ(elem);
var item = $this.data('item');
if (item && !item.parent && !$this.hasClass('phantom'))
@ -948,7 +948,7 @@ window.Items = {
for (a = 0; a < count; a++) {
/*
if (animate == 'sometimes')
immediately = (typeof(item.groupData.row) == 'undefined' || item.groupData.row == row);
immediately = (typeof(item.groupItemData.row) == 'undefined' || item.groupItemData.row == row);
else
*/
immediately = !animate;
@ -966,8 +966,8 @@ window.Items = {
}
/*
item.groupData.column = column;
item.groupData.row = row;
item.groupItemData.column = column;
item.groupItemData.row = row;
*/
box.left += box.width + padding;
@ -1020,7 +1020,7 @@ window.Items = {
else
newSize = new Point(TabItems.tabWidth, TabItems.tabHeight);
if (item.isAGroup) {
if (item.isAGroupItem) {
newBounds.width = Math.max(newBounds.width, newSize.x);
newBounds.height = Math.max(newBounds.height, newSize.y);
} else {

View File

@ -107,7 +107,7 @@ Storage = {
});
// ___ Other
this.saveGroupsData(gWindow, {});
this.saveGroupItemsData(gWindow, {});
this.saveUIData(gWindow, {});
this._sessionStore.setWindowValue(gWindow, this.GROUP_DATA_IDENTIFIER,
@ -150,54 +150,54 @@ Storage = {
},
// ----------
// Function: saveGroup
// Saves the data for a single group, associated with a specific window.
saveGroup: function(win, data) {
// Function: saveGroupItem
// Saves the data for a single groupItem, associated with a specific window.
saveGroupItem: function(win, data) {
var id = data.id;
var existingData = this.readGroupData(win);
var existingData = this.readGroupItemData(win);
existingData[id] = data;
this._sessionStore.setWindowValue(win, this.GROUP_DATA_IDENTIFIER,
JSON.stringify(existingData));
},
// ----------
// Function: deleteGroup
// Deletes the data for a single group from the given window.
deleteGroup: function(win, id) {
var existingData = this.readGroupData(win);
// Function: deleteGroupItem
// Deletes the data for a single groupItem from the given window.
deleteGroupItem: function(win, id) {
var existingData = this.readGroupItemData(win);
delete existingData[id];
this._sessionStore.setWindowValue(win, this.GROUP_DATA_IDENTIFIER,
JSON.stringify(existingData));
},
// ----------
// Function: readGroupData
// Returns the data for all groups associated with the given window.
readGroupData: function(win) {
// Function: readGroupItemData
// Returns the data for all groupItems associated with the given window.
readGroupItemData: function(win) {
var existingData = {};
try {
/* Utils.log("readGroupData" + this._sessionStore.getWindowValue(win, this.GROUP_DATA_IDENTIFIER)); */
/* Utils.log("readGroupItemData" + this._sessionStore.getWindowValue(win, this.GROUP_DATA_IDENTIFIER)); */
existingData = JSON.parse(
this._sessionStore.getWindowValue(win, this.GROUP_DATA_IDENTIFIER)
);
} catch (e) {
// getWindowValue will fail if the property doesn't exist
Utils.log("Error in readGroupData: "+e);
Utils.log("Error in readGroupItemData: "+e);
}
return existingData;
},
// ----------
// Function: saveGroupsData
// Saves the global data for the <Groups> singleton for the given window.
saveGroupsData: function(win, data) {
// Function: saveGroupItemsData
// Saves the global data for the <GroupItems> singleton for the given window.
saveGroupItemsData: function(win, data) {
this.saveData(win, this.GROUPS_DATA_IDENTIFIER, data);
},
// ----------
// Function: readGroupsData
// Reads the global data for the <Groups> singleton for the given window.
readGroupsData: function(win) {
// Function: readGroupItemsData
// Reads the global data for the <GroupItems> singleton for the given window.
readGroupItemsData: function(win) {
return this.readData(win, this.GROUPS_DATA_IDENTIFIER);
},

View File

@ -100,19 +100,19 @@ window.TabItem = function(tab) {
// ___ drag/drop
// override dropOptions with custom tabitem methods
// This is mostly to support the phantom groups.
// This is mostly to support the phantom groupItems.
this.dropOptions.drop = function(e) {
var $target = iQ(this.container);
this.isDropTarget = false;
var phantom = $target.data("phantomGroup");
var phantom = $target.data("phantomGroupItem");
var group = drag.info.item.parent;
if (group) {
group.add(drag.info.$el);
var groupItem = drag.info.item.parent;
if (groupItem) {
groupItem.add(drag.info.$el);
} else {
phantom.removeClass("phantom acceptsDrop");
new Group([$target, drag.info.$el], {container:phantom, bounds:phantom.bounds()});
new GroupItem([$target, drag.info.$el], {container:phantom, bounds:phantom.bounds()});
}
};
@ -124,17 +124,17 @@ window.TabItem = function(tab) {
var phantomMargin = 40;
var groupBounds = this.getBoundsWithTitle();
groupBounds.inset(-phantomMargin, -phantomMargin);
var groupItemBounds = this.getBoundsWithTitle();
groupItemBounds.inset(-phantomMargin, -phantomMargin);
iQ(".phantom").remove();
var phantom = iQ("<div>")
.addClass("group phantom acceptsDrop")
.addClass("groupItem phantom acceptsDrop")
.css({
position: "absolute",
zIndex: -99
})
.css(groupBounds.css())
.css(groupItemBounds.css())
.hide()
.appendTo("body");
@ -142,7 +142,7 @@ window.TabItem = function(tab) {
// Extend the margin so that it covers the case where the target tab item
// is right next to a trench.
Trenches.defaultRadius = phantomMargin + 1;
var updatedBounds = drag.info.snapBounds(groupBounds,'none');
var updatedBounds = drag.info.snapBounds(groupItemBounds,'none');
Trenches.defaultRadius = defaultRadius;
// Utils.log('updatedBounds:',updatedBounds);
@ -151,12 +151,12 @@ window.TabItem = function(tab) {
phantom.fadeIn();
$target.data("phantomGroup", phantom);
$target.data("phantomGroupItem", phantom);
};
this.dropOptions.out = function(e) {
this.isDropTarget = false;
var phantom = iQ(this.container).data("phantomGroup");
var phantom = iQ(this.container).data("phantomGroupItem");
if (phantom) {
phantom.fadeOut(function() {
iQ(this).remove();
@ -220,7 +220,7 @@ window.TabItem = function(tab) {
});
if (!TabItems.reconnect(this))
Groups.newTab(this);
GroupItems.newTab(this);
};
window.TabItem.prototype = Utils.extend(new Item(), new Subscribable(), {
@ -433,7 +433,7 @@ window.TabItem.prototype = Utils.extend(new Item(), new Subscribable(), {
// ----------
// Function: getBoundsWithTitle
// Returns a <Rect> for the group's bounds, including the title
// Returns a <Rect> for the groupItem's bounds, including the title
getBoundsWithTitle: function() {
var b = this.getBounds();
var $container = iQ(this.container);
@ -446,7 +446,7 @@ window.TabItem.prototype = Utils.extend(new Item(), new Subscribable(), {
// ----------
// Function: inStack
// Returns true if this item is in a stacked group.
// Returns true if this item is in a stacked groupItem.
inStack: function() {
return iQ(this.container).hasClass("stacked");
},
@ -561,16 +561,16 @@ window.TabItem.prototype = Utils.extend(new Item(), new Subscribable(), {
})
.removeClass("front");
// If the tab is in a group set then set the active
// group to the tab's parent.
// If the tab is in a groupItem set then set the active
// groupItem to the tab's parent.
if (self.parent) {
var gID = self.parent.id;
var group = Groups.group(gID);
Groups.setActiveGroup(group);
group.setActiveTab(self);
var groupItem = GroupItems.groupItem(gID);
GroupItems.setActiveGroupItem(groupItem);
groupItem.setActiveTab(self);
} else {
Groups.setActiveGroup(null);
Groups.setActiveOrphanTab(self);
GroupItems.setActiveGroupItem(null);
GroupItems.setActiveOrphanTab(self);
}
if (childHitResult.callback)
@ -629,7 +629,7 @@ window.TabItem.prototype = Utils.extend(new Item(), new Subscribable(), {
complete: function() { // note that this will happen on the DOM thread
$tab.removeClass('front');
Groups.setActiveOrphanTab(null);
GroupItems.setActiveOrphanTab(null);
TabItems.resumePainting();
@ -1010,12 +1010,12 @@ window.TabItems = {
item.userSize = new Point(tabData.userSize);
if (tabData.groupID) {
var group = Groups.group(tabData.groupID);
if (group) {
group.add(item);
var groupItem = GroupItems.groupItem(tabData.groupID);
if (groupItem) {
groupItem.add(item);
if (item.tab == gBrowser.selectedTab)
Groups.setActiveGroup(item.parent);
GroupItems.setActiveGroupItem(item.parent);
}
}
@ -1030,7 +1030,7 @@ window.TabItems = {
}, 15000);
}
Groups.updateTabBarForActiveGroup();
GroupItems.updateTabBarForActiveGroupItem();
item.reconnected = true;
found = true;

View File

@ -173,16 +173,16 @@ body {
-moz-box-shadow: none !important;
}
/* Tab Group
/* Tab GroupItem
----------------------------------*/
.tabInGroup {
.tabInGroupItem {
border: none;
-moz-box-shadow: none !important;
}
.group {
.groupItem {
position: absolute;
/* float: left; */
cursor: move;

View File

@ -29,7 +29,7 @@ XPCOMUtils.defineLazyGetter(this, "gTabViewFrame", function() {
#include iq.js
#include storage.js
#include items.js
#include groups.js
#include groupitems.js
#include tabitems.js
#include drag.js
#include trench.js

View File

@ -47,7 +47,7 @@
// Constructor: Trench
//
// Parameters:
// element - the DOM element for Item (Group or TabItem) from which the trench is projected
// element - the DOM element for Item (GroupItem or TabItem) from which the trench is projected
// xory - either "x" or "y": whether the trench's <position> is along the x- or y-axis.
// In other words, if "x", the trench is vertical; if "y", the trench is horizontal.
// type - either "border" or "guide". Border trenches mark the border of an Item.
@ -415,8 +415,8 @@ Trench.prototype = {
//----------
// Function: calculateActiveRange
// Computes and sets the <activeRange> for the trench, based on the <Groups> around.
// This makes it so trenches' active ranges don't extend through other groups.
// Computes and sets the <activeRange> for the trench, based on the <GroupItems> around.
// This makes it so trenches' active ranges don't extend through other groupItems.
calculateActiveRange: function Trench_calculateActiveRange() {
// set it to the default: just the range itself.
@ -426,14 +426,14 @@ Trench.prototype = {
if (this.type != 'guide')
return;
var groups = Groups.groups;
var groupItems = GroupItems.groupItems;
var trench = this;
groups.forEach(function(group) {
if (group.isDragging) // floating groups don't block trenches
groupItems.forEach(function(groupItem) {
if (groupItem.isDragging) // floating groupItems don't block trenches
return;
if (trench.el == group.container) // groups don't block their own trenches
if (trench.el == groupItem.container) // groupItems don't block their own trenches
return;
var bounds = group.getBounds();
var bounds = groupItem.getBounds();
var activeRange = new Range();
if (trench.xory == 'y') { // if this trench is horizontal...
activeRange = trench.adjustRangeIfIntercept(bounds.left, bounds.yRange);

View File

@ -70,12 +70,12 @@ var UIManager = {
_stopZoomPreparation : false,
// Variable: _reorderTabItemsOnShow
// Keeps track of the <Group>s which their tab items' tabs have been moved
// Keeps track of the <GroupItem>s which their tab items' tabs have been moved
// and re-orders the tab items when switching to TabView.
_reorderTabItemsOnShow : [],
// Variable: _reorderTabsOnHide
// Keeps track of the <Group>s which their tab items have been moved in
// Keeps track of the <GroupItem>s which their tab items have been moved in
// TabView UI and re-orders the tabs when switcing back to main browser.
_reorderTabsOnHide : [],
@ -123,10 +123,10 @@ var UIManager = {
this.showTabView();
// ensure the tabs in the tab strip are in the same order as the tab
// items in groups when switching back to main browser UI for the first
// items in groupItems when switching back to main browser UI for the first
// time.
Groups.groups.forEach(function(group) {
self._reorderTabsOnHide.push(group);
GroupItems.groupItems.forEach(function(groupItem) {
self._reorderTabsOnHide.push(groupItem);
});
}
} catch(e) {
@ -148,7 +148,7 @@ var UIManager = {
this._addDevMenu();
// When you click on the background/empty part of TabView,
// we create a new group.
// we create a new groupItem.
iQ(gTabViewFrame.contentDocument).mousedown(function(e) {
if (iQ(":focus").length > 0) {
iQ(":focus").each(function(element) {
@ -157,7 +157,7 @@ var UIManager = {
});
}
if (e.originalTarget.id == "content")
self._createGroupOnDrag(e)
self._createGroupItemOnDrag(e)
});
iQ(window).bind("beforeunload", function() {
@ -180,10 +180,10 @@ var UIManager = {
// ___ Storage
var groupsData = Storage.readGroupsData(gWindow);
var firstTime = !groupsData || Utils.isEmptyObject(groupsData);
var groupData = Storage.readGroupData(gWindow);
Groups.reconstitute(groupsData, groupData);
var groupItemsData = Storage.readGroupItemsData(gWindow);
var firstTime = !groupItemsData || Utils.isEmptyObject(groupItemsData);
var groupItemData = Storage.readGroupItemData(gWindow);
GroupItems.reconstitute(groupItemsData, groupItemData);
if (firstTime) {
var padding = 10;
@ -192,7 +192,7 @@ var UIManager = {
var pageBounds = Items.getPageBounds();
pageBounds.inset(padding, padding);
// ___ make a fresh group
// ___ make a fresh groupItem
var box = new Rect(pageBounds);
box.width =
Math.min(box.width * 0.667, pageBounds.width - (infoWidth + padding));
@ -201,14 +201,14 @@ var UIManager = {
bounds: box
};
var group = new Group([], options);
var groupItem = new GroupItem([], options);
var items = TabItems.getItems();
items.forEach(function(item) {
if (item.parent)
item.parent.remove(item);
group.add(item);
groupItem.add(item);
});
// ___ make info item
@ -322,8 +322,8 @@ var UIManager = {
var currentTab = this._currentTab;
var item = null;
this._reorderTabItemsOnShow.forEach(function(group) {
group.reorderTabItemsBasedOnTabOrder();
this._reorderTabItemsOnShow.forEach(function(groupItem) {
groupItem.reorderTabItemsBasedOnTabOrder();
});
this._reorderTabItemsOnShow = [];
@ -350,11 +350,11 @@ var UIManager = {
self.setActiveTab(item);
var activeGroup = Groups.getActiveGroup();
if (activeGroup)
activeGroup.setTopChild(item);
var activeGroupItem = GroupItems.getActiveGroupItem();
if (activeGroupItem)
activeGroupItem.setTopChild(item);
window.Groups.setActiveGroup(null);
window.GroupItems.setActiveGroupItem(null);
self._resize(true);
dispatchEvent(event);
});
@ -373,8 +373,8 @@ var UIManager = {
TabItems.pausePainting();
this._reorderTabsOnHide.forEach(function(group) {
group.reorderTabsBasedOnTabItemOrder();
this._reorderTabsOnHide.forEach(function(groupItem) {
groupItem.reorderTabsBasedOnTabItemOrder();
});
this._reorderTabsOnHide = [];
@ -430,17 +430,17 @@ var UIManager = {
} else {
// if not closing the last tab
if (gBrowser.tabs.length > 1) {
var group = Groups.getActiveGroup();
var groupItem = GroupItems.getActiveGroupItem();
// 1) Only go back to the TabView tab when there you close the last
// tab of a group.
// tab of a groupItem.
// 2) Take care of the case where you've closed the last tab in
// an un-named group, which means that the group is gone (null) and
// an un-named groupItem, which means that the groupItem is gone (null) and
// there are no visible tabs.
// Can't use timeout here because user would see a flicker of
// switching to another tab before the TabView interface shows up.
if ((group && group._children.length == 1) ||
(group == null && gBrowser.visibleTabs.length == 1)) {
if ((groupItem && groupItem._children.length == 1) ||
(groupItem == null && gBrowser.visibleTabs.length == 1)) {
// for the tab focus event to pick up.
self._closedLastVisibleTab = true;
// remove the zoom prep.
@ -452,8 +452,8 @@ var UIManager = {
// new tabs might be added after a tab is closing. Therefore, this
// hack is used. We should look for a better solution.
Utils.timeout(function() { // Marshal event from chrome thread to DOM thread
if ((group && group._children.length > 0) ||
(group == null && gBrowser.visibleTabs.length > 0))
if ((groupItem && groupItem._children.length > 0) ||
(groupItem == null && gBrowser.visibleTabs.length > 0))
self.hideTabView();
}, 1);
}
@ -466,9 +466,9 @@ var UIManager = {
return;
Utils.timeout(function() { // Marshal event from chrome thread to DOM thread
var activeGroup = Groups.getActiveGroup();
if (activeGroup)
self.setReorderTabItemsOnShow(activeGroup);
var activeGroupItem = GroupItems.getActiveGroupItem();
if (activeGroupItem)
self.setReorderTabItemsOnShow(activeGroupItem);
}, 1);
});
@ -525,7 +525,7 @@ var UIManager = {
var newItem = null;
if (focusTab && focusTab.tabItem) {
newItem = focusTab.tabItem;
Groups.setActiveGroup(newItem.parent);
GroupItems.setActiveGroupItem(newItem.parent);
}
// ___ prepare for when we return to TabView
@ -552,36 +552,36 @@ var UIManager = {
// ----------
// Function: setReorderTabsOnHide
// Sets the group which the tab items' tabs should be re-ordered when
// Sets the groupItem which the tab items' tabs should be re-ordered when
// switching to the main browser UI.
// Parameters:
// group - the group which would be used for re-ordering tabs.
setReorderTabsOnHide: function(group) {
// groupItem - the groupItem which would be used for re-ordering tabs.
setReorderTabsOnHide: function(groupItem) {
if (this._isTabViewVisible()) {
var index = this._reorderTabsOnHide.indexOf(group);
var index = this._reorderTabsOnHide.indexOf(groupItem);
if (index == -1)
this._reorderTabsOnHide.push(group);
this._reorderTabsOnHide.push(groupItem);
}
},
// ----------
// Function: setReorderTabItemsOnShow
// Sets the group which the tab items should be re-ordered when
// Sets the groupItem which the tab items should be re-ordered when
// switching to the tab view UI.
// Parameters:
// group - the group which would be used for re-ordering tab items.
setReorderTabItemsOnShow: function(group) {
// groupItem - the groupItem which would be used for re-ordering tab items.
setReorderTabItemsOnShow: function(groupItem) {
if (!this._isTabViewVisible()) {
var index = this._reorderTabItemsOnShow.indexOf(group);
var index = this._reorderTabItemsOnShow.indexOf(groupItem);
if (index == -1)
this._reorderTabItemsOnShow.push(group);
this._reorderTabItemsOnShow.push(groupItem);
}
},
// ----------
// Function: _setBrowserKeyHandlers
// Overrides the browser's keys for navigating between tab (outside of the
// TabView UI) so they do the right thing in respect to groups.
// TabView UI) so they do the right thing in respect to groupItems.
_setBrowserKeyHandlers : function() {
var self = this;
@ -610,7 +610,7 @@ var UIManager = {
(charCode == 96 || charCode == 126)) {
event.stopPropagation();
event.preventDefault();
var tabItem = Groups.getNextGroupTab(event.shiftKey);
var tabItem = GroupItems.getNextGroupItemTab(event.shiftKey);
if (tabItem)
gBrowser.selectedTab = tabItem.tab;
}
@ -706,7 +706,7 @@ var UIManager = {
var activeTab = self.getActiveTab();
if (activeTab) {
var tabItems = (activeTab.parent ? activeTab.parent.getChildren() :
Groups.getOrphanedTabs());
GroupItems.getOrphanedTabs());
var length = tabItems.length;
var currentIndex = tabItems.indexOf(activeTab);
@ -732,16 +732,16 @@ var UIManager = {
},
// ----------
// Function: _createGroupOnDrag
// Function: _createGroupItemOnDrag
// Called in response to a mousedown in empty space in the TabView UI;
// creates a new group based on the user's drag.
_createGroupOnDrag: function(e) {
// creates a new groupItem based on the user's drag.
_createGroupItemOnDrag: function(e) {
const minSize = 60;
const minMinSize = 15;
var startPos = { x: e.clientX, y: e.clientY };
var phantom = iQ("<div>")
.addClass("group phantom")
.addClass("groupItem phantom")
.css({
position: "absolute",
opacity: .7,
@ -767,7 +767,7 @@ var UIManager = {
this.container.css("opacity", opacity);
},
// we don't need to pushAway the phantom item at the end, because
// when we create a new Group, it'll do the actual pushAway.
// when we create a new GroupItem, it'll do the actual pushAway.
pushAway: function () {},
};
item.setBounds(new Rect(startPos.y, startPos.x, 0, 0));
@ -829,16 +829,16 @@ var UIManager = {
else {
var bounds = item.getBounds();
// Add all of the orphaned tabs that are contained inside the new group
// to that group.
var tabs = Groups.getOrphanedTabs();
// Add all of the orphaned tabs that are contained inside the new groupItem
// to that groupItem.
var tabs = GroupItems.getOrphanedTabs();
var insideTabs = [];
for each(tab in tabs) {
if (bounds.contains(tab.bounds))
insideTabs.push(tab);
}
var group = new Group(insideTabs,{bounds:bounds});
var groupItem = new GroupItem(insideTabs,{bounds:bounds});
phantom.remove();
dragOutInfo = null;
}
@ -1056,59 +1056,58 @@ var UIManager = {
// TODO: Save info items
_saveAll: function() {
this._save();
Groups.saveAll();
GroupItems.saveAll();
TabItems.saveAll();
},
// ----------
// Function: _arrangeBySite
// Blows away all existing groups and organizes the tabs into new groups based
// Blows away all existing groupItems and organizes the tabs into new groupItems based
// on domain.
_arrangeBySite: function() {
function putInGroup(set, key) {
var group = Groups.getGroupWithTitle(key);
if (group) {
function putInGroupItem(set, key) {
var groupItem = GroupItems.getGroupItemWithTitle(key);
if (groupItem) {
set.forEach(function(el) {
group.add(el);
groupItem.add(el);
});
} else
new Group(set, { dontPush: true, dontArrange: true, title: key });
new GroupItem(set, { dontPush: true, dontArrange: true, title: key });
}
Groups.removeAll();
GroupItems.removeAll();
var newTabsGroup = Groups.getNewTabGroup();
var groups = [];
var groupItems = [];
var leftovers = [];
var items = TabItems.getItems();
items.forEach(function(item) {
var url = item.tab.linkedBrowser.currentURI.spec;
var domain = url.split('/')[2];
if (!domain)
newTabsGroup.add(item);
leftovers.push(item.container);
else {
var domainParts = domain.split(".");
var mainDomain = domainParts[domainParts.length - 2];
if (groups[mainDomain])
groups[mainDomain].push(item.container);
if (groupItems[mainDomain])
groupItems[mainDomain].push(item.container);
else
groups[mainDomain] = [item.container];
groupItems[mainDomain] = [item.container];
}
});
var leftovers = [];
for (key in groups) {
var set = groups[key];
for (key in groupItems) {
var set = groupItems[key];
if (set.length > 1) {
putInGroup(set, key);
putInGroupItem(set, key);
} else
leftovers.push(set[0]);
}
if (leftovers.length)
putInGroup(leftovers, "mixed");
putInGroupItem(leftovers, "mixed");
Groups.arrange();
GroupItems.arrange();
},
};
@ -1118,7 +1117,7 @@ Profile.wrap(UIManager, "UIManager");
Profile.wrap(Storage, "Storage");
Profile.wrap(Items, "Items");
Profile.wrap(TabItems, "TabItems");
Profile.wrap(Groups, "Groups");
Profile.wrap(GroupItems, "GroupItems");
window.UI = UIManager;
window.UI.init();