Commits

Anonymous committed 9c3cb63

Tab properties are being propertly restored now.
Implementing 'ignore group position' sorting, not yet fully working.

Comments (0)

Files changed (4)

+syntax: glob
+_extra/
+_old/

chrome/content/gst.event.js

 	
 	onTabOpen : function(event) {
 		let tab = event.originalTarget;
-		let openDate = tab.gstLastOpened;
 		if (GST.ssTabsOpened) {	// if tabs are finished restoring
 			GST.setTabSource(tab);		// (SOURCE)
-			openDate = Date.now();
+			GST.sortedList.update(tab, GST.sort.LAST_OPENED, Date.now());		// LAST OPENED
 		}
-		GST.sortedList.update(tab, GST.sort.LAST_OPENED, openDate);		// LAST OPENED
+	},
+	
+	onTabRestore : function(event) {
+		let tab = event.originalTarget;
+		for each (let prop in GST.props) {
+		    if (prop.length > 0)
+			tab[prop] = GST.ss.getTabValue(tab, prop);
+		}
+		GST.sortedList.update(tab, GST.sort.LAST_OPENED, tab.gstLastOpened);		// LAST OPENED
 	},
 	
 	onTabClose : function(event) {
 gBrowser.tabContainer.addEventListener("TabOpen", GST.event.onTabOpen, false);
 gBrowser.tabContainer.addEventListener("TabClose", GST.event.onTabClose, false);
 gBrowser.addEventListener("DOMTitleChanged", GST.event.onTitleChange, false);
+gBrowser.tabContainer.addEventListener("SSTabRestoring", GST.event.onTabRestore, false);
 Services.obs.addObserver(GST.event.ssOpenedObserver, "sessionstore-windows-restored", false);
 GST.prefs.QueryInterface(Components.interfaces.nsIPrefBranch2);
 GST.prefs.addObserver("doFullSortNow", GST.event.prefObserver, false);

chrome/content/gst.helper.js

-let GST;
+Components.utils.import("resource://gre/modules/Services.jsm");
 
-(function() {
-Components.utils.import("resource://gre/modules/Services.jsm");
-let prefs = Services.prefs.getBranch("group_sort_tabs.");
-
-GST = {
+let GST = {
+    debug : true,
+    id : "sort_tabs_by@codeoptimism.net",
+    BETWEEN : 0, GROUPS : 1,
+    props : ["", "gstLastOpened", "gstHostname", "gstLastBrowsed", "gstTitle"],
     sort : { DISABLED : 0, LAST_OPENED : 1, HOSTNAME : 2, LAST_BROWSED : 3, TITLE : 4 },
     group : { DISABLED : 0, HOSTNAME : 1, DATE_DAY : 2, DATE_SESSION : 3, SOURCE : 4 },
-    BETWEEN : 0, GROUPS : 1,
-    get isSortBetween() { return prefs.getIntPref("sort.index") === this.BETWEEN },
-    get isSortGroups() { return prefs.getIntPref("sort.index") === this.GROUPS },
+    prefs : Services.prefs.getBranch("group_sort_tabs."),
+    get isSortBetween() { return this.prefs.getIntPref("sort.index") === this.BETWEEN },
+    get isSortGroups() { return this.prefs.getIntPref("sort.index") === this.GROUPS },
+    ss : Components.classes["@mozilla.org/browser/sessionstore;1"].getService(Components.interfaces.nsISessionStore),
     globalLastBrowsed : null
 };
 
-
-GST.props = ["", "gstLastOpened", "gstHostname", "gstLastBrowsed", "gstTitle"];
-let ss = Components.classes["@mozilla.org/browser/sessionstore;1"].getService(Components.interfaces.nsISessionStore);
-for each (let prop in GST.props) {
-    if (prop.length > 0) ss.persistTabAttribute(prop);
-}
-
-GST.prefs = prefs;
-
-GST.debug = true;
-GST.id = "sort_tabs_by@codeoptimism.net";
-
+(function() {
 (function() {
     let jQuery = null;	// inner
     GST.__defineGetter__("jQuery", function() {
 };
 
 // map prefs to properties
-GST.groupBy = GST.proto.groupBy({idx : function() { return prefs.getIntPref("operative.groupBy.index"); }});
-GST.sortBy = GST.proto.sortBy({idx : function() { return prefs.getIntPref("operative.sortBy.index"); }});
-GST.sortWithinBy = GST.proto.sortBy({idx : function() { return prefs.getIntPref("operative.sortWithinBy.index"); }});
+GST.groupBy = GST.proto.groupBy({idx : function() { return GST.prefs.getIntPref("operative.groupBy.index"); }});
+GST.sortBy = GST.proto.sortBy({idx : function() { return GST.prefs.getIntPref("operative.sortBy.index"); }});
+GST.sortWithinBy = GST.proto.sortBy({idx : function() { return GST.prefs.getIntPref("operative.sortWithinBy.index"); }});
 }());

chrome/content/gst.list.js

 GST.sortedList = function() {
-	let list = [];
+	let sortList, posList;
+	clearLists();
+	
+	function clearLists() {
+		sortList = []; posList = [];
+		sortList.groupProp = "gstSortGroup";
+		posList.groupProp = "gstPosGroup";
+	}
+	
+	function getList() {
+		if (GST.isSortBetween) return posList;
+		if (GST.isSortGroups) return sortList;
+		throw "Sort is something other than 'between' and 'groups'";
+	}
+	
 	function getSort() { return GST.groupBy.getSort() || GST.sortBy.getSort(); }
 	function getSortWithin() { return GST.sortWithinBy.getSort(); }
 	
-	function print(sortableProp) {
+	function getListLen(list) {
+		let len = 0;
+		for (let i = 0; i < list.length; i++)
+			len += list[i].length;
+		return len;
+	}
+	
+	function print(list, sortableProp) {
 		function getTabIdx(tab) {
 			for (let i = 0; i < gBrowser.tabs.length; i++)
 				if (gBrowser.tabs[i] == tab) return i;
 			}
 			output += "\n";
 		}
-		GST.log(output);
+		GST.log(output + "Len -- " + getListLen(list));
 	}
 	
-	function positionTab(tab) {
-		let group = tab.gstGroup;
+	function positionTab(tab, list) {
+		let group = tab[list.groupProp];
 		let idx = 0;
 		for (let i = 0; i < list.length; i++) {
 			if (list[i] === group) { idx += group.indexOf(tab); break; }
 		}
 		gBrowser.moveTabTo(tab, idx);
 		GST.assert(idx === tab._tPos, "Move unsuccessful. " + idx + " " + tab._tPos);
-		positionCheck();
 	}
 	
-	function positionCheck() {
+	function doSortList(list, sort) {
+		let sortProp = GST.props[sort];
+		list.sort(compareFunction);
+		
+		function compareFunction(a, b) {
+			if (a === b) throw "list has duplicates";
+			if (a instanceof Array) { a = a[0]; b = b[0]; }
+			if (a[sortProp] < b[sortProp]) return -1;
+			if (a[sortProp] > b[sortProp]) return 1;
+			if (a._tPos < b._tPos) return -1;
+			if (a._tPos > b._tPos) return 1;
+			throw "two tabs have equivalent _tPos";
+		}
+	}
+		
+	function addTab(tab) {
+		removeTab(tab, sortList);
+
+		let group = null;
+		let groupByProp = GST.groupBy.getProp(tab);
+		for (let i = 0; i < sortList.length; i++) {
+			let sameGroup = (sortList[i][0][groupByProp] === tab[groupByProp]);
+			if (sameGroup) { group = sortList[i]; break; }
+		}
+		
+		if (group) {
+			group.push(tab);
+			doSortList(group, getSortWithin());
+		} else {
+			group = [tab];
+			sortList.push(group);
+			doSortList(sortList, getSort());
+		}
+		tab.gstSortGroup = group;
+	}
+	
+	function addPosTab(tab) {
+		if (tab.gstPosGroup && tab.gstPosGroup.length === 2)
+			tab.gstPosGroup.gstIsUniform = false;
+		removeTab(tab, posList);
+
+		if (posList.length === 0) {
+			posList.push([tab]);
+			tab.gstPosGroup = posList[0];
+			return;
+		}
+		
+		let lastGroup = posList[posList.length - 1];
+		let lastTab = lastGroup[lastGroup.length - 1];
+		let groupByProp = GST.groupBy.getProp(tab);
+		let isMatch = (lastTab[groupByProp] === tab[groupByProp]);
+		
+		let group = null;
+		if (lastGroup.gstIsUniform && !isMatch) {
+			group = [tab];
+			posList.push(group);
+		} else if (isMatch && !lastGroup.gstIsUniform) {
+			group = [lastGroup.pop(), tab];
+			if (lastGroup.length === 0) posList.pop();
+			doSortList(group, getSort());
+			posList.push(group);
+			group.gstIsUniform = true;
+		}
+		
+		// add matching tabs to homogenous groups,
+		// and non-matching tabs to heterogenous groups
+		if (isMatch === lastGroup.gstIsUniform) {
+			group = lastGroup;
+			group.push(tab);
+			doSortList(group, getSort());
+		}
+		tab.gstPosGroup = group;
+	}
+	
+	function removeTab(tab, list) {
+		let group = tab[list.groupProp];
+		if (!group) return;
+		let idx = group.indexOf(tab);
+		group.splice(idx, 1);
+		if (group.length === 0)
+			list.splice(list.indexOf(group), 1);
+	}
+	
+	function positionCheck(list) {
 		let idx = 0;
 		for (let i = 0; i < list.length; i++) {
 			for (let j = 0; j < list[i].length; j++) {
 				let tab = list[i][j];
 				if (tab._tPos !== idx) {
 					GST.halt = true;
-					// BUG, OR SOMETHING :( This assertion trips somewhat often...
-					// definitely if I move tabs but that's normal until I implement that.
 					GST.assert(tab._tPos === idx, "Position check failure: " + idx + " " + tab._tPos);
 				}
 				idx++;
 		}
 	}
 	
-	function addTab(tab, sort, sortWithin) {
-		function sortList(list, sort) {
-			let sortProp = GST.props[sort];
-			list.sort(compareFunction);
-			
-			function compareFunction(a, b) {
-				if (a instanceof Array) { a = a[0]; b = b[0]; }
-				if (a[sortProp] < b[sortProp]) return -1;
-				if (a[sortProp] > b[sortProp]) return 1;
-				if (a._tPos < b._tPos) return -1;
-				if (a._tPos > b._tPos) return 1;
-				throw "two tabs have equivalent _tPos";
-			}
-		}
-
-		removeTab(tab);
-
-		let group = null;
-		let groupByProp = GST.groupBy.getProp(tab);
-		for (let i = 0; i < list.length; i++) {
-			let sameGroup = (list[i][0][groupByProp] === tab[groupByProp]);
-			if (sameGroup) { group = list[i]; break; }
-		}
-		
-		if (group) {
-			group.push(tab);
-			sortList(group, sortWithin);
-		} else {
-			group = [tab];
-			list.push(group);
-			sortList(list, sort);
-		}
-		tab.gstGroup = group;
-	}
-	
-	function removeTab(tab) {
-		let group = tab.gstGroup;
-		if (!group) return;
-		let idx = group.indexOf(tab);
-		group.splice(idx, 1);
-		if (group.length === 0)
-			list.splice(list.indexOf(group), 1);
-	}
-	
 	let that = {
 		update : function(tab, sortable, value) {
 			if (GST.halt) return;
 			let sortableProp = GST.props[sortable]
 			tab[sortableProp] = value;
-			
-			let sort = getSort();
-			let sortWithin = getSortWithin();
-			addTab(tab, sort, sortWithin);
-			let relevantToSort = (sortable === sort || sortable === sortWithin);
+			// save in session store
+			GST.ss.setTabValue(tab, sortableProp, value);
+
+			addTab(tab);
+			addPosTab(tab);
+			let relevantToSort = (sortable === getSort() || sortable === getSortWithin());
 			if (!relevantToSort) return;
 
-			positionTab(tab);
-			print(sortableProp);
+			let list = getList();
+			positionTab(tab, list);
+			print(list, sortableProp);
 		},
 		
-		removeTab : removeTab,
+		removeTab : function(tab) {
+			removeTab(tab, sortList);
+			removeTab(tab, posList);
+		},
 		
 		fullSort : function() {
 			let queue = [];
 			for (let i = 0; i < gBrowser.tabs.length; i++)
 				queue.push(gBrowser.tabs[i]);
-			list = [];
+
+			clearLists();				
+			let list = getList();
 			for (let i = queue.length - 1; i >= 0; i--) {
 				let tab = queue[i];
-				tab.gstGroup = null;
-				addTab(tab, getSort(), getSortWithin())
-				positionTab(tab);
+				tab.gstSortGroup = null;
+				tab.gstPosGroup = null;
+				addTab(tab)
+				addPosTab(tab);
+				positionTab(tab, list);
 			}
-			GST.log("====== full sort finished ======");
+			GST.assert(getListLen(list) === gBrowser.tabs.length, "List isn't correct length.");
+			print(list, GST.props[GST.isSortBetween ? GST.sortBy.getSort() : GST.sortWithinBy.getSort()]);
+			positionCheck(list);
 		}
 	};
 	return that;