Anonymous avatar Anonymous committed 3baaa21

Preference browser.tabs.insertRelatedAfterCurrent = false eliminates my tab movement woes.
Coloring adjusted to retain group colors across standard remove/re-add (for moving a tab) cycle, gives a fresh color when group is disbanded only from a tab being hand-closed.
Quick separator fix for single tab closed adjacent single tab.
Deleting lots of code, still pretty messy.
Handled new tabs.
For now opened tabs appear on far left for a moment. Will probably hide them again later.

Comments (0)

Files changed (11)

chrome/content/group_sort_tabs.xul

 	<script type="application/javascript;version=1.7" src="gst.list.js"/>
 
 	<menupopup id="contentAreaContextMenu">
-		<menuitem gst-context="tab" hidden="true" disabled="true" id="menu_loadingNotice" label="&menu.loadingNotice.label;"/>
 		<menuitem gst-context="tab" hidden="true" id="menu_returnSort" label="&menu.returnSort.label;" accesskey="&menu.returnSort.accessKey;"
 			oncommand="GST.menu.keyState(event); GST.menu.returnSort(document.popupNode);"/>
 		<menuitem gst-context="tab" hidden="true" id="menu_returnGroup" label="&menu.returnGroup.label;" accesskey="&menu.returnGroup.accessKey;"

chrome/content/gst.color.js

 		selected : 0.3,
 		hover : 0.6
 	},
+
+	colorIdx : 0,
+	colors : new Array(
+		"140, 227, 190",	// green
+		"185, 205, 246",	// blue
+		"255, 251, 209",	// yellow
+		"222, 160, 228"		// purple
+	),
 	
 	_getTabColor : function _getTabColor(tab) {
 		let color = tab.getAttribute("gst-color");
 	},
 
 	colorTab : function colorTab(tab, color) {
-		if (GST.core.isBlank(tab))
+		if (tab.getAttribute("gst-title") == "New Tab")
 			color = "";
 
 		//GST.core.tabLog("Color tab", tab);
 		let group = list[g];
 		if (!group) return;
 
-		let groupFormed = (group.length == 2);
-		let groupDisbanded = (group.length == 1);
-
 		// try to reuse an old color, keeps groups the same color on browser restart
 		// could even have single group tabs remember their color... but I may not
-		if (!group["color"]) group["color"] = GST.color._getTabColor(group[t]);
+		if (!group["color"] && t) group["color"] = GST.color._getTabColor(group[t]);
 		let prevColor = (list[g - 1] ? list[g - 1]["color"] : null);
 		// this happens when a tab separating two identically colored groups is closed
 		let needsRecolor = (prevColor && prevColor == group["color"]);
+
+		let groupFormed = (!group["colored"] && group.length == 2);
+		let groupDisbanded = (group["colored"] && group.length == 1);
 		
 		if (groupDisbanded) {	// check this first
-			delete group["color"];
-			for (let t = 0; t < group.length; t++)
-				GST.color._removeColor(group[t]);
+			delete group["colored"];
+			GST.color._removeColor(group[0]);
 		} else if (groupFormed || needsRecolor) {
 			let color = (!group["color"] || needsRecolor ? GST.color._getNewColor(list, g) : group["color"]);
 			for (let t = 0; t < group.length; t++)
 				GST.color.colorTab(group[t], color);
 			group["color"] = color;
-		} else
+		} else if (t)
 			GST.color.colorTab(group[t], group["color"]);
 
+		group["colored"] = !groupDisbanded;
 		GST.color.colorTabGradient(gBrowser.selectedTab, GST.color.tab.selected);
 	},
 	
 	_getNewColor : function _getNewColor(list, g) {
-		let colorIdx = GST.core.groupTabs.curColorIndex;
+		let colorIdx = GST.color.colorIdx;
 		let color;
 		do {
-			colorIdx = (colorIdx + 1) % GST.core.groupTabs.colors.length;
-			color = GST.core.groupTabs.colors[colorIdx];
+			colorIdx = (colorIdx + 1) % GST.color.colors.length;
+			color = GST.color.colors[colorIdx];
 			let prevColor = (list[g - 1] ? list[g - 1]["color"] : null);
 			let nextColor = (list[g + 1] ? list[g + 1]["color"] : null);
 			if (color != prevColor && color != nextColor) break;
 		} while (true)
 		
-		GST.core.groupTabs.curColorIndex = colorIdx;
+		GST.color.colorIdx = colorIdx;
 		return color;
 	}	
 };

chrome/content/gst.core.js

 		separator : {
 			enabled : null,
 			width : null
-		},
-
-		curColorIndex : 0,
-		colors : new Array(
-			"140, 227, 190",	// green
-			"185, 205, 246",	// blue
-			"255, 251, 209",	// yellow
-			"222, 160, 228"		// purple
-		)
+		}
 	},
 
 	needSort : null,
 	},
 
 	getTrueGroupValue : function getTrueGroupValue(tab) {
-		let compare = GST.sort.compare;
 		let gtb = GST.glob.groupTabsBy;
 		let groupBy = gtb.index;
 		let valueFunction;
 
 		switch (groupBy) {
 			case gtb.DISABLED:
-				return compare.disabled(tab);
+				return GST.compare.disabled(tab);
 			case gtb.HOSTNAME:
-				return compare.hostname(tab);
+				return GST.compare.hostname(tab);
 			case gtb.DATE_DAY:
-				let lastBrowsed = compare.lastBrowsed(tab);
+				let lastBrowsed = GST.compare.lastBrowsed(tab);
 				let date = new Date(lastBrowsed);
 				date.setHours(0);
 				date.setMinutes(0);
 			case gtb.DATE_SESSION:
 				return tab.getAttribute("gst-date-session");
 			case gtb.SOURCE:
-				return compare.source(tab);
+				return GST.compare.source(tab);
 			default:
 				GST.glob.trace("Not implemented.");
 				return null;
 	},
 
 	getTrueSortValue : function getTrueSortValue(tab, comparingTab) {
-		let compare = GST.sort.compare;
 		let stb = GST.glob.sortBy;
 		let sortBy = GST.core._getSortBy(tab, comparingTab);
 		let valueFunction;
 
 		switch (sortBy) {
 			case stb.DISABLED:
-				return compare.disabled(tab);
+				return GST.compare.disabled(tab);
 			case stb.LAST_OPENED:
-				return compare.lastOpened(tab);
+				return GST.compare.lastOpened(tab);
 			case stb.HOSTNAME:
-				return compare.hostname(tab);
+				return GST.compare.hostname(tab);
 			case stb.LAST_BROWSED:
-				return compare.lastBrowsed(tab);
+				return GST.compare.lastBrowsed(tab);
 			case stb.TITLE:
-				return compare.title(tab);
+				return GST.compare.title(tab);
 			default:
 				GST.glob.trace("Not implemented.");
 				return null;
 		return host;
 	},
 
-	removeSeparators : function removeSeparators() {
-		for (let i = 0; i < gBrowser.tabs.length; i++) {
-			let tab = gBrowser.tabs[i];
-			if (GST.core._hasSeparator(tab))
-				GST.core.removeSeparator(tab);
-		}
-	},
-
 	_hasSeparator : function _hasSeparator(tab) {
 		return tab.style.marginRight != "";	// for now
 	},

chrome/content/gst.event.js

 GST.event = {
-	openCount : 0,
-
-	tabsLoading : function tabsLoading() {
-		return (GST.event.openCount);
-	},
-
-	//When onTabOpen fires it will report one position (far right), but Firefox then moves it right of the selected tab - and this does *NOT* fire onTabMove.
-	//So it's going to show up at that position no matter what, even if we do an immediate move from onTabOpen, Firefox will do its thing, then ours.
+	// browser.tabs.insertRelatedAfterCurrent needs to be set false, otherwise Firefox does its own tab move after onTabOpen which does *NOT* fire onTabMove
 	onTabOpen : function onTabOpen(tab) {
-		tab.style.setProperty("display", "none", "");
-		gBrowser.moveTabTo(tab, gBrowser.tabs.length - 1);	// purely in hope that we can make it visible a tad earlier
+		//GST.core.tabLog("onTabOpen", tab);
+		if (GST.list.ssTabsOpened) {
+			if (tab.label == "New Tab") {
+				GST.list.sorted.push(tab, "hostname", "about:blank");
+				GST.list.sorted.push(tab, "title", "New Tab");
+			}
+			else
+				GST.list.sorted.push(tab);
+		}
 		tab.addEventListener("drop", GST.init.eventListeners.drop, false);
 
-		//GST.core.tabLog("onTabOpen", tab);
 		// unique ids are required for persistTabAttribute()
 		if (!tab.getAttribute("id"))
 			tab.setAttribute("id", GST.event._newTabId());
 				GST.event._setTabSource(tab);
 			}
 		}
-
-		// count tabs open & correlate with tabs loaded to know when ready for sort
-		GST.event.openCount++;
-		//GST.core.tabLog("Opened: " + GST.event.openCount, tab);
-
-		// doesn't actually work, but maybe we can determine nonLoading via label vs. this?
-		//let scheme = tab.linkedBrowser.contentDocument.documentURIObject.scheme;
-		//let nonLoadingUri = (scheme == "javascript");
-
-		let jsScheme = "javascript:";
-		if (tab.label.startsWith(jsScheme)) {
-			GST.event.loadCount++;
-			GST.event._checkLoaded();
-		}
 	},
 
 	_newTabId : function _newTabId() {
 	//restoreCount : 0,
 	onTabRestore : function onTabRestore(tab) {
 		return;
-		let tabsOpening = (GST.event.openCount != 0);
-		if (!tabsOpening)
-			return;
+		// I believe this check if any tabs had been opened yet was to differentiate between an individual tab being restored,
+		// and the sort of global restoration that occurs at startup from a single initial tab
+		// or maybe not... I need to review the order of events, I may want:
+		//	if (!GST.list.ssTabsOpened) return;
+		//// but I may not.
+		//let tabsOpening = (GST.event.openCount != 0);
+		//if (!tabsOpening)
+		//	return;
 
 		tab.setAttribute("gst-justRestored", true);
 		//GST.core.tabLog("onTabRestore", tab);
 		if (GST.core.isBlank(tab, true)) {
 			GST.event._blankTheBlank(tab);
 			tab.setAttribute("gst-isBlank", true);
-			GST.event._checkLoaded();
 		}
 	},
 
 
 			GST.move.movedTabMark(tab);	// for tab tooltip
 		}
-
-		if (GST.event._amUsingTitleSort())
-			GST.event._tabLoaded(tab);
 	},
 
-	loadCount : 0,
 	progress : {
 		QueryInterface : function(aIID) {
 			if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
 				tab.setAttribute("gst-lastBrowsed", Date.now());
 				GST.event._setTabDateSession(tab);
 			}
-
-			if (tabUrl == "about:blank") {
-				tab.setAttribute("navigatedToBlank", true);
-			} else {
-				if (!GST.event._amUsingTitleSort())
-					GST.event._tabLoaded(tab);
-			}
 		},
 
 		onStateChange : function progress_onStateChange(browser, webProgress, request, flags, status) {
 				if (tab.getAttribute("gst-justRestored"))
 					GST.event._blankTheBlank(tab);
 				tab.setAttribute("gst-isBlank", true);
-
-				if (tab.getAttribute("navigatedToBlank")) {
-					tab.removeAttribute("navigatedToBlank");
-					GST.event._tabLoaded(tab);
-				} else {
-					GST.event.loadCount++;
-					GST.event._checkLoaded();
-				}
 			}
 		},
 
 
 	_prevBrowsed : null,
 	_setTabDateSession : function _setTabDateSession(tab) {
-		let browsed = GST.sort.compare.lastBrowsed(tab);
+		let browsed = GST.compare.lastBrowsed(tab);
 		if (!GST.event._prevBrowsed)
 			GST.event._prevBrowsed = browsed;
 
 		}
 	},
 
-	_tabLoaded : function _tabLoaded(tab) {
-		//GST.core.tabLog("Tab loaded.", tab);
-		if (GST.event.tabsLoading()) {
-			GST.event.loadCount++;
-			//GST.core.tabLog("Load: " + GST.event.loadCount, tab);
-			GST.event._checkLoaded();
-		} else {
-			GST.color.colorTab(tab, "");
-			GST.sort.doSort(tab);
-		}
-	},
-
-	isAFolderOpening : false,
-	//allRestored : false,
-	_checkLoaded : function _checkLoaded() {
-		//GST.glob.log("Open: " + GST.event.openCount + " Load: " + GST.event.loadCount);
-		if (!GST.event.openCount)
-			return;
-
-		let loaded = (GST.event.openCount == GST.event.loadCount);
-		if (loaded) {
-			/*
-			if (GST.event.restoreCount > 0 && !GST.event.allRestored) {
-				if (GST.event.openCount != GST.event.restoreCount)
-					return;
-				else {
-					GST.event.restoreCount = 0;
-					GST.event.allRestored = true;
-				}
-			}
-			*/
-
-			GST.event.openCount = 0;
-			GST.event.loadCount = 0;
-			GST.event.isAFolderOpening = false;
-
-			GST.sort.doSort();
-		}
-	},
-
 	onTabClose : function onTabClose(tab) {
 		GST.list.sorted.remove(tab);
+		let group = tab["gst-group"];
+		if (group.length == 1) delete group["color"];	// fresh color
 		
 		if (gBrowser.tabs.length < 2)
 			return;

chrome/content/gst.init.js

 
 				case "groupTabs.color":
 					if (GST.core.groupTabs.color)
-						GST.core.groupTabs.curColorIndex = 0;
+						GST.color.colorIdx = 0;
 					else
 						GST.init._prefObserver.removeColors = true;
 				break;
 				break;
 			}
 
-			if (!GST.event.tabsLoading() && aData != "checkNeedSort")
+			if (aData != "checkNeedSort")
 				GST.core.needSort = true;
 		}
 	}

chrome/content/gst.list.js

 	else
 		sortBy = GST.glob.getSortFromGroup();
 	
-	let stb = GST.glob.sortBy, compare = GST.sort.compare;
+	let stb = GST.glob.sortBy;
 	switch (sortBy) {
 		case stb.DISABLED:
-			return [null, compare.disabled];
+			return [null, GST.compare.disabled];
 		case stb.LAST_OPENED:
-			return ["lastOpened", compare.lastOpened];
+			return ["lastOpened", GST.compare.lastOpened];
 		case stb.HOSTNAME:
-			return ["hostname", compare.hostname];
+			return ["hostname", GST.compare.hostname];
 		case stb.LAST_BROWSED:
-			return ["lastBrowsed", compare.lastBrowsed];
+			return ["lastBrowsed", GST.compare.lastBrowsed];
 		case stb.TITLE:
-			return ["title", compare.title];
+			return ["title", GST.compare.title];
 		default:
 			GST.glob.trace("Not implemented.");
 			return null;
 	list[g].splice(t, 1);
 	GST.list.separateGroup(list, g - 1);
 	GST.list.separateGroup(list, g);
-	GST.color.colorGroup(list, g, t);
+	GST.color.colorGroup(list, g);
 };
 
 GST.SortedTabList.prototype._removeGroup = function SortedTabList__removeGroup(list, g, t) {
 	list.splice(g, 1);
-	GST.color.colorGroup(list, g, 0);	// g here is the next group (g + 1 before splice)
+	GST.list.separateGroup(list, g - 1);
+	GST.color.colorGroup(list, g);	// g here is the next group (g + 1 before splice)
 };
 
 GST.SortedTabList.prototype.toString = function SortedTabList_toString() {
 		if (!this.updateValue(tab, valueName, value)) return;
 		found = this.remove(tab);
 	}
+	let initialAdd = !valueName;
 	
 	let r = this.s.binarySearch(tab, this.oGetter);
 	let oMatch = r[0], oIdx = r[1];
 			this.p.splice(r[1], 0, group);
 		}
 	}
-	let justAdded = !valueName;
-	GST.list.positionTab(tab, justAdded);
+	tab["gst-group"] = group;
+	GST.list.positionTab(tab);
 	GST.glob.log(" = " + (found ? "updated " : "added ") + tab._tPos + " = \n" + GST.list.sorted);
 };
 
 		let idx = 0;
 		for (let g = 0; g < list.length; g++) {
 			let group = list[g];
-			for (let t = 0; t < group.length; t++) {
-				idx++;
-				if (group[t] == tab)
-					return code(list, idx, g, t);
+			if (group != tab["gst-group"]) { idx += group.length; continue;	}
+			let t = group.indexOf(tab);
+			if (t > -1) {
+				idx += t + 1;
+				return code(list, idx, g, t);
 			}
 		}
 		return null;
 	},
 	
-	positionTab : function positionTab(tab, justAdded) {
-		if (!GST.list.ssTabsOpened) return;
-		if (justAdded) return;
-		tab.style.setProperty("display", "", "");
+	positionTab : function positionTab(tab) {
 		GST.list.tabInList(GST.list.sorted.list, tab, function(list, absIdx, g, t) {
+			GST.list.moveTab(tab, 0);
 			GST.list.moveTab(tab, absIdx);
 			
 			GST.list.separateGroup(list, g - 1);

chrome/content/gst.menu.init.js

 				let hasManGroup = GST.core.getManualGroupValue(tab);
 
 				switch (menu.id) {
-					case "menu_loadingNotice":
-						GST.menu.init._showMenu(menu, GST.event.tabsLoading());
-					break;
 					case "menu_ungroup":
-						GST.menu.init._showMenu(menu, hasManGroup && GST.glob.isSourceGroup() && !GST.event.tabsLoading());
+						GST.menu.init._showMenu(menu, hasManGroup && GST.glob.isSourceGroup());
 					break;
 					case "menu_returnGroup":
-						GST.menu.init._showMenu(menu, hasManGroup && !GST.glob.isSourceGroup() && !GST.event.tabsLoading());
+						GST.menu.init._showMenu(menu, hasManGroup && !GST.glob.isSourceGroup());
 					break;
 					case "menu_returnSort":
-						GST.menu.init._showMenu(menu, GST.move.outOfPos(tab) && !GST.event.tabsLoading());
+						GST.menu.init._showMenu(menu, GST.move.outOfPos(tab));
 					break;
 					case "menu_closeGroup":
 						GST.menu.init._showMenu(menu, GST.core.hasGroup(tab));

chrome/content/gst.menu.js

 		let reallyClose = GST.menu._closePrompt(tabs.length);
 
 		if (reallyClose) {
-			GST.sort.pauseSorting = true;
 			for (let i = tabs.length - 1; i >= 0; i--) {
 				let tab = tabs[i];
 				gBrowser.removeTab(tab);
 			}
-			GST.sort.pauseSorting = false;
 		}
 
 		GST.sort.doSort();

chrome/content/gst.move.js

 		let tab = event.target;
 		let tabOldPos = event.detail;
 		let tabNewPos = tab._tPos;
+		return;
 		
-		if (!GST.list.moving)
-			GST.list.sorted.push(tab);
+		//if (!GST.list.moving)
+		//	GST.list.sorted.push(tab);
+			
+		if (GST.list.moving) return;
 		//GST.core.tabLog("onTabMove", tab);
 		return;
 
 		if (gBrowser.tabs.length < 2)
 			return;
 
-		let isAFolderOpening = (event.explicitOriginalTarget.label == "Open All in Tabs");
-		if (isAFolderOpening) {
-			GST.move._folderOpening(event);
-			return;
-		}
-
-		if (GST.event.tabsLoading())
-			return;
+		// may technically be a good idea to wait on some pending moves? will investigate
+		//if (GST.event.tabsLoading()) return;
 
 		let leftTab;
 		if (tabNewPos > 0) {
 		GST.sort.doSort(tab);
 	},
 
-	_folderOpening : function _folderOpening(event) {
-		if (!GST.event.isAFolderOpening) {
-			GST.event.isAFolderOpening = true;
-			let folderMenu = event.explicitOriginalTarget.parentNode;
-			GST.move._countReplacedTab(folderMenu);
-		}
-	},
-
 	_manualMove : function _manualMove(tab, leftTab, rightTab, leftTabSame, rightTabSame) {
 		let neighborTab;
 		let amGrouping = !GST.glob.isDisabledGroup();
 			neighborTab = (leftTab) ? leftTab : rightTab;
 
 		let neighborValue = GST.core.getSortValue(neighborTab, tab);
-		// if we've actually returned to our correctly sorted position it's taken care of in doSort()
+		// if we've actually returned to our correctly sorted position it's taken care of in doSort() (checkSortPos)
 		GST.core.setManualSortValue(tab, neighborValue);
 		tab.setAttribute("gst-directMove", true);
 	},
 
-	// I should perhaps go back to checking a bool in onTabMove, I don't feel like event listeners should be removed and re-added so regularly
-	pauseMoveHandling : function pauseMoveHandling() {
-		gBrowser.tabContainer.removeEventListener("TabMove", GST.init.eventListeners.tabMove, false);
-	},
-
-	resumeMoveHandling : function resumeMoveHandling() {
-		gBrowser.tabContainer.addEventListener("TabMove", GST.init.eventListeners.tabMove, false);
-	},
-
-	_countReplacedTab : function _countReplacedTab(folderMenu) {
-		GST.event.openCount++;
-
-		let i = 0;
-		let firstBookmark;
-		while (i < folderMenu.childNodes.length) {
-			let bookmark = folderMenu.childNodes[i].node.uri;
-			if (!bookmark.startsWith("place:")) {
-				firstBookmark = bookmark;
-				break;
-			}
-			i++;
-		}
-
-		let currentTabUri = gBrowser.mCurrentTab.linkedBrowser.currentURI.spec;
-		if (firstBookmark == currentTabUri)
-			GST.event.loadCount++;
-	},
-
 	_moveTabGroup : function _moveTabGroup(groupTab, oldPos) {
-		GST.move.pauseMoveHandling();
+		GST.list.moving = true;
 		let moveDir = (groupTab._tPos < oldPos ? GST.core.direction.LEFT : GST.core.direction.RIGHT);
 
 		let leftPos = (moveDir == GST.core.direction.LEFT ? oldPos : oldPos - 1);
 			gBrowser.moveTabTo(tab, movePos);
 		}
 
-		GST.move.resumeMoveHandling();
+		GST.list.moving = false;
 	},
 
+	// determines what tabs have been manually moved to a spot and what tabs belong there
+	// manually positioned tabs are then marked as such
 	checkSortPositions : function checkSortPositions() {
 		for (let i = 0; i < gBrowser.tabs.length; i++) {
 			let tab = gBrowser.tabs[i];

chrome/content/gst.sort.js

-GST.sort = {
-	pauseSorting : null,
-
-	doSort : function doSort(triggerTab) {
-		return;
-		if (GST.sort.pauseSorting)
-			return;
-		else if (GST.event.tabsLoading())
-			return;
-
-		//if (triggerTab)
-		//	GST.core.tabLog("doSort()", triggerTab);
-		//else
-		//	GST.glob.log("doSort()");
-
-		GST.core.removeSeparators();
-		let tabList = GST.sort._getTabList();
-
-		let amGrouping = !GST.glob.isDisabledGroup();
-		if (amGrouping) {
-			let groupList = GST.sort._getTabGroups(tabList);
-			GST.sort._sortTabGroups(groupList);
-
-			if (GST.core.groupTabs.separator.enabled)
-				GST.sort._separateGroups(groupList);
-
-			if (GST.core.groupTabs.color)
-				GST.color.colorGroups(groupList);
-
-			GST.sort._moveGroupTabsToSortPos(groupList);
-
-			if (GST.glob.isSourceGroup()) {
-				// if a tab in a group of 2 is ungrouped, the other needs ungrouped as well
-				for (let i = 0; i < groupList.length; i++) {
-					let group = groupList[i];
-					if (group.length == 1 && GST.core.getGroupValue(group[0])) {
-						GST.core.setManualGroupValue(group[0], "");
-						GST.core.setManualSortValue(group[0], "");	// hand-in-hand to avoid confusion
-					}
-				}
-			}
-		} else {
-			tabList.sort(GST.sort.compare.tabSort);
-			GST.sort._moveTabsToSortPos(tabList);
-		}
-
-		GST.move.checkSortPositions();
+GST.compare = {
+	disabled : function compare_disabled(tab) {
+		return true;
 	},
 
-	_getTabList : function _getTabList() {
-		let tabList = new Array();
-		for (let i = 0; i < gBrowser.tabs.length; i++) {
-			let tab = gBrowser.tabs[i];
-			let isClosedTab = (gBrowser._removingTabs.indexOf(tab) > -1);
-			if (isClosedTab)
-				continue;
+	hostname : function compare_hostname(tab) {
+		let hostname = tab.getAttribute("gst-hostname");
+		if (!hostname)
+			hostname = GST.core.getHostname(tab);
+		let www = "www.";
+		if (hostname.startsWith(www))
+			hostname = hostname.substr(www.length);
 
-			tabList.push(tab);
-		}
-
-		return tabList;
+		return hostname;
 	},
 
-	_getTabGroups : function _getTabGroups(tabList) {
-		tabList.sort(GST.sort.compare.tabGroup);
+	source : function compare_source(tab) {
+		// blank tabs get their own group
+		if (GST.core.isBlank(tab))
+			return "blankTab";
 
-		let groupIndex = 0;
-		let groupList = new Array();
-
-		for (let i = 0; i < gBrowser.tabs.length; i++) {
-			let tab = gBrowser.tabs[i];
-			let prevTab = i > 0 ? gBrowser.tabs[i - 1] : null;
-			let nextTab = i < gBrowser.tabs.length - 1 ? gBrowser.tabs[i + 1] : null;
-			
-			if (groupList[groupIndex] == null)
-				groupList[groupIndex] = new Array();
-			groupList[groupIndex].push(tab);
-			
-			tab.setAttribute("gst-hasGroup", true);
-			groupChange = (nextTab == null || !GST.core.sameTabGroup(tab, nextTab));
-			if (groupChange) {
-				groupIndex++;
-				singleTab = (prevTab == null || !GST.core.sameTabGroup(tab, prevTab));
-				if (singleTab)
-					tab.removeAttribute("gst-hasGroup");
-			}
- 		}
-		return groupList;
+		return tab.getAttribute("gst-source");
 	},
 
-	_sortTabGroups : function _sortTabGroups(groupList) {
-		// this one first!
-		groupList.sort(GST.sort.compare.groupSort);
-
-		for (let groupIndex = 0; groupIndex < groupList.length; groupIndex++) {
-			groupList[groupIndex].sort(GST.sort.compare.tabSort);
-		}
+	lastBrowsed : function compare_lastBrowsed(tab) {
+		return Number(tab.getAttribute("gst-lastBrowsed"));
 	},
 
-	_moveGroupTabsToSortPos : function _moveGroupTabsToSortPos(groupList) {
-		GST.move.pauseMoveHandling();
-		let newPos = 0;
-		for (let groupIndex = 0; groupIndex < groupList.length; groupIndex++) {
-			let groupLen = groupList[groupIndex].length;
-			for (let tabIndex = 0; tabIndex < groupLen; tabIndex++) {
-				let tab = groupList[groupIndex][tabIndex];
-				tab.setAttribute("gst-groupPos", tabIndex);
-				tab.setAttribute("gst-groupLen", groupLen);
-				if (tab._tPos != newPos)
-					gBrowser.moveTabTo(tab, newPos);
-				newPos++;
-			}
-		}
-		GST.move.resumeMoveHandling();
+	lastOpened : function compare_lastOpened(tab) {
+		let lastOpened = tab.getAttribute("gst-lastOpened");
+		return lastOpened;
 	},
 
-	_moveTabsToSortPos : function _moveTabsToSortPos(tabList) {
-		GST.move.pauseMoveHandling();
-		for (let i = 0; i < gBrowser.tabs.length; i++) {
-			let tab = tabList[i];
-			let newPos = i;
-			if (tab._tPos != newPos)
-				gBrowser.moveTabTo(tab, newPos);
-		}
-		GST.move.resumeMoveHandling();
-	},
+	title : function compare_title(tab) {
+		title = tab.getAttribute("gst-title");
+		if (!title)
+			title = tab.linkedBrowser.contentTitle;
+		if (!title)
+			title = tab.label;
+		return title.toLowerCase();
+	}
+};
 
-	_compareIt : function _compareIt(compareOne, compareTwo) {
-		if (compareOne < compareTwo)
-			return -1;
-		else if (compareOne > compareTwo)
-			return 1;
-		else
-			return 0;
-	},
+//if (GST.glob.isSourceGroup()) {
+//	// if a tab in a group of 2 is ungrouped, the other needs ungrouped as well
+//	for (let i = 0; i < groupList.length; i++) {
+//		let group = groupList[i];
+//		if (group.length == 1 && GST.core.getGroupValue(group[0])) {
+//			GST.core.setManualGroupValue(group[0], "");
+//			GST.core.setManualSortValue(group[0], "");	// hand-in-hand to avoid confusion
+//		}
+//	}
+//}
 
-	_noSort : function _noSort(tabOne, tabTwo) {
-		let posCompare = GST.sort._compareIt(tabOne._tPos, tabTwo._tPos);
-		return posCompare;
-	},
+//let isClosedTab = (gBrowser._removingTabs.indexOf(tab) > -1);
+//if (isClosedTab)
+//	continue;
 
-	// blank tabs are forced on right
-	_blankCompare : function _blankCompare(tabOne, tabTwo) {
-		let blankOne = GST.core.isBlank(tabOne);
-		let blankTwo = GST.core.isBlank(tabTwo);
-		if (blankOne || blankTwo) {
-			if (blankOne && !blankTwo)
-				return 1;
-			else if (blankTwo && !blankOne)
-				return -1;
-			else
-				return null;
-		}
-		return false;
-	},
-
-	// ungroup a tab to its proper side
-	_ungroupingCompare : function _ungroupingCompare(tabOne, tabTwo) {
-		let ungroupingOne = tabOne.getAttribute("gst-ungrouping");
-		let ungroupingTwo = tabTwo.getAttribute("gst-ungrouping");
-		if (ungroupingOne || ungroupingTwo) {
-			if (ungroupingOne && GST.sort._returnedFrom(tabOne, tabTwo))
-				return (ungroupingOne == GST.core.direction.LEFT ? -1 : 1);
-			else if (ungroupingTwo && GST.sort._returnedFrom(tabTwo, tabOne))
-				return (ungroupingTwo == GST.core.direction.RIGHT ? -1 : 1);
-		}
-		return false;
-	},
-
-	_returnedFrom : function _returnedFrom(tabOne, tabTwo) {
-		return (tabOne.getAttribute("gst-ungroupFrom") == GST.core.getGroupValue(tabTwo));
-	},
-
-	_getGroupRep : function _getGroupRep(group) {
-		let tabIndex = 0;
-		let tab = group[0];
-		while (tab.getAttribute("gst-isReturning") && tabIndex < group.length - 1) {
-			tabIndex++
-			tab = group[tabIndex];
-		}
-		return tab;
-	},
-
-	sortingGroups : null,
-
-	compare : {
-		disabled : function compare_disabled(tab) {
-			return true;
-		},
-
-		hostname : function compare_hostname(tab) {
-			// blank tabs get their own group
-			if (GST.core.isBlank(tab, true))
-				return "blankTab";
-
-			let hostname = tab.getAttribute("gst-hostname");
-			if (!hostname)
-				hostname = GST.core.getHostname(tab);
-			let www = "www.";
-			if (hostname.startsWith(www))
-				hostname = hostname.substr(www.length);
-
-			return hostname;
-		},
-
-		source : function compare_source(tab) {
-			// blank tabs get their own group
-			if (GST.core.isBlank(tab))
-				return "blankTab";
-
-			return tab.getAttribute("gst-source");
-		},
-
-		lastBrowsed : function compare_lastBrowsed(tab) {
-			return Number(tab.getAttribute("gst-lastBrowsed"));
-		},
-
-		lastOpened : function compare_lastOpened(tab) {
-			let lastOpened = tab.getAttribute("gst-lastOpened");
-			return lastOpened;
-		},
-
-		title : function compare_title(tab) {
-			title = tab.getAttribute("gst-title");
-			if (!title)
-				title = tab.linkedBrowser.contentTitle;
-			if (!title)
-				title = tab.label;
-			return title.toLowerCase();
-		},
-
-		groupSort : function compare_groupSort(groupOne, groupTwo) {
-			let groupRepOne = GST.sort._getGroupRep(groupOne);
-			let groupRepTwo = GST.sort._getGroupRep(groupTwo);
-
-			let blankCompare = GST.sort._blankCompare(groupRepOne, groupRepTwo);
-			if (blankCompare == null)	// both blank
-				return GST.sort._noSort(groupRepOne, groupRepTwo);
-			else if (blankCompare)
-				return blankCompare;	// sends blank tabs to right
-
-			let ungroupingCompare = GST.sort._ungroupingCompare(groupRepOne, groupRepTwo);
-			if (ungroupingCompare)
-				return ungroupingCompare;	// ungrouped tab sorted to proper side it was on
-
-			// if we're just sorting between, we leave the groups where they are
-			if (GST.glob.isSortBetween())
-				return GST.sort._noSort(groupRepOne, groupRepTwo);
-
-			let valueOne, valueTwo;
-			// when sorting groups we use a sort derived from the grouping
-			GST.sort.sortingGroups = GST.glob.isSortGroups();
-			valueOne = GST.core.getSortValue(groupRepOne);
-			valueTwo = GST.core.getSortValue(groupRepTwo);
-			GST.sort.sortingGroups = false;
-
-			let result = GST.sort._compareIt(valueOne, valueTwo);
-			if (result == 0)
-				return GST.sort._noSort(groupRepOne, groupRepTwo);
-
-			return result;
-		},
-
-		tabGroup : function compare_tabGroup(tabOne, tabTwo) {
-			let valueOne = GST.core.getGroupValue(tabOne);
-			let valueTwo = GST.core.getGroupValue(tabTwo);
-			let result = GST.sort._compareIt(valueOne, valueTwo);
-			if (result == 0)
-				return GST.sort._noSort(tabOne, tabTwo);
-
-			return result;
-		},
-
-		tabSort : function compare_tabSort(tabOne, tabTwo) {
-			let blankCompare = GST.sort._blankCompare(tabOne, tabTwo);
-			if (blankCompare == null)
-				return GST.sort._noSort(tabOne, tabTwo);
-			else if (blankCompare)
-				return blankCompare;
-
-			let valueOne = GST.core.getSortValue(tabOne);
-			let valueTwo = GST.core.getSortValue(tabTwo);
-			let result = GST.sort._compareIt(valueOne, valueTwo);
-			if (result == 0)
-				return GST.sort._noSort(tabOne, tabTwo);
-
-			return result;
-		}
-	},
-
-	_separateGroups : function _separateGroups(groupList) {
-		if (groupList.length < 2)
-			return;
-
-		for (let groupIndex = 1; groupIndex < groupList.length; groupIndex++) {
-			let prevGroup = groupList[groupIndex - 1];
-			let group = groupList[groupIndex];
-
-			let prevGroupLastTab = prevGroup[prevGroup.length - 1];
-
-			let canSeeUngrouped = (GST.core.groupTabs.color);
-			if (!canSeeUngrouped)
-				GST.core.giveSeparator(prevGroupLastTab);
-			else if (prevGroup.length > 1 || group.length > 1)
-				GST.core.giveSeparator(prevGroupLastTab);
-		}
-	}
-};
+//// blank tabs are forced on right
+//_blankCompare : function _blankCompare(tabOne, tabTwo) {
+//	let blankOne = GST.core.isBlank(tabOne);
+//	let blankTwo = GST.core.isBlank(tabTwo);
+//	if (blankOne || blankTwo) {
+//		if (blankOne && !blankTwo)
+//			return 1;
+//		else if (blankTwo && !blankOne)
+//			return -1;
+//		else
+//			return null;
+//	}
+//	return false;
+//},
+//
+//// ungroup a tab to its proper side
+//_ungroupingCompare : function _ungroupingCompare(tabOne, tabTwo) {
+//	let ungroupingOne = tabOne.getAttribute("gst-ungrouping");
+//	let ungroupingTwo = tabTwo.getAttribute("gst-ungrouping");
+//	if (ungroupingOne || ungroupingTwo) {
+//		if (ungroupingOne && GST.sort._returnedFrom(tabOne, tabTwo))
+//			return (ungroupingOne == GST.core.direction.LEFT ? -1 : 1);
+//		else if (ungroupingTwo && GST.sort._returnedFrom(tabTwo, tabOne))
+//			return (ungroupingTwo == GST.core.direction.RIGHT ? -1 : 1);
+//	}
+//	return false;
+//},
+//
+//_returnedFrom : function _returnedFrom(tabOne, tabTwo) {
+//	return (tabOne.getAttribute("gst-ungroupFrom") == GST.core.getGroupValue(tabTwo));
+//},
+//
+//_getGroupRep : function _getGroupRep(group) {
+//	let tabIndex = 0;
+//	let tab = group[0];
+//	while (tab.getAttribute("gst-isReturning") && tabIndex < group.length - 1) {
+//		tabIndex++
+//		tab = group[tabIndex];
+//	}
+//	return tab;
+//},

chrome/locale/en-US/group_sort_tabs.dtd

 <!ENTITY menu.sort.groups.disabled.label "(no sub sort)">
 <!ENTITY menu.sort.groups.disabled.accessKey "n">
 
-<!ENTITY menu.loadingNotice.label "Loading tabs...">
 <!ENTITY menu.returnSort.label "Move to sorted position">
 <!ENTITY menu.returnSort.accessKey "M">
 <!ENTITY menu.returnGroup.label "Resume default grouping">
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.